1
0
mirror of https://github.com/flarum/core.git synced 2025-08-14 20:34:10 +02:00

Initial commit

This commit is contained in:
Toby Zerner
2015-05-14 22:01:03 +09:30
commit 57bb8702de
30 changed files with 1073 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
<?php namespace Flarum\Mentions\Handlers;
use Flarum\Mentions\PostMentionsParser;
use Flarum\Mentions\PostMentionedNotification;
use Flarum\Core\Events\PostWasPosted;
use Flarum\Core\Models\User;
use Flarum\Core\Notifications\Notifier;
use Illuminate\Contracts\Events\Dispatcher;
class PostMentionsMetadataUpdater
{
protected $parser;
protected $notifier;
public function __construct(PostMentionsParser $parser, Notifier $notifier)
{
$this->parser = $parser;
$this->notifier = $notifier;
}
public function subscribe(Dispatcher $events)
{
$events->listen('Flarum\Core\Events\PostWasPosted', __CLASS__.'@whenPostWasPosted');
// @todo listen for post edit/delete events and sync mentions as appropriate
}
public function whenPostWasPosted(PostWasPosted $event)
{
$reply = $event->post;
$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'));
// @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]);
}
}
}
}

View File

@@ -0,0 +1,46 @@
<?php namespace Flarum\Mentions\Handlers;
use Flarum\Mentions\UserMentionsParser;
use Flarum\Mentions\UserMentionedNotification;
use Flarum\Core\Events\PostWasPosted;
use Flarum\Core\Models\User;
use Flarum\Core\Notifications\Notifier;
use Illuminate\Contracts\Events\Dispatcher;
class UserMentionsMetadataUpdater
{
protected $parser;
protected $notifier;
public function __construct(UserMentionsParser $parser, Notifier $notifier)
{
$this->parser = $parser;
$this->notifier = $notifier;
}
public function subscribe(Dispatcher $events)
{
$events->listen('Flarum\Core\Events\PostWasPosted', __CLASS__.'@whenPostWasPosted');
// @todo listen for post edit/delete events and sync mentions as appropriate
}
public function whenPostWasPosted(PostWasPosted $event)
{
$post = $event->post;
$matches = $this->parser->match($post->content);
$mentioned = User::whereIn('username', array_filter($matches['username']))->get();
$post->mentionsUsers()->sync($mentioned);
// @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]);
}
}
}
}

View File

@@ -0,0 +1,20 @@
<?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);
}
}

View File

@@ -0,0 +1,69 @@
<?php namespace Flarum\Mentions;
use Flarum\Support\ServiceProvider;
use Illuminate\Contracts\Events\Dispatcher;
use Flarum\Api\Actions\Discussions\ShowAction as DiscussionsShowAction;
use Flarum\Api\Actions\Posts\IndexAction as PostsIndexAction;
use Flarum\Api\Actions\Posts\ShowAction as PostsShowAction;
use Flarum\Api\Actions\Posts\CreateAction as PostsCreateAction;
class MentionsServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot(Dispatcher $events)
{
$events->subscribe('Flarum\Mentions\Handlers\PostMentionsMetadataUpdater');
$events->subscribe('Flarum\Mentions\Handlers\UserMentionsMetadataUpdater');
$this->forumAssets([
__DIR__.'/../js/dist/extension.js',
__DIR__.'/../less/mentions.less'
]);
$this->relationship('Flarum\Core\Models\Post', function ($model) {
return $model->belongsToMany('Flarum\Core\Models\Post', 'mentions_posts', 'mentions_id');
}, 'mentionedBy');
$this->serializeRelationship('Flarum\Api\Serializers\PostSerializer', 'hasMany', 'mentionedBy', 'Flarum\Api\Serializers\PostBasicSerializer');
DiscussionsShowAction::$include['posts.mentionedBy'] = true;
DiscussionsShowAction::$include['posts.mentionedBy.user'] = true;
PostsShowAction::$include['mentionedBy'] = true;
PostsShowAction::$include['mentionedBy.user'] = true;
PostsIndexAction::$include['mentionedBy'] = true;
PostsIndexAction::$include['mentionedBy.user'] = true;
$this->relationship('Flarum\Core\Models\Post', function ($model) {
return $model->belongsToMany('Flarum\Core\Models\Post', 'mentions_posts', 'post_id', 'mentions_id');
}, 'mentionsPosts');
$this->relationship('Flarum\Core\Models\Post', function ($model) {
return $model->belongsToMany('Flarum\Core\Models\User', 'mentions_users', 'post_id', 'mentions_id');
}, 'mentionsUsers');
$this->serializeRelationship('Flarum\Api\Serializers\PostSerializer', 'hasMany', 'mentionsPosts', 'Flarum\Api\Serializers\PostBasicSerializer');
$this->serializeRelationship('Flarum\Api\Serializers\PostSerializer', 'hasMany', 'mentionsUsers', 'Flarum\Api\Serializers\UserBasicSerializer');
DiscussionsShowAction::$include['posts.mentionsPosts'] = true;
DiscussionsShowAction::$include['posts.mentionsPosts.user'] = true;
PostsCreateAction::$include['mentionsPosts'] = true;
PostsCreateAction::$include['mentionsPosts.mentionedBy'] = true;
DiscussionsShowAction::$include['posts.mentionsUsers'] = true;
$this->formatter('postMentions', 'Flarum\Mentions\PostMentionsFormatter');
$this->formatter('userMentions', 'Flarum\Mentions\UserMentionsFormatter');
$this->notificationType('Flarum\Mentions\PostMentionedNotification', ['alert' => true]);
$this->notificationType('Flarum\Mentions\UserMentionedNotification', ['alert' => true]);
}
}

