diff --git a/app/Constracts/HookConstract.php b/app/Constracts/HookConstract.php new file mode 100644 index 0000000..0270a7f --- /dev/null +++ b/app/Constracts/HookConstract.php @@ -0,0 +1,20 @@ +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; + } +} diff --git a/app/Core/HookManager.php b/app/Core/HookManager.php index 5c3a956..96eed7f 100644 --- a/app/Core/HookManager.php +++ b/app/Core/HookManager.php @@ -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; @@ -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"); @@ -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"); @@ -57,25 +60,45 @@ 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 []; } @@ -83,8 +106,14 @@ public function getFiltersByHook($hookName): array 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 + ); } } @@ -92,8 +121,16 @@ 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; diff --git a/app/Core/Hooks/ActionHook.php b/app/Core/Hooks/ActionHook.php new file mode 100644 index 0000000..63cbaac --- /dev/null +++ b/app/Core/Hooks/ActionHook.php @@ -0,0 +1,19 @@ +setCallable($fn); + $hook->setPriority($priority); + $hook->setParamsQuantity($paramsQuantity); + + return $hook; + } +} diff --git a/app/Core/Hooks/FilterHook.php b/app/Core/Hooks/FilterHook.php new file mode 100644 index 0000000..1fb3c46 --- /dev/null +++ b/app/Core/Hooks/FilterHook.php @@ -0,0 +1,19 @@ +setCallable($fn); + $hook->setPriority($priority); + $hook->setParamsQuantity($paramsQuantity); + + return $hook; + } +} diff --git a/app/Exceptions/NotCallableException.php b/app/Exceptions/NotCallableException.php index 1d22db5..e127a05 100644 --- a/app/Exceptions/NotCallableException.php +++ b/app/Exceptions/NotCallableException.php @@ -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); + } } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index a8a49a0..c68a697 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -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]; } diff --git a/app/helpers.php b/app/helpers.php index 14b3e9d..276f1e4 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -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); } }