.htaccess
1 year ago
DirIterator.php
5 months ago
DirIteratorExcludes.php
1 year ago
DirIteratorFile.php
1 year ago
index.html
1 year ago
web.config
1 year ago
DirIteratorFile.php
112 lines
| 1 | <?php |
| 2 | |
| 3 | namespace JetBackup\DirIterator; |
| 4 | |
| 5 | use JetBackup\Exception\DirIteratorException; |
| 6 | use JetBackup\Exception\DirIteratorFileVanishedException; |
| 7 | use JetBackup\Filesystem\File; |
| 8 | |
| 9 | if (!defined( '__JETBACKUP__')) die('Direct access is not allowed'); |
| 10 | |
| 11 | class DirIteratorFile { |
| 12 | |
| 13 | private $_file; |
| 14 | private $_filesize; |
| 15 | private $_archive_position; |
| 16 | |
| 17 | /** |
| 18 | * @throws DirIteratorFileVanishedException |
| 19 | * @throws DirIteratorException |
| 20 | */ |
| 21 | public function __construct($filename) { |
| 22 | // Debug: Log the initial filename |
| 23 | //error_log("Initial filename: $filename"); |
| 24 | |
| 25 | $filename = preg_replace_callback("/" . DirIterator::POSITION_EOL_REGEX . "/", function($match) { |
| 26 | switch($match[1]) { |
| 27 | case 'r': return "\r"; |
| 28 | case 'n': return "\n"; |
| 29 | } |
| 30 | return ''; |
| 31 | }, $filename); |
| 32 | |
| 33 | // Debug: Log the filename after EOL replacement |
| 34 | //error_log("Filename after EOL replacement: $filename"); |
| 35 | |
| 36 | |
| 37 | $status = $this->cleanFilename($filename); |
| 38 | $this->_archive_position = $status->pos; |
| 39 | $filename = $status->filename; |
| 40 | |
| 41 | if(!file_exists($filename)) { |
| 42 | throw new DirIteratorFileVanishedException("The file '$filename' has vanished"); |
| 43 | } |
| 44 | |
| 45 | $this->_file = new File($filename); |
| 46 | $this->_filesize = $this->_file->size(); |
| 47 | } |
| 48 | |
| 49 | |
| 50 | /** |
| 51 | * @throws DirIteratorException |
| 52 | */ |
| 53 | private function cleanFilename($filename): \stdClass { |
| 54 | |
| 55 | // Debug: Log the initial filename |
| 56 | //error_log("cleanFilename Initial filename: $filename"); |
| 57 | |
| 58 | // Regular expression to find the first occurrence of {pos: and capture everything after it |
| 59 | $pattern = "/\{pos:\d+.*$/"; |
| 60 | |
| 61 | // Find the first occurrence of {pos: and everything after it |
| 62 | if (preg_match($pattern, $filename, $matches)) { |
| 63 | // Debug: Log the match found |
| 64 | //error_log("cleanFilename Match found: " . print_r($matches[0], true)); |
| 65 | |
| 66 | // Extract the matched substring |
| 67 | $matchedSubstring = $matches[0]; |
| 68 | |
| 69 | // Calculate the length of the match |
| 70 | $matchLength = strlen($matchedSubstring); |
| 71 | |
| 72 | // Extract the position value |
| 73 | preg_match("/\d+/", $matchedSubstring, $posMatches); |
| 74 | $lastPos = end($posMatches); |
| 75 | |
| 76 | // Remove the matched substring from the original filename |
| 77 | $cleanedFilename = substr($filename, 0, -$matchLength); |
| 78 | |
| 79 | // Ensure no trailing spaces or curly braces are left |
| 80 | $cleanedFilename = trim($cleanedFilename); |
| 81 | |
| 82 | // Debug: Log the cleaned filename and position |
| 83 | //error_log("cleanFilename Cleaned filename: $cleanedFilename with pos: $lastPos"); |
| 84 | |
| 85 | // Initialize the return object |
| 86 | $result = new \stdClass(); |
| 87 | $result->filename = $cleanedFilename; |
| 88 | $result->pos = $lastPos; |
| 89 | return $result; |
| 90 | |
| 91 | } else { |
| 92 | |
| 93 | throw new DirIteratorException('Could not determine archive seek position for ' . $filename); |
| 94 | |
| 95 | } |
| 96 | |
| 97 | |
| 98 | } |
| 99 | |
| 100 | |
| 101 | |
| 102 | |
| 103 | public function getName() { return $this->_file->path(); } |
| 104 | public function getSize() { return $this->_filesize; } |
| 105 | public function getArchivePosition() { return $this->_archive_position; } |
| 106 | |
| 107 | public static function safe_filesize($filename) : int { |
| 108 | // Check if the filename contains a null byte |
| 109 | if (strpos($filename, "\0") !== false) return 0; |
| 110 | return @filesize($filename); |
| 111 | } |
| 112 | } |