Passed
Push — master ( 4ac39c...ddccf7 )
by Alain
03:15
created

FilesystemLocation::getPathPattern()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * Bright Nucleus View Component.
4
 *
5
 * @package   BrightNucleus\View
6
 * @author    Alain Schlesser <[email protected]>
7
 * @license   MIT
8
 * @link      http://www.brightnucleus.com/
9
 * @copyright 2016 Alain Schlesser, Bright Nucleus
10
 */
11
12
namespace BrightNucleus\View\Location;
13
14
use BrightNucleus\View\Support\ExtensionCollection;
15
use BrightNucleus\View\Support\URIHelper;
16
use Exception;
17
use Symfony\Component\Finder\Finder;
18
use Symfony\Component\Finder\SplFileInfo;
19
20
/**
21
 * Class FilesystemLocation.
22
 *
23
 * @since   0.1.0
24
 *
25
 * @package BrightNucleus\View\Location
26
 * @author  Alain Schlesser <[email protected]>
27
 */
28
class FilesystemLocation implements LocationInterface
29
{
30
31
    /**
32
     * Path that this location points to.
33
     *
34
     * @since 0.1.0
35
     *
36
     * @var string
37
     */
38
    protected $path;
39
40
    /**
41
     * Extensions that this location can accept.
42
     *
43
     * @since 0.1.0
44
     *
45
     * @var ExtensionCollection
46
     */
47
    protected $extensions;
48
49
    /**
50
     * Instantiate a FilesystemLocation object.
51
     *
52
     * @since 0.1.0
53
     *
54
     * @param string                                $path       Path that this location points to.
55
     * @param ExtensionCollection|array|string|null $extensions Optional. Extensions that this location can accept.
56
     */
57 35
    public function __construct($path, $extensions = null)
58
    {
59 35
        $this->path       = $path;
60 35
        $this->extensions = $this->validateExtensions($extensions);
61 35
    }
62
63
    /**
64
     * Get the first URI that matches the given criteria.
65
     *
66
     * @since 0.1.0
67
     *
68
     * @param array $criteria Criteria to match.
69
     *
70
     * @return string|false URI that matches the criteria or false if none found.
71
     */
72 34
    public function getURI(array $criteria)
73
    {
74 34
        $uris = $this->getURIs($criteria);
75
76 34
        return $uris->count() > 0
77 33
            ? $this->getURIs($criteria)->first()
78 34
            : false;
79
    }
80
81
    /**
82
     * Get all URIs that match the given criteria.
83
     *
84
     * @since 0.1.1
85
     *
86
     * @param array $criteria Criteria to match.
87
     *
88
     * @return URICollection URIs that match the criteria or an empty collection if none found.
89
     */
90 34
    public function getURIs(array $criteria)
91
    {
92 34
        $uris = new URICollection();
93
94 34
        foreach ($this->extensions as $extension) {
95 34
            $finder = new Finder();
96
97
            try {
98 34
                $finder->files()
99 34
                       ->name($this->getNamePattern($criteria, $extension))
100 34
                       ->in($this->getPathPattern());
101 33
                foreach ($finder as $file) {
102
                    /** @var SplFileInfo $file */
103 33
                    $uris->add($file->getPathname());
104
                }
105 34
            } catch (Exception $exception) {
106
                // Fail silently;
107
            }
108
        }
109
110 34
        return $uris;
111
    }
112
113
    /**
114
     * Get the name pattern to pass to the file finder.
115
     *
116
     * @since 0.1.3
117
     *
118
     * @param array  $criteria  Criteria to match.
119
     * @param string $extension Extension to match.
120
     *
121
     * @return string Name pattern to pass to the file finder.
122
     */
123 34
    protected function getNamePattern(array $criteria, $extension)
124
    {
125 34
        $names = [];
126
127
        $names[] = array_map(function ($criterion) use ($extension) {
128 34
            $criterion = URIHelper::getFilename($criterion);
129
130 34
            return empty($extension) || URIHelper::hasExtension($criterion, $extension)
131 20
                ? $criterion
132 34
                : $criterion . $extension;
133 34
        }, $criteria)[0];
134
135 34
        return $this->arrayToRegexPattern(array_unique($names));
136
    }
137
138
    /**
139
     * Get the path pattern to pass to the file finder.
140
     *
141
     * @since 0.1.3
142
     *
143
     * @return string Path pattern to pass to the file finder.
144
     */
145 34
    protected function getPathPattern()
146
    {
147 34
        return $this->path;
148
    }
149
150
    /**
151
     * Get an array as a regular expression pattern string.
152
     *
153
     * @since 0.1.3
154
     *
155
     * @param array $array Array to generate the pattern for.
156
     *
157
     * @return string Generated regular expression pattern.
158
     */
159
    protected function arrayToRegexPattern(array $array)
160
    {
161 34
        $array = array_map(function ($entry) {
162 34
            return preg_quote($entry);
163 34
        }, $array);
164
165 34
        return '/' . implode('|', $array) . '/';
166
    }
167
168
    /**
169
     * Validate the extensions and return a collection.
170
     *
171
     * @since 0.1.1
172
     *
173
     * @param ExtensionCollection|array|string|null $extensions Extensions to validate.
174
     *
175
     * @return ExtensionCollection Validated extensions collection.
176
     */
177 35
    protected function validateExtensions($extensions)
178
    {
179 35
        if (empty($extensions)) {
180 8
            $extensions = new ExtensionCollection(['']);
181
        }
182
183 35
        if (! $extensions instanceof ExtensionCollection) {
184 28
            $extensions = new ExtensionCollection((array)$extensions);
185
        }
186
187 35
        return $extensions;
188
    }
189
}
190