[HPOS] Add properties and methods for detecting order admin screens more easily (#38417)

This commit is contained in:
Vedanshu Jain 2023-06-01 12:07:16 +05:30 committed by GitHub
commit 25843a9baf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 323 additions and 1 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add properties and methods for detecting order admin screens more easily.

View File

@ -319,7 +319,7 @@ class WC_Admin_Menus {
*/
public function orders_menu(): void {
if ( wc_get_container()->get( CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled() ) {
$this->orders_page_controller = new Custom_Orders_PageController();
$this->orders_page_controller = wc_get_container()->get( Custom_Orders_PageController::class );
$this->orders_page_controller->setup();
} else {
wc_get_container()->get( COTRedirectionController::class )->setup();

View File

@ -152,6 +152,9 @@ class PageController {
* Perform initialization for the current action.
*/
private function handle_load_page_action() {
$screen = get_current_screen();
$screen->post_type = $this->order_type;
if ( method_exists( $this, 'setup_action_' . $this->current_action ) ) {
$this->{"setup_action_{$this->current_action}"}();
}
@ -425,4 +428,89 @@ class PageController {
return admin_url( 'admin.php?page=wc-orders' . ( 'shop_order' === $order_type ? '' : '--' . $order_type ) );
}
/**
* Helper method to check if the current admin screen is related to orders.
*
* @param string $type Optional. The order type to check for. Default shop_order.
* @param string $action Optional. The purpose of the screen to check for. 'list', 'edit', or 'new'.
* Leave empty to check for any order screen.
*
* @return bool
*/
public function is_order_screen( $type = 'shop_order', $action = '' ) : bool {
if ( ! did_action( 'current_screen' ) ) {
wc_doing_it_wrong(
__METHOD__,
sprintf(
// translators: %s is the name of a function.
esc_html__( '%s must be called after the current_screen action.', 'woocommerce' ),
esc_html( __METHOD__ )
),
'x.x.x'
);
return false;
}
$valid_types = wc_get_order_types( 'view-order' );
if ( ! in_array( $type, $valid_types, true ) ) {
wc_doing_it_wrong(
__METHOD__,
sprintf(
// translators: %s is the name of an order type.
esc_html__( '%s is not a valid order type.', 'woocommerce' ),
esc_html( $type )
),
'x.x.x'
);
return false;
}
if ( wc_get_container()->get( CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled() ) {
if ( $action ) {
switch ( $action ) {
case 'edit':
$is_action = 'edit_order' === $this->current_action;
break;
case 'list':
$is_action = 'list_orders' === $this->current_action;
break;
case 'new':
$is_action = 'new_order' === $this->current_action;
break;
default:
$is_action = false;
break;
}
}
$type_match = $type === $this->order_type;
$action_match = ! $action || $is_action;
} else {
$screen = get_current_screen();
if ( $action ) {
switch ( $action ) {
case 'edit':
$screen_match = 'post' === $screen->base && filter_input( INPUT_GET, 'post', FILTER_VALIDATE_INT );
break;
case 'list':
$screen_match = 'edit' === $screen->base;
break;
case 'new':
$screen_match = 'post' === $screen->base && 'add' === $screen->action;
break;
default:
$screen_match = false;
break;
}
}
$type_match = $type === $screen->post_type;
$action_match = ! $action || $screen_match;
}
return $type_match && $action_match;
}
}

View File

@ -135,6 +135,39 @@ final class OrderUtil {
return wc_get_container()->get( PageController::class )->get_new_page_url();
}
/**
* Check if the current admin screen is an order list table.
*
* @param string $order_type Optional. The order type to check for. Default shop_order.
*
* @return bool
*/
public static function is_order_list_table_screen( $order_type = 'shop_order' ) : bool {
return wc_get_container()->get( PageController::class )->is_order_screen( $order_type, 'list' );
}
/**
* Check if the current admin screen is for editing an order.
*
* @param string $order_type Optional. The order type to check for. Default shop_order.
*
* @return bool
*/
public static function is_order_edit_screen( $order_type = 'shop_order' ) : bool {
return wc_get_container()->get( PageController::class )->is_order_screen( $order_type, 'edit' );
}
/**
* Check if the current admin screen is adding a new order.
*
* @param string $order_type Optional. The order type to check for. Default shop_order.
*
* @return bool
*/
public static function is_new_order_screen( $order_type = 'shop_order' ) : bool {
return wc_get_container()->get( PageController::class )->is_order_screen( $order_type, 'new' );
}
/**
* Get the name of the database table that's currently in use for orders.
*

View File

@ -0,0 +1,197 @@
<?php
namespace Automattic\WooCommerce\Tests\Internal\Admin\Orders {
use Automattic\WooCommerce\Internal\Admin\Orders\PageController;
use Automattic\WooCommerce\RestApi\UnitTests\HPOSToggleTrait;
/**
* Tests related to the HPOS orders admin pages controller.
*/
class PageControllerTest extends \WC_Unit_Test_Case {
use HPOSToggleTrait;
/**
* @var int ID of test admin user.
*/
private $user_admin;
/**
* Set up before each test.
*
* @return void
*/
public function setUp(): void {
parent::setUp();
$this->setup_cot();
$this->toggle_cot( false );
$this->user_admin = $this->factory->user->create( array( 'role' => 'administrator' ) );
wp_set_current_user( $this->user_admin );
global $mock_filter_input;
$mock_filter_input = false;
}
/**
* Tear down after each test.
*
* @return void
*/
public function tearDown(): void {
$this->clean_up_cot_setup();
parent::tearDown();
}
/**
* @testDox Basic order screen detection works.
*/
public function test_is_order_screen_any() {
set_current_screen();
$controller = new PageController();
$screen = get_current_screen();
$screen->post_type = 'shop_order';
$this->assertTrue( $controller->is_order_screen() );
$screen->post_type = 'post';
$this->assertFalse( $controller->is_order_screen() );
$this->toggle_cot( true );
global $pagenow, $plugin_page;
$controller = new PageController();
$pagenow = 'admin.php'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$plugin_page = 'wc-orders'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$controller->setup();
$this->assertTrue( $controller->is_order_screen() );
$controller = new PageController();
$pagenow = 'edit.php'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$controller->setup();
$this->assertFalse( $controller->is_order_screen() );
}
/**
* @testDox Order list table screen detection works.
*/
public function test_is_order_screen_list() {
set_current_screen();
$controller = new PageController();
$screen = get_current_screen();
$screen->post_type = 'shop_order';
$screen->base = 'edit';
$this->assertTrue( $controller->is_order_screen( 'shop_order', 'list' ) );
$screen->base = 'post';
$this->assertFalse( $controller->is_order_screen( 'shop_order', 'list' ) );
$this->toggle_cot( true );
global $pagenow, $plugin_page;
$controller = new PageController();
$pagenow = 'admin.php'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$plugin_page = 'wc-orders'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$_GET['action'] = '';
$controller->setup();
$this->assertTrue( $controller->is_order_screen( 'shop_order', 'list' ) );
$controller = new PageController();
$_GET['action'] = 'edit';
$controller->setup();
$this->assertFalse( $controller->is_order_screen( 'shop_order', 'list' ) );
}
/**
* @testDox Edit Order screen detection works.
*/
public function test_is_order_screen_edit() {
global $mock_filter_input, $mock_return;
$mock_filter_input = true;
set_current_screen();
$controller = new PageController();
$screen = get_current_screen();
$screen->post_type = 'shop_order';
$screen->base = 'post';
$mock_return = 123;
$this->assertTrue( $controller->is_order_screen( 'shop_order', 'edit' ) );
$mock_filter_input = false;
$this->assertFalse( $controller->is_order_screen( 'shop_order', 'edit' ) );
$this->toggle_cot( true );
global $pagenow, $plugin_page;
$controller = new PageController();
$pagenow = 'admin.php'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$plugin_page = 'wc-orders'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$_GET['action'] = 'edit';
$controller->setup();
$this->assertTrue( $controller->is_order_screen( 'shop_order', 'edit' ) );
$controller = new PageController();
$_GET['action'] = 'new';
$controller->setup();
$this->assertFalse( $controller->is_order_screen( 'shop_order', 'edit' ) );
}
/**
* @testDox Add New Order screen detection works.
*/
public function test_is_order_screen_new() {
set_current_screen();
$controller = new PageController();
$screen = get_current_screen();
$screen->post_type = 'shop_order';
$screen->base = 'post';
$screen->action = 'add';
$this->assertTrue( $controller->is_order_screen( 'shop_order', 'new' ) );
$screen->action = '';
$this->assertFalse( $controller->is_order_screen( 'shop_order', 'new' ) );
$this->toggle_cot( true );
global $pagenow, $plugin_page;
$controller = new PageController();
$pagenow = 'admin.php'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$plugin_page = 'wc-orders'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$_GET['action'] = 'new';
$controller->setup();
$this->assertTrue( $controller->is_order_screen( 'shop_order', 'new' ) );
$controller = new PageController();
$_GET['action'] = 'edit';
$controller->setup();
$this->assertFalse( $controller->is_order_screen( 'shop_order', 'new' ) );
}
}
}
/**
* Mocks for global functions used in PageController
*/
namespace Automattic\WooCommerce\Internal\Admin\Orders {
/**
* The filter_input function will return NULL if we change the $_GET or $_POST variables at runtime, so we
* need to override it in PageController's namespace when we want it to return a specific value for testing.
*
* @return mixed
*/
function filter_input() {
global $mock_filter_input, $mock_return;
if ( true === $mock_filter_input ) {
return $mock_return;
} else {
return call_user_func_array( '\filter_input', func_get_args() );
}
}
}