scheme_resolver = $scheme_resolver; $this->cache_dir = $cache_dir; } /** * Returns the server path to the cache directory. * * @example /app/wp-content/cache/solid-performance * * @return string */ public function get_cache_dir(): string { return $this->cache_dir; } /** * Get the path to where pages are cached. * * @example /app/wp-content/cache/solid-performance/page * * @return string */ public function get_page_cache_dir(): string { return $this->get_cache_dir() . '/page'; } /** * Get the host site cache directory. * * @example /app/wp-content/cache/solid-performance/page/www.wordpress.test * * @return string */ public function get_site_cache_dir(): string { $path = $this->get_page_cache_dir(); $site_host = wp_parse_url( get_site_url(), PHP_URL_HOST ); $site_host = is_string( $site_host ) ? Uri::normalize_host( $site_host ) : ''; return $path . DIRECTORY_SEPARATOR . $site_host; } /** * Get the HTTP scheme, e.g. https or http. * * @return string */ public function get_scheme(): string { return $this->scheme_resolver->get_scheme(); } /** * Converts a URL into a directory structure. * * All cached requests will be saved to a directory structure that matches * the relative URL. This provides a way to consistently get the cached * resource from the URL. * * @example /app/wp-content/cache/solid-performance/page/local.test.com/test-post/index-https * * @throws RuntimeException When URL does not have valid host. * * @param string $url The full URL of the request (e.g. https://solidwp.com/about). * * @return string */ public function get_path_from_url( string $url ): string { $url_parts = parse_url( $url ); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url if ( ! isset( $url_parts['host'] ) || $url_parts['host'] === '' ) { throw new RuntimeException( 'URL needs a valid host.' ); } $host = Uri::normalize_host( trim( $url_parts['host'], '/' ) ); $path = trim( $url_parts['path'] ?? '', '/' ); $scheme = $this->get_scheme(); $cache_path = "{$this->get_page_cache_dir()}/$host"; if ( $path !== '' ) { $cache_path .= "/$path"; } return "$cache_path/index-$scheme"; } /** * Recursively count how many cache files we have. * * We count 1 supported extension per directory as a single file. * * @param string $path The optional path. * * @return int */ public function count( string $path = '' ): int { if ( ! $path ) { $path = $this->get_site_cache_dir(); } if ( ! file_exists( $path ) ) { return 0; } try { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path, FilesystemIterator::SKIP_DOTS ) ); } catch ( UnexpectedValueException $e ) { return 0; } $extensions = [ Html::EXT, Gzip::EXT, Brotli::EXT, Zstd::EXT, ]; $seen = []; /** @var FilesystemIterator $file */ foreach ( $iterator as $file ) { $dir = $file->getPath(); // Only count 1 cache extension per directory once. if ( isset( $seen[ $dir ] ) ) { continue; } if ( in_array( $file->getExtension(), $extensions, true ) ) { $seen[ $dir ] = true; } } return count( $seen ); } }