Passed
Push — master ( 894e98...cda682 )
by Aimeos
18:42 queued 10:10
created

FlyBase   B

Complexity

Total Complexity 48

Size/Duplication

Total Lines 413
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 104
dl 0
loc 413
rs 8.5599
c 0
b 0
f 0
wmc 48

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfig() 0 3 1
A isdir() 0 9 2
A has() 0 3 1
A copy() 0 13 3
A getAdapter() 0 3 1
A readf() 0 20 4
A read() 0 13 3
A writef() 0 13 3
A size() 0 13 3
A rmdir() 0 7 2
A rm() 0 9 2
A scan() 0 9 2
A reads() 0 13 3
A move() 0 13 3
A write() 0 13 3
A writes() 0 13 3
A __construct() 0 14 4
A mkdir() 0 7 2
A time() 0 13 3

How to fix   Complexity   

Complex Class

Complex classes like FlyBase often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FlyBase, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2022
6
 * @package Base
7
 * @subpackage Filesystem
8
 */
9
10
11
namespace Aimeos\Base\Filesystem;
12
13
14
/**
15
 * Implementation of Flysystem file system adapter
16
 *
17
 * @package Base
18
 * @subpackage Filesystem
19
 */
20
abstract class FlyBase implements Iface, DirIface, MetaIface
21
{
22
	private $config;
23
	private $tempdir;
24
25
26
	/**
27
	 * Initializes the object
28
	 *
29
	 * @param array $config Configuration options
30
	 */
31
	public function __construct( array $config )
32
	{
33
		$this->config = $config;
34
35
		if( !isset( $config['tempdir'] ) ) {
36
			$config['tempdir'] = sys_get_temp_dir();
37
		}
38
39
		if( !is_dir( $config['tempdir'] ) && mkdir( $config['tempdir'], 0755, true ) === false ) {
40
			throw new Exception( sprintf( 'Directory "%1$s" could not be created', $config['tempdir'] ) );
41
		}
42
43
		$ds = DIRECTORY_SEPARATOR;
44
		$this->tempdir = realpath( str_replace( '/', $ds, rtrim( $config['tempdir'], '/' ) ) ) . $ds;
45
	}
46
47
48
	/**
49
	 * Tests if the given path is a directory
50
	 *
51
	 * @param string $path Path to the file or directory
52
	 * @return bool True if directory, false if not
53
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
54
	 */
55
	public function isdir( string $path ) : bool
56
	{
57
		$result = $this->getProvider()->getMetadata( $path );
58
59
		if( $result['type'] === 'dir' ) {
60
			return true;
61
		}
62
63
		return false;
64
	}
65
66
67
	/**
68
	 * Creates a new directory for the given path
69
	 *
70
	 * @param string $path Path to the directory
71
	 * @return \Aimeos\Base\Filesystem\DirIface Filesystem object for fluent interface
72
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
73
	 */
74
	public function mkdir( string $path ) : DirIface
75
	{
76
		if( $this->getProvider()->createDir( $path ) === false ) {
77
			throw new Exception( $path );
78
		}
79
80
		return $this;
81
	}
82
83
84
	/**
85
	 * Deletes the directory for the given path
86
	 *
87
	 * @param string $path Path to the directory
88
	 * @return \Aimeos\Base\Filesystem\DirIface Filesystem object for fluent interface
89
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
90
	 */
91
	public function rmdir( string $path ) : DirIface
92
	{
93
		if( $this->getProvider()->deleteDir( $path ) === false ) {
94
			throw new Exception( $path );
95
		}
96
97
		return $this;
98
	}
99
100
101
	/**
102
	 * Returns an iterator over the entries in the given path
103
	 *
104
	 * {@inheritDoc}
105
	 *
106
	 * @param string $path Path to the filesystem or directory
107
	 * @return iterable Iterator over the entries or array with entries
108
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
109
	 */
110
	public function scan( string $path = null ) : iterable
111
	{
112
		$list = [];
113
114
		foreach( $this->getProvider()->listContents( $path ) as $entry ) {
115
			$list[] = $entry['basename'];
116
		}
117
118
		return $list;
119
	}
120
121
122
	/**
123
	 * Returns the file size
124
	 *
125
	 * @param string $path Path to the file
126
	 * @return int Size in bytes
127
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
128
	 */
129
	public function size( string $path ) : int
130
	{
131
		try {
132
			$size = $this->getProvider()->getSize( $path );
133
		} catch( \Exception $e ) {
134
			throw new Exception( $e->getMessage(), 0, $e );
135
		}
136
137
		if( $size === false ) {
138
			throw new Exception( $path );
139
		}
140
141
		return $size;
142
	}
143
144
145
	/**
146
	 * Returns the Unix time stamp for the file
147
	 *
148
	 * @param string $path Path to the file
149
	 * @return int Unix time stamp in seconds
150
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
151
	 */
152
	public function time( string $path ) : int
153
	{
154
		try {
155
			$time = $this->getProvider()->getTimestamp( $path );
156
		} catch( \Exception $e ) {
157
			throw new Exception( $e->getMessage(), 0, $e );
158
		}
159
160
		if( $time === false ) {
161
			throw new Exception( $path );
162
		}
163
164
		return $time;
165
	}
166
167
168
	/**
169
	 * Deletes the file for the given path
170
	 *
171
	 * @param string $path Path to the file
172
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
173
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
174
	 */
175
	public function rm( string $path ) : Iface
176
	{
177
		try {
178
			$this->getProvider()->delete( $path );
179
		} catch( \Exception $e ) {
180
			throw new Exception( $e->getMessage(), 0, $e );
181
		}
182
183
		return $this;
184
	}
185
186
187
	/**
188
	 * Tests if a file exists at the given path
189
	 *
190
	 * @param string $path Path to the file
191
	 * @return bool True if it exists, false if not
192
	 */
193
	public function has( string $path ) : bool
194
	{
195
		return $this->getProvider()->has( $path );
196
	}
197
198
199
	/**
200
	 * Returns the content of the file
201
	 *
202
	 * {@inheritDoc}
203
	 *
204
	 * @param string $path Path to the file
205
	 * @return string File content
206
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
207
	 */
208
	public function read( string $path ) : string
209
	{
210
		try {
211
			$content = $this->getProvider()->read( $path );
212
		} catch( \Exception $e ) {
213
			throw new Exception( $e->getMessage(), 0, $e );
214
		}
215
216
		if( $content === false ) {
217
			throw new Exception( $path );
218
		}
219
220
		return $content;
221
	}
222
223
224
	/**
225
	 * Reads the content of the remote file and writes it to a local one
226
	 *
227
	 * @param string $path Path to the remote file
228
	 * @return string Path of the local file
229
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
230
	 */
231
	public function readf( string $path ) : string
232
	{
233
		if( ( $filename = tempnam( $this->tempdir, 'ai-' ) ) === false ) {
234
			throw new Exception( sprintf( 'Unable to create file in "%1$s"', $this->tempdir ) );
235
		}
236
237
		if( ( $handle = @fopen( $filename, 'w' ) ) === false ) {
238
			throw new Exception( sprintf( 'Unable to open file "%1$s"', $filename ) );
239
		}
240
241
		$stream = $this->reads( $path );
242
243
		if( @stream_copy_to_stream( $stream, $handle ) == false ) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing @stream_copy_to_stream($stream, $handle) of type false|integer against false; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
244
			throw new Exception( sprintf( 'Couldn\'t copy stream for "%1$s"', $path ) );
245
		}
246
247
		fclose( $stream );
248
		fclose( $handle );
249
250
		return $filename;
251
	}
252
253
254
	/**
255
	 * Returns the stream descriptor for the file
256
	 *
257
	 * {@inheritDoc}
258
	 *
259
	 * @param string $path Path to the file
260
	 * @return resource File stream descriptor
261
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
262
	 */
263
	public function reads( string $path )
264
	{
265
		try {
266
			$handle = $this->getProvider()->readStream( $path );
267
		} catch( \Exception $e ) {
268
			throw new Exception( $e->getMessage(), 0, $e );
269
		}
270
271
		if( $handle === false ) {
272
			throw new Exception( $path );
273
		}
274
275
		return $handle;
276
	}
277
278
279
	/**
280
	 * Writes the given content to the file
281
	 *
282
	 * {@inheritDoc}
283
	 *
284
	 * @param string $path Path to the file
285
	 * @param string $content New file content
286
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
287
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
288
	 */
289
	public function write( string $path, string $content ) : Iface
290
	{
291
		try {
292
			$result = $this->getProvider()->put( $path, $content );
293
		} catch( \Exception $e ) {
294
			throw new Exception( $e->getMessage(), 0, $e );
295
		}
296
297
		if( $result === false ) {
298
			throw new Exception( $path );
299
		}
300
301
		return $this;
302
	}
303
304
305
	/**
306
	 * Writes the content of the local file to the remote path
307
	 *
308
	 * {@inheritDoc}
309
	 *
310
	 * @param string $path Path to the remote file
311
	 * @param string $file Path to the local file
312
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
313
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
314
	 */
