Changeset 3288294
- Timestamp:
- 05/06/2025 09:04:55 AM (10 months ago)
- Location:
- content-api
- Files:
-
- 4 edited
- 1 copied
-
tags/1.0.3 (copied) (copied from content-api/trunk)
-
tags/1.0.3/content-api.php (modified) (7 diffs)
-
tags/1.0.3/readme.txt (modified) (2 diffs)
-
trunk/content-api.php (modified) (7 diffs)
-
trunk/readme.txt (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
content-api/tags/1.0.3/content-api.php
r3284442 r3288294 5 5 * Plugin URI: https://www.polyplugins.com/contact/ 6 6 * Description: Adds various endpoints to create content 7 * Version: 1.0. 27 * Version: 1.0.3 8 8 * Requires at least: 6.5 9 9 * Requires PHP: 7.4 … … 63 63 )); 64 64 65 register_rest_route('content-api/v1', '/product-category/', array( 66 'methods' => 'GET', 67 'callback' => array($this, 'get_product_category'), 68 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 69 )); 70 71 register_rest_route('content-api/v1', '/product-category/', array( 72 'methods' => 'PATCH', 73 'callback' => array($this, 'update_product_category'), 74 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 75 )); 76 77 register_rest_route('content-api/v1', '/product-category/', array( 78 'methods' => 'POST', 79 'callback' => array($this, 'create_product_category'), 80 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 81 )); 82 65 83 register_rest_route('content-api/v1', '/product-categories/', array( 66 84 'methods' => 'GET', … … 108 126 'methods' => 'GET', 109 127 'callback' => array($this, 'get_product_attributes'), 128 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 129 )); 130 131 register_rest_route('content-api/v1', '/product-brand/', array( 132 'methods' => 'GET', 133 'callback' => array($this, 'get_brand'), 134 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 135 )); 136 137 register_rest_route('content-api/v1', '/product-brand/', array( 138 'methods' => 'PATCH', 139 'callback' => array($this, 'update_brand'), 140 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 141 )); 142 143 register_rest_route('content-api/v1', '/product-brand/', array( 144 'methods' => 'POST', 145 'callback' => array($this, 'create_brand'), 110 146 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 111 147 )); … … 656 692 657 693 /** 658 * Get product categor ies694 * Get product category 659 695 * 660 696 * @param mixed $request 661 697 * @return void 662 698 */ 663 public function get_product_categories(WP_REST_Request $request) { 664 $this->options = get_option('content_api_options_polyplugins'); 665 666 $fields = $request->get_json_params(); 667 $product_id = isset($fields['product_id']) ? absint($fields['product_id']) : 0; 668 $sku = isset($fields['sku']) ? sanitize_text_field($fields['sku']) : ''; 669 670 if (!$product_id && !$sku) { 671 return new WP_Error('missing_identifier', 'Product ID or SKU is required', array('status' => 400)); 672 } 673 674 if ($product_id) { 675 if (!is_numeric($product_id)) { 676 return new WP_Error('product_id_invalid', 'Product ID is invalid', array('status' => 400)); 677 } 678 } 679 680 if ($sku) { 681 if ($sku !== sanitize_text_field($sku)) { 682 return new WP_Error('sku_invalid', 'SKU is invalid', array('status' => 400)); 683 } 684 } 685 686 if ($product_id && $sku) { 687 return new WP_Error('conflicting_identifiers', 'Both Product ID and SKU are provided. Please provide only one.', array('status' => 400)); 688 } 689 690 if ($sku && !$product_id) { 691 $product_id_by_sku = wc_get_product_id_by_sku($sku); 692 693 if ($product_id_by_sku) { 694 $product = wc_get_product($product_id_by_sku); 695 } else { 696 return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404)); 697 } 698 } 699 elseif ($product_id) { 700 $product = wc_get_product($product_id); 701 } 702 703 if (!isset($product) || !$product) { 704 return new WP_Error('product_not_found', 'Product not found', array('status' => 404)); 705 } 706 707 $categories = wp_get_post_terms($product->get_id(), 'product_cat'); 708 709 // Map terms by ID 710 $term_map = array(); 711 foreach ($categories as $term) { 712 $term_map[$term->term_id] = array( 713 'id' => $term->term_id, 714 'name' => $term->name, 715 'slug' => $term->slug, 716 'children' => array(), 717 'parent' => $term->parent, 718 ); 719 } 720 721 // Build the category tree 722 $tree = array(); 723 724 foreach ($term_map as $id => &$term) { 725 if ($term['parent'] && isset($term_map[$term['parent']])) { 726 $term_map[$term['parent']]['children'][] = &$term; 727 } else { 728 $tree[] = &$term; 729 } 730 } 731 unset($term); // Break the reference 732 733 // Prepare category data 734 $category_data = array(); 735 foreach ($tree as $term) { 736 $category_data[] = $this->build_category_hierarchy($term); 737 } 738 739 return new WP_REST_Response(array( 740 'success' => true, 741 'product_id'=> $product->get_id(), 742 'categories'=> $category_data 743 ), 200); 744 } 745 746 /** 747 * Update product categories 748 * 749 * @param mixed $request 750 * @return void 751 */ 752 public function update_product_categories(WP_REST_Request $request) { 753 $this->options = get_option('content_api_options_polyplugins'); 754 755 $fields = $request->get_json_params(); 756 $product_id = isset($fields['product_id']) ? absint($fields['product_id']) : 0; 757 $sku = isset($fields['sku']) ? sanitize_text_field($fields['sku']) : ''; 758 $categories = isset($fields['categories']) ? array_map('absint', $fields['categories']) : array(); 759 760 if (!$product_id && !$sku) { 761 return new WP_Error('missing_identifier', 'Product ID or SKU is required', array('status' => 400)); 762 } 763 764 if ($product_id) { 765 if (!is_numeric($product_id)) { 766 return new WP_Error('product_id_invalid', 'Product ID is invalid', array('status' => 400)); 767 } 768 } 769 770 if ($sku) { 771 if ($sku !== sanitize_text_field($sku)) { 772 return new WP_Error('sku_invalid', 'SKU is invalid', array('status' => 400)); 773 } 774 } 775 776 if ($product_id && $sku) { 777 return new WP_Error('conflicting_identifiers', 'Both Product ID and SKU are provided. Please provide only one.', array('status' => 400)); 778 } 779 780 if ($sku && !$product_id) { 781 $product_id_by_sku = wc_get_product_id_by_sku($sku); 782 783 if ($product_id_by_sku) { 784 $product = wc_get_product($product_id_by_sku); 785 } else { 786 return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404)); 787 } 788 } 789 elseif ($product_id) { 790 $product = wc_get_product($product_id); 791 } 792 793 if (!isset($product) || !$product) { 794 return new WP_Error('product_not_found', 'Product not found', array('status' => 404)); 795 } 796 797 if (!$categories) { 798 return new WP_Error('invalid_input', 'Categories empty', array('status' => 400)); 799 } 800 801 // Validate that all categories exist 802 foreach ($categories as $cat_id) { 803 $term = get_term($cat_id, 'product_cat'); 804 805 if (!$term || is_wp_error($term)) { 806 return new WP_Error('category_not_found', "Category ID {$cat_id} does not exist", array('status' => 404)); 807 } 808 } 809 810 // Get current categories on the product 811 $existing_cat_ids = wp_get_object_terms($product_id, 'product_cat', array('fields' => 'ids')); 812 813 // Merge and deduplicate 814 $final_cat_ids = array_unique(array_merge($existing_cat_ids, $categories)); 815 816 wp_set_object_terms($product_id, $final_cat_ids, 'product_cat'); 817 818 return new WP_REST_Response(array( 819 'success' => true, 820 'product_id' => $product_id, 821 'assigned_category_ids' => $final_cat_ids 822 ), 200); 823 } 824 825 /** 826 * Get product brands 827 * 828 * @param WP_REST_Request $request 829 * @return WP_REST_Response 830 */ 831 public function get_brand(WP_REST_Request $request) { 699 public function get_product_category(WP_REST_Request $request) { 832 700 $params = $request->get_params(); 833 $taxonomy = isset($params['taxonomy']) ? sanitize_text_field($params['taxonomy']) : 'product_ brand';701 $taxonomy = isset($params['taxonomy']) ? sanitize_text_field($params['taxonomy']) : 'product_cat'; 834 702 $id = isset($params['id']) ? absint($params['id']) : 0; 835 703 $slug = isset($params['slug']) ? sanitize_title($params['slug']) : ''; … … 845 713 846 714 if (empty($term) || is_wp_error($term)) { 847 return new WP_Error('no_ brand_found', "No brandfound under the " . $taxonomy . " taxonomy.", array('status' => 400));848 } 849 850 $term_id = $term->term_id;851 $ brand_data = (array) $term;715 return new WP_Error('no_product_category_found', "No category found under the " . $taxonomy . " taxonomy.", array('status' => 400)); 716 } 717 718 $term_id = $term->term_id; 719 $product_category_data = (array) $term; 852 720 853 721 // Get thumbnail ID and URL … … 856 724 857 725 if ($thumbnail_url) { 858 $ brand_data['thumbnail'] = $thumbnail_url;726 $product_category_data['thumbnail'] = $thumbnail_url; 859 727 } 860 728 … … 883 751 } 884 752 753 $product_category_data['yoast'] = $yoast_data; 754 755 return new WP_REST_Response(array( 756 'success' => true, 757 'data' => $product_category_data, 758 ), 201); 759 } 760 761 /** 762 * Update product category 763 * 764 * @param mixed $request 765 * @return void 766 */ 767 public function update_product_category(WP_REST_Request $request) { 768 $fields = $request->get_json_params(); 769 $id = isset($fields['id']) ? absint($fields['id']) : 0; 770 $name = isset($fields['name']) ? sanitize_text_field($fields['name']) : ''; 771 $description = isset($fields['description']) ? wp_kses_post($fields['description']) : ''; 772 $slug = isset($fields['slug']) ? sanitize_title($fields['slug']) : ''; 773 $parent_id = isset($fields['parent']) ? absint($fields['parent']) : ''; 774 $taxonomy = isset($fields['taxonomy']) ? sanitize_text_field($fields['taxonomy']) : 'product_cat'; 775 776 // Basic input validation 777 if (!$id) { 778 return new WP_Error('missing_identifier', 'Product category ID is required', array('status' => 400)); 779 } 780 781 $term = get_term($id, $taxonomy); 782 783 if (!$term || is_wp_error($term)) { 784 return new WP_Error('category_not_found', 'Product category not found', array('status' => 404)); 785 } 786 787 $term_id = $term->term_id; 788 789 $term_args = []; 790 791 if ($name) { 792 $term_args['name'] = $name; 793 } 794 795 if ($description) { 796 $term_args['description'] = $description; 797 } 798 799 if ($slug) { 800 $term_args['slug'] = $slug; 801 } 802 803 if ($parent_id > 0) { 804 $parent_term = get_term($parent_id, $taxonomy); 805 806 if ($parent_term && !is_wp_error($parent_term)) { 807 $term_args['parent'] = $parent_id; 808 } else { 809 return new WP_Error('invalid_parent', 'The specified parent product category does not exist.', array('status' => 400)); 810 } 811 } elseif ($parent_id === 0) { 812 $term_args['parent'] = 0; // Remove parent 813 } 814 815 if (!empty($term_args)) { 816 $result = wp_update_term($term_id, $taxonomy, $term_args); 817 818 if (is_wp_error($result)) { 819 return new WP_Error('term_update_failed', 'Failed to update product category term', array('status' => 500)); 820 } 821 } 822 823 // Update Yoast fields 824 if (isset($fields['yoast']) && is_array($fields['yoast'])) { 825 $yoast_option = get_option('wpseo_taxonomy_meta'); 826 827 if (!isset($yoast_option[$taxonomy])) { 828 $yoast_option[$taxonomy] = []; 829 } 830 831 if (!isset($yoast_option[$taxonomy][$term_id])) { 832 $yoast_option[$taxonomy][$term_id] = []; 833 } 834 835 $yoast_input = $fields['yoast']; 836 837 if (isset($yoast_input['title']) && $yoast_input['title']) { 838 $yoast_option[$taxonomy][$term_id]['wpseo_title'] = $yoast_input['title']; 839 } 840 841 if (isset($yoast_input['description']) && $yoast_input['description']) { 842 $yoast_option[$taxonomy][$term_id]['wpseo_desc'] = $yoast_input['description']; 843 } 844 845 if (isset($yoast_input['premium']['social_appearance']['title']) && $yoast_input['premium']['social_appearance']['title']) { 846 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-title'] = $yoast_input['premium']['social_appearance']['title']; 847 } 848 849 if (isset($yoast_input['premium']['social_appearance']['description']) && $yoast_input['premium']['social_appearance']['description']) { 850 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-description'] = $yoast_input['premium']['social_appearance']['description']; 851 } 852 853 if (isset($yoast_input['premium']['social_appearance']['image']) && $yoast_input['premium']['social_appearance']['image']) { 854 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-image'] = $yoast_input['premium']['social_appearance']['image']; 855 } 856 857 if (isset($yoast_input['premium']['x']['title']) && $yoast_input['premium']['x']['title']) { 858 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-title'] = $yoast_input['premium']['x']['title']; 859 } 860 861 if (isset($yoast_input['premium']['x']['description']) && $yoast_input['premium']['x']['description']) { 862 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-description'] = $yoast_input['premium']['x']['description']; 863 } 864 865 if (isset($yoast_input['premium']['x']['image']) && $yoast_input['premium']['x']['image']) { 866 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-image'] = $yoast_input['premium']['x']['image']; 867 } 868 869 update_option('wpseo_taxonomy_meta', $yoast_option); 870 } 871 872 return new WP_REST_Response(array( 873 'success' => true, 874 'product_category_id' => $term_id, 875 'message' => 'Product category updated successfully.' 876 ), 200); 877 } 878 879 /** 880 * Create product category 881 * 882 * @param mixed $request 883 * @return void 884 */ 885 public function create_product_category(WP_REST_Request $request) { 886 $fields = $request->get_json_params(); 887 $name = isset($fields['name']) ? sanitize_text_field($fields['name']) : ''; 888 $description = isset($fields['description']) ? wp_kses_post($fields['description']) : ''; 889 $slug = isset($fields['slug']) ? sanitize_title($fields['slug']) : ''; 890 $parent_id = isset($fields['parent']) ? absint($fields['parent']) : 0; 891 $taxonomy = isset($fields['taxonomy']) ? sanitize_text_field($fields['taxonomy']) : 'product_cat'; 892 893 // Validate name 894 if (empty($name)) { 895 return new WP_Error('missing_name', 'Product category name is required.', array('status' => 400)); 896 } 897 898 $term_args = array( 899 'description' => $description, 900 'slug' => $slug, 901 'parent' => 0 902 ); 903 904 if ($parent_id > 0) { 905 $parent_term = get_term($parent_id, $taxonomy); 906 907 if ($parent_term && !is_wp_error($parent_term)) { 908 $term_args['parent'] = $parent_id; 909 } else { 910 return new WP_Error('invalid_parent', 'The specified parent product category does not exist.', array('status' => 400)); 911 } 912 } 913 914 // Create the term 915 $result = wp_insert_term($name, $taxonomy, $term_args); 916 917 if (is_wp_error($result)) { 918 return new WP_Error('term_creation_failed', $result->get_error_message(), array('status' => 500)); 919 } 920 921 $term_id = $result['term_id']; 922 923 // Update Yoast fields 924 if (isset($fields['yoast']) && is_array($fields['yoast'])) { 925 $yoast_option = get_option('wpseo_taxonomy_meta'); 926 927 if (!isset($yoast_option[$taxonomy])) { 928 $yoast_option[$taxonomy] = array(); 929 } 930 931 if (!isset($yoast_option[$taxonomy][$term_id])) { 932 $yoast_option[$taxonomy][$term_id] = array(); 933 } 934 935 $yoast_input = $fields['yoast']; 936 937 if (!empty($yoast_input['title'])) { 938 $yoast_option[$taxonomy][$term_id]['wpseo_title'] = $yoast_input['title']; 939 } 940 941 if (!empty($yoast_input['description'])) { 942 $yoast_option[$taxonomy][$term_id]['wpseo_desc'] = $yoast_input['description']; 943 } 944 945 if (!empty($yoast_input['premium']['social_appearance']['title'])) { 946 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-title'] = $yoast_input['premium']['social_appearance']['title']; 947 } 948 949 if (!empty($yoast_input['premium']['social_appearance']['description'])) { 950 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-description'] = $yoast_input['premium']['social_appearance']['description']; 951 } 952 953 if (!empty($yoast_input['premium']['social_appearance']['image'])) { 954 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-image'] = $yoast_input['premium']['social_appearance']['image']; 955 } 956 957 if (!empty($yoast_input['premium']['x']['title'])) { 958 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-title'] = $yoast_input['premium']['x']['title']; 959 } 960 961 if (!empty($yoast_input['premium']['x']['description'])) { 962 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-description'] = $yoast_input['premium']['x']['description']; 963 } 964 965 if (!empty($yoast_input['premium']['x']['image'])) { 966 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-image'] = $yoast_input['premium']['x']['image']; 967 } 968 969 update_option('wpseo_taxonomy_meta', $yoast_option); 970 } 971 972 return new WP_REST_Response(array( 973 'success' => true, 974 'product_category_id' => $term_id, 975 'message' => 'Product category created successfully.' 976 ), 201); 977 } 978 979 /** 980 * Get product categories 981 * 982 * @param mixed $request 983 * @return void 984 */ 985 public function get_product_categories(WP_REST_Request $request) { 986 $this->options = get_option('content_api_options_polyplugins'); 987 988 $fields = $request->get_json_params(); 989 $product_id = isset($fields['product_id']) ? absint($fields['product_id']) : 0; 990 $sku = isset($fields['sku']) ? sanitize_text_field($fields['sku']) : ''; 991 992 if (!$product_id && !$sku) { 993 return new WP_Error('missing_identifier', 'Product ID or SKU is required', array('status' => 400)); 994 } 995 996 if ($product_id) { 997 if (!is_numeric($product_id)) { 998 return new WP_Error('product_id_invalid', 'Product ID is invalid', array('status' => 400)); 999 } 1000 } 1001 1002 if ($sku) { 1003 if ($sku !== sanitize_text_field($sku)) { 1004 return new WP_Error('sku_invalid', 'SKU is invalid', array('status' => 400)); 1005 } 1006 } 1007 1008 if ($product_id && $sku) { 1009 return new WP_Error('conflicting_identifiers', 'Both Product ID and SKU are provided. Please provide only one.', array('status' => 400)); 1010 } 1011 1012 if ($sku && !$product_id) { 1013 $product_id_by_sku = wc_get_product_id_by_sku($sku); 1014 1015 if ($product_id_by_sku) { 1016 $product = wc_get_product($product_id_by_sku); 1017 } else { 1018 return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404)); 1019 } 1020 } 1021 elseif ($product_id) { 1022 $product = wc_get_product($product_id); 1023 } 1024 1025 if (!isset($product) || !$product) { 1026 return new WP_Error('product_not_found', 'Product not found', array('status' => 404)); 1027 } 1028 1029 $categories = wp_get_post_terms($product->get_id(), 'product_cat'); 1030 1031 // Map terms by ID 1032 $term_map = array(); 1033 foreach ($categories as $term) { 1034 $term_map[$term->term_id] = array( 1035 'id' => $term->term_id, 1036 'name' => $term->name, 1037 'slug' => $term->slug, 1038 'children' => array(), 1039 'parent' => $term->parent, 1040 ); 1041 } 1042 1043 // Build the category tree 1044 $tree = array(); 1045 1046 foreach ($term_map as $id => &$term) { 1047 if ($term['parent'] && isset($term_map[$term['parent']])) { 1048 $term_map[$term['parent']]['children'][] = &$term; 1049 } else { 1050 $tree[] = &$term; 1051 } 1052 } 1053 unset($term); // Break the reference 1054 1055 // Prepare category data 1056 $category_data = array(); 1057 foreach ($tree as $term) { 1058 $category_data[] = $this->build_category_hierarchy($term); 1059 } 1060 1061 return new WP_REST_Response(array( 1062 'success' => true, 1063 'product_id'=> $product->get_id(), 1064 'categories'=> $category_data 1065 ), 200); 1066 } 1067 1068 /** 1069 * Update product categories 1070 * 1071 * @param mixed $request 1072 * @return void 1073 */ 1074 public function update_product_categories(WP_REST_Request $request) { 1075 $this->options = get_option('content_api_options_polyplugins'); 1076 1077 $fields = $request->get_json_params(); 1078 $product_id = isset($fields['product_id']) ? absint($fields['product_id']) : 0; 1079 $sku = isset($fields['sku']) ? sanitize_text_field($fields['sku']) : ''; 1080 $categories = isset($fields['categories']) ? array_map('absint', $fields['categories']) : array(); 1081 1082 if (!$product_id && !$sku) { 1083 return new WP_Error('missing_identifier', 'Product ID or SKU is required', array('status' => 400)); 1084 } 1085 1086 if ($product_id) { 1087 if (!is_numeric($product_id)) { 1088 return new WP_Error('product_id_invalid', 'Product ID is invalid', array('status' => 400)); 1089 } 1090 } 1091 1092 if ($sku) { 1093 if ($sku !== sanitize_text_field($sku)) { 1094 return new WP_Error('sku_invalid', 'SKU is invalid', array('status' => 400)); 1095 } 1096 } 1097 1098 if ($product_id && $sku) { 1099 return new WP_Error('conflicting_identifiers', 'Both Product ID and SKU are provided. Please provide only one.', array('status' => 400)); 1100 } 1101 1102 if ($sku && !$product_id) { 1103 $product_id_by_sku = wc_get_product_id_by_sku($sku); 1104 1105 if ($product_id_by_sku) { 1106 $product = wc_get_product($product_id_by_sku); 1107 } else { 1108 return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404)); 1109 } 1110 } 1111 elseif ($product_id) { 1112 $product = wc_get_product($product_id); 1113 } 1114 1115 if (!isset($product) || !$product) { 1116 return new WP_Error('product_not_found', 'Product not found', array('status' => 404)); 1117 } 1118 1119 if (!$categories) { 1120 return new WP_Error('invalid_input', 'Categories empty', array('status' => 400)); 1121 } 1122 1123 // Validate that all categories exist 1124 foreach ($categories as $cat_id) { 1125 $term = get_term($cat_id, 'product_cat'); 1126 1127 if (!$term || is_wp_error($term)) { 1128 return new WP_Error('category_not_found', "Category ID {$cat_id} does not exist", array('status' => 404)); 1129 } 1130 } 1131 1132 // Get current categories on the product 1133 $existing_cat_ids = wp_get_object_terms($product_id, 'product_cat', array('fields' => 'ids')); 1134 1135 // Merge and deduplicate 1136 $final_cat_ids = array_unique(array_merge($existing_cat_ids, $categories)); 1137 1138 wp_set_object_terms($product_id, $final_cat_ids, 'product_cat'); 1139 1140 return new WP_REST_Response(array( 1141 'success' => true, 1142 'product_id' => $product_id, 1143 'assigned_category_ids' => $final_cat_ids 1144 ), 200); 1145 } 1146 1147 /** 1148 * Get product brands 1149 * 1150 * @param WP_REST_Request $request 1151 * @return WP_REST_Response 1152 */ 1153 public function get_brand(WP_REST_Request $request) { 1154 $params = $request->get_params(); 1155 $taxonomy = isset($params['taxonomy']) ? sanitize_text_field($params['taxonomy']) : 'product_brand'; 1156 $id = isset($params['id']) ? absint($params['id']) : 0; 1157 $slug = isset($params['slug']) ? sanitize_title($params['slug']) : ''; 1158 $name = isset($params['name']) ? sanitize_text_field($params['name']) : ''; 1159 1160 if ($id) { 1161 $term = get_term($id, $taxonomy); 1162 } elseif ($slug) { 1163 $term = get_term_by('slug', $slug, $taxonomy); 1164 } elseif ($name) { 1165 $term = get_term_by('name', $name, $taxonomy); 1166 } 1167 1168 if (empty($term) || is_wp_error($term)) { 1169 return new WP_Error('no_brand_found', "No brand found under the " . $taxonomy . " taxonomy.", array('status' => 400)); 1170 } 1171 1172 $term_id = $term->term_id; 1173 $brand_data = (array) $term; 1174 1175 // Get thumbnail ID and URL 1176 $thumbnail_id = get_term_meta($term_id, 'thumbnail_id', true); 1177 $thumbnail_url = $thumbnail_id ? wp_get_attachment_url($thumbnail_id) : ''; 1178 1179 if ($thumbnail_url) { 1180 $brand_data['thumbnail'] = $thumbnail_url; 1181 } 1182 1183 // Get Yoast SEO meta fields 1184 $yoast_option = get_option('wpseo_taxonomy_meta'); 1185 $yoast_data = []; 1186 1187 if (isset($yoast_option[$taxonomy]) && isset($yoast_option[$taxonomy][$term_id])) { 1188 $yoast_raw = $yoast_option[$taxonomy][$term_id]; 1189 $yoast_data = array( 1190 'title' => $yoast_raw['wpseo_title'] ?? '', 1191 'description' => $yoast_raw['wpseo_desc'] ?? '', 1192 'premium' => array( 1193 'social_appearance' => array( 1194 'title' => $yoast_raw['wpseo_opengraph-title'] ?? '', 1195 'description' => $yoast_raw['wpseo_opengraph-description'] ?? '', 1196 'image' => $yoast_raw['wpseo_opengraph-image'] ?? '', 1197 ), 1198 'x' => array( 1199 'title' => $yoast_raw['wpseo_twitter-title'] ?? '', 1200 'description' => $yoast_raw['wpseo_twitter-description'] ?? '', 1201 'image' => $yoast_raw['wpseo_twitter-image'] ?? '', 1202 ) 1203 ) 1204 ); 1205 } 1206 885 1207 $brand_data['yoast'] = $yoast_data; 886 1208 -
content-api/tags/1.0.3/readme.txt
r3284442 r3288294 3 3 Tags: content api, rest api, content, creative, api 4 4 Tested up to: 6.8 5 Stable tag: 1.0. 25 Stable tag: 1.0.3 6 6 Requires PHP: 7.4 7 7 License: GPLv3 … … 85 85 == Changelog == 86 86 87 = 1.0.3 = 88 * Added: [Get Product Category](https://www.polyplugins.com/docs/content-api/api/get-product-category/) endpoint 89 * Added: [Update Product Category](https://www.polyplugins.com/docs/content-api/api/update-product-category/) endpoint 90 * Added: [Create Product Category](https://www.polyplugins.com/docs/content-api/api/create-product-category/) endpoint 91 * Updated: [Get Brand](https://www.polyplugins.com/docs/content-api/api/get-brand/) endpoint (Previous endpoint is an alias) 92 * Updated: [Update Brand](https://www.polyplugins.com/docs/content-api/api/update-brand/) endpoint (Previous endpoint is an alias) 93 * Updated: [Create Brand](https://www.polyplugins.com/docs/content-api/api/create-brand/) endpoint (Previous endpoint is an alias) 94 87 95 = 1.0.2 = 88 96 * Added: [Get Brand](https://www.polyplugins.com/docs/content-api/api/get-brand/) endpoint -
content-api/trunk/content-api.php
r3284442 r3288294 5 5 * Plugin URI: https://www.polyplugins.com/contact/ 6 6 * Description: Adds various endpoints to create content 7 * Version: 1.0. 27 * Version: 1.0.3 8 8 * Requires at least: 6.5 9 9 * Requires PHP: 7.4 … … 63 63 )); 64 64 65 register_rest_route('content-api/v1', '/product-category/', array( 66 'methods' => 'GET', 67 'callback' => array($this, 'get_product_category'), 68 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 69 )); 70 71 register_rest_route('content-api/v1', '/product-category/', array( 72 'methods' => 'PATCH', 73 'callback' => array($this, 'update_product_category'), 74 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 75 )); 76 77 register_rest_route('content-api/v1', '/product-category/', array( 78 'methods' => 'POST', 79 'callback' => array($this, 'create_product_category'), 80 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 81 )); 82 65 83 register_rest_route('content-api/v1', '/product-categories/', array( 66 84 'methods' => 'GET', … … 108 126 'methods' => 'GET', 109 127 'callback' => array($this, 'get_product_attributes'), 128 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 129 )); 130 131 register_rest_route('content-api/v1', '/product-brand/', array( 132 'methods' => 'GET', 133 'callback' => array($this, 'get_brand'), 134 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 135 )); 136 137 register_rest_route('content-api/v1', '/product-brand/', array( 138 'methods' => 'PATCH', 139 'callback' => array($this, 'update_brand'), 140 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 141 )); 142 143 register_rest_route('content-api/v1', '/product-brand/', array( 144 'methods' => 'POST', 145 'callback' => array($this, 'create_brand'), 110 146 'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security 111 147 )); … … 656 692 657 693 /** 658 * Get product categor ies694 * Get product category 659 695 * 660 696 * @param mixed $request 661 697 * @return void 662 698 */ 663 public function get_product_categories(WP_REST_Request $request) { 664 $this->options = get_option('content_api_options_polyplugins'); 665 666 $fields = $request->get_json_params(); 667 $product_id = isset($fields['product_id']) ? absint($fields['product_id']) : 0; 668 $sku = isset($fields['sku']) ? sanitize_text_field($fields['sku']) : ''; 669 670 if (!$product_id && !$sku) { 671 return new WP_Error('missing_identifier', 'Product ID or SKU is required', array('status' => 400)); 672 } 673 674 if ($product_id) { 675 if (!is_numeric($product_id)) { 676 return new WP_Error('product_id_invalid', 'Product ID is invalid', array('status' => 400)); 677 } 678 } 679 680 if ($sku) { 681 if ($sku !== sanitize_text_field($sku)) { 682 return new WP_Error('sku_invalid', 'SKU is invalid', array('status' => 400)); 683 } 684 } 685 686 if ($product_id && $sku) { 687 return new WP_Error('conflicting_identifiers', 'Both Product ID and SKU are provided. Please provide only one.', array('status' => 400)); 688 } 689 690 if ($sku && !$product_id) { 691 $product_id_by_sku = wc_get_product_id_by_sku($sku); 692 693 if ($product_id_by_sku) { 694 $product = wc_get_product($product_id_by_sku); 695 } else { 696 return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404)); 697 } 698 } 699 elseif ($product_id) { 700 $product = wc_get_product($product_id); 701 } 702 703 if (!isset($product) || !$product) { 704 return new WP_Error('product_not_found', 'Product not found', array('status' => 404)); 705 } 706 707 $categories = wp_get_post_terms($product->get_id(), 'product_cat'); 708 709 // Map terms by ID 710 $term_map = array(); 711 foreach ($categories as $term) { 712 $term_map[$term->term_id] = array( 713 'id' => $term->term_id, 714 'name' => $term->name, 715 'slug' => $term->slug, 716 'children' => array(), 717 'parent' => $term->parent, 718 ); 719 } 720 721 // Build the category tree 722 $tree = array(); 723 724 foreach ($term_map as $id => &$term) { 725 if ($term['parent'] && isset($term_map[$term['parent']])) { 726 $term_map[$term['parent']]['children'][] = &$term; 727 } else { 728 $tree[] = &$term; 729 } 730 } 731 unset($term); // Break the reference 732 733 // Prepare category data 734 $category_data = array(); 735 foreach ($tree as $term) { 736 $category_data[] = $this->build_category_hierarchy($term); 737 } 738 739 return new WP_REST_Response(array( 740 'success' => true, 741 'product_id'=> $product->get_id(), 742 'categories'=> $category_data 743 ), 200); 744 } 745 746 /** 747 * Update product categories 748 * 749 * @param mixed $request 750 * @return void 751 */ 752 public function update_product_categories(WP_REST_Request $request) { 753 $this->options = get_option('content_api_options_polyplugins'); 754 755 $fields = $request->get_json_params(); 756 $product_id = isset($fields['product_id']) ? absint($fields['product_id']) : 0; 757 $sku = isset($fields['sku']) ? sanitize_text_field($fields['sku']) : ''; 758 $categories = isset($fields['categories']) ? array_map('absint', $fields['categories']) : array(); 759 760 if (!$product_id && !$sku) { 761 return new WP_Error('missing_identifier', 'Product ID or SKU is required', array('status' => 400)); 762 } 763 764 if ($product_id) { 765 if (!is_numeric($product_id)) { 766 return new WP_Error('product_id_invalid', 'Product ID is invalid', array('status' => 400)); 767 } 768 } 769 770 if ($sku) { 771 if ($sku !== sanitize_text_field($sku)) { 772 return new WP_Error('sku_invalid', 'SKU is invalid', array('status' => 400)); 773 } 774 } 775 776 if ($product_id && $sku) { 777 return new WP_Error('conflicting_identifiers', 'Both Product ID and SKU are provided. Please provide only one.', array('status' => 400)); 778 } 779 780 if ($sku && !$product_id) { 781 $product_id_by_sku = wc_get_product_id_by_sku($sku); 782 783 if ($product_id_by_sku) { 784 $product = wc_get_product($product_id_by_sku); 785 } else { 786 return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404)); 787 } 788 } 789 elseif ($product_id) { 790 $product = wc_get_product($product_id); 791 } 792 793 if (!isset($product) || !$product) { 794 return new WP_Error('product_not_found', 'Product not found', array('status' => 404)); 795 } 796 797 if (!$categories) { 798 return new WP_Error('invalid_input', 'Categories empty', array('status' => 400)); 799 } 800 801 // Validate that all categories exist 802 foreach ($categories as $cat_id) { 803 $term = get_term($cat_id, 'product_cat'); 804 805 if (!$term || is_wp_error($term)) { 806 return new WP_Error('category_not_found', "Category ID {$cat_id} does not exist", array('status' => 404)); 807 } 808 } 809 810 // Get current categories on the product 811 $existing_cat_ids = wp_get_object_terms($product_id, 'product_cat', array('fields' => 'ids')); 812 813 // Merge and deduplicate 814 $final_cat_ids = array_unique(array_merge($existing_cat_ids, $categories)); 815 816 wp_set_object_terms($product_id, $final_cat_ids, 'product_cat'); 817 818 return new WP_REST_Response(array( 819 'success' => true, 820 'product_id' => $product_id, 821 'assigned_category_ids' => $final_cat_ids 822 ), 200); 823 } 824 825 /** 826 * Get product brands 827 * 828 * @param WP_REST_Request $request 829 * @return WP_REST_Response 830 */ 831 public function get_brand(WP_REST_Request $request) { 699 public function get_product_category(WP_REST_Request $request) { 832 700 $params = $request->get_params(); 833 $taxonomy = isset($params['taxonomy']) ? sanitize_text_field($params['taxonomy']) : 'product_ brand';701 $taxonomy = isset($params['taxonomy']) ? sanitize_text_field($params['taxonomy']) : 'product_cat'; 834 702 $id = isset($params['id']) ? absint($params['id']) : 0; 835 703 $slug = isset($params['slug']) ? sanitize_title($params['slug']) : ''; … … 845 713 846 714 if (empty($term) || is_wp_error($term)) { 847 return new WP_Error('no_ brand_found', "No brandfound under the " . $taxonomy . " taxonomy.", array('status' => 400));848 } 849 850 $term_id = $term->term_id;851 $ brand_data = (array) $term;715 return new WP_Error('no_product_category_found', "No category found under the " . $taxonomy . " taxonomy.", array('status' => 400)); 716 } 717 718 $term_id = $term->term_id; 719 $product_category_data = (array) $term; 852 720 853 721 // Get thumbnail ID and URL … … 856 724 857 725 if ($thumbnail_url) { 858 $ brand_data['thumbnail'] = $thumbnail_url;726 $product_category_data['thumbnail'] = $thumbnail_url; 859 727 } 860 728 … … 883 751 } 884 752 753 $product_category_data['yoast'] = $yoast_data; 754 755 return new WP_REST_Response(array( 756 'success' => true, 757 'data' => $product_category_data, 758 ), 201); 759 } 760 761 /** 762 * Update product category 763 * 764 * @param mixed $request 765 * @return void 766 */ 767 public function update_product_category(WP_REST_Request $request) { 768 $fields = $request->get_json_params(); 769 $id = isset($fields['id']) ? absint($fields['id']) : 0; 770 $name = isset($fields['name']) ? sanitize_text_field($fields['name']) : ''; 771 $description = isset($fields['description']) ? wp_kses_post($fields['description']) : ''; 772 $slug = isset($fields['slug']) ? sanitize_title($fields['slug']) : ''; 773 $parent_id = isset($fields['parent']) ? absint($fields['parent']) : ''; 774 $taxonomy = isset($fields['taxonomy']) ? sanitize_text_field($fields['taxonomy']) : 'product_cat'; 775 776 // Basic input validation 777 if (!$id) { 778 return new WP_Error('missing_identifier', 'Product category ID is required', array('status' => 400)); 779 } 780 781 $term = get_term($id, $taxonomy); 782 783 if (!$term || is_wp_error($term)) { 784 return new WP_Error('category_not_found', 'Product category not found', array('status' => 404)); 785 } 786 787 $term_id = $term->term_id; 788 789 $term_args = []; 790 791 if ($name) { 792 $term_args['name'] = $name; 793 } 794 795 if ($description) { 796 $term_args['description'] = $description; 797 } 798 799 if ($slug) { 800 $term_args['slug'] = $slug; 801 } 802 803 if ($parent_id > 0) { 804 $parent_term = get_term($parent_id, $taxonomy); 805 806 if ($parent_term && !is_wp_error($parent_term)) { 807 $term_args['parent'] = $parent_id; 808 } else { 809 return new WP_Error('invalid_parent', 'The specified parent product category does not exist.', array('status' => 400)); 810 } 811 } elseif ($parent_id === 0) { 812 $term_args['parent'] = 0; // Remove parent 813 } 814 815 if (!empty($term_args)) { 816 $result = wp_update_term($term_id, $taxonomy, $term_args); 817 818 if (is_wp_error($result)) { 819 return new WP_Error('term_update_failed', 'Failed to update product category term', array('status' => 500)); 820 } 821 } 822 823 // Update Yoast fields 824 if (isset($fields['yoast']) && is_array($fields['yoast'])) { 825 $yoast_option = get_option('wpseo_taxonomy_meta'); 826 827 if (!isset($yoast_option[$taxonomy])) { 828 $yoast_option[$taxonomy] = []; 829 } 830 831 if (!isset($yoast_option[$taxonomy][$term_id])) { 832 $yoast_option[$taxonomy][$term_id] = []; 833 } 834 835 $yoast_input = $fields['yoast']; 836 837 if (isset($yoast_input['title']) && $yoast_input['title']) { 838 $yoast_option[$taxonomy][$term_id]['wpseo_title'] = $yoast_input['title']; 839 } 840 841 if (isset($yoast_input['description']) && $yoast_input['description']) { 842 $yoast_option[$taxonomy][$term_id]['wpseo_desc'] = $yoast_input['description']; 843 } 844 845 if (isset($yoast_input['premium']['social_appearance']['title']) && $yoast_input['premium']['social_appearance']['title']) { 846 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-title'] = $yoast_input['premium']['social_appearance']['title']; 847 } 848 849 if (isset($yoast_input['premium']['social_appearance']['description']) && $yoast_input['premium']['social_appearance']['description']) { 850 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-description'] = $yoast_input['premium']['social_appearance']['description']; 851 } 852 853 if (isset($yoast_input['premium']['social_appearance']['image']) && $yoast_input['premium']['social_appearance']['image']) { 854 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-image'] = $yoast_input['premium']['social_appearance']['image']; 855 } 856 857 if (isset($yoast_input['premium']['x']['title']) && $yoast_input['premium']['x']['title']) { 858 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-title'] = $yoast_input['premium']['x']['title']; 859 } 860 861 if (isset($yoast_input['premium']['x']['description']) && $yoast_input['premium']['x']['description']) { 862 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-description'] = $yoast_input['premium']['x']['description']; 863 } 864 865 if (isset($yoast_input['premium']['x']['image']) && $yoast_input['premium']['x']['image']) { 866 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-image'] = $yoast_input['premium']['x']['image']; 867 } 868 869 update_option('wpseo_taxonomy_meta', $yoast_option); 870 } 871 872 return new WP_REST_Response(array( 873 'success' => true, 874 'product_category_id' => $term_id, 875 'message' => 'Product category updated successfully.' 876 ), 200); 877 } 878 879 /** 880 * Create product category 881 * 882 * @param mixed $request 883 * @return void 884 */ 885 public function create_product_category(WP_REST_Request $request) { 886 $fields = $request->get_json_params(); 887 $name = isset($fields['name']) ? sanitize_text_field($fields['name']) : ''; 888 $description = isset($fields['description']) ? wp_kses_post($fields['description']) : ''; 889 $slug = isset($fields['slug']) ? sanitize_title($fields['slug']) : ''; 890 $parent_id = isset($fields['parent']) ? absint($fields['parent']) : 0; 891 $taxonomy = isset($fields['taxonomy']) ? sanitize_text_field($fields['taxonomy']) : 'product_cat'; 892 893 // Validate name 894 if (empty($name)) { 895 return new WP_Error('missing_name', 'Product category name is required.', array('status' => 400)); 896 } 897 898 $term_args = array( 899 'description' => $description, 900 'slug' => $slug, 901 'parent' => 0 902 ); 903 904 if ($parent_id > 0) { 905 $parent_term = get_term($parent_id, $taxonomy); 906 907 if ($parent_term && !is_wp_error($parent_term)) { 908 $term_args['parent'] = $parent_id; 909 } else { 910 return new WP_Error('invalid_parent', 'The specified parent product category does not exist.', array('status' => 400)); 911 } 912 } 913 914 // Create the term 915 $result = wp_insert_term($name, $taxonomy, $term_args); 916 917 if (is_wp_error($result)) { 918 return new WP_Error('term_creation_failed', $result->get_error_message(), array('status' => 500)); 919 } 920 921 $term_id = $result['term_id']; 922 923 // Update Yoast fields 924 if (isset($fields['yoast']) && is_array($fields['yoast'])) { 925 $yoast_option = get_option('wpseo_taxonomy_meta'); 926 927 if (!isset($yoast_option[$taxonomy])) { 928 $yoast_option[$taxonomy] = array(); 929 } 930 931 if (!isset($yoast_option[$taxonomy][$term_id])) { 932 $yoast_option[$taxonomy][$term_id] = array(); 933 } 934 935 $yoast_input = $fields['yoast']; 936 937 if (!empty($yoast_input['title'])) { 938 $yoast_option[$taxonomy][$term_id]['wpseo_title'] = $yoast_input['title']; 939 } 940 941 if (!empty($yoast_input['description'])) { 942 $yoast_option[$taxonomy][$term_id]['wpseo_desc'] = $yoast_input['description']; 943 } 944 945 if (!empty($yoast_input['premium']['social_appearance']['title'])) { 946 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-title'] = $yoast_input['premium']['social_appearance']['title']; 947 } 948 949 if (!empty($yoast_input['premium']['social_appearance']['description'])) { 950 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-description'] = $yoast_input['premium']['social_appearance']['description']; 951 } 952 953 if (!empty($yoast_input['premium']['social_appearance']['image'])) { 954 $yoast_option[$taxonomy][$term_id]['wpseo_opengraph-image'] = $yoast_input['premium']['social_appearance']['image']; 955 } 956 957 if (!empty($yoast_input['premium']['x']['title'])) { 958 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-title'] = $yoast_input['premium']['x']['title']; 959 } 960 961 if (!empty($yoast_input['premium']['x']['description'])) { 962 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-description'] = $yoast_input['premium']['x']['description']; 963 } 964 965 if (!empty($yoast_input['premium']['x']['image'])) { 966 $yoast_option[$taxonomy][$term_id]['wpseo_twitter-image'] = $yoast_input['premium']['x']['image']; 967 } 968 969 update_option('wpseo_taxonomy_meta', $yoast_option); 970 } 971 972 return new WP_REST_Response(array( 973 'success' => true, 974 'product_category_id' => $term_id, 975 'message' => 'Product category created successfully.' 976 ), 201); 977 } 978 979 /** 980 * Get product categories 981 * 982 * @param mixed $request 983 * @return void 984 */ 985 public function get_product_categories(WP_REST_Request $request) { 986 $this->options = get_option('content_api_options_polyplugins'); 987 988 $fields = $request->get_json_params(); 989 $product_id = isset($fields['product_id']) ? absint($fields['product_id']) : 0; 990 $sku = isset($fields['sku']) ? sanitize_text_field($fields['sku']) : ''; 991 992 if (!$product_id && !$sku) { 993 return new WP_Error('missing_identifier', 'Product ID or SKU is required', array('status' => 400)); 994 } 995 996 if ($product_id) { 997 if (!is_numeric($product_id)) { 998 return new WP_Error('product_id_invalid', 'Product ID is invalid', array('status' => 400)); 999 } 1000 } 1001 1002 if ($sku) { 1003 if ($sku !== sanitize_text_field($sku)) { 1004 return new WP_Error('sku_invalid', 'SKU is invalid', array('status' => 400)); 1005 } 1006 } 1007 1008 if ($product_id && $sku) { 1009 return new WP_Error('conflicting_identifiers', 'Both Product ID and SKU are provided. Please provide only one.', array('status' => 400)); 1010 } 1011 1012 if ($sku && !$product_id) { 1013 $product_id_by_sku = wc_get_product_id_by_sku($sku); 1014 1015 if ($product_id_by_sku) { 1016 $product = wc_get_product($product_id_by_sku); 1017 } else { 1018 return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404)); 1019 } 1020 } 1021 elseif ($product_id) { 1022 $product = wc_get_product($product_id); 1023 } 1024 1025 if (!isset($product) || !$product) { 1026 return new WP_Error('product_not_found', 'Product not found', array('status' => 404)); 1027 } 1028 1029 $categories = wp_get_post_terms($product->get_id(), 'product_cat'); 1030 1031 // Map terms by ID 1032 $term_map = array(); 1033 foreach ($categories as $term) { 1034 $term_map[$term->term_id] = array( 1035 'id' => $term->term_id, 1036 'name' => $term->name, 1037 'slug' => $term->slug, 1038 'children' => array(), 1039 'parent' => $term->parent, 1040 ); 1041 } 1042 1043 // Build the category tree 1044 $tree = array(); 1045 1046 foreach ($term_map as $id => &$term) { 1047 if ($term['parent'] && isset($term_map[$term['parent']])) { 1048 $term_map[$term['parent']]['children'][] = &$term; 1049 } else { 1050 $tree[] = &$term; 1051 } 1052 } 1053 unset($term); // Break the reference 1054 1055 // Prepare category data 1056 $category_data = array(); 1057 foreach ($tree as $term) { 1058 $category_data[] = $this->build_category_hierarchy($term); 1059 } 1060 1061 return new WP_REST_Response(array( 1062 'success' => true, 1063 'product_id'=> $product->get_id(), 1064 'categories'=> $category_data 1065 ), 200); 1066 } 1067 1068 /** 1069 * Update product categories 1070 * 1071 * @param mixed $request 1072 * @return void 1073 */ 1074 public function update_product_categories(WP_REST_Request $request) { 1075 $this->options = get_option('content_api_options_polyplugins'); 1076 1077 $fields = $request->get_json_params(); 1078 $product_id = isset($fields['product_id']) ? absint($fields['product_id']) : 0; 1079 $sku = isset($fields['sku']) ? sanitize_text_field($fields['sku']) : ''; 1080 $categories = isset($fields['categories']) ? array_map('absint', $fields['categories']) : array(); 1081 1082 if (!$product_id && !$sku) { 1083 return new WP_Error('missing_identifier', 'Product ID or SKU is required', array('status' => 400)); 1084 } 1085 1086 if ($product_id) { 1087 if (!is_numeric($product_id)) { 1088 return new WP_Error('product_id_invalid', 'Product ID is invalid', array('status' => 400)); 1089 } 1090 } 1091 1092 if ($sku) { 1093 if ($sku !== sanitize_text_field($sku)) { 1094 return new WP_Error('sku_invalid', 'SKU is invalid', array('status' => 400)); 1095 } 1096 } 1097 1098 if ($product_id && $sku) { 1099 return new WP_Error('conflicting_identifiers', 'Both Product ID and SKU are provided. Please provide only one.', array('status' => 400)); 1100 } 1101 1102 if ($sku && !$product_id) { 1103 $product_id_by_sku = wc_get_product_id_by_sku($sku); 1104 1105 if ($product_id_by_sku) { 1106 $product = wc_get_product($product_id_by_sku); 1107 } else { 1108 return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404)); 1109 } 1110 } 1111 elseif ($product_id) { 1112 $product = wc_get_product($product_id); 1113 } 1114 1115 if (!isset($product) || !$product) { 1116 return new WP_Error('product_not_found', 'Product not found', array('status' => 404)); 1117 } 1118 1119 if (!$categories) { 1120 return new WP_Error('invalid_input', 'Categories empty', array('status' => 400)); 1121 } 1122 1123 // Validate that all categories exist 1124 foreach ($categories as $cat_id) { 1125 $term = get_term($cat_id, 'product_cat'); 1126 1127 if (!$term || is_wp_error($term)) { 1128 return new WP_Error('category_not_found', "Category ID {$cat_id} does not exist", array('status' => 404)); 1129 } 1130 } 1131 1132 // Get current categories on the product 1133 $existing_cat_ids = wp_get_object_terms($product_id, 'product_cat', array('fields' => 'ids')); 1134 1135 // Merge and deduplicate 1136 $final_cat_ids = array_unique(array_merge($existing_cat_ids, $categories)); 1137 1138 wp_set_object_terms($product_id, $final_cat_ids, 'product_cat'); 1139 1140 return new WP_REST_Response(array( 1141 'success' => true, 1142 'product_id' => $product_id, 1143 'assigned_category_ids' => $final_cat_ids 1144 ), 200); 1145 } 1146 1147 /** 1148 * Get product brands 1149 * 1150 * @param WP_REST_Request $request 1151 * @return WP_REST_Response 1152 */ 1153 public function get_brand(WP_REST_Request $request) { 1154 $params = $request->get_params(); 1155 $taxonomy = isset($params['taxonomy']) ? sanitize_text_field($params['taxonomy']) : 'product_brand'; 1156 $id = isset($params['id']) ? absint($params['id']) : 0; 1157 $slug = isset($params['slug']) ? sanitize_title($params['slug']) : ''; 1158 $name = isset($params['name']) ? sanitize_text_field($params['name']) : ''; 1159 1160 if ($id) { 1161 $term = get_term($id, $taxonomy); 1162 } elseif ($slug) { 1163 $term = get_term_by('slug', $slug, $taxonomy); 1164 } elseif ($name) { 1165 $term = get_term_by('name', $name, $taxonomy); 1166 } 1167 1168 if (empty($term) || is_wp_error($term)) { 1169 return new WP_Error('no_brand_found', "No brand found under the " . $taxonomy . " taxonomy.", array('status' => 400)); 1170 } 1171 1172 $term_id = $term->term_id; 1173 $brand_data = (array) $term; 1174 1175 // Get thumbnail ID and URL 1176 $thumbnail_id = get_term_meta($term_id, 'thumbnail_id', true); 1177 $thumbnail_url = $thumbnail_id ? wp_get_attachment_url($thumbnail_id) : ''; 1178 1179 if ($thumbnail_url) { 1180 $brand_data['thumbnail'] = $thumbnail_url; 1181 } 1182 1183 // Get Yoast SEO meta fields 1184 $yoast_option = get_option('wpseo_taxonomy_meta'); 1185 $yoast_data = []; 1186 1187 if (isset($yoast_option[$taxonomy]) && isset($yoast_option[$taxonomy][$term_id])) { 1188 $yoast_raw = $yoast_option[$taxonomy][$term_id]; 1189 $yoast_data = array( 1190 'title' => $yoast_raw['wpseo_title'] ?? '', 1191 'description' => $yoast_raw['wpseo_desc'] ?? '', 1192 'premium' => array( 1193 'social_appearance' => array( 1194 'title' => $yoast_raw['wpseo_opengraph-title'] ?? '', 1195 'description' => $yoast_raw['wpseo_opengraph-description'] ?? '', 1196 'image' => $yoast_raw['wpseo_opengraph-image'] ?? '', 1197 ), 1198 'x' => array( 1199 'title' => $yoast_raw['wpseo_twitter-title'] ?? '', 1200 'description' => $yoast_raw['wpseo_twitter-description'] ?? '', 1201 'image' => $yoast_raw['wpseo_twitter-image'] ?? '', 1202 ) 1203 ) 1204 ); 1205 } 1206 885 1207 $brand_data['yoast'] = $yoast_data; 886 1208 -
content-api/trunk/readme.txt
r3284442 r3288294 3 3 Tags: content api, rest api, content, creative, api 4 4 Tested up to: 6.8 5 Stable tag: 1.0. 25 Stable tag: 1.0.3 6 6 Requires PHP: 7.4 7 7 License: GPLv3 … … 85 85 == Changelog == 86 86 87 = 1.0.3 = 88 * Added: [Get Product Category](https://www.polyplugins.com/docs/content-api/api/get-product-category/) endpoint 89 * Added: [Update Product Category](https://www.polyplugins.com/docs/content-api/api/update-product-category/) endpoint 90 * Added: [Create Product Category](https://www.polyplugins.com/docs/content-api/api/create-product-category/) endpoint 91 * Updated: [Get Brand](https://www.polyplugins.com/docs/content-api/api/get-brand/) endpoint (Previous endpoint is an alias) 92 * Updated: [Update Brand](https://www.polyplugins.com/docs/content-api/api/update-brand/) endpoint (Previous endpoint is an alias) 93 * Updated: [Create Brand](https://www.polyplugins.com/docs/content-api/api/create-brand/) endpoint (Previous endpoint is an alias) 94 87 95 = 1.0.2 = 88 96 * Added: [Get Brand](https://www.polyplugins.com/docs/content-api/api/get-brand/) endpoint
Note: See TracChangeset
for help on using the changeset viewer.