<?php
/**
* Backup files for maintenance tasks with fallback logic.
*
* @param string $sourceDir The directory to backup.
* @param string $backupDir The directory to store the backup.
* @param int $numBackups The number of backups to keep.
* @return bool True on success, false on failure.
*/
function backupFiles(string $sourceDir, string $backupDir, int $numBackups): bool
{
// Ensure source directory exists
if (!is_dir($sourceDir)) {
error_log("Source directory '$sourceDir' does not exist.");
return false;
}
// Ensure backup directory exists, create if not
if (!is_dir($backupDir)) {
if (!mkdir($backupDir, 0777, true)) {
error_log("Failed to create backup directory '$backupDir'.");
return false;
}
}
$timestamp = date('Y-m-d_H-i-s');
$backupFilename = $backupDir . '/' . $timestamp;
// Copy files to backup directory
if (!copyDir($sourceDir, $backupFilename, true)) { // recursive copy
error_log("Failed to copy files from '$sourceDir' to '$backupFilename'.");
return false;
}
// Cleanup old backups
cleanupOldBackups($backupDir, $numBackups);
return true;
}
/**
* Copies directory recursively.
*
* @param string $source The source directory.
* @param string $destination The destination directory.
* @param bool $recursive Whether to copy recursively.
* @return bool True on success, false on failure.
*/
function copyDir(string $source, string $destination, bool $recursive = true): bool {
if (is_dir($source)) {
if (!copyDirRecursive($source, $destination)) {
return false;
}
} else {
copyFile($source, $destination);
}
return true;
}
/**
* Copies directory recursively.
*
* @param string $source The source directory.
* @param string $destination The destination directory.
* @return bool True on success, false on failure.
*/
function copyDirRecursive(string $source, string $destination): bool {
$items = scandir($source);
if ($items === false) {
error_log("Failed to read directory '$source'.");
return false;
}
foreach ($items as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$sourcePath = $source . '/' . $item;
$destinationPath = $destination . '/' . $item;
if (is_dir($sourcePath)) {
if (!copyDirRecursive($sourcePath, $destinationPath)) {
return false;
}
} else {
copyFile($sourcePath, $destinationPath);
}
}
return true;
}
/**
* Copies a file.
*
* @param string $source The source file.
* @param string $destination The destination file.
* @return bool True on success, false on failure.
*/
function copyFile(string $source, string $destination): bool
{
if (!file_exists($source)) {
error_log("Source file '$source' does not exist.");
return false;
}
if (copy($source, $destination)) {
return true;
} else {
error_log("Failed to copy file from '$source' to '$destination'.");
return false;
}
}
/**
* Cleans up old backups.
*
* @param string $backupDir The backup directory.
* @param int $numBackups The number of backups to keep.
* @return bool True on success, false on failure.
*/
function cleanupOldBackups(string $backupDir, int $numBackups): bool
{
$files = glob($backupDir . '/*');
if ($files === false) {
error_log("Failed to list files in '$backupDir'.");
return false;
}
$files = array_reverse($files);
if (count($files) > $numBackups) {
Add your comment