Automattic\WooCommerce\Internal\OrderReviews
SubmissionHandler::handle
Entry point fired by admin-ajax.php.
Sends a JSON response and exits.
Method of the class: SubmissionHandler{}
Hooks from the method
Returns
null. Nothing (null).
Usage
$SubmissionHandler = new SubmissionHandler(); $SubmissionHandler->handle(): void;
SubmissionHandler::handle() SubmissionHandler::handle code WC 10.8.1
public function handle(): void {
// phpcs:disable WordPress.Security.NonceVerification.Missing -- nonce is checked below.
$order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
$key = isset( $_POST['key'] ) && is_string( $_POST['key'] ) ? sanitize_text_field( wp_unslash( $_POST['key'] ) ) : '';
$nonce = isset( $_POST['_wcnonce'] ) && is_string( $_POST['_wcnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wcnonce'] ) ) : '';
// Row-level fields are sanitized inside process_rows(); the array as a whole only needs unslashing.
$rows_in = isset( $_POST['reviews'] ) && is_array( $_POST['reviews'] ) ? wp_unslash( $_POST['reviews'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
// phpcs:enable WordPress.Security.NonceVerification.Missing
if ( ! is_string( $nonce ) || ! wp_verify_nonce( $nonce, self::ACTION ) ) {
wp_send_json_error( array( 'message' => __( 'Security check failed.', 'woocommerce' ) ), 403 );
}
$order = $order_id ? wc_get_order( $order_id ) : false;
if ( ! $order instanceof WC_Order ) {
wp_send_json_error( array( 'message' => __( 'Order not found.', 'woocommerce' ) ), 404 );
}
if ( '' === $key || ! hash_equals( $order->get_order_key(), $key ) ) {
wp_send_json_error( array( 'message' => __( 'Order not found.', 'woocommerce' ) ), 404 );
}
// Logged-in user must own the order. Guests with the right key still pass.
if ( $order->get_customer_id() && is_user_logged_in() && get_current_user_id() !== $order->get_customer_id() ) {
wp_send_json_error( array( 'message' => __( 'Order not found.', 'woocommerce' ) ), 404 );
}
// Reuse the same eligibility filter the page-load endpoint uses so the
// submit path can never run on an order whose status no longer permits it.
// phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingHookComment -- documented on Endpoint::is_authorised().
$eligible_statuses = (array) apply_filters(
'woocommerce_review_order_eligible_statuses',
array( OrderStatus::COMPLETED ),
$order
);
if ( ! in_array( $order->get_status(), $eligible_statuses, true ) ) {
wp_send_json_error( array( 'message' => __( 'Order not found.', 'woocommerce' ) ), 404 );
}
$results = $this->process_rows( $order, $rows_in );
$this->maybe_mark_order_complete( $order );
/**
* Fires after the Review Order form has been processed.
*
* @since 10.8.0
*
* @param WC_Order $order The order.
* @param array $results Per-row outcomes — see `SubmissionHandler::process_rows()`.
*/
do_action( 'woocommerce_review_order_submitted', $order, $results );
wp_send_json_success( array( 'results' => $results ) );
}