在最近的订单模板和管理订单(woocommerce)上显示产品帖子类型高级自定义字段

我正在尝试显示我在 WooCommerce 最近的订单模板中创建的字段,但我对 PHP 不是很了解.

I’m trying to display the fields I have created in the recent order template of WooCommerce and I’m not very knowledgeable in PHP.

我创建了一个名为 session 的字段并注册为产品帖子类型.用户购买产品后,我希望在我的帐户">最近的订单"(模板)中显示海关字段 会话" 值.

I have created a field called sessions and registered as a product post type. Once a user purchase a product I want thats customs fields "sessions" values to be displayed in the My account > Recent orders (template).

我试图寻找答案和解决方案,但似乎卡住了.

I tried looking for answers and solutions and I seem to be stuck.

这里是我一直在做的 my-order.php 模板的自定义代码.我已经对其进行了数天的黑客攻击,但似乎无法在我最近的订单表中显示此值.

Here is the customized code of my-order.php template that I have been working on. I have been hacking it for days and can't seem to display this values in my recent orders table.

更新 - 添加图像和更多描述以澄清我的问题

1.) 正如您在此处看到的,我创建了两种类型的字段并将它们注册为产品帖子类型

1.) As you can see here I created two types of fields and registered them as product post type

2.) 然后我在我创建的这两个字段上放置了一个值

2.) Then I placed a value on those two fields I have created

3.) 一旦用户或客户购买了物品/产品/包裹.我希望这两个值显示在用户 my-account 模板的最近订单中 "Sessions"

3.) Once a user or customer purchase the item/product/package. I want those two values to be shown on the recent orders of the user my-account template under the column "Sessions"

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

$my_orders_columns = apply_filters( 'woocommerce_my_account_my_orders_columns', array(
    'order-number'   => __( 'Package', 'woocommerce' ),
    'sessions'       => __( 'Session', 'woocommerce' ),
    'order-total'    => __( 'Package Prize', 'woocommerce' ),
    'order-date'     => __( 'Date', 'woocommerce' ),
    'order-end-date' => __( 'End Date', 'woocommerce'),
    'order-status'   => __( 'Status', 'woocommerce' ),
    'order-actions'  => ' ',
) );

$customer_orders = get_posts( apply_filters( 'woocommerce_my_account_my_orders_query', array(
    'numberposts' => $order_count,
    'meta_key'    => '_customer_user',
    'meta_value'  => get_current_user_id(),
    'post_type'   => wc_get_order_types( 'view-orders' ),
    'post_status' => array_keys( wc_get_order_statuses() )
) ) );

