GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 7a5cc3...25b84b )
by Constantin
03:09
created

MethodListenerDiscovery::discoverListeners()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 13
cts 13
cp 1
rs 8.5125
c 0
b 0
f 0
cc 5
eloc 12
nc 8
nop 1
crap 5
1
<?php
2
/******************************************************************************
3
 * Copyright (c) 2016 Constantin Galbenu <[email protected]>             *
4
 ******************************************************************************/
5
6
namespace Gica\CodeAnalysis;
7
8
9
use Gica\CodeAnalysis\MethodListenerDiscovery\ClassSorter;
10
use Gica\CodeAnalysis\MethodListenerDiscovery\ListenerClassValidator;
11
use Gica\CodeAnalysis\MethodListenerDiscovery\ListenerMethod;
12
use Gica\CodeAnalysis\MethodListenerDiscovery\MessageClassDetector;
13
use Gica\CodeAnalysis\Traits\FilesInDirectoryExtracter;
14
15
class MethodListenerDiscovery
16
{
17
    use FilesInDirectoryExtracter;
18
19
    protected $eventToListenerMap = [];
20
    /**
21
     * @var MessageClassDetector
22
     */
23
    private $messageClassDetector;
24
25
    /** @var ListenerClassValidator */
26
    private $classValidator;
27
28
    /** @var ListenerMethod[] */
29
    private $allEventsListeners = [];
30
    /**
31
     * @var ClassSorter
32
     */
33
    private $classSorter;
34
    /**
35
     * @var PhpClassInFileInspector
36
     */
37
    private $phpClassInFileInspector;
38
39 1
    public function __construct(
40
        MessageClassDetector $messageClassDetector,
41
        ListenerClassValidator $classValidator,
42
        ClassSorter $classSorter,
43
        PhpClassInFileInspector $phpClassInFileInspector = null
44
    )
45
    {
46 1
        $this->messageClassDetector = $messageClassDetector;
47 1
        $this->classValidator = $classValidator;
48 1
        $this->classSorter = $classSorter;
49 1
        $this->phpClassInFileInspector = $phpClassInFileInspector ?? new PhpClassInFileInspector();
50 1
    }
51
52
53 1
    public function discover($directory)
54
    {
55 1
        $files = $this->getFilesInDirectory($directory);
56
57 1
        $files = $this->filterFiles($files);
58
59 1
        foreach ($files as $file) {
60 1
            $fullFilePath = $file;
61
62 1
            $listenerEntries = $this->extractListenerMethodsFromFile($fullFilePath);
63
64 1
            if ($listenerEntries) {
65 1
                foreach ($listenerEntries as $entry) {
66 1
                    $this->addListenerToEvents($entry);
67
                }
68
            }
69
        }
70
71 1
        $this->allEventsListeners = $this->sortListeners($this->allEventsListeners);
72
73 1
        foreach ($this->eventToListenerMap as $eventClass => $listeners) {
74 1
            $this->eventToListenerMap[$eventClass] = $this->sortListeners($listeners);
75
        }
76 1
    }
77
78
    /**
79
     * @param string $filePath
80
     * @return bool
81
     */
82 1
    protected function isListenerFileName($filePath)
83
    {
84 1
        return preg_match('#\.php$#ims', $filePath);
85
    }
86
87
    /**
88
     * @param $fullFilePath
89
     * @return bool|\Gica\CodeAnalysis\MethodListenerDiscovery\ListenerMethod[]
90
     */
91 1
    protected function extractListenerMethodsFromFile($fullFilePath)
92
    {
93 1
        $fqn = $this->phpClassInFileInspector->getFullyQualifiedClassName($fullFilePath);
94
95 1
        if (null === $fqn) {
96 1
            return false;
97
        }
98
99 1
        return $this->findListenerMethodsInClass($fqn);
100
    }
101
102 1
    protected function addListenerToEvents(ListenerMethod $listener)
103
    {
104 1
        $this->eventToListenerMap[$listener->getEventClassName()][] = $listener;
105 1
        $this->allEventsListeners[] = $listener;
106 1
    }
107
108
    /**
109
     * @param ListenerMethod[] $listeners
110
     * @return ListenerMethod[]
111
     */
112 1
    private function sortListeners($listeners)
113
    {
114
        usort($listeners, function (ListenerMethod $a, ListenerMethod $b) {
115 1
            return $this->classSorter->__invoke($a->getClass(), $b->getClass());
116 1
        });
117
118 1
        return $listeners;
119
    }
120
121 1
    public function getEventToListenerMap()
122
    {
123 1
        return $this->eventToListenerMap;
124
    }
125
126
    /**
127
     * @return ListenerMethod[]
128
     */
129 1
    public function getAllEventsListeners(): array
130
    {
131 1
        return $this->allEventsListeners;
132
    }
133
134
    protected function filterFiles(array $files)
135
    {
136 1
        return array_filter($files, function ($file) {
137 1
            return $this->isListenerFileName($file);
138 1
        });
139
    }
140
141
    /**
142
     * @param $className
143
     * @return ListenerMethod[]
144
     */
145 1
    private function findListenerMethodsInClass($className)
146
    {
147 1
        $result = [];
148
149 1
        $reflectionClass = new \ReflectionClass($className);
150
151 1
        if (!$this->classValidator->isClassAccepted($reflectionClass)) {
152 1
            return [];
153
        }
154
155 1
        foreach ($reflectionClass->getMethods() as $reflectionMethod) {
156
157 1
            if (!$this->isValidListenerMethod($reflectionMethod)) {
158 1
                continue;
159
            }
160
161 1
            $eventClass = $this->getMessageClassFromMethod($reflectionMethod);
162
163 1
            if ($eventClass) {
164 1
                $result[] = new ListenerMethod($reflectionClass, $reflectionMethod->name, $eventClass);
165
            }
166
        }
167
168 1
        return $result;
169
    }
170
171 1
    private function getMessageClassFromMethod(\ReflectionMethod $reflectionMethod)
172
    {
173 1
        if (!$this->isMethodAcccepted($reflectionMethod)) {
174 1
            return false;
175
        }
176
177 1
        foreach ($reflectionMethod->getParameters() as $reflectionParameter) {
178 1
            $typeHintedClass = $reflectionParameter->getClass();
179
180 1
            if ($typeHintedClass) {
181 1
                if ($this->isOurMessageClass($typeHintedClass)) {
182 1
                    return $typeHintedClass->name;
183
                }
184
            }
185
        }
186
187 1
        return false;
188
    }
189
190 1
    private function isValidListenerMethod(\ReflectionMethod $reflectionMethod)
191
    {
192 1
        if ($reflectionMethod->getNumberOfParameters() == 0)
193 1
            return false;
194
195 1
        return true;
196
    }
197
198 1
    private function isOurMessageClass(\ReflectionClass $typeHintedClass)
199
    {
200 1
        return $this->messageClassDetector->isMessageClass($typeHintedClass);
201
    }
202
203 1
    private function isMethodAcccepted(\ReflectionMethod $reflectionMethod)
204
    {
205 1
        return $this->messageClassDetector->isMethodAccepted($reflectionMethod);
206
    }
207
}