Issues (83)

src/Backup/Cleaner/Stepwise.php (3 issues)

1
<?php
2
namespace phpbu\App\Backup\Cleaner;
3
4
use phpbu\App\Backup\Cleaner\Stepwise\Range;
5
use phpbu\App\Backup\Collector;
6
use phpbu\App\Backup\File;
7
use phpbu\App\Backup\Target;
8
use phpbu\App\Util\Arr;
9
10
/**
11
 * Cleanup backup directory.
12
 * Keep less and less backups over time
13
 *
14
 *         | for x days  | for x days        | for x weeks           | for x month                 | for x years
15
 *         | keep all    | keep one per day  | keep one per week     | keep one per month          | keep one per year
16
 * --------+-------------+-------------------+-----------------------+-----------------------------+------------------
17
 * backups | ............| . . . . . . . . . | .       .       .     | .                         . |
18
 *
19
 * @package    phpbu
20
 * @subpackage Backup
21
 * @author     Sebastian Feldmann <[email protected]>
22
 * @copyright  Sebastian Feldmann <[email protected]>
23
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
24
 * @link       http://phpbu.de/
25
 * @since      Class available since Release 5.0.0
26
 */
27
class Stepwise extends Abstraction implements Simulator
28
{
29
    /**
30
     * Current timestamp
31
     *
32
     * @var int
33
     */
34
    protected $timestamp;
35
36
    /**
37
     * Amount of days to keep all backups
38
     *
39
     * @var int
40
     */
41
    protected $daysToKeepAll;
42
43
    /**
44
     * Amount of days to keep at least one backup per day
45
     *
46
     * @var int
47
     */
48
    protected $daysToKeepDaily;
49
50
    /**
51
     * Amount of weeks to keep at least one backup per week
52
     *
53
     * @var int
54
     */
55
    protected $weeksToKeepWeekly;
56
57
    /**
58
     * Amount of month to keep at least one backup per month
59
     *
60
     * @var int
61
     */
62
    protected $monthToKeepMonthly;
63
64
    /**
65
     * Amount of years to keep at least one backup per year
66
     *
67
     * @var int
68
     */
69
    protected $yearsToKeepYearly;
70
71
    /**
72
     * List of ranges defined by the configured settings
73
     *
74
     * @var \phpbu\App\Backup\Cleaner\Stepwise\Range[]
75
     */
76
    protected $ranges;
77
78
    /**
79
     * Stepwise constructor.
80
     *
81
     * @param int $time
82
     */
83 3
    public function __construct(int $time = 0)
84
    {
85 3
        $this->timestamp = $time === 0 ? time() : $time;
86 3
    }
87
88
    /**
89
     * Setup the Cleaner
90
     *
91
     * @see    \phpbu\App\Backup\Cleanup::setup()
92
     * @param  array $options
93
     */
94 3
    public function setup(array $options)
95
    {
96 3
        $this->daysToKeepAll      = Arr::getValue($options, 'daysToKeepAll', 0);
97 3
        $this->daysToKeepDaily    = Arr::getValue($options, 'daysToKeepDaily', 0);
98 3
        $this->weeksToKeepWeekly  = Arr::getValue($options, 'weeksToKeepWeekly', 0);
99 3
        $this->monthToKeepMonthly = Arr::getValue($options, 'monthToKeepMonthly', 0);
100 3
        $this->yearsToKeepYearly  = Arr::getValue($options, 'yearsToKeepYearly', 0);
101
102 3
        $this->setupRanges();
103 3
    }
104
105
    /**
106
     * Setup the date ranges
107
     */
108 3
    protected function setupRanges()
109
    {
110
        // keep all backups for x days as specified by 'keep all'
111 3
        $start = $this->timestamp;
112 3
        $end   = mktime(0, 0, 0, date('m', $start), (int) date('d', $start) - $this->daysToKeepAll, date('Y', $start));
0 ignored issues
show
date('Y', $start) of type string is incompatible with the type integer expected by parameter $year of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

112
        $end   = mktime(0, 0, 0, date('m', $start), (int) date('d', $start) - $this->daysToKeepAll, /** @scrutinizer ignore-type */ date('Y', $start));
Loading history...
date('m', $start) of type string is incompatible with the type integer expected by parameter $month of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

112
        $end   = mktime(0, 0, 0, /** @scrutinizer ignore-type */ date('m', $start), (int) date('d', $start) - $this->daysToKeepAll, date('Y', $start));
Loading history...
113 3
        $all   = new Range($start, $end, new Stepwise\Keeper\All());
114
115
        // define the range that keeps backups per day
116 3
        $end   = mktime(0, 0, 0, date('m', $end), (int) date('d', $end) - $this->daysToKeepDaily, date('Y', $end));
117 3
        $daily = new Range($all->getEnd(), $end, new Stepwise\Keeper\OnePerGroup('Ymd'));
118
119
        // define the range that keeps backups per week
120 3
        $month  = date('m', $end);
121 3
        $day    = (int) date('d', $end) - (7 * $this->weeksToKeepWeekly);
122
        $year   = date('Y', $end);
123
        $end    = mktime(0, 0, 0, $month, $day, $year);
124 3
        $weekly = new Range($daily->getEnd(), $end, new Stepwise\Keeper\OnePerGroup('YW'));
125 3
126
        // define the range that keeps backups per month
127
        $end     = mktime(0, 0, 0, (int) date('m', $end) - $this->monthToKeepMonthly, date('d', $end), date('Y', $end));
0 ignored issues
show
date('d', $end) of type string is incompatible with the type integer expected by parameter $day of mktime(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

127
        $end     = mktime(0, 0, 0, (int) date('m', $end) - $this->monthToKeepMonthly, /** @scrutinizer ignore-type */ date('d', $end), date('Y', $end));
Loading history...
128 3
        $monthly = new Range($weekly->getEnd(), $end, new Stepwise\Keeper\OnePerGroup('Ym'));
129 3
130
        // define the range that keeps backups per year
131
        $end    = mktime(0, 0, 0, date('m', $end), date('d', $end), (int) date('Y', $end) - $this->yearsToKeepYearly);
132 3
        $yearly = new Range($monthly->getEnd(), $end, new Stepwise\Keeper\OnePerGroup('Y'));
133
134 3
        // delete all backups older then configured year range
135 3
        $delete = new Range($end, 0, new Stepwise\Keeper\None());
136
137
        $this->ranges = [$all, $daily, $weekly, $monthly, $yearly, $delete];
138
    }
139
140
    /**
141
     * Return list of files to delete
142
     *
143
     * @param  \phpbu\App\Backup\Target    $target
144
     * @param  \phpbu\App\Backup\Collector $collector
145 3
     * @return \phpbu\App\Backup\File[]
146
     * @throws \phpbu\App\Exception
147 3
     */
148 3
    protected function getFilesToDelete(Target $target, Collector $collector)
149
    {
150
        $files  = $collector->getBackupFiles();
151 3
        $delete = [];
152
153 3
        // for each backup ...
154
        foreach ($files as $file) {
155 2
            // ... find the right date range ...
156 2
            $range = $this->getRangeForFile($file);
157
            // ... and check if this backup should be kept or deleted
158
            if (!$range->keep($file)) {
159 2
                $delete[] = $file;
160
            }
161
        }
162
        return $delete;
163
    }
164
165
    /**
166
     * Get matching range for given file
167
     *
168
     * @param  \phpbu\App\Backup\File $file
169 3
     * @return \phpbu\App\Backup\Cleaner\Stepwise\Range
170
     * @throws \phpbu\App\Backup\Cleaner\Exception
171 3
     */
172 3
    protected function getRangeForFile(File $file) : Range
173 3
    {
174
        foreach ($this->ranges as $range) {
175
            if ($file->getMTime() > $range->getEnd()) {
176 1
                return $range;
177
            }
178
        }
179
        throw new Exception('no range for file');
180
    }
181
}
182