orders_page_controller ) ) { $this->orders_page_controller = wc_get_container()->get( PageController::class ); } return $this->orders_page_controller; } /** * Setup hooks, actions and variables needed to render order edit page. * * @param \WC_Order $order Order object. */ public function setup( \WC_Order $order ) { $this->order = $order; $current_screen = get_current_screen(); $current_screen->is_block_editor( false ); $this->screen_id = $current_screen->id; if ( ! isset( $this->custom_meta_box ) ) { $this->custom_meta_box = wc_get_container()->get( CustomMetaBox::class ); } if ( ! isset( $this->taxonomies_meta_box ) ) { $this->taxonomies_meta_box = wc_get_container()->get( TaxonomiesMetaBox::class ); } $this->add_save_meta_boxes(); $this->handle_order_update(); $this->add_order_meta_boxes( $this->screen_id, __( 'Order', 'woocommerce' ) ); $this->add_order_specific_meta_box(); $this->add_order_taxonomies_meta_box(); /** * From wp-admin/includes/meta-boxes.php. * * Fires after all built-in meta boxes have been added. Custom metaboxes may be enqueued here. * * @since 3.8.0. */ do_action( 'add_meta_boxes', $this->screen_id, $this->order ); /** * Provides an opportunity to inject custom meta boxes into the order editor screen. This * hook is an analog of `add_meta_boxes_` as provided by WordPress core. * * @since 7.4.0 * * @param WC_Order $order The order being edited. */ do_action( 'add_meta_boxes_' . $this->screen_id, $this->order ); $this->enqueue_scripts(); } /** * Set the current action for the form. * * @param string $action Action name. */ public function set_current_action( string $action ) { $this->current_action = $action; } /** * Hooks meta box for order specific meta. */ private function add_order_specific_meta_box() { add_meta_box( 'order_custom', __( 'Custom Fields', 'woocommerce' ), array( $this, 'render_custom_meta_box' ), $this->screen_id, 'normal' ); } /** * Render custom meta box. * * @return void */ private function add_order_taxonomies_meta_box() { $this->taxonomies_meta_box->add_taxonomies_meta_boxes( $this->screen_id, $this->order->get_type() ); } /** * Register order attribution meta boxes if the feature is enabled. * * @since 8.5.0 * * @param string $screen_id Screen ID. * @param string $title Title of the page. * * @return void */ private static function maybe_register_order_attribution( string $screen_id, string $title ) { /** * Features controller. * * @var FeaturesController $feature_controller */ $feature_controller = wc_get_container()->get( FeaturesController::class ); if ( ! $feature_controller->feature_is_enabled( 'order_attribution' ) ) { return; } /** * Order attribution meta box. * * @var OrderAttribution $order_attribution_meta_box */ $order_attribution_meta_box = wc_get_container()->get( OrderAttribution::class ); add_meta_box( 'woocommerce-order-source-data', /* Translators: %s order type name. */ sprintf( __( '%s attribution', 'woocommerce' ), $title ), function( $post_or_order ) use ( $order_attribution_meta_box ) { $order = $post_or_order instanceof WC_Order ? $post_or_order : wc_get_order( $post_or_order ); if ( $order instanceof WC_Order ) { $order_attribution_meta_box->output( $order ); } }, $screen_id, 'side', 'high' ); // Add customer history meta box if analytics is enabled. if ( 'yes' !== get_option( 'woocommerce_analytics_enabled' ) ) { return; } if ( ! OrderUtil::is_order_edit_screen() ) { return; } /** * Customer history meta box. * * @var CustomerHistory $customer_history_meta_box */ $customer_history_meta_box = wc_get_container()->get( CustomerHistory::class ); add_meta_box( 'woocommerce-customer-history', __( 'Customer history', 'woocommerce' ), function ( $post_or_order ) use ( $customer_history_meta_box ) { $order = $post_or_order instanceof WC_Order ? $post_or_order : wc_get_order( $post_or_order ); if ( $order instanceof WC_Order ) { $customer_history_meta_box->output( $order ); } }, $screen_id, 'side', 'high' ); } /** * Takes care of updating order data. Fires action that metaboxes can hook to for order data updating. * * @return void */ public function handle_order_update() { if ( ! isset( $this->order ) ) { return; } if ( 'edit_order' !== sanitize_text_field( wp_unslash( $_POST['action'] ?? '' ) ) ) { return; } check_admin_referer( $this->get_order_edit_nonce_action() ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized later on by taxonomies_meta_box object. $taxonomy_input = isset( $_POST['tax_input'] ) ? wp_unslash( $_POST['tax_input'] ) : null; $this->taxonomies_meta_box->save_taxonomies( $this->order, $taxonomy_input ); /** * Save meta for shop order. * * @param int Order ID. * @param \WC_Order Post object. * * @since 2.1.0 */ do_action( 'woocommerce_process_shop_order_meta', $this->order->get_id(), $this->order ); $this->custom_meta_box->handle_metadata_changes($this->order); // Order updated message. $this->message = 1; // Claim lock. $edit_lock = wc_get_container()->get( EditLock::class ); $edit_lock->lock( $this->order ); $this->redirect_order( $this->order ); } /** * Helper method to redirect to order edit page. * * @since 8.0.0 * * @param \WC_Order $order Order object. */ private function redirect_order( \WC_Order $order ) { $redirect_to = $this->get_page_controller()->get_edit_url( $order->get_id() ); if ( isset( $this->message ) ) { $redirect_to = add_query_arg( 'message', $this->message, $redirect_to ); } wp_safe_redirect( /** * Filter the URL used to redirect after an order is updated. Similar to the WP post's `redirect_post_location` filter. * * @param string $redirect_to The redirect destination URL. * @param int $order_id The order ID. * @param \WC_Order $order The order object. * * @since 8.0.0 */ apply_filters( 'woocommerce_redirect_order_location', $redirect_to, $order->get_id(), $order ) ); exit; } /** * Helper method to get the name of order edit nonce. * * @return string Nonce action name. */ private function get_order_edit_nonce_action() { return 'update-order_' . $this->order->get_id(); } /** * Render meta box for order specific meta. */ public function render_custom_meta_box() { $this->custom_meta_box->output( $this->order ); } /** * Render order edit page. */ public function display() { /** * This is used by the order edit page to show messages in the notice fields. * It should be similar to post_updated_messages filter, i.e.: * array( * {order_type} => array( * 1 => 'Order updated.', * 2 => 'Custom field updated.', * ... * ). * * The index to be displayed is computed from the $_GET['message'] variable. * * @since 7.4.0. */ $messages = apply_filters( 'woocommerce_order_updated_messages', array() ); $message = $this->message; if ( isset( $_GET['message'] ) ) { $message = absint( $_GET['message'] ); } if ( isset( $message ) ) { $message = $messages[ $this->order->get_type() ][ $message ] ?? false; } $this->render_wrapper_start( '', $message ); $this->render_meta_boxes(); $this->render_wrapper_end(); } /** * Helper function to render wrapper start. * * @param string $notice Notice to display, if any. * @param string $message Message to display, if any. */ private function render_wrapper_start( $notice = '', $message = '' ) { $post_type = get_post_type_object( $this->order->get_type() ); $edit_page_url = $this->get_page_controller()->get_edit_url( $this->order->get_id() ); $form_action = 'edit_order'; $referer = wp_get_referer(); $new_page_url = $this->get_page_controller()->get_new_page_url( $this->order->get_type() ); ?>

current_action ? esc_html( $post_type->labels->add_new_item ) : esc_html( $post_type->labels->edit_item ); ?>

current_action ) { echo ' ' . esc_html( $post_type->labels->add_new ) . ''; } ?>

order ); ?> > get_order_edit_nonce_action() ); ?> order ); wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false ); wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false ); ?> order->get_status( 'edit' ); ?>
screen_id, 'side', $this->order ); ?>
screen_id, 'normal', $this->order ); do_meta_boxes( $this->screen_id, 'advanced', $this->order ); ?>