Skip to content

Commit 801458c

Browse files
authored
Merge pull request #11 from PolyPlugins/version/1.0.11
Updated: Get Product manage_stock attribute to return a bool
2 parents 10735d9 + 5d0edec commit 801458c

File tree

3 files changed

+178
-23
lines changed

3 files changed

+178
-23
lines changed

README.MD

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ Yes, the plugin supports uploading images to the WordPress media library via the
6565

6666
## Changelog
6767

68+
### 1.0.11
69+
* Updated: [Get Product](https://www.polyplugins.com/docs/content-api/api/get-product/) manage_stock attribute to return a bool
70+
* Updated: [Update Product](https://www.polyplugins.com/docs/content-api/api/update-product/) manage_stock attribute to be able to use bool
71+
* Updated: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) manage_stock attribute to be able to use bool
72+
* Bugfix: [Update Product](https://www.polyplugins.com/docs/content-api/api/update-product/) attributes attribute not creating product attributes when they don't exist.
73+
* Bugfix: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) attributes attribute not creating product attributes when they don't exist.
74+
* Bugfix: [Update Product](https://www.polyplugins.com/docs/content-api/api/update-product/) triggering error sku during slug check
75+
* Bugfix: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) triggering error sku during slug check
76+
* Bugfix: [Update Product](https://www.polyplugins.com/docs/content-api/api/update-product/) triggering Exception instead of WP Error when upc attribute is already in use
77+
* Bugfix: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) triggering Exception instead of WP Error when upc attribute is already in use
78+
6879
### 1.0.10
6980
* Updated: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) endpoint to not require quantity
7081

content-api.php

Lines changed: 155 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* Plugin Name: Content API
55
* Plugin URI: https://www.polyplugins.com/contact/
66
* Description: Adds various endpoints to create content
7-
* Version: 1.0.10
7+
* Version: 1.0.11
88
* Requires at least: 6.5
99
* Requires PHP: 7.4
1010
* Author: Poly Plugins
@@ -15,6 +15,7 @@
1515

1616
namespace PolyPlugins;
1717

