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ády | Akcia | execute(…) | Vracia |
|---|---|---|---|
start()->create() | StartThread | CreateThreadData | Thread |
direct() | FindOrCreateDirectThread | Model $first, Model $second | Thread |
to()->send() / send() | SendMessage | SendMessageData | Message |
markRead() / thread()->markRead() | MarkRead | MarkReadData | Participant |
thread()->rename() | RenameThread | Thread $thread, ?string $name, ?Model $actor = null | Thread |
thread()->archive() | ArchiveThread | Thread $thread, ?Model $actor = null | Thread |
thread()->typing() | SignalTyping | Thread $thread, Model $participant | void |
participants()->add() | AddParticipant | AddParticipantData | Participant |
participants()->remove() | RemoveParticipant | RemoveParticipantData | void |
participants()->leave() | LeaveThread | Thread $thread, Model $participant | void |
participants()->setRole() | SetParticipantRole | SetParticipantRoleData | Participant |
participants()->transferOwnership() | TransferOwnership | Thread $thread, Model $currentOwner, Model $newOwner | Participant (nový vlastník) |
message()->edit() | EditMessage | EditMessageData | Message |
message()->delete() | DeleteMessage | Message $message, ?Model $actor = null | Message |
prune() | PruneMessages | PruneMessagesData | int (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ýnimka | Pomenovaný konštruktor | Vyhodí sa, keď |
|---|---|---|
MessageException | alreadyDeleted() | Upravujete alebo mažete správu, ktorej odoslanie už bolo zrušené. |
MessageException | replyAcrossThreads() | Odpoveď cieli na správu v inom vlákne alebo na neexistujúcu správu. |
MessageException | notInThread() | Messages::thread($t)->message($m) dostane správu z iného vlákna. |
MessageException | attachmentIsNotAnImage() | attachmentPreviewUrl() sa volá pre prílohu, ktorá nie je obrázok. |
ParticipationException | notAParticipant() | Označenie prečítania, odobratie, zmena roly, prevod alebo signál písania pre model, ktorý vo vlákne nie je. |
ParticipationException | ownershipOnlyByTransfer() | setRole() na rolu vlastníka alebo z nej, prípadne add() druhého vlastníka — pre každého volajúceho. |
ParticipationException | ownerMustTransferFirst() | Vlastník odchádza alebo ho niekto odoberá, kým je vo vlákne ešte niekto iný — pre každého volajúceho. |
ParticipationException | notTheOwner() | transferOwnership(from: …) uvádza účastníka, ktorý vlákno nevlastní. |
ParticipationException | directThreadHasNoRoles() | setRole() alebo transferOwnership() v priamom vlákne. |
ParticipationException | inAnotherThread() | Metóda participants() dostane záznam Participant z iného vlákna. |
ParticipationException | participantMissing() | Model za záznamom Participant už neexistuje. |
ParticipationException | interfaceImplementationRequired() | Broadcast payload potrebuje participateAs() z modelu bez ParticipatesInMessaging. |
UnauthorizedMessagingAction | requiresRole() | Vykonávateľ (actor) nie je účastníkom alebo mu chýba rola administrátora (správa vlákna), resp. vlastníka (roly, prevod). |
UnauthorizedMessagingAction | for() | 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 kryptomienOdoslaní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.