在 WooCommerce 3.3 中使用 Google Map API 计算结帐距离

2024-05-09

我已经发布几个月前有类似的问题 https://stackoverflow.com/questions/46348735/calculated-distance-shipping-cart-fee-via-google-api-in-woocommerce我得到了帮助来解决这个问题。在 Woocommerce 版本 3.1.2 之前它一直运行良好。我一直在更新到 WooCommerce 的最新版本,希望问题能够得到解决。

我根据客户之间的差异添加动态费用billing_area(定制下拉菜单)结账时和卖家的价值billing_city(在用户配置文件中设置)。我使用的代码如下 -

这是运行以获取更改后的 billing_area 值的 jQuery 脚本:

add_action( 'woocommerce_after_checkout_form', 'custom_checkout_jquery_script', 10 );
function custom_checkout_jquery_script() {
    ?>
    <script type="text/javascript">
        (function($){
            $( 'form.checkout' ).on( 'change', '#billing_area', function(){
                var location = $('#billing_area option:selected').val();
                document.cookie="cusarea="+location;

                // Browser console output (Just for testing)
                function readCookie(n){ for(var r=n+"=",t=document.cookie.split(";"),e=0;e<t.length;e++){
                    for(var i=t[e];" "==i.charAt(0);)i=i.substring(1,i.length);
                    if(0==i.indexOf(r))return i.substring(r.length,i.length)}return null}
                $('body').trigger('update_checkout');
                console.log('Selected Area: '+location+' | Cookie: '+readCookie("cusarea"));

                //$('#order_review').load(document.URL +  ' #order_review');
                //window.location.reload(true)
            });
        })(jQuery);
        </script>
    <?php
}

这是计算费用的代码:

add_action( 'woocommerce_cart_calculate_fees', 'distance_shipping_fee', 30, 1 );
function distance_shipping_fee( $wc_cart ){

    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

    if( empty($_COOKIE ['cusarea']) ) return;
    else $cookie = $_COOKIE ['cusarea'];

    // Encoding the customer's location for Google API
    $customer_area = rawurlencode( $cookie );

    // Getting billing city of vendors
    foreach( $wc_cart->get_cart() as $cart_item ){
        $vendor_id = get_post_field( 'post_author', $cart_item['product_id'] );
        $vendors[$vendor_id] = get_user_meta($vendor_id, 'billing_city', true);
    }

    foreach( $vendors as $vend_loc){

        // Setting Google API URL ##
        $gapi_key = MY_APY; // Set HERE your google api key
        $shippingurl = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=$vend_loc";
        $shippingurl .= "+dhaka+bangladesh&destinations=$customer_area+dhaka+bangladesh&key=$gapi_key";

        // Now fetching json response from googleapis:
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $shippingurl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $response = json_decode(curl_exec($ch), true);

        // If google responds with a status of OK: Extract the distance text:
        if($response['status'] == "OK")
            $dist = $response['rows'][0]['elements'][0]['distance']['text'];

        $dist_array[] = preg_replace("/[^0-9\.]/", '', $dist);
    }


    // Get the bigger distance
    $dist_ance = max($dist_array);
    $dist_abs = abs ($dist_ance);

    if ( $dist_abs < 5) {        
        $wc_cart->add_fee( "Delivery - Distance Rate", 10 , true);
        } else {
        $wc_cart->add_fee( "Delivery - Distance Rate", 20 , true);
     }
}

问题是 - 它不再起作用了。

如果我转储该值,它会返回我的值$dist_abs(类似于 5.4,即卖家位置和客户区域之间的距离)。但是,不会向购物车添加任何费用。

有时,当服务器或网站速度缓慢时,我会看到标签(送货 - 距离率)出现在订单审核中,但一旦页面正确加载,它就会消失。

谁能告诉我为什么它不再工作了?我有什么遗漏的吗?


我已经找到了使用 ajax 而不是 cookie 使其工作的方法......所以尝试以下操作:

