Php WooCommerce:管理中的动态自定义签出字段

Php WooCommerce:管理中的动态自定义签出字段,php,wordpress,woocommerce,checkout,custom-fields,Php,Wordpress,Woocommerce,Checkout,Custom Fields,我在向订单管理员添加自定义签出字段时遇到问题(可能还有电子邮件,我还没有)。撇开编码问题不谈,我主要遵循以下原则-以下是我迄今为止的代码: 假设购物车中有一种产品,我让它根据产品数量添加$fields['extra_fields']的'x'金额。我正在与kia_display_order_data_in_admin()。我在pastebin中得到了非动态变化(基于购物车中有两个产品),我试图使此部件动态化的所有其他方法都不起作用 我看到了一些在管理中加载这些动态字段的选项,但我无法实现: 再次

我在向订单管理员添加自定义签出字段时遇到问题(可能还有电子邮件,我还没有)。撇开编码问题不谈,我主要遵循以下原则-以下是我迄今为止的代码:

假设购物车中有一种产品,我让它根据产品数量添加$fields['extra_fields']的'x'金额。我正在与kia_display_order_data_in_admin()。我在pastebin中得到了非动态变化(基于购物车中有两个产品),我试图使此部件动态化的所有其他方法都不起作用

我看到了一些在管理中加载这些动态字段的选项,但我无法实现:

  • 再次抓取产品数量,并将$i附加到标准字段名称的末尾

  • 以某种方式获取所有字段的数组,这样我就可以提取$fields['extra_fields']

  • 按订单id获取额外的\u字段post meta

  • 还有别的吗

  • 编辑:在Kia的帮助下,我对代码进行了一些修改,现在它将动态添加自定义签出字段。这可以一直工作到“管理订单”屏幕,但在尝试更新“管理
    kia\u save\u extra\u details()”中的订单详细信息时不起作用。


    编辑2:请查看下面的已接受答案,因为这适用于我的问题

    您确定产品附加组件可能不适合这一点吗?如果不是,我认为您需要的是一个自定义输入类型。这应该让你开始

    /* Add a new checkout field 
     * 
     * These is our base field group, later on, depending on product quanitiy, $key = 'passenger_title_1' for example
     * 
     */
    
    function supreme_filter_checkout_fields($fields){
        $fields['extra_fields'] = array(
        'passenger_details' => array(
            'type' => 'passenger_details',
            'required'      => false,
            'label' => __( 'Passenger Details' )
            ),
        );
    
        return $fields;
    
    }
    add_filter( 'woocommerce_checkout_fields', 'supreme_filter_checkout_fields' );
    
    “乘客详细信息”输入到底是什么?我们之所以要定义它,是因为
    woocommerce\u form\u field()
    有一个包罗万象的功能,以防类型与woocommerce的任何默认值都不匹配。看

    在这里,我们将列出您希望每个乘客使用的字段组

    function supreme_filter_checkout_field_group( $field, $key, $args, $value ){
        $op_cart_count = WC()->cart->get_cart_contents_count();
    
        $html = '';
    
        for ( $i = 1; $i <= $op_cart_count; $i++) {
    
            $html .= woocommerce_form_field( "passenger_details[$i][title]", array( 
                "type" => "select",
                "return" => true,
                "value" => "",
                "options" => array( "mr" => __( "Mr" ), "mrs" => __( "Mrs" ), "miss" => __( "Miss" ) ),
                "required"      => false,
                "label" => __( "Title" )
                )
            );
            $html .= woocommerce_form_field( "passenger_details[$i][first_name]", array(
                "type" => "text",
                "return" => true,
                "value" => "",
                "required"      => false,
                "label" => __( "First Name" )
                )
            );
            $html .= woocommerce_form_field( "passenger_details[$i][middle_name]", array(
                "type" => "text",
                "return" => true,
                "value" => "",
                "required"      => false,
                "label" => __( "Middle Name" )
                )
            );
            $html .= woocommerce_form_field( "passenger_details[$i][last_name]", array(
                "type" => "text",
                "return" => true,
                "value" => "",
                "required"      => false,
                "label" => __( "Last Name" )
                )
            );
            $html .= woocommerce_form_field( "passenger_details[$i][date_of_birth]", array(
                "type"          => "text",
                "return" => true,
                "value" => "",
                "class"         => array("date-of-birth form-row-wide"),
                "required"      => false,
                "label"         => __("Date of Birth"),
                "placeholder"       => __("Select Date"),
                "options"     =>   array("" => __("Date of Birth", "woocommerce" ))
                )
            );
            $html .= woocommerce_form_field( "passenger_details[$i][dietary_required]", array(
                "type" => "select",
                "return" => true,
                "value" => "",
                "class"         => array("dietary-required form-row-wide"),
                "options" => array( "" => __( "Please Select" ), "y" => __( "Yes" ), "n" => __( "No" ) ),
                "required"      => false,
                "label" => __( "Dietary Requirements?" )
                )
            );
            $html .= woocommerce_form_field( "passenger_details[$i][dietary_preference]", array(
                "type" => "select",
                "return" => true,
                "value" => "",
                "class"         => array("dietary-requirements form-row-wide"),
                "options" => array( "v" => __( "Vegetarian" ), "GF" => __( "Gluten Free" ) ),
                "required"      => false,
                "label" => __( "Meal Preferences" )
                )
            );
    
        }
        return $html;
    }
    add_filter( 'woocommerce_form_field_passenger_details', 'supreme_filter_checkout_field_group', 10, 4 );
    
    
    
    // display the extra field on the checkout form
    function supreme_extra_checkout_fields(){ 
    
        $checkout = WC()->checkout();
    
        foreach ( $checkout->checkout_fields['extra_fields'] as $key => $field ) :
    
            woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
    
        endforeach;
    
    
    }
    add_action( 'woocommerce_checkout_after_customer_details' ,'supreme_extra_checkout_fields' );
    
    这是错误的。
    name
    参数必须是数组!名称取自
    woocommerce\u form\u field()
    的第一个参数。ID与我们的需求无关,但确实需要唯一性来维护适当的标记。这是我们需要的结果,现在应该通过上述修改得到:

    <input type="text" class="input-text " name="passenger_details[2][last_name]" id="passenger_details[2][last_name]" placeholder="" value="">
    
    现在它已被清理,更新只需保存帖子元:

    /**
     * update_post_meta
     * 
     */
    function supreme_custom_checkout_field_update_order_meta( $order_id, $posted ){
    
        if( ! empty( $posted["passenger_details"] ) ){
            update_post_meta( $order_id, "_passenger_details", $posted["passenger_details"] );
        } else {
            delete_post_meta( $order_id, "_passenger_details" );
        }
    
    }
    add_action( 'woocommerce_checkout_update_order_meta', 'supreme_custom_checkout_field_update_order_meta', 10, 2 );
    
    现在,我们肯定已经将所有字段保存在
    \u passenger\u details
    post meta键中,我们可以在需要显示该数组的任何时候循环该数组。例如,它位于管理订单页面上:

    // display the extra data in the order admin panel
    function kia_display_order_data_in_admin( $order ){  
    
        $passenger_details = get_post_meta( $order->id, "_passenger_details", true ); 
    
        if( ! empty( $passenger_details ) ) { 
    
            $passenger_defaults = array(
                    "title" => "",
                    "first_name" => "",
                    "middle_name" => "",
                    "last_name" => "",
                    "date_of_birth" => "",
                    "dietary_required" => "",
                    "dietary_preference" => ""
                );
    
        ?>
        <div class="passenger_data">
            <h4><?php _e( "Passenger Details", "your-slug" ); ?></h4>
            <?php 
                $i = 1;
    
                foreach( $passenger_details as $passenger ){
    
                    $passenger = wp_parse_args( $passenger, $passenger_defaults );
    
                    echo "<p><strong>" . sprintf( __( "Passenger #%s", "your-slug" ), $i  ) . "</strong>" . "<br/>";
                    echo __( "Title", "your-slug" ) . ' : ' . $passenger["title"] . "<br/>";
                    echo __( "First Name", "your-slug" ) . ' : ' . $passenger["first_name"] . "<br/>";
                    echo __( "Middle Name", "your-slug" ) . ' : ' . $passenger["middle_name"] . "<br/>";
                    echo __( "Last Name", "your-slug" ) . ' : ' . $passenger["last_name"] . "<br/>";
                    echo __( "Date of Birth", "your-slug" ) . ' : ' . $passenger["date_of_birth"] . "<br/>";
                    echo __( "Dietary Required", "your-slug" ) . ' : ' . $passenger["dietary_required"] . "<br/>";
                    echo __( "Dietary Preference", "your-slug" ) . ' : ' . $passenger["dietary_preference"] . "<br/>";
    
                    echo "</p>";
    
                    $i++;
    
                }
    
             ?>
        </div>
    <?php }
    }
    add_action( "woocommerce_admin_order_data_after_order_details", "kia_display_order_data_in_admin" );
    
    //在订单管理面板中显示额外数据
    函数kia_显示_顺序_数据_管理($order){
    $passenger\u details=get\u post\u meta($order->id,“\u passenger\u details”,true);
    如果(!empty($passenger_details)){
    $passenger\u默认值=数组(
    “标题”=>“”,
    “名字”=>“”,
    “中间名称”=>“”,
    “姓氏”=>“”,
    “出生日期”=>“”,
    “所需膳食”=>“”,
    “饮食偏好”=>“
    );
    ?>
    
    感谢您查看我的网站。:)我已经回答了如何在签出中设置显示。希望您可以从那里开始。您有机会尝试吗?我确实尝试了下面的代码,但无法使用它/使其正常工作。感谢您在构建初始字段数组时提供的提示-消除了一些代码重复。新增。在管理中编辑详细信息后尝试更新时,它会一直工作到管理订单屏幕。我还没有尝试过电子邮件,但我认为这些邮件将与产品相关(很像这些签出字段应该如何),我可以试试其中一个,你们不需要使用pastebin,你们可以将代码粘贴到你们的问题中solution@tringwebdesign你从中得到了什么结果?(它不起作用总是含糊不清)什么部分不起作用?我可以在有时间的时候再看一看。它不会动态地添加额外的签出字段。TBH我知道你的输入才6天,但我记不起使用上面代码的结果,它显然不能作为纯复制粘贴片段工作,因此我修改了对原始问题的编辑。我如果愿意,可以返回并重新测试吗?请再次查看,当输入显示时,它们没有所需的“名称”属性。请查看修改后的答案。我已经测试了它,它确实保存了数据。谢谢@helgatheviking它确实有效,一些玛格丽塔爱发送给你了!现在要做的就是让管理订单编辑工作正常。我和我的客户谈过,他将使用Zapier管理给供应商的订单电子邮件等。
    /**
     * update_post_meta
     * 
     */
    function supreme_custom_checkout_field_update_order_meta( $order_id, $posted ){
    
        if( ! empty( $posted["passenger_details"] ) ){
            update_post_meta( $order_id, "_passenger_details", $posted["passenger_details"] );
        } else {
            delete_post_meta( $order_id, "_passenger_details" );
        }
    
    }
    add_action( 'woocommerce_checkout_update_order_meta', 'supreme_custom_checkout_field_update_order_meta', 10, 2 );
    
    // display the extra data in the order admin panel
    function kia_display_order_data_in_admin( $order ){  
    
        $passenger_details = get_post_meta( $order->id, "_passenger_details", true ); 
    
        if( ! empty( $passenger_details ) ) { 
    
            $passenger_defaults = array(
                    "title" => "",
                    "first_name" => "",
                    "middle_name" => "",
                    "last_name" => "",
                    "date_of_birth" => "",
                    "dietary_required" => "",
                    "dietary_preference" => ""
                );
    
        ?>
        <div class="passenger_data">
            <h4><?php _e( "Passenger Details", "your-slug" ); ?></h4>
            <?php 
                $i = 1;
    
                foreach( $passenger_details as $passenger ){
    
                    $passenger = wp_parse_args( $passenger, $passenger_defaults );
    
                    echo "<p><strong>" . sprintf( __( "Passenger #%s", "your-slug" ), $i  ) . "</strong>" . "<br/>";
                    echo __( "Title", "your-slug" ) . ' : ' . $passenger["title"] . "<br/>";
                    echo __( "First Name", "your-slug" ) . ' : ' . $passenger["first_name"] . "<br/>";
                    echo __( "Middle Name", "your-slug" ) . ' : ' . $passenger["middle_name"] . "<br/>";
                    echo __( "Last Name", "your-slug" ) . ' : ' . $passenger["last_name"] . "<br/>";
                    echo __( "Date of Birth", "your-slug" ) . ' : ' . $passenger["date_of_birth"] . "<br/>";
                    echo __( "Dietary Required", "your-slug" ) . ' : ' . $passenger["dietary_required"] . "<br/>";
                    echo __( "Dietary Preference", "your-slug" ) . ' : ' . $passenger["dietary_preference"] . "<br/>";
    
                    echo "</p>";
    
                    $i++;
    
                }
    
             ?>
        </div>
    <?php }
    }
    add_action( "woocommerce_admin_order_data_after_order_details", "kia_display_order_data_in_admin" );