mirror of
https://github.com/flarum/core.git
synced 2025-08-15 12:54:47 +02:00
Update for new API + TextFormatter
This commit is contained in:
18
extensions/mentions/src/Extension.php
Normal file
18
extensions/mentions/src/Extension.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
|
||||
use Flarum\Support\Extension as BaseExtension;
|
||||
use Illuminate\Events\Dispatcher;
|
||||
|
||||
class Extension extends BaseExtension
|
||||
{
|
||||
public function boot(Dispatcher $events)
|
||||
{
|
||||
$events->subscribe('Flarum\Mentions\Listeners\AddClientAssets');
|
||||
$events->subscribe('Flarum\Mentions\Listeners\AddModelRelationships');
|
||||
$events->subscribe('Flarum\Mentions\Listeners\AddApiRelationships');
|
||||
$events->subscribe('Flarum\Mentions\Listeners\AddUserMentionsFormatter');
|
||||
$events->subscribe('Flarum\Mentions\Listeners\AddPostMentionsFormatter');
|
||||
$events->subscribe('Flarum\Mentions\Listeners\UpdateUserMentionsMetadata');
|
||||
$events->subscribe('Flarum\Mentions\Listeners\UpdatePostMentionsMetadata');
|
||||
}
|
||||
}
|
@@ -1,94 +0,0 @@
|
||||
<?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\PostWasHidden;
|
||||
use Flarum\Core\Events\PostWasRestored;
|
||||
use Flarum\Core\Events\PostWasDeleted;
|
||||
use Flarum\Core\Models\Post;
|
||||
use Flarum\Core\Notifications\Notifier;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class PostMentionsMetadataUpdater
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected $activity;
|
||||
|
||||
protected $notifications;
|
||||
|
||||
public function __construct(PostMentionsParser $parser, ActivitySyncer $activity, NotificationSyncer $notifications)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
$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)
|
||||
{
|
||||
$this->replyBecameVisible($event->post);
|
||||
}
|
||||
|
||||
public function whenPostWasRevised(PostWasRevised $event)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
$this->replyBecameInvisible($event->post);
|
||||
}
|
||||
|
||||
protected function replyBecameVisible(Post $reply)
|
||||
{
|
||||
$matches = $this->parser->match($reply->content);
|
||||
|
||||
$mentioned = $reply->discussion->posts()->with('user')->whereIn('number', array_filter($matches['number']))->get()->all();
|
||||
|
||||
$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]);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,92 +0,0 @@
|
||||
<?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 Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class UserMentionsMetadataUpdater
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
protected $activity;
|
||||
|
||||
protected $notifications;
|
||||
|
||||
public function __construct(UserMentionsParser $parser, ActivitySyncer $activity, NotificationSyncer $notifications)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
$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)
|
||||
{
|
||||
$this->postBecameVisible($event->post);
|
||||
}
|
||||
|
||||
public function whenPostWasRevised(PostWasRevised $event)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
$this->postBecameInvisible($event->post);
|
||||
}
|
||||
|
||||
protected function postBecameVisible(Post $post)
|
||||
{
|
||||
$matches = $this->parser->match($post->content);
|
||||
|
||||
$mentioned = User::whereIn('username', array_filter($matches['username']))->get()->all();
|
||||
|
||||
$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);
|
||||
}
|
||||
}
|
55
extensions/mentions/src/Listeners/AddApiRelationships.php
Executable file
55
extensions/mentions/src/Listeners/AddApiRelationships.php
Executable file
@@ -0,0 +1,55 @@
|
||||
<?php namespace Flarum\Mentions\Listeners;
|
||||
|
||||
use Flarum\Events\ApiRelationship;
|
||||
use Flarum\Events\BuildApiAction;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Flarum\Api\Serializers\PostBasicSerializer;
|
||||
use Flarum\Api\Actions\Discussions;
|
||||
use Flarum\Api\Actions\Posts;
|
||||
|
||||
class AddApiRelationships
|
||||
{
|
||||
public function subscribe(Dispatcher $events)
|
||||
{
|
||||
$events->listen(ApiRelationship::class, __CLASS__.'@addRelationships');
|
||||
$events->listen(BuildApiAction::class, __CLASS__.'@includeRelationships');
|
||||
}
|
||||
|
||||
public function addRelationships(ApiRelationship $event)
|
||||
{
|
||||
if ($event->serializer instanceof PostBasicSerializer) {
|
||||
if ($event->relationship === 'mentionedBy') {
|
||||
return $event->serializer->hasMany('Flarum\Api\Serializers\PostBasicSerializer', 'mentionedBy');
|
||||
}
|
||||
|
||||
if ($event->relationship === 'mentionsPosts') {
|
||||
return $event->serializer->hasMany('Flarum\Api\Serializers\PostBasicSerializer', 'mentionsPosts');
|
||||
}
|
||||
|
||||
if ($event->relationship === 'mentionsUsers') {
|
||||
return $event->serializer->hasMany('Flarum\Api\Serializers\PostBasicSerializer', 'mentionsUsers');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function includeRelationships(BuildApiAction $event)
|
||||
{
|
||||
if ($event->action instanceof Discussions\ShowAction) {
|
||||
$event->addInclude('posts.mentionedBy');
|
||||
$event->addInclude('posts.mentionedBy.user');
|
||||
$event->addLink('posts.mentionedBy.discussion');
|
||||
}
|
||||
|
||||
if ($event->action instanceof Posts\ShowAction ||
|
||||
$event->action instanceof Posts\IndexAction) {
|
||||
$event->addInclude('mentionedBy');
|
||||
$event->addInclude('mentionedBy.user');
|
||||
$event->addLink('mentionedBy.discussion');
|
||||
}
|
||||
|
||||
if ($event->action instanceof Posts\CreateAction) {
|
||||
$event->addInclude('mentionsPosts');
|
||||
$event->addInclude('mentionsPosts.mentionedBy');
|
||||
}
|
||||
}
|
||||
}
|
39
extensions/mentions/src/Listeners/AddClientAssets.php
Executable file
39
extensions/mentions/src/Listeners/AddClientAssets.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php namespace Flarum\Mentions\Listeners;
|
||||
|
||||
use Flarum\Events\RegisterLocales;
|
||||
use Flarum\Events\BuildClientView;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
|
||||
class AddClientAssets
|
||||
{
|
||||
public function subscribe(Dispatcher $events)
|
||||
{
|
||||
$events->listen(RegisterLocales::class, __CLASS__.'@addLocale');
|
||||
$events->listen(BuildClientView::class, __CLASS__.'@addAssets');
|
||||
}
|
||||
|
||||
public function addLocale(RegisterLocales $event)
|
||||
{
|
||||
$event->addTranslations('en', __DIR__.'/../../locale/en.yml');
|
||||
}
|
||||
|
||||
public function addAssets(BuildClientView $event)
|
||||
{
|
||||
$event->forumAssets([
|
||||
__DIR__.'/../../js/forum/dist/extension.js',
|
||||
__DIR__.'/../../less/forum/extension.less'
|
||||
]);
|
||||
|
||||
$event->forumBootstrapper('mentions/main');
|
||||
|
||||
$event->forumTranslations([
|
||||
'mentions.reply_to_post',
|
||||
'mentions.post_mentioned_notification',
|
||||
'mentions.others',
|
||||
'mentions.user_mentioned_notification',
|
||||
'mentions.post_mentioned_by',
|
||||
'mentions.you',
|
||||
'mentions.reply_link'
|
||||
]);
|
||||
}
|
||||
}
|
30
extensions/mentions/src/Listeners/AddModelRelationships.php
Executable file
30
extensions/mentions/src/Listeners/AddModelRelationships.php
Executable file
@@ -0,0 +1,30 @@
|
||||
<?php namespace Flarum\Mentions\Listeners;
|
||||
|
||||
use Flarum\Events\ModelRelationship;
|
||||
use Flarum\Core\Posts\Post;
|
||||
use Flarum\Core\Users\User;
|
||||
|
||||
class AddModelRelationships
|
||||
{
|
||||
public function subscribe($events)
|
||||
{
|
||||
$events->listen(ModelRelationship::class, __CLASS__.'@addRelationships');
|
||||
}
|
||||
|
||||
public function addRelationships(ModelRelationship $event)
|
||||
{
|
||||
if ($event->model instanceof Post) {
|
||||
if ($event->relationship === 'mentionedBy') {
|
||||
return $event->model->belongsToMany(Post::class, 'mentions_posts', 'mentions_id', 'post_id', 'mentionedBy');
|
||||
}
|
||||
|
||||
if ($event->relationship === 'mentionsPosts') {
|
||||
return $event->model->belongsToMany(Post::class, 'mentions_posts', 'post_id', 'mentions_id', 'mentionsPosts');
|
||||
}
|
||||
|
||||
if ($event->relationship === 'mentionsUsers') {
|
||||
return $event->model->belongsToMany(User::class, 'mentions_users', 'post_id', 'mentions_id', 'mentionsUsers');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
47
extensions/mentions/src/Listeners/AddPostMentionsFormatter.php
Executable file
47
extensions/mentions/src/Listeners/AddPostMentionsFormatter.php
Executable file
@@ -0,0 +1,47 @@
|
||||
<?php namespace Flarum\Mentions\Listeners;
|
||||
|
||||
use Flarum\Events\FormatterConfigurator;
|
||||
use Flarum\Events\FormatterRenderer;
|
||||
use Flarum\Core\Posts\CommentPost;
|
||||
|
||||
class AddPostMentionsFormatter
|
||||
{
|
||||
public function subscribe($events)
|
||||
{
|
||||
$events->listen(FormatterConfigurator::class, __CLASS__.'@configure');
|
||||
$events->listen(FormatterRenderer::class, __CLASS__.'@render');
|
||||
}
|
||||
|
||||
public function configure(FormatterConfigurator $event)
|
||||
{
|
||||
$configurator = $event->configurator;
|
||||
|
||||
$tagName = 'POSTMENTION';
|
||||
|
||||
$tag = $configurator->tags->add($tagName);
|
||||
$tag->attributes->add('username');
|
||||
$tag->attributes->add('number');
|
||||
$tag->attributes->add('id')->filterChain->append('#uint');
|
||||
$tag->template = '<a href="{$DISCUSSION_URL}{@number}" class="PostMention" data-number="{@number}"><xsl:value-of select="@username"/></a>';
|
||||
$tag->filterChain->prepend([static::class, 'addId'])->addParameterByName('post');
|
||||
|
||||
$configurator->Preg->match('/\B@(?<username>[a-z0-9_-]+)#(?<number>\d+)/i', $tagName);
|
||||
}
|
||||
|
||||
public function render(FormatterRenderer $event)
|
||||
{
|
||||
// TODO: use URL generator
|
||||
$event->renderer->setParameter('DISCUSSION_URL', '/d/' . $event->post->discussion_id . '/-/');
|
||||
}
|
||||
|
||||
public static function addId($tag, CommentPost $post)
|
||||
{
|
||||
$id = CommentPost::where('discussion_id', $post->discussion_id)
|
||||
->where('number', $tag->getAttribute('number'))
|
||||
->pluck('id');
|
||||
|
||||
$tag->setAttribute('id', $id);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
56
extensions/mentions/src/Listeners/AddUserMentionsFormatter.php
Executable file
56
extensions/mentions/src/Listeners/AddUserMentionsFormatter.php
Executable file
@@ -0,0 +1,56 @@
|
||||
<?php namespace Flarum\Mentions\Listeners;
|
||||
|
||||
use Flarum\Events\FormatterConfigurator;
|
||||
use Flarum\Events\FormatterRenderer;
|
||||
use Flarum\Events\FormatterParser;
|
||||
use Flarum\Core\Users\UserRepository;
|
||||
|
||||
class AddUserMentionsFormatter
|
||||
{
|
||||
protected $users;
|
||||
|
||||
public function __construct(UserRepository $users)
|
||||
{
|
||||
$this->users = $users;
|
||||
}
|
||||
|
||||
public function subscribe($events)
|
||||
{
|
||||
$events->listen(FormatterConfigurator::class, __CLASS__.'@configure');
|
||||
$events->listen(FormatterParser::class, __CLASS__.'@parse');
|
||||
$events->listen(FormatterRenderer::class, __CLASS__.'@render');
|
||||
}
|
||||
|
||||
public function configure(FormatterConfigurator $event)
|
||||
{
|
||||
$configurator = $event->configurator;
|
||||
|
||||
$tagName = 'USERMENTION';
|
||||
|
||||
$tag = $configurator->tags->add($tagName);
|
||||
$tag->attributes->add('username');
|
||||
$tag->attributes->add('id')->filterChain->append('#uint');
|
||||
$tag->template = '<a href="{$PROFILE_URL}{@username}" class="UserMention">@<xsl:value-of select="@username"/></a>';
|
||||
$tag->filterChain->prepend([static::class, 'addId'])->addParameterByName('userRepository');
|
||||
|
||||
$configurator->Preg->match('/\B@(?<username>[a-z0-9_-]+)(?!#)/i', $tagName);
|
||||
}
|
||||
|
||||
public function parse(FormatterParser $event)
|
||||
{
|
||||
$event->parser->registeredVars['userRepository'] = $this->users;
|
||||
}
|
||||
|
||||
public function render(FormatterRenderer $event)
|
||||
{
|
||||
// TODO: use URL generator
|
||||
$event->renderer->setParameter('PROFILE_URL', '/u/');
|
||||
}
|
||||
|
||||
public static function addId($tag, UserRepository $users)
|
||||
{
|
||||
$tag->setAttribute('id', $users->getIdForUsername($tag->getAttribute('username')));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
97
extensions/mentions/src/Listeners/UpdatePostMentionsMetadata.php
Executable file
97
extensions/mentions/src/Listeners/UpdatePostMentionsMetadata.php
Executable file
@@ -0,0 +1,97 @@
|
||||
<?php namespace Flarum\Mentions\Listeners;
|
||||
|
||||
use Flarum\Mentions\Notifications\PostMentionedBlueprint;
|
||||
use Flarum\Core\Notifications\NotificationSyncer;
|
||||
use Flarum\Events\RegisterNotificationTypes;
|
||||
use Flarum\Events\PostWasPosted;
|
||||
use Flarum\Events\PostWasRevised;
|
||||
use Flarum\Events\PostWasHidden;
|
||||
use Flarum\Events\PostWasRestored;
|
||||
use Flarum\Events\PostWasDeleted;
|
||||
use Flarum\Core\Posts\Post;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use s9e\TextFormatter\Utils;
|
||||
|
||||
class UpdatePostMentionsMetadata
|
||||
{
|
||||
protected $notifications;
|
||||
|
||||
public function __construct(NotificationSyncer $notifications)
|
||||
{
|
||||
$this->notifications = $notifications;
|
||||
}
|
||||
|
||||
public function subscribe(Dispatcher $events)
|
||||
{
|
||||
$events->listen(RegisterNotificationTypes::class, __CLASS__.'@registerNotificationType');
|
||||
|
||||
$events->listen(PostWasPosted::class, __CLASS__.'@whenPostWasPosted');
|
||||
$events->listen(PostWasRevised::class, __CLASS__.'@whenPostWasRevised');
|
||||
$events->listen(PostWasHidden::class, __CLASS__.'@whenPostWasHidden');
|
||||
$events->listen(PostWasRestored::class, __CLASS__.'@whenPostWasRestored');
|
||||
$events->listen(PostWasDeleted::class, __CLASS__.'@whenPostWasDeleted');
|
||||
}
|
||||
|
||||
public function registerNotificationType(RegisterNotificationTypes $event)
|
||||
{
|
||||
$event->register(
|
||||
PostMentionedBlueprint::class,
|
||||
'Flarum\Api\Serializers\PostBasicSerializer',
|
||||
['alert']
|
||||
);
|
||||
}
|
||||
|
||||
public function whenPostWasPosted(PostWasPosted $event)
|
||||
{
|
||||
$this->replyBecameVisible($event->post);
|
||||
}
|
||||
|
||||
public function whenPostWasRevised(PostWasRevised $event)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
$this->replyBecameInvisible($event->post);
|
||||
}
|
||||
|
||||
protected function replyBecameVisible(Post $reply)
|
||||
{
|
||||
$mentioned = Utils::getAttributeValues($reply->parsedContent, 'POSTMENTION', 'id');
|
||||
|
||||
$this->sync($reply, $mentioned);
|
||||
}
|
||||
|
||||
protected function replyBecameInvisible(Post $reply)
|
||||
{
|
||||
$this->sync($reply, []);
|
||||
}
|
||||
|
||||
protected function sync(Post $reply, array $mentioned)
|
||||
{
|
||||
$reply->mentionsPosts()->sync($mentioned);
|
||||
|
||||
$posts = Post::with('user')
|
||||
->whereIn('id', $mentioned)
|
||||
->get()
|
||||
->filter(function ($post) use ($reply) {
|
||||
return $post->user->id !== $reply->user->id;
|
||||
})
|
||||
->all();
|
||||
|
||||
foreach ($posts as $post) {
|
||||
$this->notifications->sync(new PostMentionedBlueprint($post, $reply), [$post->user]);
|
||||
}
|
||||
}
|
||||
}
|
95
extensions/mentions/src/Listeners/UpdateUserMentionsMetadata.php
Executable file
95
extensions/mentions/src/Listeners/UpdateUserMentionsMetadata.php
Executable file
@@ -0,0 +1,95 @@
|
||||
<?php namespace Flarum\Mentions\Listeners;
|
||||
|
||||
use Flarum\Mentions\Notifications\UserMentionedBlueprint;
|
||||
use Flarum\Core\Notifications\NotificationSyncer;
|
||||
use Flarum\Events\RegisterNotificationTypes;
|
||||
use Flarum\Events\PostWasPosted;
|
||||
use Flarum\Events\PostWasRevised;
|
||||
use Flarum\Events\PostWasHidden;
|
||||
use Flarum\Events\PostWasRestored;
|
||||
use Flarum\Events\PostWasDeleted;
|
||||
use Flarum\Core\Posts\Post;
|
||||
use Flarum\Core\Users\User;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use s9e\TextFormatter\Utils;
|
||||
|
||||
class UpdateUserMentionsMetadata
|
||||
{
|
||||
protected $notifications;
|
||||
|
||||
public function __construct(NotificationSyncer $notifications)
|
||||
{
|
||||
$this->notifications = $notifications;
|
||||
}
|
||||
|
||||
public function subscribe(Dispatcher $events)
|
||||
{
|
||||
$events->listen(RegisterNotificationTypes::class, __CLASS__.'@registerNotificationType');
|
||||
|
||||
$events->listen(PostWasPosted::class, __CLASS__.'@whenPostWasPosted');
|
||||
$events->listen(PostWasRevised::class, __CLASS__.'@whenPostWasRevised');
|
||||
$events->listen(PostWasHidden::class, __CLASS__.'@whenPostWasHidden');
|
||||
$events->listen(PostWasRestored::class, __CLASS__.'@whenPostWasRestored');
|
||||
$events->listen(PostWasDeleted::class, __CLASS__.'@whenPostWasDeleted');
|
||||
}
|
||||
|
||||
public function registerNotificationType(RegisterNotificationTypes $event)
|
||||
{
|
||||
$event->register(
|
||||
UserMentionedBlueprint::class,
|
||||
'Flarum\Api\Serializers\PostBasicSerializer',
|
||||
['alert']
|
||||
);
|
||||
}
|
||||
|
||||
public function whenPostWasPosted(PostWasPosted $event)
|
||||
{
|
||||
$this->postBecameVisible($event->post);
|
||||
}
|
||||
|
||||
public function whenPostWasRevised(PostWasRevised $event)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
$this->postBecameInvisible($event->post);
|
||||
}
|
||||
|
||||
protected function postBecameVisible(Post $post)
|
||||
{
|
||||
$mentioned = Utils::getAttributeValues($post->parsedContent, 'USERMENTION', 'id');
|
||||
|
||||
$this->sync($post, $mentioned);
|
||||
}
|
||||
|
||||
protected function postBecameInvisible(Post $post)
|
||||
{
|
||||
$this->sync($post, []);
|
||||
}
|
||||
|
||||
protected function sync(Post $post, array $mentioned)
|
||||
{
|
||||
$post->mentionsUsers()->sync($mentioned);
|
||||
|
||||
$users = User::whereIn('id', $mentioned)
|
||||
->get()
|
||||
->filter(function ($user) use ($post) {
|
||||
return $user->id !== $post->user->id;
|
||||
})
|
||||
->all();
|
||||
|
||||
$this->notifications->sync(new UserMentionedBlueprint($post), $users);
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
|
||||
abstract class MentionsParserAbstract
|
||||
{
|
||||
protected $pattern;
|
||||
|
||||
public function match($string)
|
||||
{
|
||||
preg_match_all($this->pattern, $string, $matches);
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
public function replace($string, $callback)
|
||||
{
|
||||
return preg_replace_callback($this->pattern, function ($matches) use ($callback) {
|
||||
return $callback($matches);
|
||||
}, $string);
|
||||
}
|
||||
}
|
@@ -1,69 +0,0 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
|
||||
use Flarum\Support\ServiceProvider;
|
||||
use Flarum\Extend;
|
||||
|
||||
class MentionsServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot()
|
||||
{
|
||||
$this->loadViewsFrom(__DIR__.'/../views', 'mentions');
|
||||
|
||||
$this->extend(
|
||||
new Extend\EventSubscriber([
|
||||
'Flarum\Mentions\Handlers\PostMentionsMetadataUpdater',
|
||||
'Flarum\Mentions\Handlers\UserMentionsMetadataUpdater'
|
||||
]),
|
||||
|
||||
(new Extend\ForumClient())
|
||||
->assets([
|
||||
__DIR__.'/../js/dist/extension.js',
|
||||
__DIR__.'/../less/mentions.less'
|
||||
]),
|
||||
|
||||
(new Extend\Model('Flarum\Core\Models\Post'))
|
||||
->belongsToMany('mentionedBy', 'Flarum\Core\Models\Post', 'mentions_posts', 'mentions_id')
|
||||
->belongsToMany('mentionsPosts', 'Flarum\Core\Models\Post', 'mentions_posts', 'post_id', 'mentions_id')
|
||||
->belongsToMany('mentionsUsers', 'Flarum\Core\Models\User', 'mentions_users', 'post_id', 'mentions_id'),
|
||||
|
||||
(new Extend\ApiSerializer('Flarum\Api\Serializers\PostSerializer'))
|
||||
->hasMany('mentionedBy', 'Flarum\Api\Serializers\PostBasicSerializer')
|
||||
->hasMany('mentionsPosts', 'Flarum\Api\Serializers\PostBasicSerializer')
|
||||
->hasMany('mentionsUsers', 'Flarum\Api\Serializers\UserBasicSerializer'),
|
||||
|
||||
(new Extend\ApiAction('Flarum\Api\Actions\Discussions\ShowAction'))
|
||||
->addInclude('posts.mentionedBy')
|
||||
->addInclude('posts.mentionedBy.user')
|
||||
->addLink('posts.mentionedBy.discussion')
|
||||
->addInclude('posts.mentionsPosts', false)
|
||||
->addInclude('posts.mentionsPosts.user', false)
|
||||
->addInclude('posts.mentionsUsers', false),
|
||||
|
||||
(new Extend\ApiAction([
|
||||
'Flarum\Api\Actions\Posts\IndexAction',
|
||||
'Flarum\Api\Actions\Posts\ShowAction',
|
||||
]))
|
||||
->addInclude('mentionedBy')
|
||||
->addInclude('mentionedBy.user')
|
||||
->addLink('mentionedBy.discussion'),
|
||||
|
||||
(new Extend\ApiAction('Flarum\Api\Actions\Posts\CreateAction'))
|
||||
->addInclude('mentionsPosts')
|
||||
->addInclude('mentionsPosts.mentionedBy'),
|
||||
|
||||
new Extend\Formatter('postMentions', 'Flarum\Mentions\PostMentionsFormatter'),
|
||||
|
||||
new Extend\Formatter('userMentions', 'Flarum\Mentions\UserMentionsFormatter'),
|
||||
|
||||
new Extend\ActivityType('Flarum\Mentions\PostMentionedActivity', 'Flarum\Api\Serializers\PostBasicSerializer'),
|
||||
|
||||
new Extend\ActivityType('Flarum\Mentions\UserMentionedActivity', 'Flarum\Api\Serializers\PostBasicSerializer'),
|
||||
|
||||
(new Extend\NotificationType('Flarum\Mentions\PostMentionedNotification', 'Flarum\Api\Serializers\PostBasicSerializer'))
|
||||
->enableByDefault('alert'),
|
||||
|
||||
(new Extend\NotificationType('Flarum\Mentions\UserMentionedNotification', 'Flarum\Api\Serializers\PostBasicSerializer'))
|
||||
->enableByDefault('alert')
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,9 +1,10 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
<?php namespace Flarum\Mentions\Notifications;
|
||||
|
||||
use Flarum\Core\Models\Post;
|
||||
use Flarum\Core\Notifications\NotificationAbstract;
|
||||
use Flarum\Core\Posts\Post;
|
||||
use Flarum\Core\Notifications\Blueprint;
|
||||
use Flarum\Core\Notifications\MailableBlueprint;
|
||||
|
||||
class PostMentionedNotification extends NotificationAbstract
|
||||
class PostMentionedBlueprint implements Blueprint, MailableBlueprint
|
||||
{
|
||||
public $post;
|
||||
|
||||
@@ -27,7 +28,7 @@ class PostMentionedNotification extends NotificationAbstract
|
||||
|
||||
public function getData()
|
||||
{
|
||||
return ['replyNumber' => $this->reply->number];
|
||||
return ['replyNumber' => (int) $this->reply->number];
|
||||
}
|
||||
|
||||
public function getEmailView()
|
||||
@@ -47,11 +48,6 @@ class PostMentionedNotification extends NotificationAbstract
|
||||
|
||||
public static function getSubjectModel()
|
||||
{
|
||||
return 'Flarum\Core\Models\Post';
|
||||
}
|
||||
|
||||
public static function isEmailable()
|
||||
{
|
||||
return true;
|
||||
return Post::class;
|
||||
}
|
||||
}
|
@@ -1,10 +1,11 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
<?php namespace Flarum\Mentions\Notifications;
|
||||
|
||||
use Flarum\Core\Models\User;
|
||||
use Flarum\Core\Models\Post;
|
||||
use Flarum\Core\Notifications\NotificationAbstract;
|
||||
use Flarum\Core\Users\User;
|
||||
use Flarum\Core\Posts\Post;
|
||||
use Flarum\Core\Notifications\Blueprint;
|
||||
use Flarum\Core\Notifications\MailableBlueprint;
|
||||
|
||||
class UserMentionedNotification extends NotificationAbstract
|
||||
class UserMentionedBlueprint implements Blueprint, MailableBlueprint
|
||||
{
|
||||
public $post;
|
||||
|
||||
@@ -23,6 +24,11 @@ class UserMentionedNotification extends NotificationAbstract
|
||||
return $this->post->user;
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getEmailView()
|
||||
{
|
||||
return ['text' => 'mentions::emails.userMentioned'];
|
||||
@@ -40,11 +46,6 @@ class UserMentionedNotification extends NotificationAbstract
|
||||
|
||||
public static function getSubjectModel()
|
||||
{
|
||||
return 'Flarum\Core\Models\Post';
|
||||
}
|
||||
|
||||
public static function isEmailable()
|
||||
{
|
||||
return true;
|
||||
return Post::class;
|
||||
}
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
<?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';
|
||||
}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
|
||||
use Flarum\Core\Formatter\FormatterAbstract;
|
||||
use Flarum\Core\Models\Post;
|
||||
|
||||
class PostMentionsFormatter extends FormatterAbstract
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
public function __construct(PostMentionsParser $parser)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
public function afterPurification($text, Post $post = null)
|
||||
{
|
||||
if ($post) {
|
||||
$text = $this->ignoreTags($text, ['a', 'code', 'pre'], function ($text) use ($post) {
|
||||
return $this->parser->replace($text, function ($match) use ($post) {
|
||||
// TODO: use URL generator
|
||||
return '<a href="/d/'.$post->discussion_id.'/-/'.$match['number'].'" class="mention-post" data-number="'.$match['number'].'">'.$match['username'].'</a>';
|
||||
}, $text);
|
||||
});
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
|
||||
class PostMentionsParser extends MentionsParserAbstract
|
||||
{
|
||||
protected $pattern = '/\B@(?P<username>[a-z0-9_-]+)#(?P<number>\d+)/i';
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
<?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';
|
||||
}
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
|
||||
use Flarum\Core\Formatter\FormatterAbstract;
|
||||
use Flarum\Core\Models\Post;
|
||||
|
||||
class UserMentionsFormatter extends FormatterAbstract
|
||||
{
|
||||
protected $parser;
|
||||
|
||||
public function __construct(UserMentionsParser $parser)
|
||||
{
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
public function afterPurification($text, Post $post = null)
|
||||
{
|
||||
$text = $this->ignoreTags($text, ['a', 'code', 'pre'], function ($text) {
|
||||
return $this->parser->replace($text, function ($match) {
|
||||
// TODO: use URL generator
|
||||
return '<a href="/u/'.$match['username'].'" class="mention-user" data-user="'.$match['username'].'">'.$match['username'].'</a>';
|
||||
}, $text);
|
||||
});
|
||||
|
||||
return $text;
|
||||
}
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
<?php namespace Flarum\Mentions;
|
||||
|
||||
class UserMentionsParser extends MentionsParserAbstract
|
||||
{
|
||||
protected $pattern = '/\B@(?P<username>[a-z0-9_-]+)(?!#)/i';
|
||||
}
|
Reference in New Issue
Block a user