PluginProbe
Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution / 1.8.0
Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution v1.8.0
2.0.1 trunk 1.0.0 1.1.0 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.5.0 1.6.0 1.6.1 1.7.0 1.7.1 1.8.0 1.9.0 2.0.0
solid-performance / src / Performance / Page_Cache / Cache_Handler.php

Cache_Handler.php in Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution 1.8.0, at src/Performance/Page_Cache/Cache_Handler.php

180 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Handles managing cache files.
4 *
5 * @package SolidWP\Performance
6 */
7
8 declare( strict_types=1 );
9
10 namespace SolidWP\Performance\Page_Cache;
11
12 use InvalidArgumentException;
13 use RuntimeException;
14 use SolidWP\Performance\Http\Request;
15 use SolidWP\Performance\Page_Cache\Compression\Collection;
16 use SolidWP\Performance\Page_Cache\Compression\Contracts\Compressible;
17 use SolidWP\Performance\Page_Cache\Compression\Exceptions\CompressionFailedException;
18 use SolidWP\Performance\Page_Cache\Meta\Exceptions\MetadataNotWritableException;
19 use SolidWP\Performance\Page_Cache\Meta\Meta_Manager;
20
21 /**
22 * Handles managing cache files.
23 *
24 * @package SolidWP\Performance
25 */
26 final class Cache_Handler {
27
28 /**
29 * @var Compressible
30 */
31 private Compressible $compressor;
32
33 /**
34 * @var Request
35 */
36 private Request $request;
37
38 /**
39 * @var Debug
40 */
41 private Debug $debug;
42
43 /**
44 * @var Expiration
45 */
46 private Expiration $expiration;
47
48 /**
49 * @var Cache_Path
50 */
51 private Cache_Path $cache_path;
52
53 /**
54 * @var Meta_Manager
55 */
56 private Meta_Manager $meta_manager;
57
58 /**
59 * @param Collection $compressors The collection of compression algorithms.
60 * @param Request $request The current request.
61 * @param Debug $debug The debugger.
62 * @param Expiration $expiration The expiration manager.
63 * @param Cache_Path $cache_path The server path to the cache directory.
64 * @param Meta_Manager $meta_manager The meta manager.
65 */
66 public function __construct(
67 Collection $compressors,
68 Request $request,
69 Debug $debug,
70 Expiration $expiration,
71 Cache_Path $cache_path,
72 Meta_Manager $meta_manager
73 ) {
74 $this->compressor = $compressors->get_by_header( (string) $request->header->get( 'accept-encoding' ) );
75 $this->request = $request;
76 $this->debug = $debug;
77 $this->expiration = $expiration;
78 $this->cache_path = $cache_path;
79 $this->meta_manager = $meta_manager;
80 }
81
82 /**
83 * Save a file to the cache based on the type of compression the browser is asking for
84 * and what the server supports.
85 *
86 * @param string $output Output to save in the cached file.
87 *
88 * @throws RuntimeException If the cache directory or cache file can't be created.
89 * @throws InvalidArgumentException If the URL is empty.
90 * @throws MetadataNotWritableException If we can't write the metadata.
91 *
92 * @return void
93 */
94 public function save( string $output ): void {
95 $this->ensure_cache_dir_exists();
96
97 $file = $this->get_file_path();
98
99 // Append HTML debug comment, if enabled.
100 $output .= $this->debug->get_debug_comment( $this->request, $this->compressor );
101
102 // Append HTML generated by comment if debugging is DISABLED.
103 $output .= $this->debug->get_generated_by_comment();
104
105 // Don't save any fails that failed to compress their content.
106 try {
107 $compressed = $this->compressor->compress( $output );
108 } catch ( CompressionFailedException $e ) {
109 swpsp_log( sprintf( 'Failed to compress content using "%s" compression: %s', $this->compressor->encoding(), $e->getMessage() ) );
110
111 return;
112 }
113
114 $result = swpsp_direct_filesystem()->put_contents( $file, $compressed, swpsp_get_file_mode() );
115
116 if ( $result === false ) {
117 throw new RuntimeException( sprintf( 'File could not be saved to cache: %s', $file ) );
118 }
119
120 // Save the cache metadata.
121 $this->meta_manager->save( $this->request->uri );
122 }
123
124 /**
125 * Converts a URL into a directory structure.
126 *
127 * All cached requests will be saved to a directory structure that matches
128 * the relative URL. This provides a way to consistently get the cached
129 * resource from the URL.
130 *
131 * @throws RuntimeException When URL does not have valid host.
132 *
133 * @return string
134 */
135 public function get_file_path(): string {
136 $path = $this->cache_path->get_path_from_url( $this->request->uri );
137 $ext = $this->compressor->extension();
138
139 return "$path.$ext";
140 }
141
142 /**
143 * Whether the current cache file exists and is not expired.
144 *
145 * @return bool
146 */
147 public function is_valid(): bool {
148 return file_exists( $this->get_file_path() ) && ! $this->expiration->file_expired( $this->get_file_path() );
149 }
150
151 /**
152 * Get the current compression strategy.
153 *
154 * @return Compressible
155 */
156 public function compressor(): Compressible {
157 return $this->compressor;
158 }
159
160 /**
161 * Make sure the complete directory we'll be saving our file to, actually exists.
162 *
163 * @throws RuntimeException If the cache directory can't be created.
164 *
165 * @return void
166 */
167 private function ensure_cache_dir_exists(): void {
168 $dir = dirname( $this->get_file_path() );
169
170 // If the file's directory structure does not exist yet, create it.
171 if ( ! is_dir( $dir ) ) {
172 $result = wp_mkdir_p( $dir );
173
174 if ( ! $result ) {
175 throw new RuntimeException( 'Unable to make directory: ' . $dir );
176 }
177 }
178 }
179 }
180