Skip to content

Commit

Permalink
Improve the hook manager: filter hooks and action hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
puleeno committed Sep 5, 2023
1 parent c47f529 commit cea380d
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 27 deletions.
20 changes: 20 additions & 0 deletions app/Constracts/HookConstract.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace App\Constracts;

interface HookConstract
{
public function setPriority(int $priority);

public function setCallable($callable);

public function setParamsQuantity(int $quantity);

public function getPriority(): int;

public function getCallable();

public function getParamsQuantity(): int;

public static function create($fn, $priority = 10, $paramQuantity = 1): HookConstract;
}
48 changes: 48 additions & 0 deletions app/Core/Hook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace App\Core;

use App\Constracts\HookConstract;
use App\Exceptions\NotCallableException;

abstract class Hook implements HookConstract
{
protected $callable = null;

protected $priority = 10;

protected $paramsQuantity = 1;

public function setPriority(int $priority)
{
$this->priority = $priority;
}

public function setCallable($callable)
{
if (!is_callable($callable)) {
throw new NotCallableException(var_export($callable, true));
}
$this->callable = $callable;
}

public function setParamsQuantity(int $quantity)
{
$this->paramsQuantity = $quantity;
}

public function getPriority(): int
{
return $this->priority;
}

public function getCallable()
{
return $this->callable;
}

public function getParamsQuantity(): int
{
return $this->paramsQuantity;
}
}
59 changes: 48 additions & 11 deletions app/Core/HookManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace App\Core;

use App\Constracts\HookConstract;
use App\Core\Hooks\ActionHook;
use App\Core\Hooks\FilterHook;
use App\Exceptions\NotCallableException;
use RuntimeException;

Expand Down Expand Up @@ -34,7 +37,7 @@ public static function __callStatic($name, $arguments)
return call_user_func_array([$instance, $name], $arguments);
}

public static function addAction($hookName, $fn)
public static function addAction($hookName, $fn, $priority = 10, $paramsQuantity = 1)
{
if (!is_callable($fn)) {
throw new NotCallableException(var_export($fn, true) . " is can not callable");
Expand All @@ -44,10 +47,10 @@ public static function addAction($hookName, $fn)
$instance->actions[$hookName] = [];
}

$instance->actions[$hookName][] = $fn;
$instance->actions[$hookName][] = ActionHook::create($fn, $priority, $paramsQuantity);
}

public static function addFilter($hookName, $fn)
public static function addFilter($hookName, $fn, $priority = 10, $paramsQuantity = 1)
{
if (!is_callable($fn)) {
throw new NotCallableException(var_export($fn, true) . " is can not callable");
Expand All @@ -57,43 +60,77 @@ public static function addFilter($hookName, $fn)
$instance->filters[$hookName] = [];
}

$instance->filters[$hookName][] = $fn;
$instance->filters[$hookName][] = FilterHook::create($fn, $priority, $paramsQuantity);
}

/**
* Undocumented function
*
* @param \App\Constracts\HookConstract[] $hooks
* @return void
*/
protected function sortHookByPriority(array $hooks)
{
usort($hooks, function (HookConstract $hook1, HookConstract $hook2) {
return $hook1->getPriority() - $hook2->getPriority();
});
return $hooks;
}

/**
* @param string $hookName
*
* @return \App\Core\Hooks\ActionHook[]
*/
public function getActionsByHook($hookName)
{
if (isset($this->actions[$hookName])) {
return $this->actions[$hookName];
return $this->sortHookByPriority($this->actions[$hookName]);
}
return [];
}

/**
* @param string $hookName
* @return callable[]
*
* @return \App\Core\Hooks\FilterHook[]
*/
public function getFiltersByHook($hookName): array
{
if (isset($this->filters[$hookName])) {
return $this->filters[$hookName];
return $this->sortHookByPriority($this->filters[$hookName]);
}
return [];
}

