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 ( 25b84b...7f9786 )
by Constantin
02:32
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 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 discoverListeners($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
}