Passed
Push — master ( 893d1e...31005e )
by Kirill
03:35
created

ClassLocator::getClasses()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 23
rs 8.4444
cc 8
nc 8
nop 1
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Tokenizer;
13
14
use Spiral\Tokenizer\Exception\LocatorException;
15
16
/**
17
 * Can locate classes in a specified directory.
18
 */
19
final class ClassLocator extends AbstractLocator implements ClassesInterface
20
{
21
    /**
22
     * {@inheritdoc}
23
     */
24
    public function getClasses($target = null): array
25
    {
26
        if (!empty($target) && (is_object($target) || is_string($target))) {
27
            $target = new \ReflectionClass($target);
28
        }
29
30
        $result = [];
31
        foreach ($this->availableClasses() as $class) {
32
            try {
33
                $reflection = $this->classReflection($class);
34
            } catch (LocatorException $e) {
35
                //Ignoring
36
                continue;
37
            }
38
39
            if (!$this->isTargeted($reflection, $target) || $reflection->isInterface()) {
40
                continue;
41
            }
42
43
            $result[$reflection->getName()] = $reflection;
44
        }
45
46
        return $result;
47
    }
48
49
    /**
50
     * Classes available in finder scope.
51
     *
52
     * @return array
53
     */
54
    protected function availableClasses(): array
55
    {
56
        $classes = [];
57
58
        foreach ($this->availableReflections() as $reflection) {
59
            $classes = array_merge($classes, $reflection->getClasses());
60
        }
61
62
        return $classes;
63
    }
64
65
    /**
66
     * Check if given class targeted by locator.
67
     *
68
     * @param \ReflectionClass      $class
69
     * @param \ReflectionClass|null $target
70
     * @return bool
71
     */
72
    protected function isTargeted(\ReflectionClass $class, \ReflectionClass $target = null): bool
73
    {
74
        if (empty($target)) {
75
            return true;
76
        }
77
78
        if (!$target->isTrait()) {
79
            //Target is interface or class
80
            return $class->isSubclassOf($target) || $class->getName() == $target->getName();
81
        }
82
83
        //Checking using traits
84
        return in_array($target->getName(), $this->fetchTraits($class->getName()));
85
    }
86
}
87