将自定义数据从购物车项目传递到 Woocommerce 3 中的订单元

2023-11-29

我已经实现了一个自定义 HTML 表单,并要求提供一些数据,我的客户将传递这些数据以成功下订单。如果没有这些细节,我的订单就没有任何意义。

对于 HTML 表单,我引用了下面的一些自定义 PHP 脚本,该脚本处理来自表单的 POST 数据并以编程方式使用这些数据创建购物车。感谢@LoicTheAztec 帮助我实现这一目标。

The script.php文件代码:

<?php

    require_once("../wp-load.php");

    $customer_name = $_POST["customer_name"];
    $customer_email = $_POST["customer_email"];
    $customer_sex = $_POST["customer_sex"];
    $customer_age = $_POST["customer_age"];
    $product_id = $_POST["product_id"];

$custom_data = array(); // Initializing

    if( isset($_POST['customer_name']) && ! empty($_POST['customer_name']) )
        $custom_data['custom_data']['name']  =  $_POST['customer_name'];
    if( isset($_POST['customer_email']) && ! empty($_POST['customer_email']) )
        $custom_data['custom_data']['email'] = $_POST['customer_email'];
    if( isset($_POST['customer_sex']) && ! empty($_POST['customer_sex']) )
        $custom_data['custom_data']['sex']   = $_POST['customer_sex'];
    if( isset($_POST['customer_age']) && ! empty($_POST['customer_age']) )
        $custom_data['custom_data']['age']   = $_POST['customer_age'];

    global $woocommerce;

    if (WC()->cart->add_to_cart( $product_id, '1', '0', array(), $custom_data )) {
        var_dump($product_id);
    } else {
        var_dump($customer_name);
    }

    header("Location: ./checkout");
?>

正如您所看到的,我们已经使用编程方式创建了一个购物车项目WC_Cart add_to_cart()方法。因此,所有自定义数据都将保存到购物车中自定义购物车商品数据.

现在,我们还放置了一个代码块functions.php在结帐页面上打印这些数据。

add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

function my_custom_checkout_field( $checkout ) {

    //var_dump($checkout);
    global $woocommerce;

    echo '<div id="my_custom_checkout_field"><h2>' . __('Child Info') . '</h2>';

    foreach ( $woocommerce->cart->get_cart() as $cart_item ) {
        if( isset($cart_item['custom_data']) ) {

            $custom_data = $cart_item['custom_data'];

            echo("<div>Name: <strong>" . $custom_data['name'] . "</strong></div>");
            echo("<div>Email: <strong>" . $custom_data['email'] . "</strong></div>");
            echo("<div>Gender: <strong>" . $custom_data['sex'] . "</strong></div>");
            echo("<div>Age: <strong>" . $custom_data['age'] . "</strong></div>");

        }

    }

    echo '</div>';

}

现在,我尝试将结帐页面上打印的这些数据也添加到订单页面。由于没有这些数据我的订单无法完成,因此用户需要填写这些数据,并且当他创建订单时,这些数据也需要传递到订单摘要页面。管理员还需要能够看到这些数据,以便他可以处理订单。

我希望这个描述能够澄清一切,并再次感谢@LoicTheAztec 让我能够做到这一点。非常感谢。


Update 2- 两步

1)保存数据:

我们会保存此自定义客户数据作为“隐藏”订单"item"元数据,然后也作为订单元数据,因为这与具有唯一订单项的订阅相关:

// Utility function: array of custom customer key/label pairs
function custom_data_keys_labels(){
    return array(
        'name'  => __('Customer name'),     'email' => __('Customer email'),
        'sex'   => __('Customer gender'),   'age'   => __('Customer age'),
    );
}

// Add/save custom field value as custom HIDDEN order item meta data
add_action( 'woocommerce_checkout_create_order_line_item', 'custom_field_update_order_item_meta', 20, 4 );
function custom_field_update_order_item_meta( $item, $cart_item_key, $values, $order ) {
    if ( ! isset( $values['custom_data'] ) )
        return;

    $custom_data = $values['custom_data'];
    $meta_data   = array();
    $labels_keys = custom_data_keys_labels();

    foreach( $labels_keys as $key => $label ){
        if ( isset( $custom_data[$key] ) )
            $meta_data[$key] = $custom_data[$key];
    }

    if ( sizeof( $meta_data ) > 0 )
        $item->update_meta_data( __('_customer_data'), $meta_data );

    return $cart_item_data;
}

