如何更新购物车项目meta - woocommerce

Sar*_*ark 4 wordpress woocommerce

我知道我们可以使用woocommerce_add_cart_item_datahook 为woocommerce cart项添加元数据.

有没有办法更新现有的购物车项目元.?

ben*_*kji 9

Yes, but it seems, only via accessing the cart directly:

global $woocommerce;
$woocommerce->cart->cart_contents[$cart_item_key]['whatever_meta'] = 'testing';
$woocommerce->cart->set_session();   // when in ajax calls, saves it.
Run Code Online (Sandbox Code Playgroud)

I would recommend to remove and re-add the product, as other meta data could be lost (as in Phong Tran's answer).

Based on @DanielSalcedos answer, only keeping the absolute minimum required to answer the question.

  • 你节省了我几个小时的时间。谢谢。这是这个问题的正确答案。 (2认同)

小智 6

我知道已经有一段时间了,但由于它仍然没有得到回答,而且它带走了我的大量汗水和一品脱的血液,我在这里分享我的解决方案.

第一

我假设您知道如何将元数据添加到购物车和订单中.如果没有,你可以看看pwnewbie的解决方案,但我建议你在Wisdm实验室完整的文章

Wisdm的方法需要很多步骤.首先,您通过Ajax创建PHP的会话变量.其次,您拦截woocommerce_add_cart_item_data过滤器以将您的Session变量添加到woocommerce会话.

关于woocommerce_add_cart_item_data过滤器的事情是它在add to cart过程的中间执行,所以,如果你将变量添加到主$wooocmmerce对象,在某些时候,它会被存储为add-to-cart事件.(有点)

这个想法

如果我想编辑元数据而不是任何标准购物车属性,该怎么办?理想的是获得一个过滤器或一个在保存某些东西的过程中运行的动作.问题是,只要我们不改变其他任何东西,就没有可以运行的钩子(我尝试使用woocommerce_update_cart_action_cart_updated钩子,在优惠券之后运行,推车的数量和清除已经发生,但它从未解雇,因为我从未通过验证)

我的方法

在shell中,尽可能少地重建,尽可能多.我在购物车表单OnSubmit事件中添加了一个同步ajax事件.(我希望我的UI能够根据我的更改进行更新,因此重新加载必须在我更新后进行)

AJAX:

var myFlag33322805 = true;
$('form').submit(function(e){
if(myFlag33322805){
    myFlag33322805 = false;
    e.preventDefault();     // Flag and prevent default to syncronize submits
    var kart = [];          // Will retrieve every cart item's meta

    $('.cartRow').each(function(){
    //This object will store your meta data and be pushed into kart array
    var kitm = {
        'p' : $(this).data('product_id'),
        'm' : $(this).find('select[name=myMetaData]').val(),
        'k' : $(this).data('key')
    };
    kart.push(kitm);
    });

    var data = {
    'action': 'Ajax_Update_My_MetaData_33322805',
    'k': kart
    };
    $.post(VKVAjax.ajaxurl, data, function (response) {
       // Might do something with the response here
    });
    $('form').submit();  // This time, the form will submit, but AJAX wont run because of myFlag33322805 = false
}
}); 
Run Code Online (Sandbox Code Playgroud)

魔法:

PHP的Ajax响应是接受我的元数据更新(实际上,这一切,更新与否),并会采取全局函数$woocommerce对象插入元数据将其保存到会话:

PHP:

function fn_Update_My_MetaData_33322805(){
global $woocommerce;
$cart = $woocommerce->cart->cart_contents;
$updt = Array();
foreach ($_POST['k'] AS $item){
    $product = new stdClass();
    $updtCL = new stdClass();
    $product->{'id'} = $item['p'];          //This is product id
    $product->{'mymeta'} = $item['m'];      //This is metadata
    $updtCL->{'krtkey'} = $item['k'];       //This is product key in cart
    $updtCL->{'meta'} = $product;
    $updt[] = $updtCL;
}

// cycle the cart replace the meta of the correspondant key
foreach ($cart as $key => $item) {
    foreach($updt as $updtitem){
        if($key == $updtitem->krtkey){      // if this kart item corresponds with the received, the meta data is updated
            // Update the content of the kart
            $woocommerce->cart->cart_contents[$key]['vkv_AlternCart_value'] = $updtitem->meta;
        }
    }
}

// This is the magic: With this function, the modified object gets saved.
$woocommerce->cart->set_session();

wp_die('{"e":"ok", "Updt": "'.count($arrupdt).'"}');
}
Run Code Online (Sandbox Code Playgroud)

当然,这应该像任何其他ajax事件一样被挂钩.

add_action('wp_ajax_nopriv_Ajax_Update_My_MetaData_33322805', 'fn_Ajax_Update_My_MetaData_33322805');
add_action('wp_ajax_Ajax_Update_My_MetaData_33322805',  'fn_Ajax_Update_My_MetaData_33322805');
Run Code Online (Sandbox Code Playgroud)

Conclussion

您可以使用同步Ajax调用更新购物车项目的元数据,将对象直接覆盖到$woocommerce全局变量并使用该$woocommerce->cart->set_session();方法保存.

脚注

这不是理想的方法,与$woocommerce全球直接合作风险很大.我很想知道更好的方法.


小智 1

步骤 1:在自定义会话中添加数据,在 \xe2\x80\x98Add to Cart\xe2\x80\x99 按钮上单击

\n\n

使用过 WooCommerce 的人可能知道,单击 \xe2\x80\x98Add to Cart\xe2\x80\x99 按钮时,产品页面会刷新,并且用户数据会丢失。因此,我们应该将产品页面中的自定义数据添加到使用 Ajax 创建的自定义会话中。此代码在创建 WooCommerce 会话之前调用。

\n\n
<?php\nadd_action('wp_ajax_wdm_add_user_custom_data_options', 'wdm_add_user_custom_data_options_callback');\nadd_action('wp_ajax_nopriv_wdm_add_user_custom_data_options', 'wdm_add_user_custom_data_options_callback');\n\nfunction wdm_add_user_custom_data_options_callback()\n{\n      //Custom data - Sent Via AJAX post method\n      $product_id = $_POST['id']; //This is product ID\n      $user_custom_data_values =  $_POST['user_data']; //This is User custom value sent via AJAX\n      session_start();\n      $_SESSION['wdm_user_custom_data'] = $user_custom_data_values;\n      die();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

步骤 2:在 WooCommerce 会话中添加自定义数据

\n\n

在此步骤中,WooCommerce 会话已创建,现在可供我们添加自定义数据。我们使用以下代码将自定义数据从我们创建的会话添加到 WooCommerce 会话中。在此步骤中,我们的会话也被取消设置,因为其中的数据已被捕获并且不再需要。

\n\n
add_filter('woocommerce_add_cart_item_data','wdm_add_item_data',1,2);\n\nif(!function_exists('wdm_add_item_data'))\n{\n    function wdm_add_item_data($cart_item_data,$product_id)\n    {\n        /*Here, We are adding item in WooCommerce session with, wdm_user_custom_data_value name*/\n        global $woocommerce;\n        session_start();    \n        if (isset($_SESSION['wdm_user_custom_data'])) {\n            $option = $_SESSION['wdm_user_custom_data'];       \n            $new_value = array('wdm_user_custom_data_value' => $option);\n        }\n        if(empty($option))\n            return $cart_item_data;\n        else\n        {    \n            if(empty($cart_item_data))\n                return $new_value;\n            else\n                return array_merge($cart_item_data,$new_value);\n        }\n        unset($_SESSION['wdm_user_custom_data']); \n        //Unset our custom session variable, as it is no longer needed.\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

步骤 3:从 WooCommerce 会话中提取自定义数据并将其插入购物车对象

\n\n

在此阶段,我们在 WooCommerce 会话中拥有默认产品详细信息以及自定义数据。由于插件提供的功能,默认数据被添加到购物车对象中。但是,我们需要从 WooCommerce 会话中显式提取自定义数据并将其插入购物车对象中。这可以通过以下代码来实现。

\n\n
add_filter('woocommerce_get_cart_item_from_session', 'wdm_get_cart_items_from_session', 1, 3 );\nif(!function_exists('wdm_get_cart_items_from_session'))\n{\n    function wdm_get_cart_items_from_session($item,$values,$key)\n    {\n        if (array_key_exists( 'wdm_user_custom_data_value', $values ) )\n        {\n        $item['wdm_user_custom_data_value'] = $values['wdm_user_custom_data_value'];\n        }       \n        return $item;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

第 4 步:在购物车和结帐页面上显示用户自定义数据

\n\n

现在我们在购物车对象中已经有了自定义数据,我们现在需要做的就是在购物车和结账页面中显示这些数据。这是将自定义数据从 WooCommerce 会话添加到您的购物车后您的购物车页面的外观。\nMy-Cart-Page

\n