Update for new notifications API, add user activity feed integration

This commit is contained in:
Toby Zerner 2015-05-20 12:32:08 +09:30
parent ee7044615b
commit 360b503357
8 changed files with 196 additions and 75 deletions

View File

@ -1,7 +1,10 @@
<?php namespace Flarum\Mentions\Handlers;
use Flarum\Mentions\PostMentionsParser;
use Flarum\Mentions\PostMentionedActivity;
use Flarum\Mentions\PostMentionedNotification;
use Flarum\Core\Activity\ActivitySyncer;
use Flarum\Core\Notifications\NotificationSyncer;
use Flarum\Core\Events\PostWasPosted;
use Flarum\Core\Events\PostWasRevised;
use Flarum\Core\Events\PostWasDeleted;
@ -13,53 +16,77 @@ class PostMentionsMetadataUpdater
{
protected $parser;
protected $notifier;
protected $activity;
public function __construct(PostMentionsParser $parser, Notifier $notifier)
protected $notifications;
public function __construct(PostMentionsParser $parser, ActivitySyncer $activity, NotificationSyncer $notifications)
{
$this->parser = $parser;
$this->notifier = $notifier;
$this->activity = $activity;
$this->notifications = $notifications;
}
public function subscribe(Dispatcher $events)
{
$events->listen('Flarum\Core\Events\PostWasPosted', __CLASS__.'@whenPostWasPosted');
$events->listen('Flarum\Core\Events\PostWasRevised', __CLASS__.'@whenPostWasRevised');
$events->listen('Flarum\Core\Events\PostWasHidden', __CLASS__.'@whenPostWasHidden');
$events->listen('Flarum\Core\Events\PostWasRestored', __CLASS__.'@whenPostWasRestored');
$events->listen('Flarum\Core\Events\PostWasDeleted', __CLASS__.'@whenPostWasDeleted');
}
public function whenPostWasPosted(PostWasPosted $event)
{
$reply = $event->post;
$mentioned = $this->syncMentions($reply);
// @todo convert this into a new event (PostWasMentioned) and send
// notification as a handler?
foreach ($mentioned as $post) {
if ($post->user->id !== $reply->user->id) {
$this->notifier->send(new PostMentionedNotification($post, $reply->user, $reply), [$post->user]);
}
}
$this->replyBecameVisible($event->post);
}
public function whenPostWasRevised(PostWasRevised $event)
{
$this->syncMentions($event->post);
$this->replyBecameVisible($event->post);
}
public function whenPostWasHidden(PostWasHidden $event)
{
$this->replyBecameInvisible($event->post);
}
public function whenPostWasRestored(PostWasRestored $event)
{
$this->replyBecameVisible($event->post);
}
public function whenPostWasDeleted(PostWasDeleted $event)
{
$event->post->mentionsPosts()->sync([]);
$this->replyBecameInvisible($event->post);
}
protected function syncMentions(Post $reply)
protected function replyBecameVisible(Post $reply)
{
$matches = $this->parser->match($reply->content);
$mentioned = $reply->discussion->posts()->with('user')->whereIn('number', array_filter($matches['number']))->get();
$reply->mentionsPosts()->sync($mentioned->lists('id'));
$mentioned = $reply->discussion->posts()->with('user')->whereIn('number', array_filter($matches['number']))->get()->all();
return $mentioned;
$this->sync($reply, $mentioned);
}
protected function replyBecameInvisible(Post $reply)
{
$this->sync($reply, []);
}
protected function sync(Post $reply, array $mentioned)
{
$reply->mentionsPosts()->sync(array_pluck($mentioned, 'id'));
$mentioned = array_filter($mentioned, function ($post) use ($reply) {
return $post->user->id !== $reply->user->id;
});
foreach ($mentioned as $post) {
$this->activity->sync(new PostMentionedActivity($post, $reply), [$post->user]);
$this->notifications->sync(new PostMentionedNotification($post, $reply), [$post->user]);
}
}
}

View File

