/** * Get the total filesize for a given file or directory * * If $file is a file then just return the result of `filesize()`. * If $file is a directory then schedule a recursive filesize scan. * * @param \SplFileInfo $file The file or directory you want to know the size of * @param bool $skip_excluded_files Skip excluded files when calculating a directories total size * * @return int The total of the file or directory */ public function filesize(\SplFileInfo $file, $skip_excluded_files = false) { // Skip missing or unreadable files if (!file_exists($file->getPathname()) || !$file->getRealpath() || !$file->isReadable()) { return false; } // If it's a file then just pass back the filesize if ($file->isFile() && $file->isReadable()) { return $file->getSize(); } // If it's a directory then pull it from the cached filesize array if ($file->isDir()) { // If we haven't calculated the site size yet then kick it off in a thread $directory_sizes = get_transient('hmbkp_directory_filesizes'); if (!is_array($directory_sizes)) { if (!$this->is_site_size_being_calculated()) { // Mark the filesize as being calculated set_transient('hmbkp_directory_filesizes_running', true, HOUR_IN_SECONDS); // Schedule a Backdrop task to trigger a recalculation $task = new \HM\Backdrop\Task(array($this, 'recursive_filesize_scanner')); $task->schedule(); } return; } if ($this->backup->get_root() === $file->getPathname()) { return $directory_sizes[$file->getPathname()]; } $current_pathname = trailingslashit($file->getPathname()); $root = trailingslashit($this->backup->get_root()); foreach ($directory_sizes as $path => $size) { // Remove any files that aren't part of the current tree if (false === strpos($path, $current_pathname)) { unset($directory_sizes[$path]); } } if ($skip_excluded_files) { $excludes = $this->backup->exclude_string('regex'); foreach ($directory_sizes as $path => $size) { // Skip excluded files if we have excludes if ($excludes && preg_match('(' . $excludes . ')', str_ireplace($root, '', Backup::conform_dir($path)))) { unset($directory_sizes[$path]); } } } // Directory size is now just a sum of all files across all sub directories return array_sum($directory_sizes); } }