Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 57 additions & 7 deletions includes/forms/WC_Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class WC_Order {
*/
public function __construct() {
add_action( 'load-woocommerce_page_wc-orders', array( $this, 'initialize' ) );
add_action( 'load-woocommerce_page_wc-orders--shop_subscription', array( $this, 'initialize' ) );
add_action( 'woocommerce_update_order', array( $this, 'save_order' ), 10, 1 );
// Defer registering other order type hooks to after all order types are registered
add_action( 'wp_loaded', array( $this, 'register_order_type_hooks' ) );
}

/**
Expand All @@ -39,6 +40,25 @@ public function initialize() {
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ), 10, 2 );
}

/**
* Registers initialization hooks for all WooCommerce order types.
*
* @since 6.4.4
* @return void
*/
public function register_order_type_hooks() {

$order_types = wc_get_order_types( 'view-orders' );

foreach ( $order_types as $order_type ) {
// shop_order uses the base hook without suffix
if ( 'shop_order' === $order_type ) {
continue;
}
add_action( 'load-woocommerce_page_wc-orders--' . $order_type, array( $this, 'initialize' ) );
}
}

/**
* Adds ACF metaboxes to the WooCommerce Order pages.
*
Expand All @@ -52,13 +72,19 @@ public function add_meta_boxes( $post_type, $post ) {
// Storage for localized postboxes.
$postboxes = array();

$location = 'shop_order';
$order = ( $post instanceof \WP_Post ) ? wc_get_order( $post->ID ) : $post;
$screen = $this->is_hpos_enabled() ? wc_get_page_screen_id( 'shop-order' ) : 'shop_order';
$order = ( $post instanceof \WP_Post ) ? wc_get_order( $post->ID ) : $post;
if ( ! $order ) {
return;
}

if ( $order instanceof \WC_Subscription ) {
$location = 'shop_subscription';
$screen = function_exists( 'wcs_get_page_screen_id' ) ? wcs_get_page_screen_id( 'shop_subscription' ) : 'shop_subscription';
// Dynamically get order type from the order object
$location = $order->get_type();

// Determine screen ID based on HPOS status and order type
if ( $this->is_hpos_enabled() ) {
$screen = $this->get_hpos_screen_id( $location );
} else {
$screen = $location;
}

// Get field groups for this screen.
Expand Down Expand Up @@ -141,6 +167,30 @@ public function add_meta_boxes( $post_type, $post ) {
do_action( 'acf/add_meta_boxes', $post_type, $post, $field_groups );
}

/**
* Gets the HPOS screen ID for an order type.
*
* @since 6.4.4
*
* @param string $order_type The order type (e.g., 'shop_order', 'shop_subscription', 'shop_order_charge').
* @return string The screen ID.
*/
protected function get_hpos_screen_id( string $order_type ): string {
// Check for WooCommerce Subscriptions helper function
if ( 'shop_subscription' === $order_type && function_exists( 'wcs_get_page_screen_id' ) ) {
return wcs_get_page_screen_id( 'shop_subscription' );
}

// For shop_order, use the standard WC function
if ( 'shop_order' === $order_type ) {
return wc_get_page_screen_id( 'shop-order' );
}

// For custom order types, construct the screen ID
// Pattern: woocommerce_page_wc-orders--{order_type}
return 'woocommerce_page_wc-orders--' . $order_type;
}

/**
* Renders hidden fields.
*
Expand Down
55 changes: 55 additions & 0 deletions tests/php/includes/forms/class-mock-wc-order.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* Mock WC_Order class for testing.
*
* @package wordpress/secure-custom-fields
*/

/**
* Mock WC_Order class for testing SCF WC_Order integration.
*/
class Mock_WC_Order {

/**
* Order ID.
*
* @var int
*/
private $id;

/**
* Order type.
*
* @var string
*/
private $type;

/**
* Constructor.
*
* @param int $id Order ID.
* @param string $type Order type.
*/
public function __construct( $id = 1, $type = 'shop_order' ) {
$this->id = $id;
$this->type = $type;
}

/**
* Get order ID.
*
* @return int
*/
public function get_id() {
return $this->id;
}

/**
* Get order type.
*
* @return string
*/
public function get_type() {
return $this->type;
}
}
Loading
Loading