Browse Source

studiou-wc-product-cat-manage: fix export to export structural categories

Dalibor Votruba 1 year ago
parent
commit
13da469bc3

+ 177 - 54
studiou-wc-product-cat-manage/includes/class-studiou-wc-product-cat-manage-db.php

@@ -28,17 +28,23 @@ class Studiou_WC_Product_Cat_Manage_DB {
      * @return array Array of product categories with all required properties
      */
     public function get_all_product_categories() {
+        // Get all categories regardless of hierarchy, including empty ones
         $args = array(
             'taxonomy'   => 'product_cat',
-            'orderby'    => 'name',
+            'orderby'    => 'term_id', // Order by ID to maintain creation order
             'hide_empty' => false,
+            'hierarchical' => false, // Don't nest them, get a flat list
+            'get' => 'all', // Get all fields
         );
         
         $categories = get_terms($args);
         $formatted_categories = array();
         
-        if (!is_wp_error($categories)) {
-            foreach ($categories as $category) {
+        if (!is_wp_error($categories) && !empty($categories)) {
+            // Sort by hierarchy: parent categories first, then children
+            $sorted_categories = $this->sort_categories_by_hierarchy($categories);
+            
+            foreach ($sorted_categories as $category) {
                 $formatted_categories[] = $this->format_category($category);
             }
         }
@@ -46,6 +52,95 @@ class Studiou_WC_Product_Cat_Manage_DB {
         return $formatted_categories;
     }
     
+    /**
+     * Sort categories by hierarchy - parents first, then children
+     * 
+     * @param array $categories Array of WP_Term objects
+     * @return array Sorted array of categories
+     */
+    private function sort_categories_by_hierarchy($categories) {
+        $parents = array();
+        $children = array();
+        
+        // Separate parents and children
+        foreach ($categories as $category) {
+            if ($category->parent == 0) {
+                $parents[] = $category;
+            } else {
+                $children[] = $category;
+            }
+        }
+        
+        // Sort parents alphabetically
+        usort($parents, function($a, $b) {
+            return strcmp($a->name, $b->name);
+        });
+        
+        // Recursively add children after their parents
+        $sorted = array();
+        foreach ($parents as $parent) {
+            $sorted[] = $parent;
+            $sorted = array_merge($sorted, $this->get_children_recursive($parent->term_id, $children));
+        }
+        
+        // Add any orphaned children (categories with non-existent parents)
+        foreach ($children as $child) {
+            if (!$this->is_child_added($child, $sorted)) {
+                $sorted[] = $child;
+            }
+        }
+        
+        return $sorted;
+    }
+    
+    /**
+     * Recursively get children of a category
+     * 
+     * @param int $parent_id Parent category ID
+     * @param array $all_children Array of all child categories
+     * @return array Array of child categories
+     */
+    private function get_children_recursive($parent_id, $all_children) {
+        $result = array();
+        $direct_children = array();
+        
+        // Find direct children of this parent
+        foreach ($all_children as $child) {
+            if ($child->parent == $parent_id) {
+                $direct_children[] = $child;
+            }
+        }
+        
+        // Sort direct children alphabetically
+        usort($direct_children, function($a, $b) {
+            return strcmp($a->name, $b->name);
+        });
+        
+        // Add each child and its descendants
+        foreach ($direct_children as $child) {
+            $result[] = $child;
+            $result = array_merge($result, $this->get_children_recursive($child->term_id, $all_children));
+        }
+        
+        return $result;
+    }
+    
+    /**
+     * Check if a child category has already been added to the sorted array
+     * 
+     * @param WP_Term $child Child category to check
+     * @param array $sorted Array of already sorted categories
+     * @return bool True if child is already in sorted array
+     */
+    private function is_child_added($child, $sorted) {
+        foreach ($sorted as $category) {
+            if ($category->term_id == $child->term_id) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
     /**
      * Format category data
      * 
@@ -68,27 +163,44 @@ class Studiou_WC_Product_Cat_Manage_DB {
             $display_type = 'default';
         }
         
-        // Get protected category data using direct DB access
+        // Get protected category data if available
         $visibility = 'public';
         $protected_passwords = '';
         
-        // Get visibility directly from term meta
-        $visibility_meta = get_term_meta($category->term_id, 'visibility', true);
-        if (!empty($visibility_meta)) {
-            $visibility = $visibility_meta;
-        }
-        
-        // If protected, get passwords directly from term meta
-        if ($visibility === 'protected') {
-            $passwords = get_term_meta($category->term_id, 'password', false);
-            if (!empty($passwords)) {
-                // Handle different password storage formats
-                if (is_array($passwords[0])) {
-                    $passwords = $passwords[0];
+        if (class_exists('WC_Protected_Categories')) {
+            // Use Util class to get category visibility info
+            $term_id = $category->term_id;
+            
+            // Use the plugin's own method to get visibility data if available
+            if (class_exists('\\Barn2\\Plugin\\WC_Protected_Categories\\Util')) {
+                $visibility_obj = \Barn2\Plugin\WC_Protected_Categories\Util::get_category_visibility($term_id);
+                if ($visibility_obj) {
+                    $visibility = $visibility_obj->get_visibility();
+                    
+                    if ($visibility === 'protected' && $visibility_obj->has_password_protection()) {
+                        // Get passwords using the plugin's own method
+                        $passwords = \Barn2\Plugin\WC_Protected_Categories\Util::get_term_passwords($term_id);
+                        if (!empty($passwords)) {
+                            $protected_passwords = implode('|', $passwords);
+                        }
+                    }
+                }
+            } else {
+                // Fallback to direct meta access if plugin class not available
+                $visibility = get_term_meta($term_id, 'visibility', true);
+                if (empty($visibility)) {
+                    $visibility = 'public';
                 }
                 
-                if (!empty($passwords)) {
-                    $protected_passwords = implode('|', $passwords);
+                if ($visibility === 'protected') {
+                    $passwords = get_term_meta($term_id, 'password', false);
+                    if ($passwords && !empty($passwords[0]) && is_array($passwords[0])) {
+                        $passwords = $passwords[0];
+                    }
+                    
+                    if (!empty($passwords)) {
+                        $protected_passwords = implode('|', $passwords);
+                    }
                 }
             }
         }
@@ -184,8 +296,26 @@ class Studiou_WC_Product_Cat_Manage_DB {
         // Set display type
         update_term_meta($term_id, 'display_type', $category_data['display-type']);
         
-        // Set visibility and password protection using direct DB access
-        $this->set_category_protection($term_id, $category_data);
+        // Set visibility and password protection if WC Protected Categories is active
+        if (class_exists('WC_Protected_Categories')) {
+            // Set visibility - ensure the "visibility" meta key is used (not wc_protected_categories_visibility)
+            update_term_meta($term_id, 'visibility', $category_data['visibility']);
+            
+            // Set password protection if visibility is protected and passwords are provided
+            if ($category_data['visibility'] === 'protected' && !empty($category_data['protected-passwords'])) {
+                $passwords = explode('|', $category_data['protected-passwords']);
+                // Filter out empty passwords
+                $passwords = array_filter($passwords);
+                
+                if (empty($passwords)) {
+                    // If no valid passwords after filtering, set a default one as the plugin does
+                    $passwords = ['password123'];
+                }
+                
+                // Store the passwords array as a single meta entry
+                add_term_meta($term_id, 'password', $passwords);
+            }
+        }
         
         return array(
             'status' => 'created',
@@ -251,8 +381,31 @@ class Studiou_WC_Product_Cat_Manage_DB {
         // Set display type
         update_term_meta($existing->term_id, 'display_type', $category_data['display-type']);
         
-        // Set visibility and password protection using direct DB access
-        $this->set_category_protection($existing->term_id, $category_data);
+        // Set visibility and password protection if WC Protected Categories is active
+        if (class_exists('WC_Protected_Categories')) {
+            // First remove existing protection meta
+            delete_term_meta($existing->term_id, 'password');
+            delete_term_meta($existing->term_id, 'user_roles');
+            delete_term_meta($existing->term_id, 'users');
+            
+            // Set visibility - ensure the "visibility" meta key is used
+            update_term_meta($existing->term_id, 'visibility', $category_data['visibility']);
+            
+            // Set password protection if visibility is protected and passwords are provided
+            if ($category_data['visibility'] === 'protected' && !empty($category_data['protected-passwords'])) {
+                $passwords = explode('|', $category_data['protected-passwords']);
+                // Filter out empty passwords
+                $passwords = array_filter($passwords);
+                
+                if (empty($passwords)) {
+                    // If no valid passwords after filtering, set a default one as the plugin does
+                    $passwords = ['password123'];
+                }
+                
+                // Store the passwords array as a single meta entry
+                add_term_meta($existing->term_id, 'password', $passwords);
+            }
+        }
         
         return array(
             'status' => 'updated',
@@ -300,34 +453,4 @@ class Studiou_WC_Product_Cat_Manage_DB {
             )
         );
     }
-    
-    /**
-     * Set category protection settings
-     * 
-     * @param int $term_id Term ID
-     * @param array $category_data Category data
-     */
-    private function set_category_protection($term_id, $category_data) {
-        // First remove existing protection meta to avoid duplicates
-        delete_term_meta($term_id, 'password');
-        delete_term_meta($term_id, 'visibility');
-        
-        // Set visibility
-        update_term_meta($term_id, 'visibility', $category_data['visibility']);
-        
-        // Set password protection if visibility is protected and passwords are provided
-        if ($category_data['visibility'] === 'protected' && !empty($category_data['protected-passwords'])) {
-            $passwords = explode('|', $category_data['protected-passwords']);
-            // Filter out empty passwords
-            $passwords = array_filter($passwords);
-            
-            if (empty($passwords)) {
-                // If no valid passwords after filtering, set a default one
-                $passwords = ['password123'];
-            }
-            
-            // Store the passwords array as a single meta entry
-            add_term_meta($term_id, 'password', $passwords);
-        }
-    }
-}
+}