DiscoverEvents::classFromFile()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace ByTIC\EventDispatcher\Discovery;
4
5
use Nip\Utility\Oop;
6
use Nip\Utility\Reflector;
0 ignored issues
show
Bug introduced by
The type Nip\Utility\Reflector was not found. Maybe you did not declare it correctly or list all dependencies?

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:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Nip\Utility\Str;
8
use ReflectionClass;
9
use ReflectionException;
10
use Symfony\Component\Finder\Finder;
11
use Symfony\Component\Finder\SplFileInfo;
12
13
/**
14
 * Class DiscoverEvents
15
 * @package ByTIC\EventDispatcher\ListenerProviders\Discover
16
 *
17
 * @internal
18
 */
19
class DiscoverEvents
20
{
21
    /**
22
     * Get all of the events and listeners by searching the given listener directory.
23
     *
24
     * @param array|string $listenerPaths
25
     * @return array
26
     */
27
    public static function within($listenerPaths): array
28
    {
29
        return static::getListenerEvents(
30
            static::getListenerClasses($listenerPaths)
31
        );
32
    }
33
34
    /**
35
     * @param array|string $paths
36
     * @return array
37
     */
38
    protected static function getListenerClasses($paths): iterable
39
    {
40
        $paths = is_array($paths) ? $paths : [$paths];
41
        $files = (new Finder)->files()->in($paths);
42
43
        foreach ($files as $file) {
44
            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...
45
        }
46
    }
47
48
    /**
49
     * Extract the class name from the given file path.
50
     *
51
     * @param \SplFileInfo $file
52
     * @param string $basePath
53
     * @return array
54
     */
55
    protected static function classFromFile(SplFileInfo $file)
56
    {
57
        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

57
        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...
58
    }
59
60
    /**
61
     * @param array $listeners
62
     * @return array
63
     */
64
    protected static function getListenerEvents(iterable $listeners): array
65
    {
66
        $return = [];
67
        foreach ($listeners as $listener) {
68
            $return = static::getListenerEventsFromClass($listener, $return);
69
        }
70
        return array_filter($return);
71
    }
72
73
    /**
74
     * @param string $class
75
     * @param $listenerEvents
76
     * @return array
77
     */
78
    protected static function getListenerEventsFromClass(string $class, $listenerEvents = []): array
79
    {
80
        try {
81
            $listener = new ReflectionClass($class);
82
            foreach ($listener->getMethods() as $method) {
83
                if (!$method->isPublic()) {
84
                    continue;
85
                }
86
                if (!Str::is('handle*', $method->name) ||
87
                    !isset($method->getParameters()[0])) {
88
                    continue;
89
                }
90
                $events = Reflector::getParameterClassNames($method->getParameters()[0]);
91
                foreach ($events as $event) {
92
                    $key = $listener->name . '@' . $method->name;
93
                    $listenerEvents[$event][$key] = [$listener->getName(), $method->getName()];
94
                }
95
            }
96
        } catch (ReflectionException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
97
        }
98
        return $listenerEvents;
99
    }
100
}
101