├── LICENSE ├── README.md ├── composer.json └── src ├── Action.php ├── Exceptions └── HookException.php ├── Hook.php └── Priority.php /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright (c) 2017, Josantonius 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 10 | of the Software, and to permit persons to whom the Software is furnished to do 11 | so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP Hook library 2 | 3 | [![Latest Stable Version](https://poser.pugx.org/josantonius/hook/v/stable)](https://packagist.org/packages/josantonius/hook) 4 | [![License](https://poser.pugx.org/josantonius/hook/license)](LICENSE) 5 | [![Total Downloads](https://poser.pugx.org/josantonius/hook/downloads)](https://packagist.org/packages/josantonius/hook) 6 | [![CI](https://github.com/josantonius/php-hook/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/josantonius/php-hook/actions/workflows/ci.yml) 7 | [![CodeCov](https://codecov.io/gh/josantonius/php-hook/branch/main/graph/badge.svg)](https://codecov.io/gh/josantonius/php-hook) 8 | [![PSR1](https://img.shields.io/badge/PSR-1-f57046.svg)](https://www.php-fig.org/psr/psr-1/) 9 | [![PSR4](https://img.shields.io/badge/PSR-4-9b59b6.svg)](https://www.php-fig.org/psr/psr-4/) 10 | [![PSR12](https://img.shields.io/badge/PSR-12-1abc9c.svg)](https://www.php-fig.org/psr/psr-12/) 11 | 12 | **Translations**: [Español](.github/lang/es-ES/README.md) 13 | 14 | Library for handling hooks in PHP. 15 | 16 | --- 17 | 18 | - [Requirements](#requirements) 19 | - [Installation](#installation) 20 | - [Available Classes](#available-classes) 21 | - [Action Instance](#action-instance) 22 | - [Hook Class](#hook-class) 23 | - [Priority Class](#priority-class) 24 | - [Exceptions Used](#exceptions-used) 25 | - [Usage](#usage) 26 | - [Tests](#tests) 27 | - [TODO](#todo) 28 | - [Changelog](#changelog) 29 | - [Contribution](#contribution) 30 | - [Sponsor](#sponsor) 31 | - [License](#license) 32 | 33 | --- 34 | 35 | ## Requirements 36 | 37 | - Operating System: Linux | Windows. 38 | 39 | - PHP versions: 8.1 | 8.2. 40 | 41 | ## Installation 42 | 43 | The preferred way to install this extension is through [Composer](http://getcomposer.org/download/). 44 | 45 | To install **PHP Hook library**, simply: 46 | 47 | ```console 48 | composer require josantonius/hook 49 | ``` 50 | 51 | The previous command will only install the necessary files, 52 | if you prefer to **download the entire source code** you can use: 53 | 54 | ```console 55 | composer require josantonius/hook --prefer-source 56 | ``` 57 | 58 | You can also **clone the complete repository** with Git: 59 | 60 | ```console 61 | git clone https://github.com/josantonius/php-hook.git 62 | ``` 63 | 64 | ## Available Classes 65 | 66 | ### Action Instance 67 | 68 | `Josantonius\Hook\Action` 69 | 70 | Gets action priority: 71 | 72 | ```php 73 | public function getPriority(): int; 74 | ``` 75 | 76 | Gets action callback result: 77 | 78 | ```php 79 | public function getResult(): mixed; 80 | ``` 81 | 82 | Checks if the action is done once: 83 | 84 | ```php 85 | public function isOnce(): bool; 86 | ``` 87 | 88 | Checks if the action has already been done: 89 | 90 | ```php 91 | public function wasDone(): bool; 92 | ``` 93 | 94 | ### Hook Class 95 | 96 | `Josantonius\Hook\Hook` 97 | 98 | Register new hook: 99 | 100 | ```php 101 | public function __construct(private string $name); 102 | ``` 103 | 104 | Adds action on the hook: 105 | 106 | ```php 107 | /** 108 | * Action will be maintained after performing actions and will be available if are done again. 109 | * 110 | * @see https://www.php.net/manual/en/functions.first_class_callable_syntax.php 111 | * 112 | * @return Action Added action. 113 | */ 114 | public function addAction(callable $callback, int $priority = Priority::NORMAL): Action; 115 | ``` 116 | 117 | Adds action once on the hook: 118 | 119 | ```php 120 | /** 121 | * Action will only be done once and will be deleted after it is done. 122 | * 123 | * It is recommended to use this method to release the actions 124 | * from memory if the hook actions will only be done once. 125 | * 126 | * @return Action Added action. 127 | */ 128 | public function addActionOnce(callable $callback, int $priority = Priority::NORMAL): Action; 129 | ``` 130 | 131 | Runs the added actions for the hook: 132 | 133 | ```php 134 | /** 135 | * @throws HookException if the actions have already been done. 136 | * @throws HookException if no actions were added for the hook. 137 | * 138 | * @return Action[] Done actions. 139 | */ 140 | public function doActions(mixed ...$arguments): array; 141 | ``` 142 | 143 | Checks if the hook has actions: 144 | 145 | ```php 146 | /** 147 | * True if the hook has any action even if the action has been 148 | * done before (recurring actions created with addAction). 149 | */ 150 | public function hasActions(): bool; 151 | ``` 152 | 153 | Checks if the hook has undone actions: 154 | 155 | ```php 156 | /** 157 | * True if the hook has some action left undone. 158 | */ 159 | public function hasUndoneActions(): bool; 160 | ``` 161 | 162 | Checks if the actions were done at least once: 163 | 164 | ```php 165 | /** 166 | * If doActions was executed at least once. 167 | */ 168 | public function hasDoneActions(): bool; 169 | ``` 170 | 171 | Gets hook name: 172 | 173 | ```php 174 | public function getName(): string; 175 | ``` 176 | 177 | ### Priority Class 178 | 179 | `Josantonius\Hook\Priority` 180 | 181 | Available constants: 182 | 183 | ```php 184 | public const HIGHEST = 50; 185 | public const HIGH = 100; 186 | public const NORMAL = 150; 187 | public const LOW = 200; 188 | public const LOWEST = 250; 189 | ``` 190 | 191 | ## Exceptions Used 192 | 193 | ```php 194 | use Josantonius\Hook\Exceptions\HookException; 195 | ``` 196 | 197 | ## Usage 198 | 199 | Example of use for this library: 200 | 201 | ### Register new hook 202 | 203 | ```php 204 | use Josantonius\Hook\Hook; 205 | 206 | $hook = new Hook('name'); 207 | ``` 208 | 209 | ### Adds actions on the hook 210 | 211 | ```php 212 | use Josantonius\Hook\Hook; 213 | 214 | class Foo { 215 | public static function bar() { /* do something */ } 216 | public static function baz() { /* do something */ } 217 | } 218 | 219 | $hook = new Hook('name'); 220 | 221 | $hook->addAction(Foo::bar(...)); 222 | $hook->addAction(Foo::baz(...)); 223 | ``` 224 | 225 | ### Add actions with custom priority in the hook 226 | 227 | ```php 228 | use Josantonius\Hook\Hook; 229 | use Josantonius\Hook\Priority; 230 | 231 | class Foo { 232 | public static function bar() { /* do something */ } 233 | public static function baz() { /* do something */ } 234 | } 235 | 236 | $hook = new Hook('name'); 237 | 238 | $hook->addAction(Foo::bar(...), Priority::LOW); 239 | $hook->addAction(Foo::baz(...), Priority::HIGH); 240 | ``` 241 | 242 | ### Adds actions once on the hook 243 | 244 | ```php 245 | use Josantonius\Hook\Hook; 246 | 247 | class Foo { 248 | public function bar() { /* do something */ } 249 | public function baz() { /* do something */ } 250 | } 251 | 252 | $foo = new Foo(); 253 | $hook = new Hook('name'); 254 | 255 | $hook->addActionOnce($foo->bar(...)); 256 | $hook->addActionOnce($foo->baz(...)); 257 | ``` 258 | 259 | ### Adds actions once with custom priority in the hook 260 | 261 | ```php 262 | use Josantonius\Hook\Hook; 263 | use Josantonius\Hook\Priority; 264 | 265 | class Foo { 266 | public function bar() { /* do something */ } 267 | public function baz() { /* do something */ } 268 | } 269 | 270 | $foo = new Foo(); 271 | $hook = new Hook('name'); 272 | 273 | $hook->addActionOnce($foo->bar(...), Priority::LOW); 274 | $hook->addActionOnce($foo->baz(...), Priority::HIGH); 275 | ``` 276 | 277 | ### Do actions with the same priority 278 | 279 | ```php 280 | use Josantonius\Hook\Hook; 281 | 282 | function one() { /* do something */ } 283 | function two() { /* do something */ } 284 | 285 | $hook = new Hook('name'); 286 | 287 | $hook->addAction(one(...)); 288 | $hook->addAction(two(...)); 289 | 290 | /** 291 | * The actions will be executed according to their natural order: 292 | * 293 | * one(), two()... 294 | */ 295 | $hook->doActions(); 296 | ``` 297 | 298 | ### Do actions with different priority 299 | 300 | ```php 301 | use Josantonius\Hook\Hook; 302 | use Josantonius\Hook\Priority; 303 | 304 | function a() { /* do something */ } 305 | function b() { /* do something */ } 306 | function c() { /* do something */ } 307 | 308 | $hook = new Hook('name'); 309 | 310 | $hook->addAction(a(...), priority::LOW); 311 | $hook->addAction(b(...), priority::NORMAL); 312 | $hook->addAction(c(...), priority::HIGHEST); 313 | 314 | /** 315 | * Actions will be executed according to their priority: 316 | * 317 | * c(), b(), a()... 318 | */ 319 | $hook->doActions(); 320 | ``` 321 | 322 | ### Do actions with arguments 323 | 324 | ```php 325 | use Josantonius\Hook\Hook; 326 | 327 | function foo($foo, $bar) { /* do something */ } 328 | 329 | $hook = new Hook('name'); 330 | 331 | $hook->addAction(foo(...)); 332 | 333 | $hook->doActions('foo', 'bar'); 334 | ``` 335 | 336 | ### Do actions recurrently 337 | 338 | ```php 339 | use Josantonius\Hook\Hook; 340 | 341 | function a() { /* do something */ } 342 | function b() { /* do something */ } 343 | function c() { /* do something */ } 344 | 345 | $hook = new Hook('name'); 346 | 347 | $hook->addAction(a(...)); 348 | $hook->addAction(b(...)); 349 | $hook->addActionOnce(c(...)); // Will be done only once 350 | 351 | $hook->doActions(); // a(), b(), c() 352 | 353 | $hook->doActions(); // a(), b() 354 | ``` 355 | 356 | ### Do actions only once 357 | 358 | ```php 359 | use Josantonius\Hook\Hook; 360 | 361 | function one() { /* do something */ } 362 | function two() { /* do something */ } 363 | 364 | $hook = new Hook('name'); 365 | 366 | $hook->addActionOnce(one(...)); 367 | $hook->addActionOnce(tho(...)); 368 | 369 | $hook->doActions(); 370 | 371 | // $hook->doActions(); Throw exception since there are no actions to be done 372 | ``` 373 | 374 | ### Checks if the hook has actions 375 | 376 | ```php 377 | use Josantonius\Hook\Hook; 378 | 379 | function foo() { /* do something */ } 380 | 381 | $hook = new Hook('name'); 382 | 383 | $hook->addAction(foo()); 384 | 385 | $hook->hasActions(); // true 386 | 387 | $hook->doActions(); 388 | 389 | $hook->hasActions(); // True since the action is recurrent and remains stored 390 | ``` 391 | 392 | ### Checks if the hook has undone actions 393 | 394 | ```php 395 | use Josantonius\Hook\Hook; 396 | 397 | function foo() { /* do something */ } 398 | 399 | $hook = new Hook('name'); 400 | 401 | $hook->addAction(foo()); 402 | 403 | $hook->hasUndoneActions(); // true 404 | 405 | $hook->doActions(); 406 | 407 | $hook->hasUndoneActions(); // False since there are no undone actions 408 | ``` 409 | 410 | ### Checks if the actions were done at least once 411 | 412 | ```php 413 | use Josantonius\Hook\Hook; 414 | 415 | function foo() { /* do something */ } 416 | 417 | $hook = new Hook('name'); 418 | 419 | $hook->addAction(foo()); 420 | 421 | $hook->hasDoneActions(); // false 422 | 423 | $hook->doActions(); 424 | 425 | $hook->hasDoneActions(); // True since the actions were done 426 | ``` 427 | 428 | ### Gets hook name 429 | 430 | ```php 431 | use Josantonius\Hook\Hook; 432 | 433 | $hook = new Hook('foo'); 434 | 435 | $name = $hook->getName(); // foo 436 | ``` 437 | 438 | #### Gets action priority 439 | 440 | ```php 441 | use Josantonius\Hook\Hook; 442 | 443 | function foo() { /* do something */ } 444 | 445 | $hook = new Hook('name'); 446 | 447 | $action = $hook->addAction(foo()); 448 | 449 | $action->getPriority(); 450 | ``` 451 | 452 | #### Gets action callback result 453 | 454 | ```php 455 | use Josantonius\Hook\Hook; 456 | 457 | function foo() { /* do something */ } 458 | 459 | $hook = new Hook('name'); 460 | 461 | $action = $hook->addAction(foo()); 462 | 463 | $action->getResult(); 464 | ``` 465 | 466 | #### Checks if the action is done once 467 | 468 | ```php 469 | use Josantonius\Hook\Hook; 470 | 471 | function foo() { /* do something */ } 472 | 473 | $hook = new Hook('name'); 474 | 475 | $action = $hook->addAction(foo()); 476 | 477 | $action->isOnce(); // false 478 | 479 | $action = $hook->addActionOnce(foo()); 480 | 481 | $action->isOnce(); // true 482 | ``` 483 | 484 | #### Checks if the action has already been done 485 | 486 | ```php 487 | use Josantonius\Hook\Hook; 488 | 489 | function foo() { /* do something */ } 490 | 491 | $hook = new Hook('name'); 492 | 493 | $action = $hook->addAction(foo()); 494 | 495 | $action->wasDone(); // false 496 | 497 | $hook->doActions(); 498 | 499 | $action->wasDone(); // true 500 | ``` 501 | 502 | ## Tests 503 | 504 | To run [tests](tests) you just need [composer](http://getcomposer.org/download/) 505 | and to execute the following: 506 | 507 | ```console 508 | git clone https://github.com/josantonius/php-hook.git 509 | ``` 510 | 511 | ```console 512 | cd php-hook 513 | ``` 514 | 515 | ```console 516 | composer install 517 | ``` 518 | 519 | Run unit tests with [PHPUnit](https://phpunit.de/): 520 | 521 | ```console 522 | composer phpunit 523 | ``` 524 | 525 | Run code standard tests with [PHPCS](https://github.com/squizlabs/PHP_CodeSniffer): 526 | 527 | ```console 528 | composer phpcs 529 | ``` 530 | 531 | Run [PHP Mess Detector](https://phpmd.org/) tests to detect inconsistencies in code style: 532 | 533 | ```console 534 | composer phpmd 535 | ``` 536 | 537 | Run all previous tests: 538 | 539 | ```console 540 | composer tests 541 | ``` 542 | 543 | ## TODO 544 | 545 | - [ ] Add new feature 546 | - [ ] Improve tests 547 | - [ ] Improve documentation 548 | - [ ] Improve English translation in the README file 549 | - [ ] Refactor code for disabled code style rules (see phpmd.xml and phpcs.xml) 550 | - [ ] Make Action->runCallback() accessible only to the Hook class 551 | - [ ] Add method to remove action? 552 | - [ ] Add option to add ID in actions? 553 | 554 | ## Changelog 555 | 556 | Detailed changes for each release are documented in the 557 | [release notes](https://github.com/josantonius/php-hook/releases). 558 | 559 | ## Contribution 560 | 561 | Please make sure to read the [Contributing Guide](.github/CONTRIBUTING.md), before making a pull 562 | request, start a discussion or report a issue. 563 | 564 | Thanks to all [contributors](https://github.com/josantonius/php-hook/graphs/contributors)! :heart: 565 | 566 | ## Sponsor 567 | 568 | If this project helps you to reduce your development time, 569 | [you can sponsor me](https://github.com/josantonius#sponsor) to support my open source work :blush: 570 | 571 | ## License 572 | 573 | This repository is licensed under the [MIT License](LICENSE). 574 | 575 | Copyright © 2017-present, [Josantonius](https://github.com/josantonius#contact) 576 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "josantonius/hook", 3 | "description": "Library for handling hooks.", 4 | "license": "MIT", 5 | "type": "library", 6 | "keywords": [ 7 | "hook", 8 | "actions", 9 | "action-hooks", 10 | "php" 11 | ], 12 | "authors": [ 13 | { 14 | "name": "Josantonius", 15 | "email": "hello@josantonius.dev", 16 | "homepage": "https://josantonius.dev", 17 | "role": "Developer" 18 | } 19 | ], 20 | "support": { 21 | "issues": "https://github.com/josantonius/php-hook/issues", 22 | "source": "https://github.com/josantonius/php-hook", 23 | "discussions": "https://github.com/josantonius/php-hook/discussions" 24 | }, 25 | "require": { 26 | "php": "^8.1" 27 | }, 28 | "require-dev": { 29 | "phpmd/phpmd": "^2.6", 30 | "phpunit/phpunit": "^9.5", 31 | "squizlabs/php_codesniffer": "^3.7" 32 | }, 33 | "minimum-stability": "stable", 34 | "autoload": { 35 | "psr-4": { 36 | "Josantonius\\Hook\\": "src/" 37 | } 38 | }, 39 | "autoload-dev": { 40 | "psr-4": { 41 | "Josantonius\\Hook\\Tests\\": "tests/" 42 | } 43 | }, 44 | "config": { 45 | "preferred-install": "dist" 46 | }, 47 | "extra": { 48 | "branch-alias": { 49 | "dev-master": "1.0-dev" 50 | } 51 | }, 52 | "scripts": { 53 | "coverage": "vendor/bin/phpunit --coverage-clover=coverage.xml", 54 | "fix": [ 55 | "vendor/bin/phpcbf src tests" 56 | ], 57 | "htmlCoverage": "vendor/bin/phpunit --coverage-html coverage", 58 | "phpcs": "vendor/bin/phpcs --standard=phpcs.xml $(find . -name '*.php');", 59 | "phpmd": "vendor/bin/phpmd src,tests text ./phpmd.xml", 60 | "phpunit": "vendor/bin/phpunit", 61 | "tests": [ 62 | "clear", 63 | "@phpmd", 64 | "@phpcs", 65 | "@phpunit" 66 | ] 67 | } 68 | } -------------------------------------------------------------------------------- /src/Action.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace Josantonius\Hook; 15 | 16 | /** 17 | * Action hook instance. 18 | */ 19 | class Action 20 | { 21 | /** 22 | * If the action was done. 23 | */ 24 | private bool $done = false; 25 | 26 | /** 27 | * Callback result. 28 | */ 29 | private mixed $result = null; 30 | 31 | /** 32 | * Create new action instance. 33 | */ 34 | public function __construct( 35 | private $callback, 36 | private int $priority, 37 | private bool $once 38 | ) { 39 | } 40 | 41 | /** 42 | * Gets action callback. 43 | */ 44 | public function getCallback(): callable 45 | { 46 | return $this->callback; 47 | } 48 | 49 | /** 50 | * Gets action priority. 51 | */ 52 | public function getPriority(): int 53 | { 54 | return $this->priority; 55 | } 56 | 57 | /** 58 | * Gets callback result. 59 | */ 60 | public function getResult(): mixed 61 | { 62 | return $this->result; 63 | } 64 | 65 | /** 66 | * True if the action is called only once and deleted. 67 | */ 68 | public function isOnce(): bool 69 | { 70 | return $this->once; 71 | } 72 | 73 | /** 74 | * Run action callback. 75 | */ 76 | public function runCallback(...$arguments): void 77 | { 78 | $this->result = $this->getCallback()(...$arguments); 79 | 80 | $this->done = true; 81 | } 82 | 83 | /** 84 | * If the action has already been done. 85 | */ 86 | public function wasDone(): bool 87 | { 88 | return $this->done === true; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Exceptions/HookException.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Josantonius\Hook\Exceptions; 13 | 14 | /** 15 | * Hook exception manager. 16 | */ 17 | class HookException extends \Exception 18 | { 19 | public function __construct(string $message = 'Unknown error') 20 | { 21 | parent::__construct(rtrim($message, '.') . '.'); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Hook.php: -------------------------------------------------------------------------------- 1 | 9 | * 10 | * For the full copyright and license information, please view the LICENSE 11 | * file that was distributed with this source code. 12 | */ 13 | 14 | namespace Josantonius\Hook; 15 | 16 | use Josantonius\Hook\Exceptions\HookException; 17 | 18 | /** 19 | * Hook handler. 20 | */ 21 | class Hook 22 | { 23 | private static array $hooks = []; 24 | 25 | /** 26 | * Register new hook. 27 | */ 28 | public function __construct(private string $name) 29 | { 30 | if (!isset(self::$hooks[$name])) { 31 | self::$hooks[$name] = [ 32 | 'actions' => [], 33 | 'done' => false, 34 | ]; 35 | } 36 | } 37 | 38 | /** 39 | * Add action on the hook. 40 | * 41 | * Action will be maintained after performing actions and will be available if are done again. 42 | */ 43 | public function addAction(callable $callback, int $priority = Priority::NORMAL): Action 44 | { 45 | return $this->setAction($callback, $priority, once: false); 46 | } 47 | 48 | /** 49 | * Add action once on the hook. 50 | * 51 | * Action will only be done once and will be deleted after it is done. 52 | */ 53 | public function addActionOnce(callable $callback, int $priority = Priority::NORMAL): Action 54 | { 55 | return $this->setAction($callback, $priority, once: true); 56 | } 57 | 58 | /** 59 | * Run the added actions for the hook. 60 | * 61 | * @throws HookException if the actions have already been done. 62 | * @throws HookException if no actions were added for the hook. 63 | * 64 | * @return Action[] Actions done. 65 | */ 66 | public function doActions(mixed ...$arguments): array 67 | { 68 | if (!$this->hasActions()) { 69 | $this->hasDoneActions() 70 | ? (throw new HookException("Actions for '$this->name' hook have already been done")) 71 | : (throw new HookException("No actions were added for '$this->name' hook")); 72 | } 73 | 74 | $this->sortActionsByPriority(); 75 | 76 | $actions = $this->getActions(); 77 | 78 | foreach ($actions as $key => $action) { 79 | $action->runCallback(...$arguments); 80 | if ($action->isOnce()) { 81 | unset($this->getActions()[$key]); 82 | } 83 | self::$hooks[$this->name]['done'] = true; 84 | } 85 | 86 | return $actions; 87 | } 88 | 89 | /** 90 | * Gets hook name. 91 | */ 92 | public function getName(): string 93 | { 94 | return $this->name; 95 | } 96 | 97 | /** 98 | * If there are actions to be done. 99 | */ 100 | public function hasActions(): bool 101 | { 102 | return count($this->getActions()) > 0; 103 | } 104 | 105 | /** 106 | * If the actions have already been done at least once. 107 | */ 108 | public function hasDoneActions(): bool 109 | { 110 | return self::$hooks[$this->name]['done']; 111 | } 112 | 113 | /** 114 | * If there are actions to be done. 115 | */ 116 | public function hasUndoneActions(): bool 117 | { 118 | $actions = array_filter($this->getActions(), function (Action $action) { 119 | return !$action->wasDone(); 120 | }); 121 | 122 | return count($actions) > 0; 123 | } 124 | 125 | /** 126 | * Get actions from the hook. 127 | * 128 | * @return Action[] 129 | */ 130 | private function &getActions(): array 131 | { 132 | return self::$hooks[$this->name]['actions']; 133 | } 134 | 135 | /** 136 | * Register new action on the hook. 137 | */ 138 | private function setAction(callable $callback, int $priority, bool $once): Action 139 | { 140 | $action = new Action($callback, $priority, $once); 141 | 142 | $this->getActions()[] = $action; 143 | 144 | return $action; 145 | } 146 | 147 | /** 148 | * Sort actions by priority level. 149 | */ 150 | private function sortActionsByPriority(): void 151 | { 152 | usort($this->getActions(), fn ($a, $b) => $a->getPriority() - $b->getPriority()); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/Priority.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | namespace Josantonius\Hook; 13 | 14 | /** 15 | * Priority levels. 16 | */ 17 | class Priority 18 | { 19 | public const HIGHEST = 50; 20 | 21 | public const HIGH = 100; 22 | 23 | public const NORMAL = 150; 24 | 25 | public const LOW = 200; 26 | 27 | public const LOWEST = 250; 28 | } 29 | --------------------------------------------------------------------------------