Completed
Push — master ( f62f21...f72c97 )
by Freek
05:09
created

DefaultStrategy::deleteOldBackups()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 24
rs 8.9713
cc 1
eloc 13
nc 1
nop 1
1
<?php
2
3
namespace Spatie\Backup\Tasks\Cleanup\Strategies;
4
5
use Carbon\Carbon;
6
use Illuminate\Support\Collection;
7
use Spatie\Backup\BackupDestination\Backup;
8
use Spatie\Backup\BackupDestination\BackupCollection;
9
use Spatie\Backup\Tasks\Cleanup\CleanupStrategy;
10
use Spatie\Backup\Tasks\Cleanup\Period;
11
12
class DefaultStrategy extends CleanupStrategy
13
{
14
    /** @var \Spatie\Backup\BackupDestination\Backup */
15
    protected $newestBackup;
16
17
    /**
18
     * @param \Spatie\Backup\BackupDestination\BackupCollection $backups
19
     */
20
    public function deleteOldBackups(BackupCollection $backups)
21
    {
22
        // Don't ever delete the newest backup.
23
        $this->newestBackup = $backups->shift();
24
25
        $dateRanges = $this->calculateDateRanges();
26
27
        $backupsPerPeriod = $dateRanges->map(function (Period $period) use ($backups) {
28
            return $backups->filter(function (Backup $backup) use ($period) {
29
               return $backup->date()->between($period->getStartDate(), $period->getEndDate());
30
            });
31
        });
32
33
        $backupsPerPeriod['daily'] = $this->groupByDateFormat($backupsPerPeriod['daily'], 'Ymd');
34
        $backupsPerPeriod['weekly'] = $this->groupByDateFormat($backupsPerPeriod['weekly'], 'YW');
35
        $backupsPerPeriod['monthly'] = $this->groupByDateFormat($backupsPerPeriod['monthly'], 'Ym');
36
        $backupsPerPeriod['yearly'] = $this->groupByDateFormat($backupsPerPeriod['yearly'], 'Y');
37
38
        $this->removeBackupsForAllPeriodsExceptOne($backupsPerPeriod);
39
40
        $this->removeBackupsOlderThan($dateRanges['yearly']->getEndDate(), $backups);
41
42
        $this->removeOldestsBackupsUntilUsingMaximumStorage($backups);
43
    }
44
45
    /**
46
     * @return \Illuminate\Support\Collection
47
     */
48
    protected function calculateDateRanges()
49
    {
50
        $config = $this->config->get('laravel-backup.cleanup.defaultStrategy');
51
52
        $daily = new Period(
53
            Carbon::now()->subDays($config['keepAllBackupsForDays']),
54
            Carbon::now()
55
                ->subDays($config['keepAllBackupsForDays'])
56
                ->subDays($config['keepDailyBackupsForDays'])
57
        );
58
59
        $weekly = new Period(
60
            $daily->getEndDate(),
61
            $daily->getEndDate()
62
                ->subWeeks($config['keepWeeklyBackupsForWeeks'])
63
        );
64
65
        $monthly = new Period(
66
            $weekly->getEndDate(),
67
            $weekly->getEndDate()
68
                ->subMonths($config['keepMonthlyBackupsForMonths'])
69
        );
70
71
        $yearly = new Period(
72
            $monthly->getEndDate(),
73
            $monthly->getEndDate()
74
                ->subYears($config['keepYearlyBackupsForYears'])
75
        );
76
77
        return collect(compact('daily', 'weekly', 'monthly', 'yearly'));
78
    }
79
80
    /**
81
     * @param \Illuminate\Support\Collection $backups
82
     * @param string                         $dateFormat
83
     *
84
     * @return \Illuminate\Support\Collection
85
     */
86
    protected function groupByDateFormat(Collection $backups, $dateFormat)
87
    {
88
        return $backups->groupBy(function (Backup $backup) use ($dateFormat) {
89
            return $backup->date()->format($dateFormat);
90
        });
91
    }
92
93
    /**
94
     * @param \Illuminate\Support\Collection $backupsPerPeriod
95
     */
96
    protected function removeBackupsForAllPeriodsExceptOne($backupsPerPeriod)
97
    {
98
        foreach ($backupsPerPeriod as $periodName => $groupedBackupsByDateProperty) {
99
            $groupedBackupsByDateProperty->each(function (Collection $group) {
100
                $group->shift();
101
102
                $group->each(function (Backup $backup) {
103
                    $backup->delete();
104
                });
105
            });
106
        }
107
    }
108
109
    /**
110
     * @param \Carbon\Carbon                                    $endDate
111
     * @param \Spatie\Backup\BackupDestination\BackupCollection $backups
112
     */
113
    protected function removeBackupsOlderThan(Carbon $endDate, BackupCollection $backups)
114
    {
115
        $backups->filter(function (Backup $backup) use ($endDate) {
116
            return $backup->exists() && $backup->date()->lt($endDate);
117
        })->each(function (Backup $backup) {
118
           $backup->delete();
119
        });
120
    }
121
122
    /**
123
     * @param \Spatie\Backup\BackupDestination\BackupCollection $backups
124
     */
125
    protected function removeOldestsBackupsUntilUsingMaximumStorage(BackupCollection $backups)
126
    {
127
        $maximumSize = $this->config->get('laravel-backup.cleanup.defaultStrategy.deleteOldestBackupsWhenUsingMoreMegabytesThan')
128
         * 1024 * 1024;
129
130
        if (!$oldestBackup = $backups->oldest()) {
131
            return;
132
        }
133
134
        if (($backups->size() + $this->newestBackup->size()) <= $maximumSize) {
135
            return;
136
        }
137
138
        $oldestBackup->delete();
139
140
        $this->removeOldestsBackupsUntilUsingMaximumStorage($backups);
141
    }
142
}
143