Elgg /
Elgg
Check for conflicting imported classes with local classes.
| 1 | <?php |
||
| 2 | namespace Elgg; |
||
| 3 | |||
| 4 | use Elgg\HooksRegistrationService\Hook; |
||
|
0 ignored issues
–
show
|
|||
| 5 | |||
| 6 | /** |
||
| 7 | * Plugin Hooks (and Events) |
||
| 8 | * |
||
| 9 | * @tip Use ->hooks from the service provider. |
||
| 10 | * |
||
| 11 | * @access private |
||
| 12 | */ |
||
| 13 | class PluginHooksService extends HooksRegistrationService { |
||
| 14 | |||
| 15 | /** |
||
| 16 | * @var EventsService |
||
| 17 | */ |
||
| 18 | private $events; |
||
| 19 | |||
| 20 | /** |
||
| 21 | * Constructor |
||
| 22 | * |
||
| 23 | * @param EventsService $events Events |
||
| 24 | */ |
||
| 25 | 4417 | public function __construct(EventsService $events = null) { |
|
| 26 | 4417 | if ($events === null) { |
|
| 27 | // for unit tests |
||
| 28 | 246 | $events = new EventsService(new HandlersService()); |
|
| 29 | } |
||
| 30 | |||
| 31 | 4417 | $this->events = $events; |
|
| 32 | 4417 | } |
|
| 33 | |||
| 34 | /** |
||
| 35 | * Get the events API |
||
| 36 | * |
||
| 37 | * @return EventsService |
||
| 38 | */ |
||
| 39 | 5031 | public function getEvents() { |
|
| 40 | 5031 | return $this->events; |
|
| 41 | } |
||
| 42 | |||
| 43 | /** |
||
| 44 | * Triggers a plugin hook |
||
| 45 | * |
||
| 46 | * @see elgg_trigger_plugin_hook |
||
| 47 | * @access private |
||
| 48 | */ |
||
| 49 | 1896 | public function trigger($name, $type, $params = null, $value = null) { |
|
| 50 | |||
| 51 | // This starts as a string, but if a handler type-hints an object we convert it on-demand inside |
||
| 52 | // \Elgg\HandlersService::call and keep it alive during all handler calls. We do this because |
||
| 53 | // creating objects for every triggering is expensive. |
||
| 54 | 1896 | $hook = 'hook'; |
|
| 55 | /* @var Hook|string $hook */ |
||
| 56 | |||
| 57 | 1896 | $handlers = $this->events->getHandlersService(); |
|
| 58 | |||
| 59 | 1896 | foreach ($this->getOrderedHandlers($name, $type) as $handler) { |
|
| 60 | 517 | $exit_warning = null; |
|
| 61 | |||
| 62 | 517 | if (in_array($name, ['forward', 'action', 'route'])) { |
|
| 63 | // assume the handler is going to exit the request... |
||
| 64 | 30 | $exit_warning = function () use ($name, $type, $handler, $handlers) { |
|
| 65 | _elgg_services()->deprecation->sendNotice( |
||
| 66 | "'$name', '$type' plugin hook should not be used to serve a response. Instead return an " |
||
| 67 | . "appropriate ResponseBuilder instance from an action or page handler. Do not terminate " |
||
| 68 | . "code execution with exit() or die() in {$handlers->describeCallable($handler)}", |
||
| 69 | '2.3' |
||
| 70 | ); |
||
| 71 | 30 | }; |
|
| 72 | 30 | $this->events->registerHandler('shutdown', 'system', $exit_warning); |
|
| 73 | } |
||
| 74 | |||
| 75 | 517 | list($success, $return, $hook) = $handlers->call($handler, $hook, [$name, $type, $value, $params]); |
|
| 76 | |||
| 77 | 516 | if ($exit_warning) { |
|
| 78 | // an exit did not occur, so no need for the warning... |
||
| 79 | 30 | $this->events->unregisterHandler('shutdown', 'system', $exit_warning); |
|
| 80 | } |
||
| 81 | |||
| 82 | 516 | if (!$success) { |
|
| 83 | 2 | continue; |
|
| 84 | } |
||
| 85 | 515 | if ($return !== null) { |
|
| 86 | 483 | $value = $return; |
|
| 87 | 483 | if ($hook instanceof Hook) { |
|
| 88 | 515 | $hook->setValue($return); |
|
| 89 | } |
||
| 90 | } |
||
| 91 | } |
||
| 92 | |||
| 93 | 1895 | return $value; |
|
| 94 | } |
||
| 95 | |||
| 96 | /** |
||
| 97 | * {@inheritdoc} |
||
| 98 | */ |
||
| 99 | 4980 | public function registerHandler($name, $type, $callback, $priority = 500) { |
|
| 100 | 4980 | if (($name == 'view' || $name == 'view_vars') && $type !== 'all') { |
|
| 101 | 35 | $type = ViewsService::canonicalizeViewName($type); |
|
| 102 | } |
||
| 103 | |||
| 104 | 4980 | return parent::registerHandler($name, $type, $callback, $priority); |
|
| 105 | } |
||
| 106 | } |
||
| 107 |
Let?s assume that you have a directory layout like this:
. |-- OtherDir | |-- Bar.php | `-- Foo.php `-- SomeDir `-- Foo.phpand let?s assume the following content of
Bar.php:If both files
OtherDir/Foo.phpandSomeDir/Foo.phpare loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.phpHowever, as
OtherDir/Foo.phpdoes not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: