Completed
Push — master ( 2c9ca9...7241ae )
by Sebastian
08:02
created

Target::getCrypterSuffix()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 2
eloc 2
nc 2
nop 0
crap 2
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
     * List of custom file suffixes f.e. 'tar'
71
     *
72
     * @var array
73
     */
74
    private $fileSuffixes = [];
75
76
    /**
77
     * Indicates if the filename changes over time.
78
     *
79
     * @var boolean
80
     */
81
    private $filenameIsChanging = false;
82
83
    /**
84
     * Target MIME type
85
     *
86
     * @var string
87
     */
88
    private $mimeType = 'text/plain';
89
90
    /**
91
     * Size in bytes
92
     *
93
     * @var integer
94
     */
95
    private $size;
96
97
    /**
98
     * Should the file be compressed.
99
     *
100
     * @var boolean
101
     */
102
    private $compress = false;
103
104
    /**
105
     * File compression.
106
     *
107
     * @var \phpbu\App\Backup\Compressor
108
     */
109
    private $compressor;
110
111
    /**
112
     * Should the file be encrypted.
113
     *
114
     * @var boolean
115
     */
116
    private $crypt = false;
117
118
    /**
119
     * File crypter.
120
     *
121
     * @var \phpbu\App\Backup\Crypter
122
     */
123
    private $crypter;
124
125
    /**
126 34
     * Constructor.
127
     *
128 34
     * @param  string  $path
129 34
     * @param  string  $filename
130 34
     * @param  integer $time
131
     * @throws \phpbu\App\Exception
132
     */
133
    public function __construct($path, $filename, $time = null)
134
    {
135
        $this->setPath($path, $time);
136
        $this->setFile($filename, $time);
137
    }
138
139 34
    /**
140
     * Directory setter.
141 34
     *
142 34
     * @param  string  $path
143 10
     * @param  integer $time
144
     * @throws \phpbu\App\Exception
145 10
     */
146
    public function setPath($path, $time = null)
147 10
    {
148 10
        $this->pathRaw = $path;
149 10
        if ($this->isContainingPlaceholder($path)) {
150 10
            $this->pathIsChanging = true;
151 10
            // path should be absolute so we remove the root slash
152 10
            $dirs = explode('/', substr($this->pathRaw, 1));
153 10
154 10
            $this->pathNotChanging = '';
155
            $foundChangingElement  = false;
156 10
            foreach ($dirs as $d) {
157
                if ($foundChangingElement || $this->isContainingPlaceholder($d)) {
158 10
                    $this->pathElementsChanging[] = $d;
159 10
                    $foundChangingElement         = true;
160 24
                } else {
161
                    $this->pathNotChanging .= DIRECTORY_SEPARATOR . $d;
162 34
                }
163 34
            }
164
            // replace potential date placeholder
165
            $path = Str::replaceDatePlaceholders($path, $time);
166
        } else {
167
            $this->pathNotChanging = $path;
168
        }
169
        $this->path = rtrim($path, DIRECTORY_SEPARATOR);
170
    }
171 34
172
    /**
173 34
     * Does the path contain a date placeholder.
174 34
     *
175 20
     * @param  string $path
176 20
     * @return bool
177 20
     */
178 34
    public function isContainingPlaceholder($path)
179 34
    {
180
        return false !== strpos($path, '%');
181
    }
182
183
    /**
184
     * Filename setter.
185
     *
186
     * @param string  $file
187 4
     * @param integer $time
188
     */
189
    public function setFile($file, $time = null)
190 4
    {
191 3
        $this->filenameRaw = $file;
192 3
        if ($this->isContainingPlaceholder($file)) {
193 3
            $this->filenameIsChanging = true;
194 3
            $file                     = Str::replaceDatePlaceholders($file, $time);
195 3
        }
196 1
        $this->filename = $file;
197
    }
198 2
199 3
    /**
200 1
     * Append another suffix to the filename.
201
     * 
202 2
     * @param string $suffix
203
     */
204
    public function appendFileSuffix($suffix)
205
    {
206
        $this->fileSuffixes[] = $suffix;
207
    }
208
209 1
    /**
210
     * Checks if the backup target directory is writable.
211 1
     * Creates the Directory if it doesn't exist.
212 1
     *
213
     * @throws \phpbu\App\Exception
214
     */
215
    public function setupPath()
216
    {
217
        // if directory doesn't exist, create it
218
        if (!is_dir($this->path)) {
219 5
            $reporting = error_reporting();
220
            error_reporting(0);
221 5
            $created = mkdir($this->path, 0755, true);
222
            error_reporting($reporting);
223
            if (!$created) {
224
                throw new Exception(sprintf('cant\'t create directory: %s', $this->path));
225
            }
226
        }
227
        if (!is_writable($this->path)) {
228
            throw new Exception(sprintf('no write permission for directory: %s', $this->path));
229 1
        }
230
    }