View File

@@ -0,0 +1,47 @@
<?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;
class PostMentionedNotification extends Notification implements AlertableNotification
{
protected $post;
protected $sender;
protected $reply;
public function __construct(Post $post, User $sender, Post $reply)
{
$this->post = $post;
$this->sender = $sender;
$this->reply = $reply;
}
public function getSubject()
{
return $this->post;
}
public function getSender()
{
return $this->sender;
}
public function getAlertData()
{
return ['replyNumber' => $this->reply->number];
}
public static function getType()
{
return 'postMentioned';
}
public static function getSubjectModel()
{
return 'Flarum\Core\Models\Post';
}
}

View File

@@ -0,0 +1,31 @@
<?php namespace Flarum\Mentions;
class PostMentionsFormatter
{
protected $parser;
public function __construct(PostMentionsParser $parser)
{
$this->parser = $parser;
}
public function format($text, $post = null)
{
if ($post) {
$text = $this->parser->replace($text, function ($match) use ($post) {
return '<a href="#/d/'.$post->discussion_id.'/-/'.$match['number'].'" class="mention-post" data-number="'.$match['number'].'">'.$match['username'].'</a>';
}, $text);
}
return $text;
}
public function strip($text)
{
$text = $this->parser->replace($text, function () {
return ' ';
});
return $text;
}
}

View File

@@ -0,0 +1,6 @@
<?php namespace Flarum\Mentions;
class PostMentionsParser extends MentionsParserAbstract
{
protected $pattern = '/\B@(?P<username>[a-z0-9_-]+)#(?P<number>\d+)/i';
}

View File

@@ -0,0 +1,44 @@
<?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;
class UserMentionedNotification extends Notification implements AlertableNotification
{
protected $sender;
protected $post;
public function __construct(User $sender, Post $post)
{
$this->sender = $sender;
$this->post = $post;
}
public function getSubject()
{
return $this->post;
}
public function getSender()
{
return $this->sender;
}
public function getAlertData()
{
return null;
}
public static function getType()
{
return 'userMentioned';
}
public static function getSubjectModel()
{
return 'Flarum\Core\Models\Post';
}
}

View File

@@ -0,0 +1,20 @@
<?php namespace Flarum\Mentions;
class UserMentionsFormatter
{
protected $parser;
public function __construct(UserMentionsParser $parser)
{
$this->parser = $parser;
}
public function format($text, $post = null)
{
$text = $this->parser->replace($text, function ($match) {
return '<a href="#/u/'.$match['username'].'" class="mention-user" data-user="'.$match['username'].'">'.$match['username'].'</a>';
}, $text);
return $text;
}
}

View File

@@ -0,0 +1,6 @@
<?php namespace Flarum\Mentions;
class UserMentionsParser extends MentionsParserAbstract
{
protected $pattern = '/\B@(?P<username>[a-z0-9_-]+)/i';
}