Commit d2ded717f4a for woocommerce
commit d2ded717f4aaaf50d3fd765aa6154dbfd6e1de41
Author: Jorge A. Torres <jorge.torres@automattic.com>
Date: Thu Jul 2 18:42:58 2026 +0100
Warn when an order status key is too long to store (#66164)
diff --git a/plugins/woocommerce/changelog/54584-fix-order-status-key-length b/plugins/woocommerce/changelog/54584-fix-order-status-key-length
new file mode 100644
index 00000000000..3e0ce663f64
--- /dev/null
+++ b/plugins/woocommerce/changelog/54584-fix-order-status-key-length
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Warn when an order status key is too long and can't be stored.
diff --git a/plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php
index 3aa743bb319..4d0770c2caa 100644
--- a/plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php
+++ b/plugins/woocommerce/includes/data-stores/abstract-wc-order-data-store-cpt.php
@@ -378,6 +378,18 @@ abstract class Abstract_WC_Order_Data_Store_CPT extends WC_Data_Store_WP impleme
$post_status = 'wc-' . $post_status;
}
+ // The status column holds at most 20 characters, so a longer key can't be stored.
+ if ( strlen( $post_status ) > 20 ) {
+ wc_doing_it_wrong(
+ __METHOD__,
+ sprintf(
+ 'Order status "%s" is longer than the storage limit of 20 characters and cannot be stored.',
+ esc_html( $order_status )
+ ),
+ '11.0.0'
+ );
+ }
+
return $post_status;
}
diff --git a/plugins/woocommerce/tests/php/includes/abstracts/class-wc-abstract-order-test.php b/plugins/woocommerce/tests/php/includes/abstracts/class-wc-abstract-order-test.php
index ef6dfb13ce5..b9370e0cfa0 100644
--- a/plugins/woocommerce/tests/php/includes/abstracts/class-wc-abstract-order-test.php
+++ b/plugins/woocommerce/tests/php/includes/abstracts/class-wc-abstract-order-test.php
@@ -17,10 +17,23 @@ class WC_Abstract_Order_Test extends WC_Unit_Test_Case {
use CogsAwareUnitTestSuiteTrait;
+ /**
+ * Post statuses registered during a test, to clean up on tear down.
+ *
+ * @var string[]
+ */
+ private $registered_order_statuses = array();
+
/**
* Runs after each test.
*/
public function tearDown(): void {
+ // register_post_status() mutates the global registry, which WP_UnitTestCase does not restore.
+ foreach ( $this->registered_order_statuses as $status ) {
+ unset( $GLOBALS['wp_post_statuses'][ $status ] );
+ }
+ $this->registered_order_statuses = array();
+
parent::tearDown();
$this->disable_cogs_feature();
}
@@ -995,4 +1008,56 @@ class WC_Abstract_Order_Test extends WC_Unit_Test_Case {
remove_filter( 'woocommerce_order_type_to_group', $adjust );
}
}
+
+ /**
+ * Register a custom order status so it survives set_status() and is prefixed on save.
+ *
+ * Registers it in the valid order statuses (so set_status keeps it) and as a post status
+ * (so get_post_status adds the wc- prefix, which is what pushes it over the column limit).
+ *
+ * @param string $status Unprefixed order status key.
+ */
+ private function register_custom_order_status( string $status ): void {
+ $prefixed = 'wc-' . $status;
+
+ add_filter(
+ 'wc_order_statuses',
+ function ( $statuses ) use ( $prefixed ) {
+ $statuses[ $prefixed ] = 'Custom status for testing';
+ return $statuses;
+ }
+ );
+ register_post_status( $prefixed );
+ $this->registered_order_statuses[] = $prefixed;
+ }
+
+ /**
+ * @testdox Should warn when an order is saved with a status that exceeds the storage limit.
+ */
+ public function test_saving_an_order_with_a_too_long_status_warns() {
+ $this->setExpectedIncorrectUsage( 'Abstract_WC_Order_Data_Store_CPT::get_post_status' );
+
+ // 'wc-' + 18 characters = 21, one over the 20-character storage limit.
+ $status = str_repeat( 'a', 18 );
+ $this->register_custom_order_status( $status );
+
+ $order = WC_Helper_Order::create_order();
+ $order->set_status( $status );
+ $order->save();
+ }
+
+ /**
+ * @testdox Should not warn when an order is saved with a status at the storage limit.
+ */
+ public function test_saving_an_order_with_a_status_at_the_limit_does_not_warn() {
+ // 'wc-' + 17 characters = 20, exactly the storage limit.
+ $status = str_repeat( 'a', 17 );
+ $this->register_custom_order_status( $status );
+
+ $order = WC_Helper_Order::create_order();
+ $order->set_status( $status );
+ $order->save();
+
+ $this->assertSame( $status, wc_get_order( $order->get_id() )->get_status() );
+ }
}