231 1
232
    /**
233
     * Target file MIME type setter.
234
     *
235
     * @param string $mime
236
     */
237
    public function setMimeType($mime)
238
    {
239
        $this->mimeType = $mime;
240 18
    }
241
242 18
    /**
243 18
     * Return the path to the backup file.
244 16
     *
245 16
     * @return string
246 16
     */
247 18
    public function getPath()
248
    {
249
        return $this->path;
250
    }
251
252
    /**
253
     * Return the path to the backup file.
254
     *
255 1
     * @return string
256
     */
257 1
    public function getPathRaw()
258
    {
259
        return $this->pathRaw;
260
    }
261
262
    /**
263
     * Return the name to the backup file.
264
     *
265 7
     * @return string
266
     */
267 7
    public function getFilename()
268
    {
269
        return $this->filename
270
            . $this->getFilenameSuffix()
271
            . $this->getCompressorSuffix()
272
            . $this->getCrypterSuffix();;
273
    }
274
275 3
    /**
276
     * Return the name of the backup file without compressor or encryption suffix.
277 3
     *
278 3
     * @return string
279 1
     */
280 1
    public function getFilenamePlain()
281 3
    {
282
        return $this->filename . $this->getFilenameSuffix();
283
    }
284
285
    /**
286
     * Return the raw name of the backup file incl. date placeholder.
287
     *
288
     * @return string
289
     */
290 2
    public function getFilenameRaw()
291
    {
292 2
        return $this->filenameRaw
293 2
            . $this->getFilenameSuffix()
294 1
            . $this->getCompressorSuffix()
295
            . $this->getCrypterSuffix();
296 1
    }
297 1
298 1
    /**
299
     * Return custom file suffix like '.tar'.
300
     *
301
     * @return string
302
     */
303
    public function getFilenameSuffix()
304
    {
305
        return count($this->fileSuffixes) ? '.' . implode('.', $this->fileSuffixes) : '';
306
    }
307 4
308
    /**
309 4
     * Return the compressor suffix.
310
     *
311
     * @return string
312
     */
313
    public function getCompressorSuffix()
314
    {
315
        return $this->shouldBeCompressed() ? '.' . $this->compressor->getSuffix() : '';
316
    }
317
318 3
    /**
319
     * Return the crypter suffix.
320 3
     *
321 1
     * @return string
322
     */
323 2
    public function getCrypterSuffix()
324 1
    {
325
        return $this->shouldBeEncrypted() ? '.' . $this->crypter->getSuffix() : '';
326 1
    }
327 1
328
    /**
329
     * Return file MIME type.
330
     *
331
     * @return string
332
     */
333
    public function getMimeType()
334
    {
335 14
        $mimeType = $this->mimeType;
336
        if ($this->shouldBeCompressed()) {
337 14
            $mimeType = $this->compressor->getMimeType();
338
        }
339 14
        return $mimeType;
340
    }
341
342
    /**
343
     * Size setter.
344
     *
345
     * @param int $size
346
     */
347 1
    public function setSize($size)
348
    {
349 1
        $this->size = $size;
350
    }
351
352
    /**
353
     * Return the actual file size in bytes.
354
     *
355
     * @throws Exception
356
     * @return integer
357 2
     */
358
    public function getSize()
359 2
    {
360
        if (null === $this->size) {
361
            if (!file_exists($this)) {
362
                throw new Exception(sprintf('target file \'%s\' doesn\'t exist', $this->getFilename()));
363
            }
364
            $this->size = filesize($this);
365
        }
366
        return $this->size;
367 7
    }
368
369 7
    /**
370
     * Target file exists already.
371
     *
372
     * @param  boolean $plain
373
     * @return boolean
374
     */
375
    public function fileExists($plain = false)
376
    {
377 1
        return file_exists($this->getPathname($plain));
0 ignored issues
show
Unused Code introduced by
The call to Target::getPathname() has too many arguments starting with $plain.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
378
    }
379 1
380
    /**
381
     * Return as backup file object.
382
     *
383
     * @return \phpbu\App\Backup\File
384
     */
385
    public function toFile()
386
    {
387 9
        return new File(new \SplFileInfo($this->getPathname()));
388
    }
389 9
390
    /**
391
     * Deletes the target file.
392
     *
393
     * @param  boolean $plain
394
     * @throws \phpbu\App\Exception
395
     */
396
    public function unlink($plain = false)
