当前位置: 首页 > 知识库问答 >
问题:

WooCommerce:管理中的动态自定义结账字段

毕和志
2023-03-14

我有问题添加自定义结账字段到订单管理(也许电子邮件,我还没有)。撇开编码问题不谈,我主要遵循https://www.kathyisawesome.com/woocommerce-customize-checkout-fields/-到目前为止,这是我的代码:

http://pastebin.com/y8LDcDxS

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

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

>

  • 再次获取产品数量,并在标准字段名的末尾追加$i

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

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

    别的东西?

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

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

  • 共有1个答案

    丁雅懿
    2023-03-14

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

    /* 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' );
    

    “passenger_details”输入到底是什么?好吧,我们要定义它,因为woocommerce_form_field()有一个捕获,以防类型与WooCommerce的任何默认值不匹配。请参见'woocommerce_form_field_'。$args['type']

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

    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' );
    

    EDIT处理数据的清理和保存。请注意,我更改了上面的supreme_filter_checkout_field_group函数,并删除了ID参数。

    ~~使用id参数,我们可以动态设置输入名称。生成的标记应类似于:~~

    <input type="text" class="input-text " name="last_name" id="passenger_details[2]last_name" placeholder="" value="">
    

    name参数必须是一个数组!并且名称是从woocommerce_form_field()的第一个参数中提取的。ID与我们的需求无关,但需要是唯一的以保持适当的标记。这是我们需要的结果,现在应该得到上述修改:

    <input type="text" class="input-text " name="passenger_details[2][last_name]" id="passenger_details[2][last_name]" placeholder="" value="">
    

    现在提交$_POST['passenger_data']应该是数组(乘客)的数组(乘客详细信息)。经过我的编辑,它是!

    现在,为了处理这些数据并清理乘客数据中的各个字段,我们创建了一个用于清理自定义字段类型的函数:

    /**
     * Sanitize our custom field
     * 
     */
    function supreme_custom_process_checkout_field_passenger_details( $posted ){
    
        $clean = array();
    
        foreach( $posted as $passenger ){
            $details = supreme_custom_checkout_clean_passenger_details( $passenger );
    
            if( ! empty( $details ) ){
                $clean[] = $details;
            }
        }
    
        return $clean;
    }
    add_filter( 'woocommerce_process_checkout_passenger_details_field', 'supreme_custom_process_checkout_field_passenger_details' );
    
    
    function supreme_custom_checkout_clean_passenger_details( $passenger = array() ){
        $details = array();
        if( isset( $passenger["title"] ) ){
            $details['title'] = sanitize_text_field( $passenger["title"] );
        }
        if( isset( $passenger["first_name"] ) ){
            $details['first_name'] = sanitize_text_field( $passenger["first_name"] );
        }
        if( isset( $passenger["middle_name"] ) ){
            $details['middle_name'] = sanitize_text_field( $passenger["middle_name"] );
        }
        if( isset( $passenger["last_name"] ) ){
            $details['last_name'] = sanitize_text_field( $passenger["last_name"] );
        }
        if( isset( $passenger["date_of_birth"] ) ){
            $details['date_of_birth'] = $date = preg_replace("([^0-9/])", "", $passenger["date_of_birth"] );
        }
        if( isset( $passenger["dietary_required"] ) ){
            $details['dietary_required'] = $passenger["dietary_required"] == "y" ? "y": "n";
        }
        if( isset( $passenger["dietary_preference"] ) && isset( $passenger["dietary_required"] ) && $passenger["dietary_required"] == "y" ){
            $details['dietary_preference'] = $passenger["dietary_preference"] == "GF" ? "GF": "v";
        }
        return $details;
    }
    

    现在它已被清理,更新只需保存帖子元:

    /**
     * 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 detailspost 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" );
    

    这仍然会留下感谢页面和电子邮件,但数据仍然存在。

     类似资料:
    • 您好,我有一个关于woocommerce中自定义结账字段的问题。我在结帐表单中创建了一个自定义字段,一切都很顺利。该字段包含客户卡号。我还设法将字段值(第一次输入时)保存在wp usermeta中,这样它就不会只与订单一起出现,而是与客户详细信息一起保存。 现在我想做以下几点。一旦注册客户返回商店,进入结帐表单,新字段(如果不是empyt)将自动显示,而不是每次都要求客户插入他们的卡号。 我添加到

    • WooCommerce自定义结账字段的插件有Custom Checkout Fields for WooCommerce等,如果你想要更多的自由,就用代码来解决吧。本文介绍一种用代码来自定义WooCommerce结账字段的方法。 WooCommerce自定义结账字段代码 代码单独保存一个文件引入,或直接放到子主题的functions.php中,第二种方式请将 defined('WPINC') or

    • 向结账表单添加WooCommerce自定义结账字段,可以使用插件WooCommerce checkout manager或者filter:woocommerce_checkout_fields,本文介绍的方法非上述两种,而是使用woocommerce_form_field()函数在订单备注之后添加自定义结账字段,并将字段显示在订单详情、订单邮件和后台中的方法。 2021年10月更新:WooComm

    • 我以这种方式在woocommerce文档后面的签出处添加了一个字段: 然后我想在“管理订单编辑”页面上以以下方式显示: 当我进入订单编辑页面时,我得到一个空值我不知道为什么,我只是按照留档,但它不工作,我怎么能得到存储在自定义结帐字段中的数据?

    • 我正试图在结帐时将定制费用计入订单总额。我在woocommerce中添加了一个复选框 包含一个自定义js文件,可用于处理事件 和一个php费用处理函数 由于某些原因,$_POST['state']的值没有被添加,当我给出一个硬编码值时,函数会工作,我尝试了很多选项,但无法让它工作。 我看过类似的帖子,但没有一个有答案。

    • 我正在尝试获取WooCommerce产品的自定义字段值,以显示在商店系统的不同页面上。我成功地对单个产品页面执行了此操作,但相同的代码不适用于购物车。 对于单个产品,我在函数中使用了此代码。php,它可以很好地工作: 我为购物车尝试了相同的代码,但这次值没有显示在页面上。我还提到了这个线程(获取自定义属性),将$post更改为$product,但仍然没有输出。。。 有什么建议吗?