---
title: "DI a akcie — Tickets for Laravel | Roundly"
description: "Bez fasády: injektujte TicketsManager alebo zavolajte jednoúčelovú akciu — každá akcia so signatúrou execute() a cestou cez fasádu."
url: https://roundly-consulting.com/sk/open-source/navody/tickets-for-laravel/bez-fasady
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Tickets for Laravel](https://roundly-consulting.com/sk/open-source/navody/tickets-for-laravel.md)

# DI a akcie

Fasáda je odporúčaná voľba, nie jediná cesta. Rovnaký kód spúšťajú tri vstupy: fasáda Tickets (najkratší zápis), manažér RoundlyConsulting\\Tickets\\TicketsManager — koreň fasády, singleton v kontajneri — injektovaný cez konštruktor (rovnaké API, explicitná závislosť, žiadne statické volania) a akcie (final readonly triedy s jedinou metódou execute(), ktoré skladáte do vlastných akcií, jobov a príkazov):

```php
use RoundlyConsulting\Tickets\Actions\Assignment\AssignTicketAction;
use RoundlyConsulting\Tickets\Facades\Tickets;
use RoundlyConsulting\Tickets\TicketsManager;

// Facade
Tickets::for($ticket)->by($agent)->assign($user);

// Dependency injection: the same API
public function __construct(private TicketsManager $tickets) {}
$this->tickets->for($ticket)->by($agent)->assign($user);

// The raw action
app(AssignTicketAction::class)->execute($ticket, $user, actor: $agent);
```

## Injektovanie manažéra

```php
use Illuminate\Http\Request;
use RoundlyConsulting\Comments\Models\Comment;
use RoundlyConsulting\Tickets\TicketsManager;

final class TicketReplyController
{
    public function __construct(private TicketsManager $tickets) {}

    public function __invoke(Request $request, string $reference): Comment
    {
        return $this->tickets->for($reference)->by($request->user())->reply($request->input('body'));
    }
}
```

## Volanie akcie

```php
use RoundlyConsulting\Tickets\Actions\Merge\MergeTicketsAction;

app(MergeTicketsAction::class)->execute($source, $target, reason: 'duplicate', actor: $agent);
```

?Model $actor = null, bool $system = false fungujú všade rovnako: null použije prihláseného používateľa (pri tickets.actor.from\_auth, na tickets.actor.guard), system: true znamená nikoho. ConvertGuestAction a DeleteCategoryAction berú len $actor — fasáda žiadneho neodovzdá, takže sa pripíšu prihlásenému používateľovi.

## Metóda fasády → akcia

Menné priestory sú relatívne k RoundlyConsulting\\Tickets\\Actions:

| Akcia | execute(…) | Vracia | Cesta cez fasádu |
| --- | --- | --- | --- |
| `Tickets\CreateTicketAction` | `CreateTicketData $data` | `Ticket` | `Tickets::create(), Tickets::make()->…->create()` |
| `Tickets\UpdateTicketAction` | `Ticket $ticket, UpdateTicketData $data, ?Model $actor = null, bool $system = false` | `Ticket` | `->update()` |
| `Tickets\ChangePriorityAction` | `Ticket $ticket, BackedEnum\|string $priority, ?Model $actor = null, bool $system = false` | `Ticket` | `->prioritize()` |
| `Tickets\ChangeCategoryAction` | `Ticket $ticket, TicketCategory\|int\|null $category, ?Model $actor = null, bool $system = false` | `Ticket` | `->categorize()` |
| `Tickets\SetDueDateAction` | `Ticket $ticket, ?CarbonInterface $dueAt, ?Model $actor = null, bool $system = false` | `Ticket` | `->due()` |
| `Tickets\ChangeRequesterAction` | `Ticket $ticket, Model\|GuestData $requester, ?Model $actor = null, bool $system = false` | `Ticket` | `->changeRequester()` |
| `Tickets\DeleteTicketAction` | `Ticket $ticket, ?Model $actor = null, bool $system = false` | `Ticket` | `->delete()` |
| `Tickets\RestoreTicketAction` | `Ticket $ticket, ?Model $actor = null, bool $system = false` | `Ticket` | `->restore()` |
| `Tickets\TransitionTicketAction` | `Ticket $ticket, TransitionData $data, ?Model $actor = null, bool $system = false` | `TransitionResult` | `->transition() and the named conveniences` |
| `Conversation\PostReplyAction` | `Ticket $ticket, ReplyData $data, ?TransitionData $transition = null, ?Model $actor = null, bool $system = false` | `Comment` | `->reply(), $ticket->reply()` |
| `Conversation\PostNoteAction` | `Ticket $ticket, ReplyData $data, ?Model $actor = null, bool $system = false` | `Comment` | `->note(), $ticket->note()` |
| `Conversation\UpdateCommentAction` | `Ticket $ticket, Comment $comment, string $body, ?Model $actor = null, bool $system = false` | `Comment` | `->editComment()` |
| `Conversation\DeleteCommentAction` | `Ticket $ticket, Comment $comment, ?Model $actor = null, bool $system = false` | `Comment` | `->deleteComment()` |
| `Assignment\AssignTicketAction` | `Ticket $ticket, Model $assignee, ?Model $actor = null, bool $system = false` | `Ticket` | `->assign(), $ticket->assignTo()` |
| `Assignment\UnassignTicketAction` | `Ticket $ticket, ?Model $actor = null, bool $system = false` | `Ticket` | `->unassign()` |
| `Assignment\ClaimTicketAction` | `Ticket $ticket, ?Model $actor = null, bool $system = false` | `Ticket` | `->claim()` |
| `Watchers\AddWatcherAction` | `Ticket $ticket, Model $watcher, ?Model $actor = null, bool $system = false` | `Ticket` | `->watchers()->add() / watch()` |
| `Watchers\RemoveWatcherAction` | `Ticket $ticket, Model $watcher, ?Model $actor = null, bool $system = false` | `Ticket` | `->watchers()->remove() / unwatch()` |
| `Tags\AttachTagsAction` | `Ticket $ticket, array $tags, ?Model $actor = null, bool $system = false` | `Ticket` | `->tags()->attach()` |
| `Tags\DetachTagsAction` | `Ticket $ticket, array $tags, ?Model $actor = null, bool $system = false` | `Ticket` | `->tags()->detach()` |
| `Tags\SyncTagsAction` | `Ticket $ticket, array $tags, ?Model $actor = null, bool $system = false` | `Ticket` | `->tags()->sync()` |
| `Tags\CreateTagAction` | `TagData $data, bool $orExisting = false` | `TicketTag` | `Tickets::tags()->create() / findOrCreate()` |
| `Tags\UpdateTagAction` | `TicketTag $tag, UpdateTagData $data` | `TicketTag` | `Tickets::tags()->update() / rename() / recolor()` |
| `Tags\DeleteTagAction` | `TicketTag $tag` | `TicketTag` | `Tickets::tags()->delete()` |
| `Links\LinkTicketsAction` | `Ticket $ticket, Ticket $related, LinkType $type, ?Model $actor = null, bool $system = false` | `TicketLink` | `->links()->add()` |
| `Links\UnlinkTicketsAction` | `Ticket $ticket, Ticket $related, LinkType $type, ?Model $actor = null, bool $system = false` | `Ticket` | `->links()->remove()` |
| `Merge\MergeTicketsAction` | `Ticket $source, Ticket $target, ?string $reason = null, ?Model $actor = null, bool $system = false` | `MergeResult` | `->mergeInto()` |
| `Attachments\AddAttachmentAction` | `Ticket $ticket, UploadedFile\|string $file, ?Model $actor = null, bool $system = false` | `Media` | `->attachments()->add()` |
| `Attachments\RemoveAttachmentAction` | `Ticket $ticket, Media\|string $media, ?Model $actor = null, bool $system = false` | `Ticket` | `->attachments()->remove()` |
| `Fields\SetFieldValuesAction` | `Ticket $ticket, array $values, ?Model $actor = null, bool $system = false` | `Ticket` | `->fields()->set() / setMany()` |
| `Fields\ForgetFieldValuesAction` | `Ticket $ticket, array $keys, ?Model $actor = null, bool $system = false` | `Ticket` | `->fields()->forget()` |
| `Fields\DefineFieldAction` | `FieldData $data` | `TicketField` | `Tickets::fields()->define() / make()->…->define()` |
| `Fields\UpdateFieldAction` | `TicketField $field, UpdateFieldData $data` | `TicketField` | `Tickets::fields()->update()` |
| `Fields\DeleteFieldAction` | `TicketField $field` | `TicketField` | `Tickets::fields()->delete()` |
| `Fields\RestoreFieldAction` | `TicketField $field` | `TicketField` | `Tickets::fields()->restore()` |
| `Fields\PruneOrphanFieldValuesAction` | `bool $dryRun = false, int $chunk = 200` | `int` | `Tickets::fields()->prune(), tickets:prune-fields` |
| `Categories\CreateCategoryAction` | `CategoryData $data` | `TicketCategory` | `Tickets::categories()->create() / make()->…->create()` |
| `Categories\UpdateCategoryAction` | `TicketCategory $category, UpdateCategoryData $data` | `TicketCategory` | `Tickets::categories()->update()` |
| `Categories\MoveCategoryAction` | `TicketCategory $category, TicketCategory\|int\|null $parent, ?int $position = null` | `TicketCategory` | `Tickets::categories()->move()` |
| `Categories\DeleteCategoryAction` | `TicketCategory $category, TicketCategory\|int\|null $reassignTo = null, ?Model $actor = null` | `TicketCategory` | `Tickets::categories()->delete()` |
| `Categories\RestoreCategoryAction` | `TicketCategory $category` | `TicketCategory` | `Tickets::categories()->restore()` |
| `Guests\ResolveGuestAction` | `GuestData $data` | `TicketGuest` | `Tickets::guests()->resolve()` |
| `Guests\UpdateGuestAction` | `TicketGuest $guest, GuestData $data` | `TicketGuest` | `Tickets::guests()->update()` |
| `Guests\ConvertGuestAction` | `TicketGuest $guest, Model $user, ?Model $actor = null` | `int` | `Tickets::guests()->convert()` |
| `Guests\IssueGuestLinkAction` | `Ticket $ticket, ?Model $guest = null` | `string` | `->guestLink(), Tickets::guests()->linkFor()` |
| `Guests\RevokeGuestAccessAction` | `Ticket $ticket, ?Model $actor = null, bool $system = false` | `Ticket` | `->revokeGuestAccess()` |
| `Due\SweepDueDatesAction` | `—` | `SweepResult` | `Tickets::sweep(), tickets:sweep` |

- Handly a pod-prístupy si každú akciu berú z kontajnera, takže väzba akcie vo vašej aplikácii platí pre všetky cesty — fasádu, injektovaného manažéra, handle, builder aj metódu modelu.
- Tickets::fake() vymení manažéra aj v kontajneri, takže sa podvrhne aj injektovaný TicketsManager. Priame volanie akcie sa nezaznamená — zaznamenávajú sa len volania manažéra.
- Interné stavebné bloky na fasáde nie sú a nevolajte ich: Internal\\AllocateReferenceAction, RecordActivityAction, ApplyAutomationAction, AutoWatchAction, ResolveAuthorRoleAction, ResolveTagsAction, ChangeTicketTagsAction, WriteFieldValuesAction, WriteTicketCommentAction a BumpGuestAccessAction.

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/tickets-for-laravel.md)
