xetaio/xetaravel-mentions

一个从文本中解析 @mention 并通过通知提到用户的包。

11.0.0 2024-05-18 10:29 UTC

This package is auto-updated.

Last update: 2024-09-18 11:08:22 UTC


README

Xetaravel Mentions

一个从文本中解析 @mentions 并通过通知提到用户的包。

默认情况下,此包配置为解析任何文本类型,如果提及的用户存在于数据库中,则将匹配的 @mention 替换为 markdown 链接([@Mention](/users/profile/@Mention))。它还将发送包含 Laravel Notifiable 特性的通知给所有被提及的用户。(灵感来自 laravel-mentions 包。)

快速示例

输入 文本

  Lorem ipsu @admin crepu @Member quis nostrud @UserDoesNotExist ullamcorper fail@mention nostrud @admin.

输出 文本

Lorem ipsu [@Admin](/users/profile/@Admin) crepu [@Member](/users/profile/@Member) quis nostrud
@UserDoesNotExist ullamcorper fail@mention nostrud [@Admin](/users/profile/@Admin).

并且 AdminMember 用户都将收到通知。但是 Admin 只会收到一次通知。(是的,解析器包含反垃圾邮件规则。)

目录

需求

PHP

安装

composer require xetaio/xetaravel-mentions

服务提供者

在您的 config/app.php 中导入 MentionServiceProvider

'providers' => [
  //...
  Xetaio\Mentions\Providers\MentionServiceProvider::class,
  //...
]

供应商发布

将供应商文件发布到您的应用程序(包括配置文件 config/mentions.php 和迁移文件)

php artisan vendor:publish --provider="Xetaio\Mentions\Providers\MentionServiceProvider"

然后迁移数据库

php artisan migrate

配置

<?php

return [
    'pools' => [
        // Here you configure as many pools as you want. But basically we
        // notify only the Users.
        'users' => [
            // Model that will be mentioned.
            'model' => App\Models\User::class,

            // The column that will be used to search the model by the parser.
            'column' => 'username',

            // The route used to generate the user link.
            'route' => '/users/profile/@',

            // Notification class to use when this model is mentioned.
            'notification' => App\Notifications\MentionNotification::class,
        ]
    ]
];

使用

首先,您需要将 HasMentionTrait 添加到 mentioner 模型

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Xetaio\Mentions\Models\Traits\HasMentionsTrait;

class Comment extends Model
{
    use HasMentionsTrait;
}

现在,您可以在控制器或您想要的地方开始解析文本

<?php
namespace App\Http\Controllers;

use Xetaio\Mentions\Parser\MentionParser;

class CommentController extends Controller
{
     public function create(Request $request)
     {
         // Handle the comment creation however you like
         $comment = Comment::create($request->all());

         // Register a new Parser and parse the content.
         $parser = new MentionParser($comment);
         $content = $parser->parse($comment->content);

         /**
          * Re-assign the parsed content and save it.
          *
          * Note : If you use a custom Parser and you don't modify
          * the `$content` in your custom Parser, you can ignore that.
          */
         $comment->content = $content;
         $comment->save();
     }
}

就这样!至少在默认配置下是这样。😝

解析器配置

MentionParser 接受一个配置数组作为第二个参数,这是 默认配置

<?php

[
     // The pool used with the parser.
     'pool' => 'users',

     // If `false`, the parser won't mention the user.
     'mention' => true,

     /**
      * If `false` the parser won't notify the user.
      *
      * Note : If the `mention` option is set to `false`, this setting is ignored.
      */
     'notify' => true,

     /**
      * The character that will trigger the mention.
      * Note : If you modify this setting, you will also need to modify
      * the `regex_replacement.{character}` option to match this setting.
      */
     'character' => '@',

     // The regex used to parse the mentions.
     'regex' => '/\s({character}{pattern}{rules})/',

     /**
      * The replacement used to replace the regex pattarn.
      * Can be usefull if you want to allow a special character in the mention like `_` or `-`
      * or pass dynamic value to the regex.
      *
      * Note : The parse use the PHP function `strtr` to replace the pattarn in the regex.
      */
     'regex_replacement' => [
         '{character}'  => '@',
         '{pattern}'  => '[A-Za-z0-9]',
         '{rules}'  => '{4,20}'
    ]
]

配置与默认配置合并,因此您只需设置您想要修改的选项。例如

<?php

$parser = new MentionParser($comment, [
    'pool' => 'members',
    'notify' => false
]);

您还可以在运行时设置配置

<?php

$parser = new MentionParser($comment);
$parser->setOption('notify', false);
$content = $parser->parse($comment->content);

或者获取配置选项的值

<?php

$value = $parser->getOption('notify');
// false

解析器配置方法

解析器使用 Xety/Configurator 包来管理配置。查看此存储库以获取所有方法和它们的描述。

自定义解析器

如果您想为解析器提供更多灵活性,最佳方法是创建一个新的解析器并重写您想修改的方法。例如,让我们创建一个新的解析器,它将返回 HTML 链接而不是 Markdown 链接

<?php
namespace App\Parser;

use Illuminate\Support\Str;
use Xetaio\Mentions\Parser\MentionParser;

class CustomParser extends MentionParser
{

    protected function replace(array $match): string
    {
        $character = $this->getOption('character');
        $mention = Str::title(str_replace($character, '', trim($match[0])));

        $route = config('mentions.pools.' . $this->getOption('pool') . '.route');

        $link = $route . $mention;

        // Here we return a HTML link instead of the default Markdown.
        return " <a class=\"link\" href=\"{$link} \">{$character}{$mention}</a>";
    }
}

要使用它

<?php

$parser = new \App\Parser\CustomParser($comment);
$content = $parser->parse($comment->content);

当然,如果您需要,您也可以覆盖解析器中的所有方法。

通知

您需要编写自己的通知类,但我对您很宽容,您可以在下面找到使用 database 传输通道的示例

<?php
namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;

class MentionNotification extends Notification
{
    use Queueable;

    /**
     * The Comment instance.
     *
     * @var \Illuminate\Database\Eloquent\Model
     */
    public $model;

    /**
     * Create a new notification instance.
     *
     * @param \Illuminate\Database\Eloquent\Model $model
     */
    public function __construct($model)
    {
        $this->model = $model;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param mixed $notifiable
     *
     * @return array
     */
    public function via($notifiable): array
    {
        return ['database'];
    }

    /**
     * Get the array representation of the notification.
     *
     * @param mixed $notifiable
     *
     * @return array
     */
    public function toDatabase($notifiable): array
    {
        // The instance `$this->model` represent the `Comment` model.
        $username = $this->model->user->username;
        $modelId = $this->model->getKey();

        $message = "<strong>@{ $username }</strong> has mentionned your name in his comment !";

        // You could (and probably should) use a route name here with the function `route()`.
        $link = "/comment/show/{ $modelId }";

        return [
            'message' => $message,
            'link' => $link,
            'type' => 'mention'
        ];
    }
}

贡献

如果您想做出贡献,请 遵循此指南