public function apply_srp_quotas($parent) { $parent->relayStep('Applying quotas'); $parent->relaySubstep(''); // If no quota settings are enabled, quit $registry =& AEFactory::getConfiguration(); $srpQuotas = $registry->get('akeeba.quota.srp_size_quota'); if($srpQuotas <= 0) { AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "No restore point quotas were defined; old restore point files will be kept intact" ); return true; // No quota limits were requested } // Get valid-looking backup ID's $validIDs =& AEPlatform::get_valid_backup_records(true, array('restorepoint')); $statistics =& AEFactory::getStatistics(); $latestBackupId = $statistics->getId(); // Create a list of valid files $allFiles = array(); if(count($validIDs)) { foreach($validIDs as $id) { $stat = AEPlatform::get_statistics($id); // Multipart processing $filenames = AEUtilStatistics::get_all_filenames($stat, true); if(!is_null($filenames)) { // Only process existing files $filesize = 0; foreach($filenames as $filename) { $filesize += @filesize($filename); } $allFiles[] = array('id' => $id, 'filenames' => $filenames, 'size' => $filesize); } } } unset($validIDs); // If there are no files, exit early if(count($allFiles) == 0) { AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "There were no old restore points to apply quotas on" ); return true; } // Init arrays $killids = array(); $ret = array(); $leftover = array(); // Do we need to apply size quotas? AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Processing restore point size quotas" ); // OK, let's start counting bytes! $runningSize = 0; while(count($allFiles) > 0) { // Each time, remove the last element of the backup array and calculate // running size. If it's over the limit, add the archive to the return array. $def = array_pop($allFiles); $runningSize += $def['size']; if($runningSize >= $srpQuotas) { if($latestBackupId == $def['id']) { $runningSize -= $def['size']; } else { $ret[] = $def['filenames']; $killids[] = $def['filenames']; } } } // Convert the $ret 2-dimensional array to single dimensional $quotaFiles = array(); foreach($ret as $temp) { foreach($temp as $filename) { $quotaFiles[] = $filename; } } // Update the statistics record with the removed remote files if(!empty($killids)) foreach($killids as $id) { $data = array('filesexist' => '0'); AEPlatform::set_or_update_statistics($id, $data, $parent); } // Apply quotas if(count($quotaFiles) > 0) { AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Applying quotas" ); jimport('joomla.filesystem.file'); foreach($quotaFiles as $file) { if(!@AEPlatform::unlink($file)) { $parent->setWarning("Failed to remove old system restore point file ".$file ); } } } return true; }
/** * Applies the size and count quotas * @return bool */ private function apply_quotas() { $this->setStep('Applying quotas'); $this->setSubstep(''); // If no quota settings are enabled, quit $registry =& AEFactory::getConfiguration(); $useDayQuotas = $registry->get('akeeba.quota.maxage.enable'); $useCountQuotas = $registry->get('akeeba.quota.enable_count_quota'); $useSizeQuotas = $registry->get('akeeba.quota.enable_size_quota'); if(! ($useDayQuotas || $useCountQuotas || $useSizeQuotas) ) { $this->apply_obsolete_quotas(); AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "No quotas were defined; old backup files will be kept intact" ); return true; // No quota limits were requested } // Try to find the files to be deleted due to quota settings $statistics =& AEFactory::getStatistics(); $latestBackupId = $statistics->getId(); // Get quota values $countQuota = $registry->get('akeeba.quota.count_quota'); $sizeQuota = $registry->get('akeeba.quota.size_quota'); $daysQuota = $registry->get('akeeba.quota.maxage.maxdays'); $preserveDay = $registry->get('akeeba.quota.maxage.keepday'); // Get valid-looking backup ID's $validIDs =& AEPlatform::get_valid_backup_records(true, array('NOT','restorepoint')); // Create a list of valid files $allFiles = array(); if(count($validIDs)) { foreach($validIDs as $id) { $stat = AEPlatform::get_statistics($id); try { $backupstart = new DateTime($stat['backupstart']); $backupTS = $backupstart->format('U'); $backupDay = $backupstart->format('d'); } catch (Exception $e) { $backupTS = 0; $backupDay = 0; } // Multipart processing $filenames = AEUtilStatistics::get_all_filenames($stat, true); if(!is_null($filenames)) { // Only process existing files $filesize = 0; foreach($filenames as $filename) { $filesize += @filesize($filename); } $allFiles[] = array('id' => $id, 'filenames' => $filenames, 'size' => $filesize, 'backupstart' => $backupTS, 'day' => $backupDay); } } } unset($validIDs); // If there are no files, exit early if(count($allFiles) == 0) { AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "There were no old backup files to apply quotas on" ); return true; } // Init arrays $killids = array(); $ret = array(); $leftover = array(); // Do we need to apply maximum backup age quotas? if($useDayQuotas) { $killDatetime = new DateTime(); $killDatetime->sub(new DateInterval('P'.$daysQuota.'D')); $killTS = $killDatetime->format('U'); foreach($allFiles as $file) { // Is this on a preserve day? if($preserveDay > 0) { if($preserveDay == $file['day']) { $leftover[] = $file; continue; } } // Otherwise, check the timestamp if($file['backupstart'] < $killTS) { $ret[] = $file['filenames']; $killids[] = $file['id']; } else { $leftover[] = $file; } } } // Do we need to apply count quotas? if($useCountQuotas && is_numeric($countQuota) && !($countQuota <= 0) && !$useDayQuotas ) { // Are there more files than the quota limit? if( !(count($allFiles) > $countQuota) ) { // No, effectively skip the quota checking $leftover =& $allFiles; } else { AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Processing count quotas" ); // Yes, aply the quota setting. Add to $ret all entries minus the last // $countQuota ones. $totalRecords = count($allFiles); $checkLimit = $totalRecords - $countQuota; // Only process if at least one file (current backup!) is to be left for($count = 0; $count < $totalRecords; $count++) { $def = array_pop($allFiles); if(count($ret) < $checkLimit) { if($latestBackupId != $def['id']) { $ret[] = $def['filenames']; $killids[] = $def['id']; } } else { $leftover[] = $def; } } unset($allFiles); } } else { // No count quotas are applied $leftover =& $allFiles; } // Do we need to apply size quotas? if( $useSizeQuotas && is_numeric($sizeQuota) && !($sizeQuota <= 0) && (count($leftover) > 0) && !$useDayQuotas ) { AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Processing size quotas" ); // OK, let's start counting bytes! $runningSize = 0; while(count($leftover) > 0) { // Each time, remove the last element of the backup array and calculate // running size. If it's over the limit, add the archive to the return array. $def = array_pop($leftover); $runningSize += $def['size']; if($runningSize >= $sizeQuota) { if($latestBackupId == $def['id']) { $runningSize -= $def['size']; } else { $ret[] = $def['filenames']; $killids[] = $def['filenames']; } } } } // Convert the $ret 2-dimensional array to single dimensional $quotaFiles = array(); foreach($ret as $temp) { foreach($temp as $filename) { $quotaFiles[] = $filename; } } // Update the statistics record with the removed remote files if(!empty($killids)) foreach($killids as $id) { $data = array('filesexist' => '0'); AEPlatform::set_or_update_statistics($id, $data, $this); } // Apply quotas if(count($quotaFiles) > 0) { AEUtilLogger::WriteLog(_AE_LOG_DEBUG, "Applying quotas" ); jimport('joomla.filesystem.file'); foreach($quotaFiles as $file) { if(!@AEPlatform::unlink($file)) { $this->setWarning("Failed to remove old backup file ".$file ); } } } $this->apply_obsolete_quotas(); return true; }