Completed
Push — master ( 1d6e1a...19a3cd )
by Sebastian
03:35
created

Target::appendFileSuffix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 4
ccs 1
cts 1
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
namespace phpbu\App\Backup;
3
4
use phpbu\App\Exception;
5
use phpbu\App\Util\Str;
6
7
/**
8
 * Backup Target class.
9
 *
10
 * @package    phpbu
11
 * @subpackage Backup
12
 * @author     Sebastian Feldmann <[email protected]>
13
 * @copyright  Sebastian Feldmann <[email protected]>
14
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
15
 * @link       http://phpbu.de/
16
 * @since      Class available since Release 1.0.0
17
 */
18
class Target
19
{
20
    /**
21
     * Absolute path to the directory where to store the backup.
22
     *
23
     * @var string
24
     */
25
    private $path;
26
27
    /**
28
     * Path to the backup with potential date placeholders like %d.
29
     *
30
     * @var string
31
     */
32
    private $pathRaw;
33
34
    /**
35
     * Indicates if the path changes over time.
36
     *
37
     * @var boolean
38
     */
39
    private $pathIsChanging = false;
40
41
    /**
42
     * Part of the path without placeholders
43
     *
44
     * @var string
45
     */
46
    private $pathNotChanging;
47
48
    /**
49
     * List of directories containing date placeholders
50
     *
51
     * @var array
52
     */
53
    private $pathElementsChanging = [];
54
55
    /**
56
     * Backup filename.
57
     *
58
     * @var string
59
     */
60
    private $filename;
61
62
    /**
63
     * Filename with potential date placeholders like %d.
64
     *
65
     * @var string
66
     */
67
    private $filenameRaw;
68
69
    /**
70
     * Indicates if the filename changes over time.
71
     *
72
     * @var boolean
73
     */
74
    private $filenameIsChanging = false;
75
76
    /**
77
     * Target MIME type
78
     *
79
     * @var string
80
     */
81
    private $mimeType = 'text/plain';
82
83
    /**
84
     * Size in bytes
85
     *
86
     * @var integer
87
     */
88
    private $size;
89
90
    /**
91
     * Should the file be compressed.
92
     *
93
     * @var boolean
94
     */
95
    private $compress = false;
96
97
    /**
98
     * File compression.
99
     *
100
     * @var \phpbu\App\Backup\Compressor
101
     */
102
    private $compressor;
103
104
    /**
105
     * Should the file be encrypted.
106
     *
107
     * @var boolean
108
     */
109
    private $crypt = false;
110
111
    /**
112
     * File crypter.
113
     *
114
     * @var \phpbu\App\Backup\Crypter
115
     */
116
    private $crypter;
117
118
    /**
119
     * Constructor.
120
     *
121
     * @param  string  $path
122
     * @param  string  $filename
123
     * @param  integer $time
124
     * @throws \phpbu\App\Exception
125
     */
126 34
    public function __construct($path, $filename, $time = null)
127
    {
128 34
        $this->setPath($path, $time);
129 34
        $this->setFile($filename, $time);
130 34
    }
131
132
    /**
133
     * Directory setter.
134
     *
135
     * @param  string  $path
136
     * @param  integer $time
137
     * @throws \phpbu\App\Exception
138
     */
139 34
    public function setPath($path, $time = null)
140
    {
141 34
        $this->pathRaw = $path;
142 34
        if (false !== strpos($path, '%')) {
143 10
            $this->pathIsChanging = true;
144
            // path should be absolute so we remove the root slash
145 10
            $dirs = explode('/', substr($this->pathRaw, 1));
146
147 10
            $this->pathNotChanging = '';
148 10
            $foundChangingElement  = false;
149 10
            foreach ($dirs as $d) {
150 10
                if ($foundChangingElement || false !== strpos($d, '%')) {
151 10
                    $this->pathElementsChanging[] = $d;
152 10
                    $foundChangingElement         = true;
153 10
                } else {
154 10
                    $this->pathNotChanging .= DIRECTORY_SEPARATOR . $d;
155
                }
156 10
            }
157
            // replace potential date placeholder
158 10
            $path = Str::replaceDatePlaceholders($path, $time);
159 10
        } else {
160 24
            $this->pathNotChanging = $path;
161
        }
162 34
        $this->path = rtrim($path, DIRECTORY_SEPARATOR);
163 34
    }
164
165
    /**
166
     * Filename setter.
167
     *
168
     * @param string  $file
169
     * @param integer $time
170
     */
171 34
    public function setFile($file, $time = null)
172
    {
173 34
        $this->filenameRaw = $file;
174 34
        if (false !== strpos($file, '%')) {
175 20
            $this->filenameIsChanging = true;
176 20
            $file                     = Str::replaceDatePlaceholders($file, $time);
177 20
        }
178 34
        $this->filename = $file;
179 34
    }
180
181
    /**
182
     * Append another suffix to the filename.
183
     * 
184
     * @param string $suffix
185
     */
186
    public function appendFileSuffix($suffix)
187 4
    {
188
        $this->filename .= '.' . $suffix;
189
    }
190 4
191 3
    /**
192 3
     * Checks if the backup target directory is writable.
193 3
     * Creates the Directory if it doesn't exist.
194 3
     *
195 3
     * @throws \phpbu\App\Exception
196 1
     */
197
    public function setupPath()
198 2
    {
199 3
        // if directory doesn't exist, create it
200 1
        if (!is_dir($this->path)) {
201
            $reporting = error_reporting();
202 2
            error_reporting(0);
203
            $created = mkdir($this->path, 0755, true);
204
            error_reporting($reporting);
205
            if (!$created) {
206
                throw new Exception(sprintf('cant\'t create directory: %s', $this->path));
207
            }
208
        }
209 1
        if (!is_writable($this->path)) {
210
            throw new Exception(sprintf('no write permission for directory: %s', $this->path));
211 1
        }
212 1
    }
213
214
    /**
215
     * Target file MIME type setter.
216
     *
217
     * @param string $mime
218
     */
219 5
    public function setMimeType($mime)
220
    {
221 5
        $this->mimeType = $mime;
222
    }
223
224
    /**
225
     * Return the path to the backup file.
226
     *
227
     * @return string
228
     */
229 1
    public function getPath()
230
    {
231 1
        return $this->path;
232
    }
233
234
    /**
235
     * Return the path to the backup file.
236
     *
237
     * @return string
238
     */
239
    public function getPathRaw()
240 18
    {
241
        return $this->pathRaw;
242 18
    }
243 18
244 16
    /**
245 16
     * Return the name to the backup file.
246 16
     *
247 18
     * @param  boolean $plain
248
     * @return string
249
     */
250
    public function getFilename($plain = false)
251
    {
252
        $suffix = '';
253
        if (!$plain) {
254
            $suffix .= $this->shouldBeCompressed() ? '.' . $this->compressor->getSuffix() : '';
255 1
            $suffix .= $this->shouldBeEncrypted() ? '.' . $this->crypter->getSuffix() : '';
256
        }
257 1
        return $this->filename . $suffix;
258
    }
259
260
    /**
261
     * Return the name of the backup file without compressor or encryption suffix.
262
     *
263
     * @return string
264
     */
265 7
    public function getFilenamePlain()
266
    {
267 7
        return $this->getFilename(true);
268
    }
269
270
    /**
271
     * Return the raw name of the backup file incl. date placeholder.
272
     *
273
     * @return string
274
     */
275 3
    public function getFilenameRaw()
276
    {
277 3
        return $this->filenameRaw;
278 3
    }
279 1
280 1
    /**
281 3
     * Return file MIME type.
282
     *
283
     * @return string
284
     */
285
    public function getMimeType()
286
    {
287
        $mimeType = $this->mimeType;
288
        if ($this->shouldBeCompressed()) {
289
            $mimeType = $this->compressor->getMimeType();
290 2
        }
291
        return $mimeType;
292 2
    }
293 2
294 1
    /**
295
     * Size setter.
296 1
     *
297 1
     * @param int $size
298 1
     */
299
    public function setSize($size)
300
    {
301
        $this->size = $size;
302
    }
303
304
    /**
305
     * Return the actual filesize in bytes.
306
     *
307 4
     * @throws Exception
308
     * @return integer
309 4
     */
310
    public function getSize()
311
    {
312
        if (null === $this->size) {
313
            if (!file_exists($this)) {
314
                throw new Exception(sprintf('target file \'%s\' doesn\'t exist', $this->getFilename()));
315
            }
316
            $this->size = filesize($this);
317
        }
318 3
        return $this->size;
319
    }
320 3
321 1
    /**
322
     * Target file exists already.
323 2
     *
324 1
     * @param  boolean $plain
325
     * @return boolean
326 1
     */
327 1
    public function fileExists($plain = false)
328
    {
329
        return file_exists($this->getPathname($plain));
330
    }
331
332
    /**
333
     * Return as backup file object.
334
     *
335 14
     * @return \phpbu\App\Backup\File
336
     */
337 14
    public function toFile()
338
    {
339 14
        return new File(new \SplFileInfo($this->getPathname()));
340
    }
341
342
    /**
343
     * Deletes the target file.
344
     *
345
     * @param  boolean $plain
346
     * @throws \phpbu\App\Exception
347 1
     */
348
    public function unlink($plain = false)
349 1
    {
350
        if (!$this->fileExists($plain)) {
351
            throw new Exception(sprintf('target file \'%s\' doesn\'t exist', $this->getFilename($plain)));
352
        }
353
        if (!is_writable($this->getPathname($plain))) {
354
            throw new Exception(sprintf('can\t delete file \'%s\'', $this->getFilename($plain)));
355
        }
356
        unlink($this->getPathname($plain));
357 2
    }
358
359 2
    /**
360
     * Return path and filename of the backup file.
361
     *
362
     * @param  boolean $plain
363
     * @return string
364
     */
365
    public function getPathname($plain = false)
366
    {
367 7
        return $this->path
368
        . DIRECTORY_SEPARATOR
369 7
        . $this->getFilename($plain);
370
    }
371
372
    /**
373
     * Return path and plain filename of the backup file.
374
     *
375
     * @return string
376
     */
377 1
    public function getPathnamePlain()
378
    {
379 1
        return $this->getPathname(true);
380
    }
381
382
    /**
383
     * Is dirname configured with any date placeholders.
384
     *
385
     * @return boolean
386
     */
387 9
    public function hasChangingPath()
388
    {
389 9
        return $this->pathIsChanging;
390
    }
391
392
    /**
393
     * Return the part of the path that is not changing.
394
     *
395
     * @return string
396
     */
397 2
    public function getPathThatIsNotChanging()
398
    {
399 2
        return $this->pathNotChanging;
400
    }
401
402
    /**
403
     * Changing path elements getter.
404
     *
405
     * @return array
406
     */
407
    public function getChangingPathElements()
408
    {
409
        return $this->pathElementsChanging;
410
    }
411
412
    /**
413
     * Return amount of changing path elements.
414
     *
415
     * @return integer
416
     */
417
    public function countChangingPathElements()
418
    {
419
        return count($this->pathElementsChanging);
420
    }
421
422
    /**
423
     * Filename configured with any date placeholders.
424
     *
425
     * @return boolean
426
     */
427
    public function hasChangingFilename()
428 7
    {
429
        return $this->filenameIsChanging;
430 7
    }
431 7
432 7
    /**
433
     * Disable file compression.
434
     */
435
    public function disableCompression()
436
    {
437
        $this->compress = false;
438
    }
439 2
440
    /**
441 2
     * Enable file compression.
442
     *
443
     * @throws \phpbu\App\Exception
444
     */
445
    public function enableCompression()
446
    {
447
        if (null == $this->compressor) {
448
            throw new Exception('can\'t enable compression without a compressor');
449 20
        }
450
        $this->compress = true;
451 20
    }
452
453
    /**
454
     * Compressor setter.
455
     *
456
     * @param \phpbu\App\Backup\Compressor $compressor
457
     */
458
    public function setCompressor(Compressor $compressor)
459 1
    {
460
        $this->compressor = $compressor;
461 1
        $this->compress   = true;
462
    }
463
464
    /**
465
     * Compressor getter.
466
     *
467
     * @return \phpbu\App\Backup\Compressor
468
     */
469 2
    public function getCompressor()
470
    {
471 2
        return $this->compressor;
472 2
    }
473 2
474
    /**
475
     * Is a compressor set?
476
     *
477
     * @return boolean
478
     */
479
    public function shouldBeCompressed()
480 1
    {
481
        return $this->compress !== false;
482 1
    }
483
484
    /**
485
     * Is the target already compressed.
486
     *
487
     * @return boolean
488
     */
489
    public function isCompressed()
490
    {
491
        return $this->shouldBeCompressed() ? file_exists($this->getPathname()) : false;
492
    }
493
494
    /**
495
     * Crypter setter.
496
     *
497
     * @param \phpbu\App\Backup\Crypter $crypter
498 16
     */
499
    public function setCrypter(Crypter $crypter)
500 16
    {
501
        $this->crypter = $crypter;
502
        $this->crypt   = true;
503
    }
504
505
    /**
506
     * Crypter getter.
507
     *
508 2
     * @return \phpbu\App\Backup\Crypter
509
     */
510 2
    public function getCrypter()
511
    {
512
        return $this->crypter;
513
    }
514
515
    /**
516
     * Disable file encryption.
517
     */
518
    public function disableEncryption()
519
    {
520
        $this->crypt = false;
521
    }
522
523
    /**
524
     * Is a crypter set?
525
     *
526
     * @return boolean
527
     */
528
    public function shouldBeEncrypted()
529
    {
530
        return $this->crypt !== false;
531
    }
532
533
    /**
534
     * Magic to string method.
535
     *
536
     * @return string
537
     */
538
    public function __toString()
539
    {
540
        return $this->getPathname();
541
    }
542
}
543