Passed
Push — master ( 69d06b...aefa73 )
by Gabriel
06:27 queued 12s
created

DiscoverEvents   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 22
dl 0
loc 66
rs 10
c 0
b 0
f 0
wmc 12

4 Methods

Rating   Name   Duplication   Size   Complexity  
B getListenerEvents() 0 21 7
A classFromFile() 0 3 1
A getListenerClasses() 0 7 3
A within() 0 4 1
1
<?php
2
3
namespace ByTIC\EventDispatcher\Discovery;
4
5
use Nip\Utility\Oop;
6
use Nip\Utility\Str;
7
use ReflectionClass;
8
use ReflectionException;
9
use Symfony\Component\Finder\Finder;
10
use Symfony\Component\Finder\SplFileInfo;
11
12
/**
13
 * Class DiscoverEvents
14
 * @package ByTIC\EventDispatcher\ListenerProviders\Discover
15
 *
16
 * @internal
17
 */
18
class DiscoverEvents
19
{
20
    /**
21
     * Get all of the events and listeners by searching the given listener directory.
22
     *
23
     * @param array|string $listenerPaths
24
     * @return array
25
     */
26
    public static function within($listenerPaths): array
27
    {
28
        return static::getListenerEvents(
29
            static::getListenerClasses($listenerPaths)
30
        );
31
    }
32
33
    /**
34
     * @param array|string $paths
35
     * @return array
36
     */
37
    protected static function getListenerClasses($paths): iterable
38
    {
39
        $paths = is_array($paths) ? $paths : [$paths];
40
        $files = (new Finder)->files()->in($paths);
41
42
        foreach ($files as $file) {
43
            yield from static::classFromFile($file);
0 ignored issues
show
Bug Best Practice introduced by
The expression YieldFromNode returns the type Generator which is incompatible with the documented return type array.
Loading history...
44
        }
45
    }
46
47
    /**
48
     * Extract the class name from the given file path.
49
     *
50
     * @param  \SplFileInfo  $file
51
     * @param  string  $basePath
52
     * @return array
53
     */
54
    protected static function classFromFile(SplFileInfo $file)
55
    {
56
        return Oop::classesInFile($file);
0 ignored issues
show
Bug introduced by
The method classesInFile() does not exist on Nip\Utility\Oop. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
        return Oop::/** @scrutinizer ignore-call */ classesInFile($file);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
57
    }
58
59
    /**
60
     * @param array $listeners
61
     * @return array
62
     */
63
    protected static function getListenerEvents(iterable $listeners): array
64
    {
65
        $listenerEvents = [];
66
        foreach ($listeners as $listener) {
67
            try {
68
                $listener = new ReflectionClass($listener);
69
                foreach ($listener->getMethods() as $method) {
70
                    if (!$method->isPublic()) {
71
                        continue;
72
                    }
73
                    if (!Str::is('handle*', $method->name) ||
74
                        !isset($method->getParameters()[0])) {
75
                        continue;
76
                    }
77
                    $eventName = (string)$method->getParameters()[0]->getType();
78
                    $listenerEvents[$eventName][] = [$listener->getName(), $method->getName()];
79
                }
80
            } catch (ReflectionException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
81
            }
82
        }
83
        return array_filter($listenerEvents);
84
    }
85
}
86