根据产品类别自定义购物车总计和结帐总计文本

时间:2019-03-23 00:29:28

标签: php wordpress woocommerce

我想根据产品类别(或其他某种逻辑)自定义购物车和结帐订单摘要表中的文本。例如,对于“总计”文本(参见图片)-如果购物车中包含“杂货”类别的产品,那么我希望订单摘要中的文本显示为“总计估算”文本(参见图片)下面)。如果购物车中没有任何杂货,则需要默认文本。

我找到了一个使我入门的解决方案,但需要更多帮助。

为此,link,我将文件从woocommerce / templates /复制到我的子主题中,并将其命名为woocommerce /。例如,在review_order.php文件中,我需要编辑以下部分。

<th><?php _e( 'Total', 'woocommerce' ); ?></th>

但是,我不能只用硬编码的字符串替换它,因为我的文本取决于逻辑。因此,我需要将字符串替换为函数。

我想在下面做类似的事情:

<th><?php _e( get_my_custom_text(), 'woocommerce' ); ?></th>

,其中get_my_custom_text()根据某些逻辑(例如,购物车中的商品类别。

  1. 我将在哪里放置包含函数get_my_custom_text()的文件,以便review_order.php可以看到该函数?
  2. 这是实现我想要做的最好的方法吗?

enter image description here

更新: 在下面的讨论之后,我将添加我的get_custom_text()代码。我试图解决这两种方式:第一种是woocommerce files方式,第二种是下面的建议使用add_filter( 'gettext', 'my_text_strings', 20, 3 )钩子。在这两种情况下,检查购物车时get_my_custom_text()似乎都不起作用。请参阅以下使用hook方法的代码。我在get_cart_contents_count()上遇到了一个错误,并且白屏死了。

[23-Mar-2019 11:14:13 UTC] PHP Fatal error: Uncaught Error: Call to a member function get_cart_contents_count() on null in /opt/wordpress/htdocs/wp-content/themes/divi-child/functions.php:446

也得到了: [23-Mar-2019 11:16:05 UTC] PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 20480 bytes) in /opt/wordpress/htdocs/wp-includes/class-wp-hook.php on line 279

   add_filter( 'gettext', 'my_text_strings', 20, 3 );
    function my_text_strings( $translated_text, $text, $domain ) {

            switch ( $translated_text ) {
               case 'Total' :
                    $translated_text = __( get_my_custom_text(), 'woocommerce' );
                    break;
             }

                return $translated_text;
    }

        function get_my_custom_text()
        {
            $is_groceries = has_groceries();
            if($is_groceries){
                return 'Total Estimate';
            }else{
                return 'Total';
            }
        }

        //checks whether cart has any items in the "groceries" category
        function has_groceries()
        {

            if( !$cart = WC()->cart ){
                return false;
            }

          //not sure how error gets here if cart is null     
          write_log('cart contents: '. WC()->cart->get_cart_contents_count());

            $categories = array(  
                '181' => 'groceries' 
              );

            foreach( $cart->get_cart() as $cart_item ){
                foreach ($categories as $category => $value) {
                    if( has_term( $category, 'product_cat', $cart_item['product_id']) ){
                        return true;
                     }
                  }
            }
        return false;
        }

2 个答案:

答案 0 :(得分:1)

该方法很好,您可以将该功能添加到子主题中的functions.php中。

但是,以下方法可能更好,因为您根本不需要修改woocommerce!您仍然需要相同的功能,但是现在所有内容都可以驻留在functions.php中。这使用了Wordpress的gettext filter

add_filter( 'gettext', 'my_text_strings', 20, 3 );
function my_text_strings( $translated_text, $text, $domain ) {

    switch ( $translated_text ) {
        case 'Total' :
            $translated_text = __( get_my_custom_text(), 'woocommerce' );
            break;
    }

    return $translated_text;
}

答案 1 :(得分:1)

为什么您要获取日志,购物车中的物品计数(在您的功能中)。这不是真的有用。

我已经简化并重新审视了您的代码,并且在上一个函数中我没有使用get_my_custom_text(),因为使用has_groceries()更为简单和有效:

// Custom function based on has_groceries() conditional function that returns a string
function get_my_custom_text() {
    return has_groceries() ? 'Total Estimate' : 'Total';
}

// Custom conditional function checking for a specific product category in cart items
function has_groceries() {
    if( ! WC()->cart->is_empty() ){
        // Loop through cart items
        foreach( WC()->cart->get_cart() as $cart_item ){
            if( has_term( array('groceries'), 'product_cat', $cart_item['product_id']) )
                return true;
        }
    }
    return false;
}

// Change 'Total' text conditionally
add_filter( 'gettext', 'changing_total_text_string', 10, 3 );
function changing_total_text_string( $translated_text, $text, $domain ) {
    // Only in cart and checkout pages
    if ( ( ( is_checkout() && ! is_wc_endpoint_url() ) || is_cart() )
    && $text === 'Total' && $domain === 'woocommerce' && has_groceries() ) {
        $translated_text = __('Total Estimate');
    }
    return $translated_text;
}

代码在您的活动子主题(或活动主题)的function.php文件上。经过测试,可以正常工作。

  

这样可以避免“ Total”文本替换过程中出现无限循环。