public static function executeAction($hookName, ...$params)
{
$instance = static::getInstance();
foreach ($instance->getActionsByHook($hookName) as $fn) {
call_user_func_array($fn, $params);
$hooks = $instance->getActionsByHook($hookName);

foreach ($hooks as $hook) {
$args = array_splice($params, 0, $hook->getParamsQuantity());
call_user_func_array(
$hook->getCallable(),
$args
);
}
}

public static function applyFilters($hookName, ...$params)
{
$instance = static::getInstance();
$value = count($params) > 0 ? $params[0] : null;
foreach ($instance->getFiltersByHook($hookName) as $fn) {
$value = call_user_func_array($fn, $params);
$hooks = $instance->getFiltersByHook($hookName);
foreach ($hooks as $hook) {
$value = call_user_func_array(
$hook->getCallable(),
array_splice(
$params,
0,
$hook->getParamsQuantity()
)
);
}

return $value;
Expand Down
19 changes: 19 additions & 0 deletions app/Core/Hooks/ActionHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Core\Hooks;

use App\Core\Hook;

class ActionHook extends Hook
{
public static function create($fn, $priority = 10, $paramsQuantity = 1): ActionHook
{
$hook = new ActionHook();

$hook->setCallable($fn);
$hook->setPriority($priority);
$hook->setParamsQuantity($paramsQuantity);

return $hook;
}
}
19 changes: 19 additions & 0 deletions app/Core/Hooks/FilterHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Core\Hooks;

use App\Core\Hook;

class FilterHook extends Hook
{
public static function create($fn, $priority = 10, $paramsQuantity = 1): FilterHook
{
$hook = new FilterHook();

$hook->setCallable($fn);
$hook->setPriority($priority);
$hook->setParamsQuantity($paramsQuantity);

return $hook;
}
}
9 changes: 9 additions & 0 deletions app/Exceptions/NotCallableException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@

class NotCallableException extends RuntimeException
{
public function __construct($callable = '', $code = 0)
{
if ($callable !== '') {
$message = sprintf('%s is not callable', $callable);
} else {
$message = $callable;
}
parent::__construct($message, $code);
}
}
4 changes: 2 additions & 2 deletions app/Http/Controllers/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class Controller implements ControllerConstract
public function getExtensionName(): string
{
$class_info = new ReflectionClass($this);
if (strpos($class_info->getFileName(), getPath('extension')) !== false) {
$extensionPath = str_replace(getPath('extension') . '/', '', $class_info->getFileName());
if (strpos($class_info->getFileName(), get_path('extension')) !== false) {
$extensionPath = str_replace(get_path('extension') . '/', '', $class_info->getFileName());
$extensionPathArr = explode(DIRECTORY_SEPARATOR, $extensionPath);
return $extensionPathArr[0];
}
Expand Down
22 changes: 8 additions & 14 deletions app/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,32 @@ function array_get($arr, $keyStr, $defaultValue = null)
}
}

if (!function_exists('getPath')) {
function getPath($name)
if (!function_exists('get_path')) {
function get_path($name)
{
return Constants::path($name);
}
}


if (!function_exists('getOption')) {
function getOption($optionName, $defaultValue = null)
if (!function_exists('get_option')) {
function get_option($optionName, $defaultValue = null)
{
return Option::getInstance()->get($optionName, $defaultValue);
}
}

if (!function_exists('extractExtensionNameFromFilePath')) {
function extractExtensionNameFromFilePath($path)
{
}
}


if (!function_exists('add_action')) {
function add_action($hookName, $fn)
function add_action($hookName, $fn, $priority = 10, $paramsQuantity = 1)
{
return HookManager::addAction($hookName, $fn);
return HookManager::addAction($hookName, $fn, $priority, $paramsQuantity);
}
}

if (!function_exists('add_filter')) {
function add_filter($hookName, $fn)
function add_filter($hookName, $fn, $priority = 10, $paramsQuantity = 1)
{
return HookManager::addFilter($hookName, $fn);
return HookManager::addFilter($hookName, $fn, $priority, $paramsQuantity);
}
}

0 comments on commit cea380d

Please sign in to comment.