add_action( 'woocommerce_after_checkout_form', 'custom_checkout_jquery_script', 30 );
function custom_checkout_jquery_script() {
    if( ! is_checkout() ) return;
    ?>
    <script type="text/javascript">
    jQuery(function($){
        // wc_checkout_params is required to continue
        if ( typeof wc_checkout_params === 'undefined' )
            return false;

        var a = '#billing_myfield5', b = a+' option:selected';
        $( 'form.checkout' ).on( 'change', a, function(){
            console.log('Chosen area: '+$(b).html()); // To be removed (testing)

            // Ajax: send the chosen customer location to php
            $.ajax({
                type: 'POST',
                url:.ajax_url,
                data: {
                    'action': 'set_customer_area',
                    'customer_area': $(b).html(),
                },
                success: function (response) {
                    $(document.body).trigger('update_checkout');
                    console.log('Response: '+response); // To be removed (testing)
                }
            });
        });
    });
    </script>
    <?php
}

// Wordpress Ajax: Saved the selected customer location to WC_Session
add_action( 'wp_ajax_nopriv_set_customer_area', 'set_customer_area_in_wc_sessions' );
add_action( 'wp_ajax_set_customer_area', 'set_customer_area_in_wc_sessions' );
function set_customer_area_in_wc_sessions() {
    if( ! isset($_POST['customer_area']) ) return;

    // Encoding the customer's location for Google API
    $customer_area_enc = rawurlencode( $_POST['customer_area'] );

    // Set the chosen customer location in WC_Sessions
    WC()->session->set('customer_area', rawurlencode($_POST['customer_area']) );

    // To be removed (testing: Send back the data to jQuery)
    echo json_encode( WC()->session->get('customer_area' ) );

    die(); // To avoid server error 500
}

// Add a fee based on the highest distance between customer and vendors
add_action( 'woocommerce_cart_calculate_fees', 'distance_shipping_fee', 30, 1 );
function distance_shipping_fee( $cart ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // Get Url encoded customer area that is saved in WC_Session by ajax
    $customer_area = WC()->session->get('customer_area' );

    // Only when customer area has been selected
    if( empty($customer_area) )
        return;

    // Getting billing city of vendors
    foreach( $cart->get_cart() as $cart_item ){
        $vendor_id = get_post_field( 'post_author', $cart_item['product_id'] );
        $vendors[$vendor_id] = get_user_meta($vendor_id, 'billing_city', true);
    }
    $dist_array = array();

    // Loop through vendors locations
    foreach( $vendors as $vend_loc){

        // Setting Google API URL ##
        $gapi_key = MY_APY; // Set HERE your google api key
        $shippingurl = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=$vend_loc";
        $shippingurl .= "+dhaka+bangladesh&destinations=$customer_area+dhaka+bangladesh&key=$gapi_key";

        // Now fetching json response from googleapis:
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $shippingurl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $response = json_decode(curl_exec($ch), true);

        // If google responds with a status of OK: Extract the distance text:
        if($response['status'] == "OK")
            $dist = $response['rows'][0]['elements'][0]['distance']['text'];

        $dist_array[] = preg_replace("/[^0-9\.]/", '', $dist);
    }

    // Get the bigger distance
    $distance = max ($dist_array);
    $distance = abs ($distance);

    $fee = $distance < 5 ? 10 : 20;

    if ( $distance && $fee > 0 )
        $cart->add_fee( "Delivery - Distance Rate", $fee , true);
}

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

工作后,您必须删除所有相关行// Testing ==> To be removed

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

