Преглед изворни кода

Serve admin assets under version-stamped filenames for cache busting

studiou.cz strips the ?ver= query string from static assets, so a
version bump alone never busts the browser cache and users had to
hard-refresh after every update.

get_cache_busted_asset_url() now serves admin CSS/JS under filenames
that embed the plugin version (admin-1.6.0.js etc.). The versioned
copy is auto-generated from the source admin.js/admin.css and
refreshed whenever the source changes, so no manual renaming is
needed. Falls back to the plain URL if the copy cannot be written.

Versioned copies are runtime-generated build artifacts and gitignored.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dalibor Votruba пре 1 месец
родитељ
комит
20a8c110ab

+ 6 - 0
studiou-wc-product-cat-manage/.gitignore

@@ -0,0 +1,6 @@
+# Auto-generated, version-stamped asset copies used for cache busting on
+# hosts that strip the ?ver= query string (e.g. studiou.cz). These are
+# created at runtime from the source admin.js / admin.css and must not be
+# committed.
+/assets/js/admin-*.js
+/assets/css/admin-*.css

+ 1 - 1
studiou-wc-product-cat-manage/CLAUDE.md

@@ -22,7 +22,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
 - **studiou-wc-product-cat-manage.php** - Main plugin file containing:
   - Plugin initialization and dependency loading
   - Admin menu registration under Products menu
-  - Asset enqueueing for admin pages
+  - Asset enqueueing for admin pages — CSS/JS are served under version-stamped filenames (`admin-X.Y.Z.js` / `admin-X.Y.Z.css`, auto-generated from the source files) so cache busting works on hosts that strip the `?ver=` query string. Versioned copies are gitignored.
   - WooCommerce HPOS compatibility declaration
   - Text domain loading for translations
 

+ 1 - 0
studiou-wc-product-cat-manage/readme.md

@@ -361,6 +361,7 @@ For support, please visit [https://www.quadarax.com/plugins/studiou-wc-product-c
 - New AJAX handler: `studiou_wcpcm_load_tab` renders a manipulations tab partial on demand
 - Category and media-category count queries are now transient-cached (5 minutes, automatically invalidated when categories or product/category relationships change)
 - 7 new view partials under `views/manipulations/`
+- **Cache busting** - admin CSS/JS are now served under version-stamped filenames (`admin-X.Y.Z.js` / `admin-X.Y.Z.css`), so a version bump forces browsers to fetch fresh assets even on hosts that strip the `?ver=` query string. No more manual hard refresh needed after an update.
 
 ### Version 1.5.3
 - **NEW: Update product variant prices** - bulk-update regular price of product variations

+ 51 - 3
studiou-wc-product-cat-manage/studiou-wc-product-cat-manage.php

@@ -242,14 +242,14 @@ class Studiou_WC_Product_Cat_Manage {
             
             wp_enqueue_style(
                 'studiou-wcpcm-admin',
-                STUDIOU_WCPCM_PLUGIN_URL . 'assets/css/admin.css',
+                $this->get_cache_busted_asset_url('assets/css/admin', 'css'),
                 array(),
                 STUDIOU_WCPCM_VERSION
             );
 
             wp_enqueue_script(
                 'studiou-wcpcm-admin',
-                STUDIOU_WCPCM_PLUGIN_URL . 'assets/js/admin.js',
+                $this->get_cache_busted_asset_url('assets/js/admin', 'js'),
                 array('jquery'),
                 STUDIOU_WCPCM_VERSION,
                 true
@@ -301,7 +301,55 @@ class Studiou_WC_Product_Cat_Manage {
             }
         }
     }
-    
+
+    /**
+     * Build a cache-busting URL for a plugin asset.
+     *
+     * studiou.cz (and similar host optimisers) strip the `?ver=` query string
+     * from static assets, so a version bump alone does not bust the browser
+     * cache. To work around that, this serves the asset under a filename that
+     * embeds the plugin version, e.g. assets/js/admin-1.6.0.js. The versioned
+     * copy is generated automatically from the source file and refreshed
+     * whenever the source changes, so no manual file renaming is needed.
+     *
+     * Falls back to the plain source URL if the copy cannot be written.
+     *
+     * @param string $rel_no_ext Asset path relative to the plugin dir, without
+     *                           extension, e.g. 'assets/js/admin'.
+     * @param string $ext        File extension without the dot, e.g. 'js'.
+     * @return string Absolute URL to the asset.
+     */
+    private function get_cache_busted_asset_url($rel_no_ext, $ext) {
+        $source_rel = $rel_no_ext . '.' . $ext;
+        $source_abs = STUDIOU_WCPCM_PLUGIN_DIR . $source_rel;
+
+        // Source missing - nothing we can do, return the plain URL.
+        if (!file_exists($source_abs)) {
+            return STUDIOU_WCPCM_PLUGIN_URL . $source_rel;
+        }
+
+        $versioned_rel = $rel_no_ext . '-' . STUDIOU_WCPCM_VERSION . '.' . $ext;
+        $versioned_abs = STUDIOU_WCPCM_PLUGIN_DIR . $versioned_rel;
+
+        // Regenerate the versioned copy if it is missing or out of date.
+        if (!file_exists($versioned_abs) || filemtime($source_abs) > filemtime($versioned_abs)) {
+            // Remove stale versioned copies of this asset.
+            $old_files = glob(STUDIOU_WCPCM_PLUGIN_DIR . $rel_no_ext . '-*.' . $ext);
+            if (is_array($old_files)) {
+                foreach ($old_files as $old_file) {
+                    @unlink($old_file);
+                }
+            }
+
+            // Copy failed (e.g. read-only filesystem) - fall back to plain URL.
+            if (!@copy($source_abs, $versioned_abs)) {
+                return STUDIOU_WCPCM_PLUGIN_URL . $source_rel;
+            }
+        }
+
+        return STUDIOU_WCPCM_PLUGIN_URL . $versioned_rel;
+    }
+
     /**
      * Render import page
      */