// Add/save custom fields values as custom order meta data
add_action( 'woocommerce_checkout_create_order', 'my_custom_checkout_field_update_order_meta', 20, 2 );
function my_custom_checkout_field_update_order_meta( $order, $data ) {

    $order_items = $order->get_items(); // Order itesm
    $item        = reset($order_items); // Keep only the first order item

    $item_data   = $item->get_meta( '_customer_data' ); // Get custom customer data

    if( is_array($item_data) && sizeof($item_data) > 0 ){
        foreach( $item_data as $key => $value ) {
            if ( isset( $item_data[$key] ) )
                $order->update_meta_data( '_customer_' . $key, $value );
        }
        // Mark as data saved
        $order->update_meta_data( '_customer_data_set', true );
    }
}

代码位于活动子主题(或活动主题)的 function.php 文件中。经过测试并有效。


2)显示保存的自定义数据:

下面的代码也使用了我们的实用函数custom_data_keys_labels()

// Order pages (frontend and admin) display
add_filter( 'woocommerce_order_details_after_order_table' , 'display_admin_order_meta_cutom_data', 20, 1 ); // Front
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_admin_order_meta_cutom_data', 20, 1 ); // Admin
function display_admin_order_meta_cutom_data( $order ){
    $labels_keys = custom_data_keys_labels();
    if( $order->get_meta( '_customer_data_set' ) ){
        if( is_admin() ){ // Admin
            echo '<p>';
            foreach( $labels_keys as $key => $label ){
                if ( $order->get_meta( '_customer_' . $key ) )
                    echo '<strong>' . $label . ':</strong> ' . $order->get_meta( '_customer_' . $key ) . '<br>';
            }
            echo '</p>';
        }
        else { // Front end: order view and Order received (thankyou)
            echo '<table class="woocommerce-table"><tbody>';
            foreach( $labels_keys as $key => $label ){
                if ( $order->get_meta( '_customer_' . $key ) )
                    echo '<tr><th>' . $label . ':</th><td>' . $order->get_meta( '_customer_' . $key ) . '</td></tr>';
            }
            echo '</tbody></table>';
        }
    }
}

// Email notifications display
add_filter( 'woocommerce_email_order_meta_fields' , 'display_email_cutom_data', 20, 3 );
function display_email_cutom_data ( $fields, $sent_to_admin, $order ) {
    $labels_keys = custom_data_keys_labels();
    if( $order->get_meta( '_customer_data_set' ) ){
        foreach( $labels_keys as $key => $label ){
            $fields['customer_' . $key] = array(
                'label' => $label,
                'value' => $order->get_meta( '_customer_' . $key ),
            );
        }
    }
    return $fields;
}

代码位于活动子主题(或活动主题)的 function.php 文件中。经过测试并有效。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将自定义数据从购物车项目传递到 Woocommerce 3 中的订单元 的相关文章

