isDot() || ! $item->isDir() ) { continue; } self::rrmdir( $item->getPathname() ); } } /** * Delete cached pages older than $ttl seconds, and stale temp files. * * @return int Number of pages removed. */ public static function purge_expired( int $ttl ): int { if ( $ttl <= 0 || ! is_dir( CACHE_SHARK_BASE ) ) { return 0; } $cutoff = time() - $ttl; $removed = 0; $it = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( CACHE_SHARK_BASE, \FilesystemIterator::SKIP_DOTS ) ); foreach ( $it as $f ) { if ( ! $f->isFile() ) { continue; } $name = $f->getFilename(); if ( preg_match( '/^index-(https?)(-mobile)?\.html$/', $name ) && $f->getMTime() < $cutoff ) { if ( Fs::delete( $f->getPathname() ) ) { ++$removed; } } elseif ( 0 === strpos( $name, '.tmp-' ) && $f->getMTime() < time() - HOUR_IN_SECONDS ) { Fs::delete( $f->getPathname() ); } } return $removed; } /** Remove the whole cache tree incl. config (used on uninstall). */ public static function destroy(): void { if ( is_dir( CACHE_SHARK_BASE ) ) { self::rrmdir( CACHE_SHARK_BASE ); } } private static function rrmdir( string $dir ): void { if ( is_link( $dir ) ) { Fs::delete( $dir ); // Never follow symlinks out of the cache tree. return; } $it = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( $dir, \FilesystemIterator::SKIP_DOTS ), \RecursiveIteratorIterator::CHILD_FIRST ); foreach ( $it as $f ) { if ( $f->isDir() && ! $f->isLink() ) { Fs::rmdir( $f->getPathname() ); } else { Fs::delete( $f->getPathname() ); } } Fs::rmdir( $dir ); } /** @return array{files:int,bytes:int} */ public static function stats(): array { $files = 0; $bytes = 0; if ( is_dir( CACHE_SHARK_BASE ) ) { $it = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( CACHE_SHARK_BASE, \FilesystemIterator::SKIP_DOTS ) ); foreach ( $it as $f ) { if ( '.html' === substr( $f->getFilename(), -5 ) ) { ++$files; $bytes += $f->getSize(); } } } return compact( 'files', 'bytes' ); } }