فهرست منبع

add studiou-wc-product-cat-manage

Dalibor Votruba 1 سال پیش
والد
کامیت
59d5fe3d6c

+ 88 - 0
studiou-wc-product-cat-manage/assets/css/admin.css

@@ -0,0 +1,88 @@
+/**
+ * Admin styles for Studiou WC Product Category Manager
+ */
+
+.studiou-wcpcm-wrap {
+    max-width: 1200px;
+    margin: 20px 0;
+}
+
+.studiou-wcpcm-card {
+    background: #fff;
+    border: 1px solid #ccd0d4;
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
+    padding: 20px;
+    margin-bottom: 20px;
+    border-radius: 4px;
+}
+
+.studiou-wcpcm-notice-area {
+    margin-bottom: 20px;
+}
+
+.studiou-wcpcm-notice {
+    padding: 10px 15px;
+    margin: 0 0 15px;
+    border-left: 4px solid #00a0d2;
+    background: #fff;
+    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
+    position: relative;
+}
+
+.studiou-wcpcm-notice.studiou-wcpcm-notice-error {
+    border-left-color: #dc3232;
+}
+
+.studiou-wcpcm-notice.studiou-wcpcm-notice-success {
+    border-left-color: #46b450;
+}
+
+#studiou-wcpcm-import-form .form-field,
+#studiou-wcpcm-export-form .form-field {
+    margin-bottom: 15px;
+}
+
+#studiou-wcpcm-import-form label,
+#studiou-wcpcm-export-form label {
+    display: block;
+    margin-bottom: 5px;
+    font-weight: 600;
+}
+
+#studiou-wcpcm-import-form input[type="file"] {
+    padding: 8px 0;
+}
+
+.submit-buttons {
+    margin-top: 20px;
+    display: flex;
+    align-items: center;
+}
+
+.submit-buttons .spinner {
+    float: none;
+    margin-left: 10px;
+}
+
+.studiou-wcpcm-import-results,
+.studiou-wcpcm-export-results {
+    margin-top: 30px;
+    padding-top: 20px;
+    border-top: 1px solid #eee;
+}
+
+.studiou-wcpcm-import-results pre,
+.studiou-wcpcm-sample-csv pre {
+    background: #f6f7f7;
+    padding: 15px;
+    border: 1px solid #ddd;
+    border-radius: 3px;
+    overflow: auto;
+    font-family: monospace;
+    white-space: pre;
+    max-height: 300px;
+}
+
+.studiou-wcpcm-sample-csv pre {
+    max-height: 150px;
+}

+ 172 - 0
studiou-wc-product-cat-manage/assets/js/admin.js

@@ -0,0 +1,172 @@
+/**
+ * Admin JavaScript for Studiou WC Product Category Manager
+ */
+(function($) {
+    'use strict';
+    
+    // Initialize admin scripts
+    $(document).ready(function() {
+        // Import form handling
+        if ($('#studiou-wcpcm-import-form').length) {
+            initImportForm();
+        }
+        
+        // Export form handling
+        if ($('#studiou-wcpcm-export-form').length) {
+            initExportForm();
+        }
+        
+        // Sample CSV download handler
+        if ($('#studiou-wcpcm-download-sample').length) {
+            initSampleDownload();
+        }
+    });
+    
+    /**
+     * Initialize import form
+     */
+    function initImportForm() {
+        $('#studiou-wcpcm-import-form').on('submit', function(e) {
+            e.preventDefault();
+            
+            // Show spinner
+            var $submitBtn = $(this).find('#studiou-wcpcm-import-button');
+            var $spinner = $(this).find('.spinner');
+            
+            $submitBtn.prop('disabled', true);
+            $spinner.css('visibility', 'visible');
+            
+            // Clear previous notices
+            $('.studiou-wcpcm-notice-area').empty();
+            
+            // Create form data
+            var formData = new FormData(this);
+            formData.append('action', 'studiou_wcpcm_import');
+            formData.append('nonce', studiouWcpcm.nonce);
+            
+            // Send AJAX request
+            $.ajax({
+                url: studiouWcpcm.ajaxUrl,
+                type: 'POST',
+                data: formData,
+                processData: false,
+                contentType: false,
+                success: function(response) {
+                    if (response.success) {
+                        showNotice('success', studiouWcpcm.i18n.importSuccess);
+                        
+                        // Show results
+                        $('#studiou-wcpcm-import-results').text(response.data.message);
+                        $('.studiou-wcpcm-import-results').show();
+                    } else {
+                        showNotice('error', response.data.message);
+                    }
+                },
+                error: function() {
+                    showNotice('error', studiouWcpcm.i18n.importError);
+                },
+                complete: function() {
+                    // Hide spinner
+                    $submitBtn.prop('disabled', false);
+                    $spinner.css('visibility', 'hidden');
+                }
+            });
+        });
+    }
+    
+    /**
+     * Initialize export form
+     */
+    function initExportForm() {
+        $('#studiou-wcpcm-export-form').on('submit', function(e) {
+            e.preventDefault();
+            
+            // Show spinner
+            var $submitBtn = $(this).find('#studiou-wcpcm-export-button');
+            var $spinner = $(this).find('.spinner');
+            
+            $submitBtn.prop('disabled', true);
+            $spinner.css('visibility', 'visible');
+            
+            // Clear previous notices
+            $('.studiou-wcpcm-notice-area').empty();
+            
+            // Send AJAX request
+            $.ajax({
+                url: studiouWcpcm.ajaxUrl,
+                type: 'POST',
+                data: {
+                    action: 'studiou_wcpcm_export',
+                    nonce: studiouWcpcm.nonce
+                },
+                success: function(response) {
+                    if (response.success) {
+                        showNotice('success', studiouWcpcm.i18n.exportSuccess);
+                        
+                        // Show download link
+                        $('#studiou-wcpcm-export-message').text(response.data.message);
+                        $('#studiou-wcpcm-download-export').attr('href', response.data.download_url);
+                        $('.studiou-wcpcm-export-results').show();
+                    } else {
+                        showNotice('error', response.data.message);
+                    }
+                },
+                error: function() {
+                    showNotice('error', studiouWcpcm.i18n.exportError);
+                },
+                complete: function() {
+                    // Hide spinner
+                    $submitBtn.prop('disabled', false);
+                    $spinner.css('visibility', 'hidden');
+                }
+            });
+        });
+    }
+    
+    /**
+     * Initialize sample CSV download
+     */
+    function initSampleDownload() {
+        $('#studiou-wcpcm-download-sample').on('click', function(e) {
+            e.preventDefault();
+            
+            // Sample CSV content
+            var csvContent = 'name,url-name,parent-name,description,display-type,visibility,protected-passwords,operation\n' +
+                '"Clothing","clothing","","Top quality clothing","default","public","","A"\n' +
+                '"Men","men","Clothing","Men\'s clothing","products","public","","A"\n' +
+                '"Women","women","Clothing","Women\'s clothing","products","protected","password123","A"\n' +
+                '"Kids","kids","Clothing","Kids clothing","products","public","","U"\n' +
+                '"Accessories","accessories","","All accessories","default","public","","D"';
+            
+            // Create download link
+            var blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
+            var url = URL.createObjectURL(blob);
+            var link = document.createElement('a');
+            
+            link.setAttribute('href', url);
+            link.setAttribute('download', 'sample-product-categories.csv');
+            link.style.visibility = 'hidden';
+            
+            document.body.appendChild(link);
+            link.click();
+            document.body.removeChild(link);
+        });
+    }
+    
+    /**
+     * Show notice message
+     * 
+     * @param {string} type Notice type (success, error)
+     * @param {string} message Notice message
+     */
+    function showNotice(type, message) {
+        var $notice = $('<div class="studiou-wcpcm-notice studiou-wcpcm-notice-' + type + '"></div>').text(message);
+        $('.studiou-wcpcm-notice-area').append($notice);
+        
+        // Scroll to notice
+        $('html, body').animate({
+            scrollTop: $('.studiou-wcpcm-notice-area').offset().top - 50
+        }, 500);
+    }
+    
+})(jQuery);

