Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Product Query: pass any product taxonomies existing in the URL parame…
Browse files Browse the repository at this point in the history
…ters. (#6152)

* Product Query: pass any product taxonomies existing in the URL parameters.

* Products API: add custom product taxonomy in docs.

* Docs: fixes type.

* Linting the docs.

* Product Query: add [product-taxonomy]_operator docs.

* Product Query: fixes the taxonomies merge order.

* Product Query: make sure that tax keys are unique and sanitized.

* Product Query: adds `tax_` prefix to docs.

* Product Query: fixes not_in for categories, taxonomies, and tags.

* Product Query: updates attribute operator enum.

* Product query: uses `_unstable_tax_` instead of `tax_` prefix for custom taxonomies.

Co-authored-by: cpap <[email protected]>
  • Loading branch information
cpapazoglou and cpap authored Apr 21, 2022
1 parent 9c474e2 commit d2cbc80
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 37 deletions.
28 changes: 25 additions & 3 deletions src/StoreApi/Routes/V1/Products.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,34 @@ public function get_collection_params() {
$params['category_operator'] = array(
'description' => __( 'Operator to compare product category terms.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'enum' => [ 'in', 'not in', 'and' ],
'enum' => [ 'in', 'not_in', 'and' ],
'default' => 'in',
'sanitize_callback' => 'sanitize_key',
'validate_callback' => 'rest_validate_request_arg',
);

// If the $_REQUEST contains a taxonomy query, add it to the params and sanitize it.
foreach ( $_REQUEST as $param => $value ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( str_starts_with( $param, '_unstable_tax_' ) && ! str_ends_with( $param, '_operator' ) ) {
$params[ $param ] = array(
'description' => __( 'Limit result set to products assigned a specific category ID.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'sanitize_callback' => 'wp_parse_id_list',
'validate_callback' => 'rest_validate_request_arg',
);
}
if ( str_starts_with( $param, '_unstable_tax_' ) && str_ends_with( $param, '_operator' ) ) {
$params[ $param ] = array(
'description' => __( 'Operator to compare product category terms.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'enum' => [ 'in', 'not_in', 'and' ],
'default' => 'in',
'sanitize_callback' => 'sanitize_key',
'validate_callback' => 'rest_validate_request_arg',
);
}
}

$params['tag'] = array(
'description' => __( 'Limit result set to products assigned a specific tag ID.', 'woo-gutenberg-products-block' ),
'type' => 'string',
Expand All @@ -291,7 +313,7 @@ public function get_collection_params() {
$params['tag_operator'] = array(
'description' => __( 'Operator to compare product tags.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'enum' => [ 'in', 'not in', 'and' ],
'enum' => [ 'in', 'not_in', 'and' ],
'default' => 'in',
'sanitize_callback' => 'sanitize_key',
'validate_callback' => 'rest_validate_request_arg',
Expand Down Expand Up @@ -360,7 +382,7 @@ public function get_collection_params() {
'operator' => array(
'description' => __( 'Operator to compare product attribute terms.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'enum' => [ 'in', 'not in', 'and' ],
'enum' => [ 'in', 'not_in', 'and' ],
),
),
),
Expand Down
14 changes: 13 additions & 1 deletion src/StoreApi/Utilities/ProductQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,24 @@ public function prepare_objects_query( $request ) {
'and' => 'AND',
];

// Gets all registered product taxonomies and prefixes them with `tax_`.
// This is neeeded to avoid situations where a users registers a new product taxonomy with the same name as default field.
// eg an `sku` taxonomy will be mapped to `tax_sku`.
$all_product_taxonomies = array_map(
function ( $value ) {
return '_unstable_tax_' . $value;
},
get_taxonomies( array( 'object_type' => array( 'product' ) ), 'names' )
);

// Map between taxonomy name and arg key.
$taxonomies = [
$default_taxonomies = [
'product_cat' => 'category',
'product_tag' => 'tag',
];

$taxonomies = array_merge( $all_product_taxonomies, $default_taxonomies );

// Set tax_query for each passed arg.
foreach ( $taxonomies as $taxonomy => $key ) {
if ( ! empty( $request[ $key ] ) ) {
Expand Down
69 changes: 36 additions & 33 deletions src/StoreApi/docs/products.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

The store products API provides public product data so it can be rendered on the client side.

- [List Products](#list-products)
- [Single Product](#single-product)
- [List Products](#list-products)
- [Single Product](#single-product)
- [](#)

## List Products

Expand All @@ -22,6 +23,7 @@ GET /products?type=simple
GET /products?sku=sku-1,sku-2
GET /products?featured=true
GET /products?category=t-shirts
GET /products?product-taxonomy=product-taxonomy-term-id
GET /products?tag=special-items
GET /products?attributes[0][attribute]=pa_color&attributes[0][slug]=red
GET /products?on_sale=true
Expand All @@ -35,34 +37,36 @@ GET /products?return_attribute_counts=pa_size,pa_color
GET /products?return_rating_counts=true
```

| Attribute | Type | Required | Description |
| :------------------- | :------ | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `search` | integer | no | Limit results to those matching a string. |
| `after` | string | no | Limit response to resources created after a given ISO8601 compliant date. |
| `before` | string | no | Limit response to resources created before a given ISO8601 compliant date. |
| `date_column` | string | no | When limiting response using after/before, which date column to compare against. Allowed values: `date`, `date_gmt`, `modified`, `modified_gmt` |
| `exclude` | array | no | Ensure result set excludes specific IDs. |
| `include` | array | no | Limit result set to specific ids. |
| `offset` | integer | no | Offset the result set by a specific number of items. |
| `order` | string | no | Order sort attribute ascending or descending. Allowed values: `asc`, `desc` |
| `orderby` | string | no | Sort collection by object attribute. Allowed values: `date`, `modified`, `id`, `include`, `title`, `slug`, `price`, `popularity`, `rating`, `menu_order`, `comment_count` |
| `parent` | array | no | Limit result set to those of particular parent IDs. |
| `parent_exclude` | array | no | Limit result set to all items except those of a particular parent ID. |
| `type` | string | no | Limit result set to products assigned a specific type. |
| `sku` | string | no | Limit result set to products with specific SKU(s). Use commas to separate. |
| `featured` | boolean | no | Limit result set to featured products. |
| `category` | string | no | Limit result set to products assigned a specific category ID. |
| `category_operator` | string | no | Operator to compare product category terms. Allowed values: `in`, `not_in`, `and` |
| `tag` | string | no | Limit result set to products assigned a specific tag ID. |
| `tag_operator` | string | no | Operator to compare product tags. Allowed values: `in`, `not_in`, `and` |
| `on_sale` | boolean | no | Limit result set to products on sale. |
| `min_price` | string | no | Limit result set to products based on a minimum price, provided using the smallest unit of the currency. |
| `max_price` | string | no | Limit result set to products based on a maximum price, provided using the smallest unit of the currency. |
| `stock_status` | array | no | Limit result set to products with specified stock statuses. Expects an array of strings containing 'instock', 'outofstock' or 'onbackorder'. |
| `attributes` | array | no | Limit result set to specific attribute terms. Expects an array of objects containing `attribute` (taxonomy), `term_id` or `slug`, and optional `operator` for comparison. |
| `attribute_relation` | string | no | The logical relationship between attributes when filtering across multiple at once. |
| `catalog_visibility` | string | no | Determines if hidden or visible catalog products are shown. Allowed values: `any`, `visible`, `catalog`, `search`, `hidden` |
| `rating` | boolean | no | Limit result set to products with a certain average rating. |
| Attribute | Type | Required | Description |
| :------------------------------------------ | :------ | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `search` | integer | no | Limit results to those matching a string. |
| `after` | string | no | Limit response to resources created after a given ISO8601 compliant date. |
| `before` | string | no | Limit response to resources created before a given ISO8601 compliant date. |
| `date_column` | string | no | When limiting response using after/before, which date column to compare against. Allowed values: `date`, `date_gmt`, `modified`, `modified_gmt` |
| `exclude` | array | no | Ensure result set excludes specific IDs. |
| `include` | array | no | Limit result set to specific ids. |
| `offset` | integer | no | Offset the result set by a specific number of items. |
| `order` | string | no | Order sort attribute ascending or descending. Allowed values: `asc`, `desc` |
| `orderby` | string | no | Sort collection by object attribute. Allowed values : `date`, `modified`, `id`, `include`, `title`, `slug`, `price`, `popularity`, `rating`, `menu_order`, `comment_count` |
| `parent` | array | no | Limit result set to those of particular parent IDs. |
| `parent_exclude` | array | no | Limit result set to all items except those of a particular parent ID. |
| `type` | string | no | Limit result set to products assigned a specific type. |
| `sku` | string | no | Limit result set to products with specific SKU(s). Use commas to separate. |
| `featured` | boolean | no | Limit result set to featured products. |
| `category` | string | no | Limit result set to products assigned a specific category ID. |
| `category_operator` | string | no | Operator to compare product category terms. Allowed values: `in`, `not_in`, `and` |
| `_unstable_tax_[product-taxonomy]` | string | no | Limit result set to products assigned to the term ID of that custom product taxonomy. `[product-taxonomy]` should be the key of the custom product taxonomy registered. |
| `_unstable_tax_[product-taxonomy]_operator` | string | no | Operator to compare custom product taxonomy terms. Allowed values: `in`, `not_in`, `and` |
| `tag` | string | no | Limit result set to products assigned a specific tag ID. |
| `tag_operator` | string | no | Operator to compare product tags. Allowed values: `in`, `not_in`, `and` |
| `on_sale` | boolean | no | Limit result set to products on sale. |
| `min_price` | string | no | Limit result set to products based on a minimum price, provided using the smallest unit of the currency. |
| `max_price` | string | no | Limit result set to products based on a maximum price, provided using the smallest unit of the currency. |
| `stock_status` | array | no | Limit result set to products with specified stock statuses. Expects an array of strings containing 'instock', 'outofstock' or 'onbackorder'. |
| `attributes` | array | no | Limit result set to specific attribute terms. Expects an array of objects containing `attribute` (taxonomy), `term_id` or `slug`, and optional `operator` for comparison. |
| `attribute_relation` | string | no | The logical relationship between attributes when filtering across multiple at once. |
| `catalog_visibility` | string | no | Determines if hidden or visible catalog products are shown. Allowed values: `any`, `visible`, `catalog`, `search`, `hidden` |
| `rating` | boolean | no | Limit result set to products with a certain average rating. |

```sh
curl "https://example-store.com/wp-json/wc/store/v1/products"
Expand Down Expand Up @@ -186,11 +190,10 @@ curl "https://example-store.com/wp-json/wc/store/v1/products/34"
}
```

<!-- FEEDBACK -->
---
## <!-- FEEDBACK -->

[We're hiring!](https://woocommerce.com/careers/) Come work with us!

🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./src/StoreApi/docs/products.md)
<!-- /FEEDBACK -->

<!-- /FEEDBACK -->

0 comments on commit d2cbc80

Please sign in to comment.