logo

Hook 开发指南

引言

InnoShopHook机制是一个高度灵活的扩展工具,它借鉴了WordPress插件架构的设计思想。 这一机制赋予开发者能力,在保持原始系统代码完整性的基础上,通过插件形式轻松接入并扩展系统功能,涵盖数据处理、流程操控以及模板渲染等多个方面。

InnoShop系统中,fire 操作指的是激活或触发特定的Hook事件,通常是在系统内部调用。 相对地,listen则是指对这些事件进行监听和响应,这通常需要开发者在插件中显式地绑定相应的处理逻辑或动作。

简而言之,以 fire_ 开头的方法由InnoShop系统调用; 而以 listen_ 开头的方法由插件调用。

Hook类型概览

数据Hook (Filter)

数据Hook专注于修改系统中特定方法返回的数据。它提供了一种机制,允许开发者捕获并调整输出数据。

  • fire_hook_filter: InnoShop系统内部调用此函数来触发数据过滤。
  • listen_hook_filter: 插件使用此函数监听并修改数据。

流程Hook (Action)

流程Hook用于在系统的特定流程中执行动作,如订单处理、用户注册等。

  • fire_hook_action: InnoShop系统内部调用此函数来触发流程操作。
  • listen_hook_action: 插件使用此函数监听流程事件,并在适当的时候介入。

模板Hook (Blade)

模板Hook允许开发者修改Blade模板的内容,提供了一种在现有界面上添加或更改内容的方法。

  • listen_blade_insert: 插件使用此函数在Blade模板中插入新内容。
  • listen_blade_update: 插件使用此函数更新Blade模板中的现有内容。

Hook使用示例

数据Hook示例

想象一下,您想在网站的顶部导航菜单中添加一个新的菜单项。通过listen_hook_filter,您可以轻松实现这一点:

php
listen_hook_filter('global.header.menus', function ($data) {
    $data[] = [
        'name' => 'InnoShop首页',
        'link' => 'https://www.innoshop.cn', 
    ];
    return $data;
}, 0);

流程Hook示例

假设您需要在用户完成订单后,将订单信息发送到企业微信或钉钉,或者推送到ERP系统。使用listen_hook_action可以满足这一需求:

php
listen_hook_action('front.checkout.confirm.after', function ($data) {
    // 订单生成后发送信息到企业微信、钉钉或推送到ERP系统
}, 0);

模板Hook示例

如果您希望在页面顶部的电话显示前添加一些文本,可以通过listen_blade_update实现:

php
listen_blade_update('layouts.header.telephone', function ($output, $data) {
    return '电话:' . $output;
});

如何在插件中监听Hook

在插件的Boot类中的init方法中监听 Hook,以下是一个具体的示例:

php
namespace Plugin\YourPlugin;

class Boot
{
    public function init()
    {
        listen_hook_action('front.checkout.confirm.after', function ($data) {
            // 订单生成后发送信息到企业微信、钉钉或推送到ERP系统
        }, 0);
    }
}

Blade模板中的Hook使用

插入内容 (@hookinsert)

在InnoShop的Blade模板中,使用@hookinsert指令可以在指定位置插入内容。 如果系统提供的模板标签不足以满足需求,可以通过提交Pull Request (PR) 来丰富它们。

示例:/innopacks/front/resources/views/layouts/header.blade.php模板中,您可以看到如下代码:

blade
@hookinsert('layout.header.top')

然后在插件中定义要插入的内容:

php
listen_blade_insert('layout.header.top', function ($data) {
    return '插入的动态内容';
});

更新内容 (@hookupdate@endhookupdate)

在Blade模板中,使用@hookupdate@endhookupdate指令可以包裹需要更新的内容。

示例: 在同一header.blade.php模板中,您可以这样使用:

blade
@hookupdate('layouts.header.telephone')
<span><i class="bi bi-telephone-outbound"></i> {{ system_setting('telephone') }}</span>
@endhookupdate

然后在插件中修改或替换标签中的内容:

php
listen_blade_update('layouts.header.telephone', function () {
    return '<span>更新后的内容显示</span>';
});

结语

InnoShop的Hook机制极大地增强了系统的可扩展性和可定制性。通过本指南,开发者可以更深入地理解Hook的工作原理和应用场景,从而在插件开发中更加自如地使用它们,实现各种创新的业务需求。