hooked.php

Event hook dispatch utility
git clone git://git.finwo.net/lib/hooked.php
Log | Files | Refs

commit 222427a16b141a0d48fc76a41ed0d0c8961458f7
Author: finwo <finwo@pm.me>
Date:   Fri, 22 Apr 2016 21:52:36 +0200

Project init

Diffstat:
A.gitignore | 2++
Acomposer.json | 20++++++++++++++++++++
Acomposer.lock | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Event.php | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/Hooked.php | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 296 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +/vendor/ +/.idea/ diff --git a/composer.json b/composer.json @@ -0,0 +1,20 @@ +{ + "name": "finwo/hooked", + "require": { + "php-di/invoker": "^1.3", + "finwo/property-accessor": "^0.1.0" + }, + "license": "MIT", + "authors": [ + { + "name": "Robin Bron", + "email": "robin@finwo.nl" + } + ], + "autoload": { + "psr-4": { + "Finwo\\Hooked\\": "src" + } + }, + "minimum-stability": "stable" +} diff --git a/composer.lock b/composer.lock @@ -0,0 +1,118 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "22b07a5ee1376a180d010d50c0e16427", + "content-hash": "42d2d4a1568bc10ea9d01df1ffff256c", + "packages": [ + { + "name": "container-interop/container-interop", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e", + "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "time": "2014-12-30 15:22:37" + }, + { + "name": "finwo/property-accessor", + "version": "v0.1", + "source": { + "type": "git", + "url": "https://github.com/finwo/property-accessor.git", + "reference": "43a9b49f82ba566800068427c12d28ac48efa8e3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/finwo/property-accessor/zipball/43a9b49f82ba566800068427c12d28ac48efa8e3", + "reference": "43a9b49f82ba566800068427c12d28ac48efa8e3", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Finwo\\PropertyAccessor\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "authors": [ + { + "name": "Robin Bron", + "email": "robin@finwo.nl" + } + ], + "time": "2016-04-13 09:05:33" + }, + { + "name": "php-di/invoker", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/Invoker.git", + "reference": "c5c50237115803d7410d13d9d6afb5afe6526fac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/c5c50237115803d7410d13d9d6afb5afe6526fac", + "reference": "c5c50237115803d7410d13d9d6afb5afe6526fac", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "~1.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "phpunit/phpunit": "~4.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Invoker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Generic and extensible callable invoker", + "homepage": "https://github.com/PHP-DI/Invoker", + "keywords": [ + "callable", + "dependency", + "dependency-injection", + "injection", + "invoke", + "invoker" + ], + "time": "2016-03-20 17:49:41" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/src/Event.php b/src/Event.php @@ -0,0 +1,65 @@ +<?php + +namespace Finwo\Hooked; + +use Finwo\PropertyAccessor\PropertyAccessor; + +class Event +{ + /** + * @var string + */ + protected $name = ''; + + /** + * @var array + */ + protected $param = array(); + + /** + * @var PropertyAccessor + */ + private $accessor; + + /** + * @return PropertyAccessor + */ + private function getAccessor() + { + if (is_null($this->accessor)) { + $this->accessor = new PropertyAccessor(true); + } + return $this->accessor; + } + + /** + * @param $key + * @return array|mixed|null + * @throws \Exception + */ + public function get($key) + { + // Try directly, might be the quickest way + if (isset($this->{$key})) { + return $this->{$key}; + } + + // Look deeper + $accessor = $this->getAccessor(); + return $accessor->get($this, $key, '.'); + } + + public function set($key, $value) + { + // Try directly, might be the quickest way + if (isset($this->{$key})) { + $this->{$key} = $value; + return $this; + } + + // Look deeper + $accessor = $this->getAccessor(); + $accessor->set($this, $key, $value, '.'); + return $this; + } +} +\ No newline at end of file diff --git a/src/Hooked.php b/src/Hooked.php @@ -0,0 +1,89 @@ +<?php + +namespace Finwo\Hooked; + +use Invoker\Invoker; + +abstract class Hooked +{ + /** + * @var array + */ + protected $hooks = array(); + + /** + * @var Invoker + */ + protected $invoker; + + protected function getInvoker() + { + if (is_null($this->invoker)) { + $this->invoker = new Invoker(); + } + return $this->invoker; + } + + /** + * Add a hook the the element + * + * @param string $key + * @param \Closure $callback + * @return $this|bool + */ + public function addHook( $key = '', \Closure $callback = null ) + { + // Make sure the key is valid + if (is_string($key)) { + return false; + } + + // Make sure the callback is valid + if (!is_callable($callback)) { + return false; + } + + // Make sure the hook entry exists + if (isset($this->hooks[$key])) { + $this->hooks[$key] = array(); + } + + // Store hook + $this->hooks[$key][] = $callback; + + // Return ourselves + return $this; + } + + /** + * Runs all hooks on a certain key + * + * @param Event $event + * + * @return Hooked $this + */ + protected function dispatch( Event $event ) + { + // Pre-define some required stuff + $invoker = $this->getInvoker(); + $name = $event->get('name'); + + // Make sure the hook entry exists + if (!isset($this->hooks[$name])) { + $this->hooks[$name] = array(); + } + + foreach ($this->hooks[$name] as $hook) { + + // Call the hook + if (!$invoker->call($hook, array( + 'event' => $event + ))) { + // Break propegation if asked to + break; + } + } + + return $this; + } +} +\ No newline at end of file