1 | <?php |
||||
2 | |||||
3 | declare(strict_types=1); |
||||
4 | |||||
5 | namespace Yiisoft\Yii\Event; |
||||
6 | |||||
7 | use Psr\Container\ContainerExceptionInterface; |
||||
8 | use Psr\EventDispatcher\EventDispatcherInterface; |
||||
9 | use Psr\EventDispatcher\ListenerProviderInterface; |
||||
10 | use Yiisoft\Di\Container; |
||||
11 | use Yiisoft\Di\Support\ServiceProvider; |
||||
12 | use Yiisoft\EventDispatcher\Dispatcher\Dispatcher; |
||||
13 | use Yiisoft\EventDispatcher\Provider\ListenerCollection; |
||||
0 ignored issues
–
show
|
|||||
14 | use Yiisoft\EventDispatcher\Provider\Provider; |
||||
15 | use Yiisoft\Injector\Injector; |
||||
16 | |||||
17 | final class EventDispatcherProvider extends ServiceProvider |
||||
18 | { |
||||
19 | private array $eventListeners; |
||||
20 | |||||
21 | /** |
||||
22 | * @param array $eventListeners Event listener list in format ['eventName1' => [$listener1, $listener2, ...]] |
||||
23 | */ |
||||
24 | 2 | public function __construct(array $eventListeners) |
|||
25 | { |
||||
26 | 2 | $this->eventListeners = $eventListeners; |
|||
27 | 2 | } |
|||
28 | |||||
29 | /** |
||||
30 | * @suppress PhanAccessMethodProtected |
||||
31 | */ |
||||
32 | 2 | public function register(Container $container): void |
|||
33 | { |
||||
34 | 2 | $listenerCollection = new ListenerCollection(); |
|||
35 | |||||
36 | 2 | $injector = new Injector($container); |
|||
37 | |||||
38 | 2 | foreach ($this->eventListeners as $eventName => $listeners) { |
|||
39 | 2 | if (!is_string($eventName)) { |
|||
40 | throw new InvalidEventConfigurationFormatException( |
||||
41 | 'Incorrect event listener format. Format with event name must be used.' |
||||
42 | ); |
||||
43 | } |
||||
44 | |||||
45 | 2 | if (!is_array($listeners)) { |
|||
46 | $type = $this->isCallable($listeners, $container) ? 'callable' : gettype($listeners); |
||||
47 | |||||
48 | throw new InvalidEventConfigurationFormatException( |
||||
49 | "Event listeners for $eventName must be an array, $type given." |
||||
50 | ); |
||||
51 | } |
||||
52 | |||||
53 | 2 | foreach ($listeners as $callable) { |
|||
54 | try { |
||||
55 | 2 | if (!$this->isCallable($callable, $container)) { |
|||
56 | $type = gettype($listeners); |
||||
57 | |||||
58 | throw new InvalidListenerConfigurationException( |
||||
59 | 2 | "Listener must be a callable. $type given." |
|||
60 | ); |
||||
61 | } |
||||
62 | } catch (ContainerExceptionInterface $exception) { |
||||
63 | throw new InvalidListenerConfigurationException( |
||||
64 | "Could not instantiate event listener or listener class has invalid configuration.", |
||||
65 | 0, |
||||
66 | $exception |
||||
67 | ); |
||||
68 | } |
||||
69 | |||||
70 | 2 | $listener = static function (object $event) use ($injector, $callable, $container) { |
|||
71 | 1 | if (is_array($callable) && !is_object($callable[0])) { |
|||
72 | $callable = [$container->get($callable[0]), $callable[1]]; |
||||
73 | } |
||||
74 | |||||
75 | 1 | return $injector->invoke($callable, [$event]); |
|||
76 | 2 | }; |
|||
77 | 2 | $listenerCollection = $listenerCollection->add($listener, $eventName); |
|||
78 | } |
||||
79 | } |
||||
80 | |||||
81 | 2 | $provider = new Provider($listenerCollection); |
|||
0 ignored issues
–
show
The call to
Yiisoft\EventDispatcher\...Provider::__construct() has too many arguments starting with $listenerCollection .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||
82 | |||||
83 | $container->set(ListenerProviderInterface::class, $provider); |
||||
84 | $container->set(EventDispatcherInterface::class, Dispatcher::class); |
||||
85 | 2 | } |
|||
86 | |||||
87 | 2 | private function isCallable($definition, Container $container): bool |
|||
88 | { |
||||
89 | 2 | if (is_callable($definition)) { |
|||
90 | 2 | return true; |
|||
91 | } |
||||
92 | |||||
93 | if ( |
||||
94 | 1 | is_array($definition) |
|||
95 | 1 | && array_keys($definition) === [0, 1] |
|||
96 | 1 | && is_string($definition[0]) |
|||
97 | 1 | && $container->has($definition[0]) |
|||
98 | ) { |
||||
99 | 1 | $object = $container->get($definition[0]); |
|||
100 | |||||
101 | 1 | return method_exists($object, $definition[1]); |
|||
102 | } |
||||
103 | |||||
104 | return false; |
||||
105 | } |
||||
106 | } |
||||
107 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths