Passed
Push — master ( a6ecf0...539a45 )
by Aimeos
01:59
created

FlyBase::getAdapter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
		if( !isset( $config['tempdir'] ) ) {
34
			$config['tempdir'] = sys_get_temp_dir();
35
		}
36
37
		if( !is_dir( $config['tempdir'] ) && mkdir( $config['tempdir'], 0755, true ) === false ) {
38
			throw new Exception( sprintf( 'Directory "%1$s" could not be created', $config['tempdir'] ) );
39
		}
40
41
		$ds = DIRECTORY_SEPARATOR;
42
		$this->tempdir = realpath( str_replace( '/', $ds, rtrim( $config['tempdir'], '/' ) ) ) . $ds;
43
		$this->config = $config;
44
	}
45
46
47
	/**
48
	 * Tests if the given path is a directory
49
	 *
50
	 * @param string $path Path to the file or directory
51
	 * @return bool True if directory, false if not
52
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
53
	 */
54
	public function isdir( string $path ) : bool
55
	{
56
		try {
57
			foreach( $this->getProvider()->listContents( $path ) as $attr ) {
58
				return $attr->isDir();
59
			}
60
		} catch( \Exception $e ) {
61
			throw new Exception( $e->getMessage(), 0, $e );
62
		}
63
64
		return false;
65
	}
66
67
68
	/**
69
	 * Creates a new directory for the given path
70
	 *
71
	 * @param string $path Path to the directory
72
	 * @return \Aimeos\Base\Filesystem\DirIface Filesystem object for fluent interface
73
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
74
	 */
75
	public function mkdir( string $path ) : DirIface
76
	{
77
		try {
78
			$this->getProvider()->createDirectory( $path );
79
		} catch( \Exception $e ) {
80
			throw new Exception( $e->getMessage(), 0, $e );
81
		}
82
83
		return $this;
84
	}
85
86
87
	/**
88
	 * Deletes the directory for the given path
89
	 *
90
	 * @param string $path Path to the directory
91
	 * @return \Aimeos\Base\Filesystem\DirIface Filesystem object for fluent interface
92
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
93
	 */
94
	public function rmdir( string $path ) : DirIface
95
	{
96
		try {
97
			$this->getProvider()->deleteDirectory( $path );
98
		} catch( \Exception $e ) {
99
			throw new Exception( $e->getMessage(), 0, $e );
100
		}
101
102
		return $this;
103
	}
104
105
106
	/**
107
	 * Returns an iterator over the entries in the given path
108
	 *
109
	 * {@inheritDoc}
110
	 *
111
	 * @param string $path Path to the filesystem or directory
112
	 * @return iterable Iterator over the entries or array with entries
113
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
114
	 */
115
	public function scan( string $path = null ) : iterable
116
	{
117
		$list = [];
118
119
		try
120
		{
121
			foreach( $this->getProvider()->listContents( (string) $path ) as $attr ) {
122
				$list[] = basename( $attr->path() );
123
			}
124
		}
125
		catch( \Exception $e )
126
		{
127
			throw new Exception( $e->getMessage(), 0, $e );
128
		}
129
130
		return $list;
131
	}
132
133
134
	/**
135
	 * Returns the file size
136
	 *
137
	 * @param string $path Path to the file
138
	 * @return int Size in bytes
139
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
140
	 */
141
	public function size( string $path ) : int
142
	{
143
		try {
144
			return $this->getProvider()->fileSize( $path );
145
		} catch( \Exception $e ) {
146
			throw new Exception( $e->getMessage(), 0, $e );
147
		}
148
	}
149
150
151
	/**
152
	 * Returns the Unix time stamp for the file
153
	 *
154
	 * @param string $path Path to the file
155
	 * @return int Unix time stamp in seconds
156
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
157
	 */
158
	public function time( string $path ) : int
159
	{
160
		try {
161
			return $this->getProvider()->lastModified( $path );
162
		} catch( \Exception $e ) {
163
			throw new Exception( $e->getMessage(), 0, $e );
164
		}
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
		$result = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
196
197
		try
198
		{
199
			$provider = $this->getProvider();
200
			$result = $provider->fileExists( $path );
201
202
			if( !$result && method_exists( $provider, 'directoryExists' ) ) {
203
				$result = $provider->directoryExists( $path );
204
			}
205
		}
206
		catch( \Exception $e )
207
		{
208
			throw new Exception( $e->getMessage(), 0, $e );
209
		}
210
211
		return $result;
212
	}
