Skip to content

Fix: Attribute terms REST API writes menu_order to wrong meta key#63390

Merged
kraftbj merged 5 commits intowoocommerce:trunkfrom
jacobmax:fix/attribute-terms-menu-order-meta-key
Mar 20, 2026
Merged

Fix: Attribute terms REST API writes menu_order to wrong meta key#63390
kraftbj merged 5 commits intowoocommerce:trunkfrom
jacobmax:fix/attribute-terms-menu-order-meta-key

Conversation

@jacobmax
Copy link
Copy Markdown
Contributor

Changes Proposed

Fixes #28158

The attribute terms REST API controller saves menu_order to meta key order_{taxonomy} (e.g. order_pa_size), but everywhere else in WooCommerce the meta key is just order:

  • wc_set_term_order()order
  • wc_change_get_terms_defaults()order
  • wc_change_pre_get_terms()order
  • Admin drag-and-drop → order
  • Product categories controller → order

So menu_order set via the API is silently ignored by the admin and frontend because they look up a different key.

The fix aligns class-wc-rest-product-attribute-terms-v1-controller.php with the categories controller by using order in both update_term_meta_fields() and prepare_item_for_response().

Testing Instructions

  1. Create a product attribute (e.g. "Size") with order_by set to "Custom ordering"
  2. Add a few terms (e.g. S, M, L, XL)
  3. Via the REST API, update the terms with menu_order values:
    PUT /wc/v3/products/attributes/{id}/terms/{term_id} with { "menu_order": 0 }, { "menu_order": 1 }, etc.
  4. Check the term list in WP admin → Products → Attributes → (your attribute)
  5. Check a product page with that attribute on the frontend

Before: Terms appear in alphabetical order regardless of menu_order values.
After: Terms appear in the order set via the API.

Changelog Entry

Significance: Patch
Type: Fix
Message: Fix attribute terms REST API writing menu_order to wrong meta key, preventing custom ordering from working via the API.

@github-actions github-actions bot added type: community contribution plugin: woocommerce Issues related to the WooCommerce Core plugin. labels Feb 20, 2026
@woocommercebot woocommercebot requested review from a team and albarin and removed request for a team February 20, 2026 15:29
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 20, 2026

Testing Guidelines

Hi ,

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:

  • 🖼️ Screenshots or screen recordings.
  • 📝 List of functionality tested / steps followed.
  • 🌐 Site details (environment attributes such as hosting type, plugins, theme, store size, store age, and relevant settings).
  • 🔍 Any analysis performed, such as assessing potential impacts on environment attributes and other plugins, conducting performance profiling, or using LLM/AI-based analysis.

⚠️ Within the testing details you provide, please ensure that no sensitive information (such as API keys, passwords, user data, etc.) is included in this public issue.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 8d45f4b6-567b-4941-87e3-68f75c43c223

📥 Commits

Reviewing files that changed from the base of the PR and between bff278c and 392889e.

📒 Files selected for processing (1)
  • plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller-tests.php

📝 Walkthrough

Walkthrough

The PR updates the WooCommerce REST API controller for product attribute terms to read and write menu_order using the generic term meta key 'order' instead of a taxonomy-specific key, and avoids updating meta when menu_order is absent. Tests and a changelog entry were added.

Changes

