# CLAUDE.md - Studiou WC Free Photo Product ## Project Overview WordPress/WooCommerce plugin called **studiou-wc-free-photo-product** (QDR - Studiou WC Free Photo Product) v1.1.1. Allows publishing special variable products where customers upload custom raw images to be printed for a price. ## Initial Requirements 1. WP (6.9.4) / WooCommerce (10.6.2) plugin with variants and custom raw image upload for photo printing. Frontend shows product with upload box and preview on the WooCommerce product detail page. 2. Product configuration area: Media Category for uploaded files, Maximum raw file size. Shortcode to embed product on any page. 3. Uploaded raw files stored in WP media library with a specific media category per product. Chunked upload to bypass PHP upload size limits. Media files linked with product. 4. Admin summary page: list of uploaded files, download as ZIP (bulk), order number, delete, change state (downloaded, ready, solved). 5. HPOS support and localization (English, Czech). ## Tech Stack - PHP 8.2+, WordPress 6.9.4+, WooCommerce 10.0+ - jQuery for frontend/admin JS - WordPress AJAX (admin-ajax.php) for chunked upload - WC session storage for passing file data between upload and add-to-cart (theme-agnostic) - Custom DB table via dbDelta for file tracking - Custom taxonomy `studiou_media_category` on `attachment` post type ## Architecture - Main class: `Studiou_WC_Free_Photo_Product` in root plugin file - Constants prefix: `STUDIOU_WCFPP_` - CSS class prefix: `studiou-fpp-` - JS namespace: `studiouWcfppFront` (frontend), `studiouWcfpp` (admin) - Nonces: `studiou-wcfpp-front-nonce` (frontend), `studiou-wcfpp-nonce` (admin) - Text domain: `studiou-wc-free-photo-product` ## Key Classes - `Studiou_WC_FPP_DB` - Custom table CRUD, media category taxonomy - `Studiou_WC_FPP_Product` - WC product data tab, product meta - `Studiou_WC_FPP_Upload` - Chunked upload AJAX, file assembly, attachment creation - `Studiou_WC_FPP_Single_Product` - Upload area on product page (`woocommerce_single_product_summary` priority 35), WC session storage, server-side validation (`woocommerce_add_to_cart_validation` priority 1) + safety net (`woocommerce_add_to_cart` removes items without photo) - `Studiou_WC_FPP_Shortcode` - `[studiou_free_photo_product id="X"]` renders product with WC native variation form - `Studiou_WC_FPP_Cart` - Reads file data from WC session via `woocommerce_add_cart_item_data`, replaces cart/order item thumbnails with uploaded photo, order item meta, order linking - `Studiou_WC_FPP_Admin` - Summary page, status management, ZIP download ## Frontend Flow 1. Upload area rendered below variation table via `woocommerce_single_product_summary` (priority 35) 2. On page load, existing session state restored (preview, gallery image) 3. Customer uploads photo via chunked AJAX 4. On upload complete, JS stores file ref in WC session 5. Product gallery image replaced with uploaded photo preview; restored on remove 6. Customer selects variant and clicks any Add to Cart button (buttons look normal — no client-side disabling) 7. `woocommerce_add_to_cart_validation` (priority 1) checks WC session — blocks with error notice if no photo 8. `woocommerce_add_to_cart` safety net — removes item if it was added without photo data 9. `woocommerce_add_cart_item_data` reads file data from WC session (session NOT cleared — same photo reusable for multiple variants) 10. Cart/order item thumbnails replaced with uploaded photo (`woocommerce_cart_item_thumbnail`, `woocommerce_admin_order_item_thumbnail`) 11. On checkout, file record is linked to order via `woocommerce_checkout_order_processed` 12. Session only cleared when user clicks Remove ## Coding Conventions - Follow patterns from sibling plugin `studiou-wc-product-cat-manage` - All PHP files start with `if (!defined('WPINC')) { die; }` - AJAX handlers: verify nonce, check capabilities, try/catch with WP_DEBUG logging - Output buffer cleanup in AJAX handlers - Use `wp_send_json_success` / `wp_send_json_error` for all AJAX responses - All user-facing strings wrapped in `__()` or `esc_html_e()` with text domain - Sanitize all inputs: `absint()`, `sanitize_text_field()`, `sanitize_file_name()` - Escape all outputs: `esc_html()`, `esc_attr()`, `esc_url()`, `wp_kses_post()` ## Build / Deploy Notes - Generate .mo from .po: `php languages/generate-mo.php` or `wp i18n make-mo languages/` - Plugin creates DB table on activation via `register_activation_hook` - Activation hook requires explicit `require_once` for DB class (runs before `plugins_loaded`) - Temp chunks stored in `wp-content/uploads/studiou-fpp-chunks/` (cleaned on deactivation) - Assembled files stored in `wp-content/uploads/YYYY/MM/free-photo/` ## Version Bumping When changing JS or CSS files, always bump the plugin version in the main PHP file header AND the `STUDIOU_WCFPP_VERSION` constant to bust browser cache.