Passed
Push — master ( 049e63...83af11 )
by Luke
02:50
created

File::isValidPattern()   C

Complexity

Conditions 7
Paths 25

Size

Total Lines 22
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 7

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 22
ccs 10
cts 10
cp 1
rs 6.9811
cc 7
eloc 10
nc 25
nop 1
crap 7
1
<?php
2
/**
3
 * This file is part of Affinity4\File.
4
 *
5
 * (c) 2017 Luke Watts <[email protected]>
6
 *
7
 * This software is licensed under the MIT license. For the
8
 * full copyright and license information, please view the
9
 * LICENSE file that was distributed with this source code.
10
 */
11
namespace Affinity4\File;
12
13
/**
14
 * File Class
15
 *
16
 * @author Luke Watts <[email protected]>
17
 *
18
 * @since  1.0.0
19
 *
20
 * @package Affinity4\File
21
 */
22
class File
23
{
24
    /**
25
     * @author Luke Watts <[email protected]>
26
     *
27
     * @since  1.0.0
28
     *
29
     * @var \DirectoryIterator
30
     */
31
    private $iterator;
32
33
    /**
34
     * @author Luke Watts <[email protected]>
35
     *
36
     * @since  1.0.0
37
     *
38
     * @var
39
     */
40
    private $pattern;
41
42
    /**
43
     * @author Luke Watts <[email protected]>
44
     *
45
     * @since  1.0.0
46
     *
47
     * @var
48
     */
49
    private $limit = -1;
50
51
    /**
52
     * @author Luke Watts <[email protected]>
53
     *
54
     * @since 2.0.0
55
     *
56
     * @var
57
     */
58
    private $dir;
59
60
    /**
61
     * @author Luke Watts <[email protected]>
62
     *
63
     * @since  1.0.0
64
     *
65
     * @var array
66
     */
67
    private $regex_delimiters = ['/', '#', '@', '~'];
68
69
    /**
70
     * @author Luke Watts <[email protected]>
71
     *
72
     * @since  1.0.0
73
     *
74
     * @var array
75
     */
76
    private $file_list = [];
77
78
    /**
79
     * Set the pattern to search for.
80
     *
81
     * Can be a regex pattern with the delimiters /, #, @ or ~
82
     *
83
     * Can also be a plain file name to search for only that file
84
     *
85
     * @author Luke Watts <[email protected]>
86
     *
87
     * @since  1.0.0
88
     *
89
     * @param $pattern
90
     *
91
     * @return File
92
     */
93 11
    public function find($pattern)
94
    {
95 11
        $this->pattern = $pattern;
96
97 11
        return $this;
98
    }
99
100
    /**
101
     * Alias of the upOne() method
102
     *
103
     * @author Luke Watts <[email protected]>
104
     *
105
     * @since  2.0.0
106
     *
107
     * @return File
108
     */
109 1 View Code Duplication
    public function parent()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
110
    {
111 1
        $pattern = $this->getPattern();
112 1
        $dir = $this->getDir();
113
114 1
        if ($this->find($pattern)->in($dir)->has() === false) {
115
            $dir = dirname($dir);
116
            $this->file_list = $this->find($pattern)->in($dir)->get();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->find($pattern)->in($dir)->get() of type * is incompatible with the declared type array of property $file_list.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
117
        } else {
118 1
            $this->file_list = $this->find($pattern)->in($dir)->get();
119
        }
120
121 1
        return $this;
122
    }
123
124
    /**
125
     * Alias of the up() method
126
     *
127
     * @author Luke Watts <[email protected]>
128
     *
129
     * @since  2.0.0
130
     *
131
     * @return File
132
     */
133 1 View Code Duplication
    public function parents()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
134
    {
135 1
        $dir = $this->getDir();
136 1
        $pattern = $this->getPattern();
137
138 1
        if ($this->find($pattern)->in($dir)->has() === false) {
139 1
            $dir = dirname($dir);
140
141 1
            $this->file_list = $this->find($pattern)->in($dir)->up()->get();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->find($pattern)->in($dir)->up()->get() of type * is incompatible with the declared type array of property $file_list.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
142
        } else {
143
            $this->file_list = $this->find($pattern)->in($dir)->get();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->find($pattern)->in($dir)->get() of type * is incompatible with the declared type array of property $file_list.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
144
        }
145
146 1
        return $this;
147
    }
148
149
    /**
150
     * Sets the directory to start search in.
151
     *
152
     * @author Luke Watts <[email protected]>
153
     *
154
     * @since  2.0.0
155
     *
156
     * @param $dir
157
     *
158
     * @return File
159
     */
160 9
    public function in($dir)
161
    {
162 9
        $this->dir = $dir;
163
164 9
        $this->make();
165
166 9
        return $this;
167
    }
168
169
    /**
170
     * Search the parent directory.
171
     *
172
     * @author Luke Watts <[email protected]>
173
     *
174
     * @return File
175
     */
176 1 View Code Duplication
    public function upOne()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
    {
178 1
        $dir = $this->getDir();
179 1
        $pattern = $this->getPattern();
180
181 1
        if ($this->find($pattern)->in($dir)->has() === false) {
182
            $dir = dirname($dir);
183
            $this->file_list = $this->find($pattern)->in($dir)->get();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->find($pattern)->in($dir)->get() of type * is incompatible with the declared type array of property $file_list.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
184
        } else {
185 1
            $this->file_list = $this->find($pattern)->in($dir)->get();
186
        }
187
188 1
        return $this;
189
    }
190
191
    /**
192
     * Recursively searches parent directories.
193
     *
194
     * @author Luke Watts <[email protected]>
195
     *
196
     * @return File
197
     */
198 2 View Code Duplication
    public function up()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199
    {
200 2
        $dir = $this->getDir();
201 2
        $pattern = $this->getPattern();
202
203 2
        if ($this->find($pattern)->in($dir)->has() === false) {
204
            $dir = dirname($dir);
205
206
            $this->file_list = $this->find($pattern)->in($dir)->up()->get();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->find($pattern)->in($dir)->up()->get() of type * is incompatible with the declared type array of property $file_list.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
207
        } else {
208 2
            $this->file_list = $this->find($pattern)->in($dir)->get();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->find($pattern)->in($dir)->get() of type * is incompatible with the declared type array of property $file_list.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
209
        }
210
211 2
        return $this;
212
    }
213
214
    /**
215
     * Return specified amount of files
216
     *
217
     * @author Luke Watts <[email protected]>
218
     *
219
     * @param int $limit
220
     *
221
     * @return array|bool|mixed
222
     */
223 8
    public function get($limit = -1)
224
    {
225 8
        if ($limit === 0 || $limit < -1) {
226 2
            throw new \InvalidArgumentException(sprintf('An integer of %s cannot be passed as a limit to the `get` method. Only -1, 1 or more can be given.', $limit));
227
        }
228 6
        $this->limit = $limit;
229
230 6
        if (isset($this->getFileList()[0])) {
231 6
            if ($this->limit === -1) {
232 6
                return $this->getFileList();
233 1
            } elseif ($this->limit === 1) {
234 1
                return $this->getFileList()[0];
235
            } else {
236 1
                return array_slice($this->getFileList(), 0, $this->limit);
237
            }
238
        } else {
239
            return false;
240
        }
241
    }
242
243
    /**
244
     * Checks existence of file.
245
     *
246
     * @author Luke Watts <[email protected]>
247
     *
248
     * @return bool
249
     */
250 4
    public function has()
251
    {
252 4
        return isset($this->getFileList()[0]);
253
    }
254
255
    /**
256
     * @param $pattern
257
     *
258
     * @author Luke Watts <[email protected]>
259
     *
260
     * @since 2.1.3
261
     *
262
     * @return bool
263
     */
264 10
    public function isValidPattern($pattern)
265
    {
266
        // Check if first character is one of the self::$regex_delimiters
267 10
        foreach ($this->regex_delimiters as $delimiter) {
268 10
            $pos = (strpos($pattern, $delimiter) === 0) ? $delimiter : false;
269 10
            if ($pos !== false) {
270 10
                break;
271
            }
272
        }
273
274
        // If first character is one of the $common_regex_delimiters
275 10
        if ($pos !== false) {
276
            // Then check if the last character is the same
277 10
            $index = strlen($pattern) - 1;
278
279 10
            $pos_last = (strrpos($pattern, $pos, $index) === $index) ? $pos : false;
0 ignored issues
show
Bug introduced by
The variable $pos does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
280
281 10
            return ($pos_last !== false) ? true : false;
282
        }
283
284 1
        return false;
285
    }
286
287
    /**
288
     * Make the search
289
     *
290
     * @author Luke Watts <[email protected]>
291
     */
292 9
    public function make()
293
    {
294 9
        $this->iterator = new \DirectoryIterator($this->getDir());
295
296 9
        if ($this->isValidPattern($this->pattern)) {
297
            // Reset the array to avoid duplicate entry issue in version 1.0.0 in recursive methods
298 9
            $this->file_list = [];
299
300
            // If first and last are the same treat expression as a regex
301 9
            foreach ($this->iterator as $item) {
302 9
                $filename = $item->getFilename();
303
304 9
                if ($item->isDot()) {
305 9
                    continue;
306
                }
307 9
                if ($item->isDir()) {
308 1
                    continue;
309
                }
310
311 9
                if (preg_match($this->pattern, $filename) === 1) {
312 9
                    $this->file_list[] = new \SplFileInfo($item->getPathname());
313
                }
314
            }
315
        } else {
316
            // Reset the array to avoid duplicate entry issue in version 1.0.0 in recursive methods
317
            $this->file_list = [];
318
319
            // Else use plain file name
320
            foreach ($this->iterator as $item) {
321
                $filename = $item->getFilename();
322
323
                if ($item->isDot()) {
324
                    continue;
325
                }
326
                if ($item->isDir()) {
327
                    continue;
328
                }
329
330
                if (preg_match('/^' . preg_quote($this->pattern) . '$/', $filename) === 1) {
331
                    $this->file_list[] = new \SplFileInfo($item->getPathname());
332
                }
333
            }
334
        }
335 9
    }
336
337
    /**
338
     * Returns the current pattern to search for
339
     *
340
     * @author Luke Watts <[email protected]>
341
     *
342
     * @since 1.0.0
343
     *
344
     * @return mixed
345
     */
346 6
    public function getPattern()
347
    {
348 6
        return $this->pattern;
349
    }
350
351
    /**
352
     * Returns the current limit
353
     *
354
     * @author Luke Watts <[email protected]>
355
     *
356
     * @since  1.0.0
357
     *
358
     * @return mixed
359
     */
360
    public function getLimit()
361
    {
362
        return $this->limit;
363
    }
364
365
    /**
366
     * Get the current directory.
367
     *
368
     * @author Luke Watts <[email protected]>
369
     *
370
     * @since  2.0.0
371
     *
372
     * @return mixed
373
     */
374 9
    public function getDir()
375
    {
376 9
        return $this->dir;
377
    }
378
379
    /**
380
     * Returns file list array
381
     *
382
     * @author Luke Watts <[email protected]>
383
     *
384
     * @since  1.0.0
385
     *
386
     * @return array
387
     */
388 6
    public function getFileList()
389
    {
390 6
        return $this->file_list;
391
    }
392
}
393