PluginProbe
Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution / trunk
Solid Performance – Your No-Code Caching, Performance, & Page Speed Solution vtrunk
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_Path.php

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

184 lines 4.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * A single place to get cache path directories.
4 *
5 * @package SolidWP\Performance
6 */
7
8 declare( strict_types=1 );
9
10 namespace SolidWP\Performance\Page_Cache;
11
12 use FilesystemIterator;
13 use RecursiveDirectoryIterator;
14 use RecursiveIteratorIterator;
15 use RuntimeException;
16 use SolidWP\Performance\Http\Uri;
17 use SolidWP\Performance\Page_Cache\Compression\Strategies\Brotli;
18 use SolidWP\Performance\Page_Cache\Compression\Strategies\Gzip;
19 use SolidWP\Performance\Page_Cache\Compression\Strategies\Html;
20 use SolidWP\Performance\Page_Cache\Compression\Strategies\Zstd;
21 use UnexpectedValueException;
22
23 /**
24 * A single place to get cache path directories.
25 *
26 * @package SolidWP\Performance
27 */
28 class Cache_Path {
29
30 /**
31 * @var Request_Scheme_Resolver
32 */
33 private Request_Scheme_Resolver $scheme_resolver;
34
35 /**
36 * The cache directory, e.g. /app/wp-content/cache/solid-performance.
37 *
38 * @var string
39 */
40 private string $cache_dir;
41
42 /**
43 * @param Request_Scheme_Resolver $scheme_resolver The http scheme resolver.
44 * @param string $cache_dir The cache directory, e.g. /app/wp-content/cache/solid-performance.
45 */
46 public function __construct( Request_Scheme_Resolver $scheme_resolver, string $cache_dir ) {
47 $this->scheme_resolver = $scheme_resolver;
48 $this->cache_dir = $cache_dir;
49 }
50
51 /**
52 * Returns the server path to the cache directory.
53 *
54 * @example /app/wp-content/cache/solid-performance
55 *
56 * @return string
57 */
58 public function get_cache_dir(): string {
59 return $this->cache_dir;
60 }
61
62 /**
63 * Get the path to where pages are cached.
64 *
65 * @example /app/wp-content/cache/solid-performance/page
66 *
67 * @return string
68 */
69 public function get_page_cache_dir(): string {
70 return $this->get_cache_dir() . '/page';
71 }
72
73 /**
74 * Get the host site cache directory.
75 *
76 * @example /app/wp-content/cache/solid-performance/page/www.wordpress.test
77 *
78 * @return string
79 */
80 public function get_site_cache_dir(): string {
81 $path = $this->get_page_cache_dir();
82 $site_host = wp_parse_url( get_site_url(), PHP_URL_HOST );
83 $site_host = is_string( $site_host ) ? Uri::normalize_host( $site_host ) : '';
84
85 return $path . DIRECTORY_SEPARATOR . $site_host;
86 }
87
88 /**
89 * Get the HTTP scheme, e.g. https or http.
90 *
91 * @return string
92 */
93 public function get_scheme(): string {
94 return $this->scheme_resolver->get_scheme();
95 }
96
97 /**
98 * Converts a URL into a directory structure.
99 *
100 * All cached requests will be saved to a directory structure that matches
101 * the relative URL. This provides a way to consistently get the cached
102 * resource from the URL.
103 *
104 * @example /app/wp-content/cache/solid-performance/page/local.test.com/test-post/index-https
105 *
106 * @throws RuntimeException When URL does not have valid host.
107 *
108 * @param string $url The full URL of the request (e.g. https://solidwp.com/about).
109 *
110 * @return string
111 */
112 public function get_path_from_url( string $url ): string {
113 $url_parts = parse_url( $url ); // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url
114
115 if ( ! isset( $url_parts['host'] ) || $url_parts['host'] === '' ) {
116 throw new RuntimeException( 'URL needs a valid host.' );
117 }
118
119 $host = Uri::normalize_host( trim( $url_parts['host'], '/' ) );
120 $path = trim( $url_parts['path'] ?? '', '/' );
121 $scheme = $this->get_scheme();
122
123 $cache_path = "{$this->get_page_cache_dir()}/$host";
124
125 if ( $path !== '' ) {
126 $cache_path .= "/$path";
127 }
128
129 return "$cache_path/index-$scheme";
130 }
131
132 /**
133 * Recursively count how many cache files we have.
134 *
135 * We count 1 supported extension per directory as a single file.
136 *
137 * @param string $path The optional path.
138 *
139 * @return int
140 */
141 public function count( string $path = '' ): int {
142 if ( ! $path ) {
143 $path = $this->get_site_cache_dir();
144 }
145
146 if ( ! file_exists( $path ) ) {
147 return 0;
148 }
149
150 try {
151 $iterator = new RecursiveIteratorIterator(
152 new RecursiveDirectoryIterator( $path, FilesystemIterator::SKIP_DOTS )
153 );
154 } catch ( UnexpectedValueException $e ) {
155 return 0;
156 }
157
158 $extensions = [
159 Html::EXT,
160 Gzip::EXT,
161 Brotli::EXT,
162 Zstd::EXT,
163 ];
164
165 $seen = [];
166
167 /** @var FilesystemIterator $file */
168 foreach ( $iterator as $file ) {
169 $dir = $file->getPath();
170
171 // Only count 1 cache extension per directory once.
172 if ( isset( $seen[ $dir ] ) ) {
173 continue;
174 }
175
176 if ( in_array( $file->getExtension(), $extensions, true ) ) {
177 $seen[ $dir ] = true;
178 }
179 }
180
181 return count( $seen );
182 }
183 }
184