在 WooCommerce 3.3 中使用 Google Map API 计算结帐距离 的相关文章

  • 在 HTML5 中创建可拖动和可缩放的网格

    与其他 HTML5 不同如何创建网格问题 我想知道如何制作一个可拖动且可扩展的 绘制网格非常简单 var c document getElementById canvas var ctx c getContext 2d var width
  • PHP - 类外 use 关键字和类内 use 关键字的区别

    伙计们 美好的一天 只是想问一下有什么区别use之外的class and use在 的里面class 我也用谷歌搜索过 但我的问题与答案不匹配 Example namespace App Http Controllers Auth use
  • 仅当表单已提交时才触发 jQuery 表单验证?

    不引人注目的验证基于这样的想法 don t进行表单验证 直到用户提交表单 一旦发生这种情况 如果表单上的某些内容无效 那么一旦用户更改了每个字段 就会立即验证它 我想做的是 不显眼地 触发表单元素的验证 也就是说 only如果用户已尝试提交
  • 如何在HTML中的PHP中注释掉HTML和PHP?

    这是我想注释掉的一行代码 h1 class post title a href title a h1 一种流行的注释方法是分别注释 html 和 php 有一个更好的方法吗
  • mouseover 函数在队列中多次出现

    我有这段代码 可以在鼠标悬停时使一个 div 淡出另一个 div 并在光标离开查看区域时淡出 例子 http jsfiddle net 3vgbemgu http jsfiddle net 3vgbemgu under hover func
  • 动态速度计 javascript 或 jquery 插件

    我希望有动态ajax插件在页面上显示速度计 一个想法是我设置一个背景并旋转针 有人知道相关插件吗 这里有一些供您参考 http bernii github com gauge js http bernii github com gauge
  • 如何纠正这个非法字符串偏移?

    我收到此错误 警告 第 32 行 home mysite public html wp content themes evento lib php extra class php 中的非法字符串偏移 type 我意识到文件中的这部分代码是错
  • jQuery,REAL:不是等价的运算符?

    此代码行选择任何类名不是 id 和 quantity 的 div 内的所有子输入 div item gt div not id quantity gt input live keydown function event 执行相反操作的代码行
  • 如何处理 ASP.net MVC Ajax 加载页面上的 jQuery 事件?

    我有一个问题 我是 jQuery Mobile 领域的新手 对于 ASP Net MVC 部分我有点迷失 这是我的问题 在我的移动网站中 我想更改导航栏 我使用的更像是应用程序栏 按钮 而我位于编辑页面或主页等 因此 这些页面 编辑 显示
  • 如何在 Zend MVC 中实现 SSL

    我之前已经通过使用特定的安全文件夹 例如服务器上的 https 文件夹与 http 文件夹 实现了安全页面 我已经开始使用 Zend Framework 并希望应用程序的某些部分 例如登录 使用 https 我在谷歌上搜索过 甚至在这里搜索
  • 使用具有现有访问令牌的 Google API .NET 客户端

    用例如下 移动应用程序正在通过 Google 对用户进行身份验证 并且在某些时候 我们需要将用户的视频发布到他的 YouTube 帐户 出于实际原因 实际发布应该由后端完成 已经存储在那里的大文件 由于用户已经通过应用程序的身份验证 因此应
  • Jquery 中的动态滚动位置

    请帮助我解决以下情况 我有 3 个页面 当滚动到达第二页时 用户滚动页面 它必须找到特定的 ID 然后触发一个函数 一旦第三页开始 另一个函数就会触发 根据要求我不应该使用任何插件
  • 未捕获的错误:找不到模块“jquery”

    我在用Electron https github com atom electron制作桌面应用程序 在我的应用程序中 我正在加载一个外部站点 Atom 应用程序之外 可以说http mydummysite index html http
  • 如何删除文件

    我们有一个脚本 scripts ourscript php和一个文件 media movie1 flv 当我们运行时 我们如何删除这个文件ourscript php Using unlink http php net manual en f
  • 如何将送货地址复制到帐单地址

    我想知道是否可以将送货地址复制到帐单地址 当用户单击与送货地址相同的复选框时 送货地址值将被复制到账单输入字段 我完成了大部分部分 但我不确定如何将选择菜单 状态 值复制到帐单地址 我真的很感谢任何帮助 My code document r
  • 我可以在 PHP 会话变量中安全地存储用户名和密码吗?

    我想在 REST api 之上制作一个轻量级的 web 应用程序 用户只需进行一次身份验证 从那时起 所有针对 web api 的请求都希望通过以某种方式保持用户名和密码有效来完成 我已经做了一个工作原型我在哪里将用户名和密码存储在会话变量
  • 如何从 Laravel 执行存储过程

    我需要在表单提交数据后执行存储过程 我让存储过程按照我想要的方式工作 并且我的表单正常工作 我只是不知道从 laravel 5 执行 sp 的语句 它应该是这样的 执行 my stored procedure 但我似乎在网上找不到类似的东西
  • 如何在jquery中获取保存时间和当前时间的差异?

    我想在 javascript 或 jquery 中获取保存时间和当前时间之间的时差 我节省的时间看起来像Sun Oct 24 15 55 56 GMT 05 30 2010 java中的日期格式代码如下 String newDate 201
  • phpActiveRecord 日期时间格式不正确

    当尝试使用 phpActiveRecord 在表中创建记录时 出现以下错误 Invalid datetime format 1292 Incorrect datetime value 2013 06 20 11 59 08 PDT for
  • 如何使用 php 将 *.xlsb 转换为数组或 *.csv

    我正在尝试转换 xlsb文件到php array or csv文件 或至少 xls 我尝试使用PHPExcel 但看起来它无法识别该文件中的内容 我注意到 你可以重命名 xlsb文件到 zip文件 然后使用命令行解压缩unzip zip 之

