FlyBase::writes()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 9
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-2024
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 array $config;
23
	private string $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
	 * @param string|null $local Path to the local file (optional)
239
	 * @return string Path of the local file
240
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
241
	 */
242
	public function readf( string $path, string $local = null ) : string
243
	{
244
		if( $local === null && ( $local = @tempnam( $this->tempdir, 'ai-' ) ) === false ) {
245
			throw new Exception( sprintf( 'Unable to create file in "%1$s"', $this->tempdir ) );
246
		}
247
248
		if( ( $handle = @fopen( $local, 'w' ) ) === false ) {
249
			throw new Exception( sprintf( 'Unable to open file "%1$s"', $local ) );
250
		}
251
252
		$stream = $this->reads( $path );
253
254
		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...
255
			throw new Exception( sprintf( 'Couldn\'t copy stream for "%1$s"', $path ) );
256
		}
257
258
		fclose( $stream );
259
		fclose( $handle );
260
261
		return $local;
262
	}
263
264
265
	/**
266
	 * Returns the stream descriptor for the file
267
	 *
268
	 * {@inheritDoc}
269
	 *
270
	 * @param string $path Path to the file
271
	 * @return resource File stream descriptor
272
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
273
	 */
274
	public function reads( string $path )
275
	{
276
		try {
277
			return $this->getProvider()->readStream( $path );
278
		} catch( \Exception $e ) {
279
			throw new Exception( $e->getMessage(), 0, $e );
280
		}
281
	}
282
283
284
	/**
285
	 * Writes the given content to the file
286
	 *
287
	 * {@inheritDoc}
288
	 *
289
	 * @param string $path Path to the file
290
	 * @param string $content New file content
291
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
292
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
293
	 */
294
	public function write( string $path, string $content ) : Iface
295
	{
296
		try {
297
			$this->getProvider()->write( $path, $content );
298
		} catch( \Exception $e ) {
299
			throw new Exception( $e->getMessage(), 0, $e );
300
		}
301
302
		return $this;
303
	}
304
305
306
	/**
307
	 * Writes the content of the local file to the remote path
308
	 *
309
	 * {@inheritDoc}
310
	 *
311
	 * @param string $path Path to the remote file
312
	 * @param string $local Path to the local file
313
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
314
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
315
	 */
316
	public function writef( string $path, string $local ) : Iface
317
	{
318
		if( ( $handle = @fopen( $local, 'r' ) ) === false ) {
319
			throw new Exception( sprintf( 'Unable to open file "%1$s"', $local ) );
320
		}
321
322
		$this->writes( $path, $handle );
323
324
		if( is_resource( $handle ) ) {
325
			fclose( $handle );
326
		}
327
328
		return $this;
329
	}
330
331
332
	/**
333
	 * Write the content of the stream descriptor into the remote file
334
	 *
335
	 * {@inheritDoc}
336
	 *
337
	 * @param string $path Path to the file
338
	 * @param resource $stream File stream descriptor
339
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
340
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
341
	 */
342
	public function writes( string $path, $stream ) : Iface
343
	{
344
		try {
345
			$this->getProvider()->writeStream( $path, $stream );
346
		} catch( \Exception $e ) {
347
			throw new Exception( $e->getMessage(), 0, $e );
348
		}
349
350
		return $this;
351
	}
352
353
354
	/**
355
	 * Renames a file, moves it to a new location or both at once
356
	 *
357
	 * @param string $from Path to the original file
358
	 * @param string $to Path to the new file
359
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
360
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
361
	 */
362
	public function move( string $from, string $to ) : Iface
363
	{
364
		try {
365
			$this->getProvider()->move( $from, $to );
366
		} catch( \Exception $e ) {
367
			throw new Exception( $e->getMessage(), 0, $e );
368
		}
369
370
		return $this;
371
	}
372
373
374
	/**
375
	 * Copies a file to a new location
376
	 *
377
	 * @param string $from Path to the original file
378
	 * @param string $to Path to the new file
379
	 * @return \Aimeos\Base\Filesystem\Iface Filesystem object for fluent interface
380
	 * @throws \Aimeos\Base\Filesystem\Exception If an error occurs
381
	 */
382
	public function copy( string $from, string $to ) : Iface
383
	{
384
		try {
385
			$this->getProvider()->copy( $from, $to );
386
		} catch( \Exception $e ) {
387
			throw new Exception( $e->getMessage(), 0, $e );
388
		}
389
390
		return $this;
391
	}
392
393
394
	/**
395
	 * Returns the configuration options
396
	 *
397
	 * @return array Configuration options
398
	 */
399
	protected function getConfig()
400
	{
401
		return $this->config;
402
	}
403
404
405
	/**
406
	 * Returns the file system provider
407
	 *
408
	 * @return \League\Flysystem\Filesystem File system provider
409
	 */
410
	abstract protected function getProvider();
411
}
412