Completed
Push — master ( 8096c4...8558a8 )
by ignace nyamagana
28:17 queued 13:25
created

StreamFilter   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 275
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 1 Features 0
Metric Value
wmc 24
c 7
b 1
f 0
lcom 1
cbo 0
dl 0
loc 275
ccs 74
cts 74
cp 1
rs 10

15 Methods

Rating   Name   Duplication   Size   Complexity  
A fetchStreamModeAsInt() 0 14 3
A assertStreamable() 0 6 2
A isActiveStreamFilter() 0 4 1
A setStreamFilterMode() 0 12 2
A getStreamFilterMode() 0 6 1
A appendStreamFilter() 0 7 1
A prependStreamFilter() 0 7 1
A initStreamFilter() 0 18 3
A sanitizeStreamFilter() 0 6 1
validateString() 0 1 ?
A hasStreamFilter() 0 6 1
A removeStreamFilter() 0 10 2
A clearStreamFilter() 0 7 1
A getStreamFilterPath() 0 12 2
A getStreamFilterPrefix() 0 12 3
1
<?php
2
/**
3
* This file is part of the League.csv library
4
*
5
* @license http://opensource.org/licenses/MIT
6
* @link https://github.com/thephpleague/csv/
7
* @version 8.0.0
8
* @package League.csv
9
*
10
* For the full copyright and license information, please view the LICENSE
11
* file that was distributed with this source code.
12
*/
13
namespace League\Csv\Modifier;
14
15
use LogicException;
16
use OutOfBoundsException;
17
18
/**
19
 *  A Trait to ease PHP Stream Filters manipulation
20
 *  with a SplFileObject
21
 *
22
 * @package League.csv
23
 * @since  6.0.0
24
 *
25
 */
