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

DI, akcie, DTO a výnimky

Fasáda je odporúčaná voľba, nie jediná cesta. K dispozícii sú tri rovnocenné vstupy a všetky spúšťajú ten istý kód:

  • Fasáda Messages — najkratšie volania, aké používa celá táto dokumentácia.
  • Manager RoundlyConsulting\Messages\MessagesManager — koreň fasády, registrovaný ako singleton. Vložte si ho cez konštruktor a získate to isté API ako explicitnú závislosť, bez statických volaní.
  • Akcie v RoundlyConsulting\Messages\Actions — jednoúčelové triedy s metódou execute(…), ktoré skladáte do vlastných akcií, jobov a príkazov.

Vloženie managera

use RoundlyConsulting\Messages\MessagesManager;

final class ThreadController
{
    public function __construct(private MessagesManager $messages) {}

    public function rename(Thread $thread, Request $request): Thread
    {
        return $this->messages->thread($thread)->rename($request->name, by: $request->user());
    }
}

Messages::fake() podstrčí podtyp MessagesManager, takže fake dostanú aj managery vložené cez konštruktor.

Spustenie akcie

Každú akciu získate z kontajnera, prijíma DTO alebo bežné argumenty a spustí svoju udalosť:

use RoundlyConsulting\Messages\Actions\EditMessage;
use RoundlyConsulting\Messages\DataTransferObjects\EditMessageData;

app(EditMessage::class)->execute(new EditMessageData($message, 'fixed typo', actor: $alice));

Priamo volané akcie Messages::fake() obchádzajú; fasáda, manager aj traity modelov idú cez neho.

Metóda fasády → akcia

Metóda fasádyAkciaexecute(…)Vracia
start()->create()StartThreadCreateThreadDataThread
direct()FindOrCreateDirectThreadModel $first, Model $secondThread
to()->send() / send()SendMessageSendMessageDataMessage
markRead() / thread()->markRead()MarkReadMarkReadDataParticipant
thread()->rename()RenameThreadThread $thread, ?string $name, ?Model $actor = nullThread
thread()->archive()ArchiveThreadThread $thread, ?Model $actor = nullThread
thread()->typing()SignalTypingThread $thread, Model $participantvoid
participants()->add()AddParticipantAddParticipantDataParticipant
participants()->remove()RemoveParticipantRemoveParticipantDatavoid
participants()->leave()LeaveThreadThread $thread, Model $participantvoid
participants()->setRole()SetParticipantRoleSetParticipantRoleDataParticipant
participants()->transferOwnership()TransferOwnershipThread $thread, Model $currentOwner, Model $newOwnerParticipant (nový vlastník)
message()->edit()EditMessageEditMessageDataMessage
message()->delete()DeleteMessageMessage $message, ?Model $actor = nullMessage
prune()PruneMessagesPruneMessagesDataint (počet zmazaných správ)

unreadCount(), inboxFor(), threads() a thread()->messages() len čítajú, preto žiadnu akciu nemajú.

DTO

Readonly DTO v RoundlyConsulting\Messages\DataTransferObjects:

new CreateThreadData(?string $name = null, ?bool $isPublic = null, ?bool $everyoneCanJoin = null, bool $isDirect = false, array $participants = [], ?string $directKey = null);
new SendMessageData(Thread $thread, ?Model $sender, string $body, MessageType $type = MessageType::Text, array $meta = [], int|string|null $parentMessageId = null, array $attachments = [], array $uploads = [], bool $requireParticipation = true);
new EditMessageData(Message $message, string $body, ?Model $actor = null); // actor must be the author
new MarkReadData(Thread $thread, Model $participant);
new AddParticipantData(Thread $thread, Model $participant, ?ParticipantRole $role = null, ?Model $actor = null);
new RemoveParticipantData(Thread $thread, Model $participant, ?Model $actor = null);
new SetParticipantRoleData(Thread $thread, Model $participant, ParticipantRole $role, ?Model $actor = null);
new PruneMessagesData(int $days, int|string|null $threadId = null);

Skladanie akcií

use RoundlyConsulting\Messages\Actions\SendMessage;
use RoundlyConsulting\Messages\Actions\StartThread;
use RoundlyConsulting\Messages\DataTransferObjects\CreateThreadData;
use RoundlyConsulting\Messages\DataTransferObjects\SendMessageData;

$thread = app(StartThread::class)->execute(new CreateThreadData(
    name: 'Support',
    isPublic: false,
    participants: [$customer, $agent],   // the first participant becomes the owner
));

app(SendMessage::class)->execute(new SendMessageData(
    thread: $thread,
    sender: $customer,
    body: 'My order has not arrived yet.',
    meta: ['order' => 'A-1042'],
));

SendMessage odmietne odosielateľa, ktorý nie je aktuálnym účastníkom, pokiaľ requireParticipation nie je false (to nastaví withoutParticipationCheck()), vytvorí správu a naviaže jej prílohy v jednej transakcii, aktualizuje last_activity_at vlákna a MessageSent spustí až po commite.

Výnimky

Všetky sú v RoundlyConsulting\Messages\Exceptions; ich texty sa prekladajú cez reťazce z messages-translations:

VýnimkaPomenovaný konštruktorVyhodí sa, keď
MessageExceptionalreadyDeleted()Upravujete alebo mažete správu, ktorej odoslanie už bolo zrušené.
MessageExceptionreplyAcrossThreads()Odpoveď cieli na správu v inom vlákne alebo na neexistujúcu správu.
MessageExceptionnotInThread()Messages::thread($t)->message($m) dostane správu z iného vlákna.
MessageExceptionattachmentIsNotAnImage()attachmentPreviewUrl() sa volá pre prílohu, ktorá nie je obrázok.
ParticipationExceptionnotAParticipant()Označenie prečítania, odobratie, zmena roly, prevod alebo signál písania pre model, ktorý vo vlákne nie je.
ParticipationExceptionownershipOnlyByTransfer()setRole() na rolu vlastníka alebo z nej, prípadne add() druhého vlastníka — pre každého volajúceho.
ParticipationExceptionownerMustTransferFirst()Vlastník odchádza alebo ho niekto odoberá, kým je vo vlákne ešte niekto iný — pre každého volajúceho.
ParticipationExceptionnotTheOwner()transferOwnership(from: …) uvádza účastníka, ktorý vlákno nevlastní.
ParticipationExceptiondirectThreadHasNoRoles()setRole() alebo transferOwnership() v priamom vlákne.
ParticipationExceptioninAnotherThread()Metóda participants() dostane záznam Participant z iného vlákna.
ParticipationExceptionparticipantMissing()Model za záznamom Participant už neexistuje.
ParticipationExceptioninterfaceImplementationRequired()Broadcast payload potrebuje participateAs() z modelu bez ParticipatesInMessaging.
UnauthorizedMessagingActionrequiresRole()Vykonávateľ (actor) nie je účastníkom alebo mu chýba rola administrátora (správa vlákna), resp. vlastníka (roly, prevod).
UnauthorizedMessagingActionfor()Odosielateľ nie je aktuálnym účastníkom alebo vykonávateľ (actor) nesmie túto správu zmazať či upraviť, odobrať účastníka s rovnakou alebo vyššou rolou, prípadne sa sám pridať do vlákna, ktoré nie je otvorené pre všetkých.

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.