@ -1,66 +1,92 @@
<?php namespace Flarum\Mentions\Handlers;
use Flarum\Mentions\UserMentionsParser;
use Flarum\Mentions\UserMentionedActivity;
use Flarum\Mentions\UserMentionedNotification;
use Flarum\Core\Activity\ActivitySyncer;
use Flarum\Core\Notifications\NotificationSyncer;
use Flarum\Core\Events\PostWasPosted;
use Flarum\Core\Events\PostWasRevised;
use Flarum\Core\Events\PostWasDeleted;
use Flarum\Core\Events\PostWasHidden;
use Flarum\Core\Events\PostWasRestored;
use Flarum\Core\Models\Post;
use Flarum\Core\Models\User;
use Flarum\Core\Notifications\Notifier;
use Illuminate\Contracts\Events\Dispatcher;
class UserMentionsMetadataUpdater
{
protected $parser;
protected $notifier;
protected $activity;
public function __construct(UserMentionsParser $parser, Notifier $notifier)
protected $notifications;
public function __construct(UserMentionsParser $parser, ActivitySyncer $activity, NotificationSyncer $notifications)
{
$this->parser = $parser;
$this->notifier = $notifier;
$this->activity = $activity;
$this->notifications = $notifications;
}
public function subscribe(Dispatcher $events)
{
$events->listen('Flarum\Core\Events\PostWasPosted', __CLASS__.'@whenPostWasPosted');
$events->listen('Flarum\Core\Events\PostWasRevised', __CLASS__.'@whenPostWasRevised');
$events->listen('Flarum\Core\Events\PostWasHidden', __CLASS__.'@whenPostWasHidden');
$events->listen('Flarum\Core\Events\PostWasRestored', __CLASS__.'@whenPostWasRestored');
$events->listen('Flarum\Core\Events\PostWasDeleted', __CLASS__.'@whenPostWasDeleted');
}
public function whenPostWasPosted(PostWasPosted $event)
{
$post = $event->post;
$mentioned = $this->syncMentions($post);
// @todo convert this into a new event (UserWasMentioned) and send
// notification as a handler?
foreach ($mentioned as $user) {
if ($user->id !== $post->user->id) {
$this->notifier->send(new UserMentionedNotification($post->user, $post), [$user]);
}
}
$this->postBecameVisible($event->post);
}
public function whenPostWasRevised(PostWasRevised $event)
{
$this->syncMentions($event->post);
$this->postBecameVisible($event->post);
}
public function whenPostWasHidden(PostWasHidden $event)
{
$this->postBecameInvisible($event->post);
}
public function whenPostWasRestored(PostWasRestored $event)
{
$this->postBecameVisible($event->post);
}
public function whenPostWasDeleted(PostWasDeleted $event)
{
$event->post->mentionsUsers()->sync([]);
$this->postBecameInvisible($event->post);
}
public function syncMentions(Post $post)
protected function postBecameVisible(Post $post)
{
$matches = $this->parser->match($post->content);
$mentioned = User::whereIn('username', array_filter($matches['username']))->get();
$post->mentionsUsers()->sync($mentioned);
$mentioned = User::whereIn('username', array_filter($matches['username']))->get()->all();
return $mentioned;
$this->sync($post, $mentioned);
}
protected function postBecameInvisible(Post $post)
{
$this->sync($post, []);
}
protected function sync(Post $post, array $mentioned)
{
$post->mentionsUsers()->sync(array_pluck($mentioned, 'id'));
$mentioned = array_filter($mentioned, function ($user) use ($post) {
return $user->id !== $post->user->id;
});
$this->activity->sync(new UserMentionedActivity($post), $mentioned);
$this->notifications->sync(new UserMentionedNotification($post), $mentioned);
}
}

View File

@ -8,6 +8,7 @@ use Flarum\Extend\SerializeRelationship;
use Flarum\Extend\ApiInclude;
use Flarum\Extend\Formatter;
use Flarum\Extend\NotificationType;
use Flarum\Extend\ActivityType;
class MentionsServiceProvider extends ServiceProvider
{
@ -54,9 +55,15 @@ class MentionsServiceProvider extends ServiceProvider
new Formatter('userMentions', 'Flarum\Mentions\UserMentionsFormatter'),
(new NotificationType('Flarum\Mentions\PostMentionedNotification'))->enableByDefault('alert'),
new ActivityType('Flarum\Mentions\PostMentionedActivity', 'Flarum\Api\Serializers\PostBasicSerializer'),
(new NotificationType('Flarum\Mentions\UserMentionedNotification'))->enableByDefault('alert')
new ActivityType('Flarum\Mentions\UserMentionedActivity', 'Flarum\Api\Serializers\PostBasicSerializer'),
(new NotificationType('Flarum\Mentions\PostMentionedNotification', 'Flarum\Api\Serializers\PostBasicSerializer'))
->enableByDefault('alert'),
(new NotificationType('Flarum\Mentions\UserMentionedNotification', 'Flarum\Api\Serializers\PostBasicSerializer'))
->enableByDefault('alert')
);
}
}