+ 316 - 0
studiou-wc-product-cat-manage/includes/class-studiou-wc-product-cat-manage-db.php

@@ -0,0 +1,316 @@
+<?php
+/**
+ * Database operations class
+ *
+ * Handles database operations related to product categories
+ *
+ * @since      1.0.0
+ * @package    Studiou_WC_Product_Cat_Manage
+ * @subpackage Studiou_WC_Product_Cat_Manage/includes
+ */
+
+// If this file is called directly, abort.
+if (!defined('WPINC')) {
+    die;
+}
+
+class Studiou_WC_Product_Cat_Manage_DB {
+    
+    /**
+     * Constructor
+     */
+    public function __construct() {
+    }
+    
+    /**
+     * Get all product categories
+     * 
+     * @return array Array of product categories with all required properties
+     */
+    public function get_all_product_categories() {
+        $args = array(
+            'taxonomy'   => 'product_cat',
+            'orderby'    => 'name',
+            'hide_empty' => false,
+        );
+        
+        $categories = get_terms($args);
+        $formatted_categories = array();
+        
+        if (!is_wp_error($categories)) {
+            foreach ($categories as $category) {
+                $formatted_categories[] = $this->format_category($category);
+            }
+        }
+        
+        return $formatted_categories;
+    }
+    
+    /**
+     * Format category data
+     * 
+     * @param object $category WP_Term object
+     * @return array Formatted category data
+     */
+    private function format_category($category) {
+        // Get parent category name
+        $parent_name = '';
+        if ($category->parent > 0) {
+            $parent = get_term($category->parent, 'product_cat');
+            if (!is_wp_error($parent)) {
+                $parent_name = $parent->name;
+            }
+        }
+        
+        // Get display type
+        $display_type = get_term_meta($category->term_id, 'display_type', true);
+        if (empty($display_type)) {
+            $display_type = 'default';
+        }
+        
+        // Get protected category data if available
+        $visibility = 'public';
+        $protected_passwords = '';
+        
+        if (class_exists('WC_Protected_Categories')) {
+            $visibility = get_term_meta($category->term_id, 'visibility', true);
+            if (empty($visibility)) {
+                $visibility = 'public';
+            }
+            
+            if ($visibility === 'protected') {
+                // Get password protection
+                $passwords = get_term_meta($category->term_id, 'password', true);
+                if (!empty($passwords) && is_array($passwords)) {
+                    $protected_passwords = implode('|', $passwords);
+                }
+            }
+        }
+        
+        return array(
+            'name' => $category->name,
+            'url-name' => $category->slug,
+            'parent-name' => $parent_name,
+            'description' => $category->description,
+            'display-type' => $display_type,
+            'visibility' => $visibility,
+            'protected-passwords' => $protected_passwords,
+            'operation' => 'U' // Default operation for existing categories
+        );
+    }
+    
+    /**
+     * Find category by name
+     * 
+     * @param string $name Category name
+     * @return WP_Term|null Category term object or null if not found
+     */
+    public function find_category_by_name($name) {
+        $args = array(
+            'taxonomy'   => 'product_cat',
+            'name'       => $name,
+            'hide_empty' => false,
+        );
+        
+        $categories = get_terms($args);
+        
+        if (!is_wp_error($categories) && !empty($categories)) {
+            return $categories[0];
+        }
+        
+        return null;
+    }
+    
+    /**
+     * Create product category
+     * 
+     * @param array $category_data Category data
+     * @return array Result with status and message
+     */
+    public function create_category($category_data) {
+        // Check if category already exists
+        $existing = $this->find_category_by_name($category_data['name']);
+        if ($existing) {
+            return array(
+                'status' => 'skipped',
+                'message' => sprintf(
+                    __("Product category '%s' already exists. Skipped.", 'studiou-wc-product-cat-manage'),
+                    $category_data['name']
+                )
+            );
+        }
+        
+        // Find parent category ID if parent name is provided
+        $parent_id = 0;
+        if (!empty($category_data['parent-name'])) {
+            $parent = $this->find_category_by_name($category_data['parent-name']);
+            if ($parent) {
+                $parent_id = $parent->term_id;
+            } else {
+                return array(
+                    'status' => 'error',
+                    'message' => sprintf(
+                        __("Parent category '%s' not found.", 'studiou-wc-product-cat-manage'),
+                        $category_data['parent-name']
+                    )
+                );
+            }
+        }
+        
+        // Create category
+        $args = array(
+            'description' => $category_data['description'],
+            'parent' => $parent_id,
+            'slug' => $category_data['url-name'],
+        );
+        
+        $result = wp_insert_term($category_data['name'], 'product_cat', $args);
+        
+        if (is_wp_error($result)) {
+            return array(
+                'status' => 'error',
+                'message' => $result->get_error_message()
+            );
+        }
+        
+        $term_id = $result['term_id'];
+        
+        // Set display type
+        update_term_meta($term_id, 'display_type', $category_data['display-type']);
+        
+        // Set visibility and password protection if WC Protected Categories is active
+        if (class_exists('WC_Protected_Categories')) {
+            update_term_meta($term_id, 'visibility', $category_data['visibility']);
+            
+            if ($category_data['visibility'] === 'protected' && !empty($category_data['protected-passwords'])) {
+                $passwords = explode('|', $category_data['protected-passwords']);
+                // Store passwords as an array
+                update_term_meta($term_id, 'password', $passwords);
+            }
+        }
+        
+        return array(
+            'status' => 'created',
+            'message' => sprintf(
+                __("Product category '%s' created.", 'studiou-wc-product-cat-manage'),
+                $category_data['name']
+            )
+        );
+    }
+    
+    /**
+     * Update product category
+     * 
+     * @param array $category_data Category data
+     * @return array Result with status and message
+     */
+    public function update_category($category_data) {
+        // Check if category exists
+        $existing = $this->find_category_by_name($category_data['name']);
+        if (!$existing) {
+            return array(
+                'status' => 'error',
+                'message' => sprintf(
+                    __("Product category '%s' not found.", 'studiou-wc-product-cat-manage'),
+                    $category_data['name']
+                )
+            );
+        }
+        
+        // Find parent category ID if parent name is provided
+        $parent_id = 0;
+        if (!empty($category_data['parent-name'])) {
+            $parent = $this->find_category_by_name($category_data['parent-name']);
+            if ($parent) {
+                $parent_id = $parent->term_id;
+            } else {
+                return array(
+                    'status' => 'error',
+                    'message' => sprintf(
+                        __("Parent category '%s' not found.", 'studiou-wc-product-cat-manage'),
+                        $category_data['parent-name']
+                    )
+                );
+            }
+        }
+        
+        // Update category
+        $args = array(
+            'description' => $category_data['description'],
+            'parent' => $parent_id,
+            'slug' => $category_data['url-name'],
+        );
+        
+        $result = wp_update_term($existing->term_id, 'product_cat', $args);
+        
+        if (is_wp_error($result)) {
+            return array(
+                'status' => 'error',
+                'message' => $result->get_error_message()
+            );
+        }
+        
+        // Set display type
+        update_term_meta($existing->term_id, 'display_type', $category_data['display-type']);
+        
+        // Set visibility and password protection if WC Protected Categories is active
+        if (class_exists('WC_Protected_Categories')) {
+            update_term_meta($existing->term_id, 'visibility', $category_data['visibility']);
+            
+            if ($category_data['visibility'] === 'protected' && !empty($category_data['protected-passwords'])) {
+                $passwords = explode('|', $category_data['protected-passwords']);
+                // Store passwords as an array
+                update_term_meta($existing->term_id, 'password', $passwords);
+            } else {
+                // Remove passwords if visibility is not protected
+                delete_term_meta($existing->term_id, 'password');
+            }
+        }
+        
+        return array(
+            'status' => 'updated',
+            'message' => sprintf(
+                __("Product category '%s' updated.", 'studiou-wc-product-cat-manage'),
+                $category_data['name']
+            )
+        );
+    }
+    
+    /**
+     * Delete product category
+     * 
+     * @param string $category_name Category name
+     * @return array Result with status and message
+     */
+    public function delete_category($category_name) {
+        // Check if category exists
+        $existing = $this->find_category_by_name($category_name);
+        if (!$existing) {
+            return array(
+                'status' => 'error',
+                'message' => sprintf(
+                    __("Product category '%s' not found.", 'studiou-wc-product-cat-manage'),
+                    $category_name
+                )
+            );
+        }
+        
+        // Delete category
+        $result = wp_delete_term($existing->term_id, 'product_cat');
+        
+        if (is_wp_error($result)) {
+            return array(
+                'status' => 'error',
+                'message' => $result->get_error_message()
+            );
+        }
+        
+        return array(
+            'status' => 'deleted',
+            'message' => sprintf(
+                __("Product category '%s' deleted.", 'studiou-wc-product-cat-manage'),
+                $category_name
+            )
+        );
+    }
+}

