NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky

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):

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

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

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:

Akciaexecute(…)VraciaCesta cez fasádu
Tickets\CreateTicketActionCreateTicketData $dataTicketTickets::create(), Tickets::make()->…->create()
Tickets\UpdateTicketActionTicket $ticket, UpdateTicketData $data, ?Model $actor = null, bool $system = falseTicket->update()
Tickets\ChangePriorityActionTicket $ticket, BackedEnum|string $priority, ?Model $actor = null, bool $system = falseTicket->prioritize()
Tickets\ChangeCategoryActionTicket $ticket, TicketCategory|int|null $category, ?Model $actor = null, bool $system = falseTicket->categorize()
Tickets\SetDueDateActionTicket $ticket, ?CarbonInterface $dueAt, ?Model $actor = null, bool $system = falseTicket->due()
Tickets\ChangeRequesterActionTicket $ticket, Model|GuestData $requester, ?Model $actor = null, bool $system = falseTicket->changeRequester()
Tickets\DeleteTicketActionTicket $ticket, ?Model $actor = null, bool $system = falseTicket->delete()
Tickets\RestoreTicketActionTicket $ticket, ?Model $actor = null, bool $system = falseTicket->restore()
Tickets\TransitionTicketActionTicket $ticket, TransitionData $data, ?Model $actor = null, bool $system = falseTransitionResult->transition() and the named conveniences
Conversation\PostReplyActionTicket $ticket, ReplyData $data, ?TransitionData $transition = null, ?Model $actor = null, bool $system = falseComment->reply(), $ticket->reply()
Conversation\PostNoteActionTicket $ticket, ReplyData $data, ?Model $actor = null, bool $system = falseComment->note(), $ticket->note()
Conversation\UpdateCommentActionTicket $ticket, Comment $comment, string $body, ?Model $actor = null, bool $system = falseComment->editComment()
Conversation\DeleteCommentActionTicket $ticket, Comment $comment, ?Model $actor = null, bool $system = falseComment->deleteComment()
Assignment\AssignTicketActionTicket $ticket, Model $assignee, ?Model $actor = null, bool $system = falseTicket->assign(), $ticket->assignTo()
Assignment\UnassignTicketActionTicket $ticket, ?Model $actor = null, bool $system = falseTicket->unassign()
Assignment\ClaimTicketActionTicket $ticket, ?Model $actor = null, bool $system = falseTicket->claim()
Watchers\AddWatcherActionTicket $ticket, Model $watcher, ?Model $actor = null, bool $system = falseTicket->watchers()->add() / watch()
Watchers\RemoveWatcherActionTicket $ticket, Model $watcher, ?Model $actor = null, bool $system = falseTicket->watchers()->remove() / unwatch()
Tags\AttachTagsActionTicket $ticket, array $tags, ?Model $actor = null, bool $system = falseTicket->tags()->attach()
Tags\DetachTagsActionTicket $ticket, array $tags, ?Model $actor = null, bool $system = falseTicket->tags()->detach()
Tags\SyncTagsActionTicket $ticket, array $tags, ?Model $actor = null, bool $system = falseTicket->tags()->sync()
Tags\CreateTagActionTagData $data, bool $orExisting = falseTicketTagTickets::tags()->create() / findOrCreate()
Tags\UpdateTagActionTicketTag $tag, UpdateTagData $dataTicketTagTickets::tags()->update() / rename() / recolor()
Tags\DeleteTagActionTicketTag $tagTicketTagTickets::tags()->delete()
Links\LinkTicketsActionTicket $ticket, Ticket $related, LinkType $type, ?Model $actor = null, bool $system = falseTicketLink->links()->add()
Links\UnlinkTicketsActionTicket $ticket, Ticket $related, LinkType $type, ?Model $actor = null, bool $system = falseTicket->links()->remove()
Merge\MergeTicketsActionTicket $source, Ticket $target, ?string $reason = null, ?Model $actor = null, bool $system = falseMergeResult->mergeInto()
Attachments\AddAttachmentActionTicket $ticket, UploadedFile|string $file, ?Model $actor = null, bool $system = falseMedia->attachments()->add()
Attachments\RemoveAttachmentActionTicket $ticket, Media|string $media, ?Model $actor = null, bool $system = falseTicket->attachments()->remove()
Fields\SetFieldValuesActionTicket $ticket, array $values, ?Model $actor = null, bool $system = falseTicket->fields()->set() / setMany()
Fields\ForgetFieldValuesActionTicket $ticket, array $keys, ?Model $actor = null, bool $system = falseTicket->fields()->forget()
Fields\DefineFieldActionFieldData $dataTicketFieldTickets::fields()->define() / make()->…->define()
Fields\UpdateFieldActionTicketField $field, UpdateFieldData $dataTicketFieldTickets::fields()->update()
Fields\DeleteFieldActionTicketField $fieldTicketFieldTickets::fields()->delete()
Fields\RestoreFieldActionTicketField $fieldTicketFieldTickets::fields()->restore()
Fields\PruneOrphanFieldValuesActionbool $dryRun = false, int $chunk = 200intTickets::fields()->prune(), tickets:prune-fields
Categories\CreateCategoryActionCategoryData $dataTicketCategoryTickets::categories()->create() / make()->…->create()
Categories\UpdateCategoryActionTicketCategory $category, UpdateCategoryData $dataTicketCategoryTickets::categories()->update()
Categories\MoveCategoryActionTicketCategory $category, TicketCategory|int|null $parent, ?int $position = nullTicketCategoryTickets::categories()->move()
Categories\DeleteCategoryActionTicketCategory $category, TicketCategory|int|null $reassignTo = null, ?Model $actor = nullTicketCategoryTickets::categories()->delete()
Categories\RestoreCategoryActionTicketCategory $categoryTicketCategoryTickets::categories()->restore()
Guests\ResolveGuestActionGuestData $dataTicketGuestTickets::guests()->resolve()
Guests\UpdateGuestActionTicketGuest $guest, GuestData $dataTicketGuestTickets::guests()->update()
Guests\ConvertGuestActionTicketGuest $guest, Model $user, ?Model $actor = nullintTickets::guests()->convert()
Guests\IssueGuestLinkActionTicket $ticket, ?Model $guest = nullstring->guestLink(), Tickets::guests()->linkFor()
Guests\RevokeGuestAccessActionTicket $ticket, ?Model $actor = null, bool $system = falseTicket->revokeGuestAccess()
Due\SweepDueDatesAction—SweepResultTickets::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

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

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.