Plugin Directory

Changeset 3288294


Ignore:
Timestamp:
05/06/2025 09:04:55 AM (10 months ago)
Author:
polyplugins
Message:

Update to version 1.0.3 from GitHub

Location:
content-api
Files:
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • content-api/tags/1.0.3/content-api.php

    r3284442 r3288294  
    55 * Plugin URI: https://www.polyplugins.com/contact/
    66 * Description: Adds various endpoints to create content
    7  * Version: 1.0.2
     7 * Version: 1.0.3
    88 * Requires at least: 6.5
    99 * Requires PHP: 7.4
     
    6363    ));
    6464
     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
    6583    register_rest_route('content-api/v1', '/product-categories/', array(
    6684      'methods' => 'GET',
     
    108126      'methods' => 'GET',
    109127      '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'),
    110146      'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security
    111147    ));
     
    656692 
    657693  /**
    658    * Get product categories
     694   * Get product category
    659695   *
    660696   * @param  mixed $request
    661697   * @return void
    662698   */
    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) {
    832700    $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';
    834702    $id       = isset($params['id']) ? absint($params['id']) : 0;
    835703    $slug     = isset($params['slug']) ? sanitize_title($params['slug']) : '';
     
    845713
    846714    if (empty($term) || is_wp_error($term)) {
    847       return new WP_Error('no_brand_found', "No brand found 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;
    852720
    853721    // Get thumbnail ID and URL
     
    856724
    857725    if ($thumbnail_url) {
    858       $brand_data['thumbnail'] = $thumbnail_url;
     726      $product_category_data['thumbnail'] = $thumbnail_url;
    859727    }
    860728
     
    883751    }
    884752
     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
    8851207    $brand_data['yoast'] = $yoast_data;
    8861208
  • content-api/tags/1.0.3/readme.txt

    r3284442 r3288294  
    33Tags: content api, rest api, content, creative, api
    44Tested up to: 6.8
    5 Stable tag: 1.0.2
     5Stable tag: 1.0.3
    66Requires PHP: 7.4
    77License: GPLv3
     
    8585== Changelog ==
    8686
     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
    8795= 1.0.2 =
    8896* Added: [Get Brand](https://www.polyplugins.com/docs/content-api/api/get-brand/) endpoint
  • content-api/trunk/content-api.php

    r3284442 r3288294  
    55 * Plugin URI: https://www.polyplugins.com/contact/
    66 * Description: Adds various endpoints to create content
    7  * Version: 1.0.2
     7 * Version: 1.0.3
    88 * Requires at least: 6.5
    99 * Requires PHP: 7.4
     
    6363    ));
    6464
     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
    6583    register_rest_route('content-api/v1', '/product-categories/', array(
    6684      'methods' => 'GET',
     
    108126      'methods' => 'GET',
    109127      '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'),
    110146      'permission_callback' => array($this, 'has_permission'), // Add your permission callback for security
    111147    ));
     
    656692 
    657693  /**
    658    * Get product categories
     694   * Get product category
    659695   *
    660696   * @param  mixed $request
    661697   * @return void
    662698   */
    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) {
    832700    $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';
    834702    $id       = isset($params['id']) ? absint($params['id']) : 0;
    835703    $slug     = isset($params['slug']) ? sanitize_title($params['slug']) : '';
     
    845713
    846714    if (empty($term) || is_wp_error($term)) {
    847       return new WP_Error('no_brand_found', "No brand found 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;
    852720
    853721    // Get thumbnail ID and URL
     
    856724
    857725    if ($thumbnail_url) {
    858       $brand_data['thumbnail'] = $thumbnail_url;
     726      $product_category_data['thumbnail'] = $thumbnail_url;
    859727    }
    860728
     
    883751    }
    884752
     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
    8851207    $brand_data['yoast'] = $yoast_data;
    8861208
  • content-api/trunk/readme.txt

    r3284442 r3288294  
    33Tags: content api, rest api, content, creative, api
    44Tested up to: 6.8
    5 Stable tag: 1.0.2
     5Stable tag: 1.0.3
    66Requires PHP: 7.4
    77License: GPLv3
     
    8585== Changelog ==
    8686
     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
    8795= 1.0.2 =
    8896* Added: [Get Brand](https://www.polyplugins.com/docs/content-api/api/get-brand/) endpoint
Note: See TracChangeset for help on using the changeset viewer.