+ 186 - 0
studiou-wc-product-cat-manage/includes/class-studiou-wc-product-cat-manage-export.php

@@ -0,0 +1,186 @@
+<?php
+/**
+ * Export class
+ *
+ * Handles exporting product categories to CSV
+ *
+ * @since      1.0.0
+ * @package    Studiou_WC_Product_Cat_Manage
+ * @subpackage Studiou_WC_Product_Cat_Manage/includes
+ */
+
+// If this file is called directly, abort.
+if (!defined('WPINC')) {
+    die;
+}
+
+class Studiou_WC_Product_Cat_Manage_Export {
+    
+    /**
+     * Database handler
+     *
+     * @var Studiou_WC_Product_Cat_Manage_DB
+     */
+    private $db;
+    
+    /**
+     * Constructor
+     *
+     * @param Studiou_WC_Product_Cat_Manage_DB $db Database handler
+     */
+    public function __construct($db) {
+        $this->db = $db;
+        
+        // Register AJAX handlers
+        add_action('wp_ajax_studiou_wcpcm_export', array($this, 'handle_export_ajax'));
+        
+        // Add download handler
+        add_action('admin_init', array($this, 'handle_export_download'));
+    }
+    
+    /**
+     * Handle AJAX export request
+     */
+    public function handle_export_ajax() {
+        // Check nonce
+        if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'studiou-wcpcm-nonce')) {
+            wp_send_json_error(array(
+                'message' => __('Security check failed', 'studiou-wc-product-cat-manage')
+            ));
+        }
+        
+        // Check permissions
+        if (!current_user_can('manage_woocommerce')) {
+            wp_send_json_error(array(
+                'message' => __('You do not have sufficient permissions', 'studiou-wc-product-cat-manage')
+            ));
+        }
+        
+        try {
+            // Generate export file
+            $filename = $this->generate_export_file();
+            
+            // Return success response
+            wp_send_json_success(array(
+                'message' => __('Product categories exported successfully', 'studiou-wc-product-cat-manage'),
+                'download_url' => admin_url('edit.php?post_type=product&page=studiou-export-product-categories&action=download&nonce=' . wp_create_nonce('studiou-wcpcm-export-download'))
+            ));
+        } catch (Exception $e) {
+            wp_send_json_error(array(
+                'message' => $e->getMessage()
+            ));
+        }
+    }
+    
+    /**
+     * Handle export download
+     */
+    public function handle_export_download() {
+        if (!isset($_GET['page']) || $_GET['page'] !== 'studiou-export-product-categories' || 
+            !isset($_GET['action']) || $_GET['action'] !== 'download' || 
+            !isset($_GET['nonce']) || !wp_verify_nonce($_GET['nonce'], 'studiou-wcpcm-export-download')) {
+            return;
+        }
+        
+        // Check permissions
+        if (!current_user_can('manage_woocommerce')) {
+            wp_die(__('You do not have sufficient permissions', 'studiou-wc-product-cat-manage'));
+        }
+        
+        $uploads_dir = wp_upload_dir();
+        $export_dir = trailingslashit($uploads_dir['basedir']) . 'studiou-wcpcm-exports/';
+        $filename = $export_dir . 'product-categories-export.csv';
+        
+        if (!file_exists($filename)) {
+            wp_die(__('Export file not found. Please try exporting again.', 'studiou-wc-product-cat-manage'));
+        }
+        
+        // Set headers for download
+        header('Content-Type: text/csv; charset=utf-8');
+        header('Content-Disposition: attachment; filename=product-categories-export-' . date('Y-m-d') . '.csv');
+        header('Pragma: no-cache');
+        header('Expires: 0');
+        
+        // Output file content
+        readfile($filename);
+        exit;
+    }
+    
+    /**
+     * Generate export file
+     *
+     * @return string Path to the generated file
+     * @throws Exception On error
+     */
+    public function generate_export_file() {
+        // Create export directory if it doesn't exist
+        $uploads_dir = wp_upload_dir();
+        $export_dir = trailingslashit($uploads_dir['basedir']) . 'studiou-wcpcm-exports/';
+        
+        if (!file_exists($export_dir)) {
+            wp_mkdir_p($export_dir);
+            
+            // Create an index.php file to prevent directory listing
+            file_put_contents($export_dir . 'index.php', '<?php // Silence is golden');
+        }
+        
+        // Get all categories
+        $categories = $this->db->get_all_product_categories();
+        
+        // Define CSV headers
+        $headers = array(
+            'name',
+            'url-name',
+            'parent-name',
+            'description',
+            'display-type',
+            'visibility',
+            'protected-passwords',
+            'operation'
+        );
+        
+        // Generate CSV content
+        $csv_content = $this->generate_csv($headers, $categories);
+        
+        // Save to file
+        $filename = $export_dir . 'product-categories-export.csv';
+        $result = file_put_contents($filename, $csv_content);
+        
+        if (false === $result) {
+            throw new Exception(__('Failed to write export file', 'studiou-wc-product-cat-manage'));
+        }
+        
+        return $filename;
+    }
+    
+    /**
+     * Generate CSV content
+     *
+     * @param array $headers CSV headers
+     * @param array $data Data rows
+     * @return string CSV content
+     */
+    private function generate_csv($headers, $data) {
+        $output = fopen('php://temp', 'r+');
+        
+        // Add headers
+        fputcsv($output, $headers);
+        
+        // Add data rows
+        foreach ($data as $row) {
+            // Ensure all headers are present in the row
+            $csv_row = array();
+            foreach ($headers as $header) {
+                $csv_row[] = isset($row[$header]) ? $row[$header] : '';
+            }
+            
+            fputcsv($output, $csv_row);
+        }
+        
+        rewind($output);
+        $csv_content = stream_get_contents($output);
+        fclose($output);
+        
+        return $csv_content;
+    }
+}

