如何读取WooCommerce订单编辑页关联订单的Meta Boxes
问题:无法获取WooCommerce订单页面的Meta Boxes列表
我正在开发一个插件,需要列出WooCommerce订单页面(shop_order 自定义文章类型)关联的所有Meta Boxes,但尝试了两段代码都返回空列表:
第一段代码:
function get_woocommerce_order_meta_boxes() { $meta_boxes = array(); $post_type = 'shop_order'; $registered_meta_boxes = $GLOBALS['wp_meta_boxes'][$post_type]; if ($registered_meta_boxes && is_array($registered_meta_boxes)) { foreach ($registered_meta_boxes as $context => $priority_boxes) { if (is_array($priority_boxes)) { foreach ($priority_boxes as $priority => $boxes) { if (is_array($boxes)) { foreach ($boxes as $box_id => $box_data) { // Store the meta box ID in the array. $meta_boxes[] = $box_id; } } } } } } return $meta_boxes; } $woocommerce_order_meta_boxes = get_woocommerce_order_meta_boxes(); // Output the list of meta boxes. echo '<pre>'; print_r($woocommerce_order_meta_boxes); echo '</pre>';
更新1:尝试使用current_screen钩子的方案
function custom_woocommerce_edit_order_tasks() { $current_screen = get_current_screen(); if ($current_screen && $current_screen->id === 'shop_order') { error_log('Inside order edit page'); $dashboard_boxes = get_meta_boxes('shop_order'); error_log(print_r($dashboard_boxes, true)); } } function get_meta_boxes($screen = null, $context = 'advanced') { global $wp_meta_boxes; if (empty($screen)) { $screen = get_current_screen(); error_log(print_r($screen,true)); } elseif (is_string($screen)) { $screen = convert_to_screen($screen); error_log(print_r($screen,true)); } if (isset($wp_meta_boxes[$screen->id][$context])) { return $wp_meta_boxes[$screen->id][$context]; } else { return array(); } } add_action('current_screen', 'custom_woocommerce_edit_order_tasks',10,1);
日志显示WP_Screen对象正常,但返回的Meta Boxes数组始终为空。我需要获取所有可用Meta Boxes的ID、钩子名称等完整信息。
解决方案:选对钩子时机获取Meta Boxes
代码返回空的核心原因是钩子触发过早——current_screen执行时,WordPress和WooCommerce还没完成订单页面Meta Boxes的注册。Meta Boxes是通过add_meta_boxes动作注册的,必须在这个钩子之后读取$wp_meta_boxes全局变量。
修正后的代码示例
function get_all_order_meta_boxes() { global $wp_meta_boxes; $post_type = 'shop_order'; $meta_boxes = array(); // 确认Meta Boxes已注册 if (isset($wp_meta_boxes[$post_type]) && is_array($wp_meta_boxes[$post_type])) { // 遍历所有上下文(normal/side/advanced) foreach ($wp_meta_boxes[$post_type] as $context => $priority_groups) { // 遍历所有优先级 foreach ($priority_groups as $priority => $boxes) { // 遍历每个Meta Box,收集完整信息 foreach ($boxes as $box_id => $box_data) { $meta_boxes[] = array( 'id' => $box_id, 'title' => $box_data['title'], 'context' => $context, 'priority' => $priority, 'callback' => is_callable($box_data['callback']) ? get_class($box_data['callback'][0]) . '::' . $box_data['callback'][1] : $box_data['callback'] ); } } } } // 输出格式化的Meta Boxes列表 echo '<pre>'; print_r($meta_boxes); echo '</pre>'; } // 用add_meta_boxes_shop_order钩子,优先级设为20(晚于默认的10,确保所有Meta Boxes都注册完成) add_action('add_meta_boxes_shop_order', 'get_all_order_meta_boxes', 20);
代码说明
- 钩子时机:
add_meta_boxes_shop_order是专门针对订单类型的Meta Boxes注册完成后的钩子,优先级20能确保第三方插件和WooCommerce自身的Meta Boxes都已注册。 - 完整信息收集:不仅收集ID,还包含标题、显示位置、优先级、回调函数等关键信息,满足需求。
- 输出灵活:当前是在订单编辑页面直接输出,你也可以改成写入日志(
error_log(print_r($meta_boxes, true));)。
替代方案:仅在订单编辑页面加载时执行
如果需要只在订单编辑页加载时触发,可使用load-post.php钩子:
function log_order_meta_boxes_on_load() { $current_screen = get_current_screen(); if ($current_screen && $current_screen->id === 'shop_order') { global $wp_meta_boxes; error_log(print_r($wp_meta_boxes['shop_order'], true)); } } add_action('load-post.php', 'log_order_meta_boxes_on_load');
内容的提问来源于stack exchange,提问作者Siddharth
相关产品推荐
相关产品推荐

