/** * 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()) || !@realpath($file->getPathname()) || !$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; } $current_pathname = trailingslashit($file->getPathname()); $root = trailingslashit($this->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->exclude_string('regex'); foreach ($directory_sizes as $path => $size) { // Skip excluded files if we have excludes if ($excludes && preg_match('(' . $excludes . ')', str_ireplace($root, '', HM_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); } }
/** * 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 string $file The file you want to know the size of * @return int The total of the file or directory */ public function total_filesize(SplFileInfo $file, $ignore_excludes = true) { if (!file_exists($file->getPathname()) || !@realpath($file->getPathname()) || !$file->isReadable()) { return false; } if ($file->isFile()) { return $file->getSize(); } if ($file->isDir()) { $transient_filesize_key = $this->get_transient_key($file->getPathname()); $transient_running_key = $this->get_transient_key('running_' . $file->getPathname()); if (!$ignore_excludes) { $transient_filesize_key = $this->get_transient_key($excludes . $file->getPathname()); $transient_running_key = $this->get_transient_key('running_' . $excludes . $file->getPathname()); } // If we already have a cached filesize for this directory then let's return it $size = get_transient($transient_filesize_key); if ($size !== false) { return (int) $size; // If we don't have a cached filesize then we probably need to calculate it } else { // Don't bother re-calculating if we are already doing that in a different thread through $parent_directory = $file->getPathname(); while ($parent_directory !== '/') { $parent_task = new HM_Backdrop_Task(array($this, 'recursive_directory_filesize_scanner'), $parent_directory, $ignore_excludes); // If we are already calulating the parent directory in another thread then let's just wait for that to finish if ($parent_task->is_scheduled()) { return false; } $parent_directory = dirname($parent_directory); } update_option($transient_running_key, true); // Schedule a Backdrop task to trigger a recalculation $task = new HM_Backdrop_Task(array($this, 'recursive_directory_filesize_scanner'), $file->getPathname(), $ignore_excludes); $task->schedule(); return false; } } }