- Created FileCleanup utility class to manage old upload files - Automatically removes files older than 24 hours on each request - Added cleanup calls to both estimate.php and uploader.php processes - Includes detailed logging and statistics for cleanup operations - Provides formatBytes utility for human-readable file size reporting - Includes directory statistics functionality for monitoring This prevents the uploads directory from growing indefinitely and ensures proper disk space management for the video processing system. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
180 lines
No EOL
6.4 KiB
PHP
180 lines
No EOL
6.4 KiB
PHP
<?php
|
|
require_once 'logger.php';
|
|
|
|
class FileCleanup {
|
|
|
|
/**
|
|
* Clean up files older than specified hours in the uploads directory
|
|
*
|
|
* @param int $hoursOld Files older than this many hours will be deleted
|
|
* @param string $uploadsDir Path to uploads directory
|
|
* @return array Statistics about the cleanup operation
|
|
*/
|
|
public static function cleanupOldFiles($hoursOld = 24, $uploadsDir = 'uploads/') {
|
|
$stats = [
|
|
'files_deleted' => 0,
|
|
'files_failed' => 0,
|
|
'bytes_freed' => 0,
|
|
'errors' => []
|
|
];
|
|
|
|
try {
|
|
// Ensure uploads directory exists
|
|
if (!is_dir($uploadsDir)) {
|
|
Logger::log("Uploads directory does not exist: $uploadsDir", 'WARN');
|
|
return $stats;
|
|
}
|
|
|
|
// Calculate cutoff time (24 hours ago by default)
|
|
$cutoffTime = time() - ($hoursOld * 3600);
|
|
Logger::log("Starting cleanup of files older than $hoursOld hours (before " . date('Y-m-d H:i:s', $cutoffTime) . ")");
|
|
|
|
// Get all files in uploads directory
|
|
$files = glob($uploadsDir . '*');
|
|
if ($files === false) {
|
|
Logger::log("Failed to read uploads directory: $uploadsDir", 'ERROR');
|
|
return $stats;
|
|
}
|
|
|
|
$totalFiles = 0;
|
|
$oldFiles = 0;
|
|
|
|
foreach ($files as $file) {
|
|
// Skip directories and special files
|
|
if (is_dir($file) || basename($file) === '.gitkeep' || basename($file) === '.htaccess') {
|
|
continue;
|
|
}
|
|
|
|
$totalFiles++;
|
|
$fileModTime = filemtime($file);
|
|
|
|
if ($fileModTime === false) {
|
|
Logger::log("Could not get modification time for file: $file", 'WARN');
|
|
$stats['errors'][] = "Could not get modification time for: " . basename($file);
|
|
continue;
|
|
}
|
|
|
|
// If file is older than cutoff time, delete it
|
|
if ($fileModTime < $cutoffTime) {
|
|
$oldFiles++;
|
|
$fileSize = filesize($file);
|
|
|
|
if (unlink($file)) {
|
|
$stats['files_deleted']++;
|
|
if ($fileSize !== false) {
|
|
$stats['bytes_freed'] += $fileSize;
|
|
}
|
|
Logger::log("Deleted old file: " . basename($file) . " (age: " .
|
|
round((time() - $fileModTime) / 3600, 1) . " hours)");
|
|
} else {
|
|
$stats['files_failed']++;
|
|
$error = "Failed to delete: " . basename($file);
|
|
$stats['errors'][] = $error;
|
|
Logger::log($error, 'ERROR');
|
|
}
|
|
}
|
|
}
|
|
|
|
// Log cleanup summary
|
|
$summary = "Cleanup completed - Total files: $totalFiles, Old files: $oldFiles, " .
|
|
"Deleted: {$stats['files_deleted']}, Failed: {$stats['files_failed']}, " .
|
|
"Space freed: " . self::formatBytes($stats['bytes_freed']);
|
|
Logger::log($summary);
|
|
|
|
} catch (Exception $e) {
|
|
Logger::log("Error during file cleanup: " . $e->getMessage(), 'ERROR');
|
|
$stats['errors'][] = $e->getMessage();
|
|
}
|
|
|
|
return $stats;
|
|
}
|
|
|
|
/**
|
|
* Format bytes into human readable format
|
|
*
|
|
* @param int $bytes
|
|
* @return string
|
|
*/
|
|
public static function formatBytes($bytes) {
|
|
if ($bytes == 0) return '0 B';
|
|
|
|
$units = ['B', 'KB', 'MB', 'GB'];
|
|
$pow = floor(log($bytes, 1024));
|
|
$pow = min($pow, count($units) - 1);
|
|
|
|
return round($bytes / (1024 ** $pow), 2) . ' ' . $units[$pow];
|
|
}
|
|
|
|
/**
|
|
* Get statistics about the uploads directory
|
|
*
|
|
* @param string $uploadsDir Path to uploads directory
|
|
* @return array Directory statistics
|
|
*/
|
|
public static function getDirectoryStats($uploadsDir = 'uploads/') {
|
|
$stats = [
|
|
'total_files' => 0,
|
|
'total_size' => 0,
|
|
'oldest_file' => null,
|
|
'newest_file' => null,
|
|
'files_over_24h' => 0
|
|
];
|
|
|
|
try {
|
|
if (!is_dir($uploadsDir)) {
|
|
return $stats;
|
|
}
|
|
|
|
$files = glob($uploadsDir . '*');
|
|
if ($files === false) {
|
|
return $stats;
|
|
}
|
|
|
|
$cutoffTime = time() - (24 * 3600);
|
|
$oldestTime = PHP_INT_MAX;
|
|
$newestTime = 0;
|
|
|
|
foreach ($files as $file) {
|
|
if (is_dir($file) || basename($file) === '.gitkeep' || basename($file) === '.htaccess') {
|
|
continue;
|
|
}
|
|
|
|
$stats['total_files']++;
|
|
$fileSize = filesize($file);
|
|
$fileTime = filemtime($file);
|
|
|
|
if ($fileSize !== false) {
|
|
$stats['total_size'] += $fileSize;
|
|
}
|
|
|
|
if ($fileTime !== false) {
|
|
if ($fileTime < $cutoffTime) {
|
|
$stats['files_over_24h']++;
|
|
}
|
|
|
|
if ($fileTime < $oldestTime) {
|
|
$oldestTime = $fileTime;
|
|
$stats['oldest_file'] = [
|
|
'name' => basename($file),
|
|
'age_hours' => round((time() - $fileTime) / 3600, 1)
|
|
];
|
|
}
|
|
|
|
if ($fileTime > $newestTime) {
|
|
$newestTime = $fileTime;
|
|
$stats['newest_file'] = [
|
|
'name' => basename($file),
|
|
'age_hours' => round((time() - $fileTime) / 3600, 1)
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
Logger::log("Error getting directory stats: " . $e->getMessage(), 'ERROR');
|
|
}
|
|
|
|
return $stats;
|
|
}
|
|
}
|
|
?>
|