+ 315 - 0
studiou-wc-product-cat-manage/includes/class-studiou-wc-product-cat-manage-import.php

@@ -0,0 +1,315 @@
+<?php
+/**
+ * Import class
+ *
+ * Handles importing product categories from CSV
+ *
+ * @since      1.0.0
+ * @package    Studiou_WC_Product_Cat_Manage
+ * @subpackage Studiou_WC_Product_Cat_Manage/includes
+ */
+
+// If this file is called directly, abort.
+if (!defined('WPINC')) {
+    die;
+}
+
+class Studiou_WC_Product_Cat_Manage_Import {
+    
+    /**
+     * Database handler
+     *
+     * @var Studiou_WC_Product_Cat_Manage_DB
+     */
+    private $db;
+    
+    /**
+     * Required CSV headers
+     *
+     * @var array
+     */
+    private $required_headers = array(
+        'name',
+        'url-name',
+        'parent-name',
+        'description',
+        'display-type',
+        'visibility',
+        'protected-passwords',
+        'operation'
+    );
+    
+    /**
+     * Valid display types
+     *
+     * @var array
+     */
+    private $valid_display_types = array(
+        'default',
+        'products',
+        'subcategories',
+        'both'
+    );
+    
+    /**
+     * Valid visibility values
+     *
+     * @var array
+     */
+    private $valid_visibility = array(
+        'public',
+        'protected'
+    );
+    
+    /**
+     * Valid operation values
+     *
+     * @var array
+     */
+    private $valid_operations = array(
+        'A', // Add
+        'U', // Update
+        'D'  // Delete
+    );
+    
+    /**
+     * Constructor
+     *
+     * @param Studiou_WC_Product_Cat_Manage_DB $db Database handler
+     */
+    public function __construct($db) {
+        $this->db = $db;
+        
+        // Register AJAX handler
+        add_action('wp_ajax_studiou_wcpcm_import', array($this, 'handle_import_ajax'));
+    }
+    
+    /**
+     * Handle AJAX import request
+     */
+    public function handle_import_ajax() {
+        // Check nonce
+        if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'studiou-wcpcm-nonce')) {
+            wp_send_json_error(array(
+                'message' => __('Security check failed', 'studiou-wc-product-cat-manage')
+            ));
+        }
+        
+        // Check permissions
+        if (!current_user_can('manage_woocommerce')) {
+            wp_send_json_error(array(
+                'message' => __('You do not have sufficient permissions', 'studiou-wc-product-cat-manage')
+            ));
+        }
+        
+        // Check if file was uploaded
+        if (!isset($_FILES['import_file']) || empty($_FILES['import_file']['tmp_name'])) {
+            wp_send_json_error(array(
+                'message' => __('No file was uploaded', 'studiou-wc-product-cat-manage')
+            ));
+        }
+        
+        try {
+            // Process the uploaded file
+            $results = $this->process_import_file($_FILES['import_file']['tmp_name']);
+            
+            // Generate response message
+            $message = $this->generate_import_results_message($results);
+            
+            // Return success response
+            wp_send_json_success(array(
+                'message' => $message
+            ));
+        } catch (Exception $e) {
+            wp_send_json_error(array(
+                'message' => sprintf(
+                    __('Import error: %s', 'studiou-wc-product-cat-manage'),
+                    $e->getMessage()
+                )
+            ));
+        }
+    }
+    
+    /**
+     * Process import file
+     *
+     * @param string $file_path Path to uploaded CSV file
+     * @return array Import results
+     * @throws Exception On validation or processing error
+     */
+    private function process_import_file($file_path) {
+        // Open file
+        $file = fopen($file_path, 'r');
+        if (!$file) {
+            throw new Exception(__('Failed to open the uploaded file', 'studiou-wc-product-cat-manage'));
+        }
+        
+        // Read headers
+        $headers = fgetcsv($file);
+        if (!$headers) {
+            fclose($file);
+            throw new Exception(__('Failed to read CSV headers', 'studiou-wc-product-cat-manage'));
+        }
+        
+        // Validate headers
+        $this->validate_headers($headers);
+        
+        // Process rows
+        $results = array();
+        $row_number = 1; // Header row is 1
+        
+        while (($row = fgetcsv($file)) !== false) {
+            $row_number++;
+            
+            try {
+                // Map row data to associative array
+                $category_data = array();
+                foreach ($headers as $index => $header) {
+                    $category_data[$header] = isset($row[$index]) ? $row[$index] : '';
+                }
+                
+                // Validate row data
+                $this->validate_row_data($category_data, $row_number);
+                
+                // Process based on operation
+                $operation = strtoupper(trim($category_data['operation']));
+                
+                switch ($operation) {
+                    case 'A':
+                        $result = $this->db->create_category($category_data);
+                        break;
+                    case 'U':
+                        $result = $this->db->update_category($category_data);
+                        break;
+                    case 'D':
+                        $result = $this->db->delete_category($category_data['name']);
+                        break;
+                    default:
+                        throw new Exception(sprintf(
+                            __('Invalid operation "%s" at row %d', 'studiou-wc-product-cat-manage'),
+                            $operation,
+                            $row_number
+                        ));
+                }
+                
+                $results[] = $result;
+            } catch (Exception $e) {
+                $results[] = array(
+                    'status' => 'error',
+                    'message' => sprintf(
+                        __('Error at row %d: %s', 'studiou-wc-product-cat-manage'),
+                        $row_number,
+                        $e->getMessage()
+                    )
+                );
+            }
+        }
+        
+        fclose($file);
+        return $results;
+    }
+    
+    /**
+     * Validate CSV headers
+     *
+     * @param array $headers Headers from CSV
+     * @throws Exception If headers are invalid
+     */
+    private function validate_headers($headers) {
+        // Check that all required headers are present
+        foreach ($this->required_headers as $required_header) {
+            if (!in_array($required_header, $headers)) {
+                throw new Exception(sprintf(
+                    __('Missing required header: %s', 'studiou-wc-product-cat-manage'),
+                    $required_header
+                ));
+            }
+        }
+    }
+    
+    /**
+     * Validate row data
+     *
+     * @param array $data Row data
+     * @param int $row_number Row number for error messages
+     * @throws Exception If data is invalid
+     */
+    private function validate_row_data($data, $row_number) {
+        // Check required fields based on operation
+        $operation = strtoupper(trim($data['operation']));
+        
+        if (!in_array($operation, $this->valid_operations)) {
+            throw new Exception(sprintf(
+                __('Invalid operation "%s" at row %d. Must be one of: A, U, D', 'studiou-wc-product-cat-manage'),
+                $operation,
+                $row_number
+            ));
+        }
+        
+        // Check name is required for all operations
+        if (empty($data['name'])) {
+            throw new Exception(sprintf(
+                __('Missing required field "name" at row %d', 'studiou-wc-product-cat-manage'),
+                $row_number
+            ));
+        }
+        
+        // Additional validations for Add and Update operations
+        if ($operation === 'A' || $operation === 'U') {
+            // URL name is required
+            if (empty($data['url-name'])) {
+                throw new Exception(sprintf(
+                    __('Missing required field "url-name" at row %d', 'studiou-wc-product-cat-manage'),
+                    $row_number
+                ));
+            }
+            
+            // Validate display type
+            if (!empty($data['display-type']) && !in_array($data['display-type'], $this->valid_display_types)) {
+                throw new Exception(sprintf(
+                    __('Invalid display type "%s" at row %d. Must be one of: default, products, subcategories, both', 'studiou-wc-product-cat-manage'),
+                    $data['display-type'],
+                    $row_number
+                ));
+            }
+            
+            // Validate visibility
+            if (!empty($data['visibility']) && !in_array($data['visibility'], $this->valid_visibility)) {
+                throw new Exception(sprintf(
+                    __('Invalid visibility "%s" at row %d. Must be one of: public, protected', 'studiou-wc-product-cat-manage'),
+                    $data['visibility'],
+                    $row_number
+                ));
+            }
+            
+            // If visibility is protected, passwords are required
+            if ($data['visibility'] === 'protected' && empty($data['protected-passwords'])) {
+                throw new Exception(sprintf(
+                    __('Protected visibility requires at least one password at row %d', 'studiou-wc-product-cat-manage'),
+                    $row_number
+                ));
+            }
+        }
+    }
+    
+    /**
+     * Generate import results message
+     *
+     * @param array $results Import results
+     * @return string Formatted message
+     */
+    private function generate_import_results_message($results) {
+        if (empty($results)) {
+            return __('No items were processed.', 'studiou-wc-product-cat-manage');
+        }
+        
+        $count = count($results);
+        $message = sprintf(__('Imported %d items:', 'studiou-wc-product-cat-manage'), $count) . "\n";
+        
+        foreach ($results as $result) {
+            $message .= '    ' . $result['message'] . "\n";
+        }
+        
+        return $message;
+    }
+}