213
214
215
	/**
216
	 * Returns the content of the file
217
	 *
218
	 * {@inheritDoc}
219
	 *
220
	 * @param string $path Path to the file
221
	 * @return string File content
222
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
223
	 */
224
	public function read( string $path ) : string
225
	{
226
		try {
227
			return $this->getProvider()->read( $path );
228
		} catch( \Exception $e ) {
229
			throw new Exception( $e->getMessage(), 0, $e );
230
		}
231
	}
232
233
234
	/**
235
	 * Reads the content of the remote file and writes it to a local one
236
	 *
237
	 * @param string $path Path to the remote file
238
	 * @return string Path of the local file
239
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
240
	 */
241
	public function readf( string $path ) : string
242
	{
243
		if( ( $filename = tempnam( $this->tempdir, 'ai-' ) ) === false ) {
244
			throw new Exception( sprintf( 'Unable to create file in "%1$s"', $this->tempdir ) );
245
		}
246
247
		if( ( $handle = @fopen( $filename, 'w' ) ) === false ) {
248
			throw new Exception( sprintf( 'Unable to open file "%1$s"', $filename ) );
249
		}
250
251
		$stream = $this->reads( $path );
252
253
		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...
254
			throw new Exception( sprintf( 'Couldn\'t copy stream for "%1$s"', $path ) );
255
		}
256
257
		fclose( $stream );
258
		fclose( $handle );
259
260
		return $filename;
261
	}
262
263
264
	/**
265
	 * Returns the stream descriptor for the file
266
	 *
267
	 * {@inheritDoc}
268
	 *
269
	 * @param string $path Path to the file
270
	 * @return resource File stream descriptor
271
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
272
	 */
273
	public function reads( string $path )
274
	{
275
		try {
276
			return $this->getProvider()->readStream( $path );
277
		} catch( \Exception $e ) {
278
			throw new Exception( $e->getMessage(), 0, $e );
279
		}
280
	}
281
282
283
	/**
284
	 * Writes the given content to the file
285
	 *
286
	 * {@inheritDoc}
287
	 *
288
	 * @param string $path Path to the file
289
	 * @param string $content New file content
290
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
291
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
292
	 */
293
	public function write( string $path, string $content ) : Iface
294
	{
295
		try {
296
			$this->getProvider()->write( $path, $content );
297
		} catch( \Exception $e ) {
298
			throw new Exception( $e->getMessage(), 0, $e );
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
			$this->getProvider()->writeStream( $path, $stream );
345
		} catch( \Exception $e ) {
346
			throw new Exception( $e->getMessage(), 0, $e );
347
		}
348
349
		return $this;
350
	}
351
352
353
	/**
354
	 * Renames a file, moves it to a new location or both at once
355
	 *
356
	 * @param string $from Path to the original file
357
	 * @param string $to Path to the new file
358
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
359
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
360
	 */
361
	public function move( string $from, string $to ) : Iface
362
	{
363
		try {
364
			$this->getProvider()->move( $from, $to );
365
		} catch( \Exception $e ) {
366
			throw new Exception( $e->getMessage(), 0, $e );
367
		}
368
369
		return $this;
370
	}
371
372
373
	/**
374
	 * Copies a file to a new location
375
	 *
376
	 * @param string $from Path to the original file
377
	 * @param string $to Path to the new file
378
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
379
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
380
	 */
381
	public function copy( string $from, string $to ) : Iface
382
	{
383
		try {
384
			$this->getProvider()->copy( $from, $to );
385
		} catch( \Exception $e ) {
386
			throw new Exception( $e->getMessage(), 0, $e );
387
		}
388
389
		return $this;
390
	}
391
392
393
	/**
394
	 * Returns the configuration options
395
	 *
396
	 * @return array Configuration options
397
	 */
398
	protected function getConfig()
399
	{
400
		return $this->config;
401
	}
402
403
404
	/**
405
	 * Returns the file system provider
406
	 *
407
	 * @return \League\Flysystem\Filesystem File system provider
408
	 */
409
	abstract protected function getProvider();
410
}
411