Source of file DBBackup.php
Size: 5,779 Bytes - Last Modified: 2021-12-23T10:02:23+00:00
/var/www/docs.ssmods.com/process/src/src/Storage/DBBackup.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 | <?php namespace LittleGiant\SpinDB\Storage; use DateInterval; use DateTime; use Exception; use InvalidArgumentException; use LittleGiant\SpinDB\Configuration\RotateConfig; /** * Matches a DB backup */ class DBBackup { /** * Date this backup was created (ISO_8601) * * @var string */ protected $date; /** * Time this backup was created (optional) * * @var string|null */ protected $time; public function __construct($parts = []) { if (empty($parts['date'])) { throw new InvalidArgumentException("Missing date"); } $this->date = $parts['date']; // Save optional time if (isset($parts['time'])) { $this->time = $parts['time']; } } /** * @return string|null */ public function getTime() { return $this->time; } /** * @return string */ public function getDate() { return $this->date; } /** * Get combined date / time * * @return string */ public function getDateTime() { $date = $this->getDate(); $time = $this->getTime(); if ($time) { return "{$date} {$time}"; } return $date; } /** * Build AWS key this backup corresponds to * * @return string * @throws Exception */ public function getKey(): string { $parts = [ 'date' => $this->getDate(), 'time' => $this->getTime(), ]; return RotateConfig::path($parts); } /** * Determine if this backup matches the given date * * @param string $date * @return bool */ public function matches($date): bool { return strtotime($this->date) === strtotime($date); } /** * Check if this file should be purged * * @param string $today Date to use for today * @return bool * @throws Exception */ public function requirePurging(string $today): bool { // Always keep current date if ($this->matches($today)) { return false; } if ($this->isDaily($today)) { return false; } if ($this->isWeekly($today)) { return false; } if ($this->isMonthly($today)) { return false; } if ($this->isYearly($today)) { return false; } return true; } /** * Check if this item matches one of the daily rules * * @param string $today * @return bool * @throws Exception */ protected function isDaily(string $today): bool { // Check if we keep any daily records $keepDaily = RotateConfig::keepDaily(); if (!$keepDaily) { return false; } return $this->isNewerThan($today, $keepDaily, 'D'); } /** * Check if this item matches one of the weekly rules * * @param string $today * @return bool * @throws Exception */ protected function isWeekly(string $today): bool { // Check if we keep any weekly records $keepWeekly = RotateConfig::keepWeekly(); if (!$keepWeekly) { return false; } // Check if we are past the weekly limit if (!$this->isNewerThan($today, $keepWeekly, 'W')) { return false; } // Check if day of week matches (%7 for safety) return (int)date('w', strtotime($this->getDate())) === (RotateConfig::keepWeeklyDay() % 7); } /** * Check if this item matches one of the monthly rules * * @param string $today * @return bool * @throws Exception */ protected function isMonthly(string $today): bool { // Check if we keep any weekly records $keepMonthly = RotateConfig::keepMonthly(); if (!$keepMonthly) { return false; } // Check if we are past the monthly limit if (!$this->isNewerThan($today, $keepMonthly, 'M')) { return false; } // Check if day of month matches return (int)date('j', strtotime($this->getDate())) === (int)RotateConfig::keepMonthlyDay(); } /** * Check if this item matches one of the yearly rules * * @param string $today * @return bool * @throws Exception */ protected function isYearly(string $today): bool { // Check if we keep any weekly records $keepYearly = RotateConfig::keepYearly(); if (!$keepYearly) { return false; } // Check if we are past the monthly limit if (!$this->isNewerThan($today, $keepYearly, 'Y')) { return false; } // Check if day of year matches (note: z is 0 based, day of year is 1 based) return (int)date('z', strtotime($this->getDate())) === (int)RotateConfig::keepYearlyDay(); } /** * @param string $date Date to use for today * @param string $age Number of units (e.g. days) * @param string $units Units to check. E.g. 'D' for days, 'W' for weeks * @return bool True if the date is newer than (but not equal to) than the given age * @throws Exception */ protected function isNewerThan($date, $age, $units): bool { // Negative ranges (e.g. -1 weekly backups) means there is no max age if ($age < 0) { return true; } // Check if we are within the daily backup limit $minDate = new DateTime($date); $minDate->sub(new DateInterval("P{$age}{$units}")); $self = new DateTime($this->getDate()); return $self > $minDate; } } |