随机推荐

  • 如何使用 jira-python 设置 fixVersions 字段

    我正在尝试使用 jira python 模块 http jira python readthedocs org en latest 更新现有的 JIRA 具体来说 我正在尝试设置问题的fixesVersion 列表 我已经尝试了一段时间但没
  • 序列化和反序列化 Visual Studio 解决方案文件 - 或以编程方式编辑?

    我想以编程方式添加和删除项目 解决方案文件夹和其他项目 例如解决方案的资源文件 但我不确定最好的方法是什么 对于那些不知道的人 高度简化 解决方案文件 sln 通常如下所示 Microsoft Visual Studio Solution
  • 使用 google.protobuf.Timestamp 在 Go 中解析带有时区偏移的日期时间戳

    我正在创建一个将使用 GRPC 和 protobuf 的 Go 应用程序 我的 RPC 服务应获取包含类型的消息google protobuf Timestamp 解析它并最终将其保存在数据库中或对其执行更多操作 我对什么被认为是该类型的有
  • Coredata错误setObjectForKey:对象不能为nil

    我正在尝试检查我的核心数据存储中是否有任何数据作为我的应用程序的恢复类型 基本上 如果用户处于最终视图 则 coredata 中会有一些数据不断更新 因此 他们处于最终视图中 然后应用程序崩溃 或者他们将其置于睡眠状态 然后应用程序从内存中
  • 如何使用flyway将数据从一个DB迁移到另一个DB?

    我在不同的服务器上有两个 postgreSql DB 比如说 A 和 B 我可以使用 Flyway 一些如何将所有数据从 DB A 复制到新设置且为空的 B 如果有人指出我正确的方向和工具 这将很有帮助 要求是通过某种工具自动化将数据从一个
  • 如何在动作脚本 3 中设置/访问外部 swf 文件的动态文本字段?

    我正在处理一个 fla 文件 其中添加了一个 swf 文件 我如何在该 swf 文件的动态文本上设置文本 有没有直接设置文本的方法 我不想在 url 中作为参数传递 我试过这样 var rq URLRequest new URLReques
  • 部署在 Azure 中时在 EF 迁移中使用更新数据库

    上下文 我在 Azure 中部署了 ASP NET MVC4 解决方案 我的 MSSQL Server 数据库也在 Azure 中 我目前的部署方式是这样的 在 web config 中 我将连接字符串从本地数据库 sdf 更改为 azur
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • 任何人都知道 JQuery 插件可以生成类似于 geni.com 上的树形菜单

    大家好 我花了几个小时寻找一个 Jquery 插件来生成像 geni com 上那样的树形菜单模块 如果有人知道 Jquery 中的这样的插件或脚本 请让我知道或指导我如何使用 Jquery 开发这样的功能 请检查我正在寻找什么http w
  • 如何返回每个另一个节点属性的最大计数

    我需要计算一位作曲家的音乐作品每十年被演奏了多少次 然后只返回每十年演奏次数最多的一首作品 除了过滤除每十年最高计数之外的所有内容之外 该密码可以执行所有操作 match c Composer CREATED BY w Work lt 2
  • 我可以在导航组件中使用多个 NavHostFragment 吗?

    如果您难以理解以下段落 请查看我制作的流程图 我目前正在制作一个带有 3 个顶级目的地的笔记应用程序 顶级目标之一 NotesList 显示用户创建的注释列表 NotesList 有一个过滤器按钮 可显示带有 FilterMenu 目标的底
  • Google Cloud Kubernetes 上任务队列的替代方案

    我发现任务队列主要用于App Engine标准环境 我正在将现有服务从 App Engine 迁移到 Kubernetes 任务队列的一个好的替代方案是什么 推送队列是当前正在使用的队列 我在线阅读文档并浏览了此链接 何时使用 PubSub
  • serde/bincode 如何序列化字节数组?

    这段代码完全按照我的要求序列化了一个 32 字节的数组 derive Debug Clone Serialize Deserialize PartialEq Eq PartialOrd Ord struct Hash u8 32 let h
  • 如何使 WordPress 中的自定义模板充当受密码保护的页面?

    我正在使用自定义模板构建一个页面 问题是 我需要此页面受密码保护 或者至少可供登录用户访问 但即使我在 WordPress 管理的新页面部分中将其设置为此类 私人 密码保护 它也不会显示菜单项和内容 如果是私有的 或者它会立即显示页面内容
  • 如何在jquery中创建一个全局函数,并从另一个加载的页面调用它

    如何在 jquery 中声明全局函数 如何从使用 jquery 的 load 函数加载到该页面上的某个 div 中的页面调用它 该功能很简单第 1 个子页面 main links 1st sub page myfun function is
  • 合并字符数组中的最小重复次数

    假设我有两个数组 我想合并它们 以便合并后的数组具有最小重复次数 例如 x x 是重复 arr1 x d d m f m arr2 d d x f f m 唯一的条件是在合并数组中 元素来自arr1 and arr2必须出现在各自的订单中a
  • 将 stdout 作为命令行 util 的文件名传递?

    我正在使用一个命令行实用程序 该实用程序需要传递文件名以将输出写入 例如 foo o output txt 它唯一写入的东西stdout是一条消息 表明它运行成功 我希望能够通过管道传输写入的所有内容output txt到另一个命令行实用程
  • 为什么 Excel 有时会在工作表名称中添加 $?

    我有时但并非总是发现 Excel 会放置一个 位于工作表名称末尾 但在 Excel 中看不到 只有在尝试使用 C 将其导入 SQL Server 时才可见 我遇到过很多不同的情况 它保留了原始工作表 但也创建了第二个空的 隐藏 工作表 其中
  • Laravel 雄辩的 withCount() 应该比 with() 慢

    所以我问这个的原因是在我当前的应用程序中withCount 与仅通过以下方式获取关系的所有数据相比 响应时间几乎增加了三倍with 并只是从前端获取长度 javascript 我认为使用的要点withCount 是为了加快查询速度 但也许我
  • 在 WooCommerce 3.3 中使用 Google Map API 计算结帐距离

    我已经发布几个月前有类似的问题 https stackoverflow com questions 46348735 calculated distance shipping cart fee via google api in wooco