From 62d2c0acf56b091bd1d2352b1bb65e00683ec6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Munsch?= Date: Wed, 21 Jul 2021 09:44:29 +0200 Subject: [PATCH] Upgrade notification system on tickets --- app/Events/NotifySubscriptions.php | 7 +- app/Events/NotifyTicketCreator.php | 32 +++++++++ app/Events/TicketStatusChanged.php | 12 +++- app/Http/Controllers/TicketController.php | 34 +--------- app/Listeners/AddStatusMessages.php | 10 --- .../SendNotificationMailToTicketCreator.php | 26 ++++++++ ...=> SendSubscriptionsNotificationsMail.php} | 13 ++-- app/Models/Message.php | 65 ++++++++++++++++++- app/Providers/EventServiceProvider.php | 20 ++++-- 9 files changed, 163 insertions(+), 56 deletions(-) create mode 100644 app/Events/NotifyTicketCreator.php create mode 100644 app/Listeners/SendNotificationMailToTicketCreator.php rename app/Listeners/{SendNotificationMail.php => SendSubscriptionsNotificationsMail.php} (54%) diff --git a/app/Events/NotifySubscriptions.php b/app/Events/NotifySubscriptions.php index 1f60396..b2c15bd 100644 --- a/app/Events/NotifySubscriptions.php +++ b/app/Events/NotifySubscriptions.php @@ -6,6 +6,7 @@ use App\Models\Ticket; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; +use Illuminate\Support\Collection; class NotifySubscriptions { @@ -19,14 +20,18 @@ class NotifySubscriptions /** @var string */ public $corpsMaj; + /** @var Collection */ + public $ignoreUsers; + /** * Create a new event instance. * * @return void */ - public function __construct(Ticket $ticket, string $corpsMaj) + public function __construct(Ticket $ticket, string $corpsMaj, Collection $ignoreUsers = null) { $this->ticket = $ticket; $this->corpsMaj = $corpsMaj; + $this->ignoreUsers = $ignoreUsers; } } diff --git a/app/Events/NotifyTicketCreator.php b/app/Events/NotifyTicketCreator.php new file mode 100644 index 0000000..f2e8284 --- /dev/null +++ b/app/Events/NotifyTicketCreator.php @@ -0,0 +1,32 @@ +ticket = $ticket; + $this->corpsMaj = $corpsMaj; + } +} diff --git a/app/Events/TicketStatusChanged.php b/app/Events/TicketStatusChanged.php index 64a9e3a..804cb3b 100644 --- a/app/Events/TicketStatusChanged.php +++ b/app/Events/TicketStatusChanged.php @@ -2,22 +2,28 @@ namespace App\Events; +use App\Models\Ticket; use Illuminate\Broadcasting\InteractsWithSockets; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; class TicketStatusChanged { - use Dispatchable, InteractsWithSockets, SerializesModels; + use Dispatchable; + use InteractsWithSockets; + use SerializesModels; - public $ticket, $status; + /** @var Ticket */ + public $ticket; + + public $status; /** * Create a new event instance. * * @return void */ - public function __construct($ticket, $status) + public function __construct(Ticket $ticket, $status) { $this->ticket = $ticket; $this->status = $status; diff --git a/app/Http/Controllers/TicketController.php b/app/Http/Controllers/TicketController.php index 31604c4..b3dadab 100644 --- a/app/Http/Controllers/TicketController.php +++ b/app/Http/Controllers/TicketController.php @@ -5,21 +5,17 @@ namespace App\Http\Controllers; use App\Enums\Role; use App\Enums\TicketStatus; use App\Enums\TicketType; -use App\Events\NotifySubscriptions; use App\Http\Requests\ChangeTicketStatus; use App\Http\Requests\CreateMessage; use App\Http\Requests\SortTickets; use App\Http\Requests\StoreTicket; use App\Http\Requests\UpdateTicket; -use App\Jobs\SendTicketMentionMail; use App\Mail\NewTicket; -use App\Mail\TicketMention; use App\Models\Message; use App\Models\Project; use App\Models\Ticket; use App\Models\User; use Exception; -use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; @@ -237,11 +233,11 @@ class TicketController extends Controller $message = new Message($request->validated()); $message->user()->associate(auth()->user()); $message->ticket()->associate($ticket); - $message->saveOrFail(); /** @var \App\Models\User */ $user = auth()->user(); + // Toggle auth user subscription if ($request->subscribe) { if (!$user->subscriptions()->find($ticket->id)) { $user->subscriptions()->attach($ticket->id); @@ -257,35 +253,9 @@ class TicketController extends Controller $fileMessage->move(public_path('fichiers/' . $projectSlug . '/' . $ticket->id . '/'), $fileName); $filePath = 'fichiers/' . $projectSlug . '/' . $ticket->id . '/' . $fileName; $message->file = $filePath; - $message->save(); } - event(new NotifySubscriptions( - $message->ticket, - trans('Nouvelle réponse de :name :
:message', [ - 'name' => $message->user->name, - 'message' => $message->message - ]) - )); - - // find @user + send mail si un seul user est trouvé - $matches = []; - \preg_match_all('/@\w*/', $message->message, $matches); - $matches = collect($matches[0] ?? [])->unique(); - foreach ($matches as $pseudo_usertag) { - try { - $user = User::where('name', 'LIKE', '%' . ltrim($pseudo_usertag, '@') . '%') - ->whereDoesntHave('subscriptions', function ($q) use ($ticket) { - $q->where('id', $ticket->id); - })->firstOrFail(); - SendTicketMentionMail::dispatchAfterResponse( - $user, - new TicketMention($ticket, $message->message) - ); - } catch (ModelNotFoundException $e) { - continue; - } - } + $message->saveOrFail(); return back(); } diff --git a/app/Listeners/AddStatusMessages.php b/app/Listeners/AddStatusMessages.php index 1c05a72..fa71d25 100644 --- a/app/Listeners/AddStatusMessages.php +++ b/app/Listeners/AddStatusMessages.php @@ -7,16 +7,6 @@ use App\Models\Message; class AddStatusMessages { - /** - * Create the event listener. - * - * @return void - */ - public function __construct() - { - // - } - /** * Handle the event. * diff --git a/app/Listeners/SendNotificationMailToTicketCreator.php b/app/Listeners/SendNotificationMailToTicketCreator.php new file mode 100644 index 0000000..b7089bb --- /dev/null +++ b/app/Listeners/SendNotificationMailToTicketCreator.php @@ -0,0 +1,26 @@ +ticket; + Mail::to($ticket->user->email) + ->send(new TicketUpdate($ticket, $event->corpsMaj)); + } +} diff --git a/app/Listeners/SendNotificationMail.php b/app/Listeners/SendSubscriptionsNotificationsMail.php similarity index 54% rename from app/Listeners/SendNotificationMail.php rename to app/Listeners/SendSubscriptionsNotificationsMail.php index fc9531e..00fecff 100644 --- a/app/Listeners/SendNotificationMail.php +++ b/app/Listeners/SendSubscriptionsNotificationsMail.php @@ -4,13 +4,12 @@ namespace App\Listeners; use App\Events\NotifySubscriptions; use App\Mail\TicketUpdate; -use App\Models\User; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Mail; -class SendNotificationMail +class SendSubscriptionsNotificationsMail { /** * Handle the event. @@ -20,9 +19,15 @@ class SendNotificationMail */ public function handle(NotifySubscriptions $event) { + $ignoreConnectedUserEmail = Auth::user()->email ?? ''; + $ignoreUsers = $event->ignoreUsers ?? collect(); foreach ($event->ticket->subscriptions as $sub) { - if (Auth::user() and $sub->email !== Auth::user()->email) { - Mail::to($sub->email)->send(new TicketUpdate($event->ticket, $event->corpsMaj)); + if ( + $sub->email !== $ignoreConnectedUserEmail and + !$ignoreUsers->contains('email', $sub->email) + ) { + Mail::to($sub->email) + ->send(new TicketUpdate($event->ticket, $event->corpsMaj)); } } } diff --git a/app/Models/Message.php b/app/Models/Message.php index bf61f6c..eebe2d1 100644 --- a/app/Models/Message.php +++ b/app/Models/Message.php @@ -2,10 +2,14 @@ namespace App\Models; -use App\Enums\TicketType; +use App\Enums\Role; use App\Events\NotifySubscriptions; +use App\Events\NotifyTicketCreator; +use App\Jobs\SendTicketMentionMail; +use App\Mail\TicketMention; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Http\UploadedFile; class Message extends Model @@ -16,6 +20,65 @@ class Message extends Model 'message' ]; + protected static function booted() + { + static::created(function (Message $message) { + $ticket = $message->ticket; + if ($message->user) { + $ticket->load('user'); + if ($ticket->user !== $message->user) { + event(new NotifyTicketCreator( + $ticket, + trans('Nouvelle réponse de :name :
:message sur votre ticket', [ + 'name' => $message->user->name, + 'message' => $message->message + ]) + )); + } + // find @user + send mail si un seul user est trouvé + $usersNotified = collect([]); + $matches = []; + $ticket->load('project'); + \preg_match_all('/@\w*/', $message->message, $matches); + $matches = collect($matches[0] ?? [])->unique(); + foreach ($matches as $pseudo_usertag) { + try { + $user = User::where('name', 'LIKE', '%' . ltrim($pseudo_usertag, '@') . '%') + ->where('email', '!=', $ticket->user->email) + ->where(function ($q) use ($ticket) { + $q->whereHas('projects', function ($q) use ($ticket) { + $q->where('id', $ticket->project->id); + })->orWhere('role', Role::admin()->value); + })->firstOrFail(); + $usersNotified->add($user); + SendTicketMentionMail::dispatchAfterResponse( + $user, + new TicketMention($ticket, $message->message) + ); + } catch (ModelNotFoundException $e) { + continue; + } + } + + event(new NotifySubscriptions( + $message->ticket, + trans('Nouvelle réponse de :name :
:message', [ + 'name' => $message->user->name, + 'message' => $message->message + ]), + $usersNotified + )); + } else { + event(new NotifyTicketCreator( + $ticket, + trans('Votre ticket : :message', [ + 'message' => $message->message + ]) + )); + } + }); + } + public function ticket() { return $this->belongsTo(Ticket::class, 'ticket_id'); diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 3b8ac12..de9563c 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,13 +2,20 @@ namespace App\Providers; +use App\Events\NotifySubscriptions; +use App\Events\NotifyTicketCreator; +use App\Events\TicketStatusChanged; +use App\Listeners\AddStatusMessages; +use App\Listeners\SendNotificationMail; +use App\Listeners\SendNotificationMailToTicketCreator; +use App\Listeners\SendSubscriptionsNotificationsMail; use Illuminate\Auth\Events\Registered; use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; -use Illuminate\Support\Facades\Event; class EventServiceProvider extends ServiceProvider { + /** * The event listener mappings for the application. * @@ -18,11 +25,14 @@ class EventServiceProvider extends ServiceProvider Registered::class => [ SendEmailVerificationNotification::class, ], - 'App\Events\TicketStatusChanged' => [ - 'App\Listeners\AddStatusMessages', + TicketStatusChanged::class => [ + AddStatusMessages::class ], - 'App\Events\NotifySubscriptions' => [ - 'App\Listeners\SendNotificationMail' + NotifySubscriptions::class => [ + SendSubscriptionsNotificationsMail::class + ], + NotifyTicketCreator::class => [ + SendNotificationMailToTicketCreator::class ], ];