+ 56 - 0
studiou-wc-product-cat-manage/instructions.txt

@@ -0,0 +1,56 @@
+Write WordPress plugin called "studiou-wc-product-cat-manage" in PHP, that extends WooCommerce plugin.
+Plugin will have following features:
+
+1. Allows to create batch export and import of Product Categories.
+2. Export and import data will be .csv file with following columns:
+	name					- Product Category Name
+	url-name				- Product Category url part name (slug)
+	parent-name				- Reference to parent Product Category Name (If has no parrent, value is empty)
+	description				- Product Category description
+	display-type			- Product Category display type (values: 'default', 'products', 'subcategories', 'both') 
+	visibility				- Product Category visibility according to WooCommerce Protected Categories plugin (values: 'public', 'protected')
+	protected-passwords		- Product Category visibility according to WooCommerce Protected Categories plugin if 'visibility' column is set to protected. Defines pipe (|) separated values of passwords for current settings
+	operation				- Record operation, 'A' - means add new record, 'D' - remove record (identification is 'name' column), 'U' - update record (identification is 'name' column) 
+
+	Columns 'name', 'url-name', 'parent-name', 'description', 'display-type' are native WooCommerce product category properties. Columns 'visibility' and 'protected-passwords' are properties of WooCommerce Protected Categories plugin (extended)
+	
+	.csv file separator is comma ',' changacter. String values is isolated between quotation mark '"', means if inside quotation mark is comma, comma is not separator. Encoding of import and export file is UTF-8.
+
+
+2. Extends Products menu for items "Import product categories" and "Export product categories". In "Import product categories" there will be button for file selection and second button "Import product categories". When I press this button Import will be processed. After import operation imformation will be shown as follows (sample):
+
+	Imported 5 items:
+		Product category 'Item 0' already exists. Skiped.
+		Product category 'Item 1' created
+		Product category 'Item 2' created
+		Product category 'Item 3' created
+		Product category 'Item 4' updated
+		Product category 'Item 5' deleted
+		Product category 'Item 6' not found.
+
+	or when error as follows (sample):
+	
+	Import error:
+		Null reference exception
+	
+
+3. Plugin requires following plugins:
+	WooCommerce minimal version 9.7
+	WooCommerce Protected Categories minimal version 2.7
+	
+3. Plugin will have following header:
+
+/**
+ * Plugin Name: QDR - Studiou WC Export/Import Product Categories
+ * Plugin URI: https://www.quadarax.com/plugins/studiou-wc-product-cat-manage
+ * Description: Allows batch import and export WooCommerce product categories
+ * Version: 1.0
+ * Requires at least: 6.7.2
+ * Requires PHP: 8.2
+ * Author: Dalibor Votruba
+ * Author URI: https://www.quadarax.com
+ * License: GPL v2 or later
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
+ * Text Domain: studiou-wc-product-cat-manage
+ * Domain Path: /languages
+ */

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

