Passed
Push — master ( ac3c5f...1ae773 )
by Thomas
02:32
created

FindByNamespace::getPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 * Created by PhpStorm.
5
 * User: tom
6
 * Date: 18/06/2016
7
 * Time: 16:23
8
 */
9
10
namespace twhiston\twLib\Discovery;
11
12
use RecursiveDirectoryIterator;
13
use RecursiveIteratorIterator;
14
use RegexIterator;
15
use twhiston\twLib\Str\Str;
16
17
class FindByNamespace
18
{
19
20
    protected $path;
21
22
    protected $data;
23
24
    /**
25
     * FindByNamespace constructor.
26
     * @param $path
27
     */
28 3
    public function __construct($path = null)
29
    {
30 3
        $this->path = ($path === null || $path === '') ? __DIR__ : $path;
31 3
        $this->data = [];
32 3
        $this->data[$path] = [];
33 3
    }
34
35 1
    public function setPath($path)
36
    {
37 1
        $this->path = $path;
38 1
    }
39
40
    /**
41
     * @return null
42
     */
43 1
    public function getPath()
44
    {
45 1
        return $this->path;
46
    }
47
48
49
50 2
    public function find($needle = null, $rebuild = false)
51
    {
52 2
        $this->buildData($rebuild);
53 2
        return $this->filterData($needle);
54
    }
55
56 2
    protected function buildData($rebuild)
57
    {
58
59 2
        if ($rebuild === true || empty($this->data[$this->path])) {
60 2
            $allFiles = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->path));
61 2
            $phpFiles = new RegexIterator($allFiles, '/\.php$/');
62 2
            $this->data[$this->path] = [];
63 2
            foreach ($phpFiles as $phpFile) {
64
                //tokenize file
65 2
                $realPath = $this->getRealPath($phpFile);
66 2
                if (file_exists($realPath)) {
67 2
                    $content = file_get_contents($realPath);
68 2
                    $this->processTokens(token_get_all($content), $this->path);
69 2
                }
70 2
            }
71 2
        }
72 2
    }
73
74 2
    protected function getRealPath($phpFile)
75
    {
76 2
        if (Str::startsWith($this->path, ['phar'])) {
77
            $realPath = $phpFile->getPath() . '/' . $phpFile->getFilename();
78
        } else {
79 2
            $realPath = $phpFile->getRealPath();
80
        }
81 2
        return $realPath;
82
    }
83
84 2
    protected function processTokens(array $tokens, $realPath)
85
    {
86 2
        $namespace = '';
87 2
        for ($index = 0; isset($tokens[$index]); $index++) {
88 2
            if (!isset($tokens[$index][0])) {
89
                continue;
90
            }
91 2
            if (T_NAMESPACE === $tokens[$index][0]) {
92 2
                $index += 2; // Skip namespace keyword and whitespace
93 2
                while (isset($tokens[$index]) && is_array($tokens[$index])) {
94 2
                    $namespace .= $tokens[$index++][1];
95 2
                }
96 2
            }
97 2
            if (T_CLASS === $tokens[$index][0]) {
98 2
                $index += 2; // Skip class keyword and whitespace
99 2
                if (is_array($tokens[$index]) && array_key_exists(1, $tokens[$index])) {
100 2
                    $this->data[$realPath][] = $namespace . '\\' . $tokens[$index][1];
101 2
                }
102 2
            }
103 2
        }
104 2
    }
105
106
107
    protected function filterData($needle)
108
    {
109 2
        return array_values(array_filter($this->data[$this->path], function ($var) use ($needle) {
110 2
            if (strpos($var, $needle) !== false) {
111 1
                return true;
112
            }
113 2
            return false;
114 2
        }));
115
    }
116
117
}