Woocommerce后台订单页自定义表单邮件发送失败求助
Hey there! Let's fix your WooCommerce admin order form issue step by step. The main problems with your current code are incorrect hook usage, missing security checks, and not integrating properly with WooCommerce's admin page flow. Here's the revised solution that will make your form show only on order detail pages and send emails correctly:
What Was Wrong With Your Original Code?
- Incorrect Hook:
dbx_post_sidebaris designed for regular posts/pages, not WooCommerce order (custom post typeshop_order) admin pages. This means your form wasn't targeting the right location. - No Security Validation: Missing nonce fields left your form open to CSRF attacks, and WordPress might have blocked the submission silently.
- Submission Conflict: Using the current order page URI as the form action triggered WooCommerce's order update process instead of your email-sending logic.
- Unattached Logic: Your
deliver_mail()function wasn't hooked to any admin action, so it never ran when the form was submitted.
Fixed Complete Code
// Add custom form to WooCommerce admin order detail page add_action( 'woocommerce_admin_order_data_after_order_details', 'display_custom_order_form' ); function display_custom_order_form( $order ) { // Only show form to users with order editing permissions if ( ! current_user_can( 'edit_shop_orders' ) ) { return; } echo '<div class="custom-order-form" style="margin-top:20px;padding:15px;border:1px solid #eee;">'; echo '<h3>' . __( 'Send Custom Email', 'text-domain' ) . '</h3>'; // Use WordPress admin_post endpoint for secure submission echo '<form action="' . esc_url( admin_url( 'admin-post.php' ) ) . '" method="post">'; // Security nonce to validate legitimate requests wp_nonce_field( 'custom_order_email_nonce', 'custom_order_email_nonce_field' ); // Action parameter to trigger our submission handler echo '<input type="hidden" name="action" value="send_custom_order_email">'; // Pass order ID to include order context in email (optional) echo '<input type="hidden" name="order_id" value="' . esc_attr( $order->get_id() ) . '">'; // Name field echo '<p>'; echo __( 'Your Name (required)', 'text-domain' ) . '<br>'; echo '<input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="' . ( isset( $_POST["cf-name"] ) ? esc_attr( $_POST["cf-name"] ) : '' ) . '" size="40" required>'; echo '</p>'; // Email field echo '<p>'; echo __( 'Your Email (required)', 'text-domain' ) . '<br>'; echo '<input type="email" name="cf-email" value="' . ( isset( $_POST["cf-email"] ) ? esc_attr( $_POST["cf-email"] ) : '' ) . '" size="40" required>'; echo '</p>'; // Subject field echo '<p>'; echo __( 'Subject (required)', 'text-domain' ) . '<br>'; echo '<input type="text" name="cf-subject" pattern="[a-zA-Z ]+" value="' . ( isset( $_POST["cf-subject"] ) ? esc_attr( $_POST["cf-subject"] ) : '' ) . '" size="40" required>'; echo '</p>'; // Message field echo '<p>'; echo __( 'Your Message (required)', 'text-domain' ) . '<br>'; echo '<textarea rows="10" cols="35" name="cf-message" required>' . ( isset( $_POST["cf-message"] ) ? esc_textarea( $_POST["cf-message"] ) : '' ) . '</textarea>'; echo '</p>'; echo '<p><input type="submit" name="cf-submitted" value="' . __( 'Send', 'text-domain' ) . '" class="button button-primary"></p>'; echo '</form>'; echo '</div>'; } // Handle form submission and send email add_action( 'admin_post_send_custom_order_email', 'handle_custom_order_email_submission' ); function handle_custom_order_email_submission() { // Block unauthorized users if ( ! current_user_can( 'edit_shop_orders' ) ) { wp_die( __( 'You do not have permission to perform this action.', 'text-domain' ) ); } // Validate security nonce if ( ! isset( $_POST['custom_order_email_nonce_field'] ) || ! wp_verify_nonce( $_POST['custom_order_email_nonce_field'], 'custom_order_email_nonce' ) ) { wp_die( __( 'Invalid security token. Please try again.', 'text-domain' ) ); } // Sanitize and validate form data $name = isset( $_POST['cf-name'] ) ? sanitize_text_field( $_POST['cf-name'] ) : ''; $email = isset( $_POST['cf-email'] ) ? sanitize_email( $_POST['cf-email'] ) : ''; $subject = isset( $_POST['cf-subject'] ) ? sanitize_text_field( $_POST['cf-subject'] ) : ''; $message = isset( $_POST['cf-message'] ) ? esc_textarea( $_POST['cf-message'] ) : ''; $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0; // Check for required fields and valid email if ( empty( $name ) || empty( $email ) || empty( $subject ) || empty( $message ) || ! is_email( $email ) ) { wp_redirect( add_query_arg( 'custom_email_error', 'invalid_fields', wp_get_referer() ) ); exit; } // Get target email (default to admin, change to your desired address if needed) $to = get_option( 'admin_email' ); // Optional: Add order details to the email for context $order = wc_get_order( $order_id ); if ( $order ) { $message .= "\n\n--- Order Details ---\n"; $message .= "Order ID: " . $order->get_id() . "\n"; $message .= "Order Status: " . wc_get_order_status_name( $order->get_status() ) . "\n"; $message .= "Customer: " . $order->get_billing_first_name() . " " . $order->get_billing_last_name() . "\n"; } // Set proper email headers $headers = array( 'From: ' . $name . ' <' . $email . '>', 'Content-Type: text/plain; charset=UTF-8' ); // Send email and redirect with status if ( wp_mail( $to, $subject, $message, $headers ) ) { wp_redirect( add_query_arg( 'custom_email_success', '1', wp_get_referer() ) ); } else { wp_redirect( add_query_arg( 'custom_email_error', 'send_failed', wp_get_referer() ) ); } exit; } // Show admin notices for submission status add_action( 'admin_notices', 'custom_order_email_notices' ); function custom_order_email_notices() { // Success notice if ( isset( $_GET['custom_email_success'] ) && $_GET['custom_email_success'] == '1' ) { echo '<div class="notice notice-success is-dismissible">'; echo '<p>' . __( 'Email sent successfully!', 'text-domain' ) . '</p>'; echo '</div>'; } // Error notices if ( isset( $_GET['custom_email_error'] ) ) { $error_code = $_GET['custom_email_error']; switch ( $error_code ) { case 'invalid_fields': $message = __( 'Please fill in all required fields correctly.', 'text-domain' ); break; case 'send_failed': $message = __( 'Failed to send email. Please check your WordPress email settings (try using an SMTP plugin if needed).', 'text-domain' ); break; default: $message = __( 'An unexpected error occurred. Please try again.', 'text-domain' ); } echo '<div class="notice notice-error is-dismissible">'; echo '<p>' . $message . '</p>'; echo '</div>'; } }
Key Improvements Explained:
- Targeted Hook: Uses
woocommerce_admin_order_data_after_order_detailsto ensure the form only appears on WooCommerce admin order detail pages. - Secure Submission: Integrates WordPress's
admin_postsystem with nonce validation to prevent malicious requests. - Permission Checks: Restricts form access to users who can edit orders, keeping your admin area secure.
- Seamless UI Feedback: Uses WordPress admin notices instead of raw echo statements, matching WooCommerce's native admin experience.
- Order Context: Includes the order ID in the form, so you can add relevant order details to the email (optional but highly useful).
- Robust Validation: Combines HTML5
requiredattributes and server-side checks to ensure all form data is valid before sending.
Troubleshooting Tips:
- If emails still don't arrive, test your WordPress email setup with a plugin like WP Mail SMTP (many hosts block default PHP mail).
- Verify the form appears: Navigate to any order detail page in WooCommerce admin—you'll see it below the core order details section.
- Check admin notices: Any submission issues will show a clear, actionable error message at the top of the page.
内容的提问来源于stack exchange,提问作者Parth Shah
相关产品推荐
相关产品推荐

