1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Robo\ClassDiscovery; |
4
|
|
|
|
5
|
|
|
use Symfony\Component\Finder\Finder; |
6
|
|
|
use Composer\Autoload\ClassLoader; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Class RelativeNamespaceDiscovery |
10
|
|
|
* |
11
|
|
|
* @package Robo\Plugin\ClassDiscovery |
12
|
|
|
*/ |
13
|
|
|
class RelativeNamespaceDiscovery extends AbstractClassDiscovery |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* @var \Composer\Autoload\ClassLoader |
17
|
|
|
*/ |
18
|
|
|
protected $classLoader; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @var string |
22
|
|
|
*/ |
23
|
|
|
protected $relativeNamespace = ''; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* RelativeNamespaceDiscovery constructor. |
27
|
|
|
* |
28
|
|
|
* @param \Composer\Autoload\ClassLoader $classLoader |
29
|
|
|
*/ |
30
|
|
|
public function __construct(ClassLoader $classLoader) |
31
|
|
|
{ |
32
|
|
|
$this->classLoader = $classLoader; |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @param string $relativeNamespace |
37
|
|
|
* |
38
|
|
|
* @return $this |
39
|
|
|
*/ |
40
|
|
|
public function setRelativeNamespace($relativeNamespace) |
41
|
|
|
{ |
42
|
|
|
$this->relativeNamespace = $relativeNamespace; |
43
|
|
|
|
44
|
|
|
return $this; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* {@inheritDoc} |
49
|
|
|
*/ |
50
|
|
|
public function getClasses() |
51
|
|
|
{ |
52
|
|
|
$classes = []; |
53
|
|
|
$relativePath = $this->convertNamespaceToPath($this->relativeNamespace); |
54
|
|
|
|
55
|
|
|
foreach ($this->classLoader->getPrefixesPsr4() as $baseNamespace => $directories) { |
56
|
|
|
$directories = array_filter(array_map(function ($directory) use ($relativePath) { |
57
|
|
|
return $directory . $relativePath; |
58
|
|
|
}, $directories), 'is_dir'); |
59
|
|
|
|
60
|
|
|
if ($directories) { |
61
|
|
|
foreach ($this->search($directories, $this->searchPattern) as $file) { |
62
|
|
|
$relativePathName = $file->getRelativePathname(); |
63
|
|
|
$classes[] = $baseNamespace . $this->convertPathToNamespace($relativePath . '/' . $relativePathName); |
64
|
|
|
} |
65
|
|
|
} |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
return $classes; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* {@inheritdoc} |
73
|
|
|
*/ |
74
|
|
|
public function getFile($class) |
75
|
|
|
{ |
76
|
|
|
return $this->classLoader->findFile($class); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @param string|array $directories |
81
|
|
|
* @param string $pattern |
82
|
|
|
* |
83
|
|
|
* @return \Symfony\Component\Finder\Finder |
84
|
|
|
*/ |
85
|
|
|
protected function search($directories, $pattern) |
86
|
|
|
{ |
87
|
|
|
$finder = new Finder(); |
88
|
|
|
$finder->files() |
89
|
|
|
->name($pattern) |
90
|
|
|
->in($directories); |
|
|
|
|
91
|
|
|
|
92
|
|
|
return $finder; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* @param string $path |
97
|
|
|
* |
98
|
|
|
* @return string |
99
|
|
|
*/ |
100
|
|
|
protected function convertPathToNamespace($path) |
101
|
|
|
{ |
102
|
|
|
return str_replace(['/', '.php'], ['\\', ''], trim($path, '/')); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @param string $namespace |
107
|
|
|
* |
108
|
|
|
* @return string |
109
|
|
|
*/ |
110
|
|
|
public function convertNamespaceToPath($namespace) |
111
|
|
|
{ |
112
|
|
|
return '/' . str_replace("\\", '/', trim($namespace, '\\')); |
113
|
|
|
} |
114
|
|
|
} |
115
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.