PHPackages                             rubenmartindev/prestashop-module-hook-bus - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. rubenmartindev/prestashop-module-hook-bus

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

rubenmartindev/prestashop-module-hook-bus
=========================================

Flexible and centralized way to route and handle PrestaShop hooks

v1.0.0(1mo ago)05↓90%MITPHPPHP &gt;=5.6.0

Since Jun 4Pushed 1mo agoCompare

[ Source](https://github.com/rubenmartindev/prestashop-module-hook-bus)[ Packagist](https://packagist.org/packages/rubenmartindev/prestashop-module-hook-bus)[ RSS](/packages/rubenmartindev-prestashop-module-hook-bus/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (1)Dependencies (4)Versions (3)Used By (0)

PrestaShop Hook Bus
===================

[](#prestashop-hook-bus)

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

Overview
--------

[](#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
------------

[](#requirements)

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

Installation
------------

[](#installation)

Install via Composer in your PrestaShop module:

```
composer require rubenmartindev/prestashop-module-hook-bus
```

Complete Example
----------------

[](#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
-------

[](#factory)

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

MethodBest 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()`

[](#hookbusfactorycreate)

ArgumentTypeDescription`hookIdentifier``HookIdentifierInterface`The Identifier that will be used to locate the Handler.`handlerLocator``HandlerLocatorInterface`The Locator where the Handlers are registered.#### Example

[](#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()`

[](#hookbusfactorycreatewitharray)

ArgumentTypeDescription`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

[](#example-1)

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

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

### `HookBusFactory::createWithCallable()`

[](#hookbusfactorycreatewithcallable)

ArgumentTypeDescription`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

[](#example-2)

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

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

### `HookBusFactory::createWithContainer()`

[](#hookbusfactorycreatewithcontainer)

ArgumentTypeDescription`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

[](#example-3)

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`](https://github.com/PrestaShopCorp/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
----------

[](#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

[](#literal)

The provided string will be used literally as the identifier.

#### Example

[](#example-4)

```
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

[](#method-hook)

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

#### Example

[](#example-5)

```
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

[](#callable)

Through a callback we can generate a custom identifier.

#### Example

[](#example-6)

```
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

[](#custom-identifier)

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

#### Example

[](#example-7)

```
use RubenMartinDev\PrestashopModuleHookBus\Identifier\HookIdentifierInterface;

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

Locator
-------

[](#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

[](#array)

#### Example

[](#example-8)

```
use RubenMartinDev\PrestashopModuleHookBus\Locator\ArrayLocator;

$locator = new ArrayLocator();

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

### Callable

[](#callable-1)

#### Example

[](#example-9)

```
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

[](#container)

#### Example

[](#example-10)

```
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

[](#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](#factory), you should implement the interface `AppendableHandlerLocatorInterface` to enable the `addHandler()` method.

#### Example

[](#example-11)

```
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
-------

[](#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()` method of the module received.

If the Handler implements the interface `NamedHandlerInterface`, the [Factory](#factory) can infer the identity automatically from the static method `getIdentityName()`.

### Example

[](#example-12)

```
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
----------

[](#exceptions)

All library exceptions extend `HookBusException`.

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

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance90

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity30

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

50d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/879f9974a2e32a4584e1f4532d148f88efb447ba053b014fd47876c517d58de3?d=identicon)[rubenmartindev](/maintainers/rubenmartindev)

---

Top Contributors

[![rubenmartindev](https://avatars.githubusercontent.com/u/1391979?v=4)](https://github.com/rubenmartindev "rubenmartindev (27 commits)")

---

Tags

bushandlershooksmodulesprestashophooksmodulesbusprestashophandlers

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/rubenmartindev-prestashop-module-hook-bus/health.svg)

```
[![Health](https://phpackages.com/badges/rubenmartindev-prestashop-module-hook-bus/health.svg)](https://phpackages.com/packages/rubenmartindev-prestashop-module-hook-bus)
```

###  Alternatives

[tormjens/eventy

The WordPress filter/action system in Laravel

439951.1k26](/packages/tormjens-eventy)[larapack/hooks

A Laravel Hook system

2161.5M21](/packages/larapack-hooks)[larapack/voyager-hooks

Hooks integrated in Voyager

2051.5M28](/packages/larapack-voyager-hooks)[prestashop/decimal

Object-oriented wrapper/shim for BC Math PHP extension. Allows for arbitrary-precision math operations.

178.9M9](/packages/prestashop-decimal)[bainternet/php-hooks

A fork of the WordPress filters hook system rolled in to a class to be ported into any PHP-based system

27624.1k8](/packages/bainternet-php-hooks)[ddoe/wysiwyg-editor-module

Summernote WYSIWYG Editor for OXID eShop.

191.0M5](/packages/ddoe-wysiwyg-editor-module)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
