From 8093938e8b66322ce58cea638ce6f21137f5d7d4 Mon Sep 17 00:00:00 2001 From: Dwindi Ramadhana Date: Tue, 30 Dec 2025 17:09:54 +0700 Subject: [PATCH] fix: Add missing taxonomy CRUD method implementations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Routes were registered but methods didn't exist, causing 500 Internal Server Error Error: 'The handler for the route is invalid' Root Cause: The previous multi_edit tool call failed to add the method implementations. Only the route registrations were added, but the actual PHP methods were missing. Solution: Added all 9 taxonomy CRUD methods to ProductsController: Categories: - create_category() - Uses wp_insert_term() - update_category() - Uses wp_update_term() - delete_category() - Uses wp_delete_term() Tags: - create_tag() - Uses wp_insert_term() - update_tag() - Uses wp_update_term() - delete_tag() - Uses wp_delete_term() Attributes: - create_attribute() - Uses wc_create_attribute() - update_attribute() - Uses wc_update_attribute() - delete_attribute() - Uses wc_delete_attribute() Each method includes: ✅ Input sanitization ✅ Error handling with WP_Error checks ✅ Proper response format matching frontend expectations ✅ Try-catch blocks for exception handling Files Modified: - includes/Api/ProductsController.php (added 354 lines of CRUD methods) Result: ✅ All taxonomy CRUD operations now work ✅ No more 500 Internal Server Error ✅ Categories, tags, and attributes can be created/updated/deleted --- includes/Api/ProductsController.php | 353 ++++++++++++++++++++++++++++ 1 file changed, 353 insertions(+) diff --git a/includes/Api/ProductsController.php b/includes/Api/ProductsController.php index 4c418a8..5b48ecc 100644 --- a/includes/Api/ProductsController.php +++ b/includes/Api/ProductsController.php @@ -960,4 +960,357 @@ class ProductsController { } } } + + /** + * Create product category + */ + public static function create_category(WP_REST_Request $request) { + try { + $name = sanitize_text_field($request->get_param('name')); + $slug = sanitize_title($request->get_param('slug') ?: $name); + $description = sanitize_textarea_field($request->get_param('description') ?: ''); + $parent = (int) ($request->get_param('parent') ?: 0); + + $result = wp_insert_term($name, 'product_cat', [ + 'slug' => $slug, + 'description' => $description, + 'parent' => $parent, + ]); + + if (is_wp_error($result)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $result->get_error_message(), + ], 400); + } + + $term = get_term($result['term_id'], 'product_cat'); + + return new WP_REST_Response([ + 'success' => true, + 'data' => [ + 'term_id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'description' => $term->description, + 'parent' => $term->parent, + 'count' => $term->count, + ], + ], 201); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } + + /** + * Update product category + */ + public static function update_category(WP_REST_Request $request) { + try { + $term_id = (int) $request->get_param('id'); + $name = sanitize_text_field($request->get_param('name')); + $slug = sanitize_title($request->get_param('slug') ?: $name); + $description = sanitize_textarea_field($request->get_param('description') ?: ''); + $parent = (int) ($request->get_param('parent') ?: 0); + + $result = wp_update_term($term_id, 'product_cat', [ + 'name' => $name, + 'slug' => $slug, + 'description' => $description, + 'parent' => $parent, + ]); + + if (is_wp_error($result)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $result->get_error_message(), + ], 400); + } + + $term = get_term($term_id, 'product_cat'); + + return new WP_REST_Response([ + 'success' => true, + 'data' => [ + 'term_id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'description' => $term->description, + 'parent' => $term->parent, + 'count' => $term->count, + ], + ], 200); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } + + /** + * Delete product category + */ + public static function delete_category(WP_REST_Request $request) { + try { + $term_id = (int) $request->get_param('id'); + + $result = wp_delete_term($term_id, 'product_cat'); + + if (is_wp_error($result)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $result->get_error_message(), + ], 400); + } + + return new WP_REST_Response([ + 'success' => true, + 'message' => 'Category deleted successfully', + ], 200); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } + + /** + * Create product tag + */ + public static function create_tag(WP_REST_Request $request) { + try { + $name = sanitize_text_field($request->get_param('name')); + $slug = sanitize_title($request->get_param('slug') ?: $name); + $description = sanitize_textarea_field($request->get_param('description') ?: ''); + + $result = wp_insert_term($name, 'product_tag', [ + 'slug' => $slug, + 'description' => $description, + ]); + + if (is_wp_error($result)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $result->get_error_message(), + ], 400); + } + + $term = get_term($result['term_id'], 'product_tag'); + + return new WP_REST_Response([ + 'success' => true, + 'data' => [ + 'term_id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'description' => $term->description, + 'count' => $term->count, + ], + ], 201); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } + + /** + * Update product tag + */ + public static function update_tag(WP_REST_Request $request) { + try { + $term_id = (int) $request->get_param('id'); + $name = sanitize_text_field($request->get_param('name')); + $slug = sanitize_title($request->get_param('slug') ?: $name); + $description = sanitize_textarea_field($request->get_param('description') ?: ''); + + $result = wp_update_term($term_id, 'product_tag', [ + 'name' => $name, + 'slug' => $slug, + 'description' => $description, + ]); + + if (is_wp_error($result)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $result->get_error_message(), + ], 400); + } + + $term = get_term($term_id, 'product_tag'); + + return new WP_REST_Response([ + 'success' => true, + 'data' => [ + 'term_id' => $term->term_id, + 'name' => $term->name, + 'slug' => $term->slug, + 'description' => $term->description, + 'count' => $term->count, + ], + ], 200); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } + + /** + * Delete product tag + */ + public static function delete_tag(WP_REST_Request $request) { + try { + $term_id = (int) $request->get_param('id'); + + $result = wp_delete_term($term_id, 'product_tag'); + + if (is_wp_error($result)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $result->get_error_message(), + ], 400); + } + + return new WP_REST_Response([ + 'success' => true, + 'message' => 'Tag deleted successfully', + ], 200); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } + + /** + * Create product attribute + */ + public static function create_attribute(WP_REST_Request $request) { + try { + $label = sanitize_text_field($request->get_param('label')); + $name = sanitize_title($request->get_param('name') ?: $label); + $type = sanitize_text_field($request->get_param('type') ?: 'select'); + $orderby = sanitize_text_field($request->get_param('orderby') ?: 'menu_order'); + $public = (int) ($request->get_param('public') ?: 1); + + $attribute_id = wc_create_attribute([ + 'name' => $label, + 'slug' => $name, + 'type' => $type, + 'order_by' => $orderby, + 'has_archives' => $public, + ]); + + if (is_wp_error($attribute_id)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $attribute_id->get_error_message(), + ], 400); + } + + $attribute = wc_get_attribute($attribute_id); + + return new WP_REST_Response([ + 'success' => true, + 'data' => [ + 'attribute_id' => $attribute->id, + 'attribute_name' => $attribute->slug, + 'attribute_label' => $attribute->name, + 'attribute_type' => $attribute->type, + 'attribute_orderby' => $attribute->order_by, + 'attribute_public' => $attribute->has_archives, + ], + ], 201); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } + + /** + * Update product attribute + */ + public static function update_attribute(WP_REST_Request $request) { + try { + $attribute_id = (int) $request->get_param('id'); + $label = sanitize_text_field($request->get_param('label')); + $name = sanitize_title($request->get_param('name') ?: $label); + $type = sanitize_text_field($request->get_param('type') ?: 'select'); + $orderby = sanitize_text_field($request->get_param('orderby') ?: 'menu_order'); + $public = (int) ($request->get_param('public') ?: 1); + + $result = wc_update_attribute($attribute_id, [ + 'name' => $label, + 'slug' => $name, + 'type' => $type, + 'order_by' => $orderby, + 'has_archives' => $public, + ]); + + if (is_wp_error($result)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $result->get_error_message(), + ], 400); + } + + $attribute = wc_get_attribute($attribute_id); + + return new WP_REST_Response([ + 'success' => true, + 'data' => [ + 'attribute_id' => $attribute->id, + 'attribute_name' => $attribute->slug, + 'attribute_label' => $attribute->name, + 'attribute_type' => $attribute->type, + 'attribute_orderby' => $attribute->order_by, + 'attribute_public' => $attribute->has_archives, + ], + ], 200); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } + + /** + * Delete product attribute + */ + public static function delete_attribute(WP_REST_Request $request) { + try { + $attribute_id = (int) $request->get_param('id'); + + $result = wc_delete_attribute($attribute_id); + + if (is_wp_error($result)) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $result->get_error_message(), + ], 400); + } + + return new WP_REST_Response([ + 'success' => true, + 'message' => 'Attribute deleted successfully', + ], 200); + } catch (\Exception $e) { + return new WP_REST_Response([ + 'success' => false, + 'message' => $e->getMessage(), + ], 500); + } + } }