crixuamg/laravel-mentions

一个用于从文本中解析@提及并向用户发送通知的包。

4.0.3 2022-05-10 06:46 UTC

This package is auto-updated.

Last update: 2024-09-10 11:40:16 UTC


README

Laravel Mentions

一个用于从文本中解析@提及并向用户发送通知的包。

默认情况下,此包配置为解析任何文本类型,如果提及的用户存在于数据库中,则将任何匹配的@提及替换为markdown链接([@提及](/users/profile/@提及))。它还将通过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 CrixuAMG/Laravel-mentions

服务提供商

config/app.php中导入MentionServiceProvider

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

发布供应商文件

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

php artisan vendor:publish --provider="CrixuAMG\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添加到提及者模型

<?php
namespace App\Models;

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

class Comment extends Model
{
    use HasMentionsTrait;
}

现在,您可以在控制器或其他任何地方开始解析文本

<?php
namespace App\Http\Controllers;

use CrixuAMG\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 CrixuAMG\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'
        ];
    }
}

贡献

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