FileLocator   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 1
dl 0
loc 105
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A locate() 0 4 1
A locateFirst() 0 4 1
B locateFile() 0 40 9
B isAbsolutePath() 0 15 9
A throwFileNotFoundException() 0 15 2
1
<?php
2
3
/*
4
 * This file is part of the Yosymfony config-loader.
5
 *
6
 * (c) YoSymfony <http://github.com/yosymfony>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Yosymfony\ConfigLoader;
13
14
use Yosymfony\ConfigLoader\Exception\FileNotFoundException;
15
16
/**
17
 * FileLocator uses an array of pre-defined paths to find files
18
 *
19
 * This file is based on Symfony FileLocatorInterface (Config component)
20
 * Created by Fabien Potencier <[email protected]>.
21
 *
22
 * @author Victor Puertas <[email protected]>
23
 */
24
class FileLocator implements FileLocatorInterface
25
{
26
    /** @var array */
27
    protected $paths;
28
29
    /**
30
     * @param string[] $paths An array of paths where to look for resources
31
     */
32
    public function __construct(array $paths = [])
33
    {
34
        $this->paths = $paths;
35
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40
    public function locate(string $name, string $currentPath = null) : array
41
    {
42
        return $this->locateFile($name, $currentPath, false);
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function locateFirst(string $name, string $currentPath = null) : string
49
    {
50
        return $this->locateFile($name, $currentPath, true);
51
    }
52
53
    /**
54
     * @return string|array
55
     */
56
    protected function locateFile(string $name, string $currentPath = null, bool $first)
57
    {
58
        if ($name == '') {
59
            throw new \InvalidArgumentException('An empty file name is not valid to be located.');
60
        }
61
62
        if ($this->isAbsolutePath($name)) {
63
            if (!file_exists($name)) {
64
                $this->throwFileNotFoundException($name);
65
            }
66
67
            return $name;
68
        }
69
70
        $paths = $this->paths;
71
72
        if ($currentPath !== null) {
73
            array_unshift($paths, $currentPath);
74
        }
75
76
        $paths = array_unique($paths);
77
        $filepaths = $notfound = [];
78
79
        foreach ($paths as $path) {
80
            if (@file_exists($file = $path.DIRECTORY_SEPARATOR.$name)) {
81
                if ($first) {
82
                    return $file;
83
                }
84
                $filepaths[] = $file;
85
            } else {
86
                $notfound[] = $file;
87
            }
88
        }
89
90
        if (!$filepaths) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $filepaths 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...
91
            $this->throwFileNotFoundException($name, $paths, $notfound);
92
        }
93
94
        return $filepaths;
95
    }
96
97
    protected function isAbsolutePath(string $file) : bool
98
    {
99
        if ('/' === $file[0] || '\\' === $file[0]
100
            || (
101
                strlen($file) > 3 && ctype_alpha($file[0])
102
                && ':' === $file[1]
103
                && ('\\' === $file[2] || '/' === $file[2])
104
            )
105
            || null !== parse_url($file, PHP_URL_SCHEME)
106
        ) {
107
            return true;
108
        }
109
110
        return false;
111
    }
112
113
    private function throwFileNotFoundException(string $file, array $paths = [], array $notFoundPaths = []) : void
114
    {
115
        $message = "The file \"{$file}\" does not exist";
116
117
        if (\count($paths) === 0) {
118
            $notFoundPaths[] = $file;
119
        } else {
120
            $pathsJoined = implode(', ', $paths);
121
            $message .= " in: {$pathsJoined}";
122
        }
123
        
124
        $message .= '.';
125
126
        throw new FileNotFoundException($message, 0, null, $notFoundPaths);
127
    }
128
}
129