如何在WooCommerce后台订单列表点击自定义按钮触发指定函数
Hey there! You’ve already nailed adding the custom button to your HPOS order list—great start! To get that button actually running your update_shipping_couriers_meta_field() function when clicked, we just need to wire up the form submission handling and fix a couple small issues in your existing code. Here's the step-by-step breakdown:
1. Update Your Button Code to Send a Clear Trigger
First, tweak your button to include a unique identifier in the form submission. This lets us detect when the "Import Couriers" button was clicked:
add_action( 'manage_posts_extra_tablenav', 'admin_order_list_top_bar_button', 20, 1 ); function admin_order_list_top_bar_button( $which ) { global $typenow; // Target HPOS orders and only the top toolbar if ( 'shop_order' === $typenow && 'top' === $which ) { ?> <div class="alignleft actions custom"> <!-- Add a unique name/value to identify this action --> <button type="submit" name="import_couriers" style="height:32px;" class="button" value="1"> <?php echo __( 'Import Couriers', 'woocommerce' ); ?> </button> </div> <?php } }
2. Add a Handler for the Button Submission
Next, we’ll hook into admin_init to check for the button’s trigger, validate the user has permission, and run your import function. We’ll also add admin notices to let you know if the import succeeded or failed:
add_action( 'admin_init', 'handle_courier_import_submission' ); function handle_courier_import_submission() { // Check if our button was clicked and user has proper permissions if ( isset( $_POST['import_couriers'] ) && current_user_can( 'edit_shop_orders' ) ) { // Run your import function $import_result = update_shipping_couriers_meta_field(); // Add admin notice based on result if ( is_int( $import_result ) && $import_result > 0 ) { add_action( 'admin_notices', function() use ( $import_result ) { echo '<div class="notice notice-success is-dismissible"><p>' . sprintf( __( 'Success! Updated %d orders with courier data.', 'woocommerce' ), $import_result ) . '</p></div>'; }); } else { add_action( 'admin_notices', function() { echo '<div class="notice notice-error is-dismissible"><p>' . __( 'No orders were updated—check your CSV file and try again.', 'woocommerce' ) . '</p></div>'; }); } } }
3. Fix & Refine Your Import Function
Your original function has a couple small syntax errors and a redundant loop that would cause duplicate processing. Here’s the cleaned-up version that returns the number of updated orders for our notice:
function update_shipping_couriers_meta_field() { $updated_count = 0; $csv_path = __DIR__ . '/import-couriers.csv'; // Check if CSV file exists first if ( ! file_exists( $csv_path ) ) { return 0; } // Read CSV lines $couriers = file( $csv_path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ); if ( empty( $couriers ) ) { return 0; } // Loop through each CSV row (removed the unnecessary do-while loop) foreach ( $couriers as $row ) { $row_data = explode( ';', $row ); // Make sure we have at least order ID and courier value if ( count( $row_data ) >= 2 && ! empty( $row_data[0] ) && ! empty( $row_data[1] ) ) { $order_id = intval( $row_data[0] ); $courier_value = sanitize_text_field( $row_data[1] ); // Update the meta field only if the order exists if ( wc_get_order( $order_id ) ) { update_post_meta( $order_id, '_shipping_couriers', $courier_value ); $updated_count++; } } } return $updated_count; }
Key Improvements Made:
- Added permission checks to prevent unauthorized access to the import action
- Added admin notices for feedback on import success/failure
- Fixed syntax errors (missing
$incount(couriers), replacedint()with validintval()) - Removed the redundant
do-whileloop that would repeat processing - Added checks for CSV file existence and valid row data
- Added validation that the order actually exists before updating meta
- Returns the number of updated orders for better feedback
Just drop all this code into your theme’s functions.php file or a custom plugin, and your button will now trigger the import when clicked!
内容的提问来源于stack exchange,提问作者Vincenzo Di Gaetano