随机推荐

  • 在Lua中生成均匀随机数

    我正在用 Lua 编写马尔可夫链 其中一个要素要求我统一生成随机数 这是一个简化的例子来说明我的问题 example function x local r math random 1 10 print r return x r end ex
  • Servlet - 关闭连接但不关闭方法

    我必须实现将发送的服务 servlet 2 5 或 3 204在每个连接上编写代码但不关闭线程 我需要对收到的数据做一些事情 比如打开新连接 可以关闭连接但不能结束方法吗 或者在连接关闭时启动另一个方法 规范中尚不清楚 但它似乎可以在 To
  • 如何在服务器端获取客户端屏幕分辨率宽度/高度

    我可以使用客户端脚本 javascript 获取客户端屏幕分辨率 但我不想那样做 我也尝试过Request Browser ScreenPixelsWidth 但它总是返回固定宽度680 任何想法 客户端屏幕分辨率等信息是never在 HT
  • RDPSession ConnectToClient 意外终止

    我已经成功创建了一个桌面共享解决方案 其中 RDPViewer 连接到 RDPSession 这一切都很顺利 然而 现在我正在尝试相反的方法 使用 RDPViewer 的 StartReverseConnectListener 方法和 RD
  • 复制具有 unicode 名称的文件

    这应该是一个简单的脚本 import shutil files os listdir C for efile in files shutil copy efile D 它工作得很好 直到我在电脑上尝试使用 unicode 字符命名的文件 p
  • 具有地理位置策略的 AWS Cloudfront 与 Route53

    我们可以将CloudFront与Geolocation策略一起使用吗 或者CloudFront内部是否具有此功能并且可以单独使用来满足 或者 Route53 是一个正确的选择 同时需要为全球网站提供来自最近地理位置的请求以改善客户体验 另外
  • 为什么PHP不能创建777权限的目录?

    我正在尝试使用 PHP 和以下命令在我的服务器上创建一个目录 mkdir test 0777 但它并没有给出完整的权限 只有这些 rwxr xr x 该模式根据您当前的情况进行修改umask 即022在这种情况下 方式umask作品是一种减
  • Laravel 8:未定义方法“createToken”intelephense(1013)

    我对 PHP intelephense 方法有疑问创建令牌未定义 我不知道如何解决它 但是当我在邮递员中运行它时它就起作用了 我不知道为什么 vscode 不识别它 我还添加了使用 Laravel Passport HasApiTokens
  • HQL IN 运算符,枚举数组 ClassCastException

    这是我精简的类和枚举 class A Enumerated value EnumType STRING AType type enum AType X Y 如果我跑 query FROM A a WHERE a type type quer
  • Karate WebSocket 如何在一个会话中监听多个消息?

    对于我们的集成测试 我们有一个场景 我们想要监听由我们使用的环境预定义的一定数量的消息 我已经看到可以通过打开新连接来收听多个消息 但这并没有太大的灵活性 您是否阅读过文档 因为据我所知 如果您定义了 处理程序 函数 则可以对多个消息使用相
  • 在 R 中结合 grid_arrange_shared_legend() 和facet_wrap_labeller()

    我正在尝试结合grid arrange shared legend and facet wrap labeller 更具体地说 我想绘制一个包含两个 ggplot 图形的图形 每个图形都有多个面板 并且有一个共同的图例 我还想将部分刻面条标
  • 使用批处理文件并排合并 csv 文件[重复]

    这个问题在这里已经有答案了 我有一个非常基本的批处理命令来将 csv 文件合并在一起 但是我需要将它们合并 以便各列并排而不是继续 每个文件上的记录数量始终相同 这是我到目前为止的基本代码 COPY File1 csv File2 csv
  • 尝试使用 XML 配置关闭一个 URL 的安全性

    我检查了几个博客 doc stackoverflow 论坛条目 但我仍然不知道我做错了什么 我想向任何人授予对 URL 的访问权限 这permitAll不起作用 因为我有自定义过滤器 所以我想创建一个单独的http元素并使用security
  • 基于 boost::asio 的慢速 http 客户端 - (分块传输)

    我正在使用以下代码 取自 boost 教程 从服务器获取 json 字符串 问题是它需要一些时间来执行 即超过 2 秒才能完成 并且客户端和服务器都在本地主机上 如果我删除程序的最后两行 即此时 while boost asio read
  • 有没有办法让 GCC/Clang 知道 C 中的继承?

    我正在编写一个 C 库 它使用一些简单的面向对象继承 如下所示 struct Base int x struct Derived struct Base base int y 现在我想将 Derived 传递给一个采用 Base 的函数 如
  • 有没有像这个网站一样进行 AES 加密的示例 Java 代码?

    http www hanewin net encrypt aes aes test htm 如果您访问该网站并输入以下内容 Key In Hex 00000000000000000000000000123456 Plain Text in
  • 具有列重新排序功能的 JQGrid

    我有一个 jqgrid 我可以使用 JQGrid 中的此选项重新排序我的列 jQuery list jqGrid sortable true 此功能让我可以重新排序所有列 但我希望某些列必须位于固定位置 有办法解决这个问题吗 提前致谢 Br
  • Laravel Eloquent 在当前月份和前 3 个月之间进行选择

    我正在尝试构建一个查询 该查询将选择数据库中现在 当月 和前 3 个月之间的所有记录 我的查询有些有效 但我想忽略该月的某一天 目前 它也选择当前日期的最后几个月 但我想忽略当前日期并使用月份的开始和结束 这是我的查询 dateS Carb
  • 通过命令行传递 karate.env 无法按预期工作[重复]

    这个问题在这里已经有答案了 我下载了空手道演示项目并做了一些小更改 在空手道配置 js 函数的第一行 karate log Environment from command line karate env 然后我从终端执行 mvn test
  • 将自定义数据从购物车项目传递到 Woocommerce 3 中的订单元

    我已经实现了一个自定义 HTML 表单 并要求提供一些数据 我的客户将传递这些数据以成功下订单 如果没有这些细节 我的订单就没有任何意义 对于 HTML 表单 我引用了下面的一些自定义 PHP 脚本 该脚本处理来自表单的 POST 数据并以