Phata Hook

A minimalistic hook library based on PHP's Interface feature and PSR-11 container.

Pure Nim score 15/100 · last commit 2018-09-19 · 2 stars · tests present · no docs generated

Summary

Latest Version Unknown
License Unknown
CI Status Failing
Stars 2
Forks 0
Open Issues 0
Last Commit 2018-09-19
Downloads 0
Last Indexed 2026-09-06 06:05

Installation

nimble install Phata Hook
choosenim install Phata Hook
git clone https://gitlab.com/phata/hook

OS Compatibility

Platform Linux macOS Windows FreeBSD OpenBSD NetBSD Android iOS WASM Embedded
Phata Hook - - - - - - -

Source

Repository https://gitlab.com/phata/hook
Homepage https://gitlab.com/phata/hook
Registry Source gitlab

README

Phata\Hook

build status latest stable version total downloads total downloads

A minimalistic hook library based on PHP's Interface feature and PSR-11 container.

Why

Many CMS (like Drupal, Wordpress) are based on hook system for their modules. They usually work like this:

  1. The CMS declare the hooks somewhere in their documentations.
  2. And provide a way for modules to declare that they implemented any hook.
  3. The modules implement the hook(s) as documented.
  4. Somewhere in the CMS, when the hook is "invoked", all implementations from (3) are drawn out and run against certain data. Returned values are collected.

They usually also allow modules to declare their own hook. But they need to implement (4) on their own. CMS would provide helper API for invoking the hooks.

This library provide a way to do so in a modern manner.

Installation

The recommended method is using composer:

composer require "phata/hook"

Then you should be able to use it with composer's autoloading.

Example Usage

Basic invoker map and reduce
// path to composer's autoloader
require_once '../vendor/autoload.php';

$container = new DI\Container; // or other PHP-11 compliant container
$registry = new Phata\Hook\Registry;
$invoker = new Phata\Hook\Invoker($registry, $container);


// declare existing interfaces as hook.
$registry->declareHooks([
    App\MyInterface::class,
    SomeAwesomeLibrary\Interface::class,
]);

// add class to the registry, which would
// automatically index against the declared
// hooks.
$registry->add([
    App\MyModule1::class,
    App\MyModule2::class,
    FooBar\External\Module::class,
]);


// use $invoker to invoke a hook

// Use 1: map results
$array = $invoker->map(
    App\MyInterface::class,
    function (App\MyInterface $module) {
        return $module->doSomething();
    }
);

// Use 2: reduce
$result = $invoker->reduce(
    App\MyInterface::class,
    function ($carry, App\MyInterface $module) {
        return $module->process($carry);
    },
    $someInitialValue
);

Advanced Examples

Ordered modules with SortingInvoker
nameapace App;
use Phata\Hook\SortableInterface;

class MyModule1 implements SortableInterface, MyInterface
{
    public function myProcess($input)
    {
        // some processsing of $input
        // ...
        return $output;
    }

    public function getWeight():int
    {
        // some logics to get the module's weight
        // perhapse from database operations
        // ...

        return $weight;
    }
}
// path to composer's autoloader
require_once '../vendor/autoload.php';

$container = new DI\Container; // or other PHP-11 compliant container
$registry = new Phata\Hook\Registry;
$invoker = new Phata\Hook\SortingInvoker($registry, $container);


// declare existing interfaces as hook.
$registry->declareHooks([
    Psr\Http\Server\MiddlewareInterface::class,
]);

// add class to the registry, which would
// automatically index against the declared
// hooks.
$registry->add([
    App\MyModule1::class,
    App\MyModule2::class,
    FooBar\External\Module::class,
]);

// handling the request
//
// Note: sorting invoker will sort the modules by their weight
// before invoking.
$results = $invoker->map(
    App\MyInterface::class,
    function (App\MyInterface $module) use ($input) {
        return $module->process($input);
    }
);

// use the $results
//...
Consuming PSR-7 request with PSR-15 middleware
// path to composer's autoloader
require_once '../vendor/autoload.php';

$container = new DI\Container; // or other PHP-11 compliant container
$registry = new Phata\Hook\Registry;
$invoker = new Phata\Hook\Invoker($registry, $container);


// declare existing interfaces as hook.
$registry->declareHooks([
    Psr\Http\Server\MiddlewareInterface::class,
]);

// add class to the registry, which would
// automatically index against the declared
// hooks.
$registry->add([
    App\MyModule1::class,
    App\MyModule2::class,
    FooBar\External\Module::class,
]);

// handling the request
$request = $invoker->reduce(
    Psr\Http\Server\MiddlewareInterface::class,
    function ($request, Psr\Http\Server\MiddlewareInterface::class $middleware) {
        return $middleware->process($request);
    },
    GuzzleHttp\Psr7\ServerRequest::fromGlobals()
);

// handler handles the request
//...
Reduce PSR-7 Request with `$carry` aggregation
// path to composer's autoloader
require_once '../vendor/autoload.php';

$container = new DI\Container; // or other PHP-11 compliant container
$registry = new Phata\Hook\Registry;
$invoker = new Phata\Hook\Invoker($registry, $container);


// declare existing interfaces as hook.
$registry->declareHooks([
    App\Middleware\Interface::class,
]);

// add class to the registry, which would
// automatically index against the declared
// hooks.
$registry->add([
    App\MyModule1::class,
    App\MyModule2::class,
    FooBar\External\Module::class,
]);

// handling the request
$request = GuzzleHttp\Psr7\ServerRequest::fromGlobals();
$result = $invoker->reduce(
    App\Middleware\Interface::class,
    function ($carry, App\Middleware\Interface::class $middleware) use ($request) {
        $middleware->process($carry, $request);
        return $carry;
    },
    null
);

Documentation

Class and type documentation of Phata\Hook can be found here.

License

Phata\Hook is distributed under the MIT License. You should have received a copy of the GNU Lesser General Public License along with Phata/Hook. If not, see https://opensource.org/licenses/MIT.