Cohort / File(s) Summary
REST API Controller Fix
plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php
Switched menu_order term meta read/write from taxonomy-specific 'order_' . $this->taxonomy to generic 'order'. Added conditional to update menu_order only when present in the request.
Test Coverage
plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller-tests.php
Added four tests validating create, update, read, and update-without-menu_order behaviors to ensure menu_order uses the order meta key and preserves existing values when omitted.
Changelog Entry
plugins/woocommerce/changelog/fix-attribute-terms-menu-order-meta-key
Added a changelog note documenting the patch that corrects the REST API menu_order meta key for attribute terms.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically identifies the main fix: correcting the meta key used by the attribute terms REST API for menu_order.
Description check ✅ Passed The description provides comprehensive context about the bug, the fix, testing instructions, and a changelog entry, all directly related to the changeset.
Linked Issues check ✅ Passed The PR fully addresses issue #28158 by correcting the meta key used for menu_order in the REST API controller, ensuring attribute terms respect custom ordering in both admin and frontend.
Out of Scope Changes check ✅ Passed All changes are directly scoped to fixing the menu_order meta key issue: controller updates, comprehensive test coverage, and a changelog entry with no unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-attribute-terms-v1-controller.php`:
- Around line 176-182: The update_term_meta_fields function currently calls
update_term_meta( $id, 'order', $request['menu_order'] ) without checking if
$request['menu_order'] is present, which allows null to overwrite existing meta;
modify update_term_meta_fields (referencing update_term_meta_fields,
$term->term_id, and $request['menu_order']) to first check that menu_order
exists and is not null (e.g. isset($request['menu_order']) or array_key_exists
and !== null) and only call update_term_meta when that guard passes, leaving
existing term meta unchanged for partial/PATCH requests.
- Line 138: prepare_item_for_response now reads term meta 'order' while
update_term_meta_fields writes 'order', but existing installations still have
ordering stored under legacy keys like 'order_{taxonomy}' (e.g. order_pa_size),
causing silent data loss on upgrade; add a one-time migration (run during a WC
upgrade routine or activation hook) that scans product attribute taxonomies and
copies meta from each legacy key ('order_' . $taxonomy) into the unified 'order'
meta for the same term_id when 'order' does not already exist, then remove or
ignore the old keys; implement this migration near the plugin/theme upgrade
entrypoint and reference prepare_item_for_response and update_term_meta_fields
to ensure reads/writes use the new 'order' meta consistently.

@albarin albarin requested review from a team and kraftbj and removed request for a team and albarin February 24, 2026 11:34
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
(1)

1-1: Add strict types declaration to align with WooCommerce test conventions.

Please add declare( strict_types = 1 ); after the opening PHP tag.

Proposed patch
 <?php
+declare( strict_types = 1 );
 /**
  * Tests for WC_REST_Product_Attribute_Terms_Controller menu_order meta key.
  */

Based on learnings: Applies to plugins/woocommerce/tests/**/*.php : Add declare( strict_types = 1 ); at the top of WooCommerce PHPUnit test files.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @  at line 1, Add a strict types declaration immediately after the opening
PHP tag: where you find files starting with "<?php" in the WooCommerce PHPUnit
test files, insert the line declare( strict_types = 1 ); on the next line so the
file begins with "<?php" followed by "declare( strict_types = 1 );" to align
with test conventions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @ :
- Line 1: Add a strict types declaration immediately after the opening PHP tag:
where you find files starting with "<?php" in the WooCommerce PHPUnit test
files, insert the line declare( strict_types = 1 ); on the next line so the file
begins with "<?php" followed by "declare( strict_types = 1 );" to align with
test conventions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 56039d7b-8445-4318-8f2a-850b9130c411

📥 Commits

Reviewing files that changed from the base of the PR and between 1fc8118 and 7af7eba.

📒 Files selected for processing (1)

- Remove garbled test file (space character filename) and add tests to
  the existing V1 controller test class at the correct path.
- Add isset($request['menu_order']) guard to prevent overwriting order
  meta when updating unrelated term fields (matches categories controller).
- Add tests for create, update, read, old-key regression, and the
  isset guard preserving existing order.
- Add missing changelog entry.
@kraftbj
Copy link
Copy Markdown
Contributor

kraftbj commented Mar 19, 2026

Thanks for the contribution — this is a great catch! The meta key mismatch has been there since 3.6 and your fix is spot on.

I pushed a couple of small tweaks: added an isset() guard on menu_order in update_term_meta_fields (matching the categories controller pattern), moved the tests into the existing test class at the correct path, added a changelog entry, and removed the stray test file. Will get this moving!

@kraftbj kraftbj self-assigned this Mar 19, 2026
@kraftbj kraftbj added this to the 10.7.0 milestone Mar 19, 2026
- Move file docblock before declare(strict_types) per WooCommerce standards
- Add short descriptions to all test method docblocks
- Fix equals sign alignment
@kraftbj kraftbj enabled auto-merge (squash) March 20, 2026 03:43
@kraftbj kraftbj merged commit 73fee4f into woocommerce:trunk Mar 20, 2026
86 of 89 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin: woocommerce Issues related to the WooCommerce Core plugin. type: community contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When adding product attribute terms using the REST API (V3) ordering is not kept

2 participants