定制 rubenmartindev/prestashop-module-hook-bus 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

rubenmartindev/prestashop-module-hook-bus

Composer 安装命令:

composer require rubenmartindev/prestashop-module-hook-bus

包简介

Flexible and centralized way to route and handle PrestaShop hooks

README 文档

README

This library provides a flexible and centralized way to route and handle PrestaShop hooks.

Overview

As you develop your module and add hooks to the main file, the module can grow disproportionately; all logic ends up in a single place, breaking the SOLID Single Responsibility principle and making maintenance and readability chaotic.

Ideally, each hook should be self-contained and have a single responsibility. Making it easy to configure, use, and maintain.

Compared to managing hooks directly in your module's main class, Hook Bus offers:

  • Better separation of concerns.
  • Easier testing.
  • Cleaner module classes.
  • Dependency Injection friendly handlers.
  • Reusable hook logic.

The library is composed of three main building blocks:

  • Identifier: determines the hook identity.
  • Locator: resolves the Handler for that identity.
  • Handler: contains the hook business logic.

Requirements

  • PHP 5.6+
  • PrestaShop 1.6.x / 1.7.x / 8.x / 9.x+

Installation

Install via Composer in your PrestaShop module:

composer require rubenmartindev/prestashop-module-hook-bus

Complete Example

A typical module structure could look like this:

modules/
└── mymodule/
    ├── mymodule.php
    └── src/
        └── Hook/
            ├── DisplayHeaderHandler.php
            └── DisplayFooterHandler.php

Configure the Hook Bus once in the module constructor:

use RubenMartinDev\PrestashopModuleHookBus\HookBusFactory;
use RubenMartinDev\PrestashopModuleHookBus\HookBusInterface;
use RubenMartinDev\PrestashopModuleHookBus\Identifier\MethodHookIdentifier;

class MyModule extends Module
{
    /** @var HookBusInterface */
    private $hookBus;

    public function __construct()
    {
        // ...

        $this->hookBus = HookBusFactory::createWithArray(
            new MethodHookIdentifier(),
            [
                new DisplayHeaderHandler(),
                new DisplayFooterHandler(),
            ]
        );
    }

    public function hookDisplayHeader(array $params)
    {
        return $this->hookBus->dispatch(__FUNCTION__, $params);
    }

    public function hookDisplayFooter(array $params)
    {
        return $this->hookBus->dispatch(__FUNCTION__, $params);
    }
}

Each hook is implemented in its own Handler:

use RubenMartinDev\PrestashopModuleHookBus\Handler\NamedHandlerInterface;

final class DisplayHeaderHandler implements NamedHandlerInterface
{
    public static function getIdentityName()
    {
        return 'displayHeader';
    }

    public function handle(array $params = [])
    {
        // Hook logic here
    }
}

Factory

To make configuring and creating the Hook Bus easier, HookBusFactory provides static methods:

Method Best suited for
create() Full control over the Identifier and Locator.
createWithArray() Quick setup using an array of handlers.
createWithCallable() Dynamic handler resolution.
createWithContainer() Symfony service containers and Dependency Injection.

HookBusFactory::create()

Argument Type Description
hookIdentifier HookIdentifierInterface The Identifier that will be used to locate the Handler.
handlerLocator HandlerLocatorInterface The Locator where the Handlers are registered.

Example

use RubenMartinDev\PrestashopModuleHookBus\HookBusFactory;
use RubenMartinDev\PrestashopModuleHookBus\Identifier\LiteralIdentifier;
use RubenMartinDev\PrestashopModuleHookBus\Locator\ArrayLocator;

$arrayLocator = new ArrayLocator();
$arrayLocator->addHandler('displayHeader', new DisplayHeaderHandler());

HookBusFactory::create(
    new LiteralIdentifier(),
    $arrayLocator
);

HookBusFactory::createWithArray()

Argument Type Description
hookIdentifier HookIdentifierInterface The Identifier that will be used to locate the Handler.
handlers array An array with key representing the Identifier and value the Handler. If the handler implements NamedHandlerInterface, key is optional.

Example

use RubenMartinDev\PrestashopModuleHookBus\HookBusFactory;
use RubenMartinDev\PrestashopModuleHookBus\Identifier\LiteralIdentifier;

HookBusFactory::createWithArray(
    new LiteralIdentifier(),
    ['displayHeader' => new DisplayHeaderHandler()]
);

HookBusFactory::createWithCallable()

Argument Type Description
hookIdentifier HookIdentifierInterface The Identifier that will be used to locate the Handler.
callable callable A callback that will resolve which Handler will be used.

Example

use RubenMartinDev\PrestashopModuleHookBus\HookBusFactory;
use RubenMartinDev\PrestashopModuleHookBus\Identifier\LiteralIdentifier;

HookBusFactory::createWithCallable(
    new LiteralIdentifier(),
    function ($identifier) {
        if ('displayHeader' === $identifier) {
            return new DisplayHeaderHandler();
        }
    }
);

HookBusFactory::createWithContainer()

Argument Type Description
container ContainerInterface Container where services are registered.
hookIdentifier HookIdentifierInterface The Identifier that will be used to locate the Handler.
handlers array An array with key representing the Identifier and value the service to use as Handler. If the handler implements NamedHandlerInterface, key is optional.

Example

Note

Service container integration requires PrestaShop 1.7 or higher, as PrestaShop 1.6 does not use Symfony, or, use your own container, for example prestashop/module-lib-service-container.

use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
use RubenMartinDev\PrestashopModuleHookBus\HookBusFactory;
use RubenMartinDev\PrestashopModuleHookBus\Identifier\LiteralIdentifier;

