FileCollection::remove()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 9
nc 2
nop 1
crap 2
1
<?php
2
3
/*
4
 * This file is part of the Conveyor package.
5
 *
6
 * (c) Jeroen Fiege <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Webcreate\Conveyor\Util;
13
14
use Symfony\Component\Finder\Finder;
15
use Symfony\Component\Finder\Glob;
16
17
class FileCollection implements \IteratorAggregate, \Countable, \ArrayAccess
18
{
19
    protected $basepath;
20
    protected $files = array();
21
22 24
    public function __construct($basepath = null)
23
    {
24 24
        if (null !== $basepath) {
25 17
            $this->setBasepath($basepath);
26
        }
27 24
    }
28
29 17
    public function setBasepath($basepath)
30
    {
31 17
        $this->basepath = rtrim($basepath, '/');
32
33 17
        return $this;
34
    }
35
36 1
    public function getBasepath()
37
    {
38 1
        return $this->basepath;
39
    }
40
41
    /**
42
     * @param $pattern
43
     * @param  bool            $force assumes the $pattern is a absolute file and adds it, even if it doesn't exist
44
     *
45
     * @throws \LogicException
46
     *
47
     * @return $this
48
     */
49 16
    public function add($pattern, $force = false)
50
    {
51 16
        if (null === $this->basepath) {
52
            throw new \LogicException('You need to call "setBasepath()" first before adding files');
53
        }
54
55 16
        $filepath = $this->basepath . '/' . $pattern;
56 16
        if ($force || is_file($filepath)) {
57 11
            $this->files[] = $pattern;
58
59 11
            return $this;
60
        }
61
62 16
        $regex = Glob::toRegex($pattern, false);
63 16
        if (is_dir($filepath) || '*' === $pattern) {
64 16
            $regex = str_replace('$', '', $regex);
65
        }
66
67 16
        $finder = new Finder();
68
        $finder
69 16
            ->files()
70 16
            ->ignoreDotFiles(false)
71 16
            ->in($this->basepath)
72 16
            ->path($regex)
73
        ;
74
75 16
        $this->files = array_merge($this->files, $this->mapFinder($finder));
76 16
        $this->files = array_unique($this->files);
77
78 16
        return $this;
79
    }
80
81
    /**
82
     * @param Finder $finder
83
     *
84
     * @return array
85
     */
86 16
    protected function mapFinder($finder)
87
    {
88 16
        return array_map(function ($file) {
89 16
            return $file->getRelativePathname();
90 16
        }, iterator_to_array($finder, false));
91
    }
92
93 3
    public function remove($pattern)
94
    {
95 3
        if ('*' === $pattern) {
96 2
            $this->files = array();
97
        } else {
98 1
            $matching = $this->match($pattern);
99
100
            $this->files = array_filter($this->files, function ($file) use ($pattern, $matching) {
101 1
                return false === in_array($file, $matching);
102 1
            });
103
104 1
            $this->files = array_values($this->files);
105
        }
106
107 3
        return $this;
108
    }
109
110
    public function merge(FileCollection $collection)
111
    {
112
        $this->files = array_merge($this->files, $collection->toArray());
113
    }
114
115
    public function toArray()
116
    {
117
        return $this->files;
118
    }
119
120
    /**
121
     * @param FileCollection $array
122
     */
123
    public function intersect($array)
124
    {
125
        if ($array instanceof self) {
126
            $array = $array->toArray();
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $array. This often makes code more readable.
Loading history...
127
        }
128
129
        $this->files = array_intersect($array, $this->files);
130
    }
131
132 2
    public function match($pattern)
133
    {
134 2
        if ('*' === $pattern) {
135
            return $this->files;
136
        }
137
138
        $retval = array_filter($this->files, function ($file) use ($pattern) {
139 2
            $regex = Glob::toRegex($pattern, false);
140 2
            $regex = str_replace('$', '', $regex);
141
142 2
            return (1 === preg_match($regex, $file));
143 2
        });
144
145 2
        return array_values($retval); // reindex
146
    }
147
148 10
    public function has($pattern)
149
    {
150 10
        if ('*' !== substr($pattern, -1)) {
151 9
            if ('/' === substr($pattern, -1, 1)) {
152 2
                $pattern .= '*';
153
            }
154
        }
155
156 10
        $regex = Glob::toRegex($pattern, false, false);
157
158 10
        foreach ($this->files as $file) {
159 10
            if (1 === preg_match($regex, $file)) {
160 10
                return true;
161
            }
162
        }
163
164 4
        return false;
165
    }
166
167 4
    public function getIterator()
168
    {
169 4
        return new \ArrayIterator($this->files);
170
    }
171
172 1
    public function count()
173
    {
174 1
        return count($this->files);
175
    }
176
177
    public function offsetExists($offset)
178
    {
179
        return isset($this->files[$offset]);
180
    }
181
182
    public function offsetGet($offset)
183
    {
184
        return $this->offsetExists($offset) ? $this->files[$offset] : null;
185
    }
186
187 1
    public function offsetSet($offset, $value)
188
    {
189 1
        $this->add($value);
190 1
    }
191
192
    public function offsetUnset($offset)
193
    {
194
        unset($this->files[$offset]);
195
    }
196
}
197