【问题标题】:Get fields from checkout form into calculate_shipping从结帐表单中获取字段到 calculate_shipping
【发布时间】:2019-03-30 18:22:43
【问题描述】:

我正在为我的 WooCommerce 商店创建一个自定义运费计算器。我需要从用户那里收集一些额外的表单数据来正确计算运费。

我已将表单字段添加到 woocommerce_checkout_after_customer_details。一旦我弄清楚结帐页面的功能,我可能可以毫不费力地将它放入购物车页面,所以让我们专注于此。

我有一个扩展 WC_Shipping_Method 的类,使用 calculate_shipping 方法,例如 this tutorial

在该方法中,我想使用额外的表单数据(加上目的地)来计算该客户的运费。现在我只是添加了一个虚拟汇率,它会显示出来。

我还创建了一个自定义cart-shipping.php 文件,以不显示订单审查购物车中可用方法的任何输入,仅显示标签和成本。由于采摘是在我的自定义表单中进行的,因此无需在此处设置选项。

  1. 我这样做是对的,还是这种方法超级 hacky?
  2. 如果这是正确的方法,我如何访问 calculate_shipping 方法中的额外表单字段?

试过了

在我的自定义表单中命名了最终选项shipping_method_*,它触发了wc-ajax=update_order_review 调用...它初始化了我的自定义运输方法类,但无论如何似乎都没有调用calculate_shipping 方法。似乎唯一一次调用此方法是当我实际将产品添加到订单中时。

也试过了

定义了我所有可能的交付选项,并将它们添加到 calculate_shipping 中,例如 $this->add_rate( $rate );。我想当购物车通过update_order_review ajax 调用更新时,我可以以某种方式选择一个(强制用户进入一个)?同样,设置选项应由用户在结帐表单上与之交互的这些字段确定。但是我还没有弄清楚如何设置该操作的运输。

【问题讨论】:

  • 如果您只想从calculate_shipping() 方法中获取提交的值,那么您可以使用$_POST['field_name'] 访问它。但是,我想你已经知道了?.. 你知道 WooCommerce 在 WooCommerce 会话中保存 计算的 运费,并且仅在例如送货地址为时调用 calculate_shipping() 方法变了吗?
  • @SallyCJ Sorta 现在知道了,我对此有一个单独的问题......我试图在这里弄清楚很多事情。我现在正在获取woocommerce_checkout_update_order_review 中的帖子值并将其存储在会话中,然后稍后再获取。我想我可以直接在calculate_shipping 方法中获取 POST 数据,我想不出我一开始不这样做的原因。如果您想将其作为答案,我会接受。
  • 我已经发布了答案。我希望你能很快看到它.. :p 但老实说,我希望它也能帮助其他人。 :)

标签: php woocommerce hook-woocommerce


【解决方案1】:

calculate_shipping()并不总是被调用

首先,您应该知道,您的运输方法类的 calculate_shipping() 方法只会在首次计算运费时(在当前 WooCommerce 会话中)被调用,每次将产品添加到购物车,以及无论何时更改送货地址 - 从购物车或结帐页面。

当然,插件或自定义代码可以以编程方式随时调用该方法(或重新计算费率)。但是,默认行为如下:

费率根据包哈希存储在会话中以避免 重新计算每个页面加载

calculate_shipping() 方法由WC_Shipping 类通过其calculate_shipping_for_package() 方法执行。事实上,上面的引用来自WC_Shipping::calculate_shipping_for_package() 的描述,它调用了WC_Shipping_Method::get_rates_for_package(),最终调用了你自己类中的calculate_shipping() 方法。

如何通过calculate_shipping()方法获取结账表单中某个表单字段的提交值

因此,如果您在结帐表单中有此内容:

<input type="text" name="my_field"...>

然后您可以使用$_POST superglobal 或WC_Checkout::get_value() 方法获取提交的(POSTed)值:

  1. $_POST['my_field']

  2. WC()-&gt;checkout-&gt;get_value( 'my_field' )

就这么简单。 :)


确保调用calculate_shipping

运行类似下面的东西来清除会话信息,这表明仍然需要进行计算。请注意,如果您在每一页上都这样做,则意味着运费会在不需要时不断重新计算。

$packages = WC()->cart->get_shipping_packages();
foreach( $packages as $package_key => $package ) {
    $session_key  = 'shipping_for_package_'.$package_key;
    $stored_rates = WC()->session->__unset( $session_key );
}

【讨论】:

  • 感谢您的编辑,@RandyHall。并对(有用的)问题+1。 :)
【解决方案2】:

我不确定这是否是实现此目的的最佳方式,但目前我正在通过在 woocommerce_checkout_update_order_review 上设置会话值然后在我的 calculate_shipping 方法中访问该值来完成这项工作。

【讨论】:

    【解决方案3】:

    查看 WooCommerce 文档,似乎他们希望您从 calculate_shipping 函数访问诸如用户位置之类的东西的方法是使用他们的设置 API。 https://docs.woocommerce.com/document/settings-api/。阅读文档以了解具体方法,但这里有一个简化:


    使用读取位置
    $this->init_settings();
    $this->location = $this->settings['location'];

    使用此表写入/设置用户的位置:

    <?php function admin_options() {
         ?>
        <h2><?php _e('You plugin name','woocommerce'); ?></h2>
         <table class="form-table">
         <?php $this->generate_settings_html(); ?>
         </table><?php
         }

    这张桌子是用

    制作的
    function init_form_fields() {
         $this->form_fields = array(
         'location' => array(
              'title' => __( 'Location', 'woocommerce' ),
              'type' => 'text',
              'description' => __( 'This is the users address.', 'woocommerce' ),
              'default' => __( 'none', 'woocommerce' )
              )
         );
    }
    

    【讨论】:

    • 我……不知道这有什么关系。这是为管理员选项创建字段...我正在尝试在结帐时获取额外信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-07
    • 2018-11-11
    • 2023-03-27
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多