Passed
Push — master ( 6d9d43...921f98 )
by Alain
02:46
created

FilesystemLocation::validateExtensions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
cc 2
eloc 5
nc 2
nop 1
crap 2
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 Exception;
16
17
/**
18
 * Class FilesystemLocation.
19
 *
20
 * @since   0.1.0
21
 *
22
 * @package BrightNucleus\View\Location
23
 * @author  Alain Schlesser <[email protected]>
24
 */
25
class FilesystemLocation implements LocationInterface
26
{
27
28
    /**
29
     * Path that this location points to.
30
     *
31
     * @since 0.1.0
32
     *
33
     * @var string
34
     */
35
    protected $path;
36
37
    /**
38
     * Extensions that this location can accept.
39
     *
40
     * @since 0.1.0
41
     *
42
     * @var ExtensionCollection
43
     */
44
    protected $extensions;
45
46
    /**
47
     * Instantiate a FilesystemLocation object.
48
     *
49
     * @since 0.1.0
50
     *
51
     * @param string                           $path       Path that this location points to.
52
     * @param ExtensionCollection|array|string $extensions Extensions that this location can accept.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $extensions not be ExtensionCollection|array|string|null? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
53
     */
54 21
    public function __construct($path, $extensions = null)
55
    {
56 21
        $this->path       = $path;
57 21
        $this->extensions = $this->validateExtensions($extensions);
58 21
    }
59
60
    /**
61
     * Get the first URI that matches the given criteria.
62
     *
63
     * @since 0.1.0
64
     *
65
     * @param array $criteria Criteria to match.
66
     *
67
     * @return string|false URI that matches the criteria or false if none found.
0 ignored issues
show
Documentation introduced by
Should the return type not be array|string|false? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
68
     */
69 21
    public function getURI(array $criteria)
70
    {
71 21
        foreach ($criteria as $entry) {
72 21
            if ($uri = $this->transform($entry, true)) {
73 21
                return $uri;
74
            }
75
        }
76
77 3
        return false;
78
    }
79
80
    /**
81
     * Get all URIs that match the given criteria.
82
     *
83
     * @since 0.1.1
84
     *
85
     * @param array $criteria Criteria to match.
86
     *
87
     * @return array URIs that match the criteria or empty array if none found.
88
     */
89 3
    public function getURIs(array $criteria)
90
    {
91 3
        $uris = [];
92
93 3
        foreach ($criteria as $entry) {
94 3
            if ($uri = $this->transform($entry, false)) {
95 3
                $uris = array_merge($uris, (array)$uri);
96
            }
97
        }
98
99 3
        return $uris;
100
    }
101
102
    /**
103
     * Validate the extensions and return a collection.
104
     *
105
     * @since 0.1.1
106
     *
107
     * @param ExtensionCollection|array|string $extensions Extensions to validate.
108
     *
109
     * @return ExtensionCollection Validated extensions collection.
110
     */
111 21
    protected function validateExtensions($extensions)
112
    {
113 21
        if (! $extensions instanceof ExtensionCollection) {
114 21
            $extensions = new ExtensionCollection((array)$extensions);
115
        }
116 21
        $extensions->add('');
117
118 21
        return $extensions;
119
    }
120
121
    /**
122
     * Try to transform the entry into possible URIs.
123
     *
124
     * @since 0.1.0
125
     *
126
     * @param string $entry     Entry to transform.
127
     * @param bool   $firstOnly Return the first result only.
128
     *
129
     * @return array|string|false If $firstOnly is true, returns a string with the URI of the view, or false if none
130
     *                            found.
131
     *                            If $firstOnly is false, returns an array with all matching URIs, or an empty array if
132
     *                            none found.
133
     */
134 21
    protected function transform($entry, $firstOnly = true)
135
    {
136 21
        $uris = [];
137
138
        try {
139 21
            foreach ($this->getVariants($entry) as $uri) {
140 21
                if (is_readable($uri)) {
141 20
                    if ($firstOnly) {
142 20
                        return $uri;
143
                    }
144 21
                    $uris [] = $uri;
145
                }
146
            }
147
        } catch (Exception $exception) {
148
            // Fail silently.
149
        }
150
151 6
        return $firstOnly ? false : $uris;
152
    }
153
154
    /**
155
     * Get the individual variants that could be matched for the location.
156
     *
157
     * @since 0.1.1
158
     *
159
     * @param string $entry Entry to get the variants for.
160
     *
161
     * @return array Array of variants to check.
162
     */
163 21
    protected function getVariants($entry)
164
    {
165 21
        $variants = [];
166
167 21
        $this->extensions->map(function ($extension) use ($entry, &$variants) {
168 21
            $variants[] = $entry . $extension;
169 21
            $variants[] = $this->path . DIRECTORY_SEPARATOR . $entry . $extension;
170 21
        });
171
172 21
        return $variants;
173
    }
174
}
175