PrioritizedPathsResolver   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 192
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 30
lcom 1
cbo 7
dl 0
loc 192
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
C addPath() 0 23 7
A getPaths() 0 4 1
A clearPaths() 0 4 1
A addPaths() 0 6 2
A setPaths() 0 12 4
A normalizePath() 0 7 1
A setLfiProtection() 0 4 1
A isLfiProtectionOn() 0 4 1
B resolve() 0 20 5
B collect() 0 28 6
1
<?php
2
3
namespace AssetManager\Core\Resolver;
4
5
use ArrayAccess;
6
use Assetic\Asset\FileAsset;
7
use Assetic\Factory\Resource\DirectoryResource;
8
use AssetManager\Core\Exception;
9
use AssetManager\Core\Service\MimeResolver;
10
use SplFileInfo;
11
use Traversable;
12
use Zend\Stdlib\PriorityQueue;
13
use Zend\Stdlib\SplStack;
14
15
/**
16
 * This resolver allows you to resolve from a multitude of prioritized paths.
17
 */
18
class PrioritizedPathsResolver extends FileResolverAbstract
19
{
20
    /**
21
     * @var PriorityQueue|ResolverInterface[]
22
     */
23
    protected $paths;
24
25
    /**
26
     * Flag indicating whether or not LFI protection for rendering view scripts is enabled
27
     *
28
     * @var bool
29
     */
30
    protected $lfiProtectionOn = true;
31
32
    /**
33
     * Constructor.
34
     * Construct object and set a new PriorityQueue.
35
     */
36
    public function __construct()
37
    {
38
        $this->paths = new PriorityQueue();
39
    }
40
41
    /**
42
     * {@inheritDoc}
43
     */
44
    public function addPath($path)
45
    {
46
        if (is_string($path)) {
47
            $this->paths->insert($this->normalizePath($path), 1);
48
49
            return;
50
        }
51
52
        if (!is_array($path) && !$path instanceof ArrayAccess) {
53
            throw new Exception\InvalidArgumentException(sprintf(
54
                'Provided path must be an array or an instance of ArrayAccess, %s given',
55
                is_object($path) ? get_class($path) : gettype($path)
56
            ));
57
        }
58
59
        if (isset($path['priority']) && isset($path['path'])) {
60
            $this->paths->insert($this->normalizePath($path['path']), $path['priority']);
61
62
            return;
63
        }
64
65
        throw new Exception\InvalidArgumentException('Provided array must contain both keys "priority" and "path"');
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     */
71
    public function getPaths()
72
    {
73
        return $this->paths;
74
    }
75
76
    /**
77
     * {@inheritDoc}
78
     */
79
    public function clearPaths()
80
    {
81
        $this->paths = new PriorityQueue();
82
    }
83
84
     /**
85
      * Add many paths to the stack at once
86
      *
87
      * @param  array|Traversable $paths
88
      *
89
      * @return void
90
      */
91
    public function addPaths($paths)
92
    {
93
        foreach ($paths as $path) {
94
            $this->addPath($path);
95
        }
96
    }
97
98
    /**
99
     * Rest the path stack to the paths provided
100
     *
101
     * @param  Traversable|array                  $paths
102
     *
103
     * @throws Exception\InvalidArgumentException
104
     */
105
    public function setPaths($paths)
106
    {
107
        if (!is_array($paths) && !$paths instanceof Traversable) {
108
            throw new Exception\InvalidArgumentException(sprintf(
109
                'Invalid argument provided for $paths, expecting either an array or Traversable object, "%s" given',
110
                is_object($paths) ? get_class($paths) : gettype($paths)
111
            ));
112
        }
113
114
        $this->clearPaths();
115
        $this->addPaths($paths);
116
    }
117
118
    /**
119
     * Normalize a path for insertion in the stack
120
     *
121
     * @param  string $path
122
     *
123
     * @return string
124
     */
125
    protected function normalizePath($path)
126
    {
127
        $path = rtrim($path, '/\\');
128
        $path .= DIRECTORY_SEPARATOR;
129
130
        return $path;
131
    }
132
133
    /**
134
     * Set LFI protection flag
135
     *
136
     * @param  bool $flag
137
     * @return void
138
     */
139
    public function setLfiProtection($flag)
140
    {
141
        $this->lfiProtectionOn = (bool) $flag;
142
    }
143
144
    /**
145
     * Return status of LFI protection flag
146
     *
147
     * @return bool
148
     */
149
    public function isLfiProtectionOn()
150
    {
151
        return $this->lfiProtectionOn;
152
    }
153
154
    /**
155
     * {@inheritDoc}
156
     */
157
    public function resolve($name)
158
    {
159
        if ($this->isLfiProtectionOn() && preg_match('#\.\.[\\\/]#', $name)) {
160
            return null;
161
        }
162
163
        foreach ($this->getPaths() as $path) {
164
            $asset = $this->resolveFile($path . $name);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $asset is correct as $this->resolveFile($path . $name) (which targets AssetManager\Core\Resolv...Abstract::resolveFile()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
165
166
            if (!$asset) {
167
                continue;
168
            }
169
170
            $asset->mimetype = $this->getMimeResolver()->getMimeType($name);
171
172
            return $asset;
173
        }
174
175
        return null;
176
    }
177
178
    /**
179
     * {@inheritDoc}
180
     */
181
    public function collect()
182
    {
183
        $collection = array();
184
185
        foreach ($this->getPaths() as $path) {
186
            $locations = new SplStack();
187
            $pathInfo = new SplFileInfo($path);
188
            $locations->push($pathInfo);
189
            $basePath = $this->normalizePath($pathInfo->getRealPath());
190
191
            while (!$locations->isEmpty()) {
192
                /** @var SplFileInfo $pathInfo */
193
                $pathInfo = $locations->pop();
194
                if (!$pathInfo->isReadable()) {
195
                    throw new Exception\RuntimeException(sprintf('%s is not readable.', $pathInfo->getPath()));
196
                }
197
                if ($pathInfo->isDir()) {
198
                    foreach (new DirectoryResource($pathInfo->getRealPath()) as $resource) {
199
                        $locations->push(new SplFileInfo($resource));
200
                    }
201
                } else {
202
                    $collection[] = substr($pathInfo->getRealPath(), strlen($basePath));
203
                }
204
            }
205
        }
206
207
        return array_unique($collection);
208
    }
209
}
210