Redirect new/edit/delete URLs from CPT implementation to COT (#34644)

Redirect legacy/CPT admin order URLs when Custom Order Tables are enabled.

* Add utility method to generate a link to the orders screen

* Add `PostsRedirectionController` to handle redirection from CPT-based URLs to new ones

* Use the redirections controller inside the orders screen PageController

* Add changelog

* Add check for COT enabled before enabling redirection controller

* Add support for trashing orders

* Update changelog

* Take into account ‘shop_orderplacehold’ when redirecting

* Correctly handle bulk actions
This commit is contained in:
Jorge A. Torres 2022-09-14 12:42:48 -03:00 committed by GitHub
parent d0e28b89b5
commit 2d3aa4fd45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 198 additions and 0 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: enhancement
Redirect CPT-based admin order URLs to the corresponding Custom Order Table URLs.

View File

@ -8,6 +8,13 @@ use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableControlle
*/
class PageController {
/**
* Instance of the posts redirection controller.
*
* @var PostsRedirectionController
*/
private $redirection_controller;
/**
* Instance of the orders list table.
*
@ -70,6 +77,8 @@ class PageController {
* @return void
*/
public function setup(): void {
$this->redirection_controller = new PostsRedirectionController( $this );
// Register menu.
if ( 'admin_menu' === current_action() ) {
$this->register_menu();
@ -214,6 +223,17 @@ class PageController {
$theorder = $this->order;
}
/**
* Helper method to generate a link to the main orders screen.
*
* @return string Orders screen URL.
*/
public function get_orders_url(): string {
return wc_get_container()->get( CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled() ?
admin_url( 'admin.php?page=wc-orders' ) :
admin_url( 'edit.php?post_type=shop_order' );
}
/**
* Helper method to generate edit link for an order.
*

View File

@ -0,0 +1,174 @@
<?php
namespace Automattic\WooCommerce\Internal\Admin\Orders;
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
/**
* When {@see OrdersTableDataStore} is in use, this class takes care of redirecting admins from CPT-based URLs
* to the new ones.
*/
class PostsRedirectionController {
/**
* Instance of the PageController class.
*
* @var PageController
*/
private $page_controller;
/**
* Constructor.
*
* @param PageController $page_controller Page controller instance. Used to generate links/URLs.
*/
public function __construct( PageController $page_controller ) {
$this->page_controller = $page_controller;
if ( ! wc_get_container()->get( CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled() ) {
return;
}
add_action(
'load-edit.php',
function() {
$this->maybe_redirect_to_orders_page();
}
);
add_action(
'load-post-new.php',
function() {
$this->maybe_redirect_to_new_order_page();
}
);
add_action(
'load-post.php',
function() {
$this->maybe_redirect_to_edit_order_page();
}
);
}
/**
* If needed, performs a redirection to the main orders page.
*
* @return void
*/
private function maybe_redirect_to_orders_page(): void {
if ( ! isset( $_GET['post_type'] ) || 'shop_order' !== $_GET['post_type'] ) {
return;
}
// Respect query args, except for 'post_type'.
$query_args = wp_unslash( $_GET );
$action = $query_args['action'] ?? '';
$posts = $query_args['post'] ?? array();
unset( $query_args['post_type'], $query_args['post'], $query_args['_wpnonce'], $query_args['_wp_http_referer'], $query_args['action'] );
// Remap 'post_status' arg.
if ( isset( $query_args['post_status'] ) ) {
$query_args['status'] = $query_args['post_status'];
unset( $query_args['post_status'] );
}
$new_url = $this->page_controller->get_orders_url();
// Handle bulk actions.
if ( $action && in_array( $action, array( 'trash', 'untrash', 'delete', 'mark_processing', 'mark_on-hold', 'mark_completed', 'mark_cancelled' ), true ) ) {
check_admin_referer( 'bulk-posts' );
$new_url = add_query_arg(
array(
'action' => $action,
'order' => $posts,
'_wp_http_referer' => $this->page_controller->get_orders_url(),
'_wpnonce' => wp_create_nonce( 'bulk-orders' ),
),
$new_url
);
}
wp_safe_redirect( $new_url, 301 );
exit;
}
/**
* If needed, performs a redirection to the new order page.
*
* @return void
*/
private function maybe_redirect_to_new_order_page(): void {
if ( ! isset( $_GET['post_type'] ) || 'shop_order' !== $_GET['post_type'] ) {
return;
}
// Respect query args, except for 'post_type'.
$query_args = wp_unslash( $_GET );
unset( $query_args['post_type'] );
$new_url = $this->page_controller->get_new_page_url();
$new_url = add_query_arg( $query_args, $new_url );
wp_safe_redirect( $new_url, 301 );
exit;
}
/**
* If needed, performs a redirection to the edit order page.
*
* @return void
*/
private function maybe_redirect_to_edit_order_page(): void {
$post_id = absint( $_GET['post'] ?? 0 );
if ( ! $post_id || ! in_array( get_post_type( $post_id ), array( 'shop_order_placehold', 'shop_order' ), true ) || ! isset( $_GET['action'] ) ) {
return;
}
// Respect query args, except for 'post'.
$query_args = wp_unslash( $_GET );
$action = $query_args['action'];
unset( $query_args['post'], $query_args['_wpnonce'], $query_args['_wp_http_referer'], $query_args['action'] );
$new_url = '';
switch ( $action ) {
case 'edit':
$new_url = $this->page_controller->get_edit_url( $post_id );
break;
case 'trash':
case 'untrash':
case 'delete':
// Re-generate nonce if validation passes.
check_admin_referer( $action . '-post_' . $post_id );
$new_url = add_query_arg(
array(
'action' => $action,
'order' => array( $post_id ),
'_wp_http_referer' => $this->page_controller->get_orders_url(),
'_wpnonce' => wp_create_nonce( 'bulk-orders' ),
),
$this->page_controller->get_orders_url()
);
break;
default:
break;
}
if ( ! $new_url ) {
return;
}
$new_url = add_query_arg( $query_args, $new_url );
wp_safe_redirect( $new_url, 301 );
exit;
}
}