javanile/eventy

Vtiger中的WordPress过滤器/动作系统

0.8.1 2022-02-03 12:42 UTC

This package is auto-updated.

Last update: 2024-08-29 05:38:08 UTC


README

eventy logo


Build Status Coverage Status

Vtiger中的动作和过滤器。WordPress风格的。

Eventy(由于没有更好的名字)是一个简单的动作和过滤器(如果你喜欢,也可以说是钩子)系统。

关于

动作是你希望在代码的某些特定点执行的代码片段。动作永远不会返回任何内容,只是提供了一个选项,可以在不破坏现有代码的情况下将其钩入。

过滤器是用于修改实体的。它们总是返回某种类型的值。默认情况下,它们返回第一个参数,你也应该这样做。

了解更多关于过滤器

了解更多关于动作

何时使用Eventy?

Eventy最好用作允许代码扩展的一种方式。无论是创建一个包还是应用程序,Eventy都可以提供所需的扩展性。

例如,Eventy可以为基于插件/模块的系统奠定基础。你可以提供一个“动作”,允许插件注册自己。你可能提供一个“过滤器”,以便插件可以更改核心中的数组内容。你也可以提供一个“动作”,以便插件可以修改应用程序的菜单。

Eventy在方法上并不独特。Laravel提供了允许你“入侵”类和事件的Macroable特性,这样你就可以直接在代码中的特定点进行操作。

安装

  1. 使用Composer安装
composer require tormjens/eventy

如果你使用的是Laravel 5.5或更高版本,你现在可以开始使用这个包了。Eventy会被Laravel框架自动发现。

  1. 将服务提供者添加到你的config/app.php文件中的providers数组。
    'Javanile\Eventy\EventServiceProvider',
    'Javanile\Eventy\EventBladeServiceProvider',
  1. config/app.php中添加外观
    'Eventy' => Javanile\Eventy\Facades\Events::class,

用法

动作

在你的代码的任何地方,你可以创建一个新的动作,如下所示

use Javanile\Eventy\Facades\Events as Eventy;

Eventy::action('my.hook', $user);

第一个参数是钩子的名称;你将在稍后使用这个钩子时用到它。所有后续参数都作为参数发送到动作。这些可以是任何你想要的东西。例如,你可能想告诉监听器,这个钩子连接到某个特定的模型。然后,你会将这个作为其中一个参数传递。

要监听你的钩子,请添加监听器。这些最好添加到你的AppServiceProviderboot()方法。

例如,如果你想钩入上面的钩子,你可以这样做

Eventy::addAction('my.hook', function($user) {
    if ($user->is_awesome) {
         $this->doSomethingAwesome($user);
    }
}, 20, 1);

再次强调,第一个参数必须是钩子的名称。第二个是回调。这可以是一个闭包、指向应用程序容器中类的字符串(MyNamespace\Http\Listener@myHookListener)、一个数组回调([$object, 'method'])或一个全局注册的函数(function_name)。第三个参数是钩子的优先级。数字越小,执行越早。第四个参数指定监听器接受的参数数量。

过滤器

过滤器与动作的工作方式非常相似,并且具有与动作相同的结构。最显著的区别是过滤器总是返回其值。

要添加过滤器

$value = Eventy::filter('my.hook', 'awesome');

如果没有监听器连接到这个钩子,过滤器将简单地返回'awesome'

这就是你如何向这个过滤器添加监听器(仍然在AppServiceProvider中)

Eventy::addFilter('my.hook', function($what) {
    $what = 'not '. $what;
    return $what;
}, 20, 1);

现在,过滤器将返回'not awesome'。很酷!

您可以将它与之前的钩子结合使用

Eventy::addAction('my.hook', function($what) {
    $what = Eventy::filter('my.hook', 'awesome');
    echo 'You are '. $what;
});

在Blade中使用

假设您已经将 EventBladeServiceProvider 添加到您的配置中,有两个指令可用,因此您可以在Blade模板中使用它。

添加与上面动作示例中相同的行为

@action('my.hook', $user)

添加与上面过滤器示例中相同的过滤器

You are @filter('my.hook', 'awesome')

使用它来启用可扩展性

以下是一个示例,说明Eventy如何在具有插件概念的实际应用程序中使用。

插件A有一个类,它构建查询以获取所有已发布的帖子

class PostsQueryBuilder
{
    public function query()
    {
        return Post::where('published_at', '>', now());
    }
}

使用Eventy,我可以为其他插件提供可以挂载的过滤器

use Javanile\Eventy\Facades\Events as Eventy;
class PostsQueryBuilder
{
    public function query()
    {
        $query = resolve(Post::where('published_at', '>', now());
        return Eventy::filter('posts-query-builder:query', $query);
    }
}

然后,插件B出现,并需要修改该查询以仅包含标题中包含单词foo的帖子。

在插件B的服务提供者中(最好在启动方法中,因为这将始终在Eventy可用后触发)我们将为该事件添加监听器。

use Javanile\Eventy\Facades\Events as Eventy;

class PluginBServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Eventy::addFilter('posts-query-builder:query', function($query) {
            return $query->where('title', 'like', '%foo%');
        });
    }
}

以下是一个示例,说明如何将动作添加到Blade模板中,以便插件可以进行条件加载,并通过抽象模板视图中的控制器依赖关系进行扩展。

@foreach ($posts as $post)
    ...
    <p>{{ $post->body }}</p>
    ...
    @action('blade-posts-loop-post-footer', $post)
@endforeach

这将允许您的插件/控制器挂钩到每个博客帖子页脚。

在这个例子中添加了一个分享链接。

use Javanile\Eventy\Facades\Events as Eventy;
class SharePostsController
{
    public function boot()
    {
        Eventy::addAction('blade-posts-loop-post-footer', function($post) {
            echo '<a href="twitter.com?share='.$post->url.'">Twitter</a>';
            printf('<a href="https://xyz.com?share='.$post->url.'">XYZbook</a>');
        });
    }
}

在这个例子中添加了一个评论计数。

use Javanile\Eventy\Facades\Events as Eventy;
class CommentsPostsController
{
    public function boot()
    {
        Eventy::addAction('blade-posts-loop-post-footer', function($post) {
            echo 'Comments: ' . count($post->comments);
        });
    }
}

鸣谢