315
	public function writef( string $path, string $local ) : Iface
316
	{
317
		if( ( $handle = @fopen( $local, 'r' ) ) === false ) {
318
			throw new Exception( sprintf( 'Unable to open file "%1$s"', $local ) );
319
		}
320
321
		$this->writes( $path, $handle );
322
323
		if( is_resource( $handle ) ) {
324
			fclose( $handle );
325
		}
326
327
		return $this;
328
	}
329
330
331
	/**
332
	 * Write the content of the stream descriptor into the remote file
333
	 *
334
	 * {@inheritDoc}
335
	 *
336
	 * @param string $path Path to the file
337
	 * @param resource $stream File stream descriptor
338
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
339
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
340
	 */
341
	public function writes( string $path, $stream ) : Iface
342
	{
343
		try {
344
			$result = $this->getProvider()->putStream( $path, $stream );
345
		} catch( \Exception $e ) {
346
			throw new Exception( $e->getMessage(), 0, $e );
347
		}
348
349
		if( $result === false ) {
350
			throw new Exception( $path );
351
		}
352
353
		return $this;
354
	}
355
356
357
	/**
358
	 * Renames a file, moves it to a new location or both at once
359
	 *
360
	 * @param string $from Path to the original file
361
	 * @param string $to Path to the new file
362
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
363
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
364
	 */
365
	public function move( string $from, string $to ) : Iface
366
	{
367
		try {
368
			$result = $this->getProvider()->rename( $from, $to );
369
		} catch( \Exception $e ) {
370
			throw new Exception( $e->getMessage(), 0, $e );
371
		}
372
373
		if( $result === false ) {
374
			throw new Exception( sprintf( 'Error moving "%1$s" to "%2$s"', $from, $to ) );
375
		}
376
377
		return $this;
378
	}
379
380
381
	/**
382
	 * Copies a file to a new location
383
	 *
384
	 * @param string $from Path to the original file
385
	 * @param string $to Path to the new file
386
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
387
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
388
	 */
389
	public function copy( string $from, string $to ) : Iface
390
	{
391
		try {
392
			$result = $this->getProvider()->copy( $from, $to );
393
		} catch( \Exception $e ) {
394
			throw new Exception( $e->getMessage(), 0, $e );
395
		}
396
397
		if( $result === false ) {
398
			throw new Exception( sprintf( 'Error copying "%1$s" to "%2$s"', $from, $to ) );
399
		}
400
401
		return $this;
402
	}
403
404
405
	/**
406
	 * Returns the flysystem adapter
407
	 *
408
	 * @return \League\Flysystem\AdapterInterface Flysystem adapter
409
	 */
410
	protected function getAdapter()
411
	{
412
		return $this->getProvider()->getAdapter();
413
	}
414
415
416
	/**
417
	 * Returns the configuration options
418
	 *
419
	 * @return array Configuration options
420
	 */
421
	protected function getConfig()
422
	{
423
		return $this->config;
424
	}
425
426
427
	/**
428
	 * Returns the file system provider
429
	 *
430
	 * @return \League\Flysystem\FilesystemInterface File system provider
431
	 */
432
	abstract protected function getProvider();
433
}
434