request = $request; $this->compressor = $compressors->get_by_header( (string) $request->header->get( 'accept-encoding' ) ); $this->debug = $debug; $this->expiration = $expiration; $this->cache_path = $cache_path; } /** * Save a file to the cache based on the type of compression the browser is asking for * and what the server supports. * * @param string $output Output to save in the cached file. * * @throws RuntimeException If the cache directory or cache file can't be created. * * @return void */ public function save( string $output ): void { $this->ensure_cache_dir_exists(); $file = $this->get_file_path(); // Append HTML debug comment, if enabled. $output .= $this->debug->get_debug_comment( $this->request, $this->compressor ); // Append HTML generated by comment if debugging is DISABLED. $output .= $this->debug->get_generated_by_comment(); // Don't save any fails that failed to compress their content. try { $compressed = $this->compressor->compress( $output ); } catch ( CompressionFailedException $e ) { swpsp_log( sprintf( 'Failed to compress content using "%s" compression: %s', $this->compressor->encoding(), $e->getMessage() ) ); return; } $result = swpsp_direct_filesystem()->put_contents( $file, $compressed, swpsp_get_file_mode() ); if ( $result === false ) { throw new RuntimeException( sprintf( 'File could not be saved to cache: %s', $file ) ); } } /** * 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. * * @throws RuntimeException When URL does not have valid host. * * @return string */ public function get_file_path(): string { $path = $this->cache_path->get_path_from_url( $this->request->uri ); $ext = $this->compressor->extension(); return "$path.$ext"; } /** * Whether the current cache file exists and is not expired. * * @return bool */ public function is_valid(): bool { return file_exists( $this->get_file_path() ) && ! $this->expiration->file_expired( $this->get_file_path() ); } /** * Get the current compression strategy. * * @return Compressible */ public function compressor(): Compressible { return $this->compressor; } /** * Make sure the complete directory we'll be saving our file to, actually exists. * * @throws RuntimeException If the cache directory can't be created. * * @return void */ private function ensure_cache_dir_exists(): void { $dir = dirname( $this->get_file_path() ); // If the file's directory structure does not exist yet, create it. if ( ! is_dir( $dir ) ) { $result = wp_mkdir_p( $dir ); if ( ! $result ) { throw new RuntimeException( 'Unable to make directory: ' . $dir ); } } } }