Commit 8082f639c3f for woocommerce
commit 8082f639c3f26ab819ef9d024f80219de31c48f5
Author: Taha Paksu <3295+tpaksu@users.noreply.github.com>
Date: Thu Mar 5 00:12:53 2026 +0300
[WOOPLUG-6287] update: use WC_Data_Store to register fulfillments data store (#63485)
* [WOOPLUG-6287] update: use WC_Data_Store to register fulfillments data store
* Register fulfillments data store via WC_Data_Store for extensibility
Replace direct DI container access (wc_get_container()->get(FulfillmentsDataStore::class))
with WC_Data_Store::load('order-fulfillment') across all fulfillment consumers. Register the
data store via the woocommerce_data_stores filter in FulfillmentsController, allowing
extensions to replace it with a custom implementation.
* Update version number to 10.7.0
* Revert phpstan baseline change
* Update phpstan baseline
* Remove unrelated phpstan baseline changes
* Fix actual errors instead adding them to phpstan baseline
* Add changefile(s) from automation for the following project(s): woocommerce
* Update docblocks for Fulfillments data store usage
* Remove old baseline errors
* Only load the data store when feature is enabled
* Preserve original fulfillments feature flag in tests (Coderabbit review fix)
* Add error handling for fulfillments data store loading
* Update Fulfillments data store references to use the correct namespace
* Update exception handling to use Throwable for fulfillments
* Add error handling for fulfillments data store loading in template functions
---------
Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>
diff --git a/plugins/woocommerce/changelog/63485-update-wooplug-6287-order-fulfillments-use-wc_data_store-to-register b/plugins/woocommerce/changelog/63485-update-wooplug-6287-order-fulfillments-use-wc_data_store-to-register
new file mode 100644
index 00000000000..0cacd26d43d
--- /dev/null
+++ b/plugins/woocommerce/changelog/63485-update-wooplug-6287-order-fulfillments-use-wc_data_store-to-register
@@ -0,0 +1,4 @@
+Significance: patch
+Type: update
+
+Register fulfillments data store via WC_Data_Store for extensibility, allowing extensions to provide custom data store implementations.
\ No newline at end of file
diff --git a/plugins/woocommerce/includes/wc-template-functions.php b/plugins/woocommerce/includes/wc-template-functions.php
index 571ccd57e33..96931a81f7b 100644
--- a/plugins/woocommerce/includes/wc-template-functions.php
+++ b/plugins/woocommerce/includes/wc-template-functions.php
@@ -13,7 +13,6 @@ use Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils;
use Automattic\WooCommerce\Enums\OrderStatus;
use Automattic\WooCommerce\Enums\PaymentGatewayFeature;
use Automattic\WooCommerce\Enums\ProductType;
-use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
use Automattic\WooCommerce\Admin\Features\Fulfillments\Fulfillment;
use Automattic\WooCommerce\Internal\Utilities\HtmlSanitizer;
use Automattic\WooCommerce\Utilities\FeaturesUtil;
@@ -3038,10 +3037,22 @@ if ( ! function_exists( 'woocommerce_order_details_table' ) ) {
$template = 'order/order-details.php';
if ( FeaturesUtil::feature_is_enabled( 'fulfillments' ) ) {
- $fulfillment_data_store = wc_get_container()->get( FulfillmentsDataStore::class );
- $fulfillments = $fulfillment_data_store->read_fulfillments( WC_Order::class, $order_id );
- if ( ! empty( $fulfillments ) ) {
- $template = 'order/order-details-fulfillments.php';
+ try {
+ /**
+ * Fulfillments data store.
+ *
+ * @var \Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore $fulfillment_data_store
+ */
+ $fulfillment_data_store = \WC_Data_Store::load( 'order-fulfillment' );
+ $fulfillments = $fulfillment_data_store->read_fulfillments( WC_Order::class, $order_id );
+ if ( ! empty( $fulfillments ) ) {
+ $template = 'order/order-details-fulfillments.php';
+ }
+ } catch ( \Throwable $e ) {
+ wc_get_logger()->error(
+ sprintf( 'Failed to load fulfillments for order %s: %s', $order_id, $e->getMessage() ),
+ array( 'source' => 'fulfillments' )
+ );
}
}
diff --git a/plugins/woocommerce/src/Admin/Features/Fulfillments/Fulfillment.php b/plugins/woocommerce/src/Admin/Features/Fulfillments/Fulfillment.php
index efd47e93db4..3792632eae9 100644
--- a/plugins/woocommerce/src/Admin/Features/Fulfillments/Fulfillment.php
+++ b/plugins/woocommerce/src/Admin/Features/Fulfillments/Fulfillment.php
@@ -12,7 +12,6 @@ declare( strict_types=1 );
namespace Automattic\WooCommerce\Admin\Features\Fulfillments;
-use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
use WC_Meta_Data;
defined( 'ABSPATH' ) || exit;
@@ -46,7 +45,7 @@ class Fulfillment extends \WC_Data {
}
// Load the items array.
- $this->data_store = wc_get_container()->get( FulfillmentsDataStore::class );
+ $this->data_store = \WC_Data_Store::load( 'order-fulfillment' );
if ( $this->get_id() > 0 ) {
$this->data_store->read( $this );
}
diff --git a/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsController.php b/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsController.php
index 8eecb295d91..8e9999b4787 100644
--- a/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsController.php
+++ b/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsController.php
@@ -2,6 +2,7 @@
namespace Automattic\WooCommerce\Admin\Features\Fulfillments;
+use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
use Automattic\WooCommerce\Internal\Features\FeaturesController;
use Automattic\WooCommerce\Internal\Utilities\DatabaseUtil;
@@ -29,9 +30,36 @@ class FulfillmentsController {
* @return void
*/
public function register() {
+ add_filter( 'woocommerce_data_stores', array( $this, 'register_data_stores' ) );
add_action( 'init', array( $this, 'initialize_fulfillments' ), 10, 0 );
}
+ /**
+ * Register the fulfillments data store via the woocommerce_data_stores filter.
+ *
+ * This allows extensions to replace the data store with a custom implementation
+ * by filtering 'woocommerce_data_stores' or 'woocommerce_order-fulfillment_data_store'.
+ *
+ * @param array $data_stores Data stores.
+ * @return array
+ */
+ public function register_data_stores( $data_stores ) {
+ if ( ! is_array( $data_stores ) ) {
+ return $data_stores;
+ }
+
+ $container = wc_get_container();
+ $features_controller = $container->get( FeaturesController::class );
+
+ // If fulfillments feature is not enabled, don't register the data store.
+ if ( ! $features_controller->feature_is_enabled( 'fulfillments' ) ) {
+ return $data_stores;
+ }
+
+ $data_stores['order-fulfillment'] = FulfillmentsDataStore::class;
+ return $data_stores;
+ }
+
/**
* Initialize the fulfillments controller.
*/
diff --git a/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsManager.php b/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsManager.php
index 88c8255d1d1..541f5dbca68 100644
--- a/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsManager.php
+++ b/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsManager.php
@@ -7,7 +7,6 @@ declare( strict_types=1 );
namespace Automattic\WooCommerce\Admin\Features\Fulfillments;
-use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
use Automattic\WooCommerce\Admin\Features\Fulfillments\Providers\AbstractShippingProvider;
use WC_Order;
use WC_Order_Refund;
@@ -134,14 +133,21 @@ class FulfillmentsManager {
return;
}
- /**
- * Get the FulfillmentsDataStore instance.
- *
- * @var FulfillmentsDataStore $fulfillments_data_store
- */
- $fulfillments_data_store = wc_get_container()->get( FulfillmentsDataStore::class );
- // Read all fulfillments for the order.
- $fulfillments = $fulfillments_data_store->read_fulfillments( \WC_Order::class, (string) $order->get_id() );
+ try {
+ /**
+ * Fulfillments data store.
+ *
+ * @var \Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore $fulfillments_data_store
+ */
+ $fulfillments_data_store = \WC_Data_Store::load( 'order-fulfillment' );
+ $fulfillments = $fulfillments_data_store->read_fulfillments( \WC_Order::class, (string) $order->get_id() );
+ } catch ( \Throwable $e ) {
+ wc_get_logger()->error(
+ sprintf( 'Failed to load fulfillments for order %d: %s', $order->get_id(), $e->getMessage() ),
+ array( 'source' => 'fulfillments' )
+ );
+ return;
+ }
$this->update_fulfillment_status( $order, $fulfillments );
}
@@ -172,8 +178,21 @@ class FulfillmentsManager {
return; // If the order is not valid, do nothing.
}
- $fulfillments_data_store = wc_get_container()->get( FulfillmentsDataStore::class );
- $fulfillments = $fulfillments_data_store->read_fulfillments( \WC_Order::class, (string) $order_id );
+ try {
+ /**
+ * Fulfillments data store.
+ *
+ * @var \Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore $fulfillments_data_store
+ */
+ $fulfillments_data_store = \WC_Data_Store::load( 'order-fulfillment' );
+ $fulfillments = $fulfillments_data_store->read_fulfillments( \WC_Order::class, (string) $order_id );
+ } catch ( \Throwable $e ) {
+ wc_get_logger()->error(
+ sprintf( 'Failed to load fulfillments for order %d: %s', $order_id, $e->getMessage() ),
+ array( 'source' => 'fulfillments' )
+ );
+ return;
+ }
$this->update_fulfillment_status( $order, $fulfillments );
}
@@ -208,8 +227,21 @@ class FulfillmentsManager {
}
// Get the fulfillments data store and read all fulfillments for the order.
- $fulfillments_data_store = wc_get_container()->get( FulfillmentsDataStore::class );
- $fulfillments = $fulfillments_data_store->read_fulfillments( \WC_Order::class, (string) $order_id );
+ try {
+ /**
+ * Fulfillments data store.
+ *
+ * @var \Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore $fulfillments_data_store
+ */
+ $fulfillments_data_store = \WC_Data_Store::load( 'order-fulfillment' );
+ $fulfillments = $fulfillments_data_store->read_fulfillments( \WC_Order::class, (string) $order_id );
+ } catch ( \Throwable $e ) {
+ wc_get_logger()->error(
+ sprintf( 'Failed to load fulfillments for order %d: %s', $order_id, $e->getMessage() ),
+ array( 'source' => 'fulfillments' )
+ );
+ return;
+ }
if ( empty( $fulfillments ) ) {
return; // No fulfillments found for the order.
}
diff --git a/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsRenderer.php b/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsRenderer.php
index c08ac2510aa..ea3933ca9ce 100644
--- a/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsRenderer.php
+++ b/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsRenderer.php
@@ -8,7 +8,6 @@ declare( strict_types=1 );
namespace Automattic\WooCommerce\Admin\Features\Fulfillments;
use Automattic\WooCommerce\Internal\Admin\WCAdminAssets;
-use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
use Automattic\WooCommerce\Utilities\OrderUtil;
use WC_Order;
@@ -558,8 +557,21 @@ class FulfillmentsRenderer {
}
// If not, fetch them and cache them.
- $data_store = wc_get_container()->get( FulfillmentsDataStore::class );
- $fulfillments = $data_store->read_fulfillments( WC_Order::class, '' . $order->get_id() );
+ try {
+ /**
+ * Fulfillments data store.
+ *
+ * @var \Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore $data_store
+ */
+ $data_store = \WC_Data_Store::load( 'order-fulfillment' );
+ $fulfillments = $data_store->read_fulfillments( WC_Order::class, '' . $order->get_id() );
+ } catch ( \Throwable $e ) {
+ wc_get_logger()->error(
+ sprintf( 'Failed to load fulfillments for order %d: %s', $order->get_id(), $e->getMessage() ),
+ array( 'source' => 'fulfillments' )
+ );
+ $fulfillments = array();
+ }
$this->fulfillments_cache[ $order->get_id() ] = $fulfillments;
return $fulfillments;
diff --git a/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsSettings.php b/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsSettings.php
index 3acf41c7dbb..f44123da2b5 100644
--- a/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsSettings.php
+++ b/plugins/woocommerce/src/Admin/Features/Fulfillments/FulfillmentsSettings.php
@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Automattic\WooCommerce\Admin\Features\Fulfillments;
-use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
use WC_Order;
/**
@@ -180,8 +179,22 @@ class FulfillmentsSettings {
}
// If fulfillments already exist, skip auto-fulfillment.
- $fulfillments = wc_get_container()->get( FulfillmentsDataStore::class )->read_fulfillments( \WC_Order::class, (string) $order_id );
- if ( ! empty( $fulfillments ) ) {
+ try {
+ /**
+ * Fulfillments data store.
+ *
+ * @var \Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore $fulfillment_data_store
+ */
+ $fulfillment_data_store = \WC_Data_Store::load( 'order-fulfillment' );
+ $fulfillments = $fulfillment_data_store->read_fulfillments( \WC_Order::class, (string) $order_id );
+ if ( ! empty( $fulfillments ) ) {
+ return;
+ }
+ } catch ( \Throwable $e ) {
+ wc_get_logger()->error(
+ sprintf( 'Failed to load fulfillments for order %d: %s', $order_id, $e->getMessage() ),
+ array( 'source' => 'fulfillments' )
+ );
return;
}
diff --git a/plugins/woocommerce/src/Admin/Features/Fulfillments/OrderFulfillmentsRestController.php b/plugins/woocommerce/src/Admin/Features/Fulfillments/OrderFulfillmentsRestController.php
index c0d2a29077f..9d7cffed2c7 100644
--- a/plugins/woocommerce/src/Admin/Features/Fulfillments/OrderFulfillmentsRestController.php
+++ b/plugins/woocommerce/src/Admin/Features/Fulfillments/OrderFulfillmentsRestController.php
@@ -9,7 +9,6 @@ namespace Automattic\WooCommerce\Admin\Features\Fulfillments;
use Automattic\WooCommerce\Internal\Admin\Settings\Exceptions\ApiException;
use Automattic\WooCommerce\Internal\RestApiControllerBase;
-use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
use WC_Order;
use WP_Http;
use WP_REST_Request;
@@ -216,9 +215,14 @@ class OrderFulfillmentsRestController extends RestApiControllerBase {
// Fetch fulfillments for the order.
try {
- $datastore = wc_get_container()->get( FulfillmentsDataStore::class );
+ /**
+ * Fulfillments data store.
+ *
+ * @var \Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore $datastore
+ */
+ $datastore = \WC_Data_Store::load( 'order-fulfillment' );
$fulfillments = $datastore->read_fulfillments( WC_Order::class, "$order_id" );
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return $this->prepare_error_response(
$e->getCode(),
$e->getMessage(),
@@ -272,7 +276,7 @@ class OrderFulfillmentsRestController extends RestApiControllerBase {
WP_Http::BAD_REQUEST
);
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return $this->prepare_error_response(
$e->getCode(),
$e->getMessage(),
@@ -306,7 +310,7 @@ class OrderFulfillmentsRestController extends RestApiControllerBase {
WP_Http::NOT_FOUND
);
}
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return $this->prepare_error_response(
$e->getCode(),
$e->getMessage(),
@@ -381,7 +385,7 @@ class OrderFulfillmentsRestController extends RestApiControllerBase {
$ex->getMessage(),
WP_Http::BAD_REQUEST
);
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return $this->prepare_error_response(
$e->getCode(),
$e->getMessage(),
@@ -418,7 +422,7 @@ class OrderFulfillmentsRestController extends RestApiControllerBase {
$ex->getMessage(),
WP_Http::BAD_REQUEST
);
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return $this->prepare_error_response(
$e->getCode(),
$e->getMessage(),
@@ -457,7 +461,7 @@ class OrderFulfillmentsRestController extends RestApiControllerBase {
try {
$fulfillment = new Fulfillment( $fulfillment_id );
$this->validate_fulfillment( $fulfillment, $fulfillment_id, $order_id );
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return $this->prepare_error_response(
$e->getCode(),
$e->getMessage(),
@@ -506,7 +510,7 @@ class OrderFulfillmentsRestController extends RestApiControllerBase {
$ex->getMessage(),
WP_Http::BAD_REQUEST
);
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return $this->prepare_error_response(
$e->getCode(),
$e->getMessage(),
@@ -545,7 +549,7 @@ class OrderFulfillmentsRestController extends RestApiControllerBase {
$ex->getMessage(),
WP_Http::BAD_REQUEST
);
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return $this->prepare_error_response(
$e->getCode(),
$e->getMessage(),
diff --git a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Fulfillments/Controller.php b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Fulfillments/Controller.php
index c30bb5ad5b8..e5226806d16 100644
--- a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Fulfillments/Controller.php
+++ b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Fulfillments/Controller.php
@@ -329,7 +329,7 @@ class Controller extends AbstractController {
$ex->getMessage(),
array( 'status' => esc_attr( WP_Http::BAD_REQUEST ) )
);
- } catch ( \Exception $e ) {
+ } catch ( \Throwable $e ) {
return new WP_Error(
'woocommerce_rest_fulfillment_invalid_id',
$e->getMessage(),
diff --git a/plugins/woocommerce/templates/order/order-details-fulfillments.php b/plugins/woocommerce/templates/order/order-details-fulfillments.php
index 8314f40a98d..a6da4726e3d 100644
--- a/plugins/woocommerce/templates/order/order-details-fulfillments.php
+++ b/plugins/woocommerce/templates/order/order-details-fulfillments.php
@@ -12,12 +12,11 @@
*
* @see https://woocommerce.com/document/template-structure/
* @package WooCommerce\Templates
- * @version 10.6.0
+ * @version 10.7.0
*
* @var bool $show_downloads Controls whether the downloads table should be rendered.
*/
-use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
use Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentUtils;
// phpcs:disable WooCommerce.Commenting.CommentHooks.MissingHookComment
@@ -61,7 +60,7 @@ if ( $show_downloads ) {
<table class="woocommerce-table woocommerce-table--order-details shop_table order_details">
<?php
- $fulfillments_data_store = wc_get_container()->get( FulfillmentsDataStore::class );
+ $fulfillments_data_store = \WC_Data_Store::load( 'order-fulfillment' );
$fulfillments = $fulfillments_data_store->read_fulfillments( WC_Order::class, (string) $order->get_id() );
if ( FulfillmentUtils::has_pending_items( $order, $fulfillments ) ) {
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentTest.php
index 576b901d239..d2c6d1e8764 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentTest.php
@@ -11,11 +11,19 @@ use WC_Order;
*/
class FulfillmentTest extends \WC_Unit_Test_Case {
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Set up the test environment.
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -26,7 +34,11 @@ class FulfillmentTest extends \WC_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentUtilsTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentUtilsTest.php
index 25fe09cc431..8795e80ccb5 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentUtilsTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentUtilsTest.php
@@ -8,11 +8,19 @@ use Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentUtils;
* FulfillmentUtilsTest class.
*/
class FulfillmentUtilsTest extends \WC_Unit_Test_Case {
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Set up the test environment.
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -23,7 +31,11 @@ class FulfillmentUtilsTest extends \WC_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsControllerTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsControllerTest.php
new file mode 100644
index 00000000000..c94d5ba20e4
--- /dev/null
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsControllerTest.php
@@ -0,0 +1,108 @@
+<?php
+declare( strict_types = 1 );
+
+namespace Automattic\WooCommerce\Tests\Admin\Features\Fulfillments;
+
+use Automattic\WooCommerce\Admin\Features\Fulfillments\DataStore\FulfillmentsDataStore;
+use Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController;
+use WC_Unit_Test_Case;
+
+/**
+ * Tests for the FulfillmentsController class.
+ */
+class FulfillmentsControllerTest extends WC_Unit_Test_Case {
+
+ /**
+ * The System Under Test.
+ *
+ * @var FulfillmentsController
+ */
+ private $sut;
+
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private $original_fulfillments_flag;
+
+ /**
+ * Set up test fixtures.
+ */
+ public function setUp(): void {
+ parent::setUp();
+ $this->original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
+ $this->sut = wc_get_container()->get( FulfillmentsController::class );
+ }
+
+ /**
+ * Tear down test fixtures.
+ */
+ public function tearDown(): void {
+ if ( false === $this->original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', $this->original_fulfillments_flag );
+ }
+ parent::tearDown();
+ }
+
+ /**
+ * @testdox Should register the order-fulfillment data store when feature is enabled.
+ */
+ public function test_register_data_stores_when_feature_enabled(): void {
+ update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
+
+ $result = $this->sut->register_data_stores( array() );
+
+ $this->assertArrayHasKey( 'order-fulfillment', $result, 'Data store should be registered when feature is enabled' );
+ $this->assertSame( FulfillmentsDataStore::class, $result['order-fulfillment'], 'Data store class should be FulfillmentsDataStore' );
+ }
+
+ /**
+ * @testdox Should not register the order-fulfillment data store when feature is disabled.
+ */
+ public function test_register_data_stores_when_feature_disabled(): void {
+ update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+
+ $result = $this->sut->register_data_stores( array() );
+
+ $this->assertArrayNotHasKey( 'order-fulfillment', $result, 'Data store should not be registered when feature is disabled' );
+ }
+
+ /**
+ * @testdox Should preserve existing data stores when feature is enabled.
+ */
+ public function test_register_data_stores_preserves_existing_stores(): void {
+ update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
+ $existing = array( 'some-store' => 'SomeStoreClass' );
+
+ $result = $this->sut->register_data_stores( $existing );
+
+ $this->assertArrayHasKey( 'some-store', $result, 'Existing data stores should be preserved' );
+ $this->assertSame( 'SomeStoreClass', $result['some-store'] );
+ $this->assertArrayHasKey( 'order-fulfillment', $result );
+ }
+
+ /**
+ * @testdox Should preserve existing data stores when feature is disabled.
+ */
+ public function test_register_data_stores_preserves_existing_stores_when_disabled(): void {
+ update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ $existing = array( 'some-store' => 'SomeStoreClass' );
+
+ $result = $this->sut->register_data_stores( $existing );
+
+ $this->assertArrayHasKey( 'some-store', $result, 'Existing data stores should be preserved' );
+ $this->assertArrayNotHasKey( 'order-fulfillment', $result );
+ }
+
+ /**
+ * @testdox Should return non-array input unchanged.
+ */
+ public function test_register_data_stores_returns_non_array_unchanged(): void {
+ $result = $this->sut->register_data_stores( 'not-an-array' );
+
+ $this->assertSame( 'not-an-array', $result, 'Non-array input should be returned unchanged' );
+ }
+}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsManagerTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsManagerTest.php
index 459dcec9041..7c8c4a9df37 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsManagerTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsManagerTest.php
@@ -19,11 +19,19 @@ class FulfillmentsManagerTest extends \WC_Unit_Test_Case {
*/
private FulfillmentsManager $manager;
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Set up the test environment.
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -34,7 +42,11 @@ class FulfillmentsManagerTest extends \WC_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRefundTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRefundTest.php
index a7835d17d86..d907a3954e1 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRefundTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRefundTest.php
@@ -29,11 +29,19 @@ class FulfillmentsRefundTest extends \WC_Unit_Test_Case {
*/
private FulfillmentsManager $manager;
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Set up the test environment.
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$container = wc_get_container();
$controller = $container->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
@@ -45,7 +53,11 @@ class FulfillmentsRefundTest extends \WC_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRendererHooksTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRendererHooksTest.php
index efd7b0d08cc..94ad20f5cf6 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRendererHooksTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRendererHooksTest.php
@@ -17,11 +17,19 @@ class FulfillmentsRendererHooksTest extends \WC_Unit_Test_Case {
*/
private FulfillmentsRenderer $renderer;
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Set up the test environment.
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -32,7 +40,11 @@ class FulfillmentsRendererHooksTest extends \WC_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRendererTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRendererTest.php
index cf77a6fa92e..4118ddf52e1 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRendererTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsRendererTest.php
@@ -23,11 +23,19 @@ class FulfillmentsRendererTest extends \WC_Unit_Test_Case {
*/
private FulfillmentsRenderer $renderer;
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Set up the test environment.
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -38,7 +46,11 @@ class FulfillmentsRendererTest extends \WC_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsSettingsTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsSettingsTest.php
index 7bf4a1b946e..e4bff6ddfeb 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsSettingsTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/FulfillmentsSettingsTest.php
@@ -15,11 +15,19 @@ use WC_Unit_Test_Case;
*/
class FulfillmentsSettingsTest extends WC_Unit_Test_Case {
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Set up the test environment.
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -30,7 +38,11 @@ class FulfillmentsSettingsTest extends WC_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/OrderFulfillmentsRestControllerTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/OrderFulfillmentsRestControllerTest.php
index d2af766ae5d..e72ca32bc84 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/OrderFulfillmentsRestControllerTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/OrderFulfillmentsRestControllerTest.php
@@ -36,6 +36,13 @@ class OrderFulfillmentsRestControllerTest extends WC_REST_Unit_Test_Case {
*/
private static int $created_user_id = -1;
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Setup test case.
*/
@@ -52,6 +59,7 @@ class OrderFulfillmentsRestControllerTest extends WC_REST_Unit_Test_Case {
public static function setupBeforeClass(): void {
parent::setupBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -87,7 +95,11 @@ class OrderFulfillmentsRestControllerTest extends WC_REST_Unit_Test_Case {
// Delete the created user.
wp_delete_user( self::$created_user_id );
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/ShippingProvidersTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/ShippingProvidersTest.php
index 43eb9df581b..7c98d0e641e 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/ShippingProvidersTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/ShippingProvidersTest.php
@@ -11,6 +11,34 @@ use Automattic\WooCommerce\Admin\Features\Fulfillments\Providers as ShippingProv
* This class tests the shipping providers configuration.
*/
class ShippingProvidersTest extends \WP_UnitTestCase {
+
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private $original_fulfillments_flag;
+
+ /**
+ * Set up the test environment.
+ */
+ public function setUp(): void {
+ parent::setUp();
+ $this->original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
+ }
+
+ /**
+ * Tear down the test environment.
+ */
+ public function tearDown(): void {
+ if ( false === $this->original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', $this->original_fulfillments_flag );
+ }
+ parent::tearDown();
+ }
+
/**
* Test that the shipping providers configuration returns the correct classes.
*/
diff --git a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/TrackingNumbersTest.php b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/TrackingNumbersTest.php
index d82b1d16d91..261d5c05fa2 100644
--- a/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/TrackingNumbersTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/Features/Fulfillments/TrackingNumbersTest.php
@@ -16,11 +16,19 @@ class TrackingNumbersTest extends WP_UnitTestCase {
*/
private $combinator;
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private $original_fulfillments_flag;
+
/**
* Set up the combinator instance.
*/
- protected function setUp(): void {
+ public function setUp(): void {
parent::setUp();
+ $this->original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -28,6 +36,18 @@ class TrackingNumbersTest extends WP_UnitTestCase {
$this->combinator = wc_get_container()->get( FulfillmentsManager::class );
}
+ /**
+ * Tear down the test environment.
+ */
+ public function tearDown(): void {
+ if ( false === $this->original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', $this->original_fulfillments_flag );
+ }
+ parent::tearDown();
+ }
+
/**
* Data provider for all major shipping provider patterns.
*
diff --git a/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Fulfillments/ControllerTest.php b/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Fulfillments/ControllerTest.php
index 897e92854d0..9c1e1ba31ac 100644
--- a/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Fulfillments/ControllerTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Fulfillments/ControllerTest.php
@@ -25,6 +25,13 @@ class ControllerTest extends WC_REST_Unit_Test_Case {
*/
private FulfillmentsController $controller;
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Admin user for tests
*
@@ -58,6 +65,7 @@ class ControllerTest extends WC_REST_Unit_Test_Case {
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -68,7 +76,11 @@ class ControllerTest extends WC_REST_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}
diff --git a/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Fulfillments/ProvidersTest.php b/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Fulfillments/ProvidersTest.php
index 2488d6be6b1..fb3ebdb6f6a 100644
--- a/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Fulfillments/ProvidersTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/RestApi/Routes/V4/Fulfillments/ProvidersTest.php
@@ -21,6 +21,13 @@ class ProvidersTest extends WC_REST_Unit_Test_Case {
*/
private FulfillmentsController $controller;
+ /**
+ * Original value of the fulfillments feature flag.
+ *
+ * @var mixed
+ */
+ private static $original_fulfillments_flag;
+
/**
* Admin user for tests
*
@@ -47,6 +54,7 @@ class ProvidersTest extends WC_REST_Unit_Test_Case {
*/
public static function setUpBeforeClass(): void {
parent::setUpBeforeClass();
+ self::$original_fulfillments_flag = get_option( 'woocommerce_feature_fulfillments_enabled' );
update_option( 'woocommerce_feature_fulfillments_enabled', 'yes' );
$controller = wc_get_container()->get( \Automattic\WooCommerce\Admin\Features\Fulfillments\FulfillmentsController::class );
$controller->register();
@@ -57,7 +65,11 @@ class ProvidersTest extends WC_REST_Unit_Test_Case {
* Tear down the test environment.
*/
public static function tearDownAfterClass(): void {
- update_option( 'woocommerce_feature_fulfillments_enabled', 'no' );
+ if ( false === self::$original_fulfillments_flag ) {
+ delete_option( 'woocommerce_feature_fulfillments_enabled' );
+ } else {
+ update_option( 'woocommerce_feature_fulfillments_enabled', self::$original_fulfillments_flag );
+ }
parent::tearDownAfterClass();
}