View File

@ -0,0 +1,37 @@
<?php namespace Flarum\Mentions;
use Flarum\Core\Models\Post;
use Flarum\Core\Activity\ActivityAbstract;
class PostMentionedActivity extends ActivityAbstract
{
public $post;
public $reply;
public function __construct(Post $post, Post $reply)
{
$this->post = $post;
$this->reply = $reply;
}
public function getSubject()
{
return $this->reply;
}
public function getTime()
{
return $this->reply->time;
}
public static function getType()
{
return 'postMentioned';
}
public static function getSubjectModel()
{
return 'Flarum\Core\Models\Post';
}
}

View File

@ -1,25 +1,17 @@
<?php namespace Flarum\Mentions;
use Flarum\Core\Models\User;
use Flarum\Core\Models\Post;
use Flarum\Core\Notifications\Types\Notification;
use Flarum\Core\Notifications\Types\AlertableNotification;
use Flarum\Core\Notifications\Types\EmailableNotification;
use Flarum\Core\Notifications\NotificationAbstract;
class PostMentionedNotification extends Notification implements
AlertableNotification,
EmailableNotification
class PostMentionedNotification extends NotificationAbstract
{
public $post;
public $sender;
public $reply;
public function __construct(Post $post, User $sender, Post $reply)
public function __construct(Post $post, Post $reply)
{
$this->post = $post;
$this->sender = $sender;
$this->reply = $reply;
}
@ -30,10 +22,10 @@ class PostMentionedNotification extends Notification implements
public function getSender()
{
return $this->sender;
return $this->reply->user;
}
public function getAlertData()
public function getData()
{
return ['replyNumber' => $this->reply->number];
}
@ -45,7 +37,7 @@ class PostMentionedNotification extends Notification implements
public function getEmailSubject()
{
return "{$this->sender->username} replied to your post in {$this->post->discussion->title}";
return "{$this->reply->user->username} replied to your post in {$this->post->discussion->title}";
}
public static function getType()
@ -57,4 +49,9 @@ class PostMentionedNotification extends Notification implements
{
return 'Flarum\Core\Models\Post';
}
public static function isEmailable()
{
return true;
}
}

View File

@ -0,0 +1,34 @@
<?php namespace Flarum\Mentions;
use Flarum\Core\Models\Post;
use Flarum\Core\Activity\ActivityAbstract;
class UserMentionedActivity extends ActivityAbstract
{
public $post;
public function __construct(Post $post)
{
$this->post = $post;
}
public function getSubject()
{
return $this->post;
}
public function getTime()
{
return $this->post->time;
}
public static function getType()
{
return 'userMentioned';
}
public static function getSubjectModel()
{
return 'Flarum\Core\Models\Post';
}
}

View File

@ -2,21 +2,14 @@
use Flarum\Core\Models\User;
use Flarum\Core\Models\Post;
use Flarum\Core\Notifications\Types\Notification;
use Flarum\Core\Notifications\Types\AlertableNotification;
use Flarum\Core\Notifications\Types\EmailableNotification;
use Flarum\Core\Notifications\NotificationAbstract;
class UserMentionedNotification extends Notification implements
AlertableNotification,
EmailableNotification
class UserMentionedNotification extends NotificationAbstract
{
public $sender;
public $post;
public function __construct(User $sender, Post $post)
public function __construct(Post $post)
{
$this->sender = $sender;
$this->post = $post;
}
@ -27,12 +20,7 @@ class UserMentionedNotification extends Notification implements
public function getSender()
{
return $this->sender;
}
public function getAlertData()
{
return null;
return $this->post->user;
}
public function getEmailView()
@ -42,7 +30,7 @@ class UserMentionedNotification extends Notification implements
public function getEmailSubject()
{
return "{$this->sender->username} mentioned you in {$this->post->discussion->title}";
return "{$this->post->user->username} mentioned you in {$this->post->discussion->title}";
}
public static function getType()
@ -54,4 +42,9 @@ class UserMentionedNotification extends Notification implements
{
return 'Flarum\Core\Models\Post';
}
public static function isEmailable()
{
return true;
}
}

View File

@ -1,6 +1,6 @@
Hey {{ $user->username }}!
{{ $notification->sender->username }} mentioned you in a post in {{ $notification->post->discussion->title }}.
{{ $notification->post->user->username }} mentioned you in a post in {{ $notification->post->discussion->title }}.
{{ \Flarum\Core::config('base_url') }}/d/{{ $notification->post->discussion_id }}/-/{{ $notification->post->number }}