-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Add taxonomy support to Product Collection Data API endpoint #59608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add taxonomy support to Product Collection Data API endpoint #59608
Conversation
…ata for taxonomy counts
Use + operator instead of array_merge to preserve term IDs when combining taxonomy counts from multiple taxonomies.
Change calculate_taxonomy_counts from array of objects to simple array of taxonomy name strings since query types are not needed for taxonomies. Before: calculate_taxonomy_counts[0][taxonomy]=product_cat After: calculate_taxonomy_counts[0]=product_cat
Testing GuidelinesHi @gigitux @opr @woocommerce/developer-advocacy, Apart from reviewing the code changes, please make sure to review the testing instructions (Guide) and verify that relevant tests (E2E, Unit, Integration, etc.) have been added or updated as needed. Reminder: PR reviewers are required to document testing performed. This includes:
|
📝 WalkthroughWalkthroughSupport for taxonomy term counts was added to the Product Collection Data API in WooCommerce. This includes a new Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant API as ProductCollectionData API
participant Filters as ProductQueryFilters
participant Query as ProductQuery
participant Data as FilterDataProvider
Client->>API: GET /products/collection-data?calculate_taxonomy_counts=[...]
API->>Filters: get_taxonomy_counts(request, taxonomies)
Filters->>Query: request_to_query_vars(request)
Filters->>Data: get(FilterDataProvider)
Filters->>Data: get_taxonomy_counts(query_vars, taxonomy)
Data-->>Filters: {term_id: count, ...}
Filters-->>API: taxonomy_counts array
API-->>Client: Response with taxonomy_counts
Possibly related PRs
📜 Recent review detailsConfiguration used: .coderabbit.yml 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
plugins/woocommerce/src/StoreApi/Routes/V1/ProductCollectionData.php (1)
171-185
: Refactor: Simplify redundant condition checksThe nested condition checks can be simplified since
! empty( $request['calculate_taxonomy_counts'] )
already ensures the parameter exists and is not empty.-if ( ! empty( $request['calculate_taxonomy_counts'] ) ) { - $taxonomies = $request['calculate_taxonomy_counts']; - $data['taxonomy_counts'] = []; - - if ( $taxonomies ) { - $counts = $filters->get_taxonomy_counts( $request, $taxonomies ); - - foreach ( $counts as $key => $value ) { - $data['taxonomy_counts'][] = (object) [ - 'term' => $key, - 'count' => $value, - ]; - } - } -} +if ( ! empty( $request['calculate_taxonomy_counts'] ) ) { + $taxonomies = $request['calculate_taxonomy_counts']; + $data['taxonomy_counts'] = []; + $counts = $filters->get_taxonomy_counts( $request, $taxonomies ); + + foreach ( $counts as $key => $value ) { + $data['taxonomy_counts'][] = (object) [ + 'term' => $key, + 'count' => $value, + ]; + } +}
📜 Review details
Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
docs/apis/store-api/resources-endpoints/product-collection-data.md
(2 hunks)plugins/woocommerce/changelog/59608-wooplug-4766-product-collection-data-api-add-support-for-taxonomy
(1 hunks)plugins/woocommerce/src/StoreApi/Routes/V1/ProductCollectionData.php
(3 hunks)plugins/woocommerce/src/StoreApi/Schemas/V1/ProductCollectionDataSchema.php
(2 hunks)plugins/woocommerce/src/StoreApi/Utilities/ProductQuery.php
(2 hunks)plugins/woocommerce/src/StoreApi/Utilities/ProductQueryFilters.php
(1 hunks)plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/ProductCollectionData.php
(9 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
`plugins/woocommerce/tests/**/*.php`: Run WooCommerce PHPUnit tests for specific...
plugins/woocommerce/tests/**/*.php
: Run WooCommerce PHPUnit tests for specific files or directories using the command: pnpm run test:php:env {relative_path} --verbose, and ensure the command is run in the plugins/woocommerce directory.
📄 Source: CodeRabbit Inference Engine (.cursor/rules/woo-phpunit.mdc)
List of files the instruction was applied to:
plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/ProductCollectionData.php
`**/*.{php,js,ts,jsx,tsx}`: Don't trust that extension developers will follow th...
**/*.{php,js,ts,jsx,tsx}
: Don't trust that extension developers will follow the best practices, make sure the code:
- Guards against unexpected inputs.
- Sanitizes and validates any potentially dangerous inputs.
- Is backwards compatible.
- Is readable and intuitive.
- Has unit or E2E tests where applicable.
⚙️ Source: CodeRabbit Configuration File
List of files the instruction was applied to:
plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/ProductCollectionData.php
plugins/woocommerce/src/StoreApi/Routes/V1/ProductCollectionData.php
plugins/woocommerce/src/StoreApi/Utilities/ProductQueryFilters.php
plugins/woocommerce/src/StoreApi/Schemas/V1/ProductCollectionDataSchema.php
plugins/woocommerce/src/StoreApi/Utilities/ProductQuery.php
🧠 Learnings (7)
📓 Common learnings
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59499
File: plugins/woocommerce/src/Internal/ProductFilters/QueryClauses.php:327-332
Timestamp: 2025-07-10T04:22:27.625Z
Learning: In the WooCommerce ProductFilters QueryClauses class, the $chosen_taxonomies parameter in add_taxonomy_clauses() already contains only validated public product taxonomies. The validation occurs upstream in the Params class during parameter registration, so additional taxonomy existence validation in the processing methods is redundant.
plugins/woocommerce/changelog/59608-wooplug-4766-product-collection-data-api-add-support-for-taxonomy (1)
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59499
File: plugins/woocommerce/src/Internal/ProductFilters/QueryClauses.php:327-332
Timestamp: 2025-07-10T04:22:27.625Z
Learning: In the WooCommerce ProductFilters QueryClauses class, the $chosen_taxonomies parameter in add_taxonomy_clauses() already contains only validated public product taxonomies. The validation occurs upstream in the Params class during parameter registration, so additional taxonomy existence validation in the processing methods is redundant.
plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/ProductCollectionData.php (2)
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59499
File: plugins/woocommerce/src/Internal/ProductFilters/QueryClauses.php:327-332
Timestamp: 2025-07-10T04:22:27.625Z
Learning: In the WooCommerce ProductFilters QueryClauses class, the $chosen_taxonomies parameter in add_taxonomy_clauses() already contains only validated public product taxonomies. The validation occurs upstream in the Params class during parameter registration, so additional taxonomy existence validation in the processing methods is redundant.
Learnt from: mreishus
PR: woocommerce/woocommerce#58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().
plugins/woocommerce/src/StoreApi/Routes/V1/ProductCollectionData.php (2)
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59499
File: plugins/woocommerce/src/Internal/ProductFilters/QueryClauses.php:327-332
Timestamp: 2025-07-10T04:22:27.625Z
Learning: In the WooCommerce ProductFilters QueryClauses class, the $chosen_taxonomies parameter in add_taxonomy_clauses() already contains only validated public product taxonomies. The validation occurs upstream in the Params class during parameter registration, so additional taxonomy existence validation in the processing methods is redundant.
Learnt from: mreishus
PR: woocommerce/woocommerce#58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().
plugins/woocommerce/src/StoreApi/Utilities/ProductQueryFilters.php (1)
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59499
File: plugins/woocommerce/src/Internal/ProductFilters/QueryClauses.php:327-332
Timestamp: 2025-07-10T04:22:27.625Z
Learning: In the WooCommerce ProductFilters QueryClauses class, the $chosen_taxonomies parameter in add_taxonomy_clauses() already contains only validated public product taxonomies. The validation occurs upstream in the Params class during parameter registration, so additional taxonomy existence validation in the processing methods is redundant.
plugins/woocommerce/src/StoreApi/Schemas/V1/ProductCollectionDataSchema.php (2)
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59499
File: plugins/woocommerce/src/Internal/ProductFilters/QueryClauses.php:327-332
Timestamp: 2025-07-10T04:22:27.625Z
Learning: In the WooCommerce ProductFilters QueryClauses class, the $chosen_taxonomies parameter in add_taxonomy_clauses() already contains only validated public product taxonomies. The validation occurs upstream in the Params class during parameter registration, so additional taxonomy existence validation in the processing methods is redundant.
Learnt from: mreishus
PR: woocommerce/woocommerce#58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().
plugins/woocommerce/src/StoreApi/Utilities/ProductQuery.php (1)
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59499
File: plugins/woocommerce/src/Internal/ProductFilters/QueryClauses.php:327-332
Timestamp: 2025-07-10T04:22:27.625Z
Learning: In the WooCommerce ProductFilters QueryClauses class, the $chosen_taxonomies parameter in add_taxonomy_clauses() already contains only validated public product taxonomies. The validation occurs upstream in the Params class during parameter registration, so additional taxonomy existence validation in the processing methods is redundant.
🧬 Code Graph Analysis (1)
plugins/woocommerce/src/StoreApi/Routes/V1/ProductCollectionData.php (1)
plugins/woocommerce/src/StoreApi/Utilities/ProductQueryFilters.php (1)
get_taxonomy_counts
(224-250)
🪛 PHPMD (2.15.0)
plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/ProductCollectionData.php
183-183: Avoid unused local variables such as '$fixtures'. (Unused Code Rules)
(UnusedLocalVariable)
🔇 Additional comments (16)
plugins/woocommerce/changelog/59608-wooplug-4766-product-collection-data-api-add-support-for-taxonomy (1)
1-4
: LGTM - Changelog entry is properly formatted.The changelog entry correctly documents the new feature with appropriate significance (minor) and type (add).
docs/apis/store-api/resources-endpoints/product-collection-data.md (3)
10-10
: LGTM - Example URL correctly demonstrates the new parameter.The example URL shows proper usage of the
calculate_taxonomy_counts
parameter as an array.
13-19
: LGTM - Parameter documentation is clear and consistent.The parameter table correctly describes the new
calculate_taxonomy_counts
parameter with appropriate type (array) and description.
67-81
: LGTM - Response example accurately shows the new taxonomy_counts structure.The example response correctly demonstrates the expected structure with term IDs and counts.
plugins/woocommerce/src/StoreApi/Schemas/V1/ProductCollectionDataSchema.php (2)
121-143
: LGTM - Schema property follows consistent pattern.The
taxonomy_counts
property definition is consistent with other count properties in the schema, using the same structure withterm
andcount
fields.
164-164
: LGTM - Property correctly added to response.The
taxonomy_counts
data is properly included in the response array.plugins/woocommerce/src/StoreApi/Utilities/ProductQueryFilters.php (1)
217-250
: LGTM - Well-implemented taxonomy counting method.The
get_taxonomy_counts
method follows the established pattern of other count methods in this class. It correctly:
- Clears pagination and sorting parameters to get accurate counts
- Uses the FilterDataProvider with ProductQuery as QueryClausesGenerator
- Preserves array keys when merging counts using the + operator
- Leverages the existing taxonomy validation that occurs upstream
The implementation is secure and consistent with WooCommerce coding standards.
plugins/woocommerce/src/StoreApi/Utilities/ProductQuery.php (3)
9-9
: LGTM - Interface import added correctly.The QueryClausesGenerator interface import is properly added to support the new functionality.
17-17
: LGTM - Interface implementation enables FilterDataProvider usage.Implementing the QueryClausesGenerator interface allows this class to be used with the FilterDataProvider for taxonomy counting.
350-353
: LGTM - Method signature corrected with proper type hints.The method signature now has proper type hints (
array $args
and\WP_Query $wp_query
) which improves type safety and corrects the previous incorrect\WC_Query
reference.plugins/woocommerce/src/StoreApi/Routes/V1/ProductCollectionData.php (2)
76-76
: LGTM: Consistent initialization patternThe null initialization of
taxonomy_counts
follows the same pattern as other similar fields in the response data structure.
240-248
: LGTM: Well-defined parameter structureThe parameter definition follows REST API best practices with proper type definition, description, and default value. The array of strings structure is appropriate for taxonomy names.
plugins/woocommerce/tests/php/src/Blocks/StoreApi/Routes/ProductCollectionData.php (4)
55-55
: LGTM: Consistent test assertionsThe additions of
taxonomy_counts
null assertions in existing tests maintain consistency with the established testing pattern for other optional fields.Also applies to: 73-73, 107-107, 143-143, 163-163
179-278
: Excellent comprehensive test coverageThe test method provides thorough coverage of the taxonomy counts feature:
- Tests both single and multiple taxonomies
- Verifies response structure and data types
- Validates actual count accuracy
- Uses proper WordPress taxonomy functions for test data setup
The test follows best practices and will effectively catch regressions in the taxonomy counting functionality.
291-291
: LGTM: Parameter validation updatedThe collection params test is correctly updated to include the new
calculate_taxonomy_counts
parameter.
306-329
: LGTM: Schema validation enhancedThe schema test is properly updated to include taxonomy setup and parameter usage, ensuring the response structure validation covers the new feature.
Test using WordPress PlaygroundThe changes in this pull request can be previewed and tested using a WordPress Playground instance. Test this pull request with WordPress Playground. Note that this URL is valid for 30 days from when this comment was last updated. You can update it by closing/reopening the PR or pushing a new commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this! I left one comment regarding the DI in the src
folder. Besides this, everything LGTM! I'm not approving because I want to ensure that I tested the PR correctly.
/wc/store/v1/products/collection-data?calculate_taxonomy_counts[]=product_cat&calculate_taxonomy_counts[]=product_tag
Can you clarify this step in the testing instruction? If I use this URL structure, I got:
Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 20480 bytes)
With this URL, everything works as expected:
/wc/store/v1/products/collection-data?calculate_taxonomy_counts=product_cat, product_tag
right?
$query_vars = $product_query->prepare_objects_query( $request ); | ||
|
||
// Use FilterData with ProductQuery as QueryClausesGenerator. | ||
$container = wc_get_container(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking the documentation, in the src folder, the DI should be done in a different way: https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/src/README.md#1-other-classes-in-the-src-directory
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Store API (and Blocks) has its own container, so it's not possible to follow that guide right now. See #43772 (comment)
* Test taxonomy calculation method. | ||
*/ | ||
public function test_calculate_taxonomy_counts() { | ||
$fixtures = new FixtureData(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like not necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I will delete this. It was used initially but I forgot to remove after a refactor.
@gigitux both URLs should work fine. I'm curious what can cause the error for you. It's working as expected on my end. You should still get the same array of two either using comma separated string or the array notion. 🤔 ![]() ![]() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…d syntax - Change from array syntax calculate_taxonomy_counts[0]=product_cat to comma-separated calculate_taxonomy_counts=product_cat - Update cURL example to show multiple taxonomies with comma separation - Both formats work due to WordPress REST API parameter parsing, but comma-separated is more concise
Hi @dinhtungdu! Your PR contains REST API changes. Please consider updating the REST API documentation if your changes affect the public API. Changed API files:
|
Submission Review Guidelines:
Changes proposed in this Pull Request:
This PR adds taxonomy support to the Product Collection Data API endpoint, enabling clients to retrieve taxonomy counts (such as categories and tags) for products in a collection.
Key changes:
calculate_taxonomy_counts
parameter to the product collection data endpointCloses WOOPLUG-4766
Closes #59130
How to test the changes in this Pull Request:
Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:
/wc/store/v1/products/collection-data
with thecalculate_taxonomy_counts
parameter:taxonomy_counts
array with term IDs and their corresponding product countsChangelog entry
Changelog Entry Details
Significance
Type
Message
Add taxonomy support to Product Collection Data API endpoint with calculate_taxonomy_counts parameter