ソースを参照

Fix protected categories missing from manipulations dropdowns

Since v1.6.0 the category list is fetched inside an admin-ajax request
(tab partial loading). In that context the WooCommerce Protected
Categories plugin filters get_terms() and hides protected categories,
so they disappeared from every category dropdown/checklist on the
Category Manipulations page.

get_categories_with_counts_uncached() now queries the product_cat
terms directly via $wpdb, bypassing all term-query filters, so the
list always includes protected categories - admins need to operate on
them here. Renamed the count transient key so the previously cached
(filtered) list is discarded immediately.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dalibor Votruba 1 ヶ月 前
コミット
89360f0acb

+ 26 - 15
studiou-wc-product-cat-manage/includes/class-studiou-wc-product-cat-manage-manipulator.php

@@ -72,7 +72,7 @@ class Studiou_WC_Product_Cat_Manage_Manipulator {
      * manipulations tabs stay accurate.
      */
     public function bust_count_cache() {
-        delete_transient('studiou_wcpcm_cat_counts');
+        delete_transient('studiou_wcpcm_category_counts');
         delete_transient('studiou_wcpcm_media_cat_counts');
     }
 
@@ -627,11 +627,11 @@ class Studiou_WC_Product_Cat_Manage_Manipulator {
      * @return array Array of categories with ID, name, and product count
      */
     public function get_categories_with_counts() {
-        $data = get_transient('studiou_wcpcm_cat_counts');
+        $data = get_transient('studiou_wcpcm_category_counts');
 
         if (false === $data) {
             $data = $this->get_categories_with_counts_uncached();
-            set_transient('studiou_wcpcm_cat_counts', $data, 5 * MINUTE_IN_SECONDS);
+            set_transient('studiou_wcpcm_category_counts', $data, 5 * MINUTE_IN_SECONDS);
         }
 
         return $data;
@@ -640,27 +640,38 @@ class Studiou_WC_Product_Cat_Manage_Manipulator {
     /**
      * Get all categories with product counts for select lists (uncached).
      *
+     * Queries the product_cat terms directly via $wpdb instead of get_terms()
+     * on purpose: the WooCommerce Protected Categories plugin filters
+     * get_terms() and hides protected categories in admin-ajax / front-end
+     * contexts. Since v1.6.0 the manipulations tabs fetch this list inside an
+     * admin-ajax request, so get_terms() would drop protected categories from
+     * the dropdowns. Admins must be able to see and operate on every category,
+     * protected ones included, so we bypass the term-query filters entirely.
+     *
      * @return array Array of categories with ID, name, and product count
      */
     public function get_categories_with_counts_uncached() {
-        $args = array(
-            'taxonomy' => 'product_cat',
-            'orderby' => 'name',
-            'hide_empty' => false,
-        );
+        global $wpdb;
+
+        $terms = $wpdb->get_results($wpdb->prepare("
+            SELECT t.term_id, t.name
+            FROM {$wpdb->terms} t
+            INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id
+            WHERE tt.taxonomy = %s
+            ORDER BY t.name ASC
+        ", 'product_cat'));
 
-        $categories = get_terms($args);
         $categories_with_counts = array();
 
-        if (!is_wp_error($categories)) {
-            foreach ($categories as $category) {
-                $product_count = $this->get_category_product_count($category->term_id);
+        if (!empty($terms)) {
+            foreach ($terms as $term) {
+                $product_count = $this->get_category_product_count($term->term_id);
 
                 $categories_with_counts[] = array(
-                    'id' => $category->term_id,
-                    'name' => $category->name,
+                    'id' => (int) $term->term_id,
+                    'name' => $term->name,
                     'count' => $product_count,
-                    'display_name' => sprintf('%s (%d products)', $category->name, $product_count)
+                    'display_name' => sprintf('%s (%d products)', $term->name, $product_count)
                 );
             }
         }