Completed
Push — master ( 76ad1f...386b33 )
by Greg
05:49
created

src/ClassDiscovery/RelativeNamespaceDiscovery.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $directories of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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);
0 ignored issues
show
It seems like $directories defined by parameter $directories on line 85 can also be of type array; however, Symfony\Component\Finder\Finder::in() does only seem to accept string|array<integer,string>, maybe add an additional type check?

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.

Loading history...
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