/** * 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; } } }