Completed
Push — master ( c8064a...3eed6d )
by Sebastian
06:02
created

Capacity::getFilesToDelete()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 27
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 14
cts 14
cp 1
rs 8.439
c 0
b 0
f 0
cc 5
eloc 13
nc 4
nop 2
crap 5
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
    public function setup(array $options)
54 7
    {
55
        if (!isset($options['size'])) {
56 7
            throw new Exception('option \'size\' is missing');
57 1
        }
58
        try {
59
            $bytes = Str::toBytes($options['size']);
60 6
        } catch (RuntimeException $e) {
61 6
            throw new Exception($e->getMessage());
62 1
        }
63
        $this->deleteTarget  = isset($options['deleteTarget'])
64 5
                             ? Str::toBoolean($options['deleteTarget'], false)
65 5
                             : false;
66 5
        $this->capacityRaw   = $options['size'];
67 5
        $this->capacityBytes = $bytes;
68 5
    }
69 5
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
    public function simulate(Target $target, Collector $collector, Result $result)
78
    {
79
        $target->setSize('20000000');
80 4
        $result->debug('assuming backup size 20MB');
81
        parent::simulate($target, $collector, $result);
82 4
    }
83 4
84
    /**
85
     * Return list of files to delete.
86 4
     *
87 4
     * @param  \phpbu\App\Backup\Target    $target
88 4
     * @param  \phpbu\App\Backup\Collector $collector
89
     * @return \phpbu\App\Backup\File[]
90
     * @throws \phpbu\App\Exception
91 4
     */
92
    protected function getFilesToDelete(Target $target, Collector $collector)
93 3
    {
94
        $files  = $this->getDeletableBackups($target, $collector);
95 3
        $size   = $target->getSize();
96 3
        $delete = [];
97 3
98 3
        // sum up the size of all backups
99 1
        /** @var \phpbu\App\Backup\File $file */
100
        foreach ($files as $file) {
101 2
            $size += $file->getSize();
102 2
        }
103 2
104
        // check if backups exceed capacity?
105
        if ($this->isCapacityExceeded($size)) {
106
            // sort backups by date, oldest first, key 'YYYYMMDDHHIISS-NR-PATH'
107 2
            ksort($files);
108 1
109 1
            while ($this->isCapacityExceeded($size) && count($files) > 0) {
110 2
                // get oldest backup from list, move it to delete list
111 3
                $file     = array_shift($files);
112
                $size    -= $file->getSize();
113
                $delete[] = $file;
114
            }
115
        }
116
117
        return $delete;
118
    }
119
120
    /**
121
     * Return a list of all deletable backups, including the currently created one if configured.
122
     *
123
     * @param  \phpbu\App\Backup\Target    $target
124
     * @param  \phpbu\App\Backup\Collector $collector
125
     * @return \phpbu\App\Backup\File[]
126
     */
127
    protected function getDeletableBackups(Target $target, Collector $collector) : array
128
    {
129
        $files = $collector->getBackupFiles();
130
        // should the currently created backup be deleted as well?
131
        if ($this->deleteTarget) {
132
            $file          = $target->toFile();
133
            $index         = date('YmdHis', $file->getMTime()) . '-' . count($files) . '-' . $file->getPathname();
134
            $files[$index] = $file;
135
        }
136
        return $files;
137
    }
138
139
    /**
140
     * Is a given size bigger than the configured capacity limit.
141
     *
142
     * @param  int|double $currentCapacity
143
     * @return bool
144
     */
145
    protected function isCapacityExceeded($currentCapacity) : bool
146
    {
147
        return $currentCapacity > $this->capacityBytes;
148
    }
149
}
150