PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.4.1
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.4.1
1.4.1 1.4.0 1.3.7 1.3.6 1.3.5 1.3.4 1.3.3 1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 All 35 releases
← All changes | includes/class-css-combine-buffer.php +19 -3 1.3.7 → 1.4.1 View file →
@@ -276,9 +276,22 @@
276 276 *
277 277 * @param array{media:string,async:bool,tags:string[],urls:string[]} $run Run to merge.
278 278 */
279 279 private static function merge_run( array $run ): ?string {
280 - $key = md5( implode( '|', array_map( static fn( $p ) => $p . ':' . (int) @filemtime( $p ), $run['urls'] ) ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- a missing file contributes 0 to the key; handled below.
280 + // Nowhere to write means nothing to link: a <link> to a file that was
281 + // never written unstyles the page.
282 + if ( ! Minifier::min_dir_writable() ) {
283 + return null;
284 + }
285 + // Named by content and by site. See Asset_Combiner::combined_key().
286 + $parts = array();
287 + foreach ( $run['urls'] as $path ) {
288 + $parts[] = array(
289 + 'path' => $path,
290 + 'url' => self::path_to_url( $path ),
291 + );
292 + }
293 + $key = Asset_Combiner::combined_key( $parts, 'css' );
281 294 $dir = Asset_Combiner::cache_dir();
282 295 $file = $dir . '/combined-' . $key . '.css';
283 296 $url = Asset_Combiner::cache_url() . '/combined-' . $key . '.css';
284 297
@@ -324,10 +337,13 @@
324 337 $css = Asset_Combiner::minify_css_body( $css );
325 338 if ( ! is_dir( $dir ) ) {
326 339 wp_mkdir_p( $dir );
327 340 }
328 - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_put_contents_file_put_contents -- WP_Filesystem requires admin context, unavailable on the frontend.
329 - file_put_contents( $file, $css, LOCK_EX );
341 + // Atomic: a concurrent render sees the whole file or none of it.
342 + // A failed write links nothing rather than a file that is not there.
343 + if ( ! Asset_Manifest::write_atomic( $file, $css ) && ! file_exists( $file ) ) {
344 + return null;
345 + }
330 346 }
331 347
332 348 // Carry Async CSS across the merge (issue #330). Every sheet in the
333 349 // run was async'd — that is a condition of grouping them, enforced in