CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
QDR - Studiou WC Export/Import Product Categories is a WordPress plugin that extends WooCommerce to provide batch export/import functionality for both product categories and products, along with category manipulation tools.
Current Version: 1.5.3
Requirements
- WordPress 6.8.1+
- PHP 8.2+
- WooCommerce 9.8+
- WooCommerce Protected Categories 2.7+ (optional, for visibility features)
Plugin Architecture
Core Files
- 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
- WooCommerce HPOS compatibility declaration
- Text domain loading for translations
Class Structure (includes/)
The plugin follows a modular class-based architecture:
class-studiou-wc-product-cat-manage-db.php - Database operations layer
- Handles all database queries for product categories
- Manages category hierarchy (parent/child relationships)
- Provides category formatting and data retrieval
- Interfaces with WooCommerce taxonomy and WooCommerce Protected Categories plugin
class-studiou-wc-product-cat-manage-export.php - Export functionality
- Generates CSV files from product categories
- Includes all category properties (name, slug, parent, description, display-type, visibility, protected-passwords)
- Handles UTF-8 encoding and proper CSV formatting
class-studiou-wc-product-cat-manage-import.php - Import functionality
- Processes CSV files with operations: 'A' (add), 'U' (update), 'D' (delete)
- Validates data and handles errors
- Creates/updates/deletes categories based on operation column
- Manages WooCommerce Protected Categories settings
class-studiou-wc-product-cat-manage-manipulator.php - Category manipulation operations
- Move products between categories (removes from source, adds to target)
- Batch description updates for multiple categories
- Delete products in category (permanently deletes products and variants)
- Clear Media Categories (permanently deletes media files from media categories) (NEW in v1.5)
- Remove Not Assigned Media (deletes unused uncategorized media) (NEW in v1.5.2)
- Update product variant prices (regular_price only, by category + attribute filter) (NEW in v1.5.3)
- Uses direct database queries for reliable product detection
- Batch processing for delete operations (10 items per batch)
- Auto-detects media category taxonomy (any custom taxonomy registered for attachments)
- Robust media deletion with post-deletion verification and manual fallback cleanup
- Always-on error logging for media operations (prefix: "STUDIOU WC MEDIA:")
class-studiou-wc-product-manage-product-db.php - Product database operations (NEW in v1.4)
- Retrieves product categories with hierarchy
- Gets products by category IDs
- Validates product SKU uniqueness
- Validates image URLs
- Manages product attributes (create if not exists)
class-studiou-wc-product-manage-product-import.php - Product import functionality (NEW in v1.4)
- Batch processing - Processes 5 products per batch to avoid PHP timeout (60 second limit)
- Parses CSV and stores in WordPress transient for batch processing
- Creates/updates variable products via WooCommerce API
- Creates/updates product variations via WooCommerce API
- Enforces 7 comprehensive import rules
- Auto-creates missing categories - Creates categories if they don't exist
- Handles product attributes, images, categories
- Image download with 30-second timeout, intermediate sizes disabled
- Generates failed products CSV for retry
- Supports Min/Max quantity metadata
- Comprehensive error logging (always enabled, prefix: "STUDIOU WC IMPORT:")
- Logs only skipped/failed items (not successful ones)
class-studiou-wc-product-manage-product-export.php - Product export functionality (NEW in v1.4)
- Exports products by category selection
- Includes variable products and variations
- Generates CSV with 18 columns of product data
- Exports full category paths for subcategories (format: "Parent > Child")
- Handles product attributes, images, pricing
- Creates downloadable export files
Views (views/)
- import.php - Category import page UI
- export.php - Category export page UI
- manipulations.php - Category manipulations page UI with three operations:
- Move products between categories (two dropdowns + "Do" button)
- Batch description between categories (checkbox list + textarea + "Do" button)
- Delete products in category (checkbox list + "Delete" button + progress bar)
- Clear Media Categories (checkbox list + "Delete" button + progress bar) (NEW in v1.5)
- Remove Not Assigned Media ("Delete unused uncategorized media (N)" button + progress bar) (NEW in v1.5.2)
- Update product variant prices (checkbox list + 2 comboboxes + price input + Dry Run/Apply buttons + live affected-count label) (NEW in v1.5.3)
- product-import.php - Product import page UI (NEW in v1.4)
- File upload for CSV import
- Progress bar for import operations
- Import results with statistics
- Failed products download button
- Import rules documentation
- product-export.php - Product export page UI (NEW in v1.4)
- Category hierarchy selection with checkboxes
- Select All/Deselect All buttons
- Export results with download link
- Export information documentation
Assets
- assets/css/admin.css - Admin styling including:
- Progress bar styling
- Warning message styling (yellow background for destructive operations)
- Danger button styling (red for delete operations)
- assets/js/admin.js - Admin JavaScript including:
safeInit() wrapper - each form init is isolated in try-catch so one error cannot block others
- AJAX handlers for all category operations
- AJAX handlers for product import/export operations (NEW in v1.4)
- AJAX handlers for clear media categories operations (NEW in v1.5)
- AJAX handlers for remove unassigned media operations (NEW in v1.5.2)
- Batch processing logic for delete and media deletion operations
- Real-time progress bar updates
- Confirmation dialogs for destructive operations
- Failed products CSV download handler
- Select All/Deselect All handlers for category selection
Translations
- languages/ - Contains .pot, .po, and .mo files
- Text domain:
studiou-wc-product-cat-manage
- All user-facing strings must be wrapped in translation functions:
__(), _e(), sprintf()
CSV Formats
Product Category CSV Format
CSV files use comma separators, double-quote string isolation, UTF-8 encoding:
| Column |
Description |
| name |
Category name (required, used as identifier) |
| url-name |
URL slug |
| parent-name |
Parent category name (empty if root) |
| description |
Category description |
| display-type |
Values: 'default', 'products', 'subcategories', 'both' |
| visibility |
Values: 'public', 'protected' (WooCommerce Protected Categories) |
| protected-passwords |
Pipe-separated passwords (|) if visibility='protected' |
| operation |
'A' (add), 'U' (update), 'D' (delete) |
Product CSV Format (NEW in v1.4)
CSV files use comma separators, double-quote string isolation, UTF-8 encoding:
| Column |
Description |
| ID |
Product ID (0 for new products) |
| Typ |
Product type (only "variable" or "variation" allowed) |
| Katalogové číslo |
SKU (must be unique) |
| Jméno |
Product name |
| Nadřazené |
Parent product SKU (for variations only) |
| Krátký popis |
Short description |
| Popis |
Description |
| Název 1 vlastnosti |
Attribute 1 name |
| Hodnota(y) 1 vlastnosti |
Attribute 1 value(s) (pipe-separated) |
| Kategorie |
Categories (pipe-separated) |
| Obrázky |
Image URL (must be valid) |
| Běžná cena |
Regular price (required for variations) |
| Vlastnost 1 viditelnost |
Attribute 1 visibility (1 or 0) |
| Vlastnost 1 globální |
Attribute 1 global (1 or 0) |
| Vlastnost 1 varianta |
Attribute 1 used for variations (1 or 0) |
| Povolit zákaznické recenze? |
Enable reviews (1 or 0) |
| Minimum Quantity |
Minimum order quantity |
| Maximum Quantity |
Maximum order quantity |
Development Guidelines
When Modifying Code
- Translations: All new user-facing strings must use
__() or _e() with text domain 'studiou-wc-product-cat-manage'
- Security: Always validate and sanitize user input, use nonces for form submissions
- WooCommerce Integration: Use WooCommerce taxonomy 'product_cat' for all category operations
- Error Handling: Provide clear error messages and validation feedback
- Compatibility: Maintain HPOS (High-Performance Order Storage) compatibility declaration
- Direct Exits: Always include
if (!defined('WPINC')) { die; } at top of PHP files
- Batch Processing: For operations on large datasets, use batch processing (10 items per batch recommended)
- Destructive Operations: Always include confirmation dialogs and warning messages for operations that cannot be undone
- Progress Tracking: For long-running operations, implement real-time progress bars
Plugin Constants
STUDIOU_WCPCM_VERSION // Plugin version
STUDIOU_WCPCM_PLUGIN_DIR // Plugin directory path
STUDIOU_WCPCM_PLUGIN_URL // Plugin URL
STUDIOU_WCPCM_PLUGIN_BASENAME // Plugin basename
Admin Menu Structure
All pages are added under Products menu:
- Import Product Categories (slug:
studiou-import-product-categories)
- Export Product Categories (slug:
studiou-export-product-categories)
- Category Manipulations (slug:
studiou-category-manipulations)
- Move products between categories
- Batch description between categories
- Delete products in category
- Clear Media Categories (NEW in v1.5)
- Remove Not Assigned Media (NEW in v1.5.2)
- Update product variant prices (NEW in v1.5.3)
- Product Import (slug:
studiou-product-import) - NEW in v1.4
- Product Export (slug:
studiou-product-export) - NEW in v1.4
Key Integration Points
- WooCommerce Protected Categories: Plugin extends category visibility with 'public'/'protected' settings and password protection
- Product Assignment: When moving products, the plugin modifies product-category term relationships while preserving other category assignments
- Hierarchy Management: Categories maintain parent-child relationships via
parent-name field
- Product Deletion: Uses WooCommerce
wc_get_product() and product->delete(true) for proper product deletion
- Automatically handles variable products by deleting all variations first
- Force delete (true parameter) ensures permanent removal bypassing trash
- Processes in batches to prevent PHP timeouts and memory issues
- Product Import/Export (NEW in v1.4): All operations performed via WooCommerce API
- Uses
WC_Product_Variable and WC_Product_Variation classes
- Uses
WC_Product_Attribute for attribute management
- Image uploads via
media_handle_sideload()
- SKU validation via
wc_get_product_id_by_sku()
- Attribute taxonomy creation via
wc_create_attribute()
- 7 comprehensive import rules enforced
Testing Notes
Category Operations
- Test import/export with categories that have special characters, quotes, commas
- Test category hierarchy (parent/child relationships)
- Test moving products between categories when products have multiple category assignments
- Test batch description updates with multiline text
- Test delete products operation with:
- Simple products
- Variable products with multiple variations
- Products in multiple categories
- Large numbers of products (test batch processing)
- Edge cases: empty categories, categories with only variations
Product Import/Export Operations (NEW in v1.4)
- Test product import with:
- Variable products with multiple attributes
- Product variations with valid parent references
- Invalid SKUs (duplicate, empty)
- Invalid image URLs (404, malformed)
- Invalid parent references
- Missing required fields (price for variations)
- Special characters in product names and descriptions
- Large CSV files (test progress bar)
- Failed products download and re-import
- Test product export with:
- Multiple category selections
- Category hierarchy display
- Empty categories
- Categories with only variable products
- Categories with only variations
- Select All/Deselect All functionality
- Test all 7 import rules:
- WooCommerce API usage (no direct SQL)
- Create vs. Update based on ID
- Type validation (only variable/variation)
- SKU uniqueness
- Image URL validation
- Parent reference validation
- Variation price requirement
Clear Media Categories Operations (NEW in v1.5)
- Test with media category plugin installed (e.g., Media Library Categories)
- Test without media category plugin installed (should show graceful fallback message)
- Test deletion with:
- Single media category selected
- Multiple media categories selected
- Empty media categories
- Large numbers of media files (test batch processing)
- Check All/Uncheck All functionality
- Verify confirmation dialog appears before deletion
- Verify progress bar updates correctly during batch deletion
- Verify media files are actually removed from disk
- Verify deletion statistics are accurate
- Test with media files used as product images (verify WooCommerce product references are handled)
- Verify physical files are deleted from disk (check wp-content/uploads/)
- Verify attachment posts are removed from Media Library
Remove Not Assigned Media Operations (NEW in v1.5.2)
- Verify button count matches actual unused uncategorized media
- Test deletion with:
- Media not in any category and not used anywhere
- Media used as featured image (should NOT be deleted)
- Media used in WooCommerce product galleries (should NOT be deleted)
- Media attached to a post (post_parent > 0, should NOT be deleted)
- Media in a media category (should NOT be deleted)
- Large numbers of unused media (test batch processing)
- Verify confirmation dialog appears before deletion
- Verify progress bar updates correctly
- Verify physical files and attachment posts are both deleted
- Verify button count updates after page reload
Update Product Variant Prices Operations (NEW in v1.5.3)
- Test happy path with a global taxonomy attribute (e.g.
pa_color = red) — Dry Run shows correct count + sample, Apply commits new regular price
- Test happy path with a custom non-taxonomy attribute (product-level)
- Test multi-category selection — variations counted only once each
- Test no-match filter — Apply button stays disabled, label shows 0
- Test invalid price input (empty / negative / non-numeric) — server-side error, no DB write
- Verify a user without
manage_woocommerce cannot trigger AJAX
- Verify nonce tampering returns "Security check failed"
- Order data integrity: place a test order with a variation, run UPVP, verify the order line item retains the original price (only product-side price changes)
- Verify parent variable product price-range cache is refreshed (
WC_Product_Variable::sync + wc_delete_product_transients) — storefront price range reflects new price
- Verify Czech translations render when site locale is
cs_CZ
- Verify asset version query string updates from
1.5.2 to 1.5.3 (note: studiou.cz strips ?ver= — instruct user to hard-refresh)
General
- Verify translations are properly loaded (English/Czech)
- Verify progress bars update correctly
- Verify confirmation dialogs appear for destructive operations
- Test with WP_DEBUG enabled to catch errors
AJAX Handlers
The plugin registers the following AJAX actions:
Category Operations
- studiou_wcpcm_import - Handles category CSV import
- studiou_wcpcm_export - Generates category CSV export
- studiou_wcpcm_move_products - Moves products between categories
- studiou_wcpcm_batch_description - Updates descriptions for multiple categories
- studiou_wcpcm_delete_products - Initial request to get product IDs for deletion
- studiou_wcpcm_delete_products_batch - Processes product deletion in batches
- studiou_wcpcm_clear_media - Initial request to get media IDs for deletion (NEW in v1.5)
- studiou_wcpcm_clear_media_batch - Processes media deletion in batches (NEW in v1.5)
- studiou_wcpcm_remove_unassigned_media - Gets IDs of unused uncategorized media (NEW in v1.5.2)
- studiou_wcpcm_remove_unassigned_media_batch - Processes unassigned media deletion in batches (NEW in v1.5.2)
- studiou_wcpcm_upvp_get_attributes - Lists variation attribute heads (NEW in v1.5.3)
- studiou_wcpcm_upvp_get_attribute_values - Lists values for the selected attribute, scoped to selected categories (NEW in v1.5.3)
- studiou_wcpcm_upvp_count - Counts and samples variations matching the current filter (NEW in v1.5.3)
- studiou_wcpcm_upvp_apply - Commits new regular price to matching variations via WC API (NEW in v1.5.3)
Product Operations (NEW in v1.4)
- studiou_wcpcm_product_import_parse - Parses CSV file and stores in transient (Step 1)
- studiou_wcpcm_product_import_batch - Processes batch of 5 products (Step 2, called recursively)
- studiou_wcpcm_product_export - Generates product CSV export by category selection
All AJAX handlers include:
- Nonce verification (
studiou-wcpcm-nonce)
- Permission checks (
manage_woocommerce capability)
- Output buffer cleaning to prevent JSON corruption
- Comprehensive error logging (always enabled for product import)
Product Import Rules (v1.4)
The product import functionality enforces 7 comprehensive rules:
- Rule 1: All operations performed via WooCommerce API (not direct SQL)
- Rule 2: If ID = 0, item will be created; otherwise updated
- Rule 3: Only "variable" or "variation" types are allowed
- Rule 4: SKU (Katalogové číslo) must be unique in WooCommerce database
- Rule 5: Image URL must be valid format (actual accessibility checked during download)
- Rule 6: Parent reference (Nadřazené) must point to an existing variable product SKU
- Rule 7: Variations must have a regular price (Běžná cena)
Product Import Technical Details (v1.4)
Batch Processing Architecture
To avoid PHP timeout issues (typically 60 seconds on production servers):
- Parse Phase: CSV file is read entirely and stored in WordPress transient (expires in 1 hour)
- Batch Phase: Products are processed in batches of 5 via recursive AJAX calls
- Progress Tracking: Real-time progress bar shows "Processing: X / Y products"
- Result Accumulation: Success/failed/skipped counts are accumulated across batches
Category Handling
- Simple name lookup only - Categories have unique names throughout the system
- No hierarchy detection - Dashes and other characters are part of category names, not separators
- Auto-create: If category doesn't exist, it's automatically created during import
- Lookup methods: Tries exact name match, slug match, then case-insensitive search
Image Processing
- 30-second timeout per image download
- Intermediate sizes disabled during import for speed
- Graceful failure: Failed image downloads don't stop import, just logged
Error Logging
- Always enabled (no WP_DEBUG required)
- Prefix: "STUDIOU WC IMPORT:" for easy filtering
- Only logs failures: Success messages not logged to reduce noise
- Detailed debugging: Shows category lookup attempts, creation, and assignment
Items that fail validation are:
- Skipped during import
- Logged with SKIPPED or FAILED prefix
- Added to failed items list
- Available for download via "Save Failed Products" button
- Can be corrected and re-imported
- new Rule is that product category has unique name through whole product categories