Completed
Pull Request — master (#15)
by
unknown
03:20
created

Finder::yieldFilesInPath()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 7.0283

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 11
cts 12
cp 0.9167
rs 8.6506
c 0
b 0
f 0
cc 7
nc 7
nop 2
crap 7.0283
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;
16
17
use Flyfinder\Specification\SpecificationInterface;
18
use Generator;
19
use League\Flysystem\FilesystemInterface;
20
use League\Flysystem\PluginInterface;
21
22
/**
23
 * Flysystem plugin to add file finding capabilities to the filesystem entity.
24
 *
25
 * Note that found *directories* are **not** returned... only found *files*.
26
 */
27
class Finder implements PluginInterface
28
{
29
    const ALGORITHM_LEGACY = 0;
30
    const ALGORITHM_OPTIMIZED = 1;
31
32
    /** @var FilesystemInterface */
33
    private $filesystem;
34
35
    /** @var int */
36
    private $algorithm = self::ALGORITHM_LEGACY;
37
38
    /**
39
     * Get the method name.
40
     */
41 1
    public function getMethod(): string
42
    {
43 1
        return 'find';
44
    }
45
46
    /**
47
     * Set the Filesystem object.
48
     */
49 2
    public function setFilesystem(FilesystemInterface $filesystem): void
50
    {
51 2
        $this->filesystem = $filesystem;
52 2
    }
53
54
    /**
55
     * Find the specified files
56
     *
57
     * Note that only found *files* are yielded at this level,
58
     * which go back to the caller.
59
     */
60 2
    public function handle(SpecificationInterface $specification): Generator
61
    {
62 2
        foreach ($this->yieldFilesInPath($specification, '') as $path) {
63 2
            if (isset($path['type']) && $path['type'] === 'file') {
64 2
                yield $path;
65
            }
66
        }
67 2
    }
68
69
    /**
70
     * Recursively yield files that meet the specification
71
     *
72
     * Note that directories are also yielded at this level,
73
     * since they have to be recursed into.  Yielded directories
74
     * will not make their way back to the caller, as they are filtered out
75
     * by {@link handle()}.
76
     * @param SpecificationInterface $specification
77
     * @param string $path
78
     * @return Generator
79
     */
80 2
    private function yieldFilesInPath(SpecificationInterface $specification, string $path): Generator
81
    {
82 2
        $listContents = $this->filesystem->listContents($path);
83 2
        foreach ($listContents as $location) {
84 2
            if ($specification->isSatisfiedBy($location)) {
85 2
                yield $location;
86
            }
87
88 2
            if ($location['type'] === 'dir') {
89
                if (
90 2
                    self::ALGORITHM_OPTIMIZED === $this->algorithm
91 2
                    && !$specification->canBeSatisfiedByAnythingBelow($location)
92
                ) {
93
                    continue;
94
                }
95 2
                foreach ($this->yieldFilesInPath($specification, $location['path']) as $returnedLocation) {
96 2
                    yield $returnedLocation;
97
                }
98
            }
99
        }
100 2
    }
101
102
    /**
103
     * @return int
104
     */
105
    public function getAlgorithm(): int
106
    {
107
        return $this->algorithm;
108
    }
109
110
    /**
111
     * @param int $algorithm
112
     */
113
    public function setAlgorithm(int $algorithm): void
114
    {
115
        $this->algorithm = self::ALGORITHM_OPTIMIZED === $algorithm ? $algorithm : self::ALGORITHM_LEGACY;
116
    }
117
}
118