if ( $customer_orders ) : ?>

    <h2><?php // echo apply_filters( 'woocommerce_my_account_my_orders_title', __( 'Recent Orders', 'woocommerce' ) ); ?></h2>

    <table class="shop_table shop_table_responsive my_account_orders">

        <thead>
            <tr>
                <?php foreach ( $my_orders_columns as $column_id => $column_name ) : ?>
                    <th class="<?php echo esc_attr( $column_id ); ?>"><span class="nobr"><?php echo esc_html( $column_name ); ?></span></th>
                <?php endforeach; ?>
            </tr>
        </thead>

        <tbody>
            <?php foreach ( $customer_orders as $customer_order ) :
                $order      = wc_get_order( $customer_order );
                $item_count = $order->get_item_count();
                ?>
                <tr class="order">
                    <?php foreach ( $my_orders_columns as $column_id => $column_name ) : ?>
                        <td class="<?php echo esc_attr( $column_id ); ?>" data-title="<?php echo esc_attr( $column_name ); ?>">
                            <?php if ( has_action( 'woocommerce_my_account_my_orders_column_' . $column_id ) ) : ?>
                                <?php do_action( 'woocommerce_my_account_my_orders_column_' . $column_id, $order ); ?>

                            <?php elseif ( 'order-number' === $column_id ) : ?>
                                <?php foreach($order->get_items() as $item) {
                                    $product_name = $item['name'];

                                } ?>

                                <?php echo $product_name;?>

                            <?php elseif ( 'session'  === $column_id ) : ?>
                                <?php if (get_field('session_period', $product->id) ) :  ?>



                            <?php endif; ?>


                            <?php elseif ( 'order-total' === $column_id ) : ?>
                                <?php echo sprintf( _n( '%s', '%s', $item_count, 'woocommerce' ), $order->get_formatted_order_total(), $item_count ); ?>

                            <?php elseif ( 'order-date' === $column_id ) : ?>
                                <time datetime="<?php echo date( 'Y-m-d', strtotime( $order->order_date ) ); ?>" title="<?php echo esc_attr( strtotime( $order->order_date ) ); ?>"><?php echo date_i18n( get_option( 'date_format' ), strtotime( $order->order_date ) ); ?></time>

                            <?php /* Order End Date */ ?>
                            <?php elseif ( 'order-end-date' === $column_id ) : ?>
                                <?php if (get_field('date_ended', $order->id) ) :    ?>
                                <p class="sendungsnummer"><?php the_field('date_ended', $order->id); ?>

                            <?php endif; ?>

                            <?php elseif ( 'order-status' === $column_id ) : ?>
                                <?php echo wc_get_order_status_name( $order->get_status() ); ?>


                            <?php elseif ( 'order-actions' === $column_id ) : ?>
                                <?php
                                    $actions = array(
                                        'pay'    => array(
                                            'url'  => $order->get_checkout_payment_url(),
                                            'name' => __( 'Pay', 'woocommerce' )
                                        ),
                                        'view'   => array(
                                            'url'  => $order->get_view_order_url(),
                                            'name' => __( 'View', 'woocommerce' )
                                        ),
                                        'cancel' => array(
                                            'url'  => $order->get_cancel_order_url( wc_get_page_permalink( 'myaccount' ) ),
                                            'name' => __( 'Cancel', 'woocommerce' )
                                        )
                                    );

                                    if ( ! $order->needs_payment() ) {
                                        unset( $actions['pay'] );
                                    }

                                    if ( ! in_array( $order->get_status(), apply_filters( 'woocommerce_valid_order_statuses_for_cancel', array( 'pending', 'failed' ), $order ) ) ) {
                                        unset( $actions['cancel'] );
                                    }

                                    /* -------- View Button --------
                                    if ( $actions = apply_filters( 'woocommerce_my_account_my_orders_actions', $actions, $order ) ) {
                                        foreach ( $actions as $key => $action ) {
                                            echo '<a href="' . esc_url( $action['url'] ) . '" class="button ' . sanitize_html_class( $key ) . '">' . esc_html( $action['name'] ) . '</a>';
                                        }
                                    }
                                    */
                                ?>
                            <?php endif; ?>
                        </td>
                    <?php endforeach; ?>
                </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
<?php endif; ?>

推荐答案

这里我们采用了一种与使用 ACF 插件制作的自定义字段不同的方法.我们创建了一个专用的元框,里面有 2 个字段,位于后端产品页面的右侧列,使用以下代码:

Here we are going on a different approach than custom fields made with ACF plugin. We create a dedicated metabox with 2 fields inside it, located on the right side column in backend product pages, with this code:

//
//Adding Meta container admin product pages
//
add_action( 'add_meta_boxes', 'cc_add_meta_boxes' );
if ( ! function_exists( 'cc_add_meta_boxes' ) )
{
    function cc_add_meta_boxes()
    {
        global $woocommerce, $post;

        add_meta_box( 'cc_other_fields', __('Sessions','woocommerce'), 'cc_add_other_fields_for_packaging', 'product', 'side', 'core' );
    }
}

//
//adding Meta field in the meta container admin product pages
//
if ( ! function_exists( 'cc_save_wc_order_other_fields' ) )
{
    function cc_add_other_fields_for_packaging()
    {
        global $woocommerce, $product, $post;

        $meta_field_session_period = get_post_meta( $post->ID, '_session_period', true ) ? get_post_meta( $post->ID, '_session_period', true ) : '';

        $meta_field_number_sessions = get_post_meta( $post->ID, '_number_sessions', true ) ? get_post_meta( $post->ID, '_number_sessions', true ) : '';

        echo '<input type="hidden" name="cc_other_meta_field_nonce" value="' . wp_create_nonce() . '">
    <p><label style="display:inline-block;" class="cc_opt_label">' .   __( "Session period", "your_theme_slug" ) . '</label><br>
        <input type="text" style="width:250px;";" name="session_period" placeholder="' . $meta_field_session_period . '" value="' . $meta_field_session_period . '"></p>
    <p><label style="display:inline-block;" class="cc_opt_label">' .   __( "Number of sessions", "your_theme_slug" ) . '</label><br>
        <input type="text" style="width:250px;";" name="number_sessions" placeholder="' . $meta_field_number_sessions . '" value="' . $meta_field_number_sessions . '"><br></p>';

    }
}

