Completed
Push — master ( 273c09...c70526 )
by Sebastian
02:52
created

Capacity   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 93.02%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 7
dl 0
loc 136
ccs 40
cts 43
cp 0.9302
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A setup() 0 16 4
A simulate() 0 15 2
B getFilesToDelete() 0 27 5
A getDeletableBackups() 0 11 2
A isCapacityExceeded() 0 4 1
1
<?php
2
namespace phpbu\App\Backup\Cleaner;
3
4
use phpbu\App\Backup\Collector;
5
use phpbu\App\Backup\Target;
6
use phpbu\App\Result;
7
use phpbu\App\Util\Str;
8
use RuntimeException;
9
10
/**
11
 * Cleanup backup directory.
12
 *
13
 * Removes oldest backup till the given capacity isn't exceeded anymore.
14
 *
15
 * @package    phpbu
16
 * @subpackage Backup
17
 * @author     Sebastian Feldmann <[email protected]>
18
 * @copyright  Sebastian Feldmann <[email protected]>
19
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
20
 * @link       http://phpbu.de/
21
 * @since      Class available since Release 1.0.0
22
 */
23
class Capacity extends Abstraction implements Simulator
24
{
25
    /**
26
     * Original XML value
27
     *
28
     * @var string
29
     */
30
    protected $capacityRaw;
31
32
    /**
33
     * Capacity in bytes.
34
     *
35
     * @var mixed <integer|double>
36
     */
37
    protected $capacityBytes;
38
39
    /**
40
     * Delete current backup as well
41
     *
42
     * @var bool
43
     */
44
    protected $deleteTarget;
45
46
    /**
47
     * Setup the the Cleaner.
48
     *
49
     * @see    \phpbu\App\Backup\Cleanup::setup()
50
     * @param  array $options
51
     * @throws \phpbu\App\Backup\Cleaner\Exception
52
     */
53 8
    public function setup(array $options)
54
    {
55 8
        if (!isset($options['size'])) {
56 1
            throw new Exception('option \'size\' is missing');
57
        }
58
        try {
59 7
            $bytes = Str::toBytes($options['size']);
60 1
        } catch (RuntimeException $e) {
61 1
            throw new Exception($e->getMessage());
62
        }
63 6
        $this->deleteTarget  = isset($options['deleteTarget'])
64 1
                             ? Str::toBoolean($options['deleteTarget'], false)
65 5
                             : false;
66 6
        $this->capacityRaw   = $options['size'];
67 6
        $this->capacityBytes = $bytes;
68 6
    }
69
70
    /**
71
     * Simulate the cleanup execution.
72
     *
73
     * @param \phpbu\App\Backup\Target    $target
74
     * @param \phpbu\App\Backup\Collector $collector
75
     * @param \phpbu\App\Result           $result
76
     */
77 1
    public function simulate(Target $target, Collector $collector, Result $result)
78
    {
79 1
        $target->setSize('20000000');
80 1
        $result->debug('assuming backup size 20MB');
81
82
        // because there is no target file on disc to read
83
        // we have to deactivate the target handling
84
        // so $targetFile->getMTime or $targetFile->getSize will not be called
85 1
        if ($this->deleteTarget) {
86
            $this->deleteTarget = false;
87
            $result->debug('target will be deleted as well');
88
            $result->debug('delete ' . $target->getPathname());
89
        }
90 1
        parent::simulate($target, $collector, $result);
91 1
    }
92
93
    /**
94
     * Return list of files to delete.
95
     *
96
     * @param  \phpbu\App\Backup\Target    $target
97
     * @param  \phpbu\App\Backup\Collector $collector
98
     * @return \phpbu\App\Backup\File[]
99
     * @throws \phpbu\App\Exception
100
     */
101 5
    protected function getFilesToDelete(Target $target, Collector $collector)
102
    {
103 5
        $files  = $this->getDeletableBackups($target, $collector);
104 5
        $size   = $target->getSize();
105 5
        $delete = [];
106
107
        // sum up the size of all backups
108
        /** @var \phpbu\App\Backup\File $file */
109 5
        foreach ($files as $file) {
110 5
            $size += $file->getSize();
111
        }
112
113
        // check if backups exceed capacity?
114 5
        if ($this->isCapacityExceeded($size)) {
115
            // sort backups by date, oldest first, key 'YYYYMMDDHHIISS-NR-PATH'
116 4
            ksort($files);
117
118 4
            while ($this->isCapacityExceeded($size) && count($files) > 0) {
119
                // get oldest backup from list, move it to delete list
120 4
                $file     = array_shift($files);
121 4
                $size    -= $file->getSize();
122 4
                $delete[] = $file;
123
            }
124
        }
125
126 5
        return $delete;
127
    }
128
129
    /**
130
     * Return a list of all deletable backups, including the currently created one if configured.
131
     *
132
     * @param  \phpbu\App\Backup\Target    $target
133
     * @param  \phpbu\App\Backup\Collector $collector
134
     * @return \phpbu\App\Backup\File[]
135
     */
136 5
    protected function getDeletableBackups(Target $target, Collector $collector) : array
137
    {
138 5
        $files = $collector->getBackupFiles();
139
        // should the currently created backup be deleted as well?
140 5
        if ($this->deleteTarget) {
141 1
            $file          = $target->toFile();
142 1
            $index         = date('YmdHis', $file->getMTime()) . '-' . count($files) . '-' . $file->getPathname();
143 1
            $files[$index] = $file;
144
        }
145 5
        return $files;
146
    }
147
148
    /**
149
     * Is a given size bigger than the configured capacity limit.
150
     *
151
     * @param  int|double $currentCapacity
152
     * @return bool
153
     */
154 5
    protected function isCapacityExceeded($currentCapacity) : bool
155
    {
156 5
        return $currentCapacity > $this->capacityBytes;
157
    }
158
}
159