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

AnnotationPathMetadataCollector::collect()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 1
crap 3
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