Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

PluginHooksService::trigger()   C

Complexity

Conditions 7
Paths 17

Size

Total Lines 45
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 7.4428

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 17
nop 4
dl 0
loc 45
rs 6.7272
c 0
b 0
f 0
ccs 19
cts 24
cp 0.7917
crap 7.4428
1
<?php
2
namespace Elgg;
3
4
use Elgg\HooksRegistrationService\Hook;
0 ignored issues
show
Bug introduced by Steve Clay
This use statement conflicts with another class in this namespace, Elgg\Hook. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are 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.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/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:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
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