Completed
Push — 1.0 ( de4310...f8542e )
by Rob
12s
created

FileSystemLocator::locateUsingRootPathsSearch()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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