18+
use Exception;
1819
use WC_Product_Attribute;
1920
use WC_Product_Simple;
2021
use WP_Error;
@@ -506,7 +507,7 @@ public function get_product(WP_REST_Request $request) {
506507
'upc' => $upc ? sanitize_text_field($upc) : '',
507508
'weight' => $weight ? floatval($weight) : '',
508509
'stock_status' => $stock_status ? sanitize_text_field($stock_status) : '',
509-
'manage_stock' => $manage_stock ? sanitize_text_field($manage_stock) : '',
510+
'manage_stock' => $manage_stock ? true : false,
510511
'stock_quantity' => $stock_quantity ? absint($product->get_stock_quantity()) : 0,
511512
'tags' => $tags ? array_map('sanitize_text_field', $tags) : array(),
512513
'categories' => $categories ? array_map('sanitize_text_field', $categories) : array(),
@@ -543,10 +544,11 @@ public function update_product(WP_REST_Request $request) {
543544
$upc = isset($fields['upc']) ? sanitize_text_field($fields['upc']) : '';
544545
$weight = isset($fields['weight']) ? floatval($fields['weight']) : '';
545546
$stock_status = isset($fields['stock_status']) ? sanitize_text_field($fields['stock_status']) : '';
546-
$manage_stock = isset($fields['manage_stock']) ? sanitize_text_field($fields['manage_stock']) : '';
547+
$manage_stock = isset($fields['manage_stock']) ? wc_string_to_bool($fields['manage_stock']) : null;
547548
$stock_quantity = isset($fields['stock_quantity']) ? intval($fields['stock_quantity']) : false;
548549
$tags = isset($fields['tags']) && is_array($fields['tags']) ? array_map('sanitize_text_field', $fields['tags']) : array();
549550
$categories = isset($fields['categories']) && is_array($fields['categories']) ? array_map('sanitize_text_field', $fields['categories']) : array();
551+
$attributes = isset($fields['attributes']) ? $fields['attributes'] : array();
550552
$featured_image = isset($fields['featured_image']) ? sanitize_url($fields['featured_image']) : '';
551553
$images = isset($fields['images']) && is_array($fields['images']) ? array_map('sanitize_url', $fields['images']) : array();
552554
$yoast = isset($fields['yoast']) ? $fields['yoast'] : '';
@@ -575,24 +577,27 @@ public function update_product(WP_REST_Request $request) {
575577
} else {
576578
return new WP_Error('product_not_found', 'Product not found with provided SKU', array('status' => 404));
577579
}
578-
}
579-
elseif ($product_id) {
580+
} elseif ($product_id) {
580581
$product = wc_get_product($product_id);
581582
}
582583

583584
if (!isset($product) || !$product) {
584585
return new WP_Error('product_not_found', 'Product not found', array('status' => 404));
585586
}
586587

587-
if ($slug) {
588-
// Check if slug is empty after sanitization
589-
if (empty($slug)) {
590-
return new WP_Error('slug_invalid', 'Invalid slug format', array('status' => 400));
588+
if ($sku) {
589+
$product_id_by_sku = wc_get_product_id_by_sku($sku);
590+
591+
if ($product_id_by_sku != $product->get_id()) {
592+
return new WP_Error('product_sku_exists', 'Product with provided SKU already exists', array('status' => 404));
591593
}
594+
}
592595

596+
if ($slug) {
593597
// Check if slug already exists for a different product
594598
$existing_product_id = get_page_by_path($slug, OBJECT, get_post_types());
595-
if ($existing_product_id && (($product_id && $existing_product_id->ID != $product_id) || ($sku && $existing_product_id->ID != wc_get_product_id_by_sku($sku)))) {
599+
600+
if ($existing_product_id) {
596601
return new WP_Error('slug_exists', 'Slug already in use by another product', array('status' => 400));
597602
}
598603
}
@@ -643,7 +648,11 @@ public function update_product(WP_REST_Request $request) {
643648
return new WP_Error('upc_malformed', 'UPC must contain only numbers and hyphens', array('status' => 500));
644649
}
645650

646-
$product->update_meta_data('_global_unique_id', $upc);
651+
try {
652+
$product->update_meta_data('_global_unique_id', $upc);
653+
} catch (Exception $e) {
654+
return new WP_Error('product_exception', 'An error occurred when attempting to update UPC. It may be in use, please check your trash.', array('status' => 500));
655+
}
647656
}
648657

649658
if ($weight) {
@@ -654,9 +663,9 @@ public function update_product(WP_REST_Request $request) {
654663
$product->set_stock_status($stock_status);
655664
}
656665

657-
if ($manage_stock == 'true') {
666+
if ($manage_stock === true) {
658667
$product->set_manage_stock(true);
659-
} elseif ($manage_stock == 'false') {
668+
} elseif ($manage_stock === false) {
660669
$product->set_manage_stock(false);
661670
}
662671

@@ -673,6 +682,18 @@ public function update_product(WP_REST_Request $request) {
673682
wp_set_object_terms($product_id, $categories, 'product_cat');
674683
}
675684

685+
if (!empty($attributes) && is_array($attributes)) {
686+
$existing_attributes = $product->get_attributes();
687+
$attributes = $this->create_or_update_product_attributes($attributes, $existing_attributes);
688+
689+
if (is_wp_error($attributes)) {
690+
return $attributes;
691+
}
692+
693+
// Update product attributes
694+
$product->set_attributes($attributes);
695+
}
696+
676697
// Handle featured image
677698
if ($featured_image) {
678699
$image_id = $this->upload_image_to_media_library($featured_image, $product_id);
@@ -736,7 +757,11 @@ public function update_product(WP_REST_Request $request) {
736757
}
737758

738759
// Save the product
739-
$product_id = $product->save();
760+
try {
761+
$product_id = $product->save();
762+
} catch (Exception $e) {
763+
return new WP_Error('product_exception', 'Error saving product. This typically happens if you are trying to create a new product with a SKU already in use, please check your trash.', array('status' => 500));
764+
}
740765

741766
if (!$product_id) {
742767
return new WP_Error('update_failed', 'Failed to update product', array('status' => 500));
@@ -773,10 +798,11 @@ public function create_product(WP_REST_Request $request) {
773798
$upc = isset($fields['upc']) ? sanitize_text_field($fields['upc']) : '';
774799
$weight = isset($fields['weight']) ? floatval($fields['weight']) : '';
775800
$stock_status = isset($fields['stock_status']) ? sanitize_text_field($fields['stock_status']) : '';
776-
$manage_stock = isset($fields['manage_stock']) ? sanitize_text_field($fields['manage_stock']) : '';
801+
$manage_stock = isset($fields['manage_stock']) ? wc_string_to_bool($fields['manage_stock']) : null;
777802
$stock_quantity = isset($fields['stock_quantity']) ? intval($fields['stock_quantity']) : false;
778803
$tags = isset($fields['tags']) && is_array($fields['tags']) ? array_map('sanitize_text_field', $fields['tags']) : array();
779804
$categories = isset($fields['categories']) && is_array($fields['categories']) ? array_map('sanitize_text_field', $fields['categories']) : array();
805+
$attributes = isset($fields['attributes']) ? $fields['attributes'] : array();
780806
$featured_image = isset($fields['featured_image']) ? sanitize_url($fields['featured_image']) : '';
781807
$images = isset($fields['images']) && is_array($fields['images']) ? array_map('sanitize_url', $fields['images']) : array();
782808
$yoast = isset($fields['yoast']) ? $fields['yoast'] : '';
@@ -797,7 +823,9 @@ public function create_product(WP_REST_Request $request) {
797823

798824
if ($slug) {
799825
// Check if slug already exists for a different product
800-
if (wc_get_product_id_by_sku($sku)) {
826+
$existing_product_id = get_page_by_path($slug, OBJECT, get_post_types());
827+
828+
if ($existing_product_id) {
801829
return new WP_Error('slug_exists', 'Slug already in use by another product', array('status' => 400));
802830
}
803831
}
@@ -849,7 +877,11 @@ public function create_product(WP_REST_Request $request) {
849877
return new WP_Error('upc_malformed', 'UPC must contain only numbers and hyphens', array('status' => 500));
850878
}
851879

852-
$product->update_meta_data('_global_unique_id', $upc);
880+
try {
881+
$product->update_meta_data('_global_unique_id', $upc);
882+
} catch (Exception $e) {
883+
return new WP_Error('product_exception', 'An error occurred when attempting to update UPC. It may be in use, please check your trash.', array('status' => 500));
884+
}
853885
}
854886

855887
if ($weight) {
@@ -860,9 +892,9 @@ public function create_product(WP_REST_Request $request) {
860892
$product->set_stock_status($stock_status);
861893
}
862894

863-
if ($manage_stock == 'true') {
895+
if ($manage_stock === true) {
864896
$product->set_manage_stock(true);
865-
} elseif ($manage_stock == 'false') {
897+
} elseif ($manage_stock === false) {
866898
$product->set_manage_stock(false);
867899
}
868900

@@ -912,7 +944,11 @@ public function create_product(WP_REST_Request $request) {
912944
}
913945

914946
// Save the product
915-
$product_id = $product->save();
947+
try {
948+
$product_id = $product->save();
949+
} catch (Exception $e) {
950+
return new WP_Error('product_exception', 'Error saving product. This typically happens if you are trying to create a new product with a SKU already in use, please check your trash.', array('status' => 500));
951+
}
916952

917953
if ($tags) {
918954
wp_set_object_terms($product_id, $tags, 'product_tag');
@@ -922,6 +958,18 @@ public function create_product(WP_REST_Request $request) {
922958
wp_set_object_terms($product_id, $categories, 'product_cat');
923959
}
924960

961+
if (!empty($attributes) && is_array($attributes)) {
962+
$existing_attributes = $product->get_attributes();
963+
$attributes = $this->create_or_update_product_attributes($attributes, $existing_attributes);
964+
965+
if (is_wp_error($attributes)) {
966+
return $attributes;
967+
}
968+
969+
// Update product attributes
970+
$product->set_attributes($attributes);
971+
}
972+
925973
// Handle featured image
926974
if ($featured_image) {
927975
$image_id = $this->upload_image_to_media_library($featured_image, $product_id);
@@ -944,7 +992,11 @@ public function create_product(WP_REST_Request $request) {
944992
$product->set_gallery_image_ids($image_ids);
945993
}
946994

947-
$product->save();
995+
try {
996+
$product->save();
997+
} catch (Exception $e) {
998+
return new WP_Error('product_exception', 'An error occurred when attempting to save the product.', array('status' => 500));
999+
}
9481000

9491001
if (!$product_id) {
9501002
return new WP_Error('creation_failed', 'Failed to create product', array('status' => 500));
@@ -2140,7 +2192,12 @@ public function update_attributes(WP_REST_Request $request)
21402192

21412193
// Update product attributes
21422194
$product->set_attributes($existing_attributes);
2143-
$product->save();
2195+
2196+
try {
2197+
$product->save();
2198+
} catch (Exception $e) {
2199+
return new WP_Error('product_exception', 'An error occurred when attempting to save the product.', array('status' => 500));
2200+
}
21442201

21452202
return new WP_REST_Response(array(
21462203
'success' => true,
@@ -2516,6 +2573,82 @@ private function maybe_create_category($category_name) {
25162573
return false;
25172574
}
25182575

2576+
/**
2577+
* Create or update product attributes
2578+
*
2579+
* @param array $attributes
2580+
* @param array $existing_attributes
2581+
* @return void
2582+
*/
2583+
private function create_or_update_product_attributes($attributes, $existing_attributes) {
2584+
// Loop through new attributes and update/add them
2585+
foreach ($attributes as $attribute) {
2586+
if (!isset($attribute['name']) || !isset($attribute['value'])) {
2587+
return new WP_Error('invalid_attribute', "Each attribute must include 'name' and 'value'", array('status' => 400));
2588+
}
2589+
2590+
$attr_name = sanitize_text_field($attribute['name']);
2591+
$attr_slug = sanitize_title($attribute['name']);
2592+
$attr_value = is_array($attribute['value']) ? array_map('sanitize_text_field', $attribute['value']) : array(sanitize_text_field($attribute['value']));
2593+
$taxonomy = wc_attribute_taxonomy_name($attr_slug);
2594+
2595+
if (!taxonomy_exists($taxonomy)) {
2596+
$attribute_args = array(
2597+
'name' => $attr_name,
2598+
'slug' => $attr_slug,
2599+
);
2600+
2601+
$create_taxonomy = wc_create_attribute($attribute_args);
2602+
2603+
register_taxonomy(
2604+
$taxonomy,
2605+
apply_filters('woocommerce_taxonomy_objects_' . $taxonomy, array('product')),
2606+
apply_filters('woocommerce_taxonomy_args_' . $taxonomy, array(
2607+
'labels' => array(
2608+
'name' => $attr_name,
2609+
),
2610+
'hierarchical' => true,
2611+
'show_ui' => false,
2612+
'query_var' => true,
2613+
'rewrite' => false,
2614+
)
2615+
)
2616+
);
2617+
}
2618+
2619+
// Check if it's a global attribute (taxonomy-based)
2620+
if (taxonomy_exists($taxonomy)) {
2621+
// Ensure terms exist before assigning
2622+
$term_ids = array();
2623+
2624+
foreach ($attr_value as $term_name) {
2625+
$term = term_exists($term_name, $taxonomy);
2626+
2627+
if (!$term) {
2628+
$term = wp_insert_term($term_name, $taxonomy);
2629+
}
2630+
2631+
if (!is_wp_error($term)) {
2632+
$term_ids[] = (int) $term['term_id'];
2633+
}
2634+
}
2635+
2636+
// Set taxonomy-based attribute
2637+
$existing_attributes[$taxonomy] = new WC_Product_Attribute();
2638+
$existing_attributes[$taxonomy]->set_id(wc_attribute_taxonomy_id_by_name($attr_slug));
2639+
$existing_attributes[$taxonomy]->set_name($taxonomy);
2640+
$existing_attributes[$taxonomy]->set_options($term_ids);
2641+
$existing_attributes[$taxonomy]->set_position(0);
2642+
$existing_attributes[$taxonomy]->set_visible(true);
2643+
$existing_attributes[$taxonomy]->set_variation(false);
2644+
} else {
2645+
return new WP_Error('attribute_does_not_exist', "The attribute ". $attr_slug . " does not exist. Attempt to create failed.", array('status' => 400));
2646+
}
2647+
}
2648+
2649+
return $existing_attributes;
2650+
}
2651+
25192652
/**
25202653
* Get product IDs with missing descriptions
25212654
*

readme.txt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Contributors: polyplugins
33
Tags: content api, rest api, content, creative, api
44
Tested up to: 6.8
5-
Stable tag: 1.0.10
5+
Stable tag: 1.0.11
66
Requires PHP: 7.4
77
License: GPLv3
88
License URI: https://www.gnu.org/licenses/gpl-3.0.html
@@ -84,6 +84,17 @@ Yes, the plugin supports uploading images to the WordPress media library via the
8484

8585
== Changelog ==
8686

87+
= 1.0.11 =
88+
* Updated: [Get Product](https://www.polyplugins.com/docs/content-api/api/get-product/) manage_stock attribute to return a bool
89+
* Updated: [Update Product](https://www.polyplugins.com/docs/content-api/api/update-product/) manage_stock attribute to be able to use bool
90+
* Updated: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) manage_stock attribute to be able to use bool
91+
* Bugfix: [Update Product](https://www.polyplugins.com/docs/content-api/api/update-product/) attributes attribute not creating product attributes when they don't exist.
92+
* Bugfix: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) attributes attribute not creating product attributes when they don't exist.
93+
* Bugfix: [Update Product](https://www.polyplugins.com/docs/content-api/api/update-product/) triggering error sku during slug check
94+
* Bugfix: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) triggering error sku during slug check
95+
* Bugfix: [Update Product](https://www.polyplugins.com/docs/content-api/api/update-product/) triggering Exception instead of WP Error when upc attribute is already in use
96+
* Bugfix: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) triggering Exception instead of WP Error when upc attribute is already in use
97+
8798
= 1.0.10 =
8899
* Updated: [Create Product](https://www.polyplugins.com/docs/content-api/api/create-product/) endpoint to not require quantity
89100

0 commit comments

Comments
 (0)