Completed
Branch develop (c2aa4c)
by Anton
05:17
created

ClassLocator::getClasses()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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