397 2
    {
398
        if (!$this->fileExists($plain)) {
399 2
            throw new Exception(sprintf('target file \'%s\' doesn\'t exist', $this->getFilename($plain)));
0 ignored issues
show
Unused Code introduced by
The call to Target::getFilename() has too many arguments starting with $plain.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
400
        }
401
        if (!is_writable($this->getPathname($plain))) {
0 ignored issues
show
Unused Code introduced by
The call to Target::getPathname() has too many arguments starting with $plain.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
402
            throw new Exception(sprintf('can\t delete file \'%s\'', $this->getFilename($plain)));
0 ignored issues
show
Unused Code introduced by
The call to Target::getFilename() has too many arguments starting with $plain.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
403
        }
404
        unlink($this->getPathname($plain));
0 ignored issues
show
Unused Code introduced by
The call to Target::getPathname() has too many arguments starting with $plain.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
405
    }
406
407
    /**
408
     * Return path and filename of the backup file.
409
     *
410
     * @return string
411
     */
412
    public function getPathname()
413
    {
414
        return $this->path . DIRECTORY_SEPARATOR . $this->getFilename();
415
    }
416
417
    /**
418
     * Return path and plain filename of the backup file.
419
     *
420
     * @return string
421
     */
422
    public function getPathnamePlain()
423
    {
424
        return $this->path . DIRECTORY_SEPARATOR . $this->getFilenamePlain();
425
    }
426
427
    /**
428 7
     * Is dirname configured with any date placeholders.
429
     *
430 7
     * @return boolean
431 7
     */
432 7
    public function hasChangingPath()
433
    {
434
        return $this->pathIsChanging;
435
    }
436
437
    /**
438
     * Return the part of the path that is not changing.
439 2
     *
440
     * @return string
441 2
     */
442
    public function getPathThatIsNotChanging()
443
    {
444
        return $this->pathNotChanging;
445
    }
446
447
    /**
448
     * Changing path elements getter.
449 20
     *
450
     * @return array
451 20
     */
452
    public function getChangingPathElements()
453
    {
454
        return $this->pathElementsChanging;
455
    }
456
457
    /**
458
     * Return amount of changing path elements.
459 1
     *
460
     * @return integer
461 1
     */
462
    public function countChangingPathElements()
463
    {
464
        return count($this->pathElementsChanging);
465
    }
466
467
    /**
468
     * Filename configured with any date placeholders.
469 2
     *
470
     * @return boolean
471 2
     */
472 2
    public function hasChangingFilename()
473 2
    {
474
        return $this->filenameIsChanging;
475
    }
476
477
    /**
478
     * Disable file compression.
479
     */
480 1
    public function disableCompression()
481
    {
482 1
        $this->compress = false;
483
    }
484
485
    /**
486
     * Enable file compression.
487
     *
488
     * @throws \phpbu\App\Exception
489
     */
490
    public function enableCompression()
491
    {
492
        if (null == $this->compressor) {
493
            throw new Exception('can\'t enable compression without a compressor');
494
        }
495
        $this->compress = true;
496
    }
497
498 16
    /**
499
     * Compressor setter.
500 16
     *
501
     * @param \phpbu\App\Backup\Compressor $compressor
502
     */
503
    public function setCompressor(Compressor $compressor)
504
    {
505
        $this->compressor = $compressor;
506
        $this->compress   = true;
507
    }
508 2
509
    /**
510 2
     * Compressor getter.
511
     *
512
     * @return \phpbu\App\Backup\Compressor
513
     */
514
    public function getCompressor()
515
    {
516
        return $this->compressor;
517
    }
518
519
    /**
520
     * Is a compressor set?
521
     *
522
     * @return boolean
523
     */
524
    public function shouldBeCompressed()
525
    {
526
        return $this->compress !== false;
527
    }
528
529
    /**
530
     * Crypter setter.
531
     *
532
     * @param \phpbu\App\Backup\Crypter $crypter
533
     */
534
    public function setCrypter(Crypter $crypter)
535
    {
536
        $this->crypter = $crypter;
537
        $this->crypt   = true;
538
    }
539
540
    /**
541
     * Crypter getter.
542
     *
543
     * @return \phpbu\App\Backup\Crypter
544
     */
545
    public function getCrypter()
546
    {
547
        return $this->crypter;
548
    }
549
550
    /**
551
     * Disable file encryption.
552
     */
553
    public function disableEncryption()
554
    {
555
        $this->crypt = false;
556
    }
557
558
    /**
559
     * Is a crypter set?
560
     *
561
     * @return boolean
562
     */
563
    public function shouldBeEncrypted()
564
    {
565
        return $this->crypt !== false;
566
    }
567
568
    /**
569
     * Magic to string method.
570
     *
571
     * @return string
572
     */
573
    public function __toString()
574
    {
575
        return $this->getPathname();
576
    }
577
}
578