Completed
Pull Request — 1.0 (#937)
by
unknown
02:21
created

FileSystemLocator::locateUsingRootPlaceholder()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 3
nop 1
1
<?php
2
3
/*
4
 * This file is part of the `liip/LiipImagineBundle` project.
5
 *
6
 * (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
7
 *
8
 * For the full copyright and license information, please view the LICENSE.md
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Liip\ImagineBundle\Binary\Locator;
13
14
use Liip\ImagineBundle\Exception\Binary\Loader\NotLoadableException;
15
use Liip\ImagineBundle\Exception\InvalidArgumentException;
16
use Symfony\Component\OptionsResolver\Exception\ExceptionInterface;
17
use Symfony\Component\OptionsResolver\OptionsResolver;
18
19
class FileSystemLocator implements LocatorInterface
20
{
21
    /**
22
     * @var string[]
23
     */
24
    private $roots = array();
25
26
    public function __construct(array $dataRoots = array())
27
    {
28
        $this->roots = array_map(array($this, 'sanitizeRootPath'), (array) $dataRoots);
29
    }
30
31
    /**
32
     * @param array[] $options
33
     */
34
    public function setOptions(array $options = array())
35
    {
36
        $resolver = new OptionsResolver();
37
        $resolver->setDefaults(array('roots' => array()));
38
39
        try {
40
            $options = $resolver->resolve($options);
41
        } catch (ExceptionInterface $e) {
42
            throw new InvalidArgumentException(sprintf('Invalid options provided to %s()', __METHOD__), null, $e);
43
        }
44
45
        @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
46
            sprintf('%s() is deprecated. Pass the dataroots to the constuctor instead.', __METHOD__),
47
            E_USER_DEPRECATED
48
        );
49
50
        $this->roots = array_map(array($this, 'sanitizeRootPath'), (array) $options['roots']);
51
    }
52
53
    /**
54
     * @param string $path
55
     *
56
     * @throws NotLoadableException
57
     *
58
     * @return string
59
     */
60
    public function locate($path)
61
    {
62
        if (false !== $absolute = $this->locateUsingRootPlaceholder($path)) {
63
            return $this->sanitizeAbsolutePath($absolute);
64
        }
65
66
        if (false !== $absolute = $this->locateUsingRootPathsSearch($path)) {
67
            return $this->sanitizeAbsolutePath($absolute);
68
        }
69
70
        throw new NotLoadableException(sprintf('Source image not resolvable "%s" in root path(s) "%s"',
71
            $path, implode(':', $this->roots)));
72
    }
73
74
    /**
75
     * @param string $path
76
     *
77
     * @return bool|string
78
     */
79
    private function locateUsingRootPathsSearch($path)
80
    {
81
        foreach ($this->roots as $root) {
82
            if (false !== $absolute = $this->generateAbsolutePath($root, $path)) {
83
                return $absolute;
84
            }
85
        }
86
87
        return false;
88
    }
89
90
    /**
91
     * @param string $path
92
     *
93
     * @return bool|string
94
     */
95
    private function locateUsingRootPlaceholder($path)
96
    {
97
        if (0 !== strpos($path, '@') || 1 !== preg_match('{@(?<name>[^:]+):(?<path>.+)}', $path, $matches)) {
98
            return false;
99
        }
100
101
        if (isset($this->roots[$matches['name']])) {
102
            return $this->generateAbsolutePath($this->roots[$matches['name']], $matches['path']);
103
        }
104
105
        throw new NotLoadableException(sprintf('Invalid root placeholder "%s" for path "%s"',
106
            $matches['name'], $matches['path']));
107
    }
108
109
    /**
110
     * @param string $root
111
     * @param string $path
112
     *
113
     * @return string|false
114
     */
115
    protected function generateAbsolutePath($root, $path)
116
    {
117
        return realpath($root.DIRECTORY_SEPARATOR.$path);
118
    }
119
120
    /**
121
     * @param string $root
122
     *
123
     * @throws InvalidArgumentException
124
     *
125
     * @return string
126
     */
127
    private function sanitizeRootPath($root)
128
    {
129
        if (!empty($root) && false !== $realRoot = realpath($root)) {
130
            return $realRoot;
131
        }
132
133
        throw new InvalidArgumentException(sprintf('Root image path not resolvable "%s"', $root));
134
    }
135
136
    /**
137
     * @param string $path
138
     *
139
     * @throws NotLoadableException
140
     *
141
     * @return string
142
     */
143
    private function sanitizeAbsolutePath($path)
144
    {
145
        foreach ($this->roots as $root) {
146
            if (0 === strpos($path, $root)) {
147
                return $path;
148
            }
149
        }
150
151
        throw new NotLoadableException(sprintf('Source image invalid "%s" as it is outside of the defined root path(s) "%s"',
152
            $path, implode(':', $this->roots)));
153
    }
154
}
155