Completed
Pull Request — master (#15)
by
unknown
04:30
created

InPath   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 76%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 2
dl 0
loc 74
ccs 19
cts 25
cp 0.76
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B isSatisfiedBy() 0 42 6
A canBeSatisfiedByAnythingBelow() 0 8 1
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @copyright 2010-2018 Mike van Riel<[email protected]>
11
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
12
 * @link      http://phpdoc.org
13
 */
14
15
namespace Flyfinder\Specification;
16
17
use Flyfinder\Path;
18
19
/**
20
 * Class InPath
21
 *
22
 * Files *and directories* meet the specification if they are in the given path.
23
 * Note this behavior is different than in Finder, in that directories *can* meet the spec,
24
 * whereas Finder would never return a directory as "found".
25
 */
26
class InPath extends CompositeSpecification
27
{
28
    /**
29
     * @var Path
30
     */
31
    private $path;
32
33
    /**
34
     * Initializes the InPath specification
35
     */
36 25
    public function __construct(Path $path)
37
    {
38 25
        $this->path = $path;
39 25
    }
40
41
    /**
42
     * Checks if the value meets the specification
43
     *
44
     * @param mixed[] $value
45
     * @return bool
46
     */
47 25
    public function isSatisfiedBy(array $value): bool
48
    {
49 25
        if (in_array($this->path, ['', '.', './'], false)) {
50
            /*
51
             * since flysystem stuff is always relative to the filesystem object's root,
52
             * a spec of "current" dir should always be a match anything being considered
53
             */
54 10
            return true;
55
        }
56
57 15
        $path = (string) $this->path;
58 15
        $validChars = '[a-zA-Z0-9\\\/\.\<\>\,\|\:\(\)\&\;\#]';
59
60
        /*
61
         * a FILE spec would have to match on 'path',
62
         *   e.g. value path 'src/Cilex/Provider/MonologServiceProvider.php' should match FILE spec of same path...
63
         * this should also hit a perfect DIR=DIR_SPEC match,
64
         *   e.g. value path 'src/Cilex/Provider' should match DIR spec of 'src/Cilex/Provider'
65
         */
66 15
        if (isset($value['path'])) {
67
            $pattern = '(^(?!\/)'
68 5
                . str_replace(['?', '*'], [$validChars . '{1}', $validChars . '*'], $path)
69 5
                . $validChars . '*)';
70 5
            if (preg_match($pattern, $value['path'])) {
71 5
                return true;
72
            }
73
        }
74
75
        /* a DIR spec that wasn't an exact match should be able to match on dirname,
76
         *   e.g. value dirname 'src' of path 'src/Cilex' should match DIR spec of 'src'
77
         */
78 10
        if (isset($value['dirname'])) {
79
            $pattern = '(^(?!\/)'
80 10
                . str_replace(['?', '*'], [$validChars . '{1}', $validChars . '*'], $path . '/')
81 10
                . $validChars . '*)';
82 10
            if (preg_match($pattern, $value['dirname'] . '/')) {
83 5
                return true;
84
            }
85
        }
86
87 5
        return false;
88
    }
89
90
    /** @inheritDoc */
91
    public function canBeSatisfiedByAnythingBelow(array $value): bool
92
    {
93
        $pathSegments = explode("/",(string)$this->path);
94
        $valueSegments = explode("/",$value['path']);
95
        $pathPrefixSegments = array_slice($pathSegments,0,min(count($pathSegments),count($valueSegments)));
96
        $spec = new InPath(new Path(implode("/",$pathPrefixSegments)));
97
        return $spec->isSatisfiedBy($value);
98
    }
99
}
100