Completed
Push — master ( a44372...459e0f )
by Sebastian
07:19
created

Target::isContainingPlaceholder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
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
     * 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 (Str::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 || Str::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
     * Filename setter.
174 34
     *
175 20
     * @param string  $file
176 20
     * @param integer $time
177 20
     */
178 34
    public function setFile($file, $time = null)
179 34
    {
180
        $this->filenameRaw = $file;
181
        if (Str::isContainingPlaceholder($file)) {
182
            $this->filenameIsChanging = true;
183
            $file                     = Str::replaceDatePlaceholders($file, $time);
184
        }
185
        $this->filename = $file;
186
    }
187 4
188
    /**
189
     * Append another suffix to the filename.
190 4
     *
191 3
     * @param string $suffix
192 3
     */
193 3
    public function appendFileSuffix($suffix)
194 3
    {
195 3
        $this->fileSuffixes[] = $suffix;
196 1
    }
197
198 2
    /**
199 3
     * Checks if the backup target directory is writable.
200 1
     * Creates the Directory if it doesn't exist.
201
     *
202 2
     * @throws \phpbu\App\Exception
203
     */
204
    public function setupPath()
205
    {
206
        // if directory doesn't exist, create it
207
        if (!is_dir($this->path)) {
208
            $reporting = error_reporting();
209 1
            error_reporting(0);
210
            $created = mkdir($this->path, 0755, true);
211 1
            error_reporting($reporting);
212 1
            if (!$created) {
213
                throw new Exception(sprintf('cant\'t create directory: %s', $this->path));
214
            }
215
        }
216
        if (!is_writable($this->path)) {
217
            throw new Exception(sprintf('no write permission for directory: %s', $this->path));
218
        }
219 5
    }
220
221 5
    /**
222
     * Target file MIME type setter.
223
     *
224
     * @param string $mime
225
     */
226
    public function setMimeType($mime)
227
    {
228
        $this->mimeType = $mime;
229 1
    }
230
231 1
    /**
232
     * Return the path to the backup file.
233
     *
234
     * @return string
235
     */
236
    public function getPath()
237
    {
238
        return $this->path;
239
    }
240 18
241
    /**
242 18
     * Return the path to the backup file.
243 18
     *
244 16
     * @return string
245 16
     */
246 16
    public function getPathRaw()
247 18
    {
248
        return $this->pathRaw;
249
    }
250
251
    /**
252
     * Return the name to the backup file.
253
     *
254
     * @param  bool $plain
255 1
     * @return string
256
     */
257 1
    public function getFilename($plain = false)
258
    {
259
        return $this->filename
260
            . $this->getFilenameSuffix($plain);
261
    }
262
263
    /**
264
     * Return the name of the backup file without compressor or encryption suffix.
265 7
     *
266
     * @return string
267 7
     */
268
    public function getFilenamePlain()
269
    {
270
        return $this->getFilename(true);
271
    }
272
273
    /**
274
     * Return the raw name of the backup file incl. date placeholder.
275 3
     *
276
     * @param  bool $plain
277 3
     * @return string
278 3
     */
279 1
    public function getFilenameRaw($plain = false)
280 1
    {
281 3
        return $this->filenameRaw
282
            . $this->getFilenameSuffix($plain);
283
    }
284
285
    /**
286
     * Return custom file suffix like '.tar'.
287
     *
288
     * @param bool $plain
289
     * @return string
290 2
     */
291
    public function getFilenameSuffix($plain = false)
292 2
    {
293 2
        return (count($this->fileSuffixes) ? '.' . implode('.', $this->fileSuffixes) : '')
294 1
             . ($plain ? '' : $this->getCompressorSuffix() . $this->getCrypterSuffix());
295
    }
296 1
297 1
    /**
298 1
     * Return the compressor suffix.
299
     *
300
     * @return string
301
     */
302
    public function getCompressorSuffix()
303
    {
304
        return $this->shouldBeCompressed() ? '.' . $this->compressor->getSuffix() : '';
305
    }
306
307 4
    /**
308
     * Return the crypter suffix.
309 4
     *
310
     * @return string
311
     */
312
    public function getCrypterSuffix()
313
    {
314
        return $this->shouldBeEncrypted() ? '.' . $this->crypter->getSuffix() : '';
315
    }
316
317
    /**
318 3
     * Return file MIME type.
319
     *
320 3
     * @return string
321 1
     */
322
    public function getMimeType()
323 2
    {
324 1
        $mimeType = $this->mimeType;
325
        if ($this->shouldBeCompressed()) {
326 1
            $mimeType = $this->compressor->getMimeType();
327 1
        }
328
        return $mimeType;
329
    }
330
331
    /**
332
     * Size setter.
333
     *
334
     * @param int $size
335 14
     */
336
    public function setSize($size)
337 14
    {
338
        $this->size = $size;
339 14
    }
340
341
    /**
342
     * Return the actual file size in bytes.
343
     *
344
     * @throws Exception
345
     * @return integer
346
     */
347 1
    public function getSize()
348
    {
349 1
        if (null === $this->size) {
350
            if (!file_exists($this)) {
351
                throw new Exception(sprintf('target file \'%s\' doesn\'t exist', $this->getFilename()));
352
            }
353
            $this->size = filesize($this);
354
        }
355
        return $this->size;
356
    }
357 2
358
    /**
359 2
     * Target file exists already.
360
     *
361
     * @param  boolean $plain
362
     * @return boolean
363
     */
364
    public function fileExists($plain = false)
365
    {
366
        return file_exists($this->getPathname($plain));
367 7
    }
368
369 7
    /**
370
     * Return as backup file object.
371
     *
372
     * @return \phpbu\App\Backup\File
373
     */
374
    public function toFile()
375
    {
376
        return new File(new \SplFileInfo($this->getPathname()));
377 1
    }
378
379 1
    /**
380
     * Deletes the target file.
381
     *
382
     * @param  boolean $plain
383
     * @throws \phpbu\App\Exception
384
     */
385
    public function unlink($plain = false)
386
    {
387 9
        if (!$this->fileExists($plain)) {
388
            throw new Exception(sprintf('target file \'%s\' doesn\'t exist', $this->getFilename($plain)));
389 9
        }
390
        if (!is_writable($this->getPathname($plain))) {
391
            throw new Exception(sprintf('can\t delete file \'%s\'', $this->getFilename($plain)));
392
        }
393
        unlink($this->getPathname($plain));
394
    }
395
396
    /**
397 2
     * Return path and filename of the backup file.
398
     *
399 2
     * @param  bool $plain
400
     * @return string
401
     */
402
    public function getPathname($plain = false)
403
    {
404
        return $this->path . DIRECTORY_SEPARATOR . $this->getFilename($plain);
405
    }
406
407
    /**
408
     * Return path and plain filename of the backup file.
409
     *
410
     * @return string
411
     */
412
    public function getPathnamePlain()
413
    {
414
        return $this->getPathname(true);
415
    }
416
417
    /**
418
     * Is dirname configured with any date placeholders.
419
     *
420
     * @return boolean
421
     */
422
    public function hasChangingPath()
423
    {
424
        return $this->pathIsChanging;
425
    }
426
427
    /**
428 7
     * Return the part of the path that is not changing.
429
     *
430 7
     * @return string
431 7
     */
432 7
    public function getPathThatIsNotChanging()
433
    {
434
        return $this->pathNotChanging;
435
    }
436
437
    /**
438
     * Changing path elements getter.
439 2
     *
440
     * @return array
441 2
     */
442
    public function getChangingPathElements()
443
    {
444
        return $this->pathElementsChanging;
445
    }
446
447
    /**
448
     * Return amount of changing path elements.
449 20
     *
450
     * @return integer
451 20
     */
452
    public function countChangingPathElements()
453
    {
454
        return count($this->pathElementsChanging);
455
    }
456
457
    /**
458
     * Filename configured with any date placeholders.
459 1
     *
460
     * @return boolean
461 1
     */
462
    public function hasChangingFilename()
463
    {
464
        return $this->filenameIsChanging;
465
    }
466
467
    /**
468
     * Disable file compression.
469 2
     */
470
    public function disableCompression()
471 2
    {
472 2
        $this->compress = false;
473 2
    }
474
475
    /**
476
     * Enable file compression.
477
     *
478
     * @throws \phpbu\App\Exception
479
     */
480 1
    public function enableCompression()
481
    {
482 1
        if (null == $this->compressor) {
483
            throw new Exception('can\'t enable compression without a compressor');
484
        }
485
        $this->compress = true;
486
    }
487
488
    /**
489
     * Compressor setter.
490
     *
491
     * @param \phpbu\App\Backup\Compressor $compressor
492
     */
493
    public function setCompressor(Compressor $compressor)
494
    {
495
        $this->compressor = $compressor;
496
        $this->compress   = true;
497
    }
498 16
499
    /**
500 16
     * Compressor getter.
501
     *
502
     * @return \phpbu\App\Backup\Compressor
503
     */
504
    public function getCompressor()
505
    {
506
        return $this->compressor;
507
    }
508 2
509
    /**
510 2
     * Is a compressor set?
511
     *
512
     * @return boolean
513
     */
514
    public function shouldBeCompressed()
515
    {
516
        return $this->compress !== false;
517
    }
518
519
    /**
520
     * Crypter setter.
521
     *
522
     * @param \phpbu\App\Backup\Crypter $crypter
523
     */
524
    public function setCrypter(Crypter $crypter)
525
    {
526
        $this->crypter = $crypter;
527
        $this->crypt   = true;
528
    }
529
530
    /**
531
     * Crypter getter.
532
     *
533
     * @return \phpbu\App\Backup\Crypter
534
     */
535
    public function getCrypter()
536
    {
537
        return $this->crypter;
538
    }
539
540
    /**
541
     * Disable file encryption.
542
     */
543
    public function disableEncryption()
544
    {
545
        $this->crypt = false;
546
    }
547
548
    /**
549
     * Is a crypter set?
550
     *
551
     * @return boolean
552
     */
553
    public function shouldBeEncrypted()
554
    {
555
        return $this->crypt !== false;
556
    }
557
558
    /**
559
     * Magic to string method.
560
     *
561
     * @return string
562
     */
563
    public function __toString()
564
    {
565
        return $this->getPathname();
566
    }
567
}
568