@@ -0,0 +1,95 @@
+# QDR - Studiou WC Export/Import Product Categories
+
+**Version: 1.0**
+
+A WordPress plugin that extends WooCommerce to provide batch export and import functionality for product categories.
+
+## Description
+
+QDR - Studiou WC Export/Import Product Categories is a powerful WordPress plugin for WooCommerce store administrators who need to manage product categories in bulk. This plugin allows you to export your existing product categories to a CSV file, make modifications, and import them back into your store.
+
+The plugin also supports the WooCommerce Protected Categories extension, allowing you to manage visibility settings and passwords for your product categories.
+
+## Features
+
+- Export all product categories to a CSV file
+- Import product categories from a CSV file
+- Add, update, or delete product categories in batch
+- Support for WooCommerce Protected Categories visibility settings
+- User-friendly interface integrated with WooCommerce admin
+- Comprehensive validation and error reporting
+
+## Requirements
+
+- WordPress 6.7.2 or higher
+- PHP 8.2 or higher
+- WooCommerce 9.7 or higher
+- WooCommerce Protected Categories 2.7 or higher
+
+## Installation
+
+1. Download the plugin ZIP file
+2. Go to WordPress Dashboard > Plugins > Add New
+3. Click "Upload Plugin" and select the ZIP file
+4. Click "Install Now"
+5. Activate the plugin
+
+## CSV Format
+
+The plugin uses CSV files with the following columns:
+
+| Column | Description |
+|--------|-------------|
+| name | Product Category Name |
+| url-name | Product Category URL slug |
+| parent-name | Parent Product Category Name (empty if no parent) |
+| description | Product Category description |
+| display-type | Product Category display type (values: 'default', 'products', 'subcategories', 'both') |
+| visibility | Product Category visibility (values: 'public', 'protected') |
+| protected-passwords | Pipe (&#124;) separated passwords if visibility is 'protected' |
+| operation | Record operation: 'A' - add, 'U' - update, 'D' - delete |
+
+## Usage
+
+### Exporting Product Categories
+
+1. Go to Products > Export Product Categories
+2. Click "Export Product Categories"
+3. Download the generated CSV file
+
+### Importing Product Categories
+
+1. Go to Products > Import Product Categories
+2. Select your CSV file
+3. Click "Import Product Categories"
+4. Review the import results
+
+## Sample CSV
+
+```
+name,url-name,parent-name,description,display-type,visibility,protected-passwords,operation
+"Clothing","clothing","","Top quality clothing","default","public","","A"
+"Men","men","Clothing","Men's clothing","products","public","","A"
+"Women","women","Clothing","Women's clothing","products","protected","password123","A"
+"Kids","kids","Clothing","Kids clothing","products","public","","U"
+"Accessories","accessories","","All accessories","default","public","","D"
+```
+
+## Import Operations
+
+- `A` - Add a new product category
+- `U` - Update an existing product category (identified by name)
+- `D` - Delete an existing product category (identified by name)
+
+## License
+
+GPL v2 or later - https://www.gnu.org/licenses/gpl-2.0.html
+
+## Author
+
+Dalibor Votruba  
+Website: [Quadarax](https://www.quadarax.com)
+
+## Support
+
+For support, please visit [https://www.quadarax.com/plugins/studiou-wc-product-cat-manage](https://www.quadarax.com/plugins/studiou-wc-product-cat-manage)

+ 215 - 0
studiou-wc-product-cat-manage/studiou-wc-product-cat-manage.php

@@ -0,0 +1,215 @@
+<?php
+/**
+ * Plugin Name: QDR - Studiou WC Export/Import Product Categories
+ * Plugin URI: https://www.quadarax.com/plugins/studiou-wc-product-cat-manage
+ * Description: Allows batch import and export WooCommerce product categories
+ * Version: 1.0
+ * Requires at least: 6.7.2
+ * Requires PHP: 8.2
+ * Author: Dalibor Votruba
+ * Author URI: https://www.quadarax.com
+ * License: GPL v2 or later
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
+ */
+
+// If this file is called directly, abort.
+if (!defined('WPINC')) {
+    die;
+}
+
+// Define plugin constants
+define('STUDIOU_WCPCM_VERSION', '1.0');
+define('STUDIOU_WCPCM_PLUGIN_DIR', plugin_dir_path(__FILE__));
+define('STUDIOU_WCPCM_PLUGIN_URL', plugin_dir_url(__FILE__));
+define('STUDIOU_WCPCM_PLUGIN_BASENAME', plugin_basename(__FILE__));
+
+/**
+ * Main plugin class
+ */
+class Studiou_WC_Product_Cat_Manage {
+    
+    /**
+     * @var Studiou_WC_Product_Cat_Manage_Export
+     */
+    private $exporter;
+    
+    /**
+     * @var Studiou_WC_Product_Cat_Manage_Import
+     */
+    private $importer;
+    
+    /**
+     * @var Studiou_WC_Product_Cat_Manage_DB
+     */
+    private $db;
+    
+    /**
+     * Initialize the plugin
+     */
+    public function __construct() {
+        // Load dependencies
+        $this->load_dependencies();
+        
+        // Check required plugins
+        add_action('admin_init', array($this, 'check_required_plugins'));
+        
+        // Add admin menu items
+        add_action('admin_menu', array($this, 'add_admin_menu'), 99);
+        
+        // Register admin assets
+        add_action('admin_enqueue_scripts', array($this, 'register_admin_assets'));
+        
+        // Initialize components
+        $this->init_components();
+    }
+    
+    /**
+     * Load required dependencies
+     */
+    private function load_dependencies() {
+        require_once STUDIOU_WCPCM_PLUGIN_DIR . 'includes/class-studiou-wc-product-cat-manage-db.php';
+        require_once STUDIOU_WCPCM_PLUGIN_DIR . 'includes/class-studiou-wc-product-cat-manage-export.php';
+        require_once STUDIOU_WCPCM_PLUGIN_DIR . 'includes/class-studiou-wc-product-cat-manage-import.php';
+    }
+    
+    /**
+     * Initialize components
+     */
+    private function init_components() {
+        $this->db = new Studiou_WC_Product_Cat_Manage_DB();
+        $this->exporter = new Studiou_WC_Product_Cat_Manage_Export($this->db);
+        $this->importer = new Studiou_WC_Product_Cat_Manage_Import($this->db);
+    }
+    
+    /**
+     * Check if required plugins are active
+     */
+    public function check_required_plugins() {
+        if (!is_admin() || isset($_GET['activate-multi'])) {
+            return;
+        }
+        
+        // Check for WooCommerce
+        if (!class_exists('WooCommerce') || !defined('WC_VERSION') || version_compare(WC_VERSION, '9.7', '<')) {
+            add_action('admin_notices', array($this, 'woocommerce_missing_notice'));
+            deactivate_plugins(STUDIOU_WCPCM_PLUGIN_BASENAME);
+            if (isset($_GET['activate'])) {
+                unset($_GET['activate']);
+            }
+        }
+    }
+    
+    /**
+     * WooCommerce missing notice
+     */
+    public function woocommerce_missing_notice() {
+        ?>
+        <div class="error">
+            <p><?php echo sprintf(
+                __('QDR - Studiou WC Export/Import Product Categories requires WooCommerce version 9.7 or higher. Please %sinstall or update WooCommerce%s.', 'studiou-wc-product-cat-manage'),
+                '<a href="' . admin_url('plugin-install.php?s=woocommerce&tab=search&type=term') . '">',
+                '</a>'
+            ); ?></p>
+        </div>
+        <?php
+    }
+    
+    /**
+     * WooCommerce Protected Categories missing notice
+     */
+    public function wc_protected_categories_missing_notice() {
+        ?>
+        <div class="error">
+            <p><?php echo sprintf(
+                __('QDR - Studiou WC Export/Import Product Categories requires WooCommerce Protected Categories version 2.7 or higher. Please install or update WooCommerce Protected Categories.', 'studiou-wc-product-cat-manage')
+            ); ?></p>
+        </div>
+        <?php
+    }
+    
+    /**
+     * Add admin menu items
+     */
+    public function add_admin_menu() {
+        // Make sure WooCommerce menu exists
+        if (class_exists('WooCommerce')) {
+            add_submenu_page(
+                'edit.php?post_type=product',
+                __('Import Product Categories', 'studiou-wc-product-cat-manage'),
+                __('Import Product Categories', 'studiou-wc-product-cat-manage'),
+                'manage_woocommerce',
+                'studiou-import-product-categories',
+                array($this, 'render_import_page')
+            );
+            
+            add_submenu_page(
+                'edit.php?post_type=product',
+                __('Export Product Categories', 'studiou-wc-product-cat-manage'),
+                __('Export Product Categories', 'studiou-wc-product-cat-manage'),
+                'manage_woocommerce',
+                'studiou-export-product-categories',
+                array($this, 'render_export_page')
+            );
+        }
+    }
+    
+    /**
+     * Register admin assets
+     */
+    public function register_admin_assets($hook) {
+        if ('product_page_studiou-import-product-categories' === $hook || 
+            'product_page_studiou-export-product-categories' === $hook) {
+            
+            wp_enqueue_style(
+                'studiou-wcpcm-admin',
+                STUDIOU_WCPCM_PLUGIN_URL . 'assets/css/admin.css',
+                array(),
+                STUDIOU_WCPCM_VERSION
+            );
+            
+            wp_enqueue_script(
+                'studiou-wcpcm-admin',
+                STUDIOU_WCPCM_PLUGIN_URL . 'assets/js/admin.js',
+                array('jquery'),
+                STUDIOU_WCPCM_VERSION,
+                true
+            );
+            
+            wp_localize_script('studiou-wcpcm-admin', 'studiouWcpcm', array(
+                'ajaxUrl' => admin_url('admin-ajax.php'),
+                'nonce' => wp_create_nonce('studiou-wcpcm-nonce'),
+                'i18n' => array(
+                    'importSuccess' => __('Import successful', 'studiou-wc-product-cat-manage'),
+                    'importError' => __('Import error', 'studiou-wc-product-cat-manage'),
+                    'exportSuccess' => __('Export successful', 'studiou-wc-product-cat-manage'),
+                    'exportError' => __('Export error', 'studiou-wc-product-cat-manage'),
+                )
+            ));
+        }
+    }
+    
+    /**
+     * Render import page
+     */
+    public function render_import_page() {
+        include STUDIOU_WCPCM_PLUGIN_DIR . 'views/import.php';
+    }
+    
+    /**
+     * Render export page
+     */
+    public function render_export_page() {
+        include STUDIOU_WCPCM_PLUGIN_DIR . 'views/export.php';
+    }
+}
+
+/**
+ * Begin execution of the plugin
+ */
+function run_studiou_wc_product_cat_manage() {
+    // Create instance
+    new Studiou_WC_Product_Cat_Manage();
+}
+
+// Run the plugin
+run_studiou_wc_product_cat_manage();

+ 59 - 0
studiou-wc-product-cat-manage/views/export.php

@@ -0,0 +1,59 @@
+<?php
+/**
+ * Export page view
+ *
+ * @since      1.0.0
+ * @package    Studiou_WC_Product_Cat_Manage
+ */
+
+// If this file is called directly, abort.
+if (!defined('WPINC')) {
+    die;
+}
+?>
+
+<div class="wrap studiou-wcpcm-wrap">
+    <h1><?php echo esc_html__('Export Product Categories', 'studiou-wc-product-cat-manage'); ?></h1>
+    
+    <div class="studiou-wcpcm-notice-area">
+        <!-- Area for displaying notices -->
+    </div>
+    
+    <div class="studiou-wcpcm-card">
+        <h2><?php echo esc_html__('Export to CSV', 'studiou-wc-product-cat-manage'); ?></h2>
+        
+        <p><?php echo esc_html__('Export your product categories to a CSV file. The export will include all product categories with their properties.', 'studiou-wc-product-cat-manage'); ?></p>
+        
+        <p><?php echo esc_html__('The exported CSV file will have the following columns:', 'studiou-wc-product-cat-manage'); ?></p>
+        
+        <ul>
+            <li><strong>name</strong> - <?php echo esc_html__('Product Category Name', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>url-name</strong> - <?php echo esc_html__('Product Category URL part name (slug)', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>parent-name</strong> - <?php echo esc_html__('Reference to parent Product Category Name (If has no parent, value is empty)', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>description</strong> - <?php echo esc_html__('Product Category description', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>display-type</strong> - <?php echo esc_html__('Product Category display type', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>visibility</strong> - <?php echo esc_html__('Product Category visibility', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>protected-passwords</strong> - <?php echo esc_html__('Protected category passwords', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>operation</strong> - <?php echo esc_html__('Default is "U" (update) for all exported categories', 'studiou-wc-product-cat-manage'); ?></li>
+        </ul>
+        
+        <form id="studiou-wcpcm-export-form" method="post">
+            <div class="submit-buttons">
+                <button type="submit" class="button button-primary" id="studiou-wcpcm-export-button">
+                    <?php echo esc_html__('Export Product Categories', 'studiou-wc-product-cat-manage'); ?>
+                </button>
+                <span class="spinner"></span>
+            </div>
+        </form>
+        
+        <div class="studiou-wcpcm-export-results" style="display: none;">
+            <h3><?php echo esc_html__('Export Complete', 'studiou-wc-product-cat-manage'); ?></h3>
+            <p id="studiou-wcpcm-export-message"></p>
+            <p>
+                <a href="#" id="studiou-wcpcm-download-export" class="button button-primary">
+                    <?php echo esc_html__('Download CSV File', 'studiou-wc-product-cat-manage'); ?>
+                </a>
+            </p>
+        </div>
+    </div>
+</div>

+ 76 - 0
studiou-wc-product-cat-manage/views/import.php

@@ -0,0 +1,76 @@
+<?php
+/**
+ * Import page view
+ *
+ * @since      1.0.0
+ * @package    Studiou_WC_Product_Cat_Manage
+ */
+
+// If this file is called directly, abort.
+if (!defined('WPINC')) {
+    die;
+}
+?>
+
+<div class="wrap studiou-wcpcm-wrap">
+    <h1><?php echo esc_html__('Import Product Categories', 'studiou-wc-product-cat-manage'); ?></h1>
+    
+    <div class="studiou-wcpcm-notice-area">
+        <!-- Area for displaying notices -->
+    </div>
+    
+    <div class="studiou-wcpcm-card">
+        <h2><?php echo esc_html__('Import from CSV', 'studiou-wc-product-cat-manage'); ?></h2>
+        
+        <p><?php echo esc_html__('Import product categories from a CSV file. The file should have the following columns:', 'studiou-wc-product-cat-manage'); ?></p>
+        
+        <ul>
+            <li><strong>name</strong> - <?php echo esc_html__('Product Category Name', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>url-name</strong> - <?php echo esc_html__('Product Category URL part name (slug)', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>parent-name</strong> - <?php echo esc_html__('Reference to parent Product Category Name (If has no parent, value is empty)', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>description</strong> - <?php echo esc_html__('Product Category description', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>display-type</strong> - <?php echo esc_html__('Product Category display type (values: \'default\', \'products\', \'subcategories\', \'both\')', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>visibility</strong> - <?php echo esc_html__('Product Category visibility (values: \'public\', \'protected\')', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>protected-passwords</strong> - <?php echo esc_html__('Pipe (|) separated list of passwords if visibility is set to \'protected\'', 'studiou-wc-product-cat-manage'); ?></li>
+            <li><strong>operation</strong> - <?php echo esc_html__('Record operation, \'A\' - add new, \'D\' - delete, \'U\' - update', 'studiou-wc-product-cat-manage'); ?></li>
+        </ul>
+        
+        <p><?php echo esc_html__('The CSV file should use commas (,) as separators and double quotes (") around text values. The file encoding must be UTF-8.', 'studiou-wc-product-cat-manage'); ?></p>
+        
+        <form id="studiou-wcpcm-import-form" method="post" enctype="multipart/form-data">
+            <div class="form-field">
+                <label for="import_file"><?php echo esc_html__('Choose CSV file', 'studiou-wc-product-cat-manage'); ?></label>
+                <input type="file" name="import_file" id="import_file" accept=".csv" required>
+            </div>
+            
+            <div class="submit-buttons">
+                <button type="submit" class="button button-primary" id="studiou-wcpcm-import-button">
+                    <?php echo esc_html__('Import Product Categories', 'studiou-wc-product-cat-manage'); ?>
+                </button>
+                <span class="spinner"></span>
+            </div>
+        </form>
+        
+        <div class="studiou-wcpcm-import-results" style="display: none;">
+            <h3><?php echo esc_html__('Import Results', 'studiou-wc-product-cat-manage'); ?></h3>
+            <pre id="studiou-wcpcm-import-results"></pre>
+        </div>
+    </div>
+    
+    <div class="studiou-wcpcm-card studiou-wcpcm-sample-csv">
+        <h2><?php echo esc_html__('Sample CSV Format', 'studiou-wc-product-cat-manage'); ?></h2>
+        
+        <pre>name,url-name,parent-name,description,display-type,visibility,protected-passwords,operation
+"Clothing","clothing","","Top quality clothing","default","public","","A"
+"Men","men","Clothing","Men's clothing","products","public","","A"
+"Women","women","Clothing","Women's clothing","products","protected","password123","A"
+"Kids","kids","Clothing","Kids clothing","products","public","","U"
+"Accessories","accessories","","All accessories","default","public","","D"</pre>
+        
+        <p>
+            <a href="#" id="studiou-wcpcm-download-sample" class="button">
+                <?php echo esc_html__('Download Sample CSV', 'studiou-wc-product-cat-manage'); ?>
+            </a>
+        </p>
+    </div>
+</div>