Permalink
Browse files

Episode 57

  • Loading branch information...
JeffreyWay committed Jul 6, 2017
1 parent a8eb9d1 commit 66fc118d8d3a66f9927a8f19befc5a9017c5e335
@@ -0,0 +1,23 @@
<?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class ThreadReceivedNewReply
{
use Dispatchable, SerializesModels;
public $reply;
/**
* Create a new event instance.
*
* @param $reply
*/
public function __construct($reply)
{
$this->reply = $reply;
}
}
@@ -0,0 +1,28 @@
<?php
namespace App\Listeners;
use App\Events\ThreadReceivedNewReply;
use App\Notifications\YouWereMentioned;
use App\User;
class NotifyMentionedUsers
{
/**
* Handle the event.
*
* @param ThreadReceivedNewReply $event
* @return void
*/
public function handle(ThreadReceivedNewReply $event)
{
collect($event->reply->mentionedUsers())
->map(function ($name) {
return User::where('name', $name)->first();
})
->filter()
->each(function ($user) use ($event) {
$user->notify(new YouWereMentioned($event->reply));
});
}
}
@@ -0,0 +1,24 @@
<?php
namespace App\Listeners;
use App\Events\ThreadReceivedNewReply;
class NotifySubscribers
{
/**
* Handle the event.
*
* @param ThreadReceivedNewReply $event
* @return void
*/
public function handle(ThreadReceivedNewReply $event)
{
$thread = $event->reply->thread;
$thread->subscriptions
->where('user_id', '!=', $event->reply->user_id)
->each
->notify($event->reply);
}
}
@@ -0,0 +1,51 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
class YouWereMentioned extends Notification
{
use Queueable;
/**
* @var \App\Reply
*/
protected $reply;
/**
* Create a new notification instance.
*
* @param \App\Reply $reply
*/
public function __construct($reply)
{
$this->reply = $reply;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['database'];
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
'message' => $this->reply->owner->name . ' mentioned you in ' . $this->reply->thread->title,
'link' => $this->reply->path()
];
}
}
@@ -2,7 +2,6 @@
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
@@ -13,8 +12,9 @@ class EventServiceProvider extends ServiceProvider
* @var array
*/
protected $listen = [
'App\Events\SomeEvent' => [
'App\Listeners\EventListener',
'App\Events\ThreadReceivedNewReply' => [
'App\Listeners\NotifyMentionedUsers',
'App\Listeners\NotifySubscribers'
],
];
@@ -76,6 +76,18 @@ public function wasJustPublished()
return $this->created_at->gt(Carbon::now()->subMinute());
}
/**
* Fetch all mentioned users within the reply's body.
*
* @return array
*/
public function mentionedUsers()
{
preg_match_all('/\@([^\s\.]+)/', $this->body, $matches);
return $matches[1];
}
/**
* Determine the path to the reply.
*
@@ -2,6 +2,7 @@
namespace App;
use App\Events\ThreadReceivedNewReply;
use App\Filters\ThreadFilters;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
@@ -93,24 +94,11 @@ public function addReply($reply)
{
$reply = $this->replies()->create($reply);
$this->notifySubscribers($reply);
event(new ThreadReceivedNewReply($reply));
return $reply;
}
/**
* Notify all thread subscribers about a new reply.
*
* @param \App\Reply $reply
*/
public function notifySubscribers($reply)
{
$this->subscriptions
->where('user_id', '!=', $reply->user_id)
->each
->notify($reply);
}
/**
* Apply all relevant thread filters.
*
@@ -0,0 +1,36 @@
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Tests\TestCase;
class MentionUsersTest extends TestCase
{
use DatabaseMigrations;
/** @test */
function mentioned_users_in_a_reply_are_notified()
{
// Given we have a user, JohnDoe, who is signed in.
$john = create('App\User', ['name' => 'JohnDoe']);
$this->signIn($john);
// And we also have a user, JaneDoe.
$jane = create('App\User', ['name' => 'JaneDoe']);
// If we have a thread
$thread = create('App\Thread');
// And JohnDoe replies to that thread and mentions @JaneDoe.
$reply = make('App\Reply', [
'body' => 'Hey @JaneDoe check this out.'
]);
$this->json('post', $thread->path() . '/replies', $reply->toArray());
// Then @JaneDoe should receive a notification.
$this->assertCount(1, $jane->notifications);
}
}
@@ -29,4 +29,14 @@ function it_knows_if_it_was_just_published()
$this->assertFalse($reply->wasJustPublished());
}
/** @test */
function it_can_detect_all_mentioned_users_in_the_body()
{
$reply = create('App\Reply', [
'body' => '@JaneDoe wants to talk to @JohnDoe'
]);
$this->assertEquals(['JaneDoe', 'JohnDoe'], $reply->mentionedUsers());
}
}

0 comments on commit 66fc118

Please sign in to comment.