$container = SymfonyContainer::getInstance();

HookBusFactory::createWithContainer(
    $container,
    new LiteralIdentifier(),
    ['displayHeader' => 'my_module.hook.handler.display_header']
);

Identifier

Used to identify the hook and to locate the corresponding Handler during the dispatch cycle.

If the Identifier cannot resolve the identity, it will throw the exception UnresolvedHookIdentifierException.

Literal

The provided string will be used literally as the identifier.

Example

use RubenMartinDev\PrestashopModuleHookBus\HookBusFactory;
use RubenMartinDev\PrestashopModuleHookBus\Identifier\LiteralIdentifier;

class MyModule extends Module
{
    public function __construct()
    {
        // ...

        $this->hookBus = HookBusFactory::createWithArray(
            new LiteralIdentifier(),
            // ...
        );
    }

    public function hookDisplayHeader(array $params)
    {
        return $this->hookBus->dispatch('myCustomIdentity', $params);
    }
}

Method Hook

Designed to be used inside the module's public hook<hook_name>() methods. It obtains the identifier from the method name; for example, the method hookActionAdminControllerSetMedia() will be the identifier actionAdminControllerSetMedia.

Example

use RubenMartinDev\PrestashopModuleHookBus\HookBusFactory;
use RubenMartinDev\PrestashopModuleHookBus\Identifier\MethodHookIdentifier;

class MyModule extends Module
{
    public function __construct()
    {
        // ...

        $this->hookBus = HookBusFactory::createWithArray(
            new MethodHookIdentifier(),
            // ...
        );
    }

    public function hookDisplayHeader(array $params)
    {
        return $this->hookBus->dispatch(__FUNCTION__, $params);
    }
}

Callable

Through a callback we can generate a custom identifier.

Example

use RubenMartinDev\PrestashopModuleHookBus\HookBusFactory;
use RubenMartinDev\PrestashopModuleHookBus\Identifier\CallableIdentifier;

class MyModule extends Module
{
    public function __construct()
    {
        // ...

        $this->hookBus = HookBusFactory::createWithArray(
            new CallableIdentifier(function ($hookName) {
                if ('myCustomIdentity' === $hookName) {
                    return 'myCustomIdentityHandler';
                }
            }),
            // ...
        );
    }

    public function hookDisplayHeader(array $params)
    {
        return $this->hookBus->dispatch('myCustomIdentity', $params);
    }
}

Custom Identifier

You can create your own Identifiers to generate custom identities. It should implement the interface HookIdentifierInterface.

Example

use RubenMartinDev\PrestashopModuleHookBus\Identifier\HookIdentifierInterface;

final class MyCustomIdentifier implements HookIdentifierInterface
{
    public function identify($hookName)
    {
        return \strtolower($hookName);
    }
}

Locator

Where Handlers are located and which identities are associated with them.

If the Locator cannot resolve which Handler is assigned to the identity, it will throw the exception MissingHandlerException.

Array

Example

use RubenMartinDev\PrestashopModuleHookBus\Locator\ArrayLocator;

$locator = new ArrayLocator();

$locator->addHandler('displayHeader', new DisplayHeaderHandler());
$locator->addHandler('displayFooter', new DisplayFooterHandler());

Callable

Example

use RubenMartinDev\PrestashopModuleHookBus\Locator\CallableLocator;

$locator = new CallableLocator(function ($hookName) {
    if ('displayHeader' === $hookName) {
        return new DisplayHeaderHandler();
    }

    if ('displayFooter' === $hookName) {
        return new DisplayFooterHandler();
    }

    return null;
});

Container

Example

use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
use RubenMartinDev\PrestashopModuleHookBus\Locator\ContainerLocator;

$container = SymfonyContainer::getInstance();

$locator = new ContainerLocator($container);

$locator->addHandler('displayHeader', 'my_module.hook.handler.display_header');
$locator->addHandler('displayFooter', 'my_module.hook.handler.display_footer');

Custom Locator

You can create your own Locators that return which Handler will manage the hook. It should implement the interface HandlerLocatorInterface.

If you want it to be compatible with the Factory, you should implement the interface AppendableHandlerLocatorInterface to enable the addHandler() method.

Example

use RubenMartinDev\PrestashopModuleHookBus\Locator\HandlerLocatorInterface;

final class MyCustomLocator implements HandlerLocatorInterface
{
    public function getHandlerForIdentity($identity)
    {
        if ('displayHeader' === $identity) {
            return new DisplayHeaderHandler();
        }

        if ('displayFooter' === $identity) {
            return new DisplayFooterHandler();
        }

        throw MissingHandlerException::forIdentity($identity);
    }
}

Handler

Handlers are responsible for resolving what to do with the hook. They must implement the interface HookHandlerInterface.

The handle() method receives the $params argument, which is the same argument that the native hook<hook_name>() method of the module received.

If the Handler implements the interface NamedHandlerInterface, the Factory can infer the identity automatically from the static method getIdentityName().

Example

use RubenMartinDev\PrestashopModuleHookBus\Handler\NamedHandlerInterface;

final class DisplayHeaderHandler implements NamedHandlerInterface
{
    public static function getIdentityName()
    {
        return 'displayHeader';
    }

    public function handle(array $params = [])
    {
        $cartTotal = $params['cart']->getOrderTotal();

        return Tools::displayPrice($cartTotal);
    }
}

Exceptions

All library exceptions extend HookBusException.

Exception Description
MissingHandlerException No Handler was found for the resolved identity.
UnresolvedHookIdentifierException The Identifier could not resolve an identity.

统计信息

  • 总下载量: 5
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-04

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固