Completed
Push — master ( 01582c...42d944 )
by Vitaly
02:30
created

AnnotationPathMetadataCollector   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 2
dl 0
loc 74
ccs 27
cts 27
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A collect() 0 16 3
C getDefinedClasses() 0 28 13
1
<?php declare(strict_types = 1);
2
/**
3
 * Created by Vitaly Iegorov <[email protected]>.
4
 * on 20.08.16 at 12:39
5
 */
6
namespace samsonframework\container;
7
8
use samsonframework\container\resolver\ResolverInterface;
9
use samsonframework\filemanager\FileManagerInterface;
10
11
/**
12
 * Annotation path class metadata collector.
13
 * Class read files in specified paths, resolves and collects class metadata from annotations.
14
 *
15
 * @author Vitaly Egorov <[email protected]>
16
 */
17
class AnnotationPathMetadataCollector extends AbstractMetadataCollector
18
{
19
    /** @var FileManagerInterface */
20
    protected $fileManager;
21
22
    /**
23
     * AnnotationPathMetadataCollector constructor.
24
     *
25
     * @param ResolverInterface    $resolver
26
     * @param FileManagerInterface $fileManager
27
     */
28 1
    public function __construct(ResolverInterface $resolver, FileManagerInterface $fileManager)
29
    {
30 1
        $this->fileManager = $fileManager;
31
32 1
        parent::__construct($resolver);
33 1
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38 1
    public function collect($paths) : array
39
    {
40
        /** @var array $paths */
41 1
        $classesMetadata = [];
42
43
        // Iterate all paths and get files
44 1
        foreach ($this->fileManager->scan($paths, ['php']) as $phpFile) {
45 1
            require_once($phpFile);
46
            // Read all classes in given file
47 1
            foreach ($this->getDefinedClasses(file_get_contents($phpFile)) as $className) {
48 1
                $classesMetadata[] = $this->resolver->resolve(new \ReflectionClass($className));
0 ignored issues
show
Bug introduced by
The property resolver does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
49
            }
50
        }
51
52 1
        return $classesMetadata;
53
    }
54
55
    /**
56
     * Find class names defined in PHP code.
57
     *
58
     * @param string $php PHP code for scanning
59
     *
60
     * @return string[] Collection of found class names in php code
61
     */
62 1
    protected function getDefinedClasses(string $php) : array
63
    {
64 1
        $classes = [];
65 1
        $namespace = null;
66
67
        // Append php marker for parsing file
68 1
        $php = strpos(is_string($php) ? $php : '', '<?php') !== 0 ? '<?php ' . $php : $php;
69
70 1
        $tokens = token_get_all($php);
71
72 1
        for ($i = 2, $count = count($tokens); $i < $count; $i++) {
73 1
            if ($tokens[$i - 2][0] === T_CLASS
74 1
                && $tokens[$i - 1][0] === T_WHITESPACE
75 1
                && $tokens[$i][0] === T_STRING
76
            ) {
77 1
                $classes[] = $namespace ? $namespace . '\\' . $tokens[$i][1] : $tokens[$i][1];
78 1
            } elseif ($tokens[$i - 2][0] === T_NAMESPACE
79 1
                && $tokens[$i - 1][0] === T_WHITESPACE
80 1
                && $tokens[$i][0] === T_STRING
81
            ) {
82 1
                while (isset($tokens[$i]) && is_array($tokens[$i])) {
83 1
                    $namespace .= $tokens[$i++][1];
84
                }
85
            }
86
        }
87
88 1
        return $classes;
89
    }
90
}
91