26
trait StreamFilter
27
{
28
    /**
29
     * collection of stream filters
30
     *
31
     * @var array
32
     */
33
    protected $stream_filters = [];
34
35
    /**
36
     * Stream filtering mode to apply on all filters
37
     *
38
     * @var int
39
     */
40
    protected $stream_filter_mode = STREAM_FILTER_ALL;
41
42
    /**
43
     *the real path
44
     *
45
     * @var string the real path to the file
46
     *
47
     */
48
    protected $stream_uri;
49
50
    /**
51
     * PHP Stream Filter Regex
52
     *
53
     * @var string
54
     */
55
    protected $stream_regex = ',^
56
        php://filter/
57
        (?P<mode>:?read=|write=)?  # The resource open mode
58
        (?P<filters>.*?)           # The resource registered filters
59
        /resource=(?P<resource>.*) # The resource path
60
        $,ix';
61
62
    /**
63
     * Internal path setter
64
     *
65
     * The path must be an SplFileInfo object
66
     * an object that implements the `__toString` method
67
     * a path to a file
68
     *
69
     * @param \SplFileObject|string $path The file path
70
     */
71 357
    protected function initStreamFilter($path)
72
    {
73 357
        $this->stream_filters = [];
74 357
        if (!is_string($path)) {
75 315
            $this->stream_uri = null;
76
77 315
            return;
78
        }
79
80 48
        if (!preg_match($this->stream_regex, $path, $matches)) {
81 33
            $this->stream_uri = $path;
82
83 33
            return;
84
        }
85 15
        $this->stream_uri = $matches['resource'];
86 15
        $this->stream_filters = explode('|', $matches['filters']);
87 15
        $this->stream_filter_mode = $this->fetchStreamModeAsInt($matches['mode']);
88 15
    }
89
90
    /**
91
     * Get the stream mode
92
     *
93
     * @param string $mode
94
     *
95
     * @return int
96
     */
97 15
    protected function fetchStreamModeAsInt($mode)
98
    {
99 15
        $mode = strtolower($mode);
100 15
        $mode = rtrim($mode, '=');
101 15
        if ('write' == $mode) {
102 3
            return STREAM_FILTER_WRITE;
103
        }
104
105 12
        if ('read' == $mode) {
106 6
            return STREAM_FILTER_READ;
107
        }
108
109 6
        return STREAM_FILTER_ALL;
110
    }
111
112
    /**
113
     * Check if the trait methods can be used
114
     *
115
     * @throws LogicException If the API can not be use
116
     */
117 57
    protected function assertStreamable()
118
    {
119 57
        if (!is_string($this->stream_uri)) {
120 9
            throw new LogicException('The stream filter API can not be used');
121
        }
122 48
    }
123
124
    /**
125
     * Tells whether the stream filter capabilities can be used
126
     *
127
     * @return bool
128
     */
129 9
    public function isActiveStreamFilter()
130
    {
131 9
        return is_string($this->stream_uri);
132
    }
133
134
    /**
135
     * stream filter mode Setter
136
     *
137
     * Set the new Stream Filter mode and remove all
138
     * previously attached stream filters
139
     *
140
     * @param int $mode
141
     *
142
     * @throws OutOfBoundsException If the mode is invalid
143
     *
144
     * @return $this
145
     */
146 6
    public function setStreamFilterMode($mode)
147
    {
148 6
        $this->assertStreamable();
149 6
        if (!in_array($mode, [STREAM_FILTER_ALL, STREAM_FILTER_READ, STREAM_FILTER_WRITE])) {
150 3
            throw new OutOfBoundsException('the $mode should be a valid `STREAM_FILTER_*` constant');
151
        }
152
153 3
        $this->stream_filter_mode = $mode;
154 3
        $this->stream_filters = [];
155
156 3
        return $this;
157
    }
158
159
    /**
160
     * stream filter mode getter
161
     *
162
     * @return int
163
     */
164 15
    public function getStreamFilterMode()
165
    {
166 15
        $this->assertStreamable();
167
168 12
        return $this->stream_filter_mode;
169
    }
170
171
    /**
172
     * append a stream filter
173
     *
174
     * @param string $filter_name a string or an object that implements the '__toString' method
175
     *
176
     * @return $this
177
     */
178 24
    public function appendStreamFilter($filter_name)
179
    {
180 24
        $this->assertStreamable();
181 21
        $this->stream_filters[] = $this->sanitizeStreamFilter($filter_name);
182
183 21
        return $this;
184
    }
185
186
    /**
187
     * prepend a stream filter
188
     *
189
     * @param string $filter_name a string or an object that implements the '__toString' method
190
     *
191
     * @return $this
192
     */
193 9
    public function prependStreamFilter($filter_name)
194
    {
195 9
        $this->assertStreamable();
196 6
        array_unshift($this->stream_filters, $this->sanitizeStreamFilter($filter_name));
197
198 6
        return $this;
199
    }
200
201
    /**
202
     * Sanitize the stream filter name
203
     *
204
     * @param string $filter_name the stream filter name
205
     *
206
     * @return string
207
     */
208 21
    protected function sanitizeStreamFilter($filter_name)
209
    {
210 21
        $this->assertStreamable();
211
212 21
        return $this->validateString($filter_name);
213
    }
214
215
    /**
216
     * @inheritdoc
217
     */
218
    abstract public function validateString($str);
219
220
    /**
221
     * Detect if the stream filter is already present
222
     *
223
     * @param string $filter_name
224
     *
225
     * @return bool
226
     */
227 18
    public function hasStreamFilter($filter_name)
228
    {
229 18
        $this->assertStreamable();
230
231 18
        return false !== array_search($filter_name, $this->stream_filters, true);
232
    }
233
234
    /**
235
     * Remove a filter from the collection
236
     *
237
     * @param string $filter_name
238
     *
239
     * @return $this
240
     */
241 3
    public function removeStreamFilter($filter_name)
242
    {
243 3
        $this->assertStreamable();
244 3
        $res = array_search($filter_name, $this->stream_filters, true);
245 3
        if (false !== $res) {
246 3
            unset($this->stream_filters[$res]);
247 2
        }
248
249 3
        return $this;
250
    }
251
252
    /**
253
     * Remove all registered stream filter
254
     *
255
     * @return $this
256
     */
257 3
    public function clearStreamFilter()
258
    {
259 3
        $this->assertStreamable();
260 3
        $this->stream_filters = [];
261
262 3
        return $this;
263
    }
264
265
    /**
266
     * Return the filter path
267
     *
268
     * @return string
269
     */
270 33
    protected function getStreamFilterPath()
271
    {
272 33
        $this->assertStreamable();
273 33
        if (!$this->stream_filters) {
274 12
            return $this->stream_uri;
275
        }
276
277
        return 'php://filter/'
278 21
            .$this->getStreamFilterPrefix()
279 21
            .implode('|', $this->stream_filters)
280 21
            .'/resource='.$this->stream_uri;
281
    }
282
283
    /**
284
     * Return PHP stream filter prefix
285
     *
286
     * @return string
287
     */
288 21
    protected function getStreamFilterPrefix()
289
    {
290 21
        if (STREAM_FILTER_READ == $this->stream_filter_mode) {
291 9
            return 'read=';
292
        }
293
294 12
        if (STREAM_FILTER_WRITE == $this->stream_filter_mode) {
295 9
            return 'write=';
296
        }
297
298 3
        return '';
299
    }
300
}
301