Completed
Pull Request — 2.0 (#930)
by
unknown
04:25
created

FileSystemLocator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
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
17
class FileSystemLocator implements LocatorInterface
18
{
19
    /**
20
     * @var string[]
21
     */
22
    private $roots = [];
23
24
    /**
25
     * @param string[] $roots
26
     */
27
    public function __construct(array $roots = [])
28
    {
29
        $this->roots = array_map([$this, 'sanitizeRootPath'], $roots);
30
    }
31
32
    /**
33
     * @param string $path
34
     *
35
     * @throws NotLoadableException
36
     *
37
     * @return string
38
     */
39
    public function locate($path)
40
    {
41
        if (false !== $absolute = $this->locateUsingRootPlaceholder($path)) {
42
            return $this->sanitizeAbsolutePath($absolute);
43
        }
44
45
        if (false !== $absolute = $this->locateUsingRootPathsSearch($path)) {
46
            return $this->sanitizeAbsolutePath($absolute);
47
        }
48
49
        throw new NotLoadableException(sprintf('Source image not resolvable "%s" in root path(s) "%s"',
50
            $path, implode(':', $this->roots)));
51
    }
52
53
    /**
54
     * @param string $path
55
     *
56
     * @return bool|string
57
     */
58
    private function locateUsingRootPathsSearch($path)
59
    {
60
        foreach ($this->roots as $root) {
61
            if (false !== $absolute = $this->generateAbsolutePath($root, $path)) {
62
                return $absolute;
63
            }
64
        }
65
66
        return false;
67
    }
68
69
    /**
70
     * @param string $path
71
     *
72
     * @return bool|string
73
     */
74
    private function locateUsingRootPlaceholder($path)
75
    {
76
        if (0 !== strpos($path, '@') || 1 !== preg_match('{@(?<name>[^:]+):(?<path>.+)}', $path, $matches)) {
77
            return false;
78
        }
79
80
        if (isset($this->roots[$matches['name']])) {
81
            return $this->generateAbsolutePath($this->roots[$matches['name']], $matches['path']);
82
        }
83
84
        throw new NotLoadableException(sprintf('Invalid root placeholder "%s" for path "%s"',
85
            $matches['name'], $matches['path']));
86
    }
87
88
    /**
89
     * @param string $root
90
     * @param string $path
91
     *
92
     * @return string|false
93
     */
94
    protected function generateAbsolutePath($root, $path)
95
    {
96
        return realpath($root.DIRECTORY_SEPARATOR.$path);
97
    }
98
99
    /**
100
     * @param string $root
101
     *
102
     * @throws InvalidArgumentException
103
     *
104
     * @return string
105
     */
106
    private function sanitizeRootPath($root)
107
    {
108
        if (!empty($root) && false !== $realRoot = realpath($root)) {
109
            return $realRoot;
110
        }
111
112
        throw new InvalidArgumentException(sprintf('Root image path not resolvable "%s"', $root));
113
    }
114
115
    /**
116
     * @param string $path
117
     *
118
     * @throws NotLoadableException
119
     *
120
     * @return string
121
     */
122
    private function sanitizeAbsolutePath($path)
123
    {
124
        foreach ($this->roots as $root) {
125
            if (0 === strpos($path, $root)) {
126
                return $path;
127
            }
128
        }
129
130
        throw new NotLoadableException(sprintf('Source image invalid "%s" as it is outside of the defined root path(s) "%s"',
131
            $path, implode(':', $this->roots)));
132
    }
133
}
134