//Save the data of the product Meta fields pages
add_action( 'save_post', 'cc_save_product_other_fields', 10, 1 );
if ( ! function_exists( 'cc_save_product_other_fields' ) )
{

    function cc_save_product_other_fields( $post_id ) {

        // We need to verify this with the proper authorization (security stuff).

        // Check if our nonce is set.
        if ( ! isset( $_POST[ 'cc_other_meta_field_nonce' ] ) ) {
            return $post_id;
        }
        $nonce = $_REQUEST[ 'cc_other_meta_field_nonce' ];

        //Verify that the nonce is valid.
        if ( ! wp_verify_nonce( $nonce ) ) {
            return $post_id;
        }

        // If this is an autosave, our form has not been submitted, so we don't want to do anything.
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            return $post_id;
        }

        // Check the user's permissions.
        if ( 'page' == $_POST[ 'post_type' ] ) {

            if ( ! current_user_can( 'edit_page', $post_id ) ) {
                return $post_id;
            }
        } else {

            if ( ! current_user_can( 'edit_post', $post_id ) ) {
                return $post_id;
            }
        }
        // --- Its safe for us to save the data ! --- //

        // Sanitize user input  and update the meta field in the database.
        update_post_meta( $post_id, '_session_period', $_POST[ 'session_period' ] );
        update_post_meta( $post_id, '_number_sessions', $_POST[ 'number_sessions' ] );
    }
}

注意:您将此代码粘贴到活动子主题或主题的function.php文件中.

Note: you will paste this code in the function.php file of active child theme or theme.

如何在模板代码中使用它 + 更正的错误:

对于那些简单的字段,您不需要使用 ACF 插件.您还会发现缺少的代码来检索订单 ID、产品 ID 并显示在我的帐户 > 最近的订单表、会话数据:

You will not need to use ACF plugin for those simple fields. You will find also the missing code to retrieve order ID, Product ID and to display on My account > recent orders table, the sessions data:

// This is your existing code:
<?php 

<?php foreach ( $customer_orders as $customer_order ) :
                $order      = wc_get_order( $customer_order );

                // This way you can retrieve order ID:
                $order_id   = $order->post->ID;

您需要的:

if (get_field('date_ended', $order_id) ) : 
// or
if (get_field('date_ended', $order->post->id) ) :
// instead of: 
//get_field('date_ended', $order->id)

// and use </p> instead of <p> at the end of this line:
<p class="sendungsnummer"><?php the_field('date_ended', $order->id); ?></p>

.../...

foreach($order->get_items() as $item) {
$product_name = $item['name'];

// This way you can retrieve product ID:
$product_id = $item['product_id'];

.../...

您将使用产品 ID(或帖子 ID)和模板中的 Wordpress 函数get_post_meta() 访问此数据:

You will access this data with product ID (or post ID) and the Wordpress function get_post_meta() in your template:

// Then you get your data fields with this two:
$session_period = get_post_meta( $product_id, '_session_period', true );
$number_sessions = get_post_meta( $product_id, '_number_sessions', true ); 

您将使用它们,以这种方式显示它们的值:

And you will use them, displaying their values this way:

echo $session_period; // For Session period
echo $number_sessions; // For Number of sessions

.../...

elseif ( 'sessions'  === $column_id ) // <=== It is 'sessions' instead of 'session' !!!

这种方法更专业、更干净:

This approach is more professional and cleaner:

这是基于不同的问题,但有些类似:
WooCommerce:将自定义 Metabox 添加到管理订单页面

This is based on a different problem but some kind of similar:
WooCommerce : Add custom Metabox to admin order page

相关文章