【问题标题】:Woocommerce: Invalid argument supplied for foreach() in class-wc-product-variable.php fileWoocommerce:在 class-wc-product-variable.php 文件中为 foreach() 提供的参数无效
【发布时间】:2019-03-10 06:18:06
【问题描述】:

我正在创建一种为我的主题定制的可变产品,我设法出现在产品数据的下拉列表中,并且可以保存而不会引起冲突。问题是在前端看到产品会给我以下错误:

警告:为 foreach() 提供的参数无效 /Applications/MAMP/htdocs/canopy/wp-content/plugins/Woocommerce/includes/class-wc-product-variable.php 在第 83 行

我已将问题追溯到文件Wordpress/includes/data-stores/class-wc-product-variable-data-store-cpt.php,但事实是我不知道还能做什么。

我留下我为此编写的代码:

WC_Product_variable_canopytour.php

class WC_Product_Variable_CanopyTour extends WC_Product_Variable {
    public function __construct( $product ) {
        $this->product_type = 'variable_canopytour';
        parent::__construct( $product );
    }

    public function get_type() {
        return 'variable_canopytour';
    }
}

class-woocommerce-custom-product.php

class WCB_Woocommerce_CanopyTour_Product_Type {
    private $wcb;
    private $version;

    public function __construct( $wcb, $version ) {
        $this->wcb = $wcb;
        $this->version = $version;
    }

    public function register_canopytour_product_type() {
        remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );

        include_once(get_template_directory() . 'woocommerce/WC_Product_variable_canopytour.php');
    }

    public function add_canopytour_product( $types ) {
        $types[ 'variable_canopytour' ] = __( 'Variable Canopy Tour', $this->wcb );
        return $types;
    }

    public function get_tour_product_class($classname, $product_type) {
        if ( $product_type === "variable_canopytour" ) {
            $classname = 'WC_Product_Variable_CanopyTour';
        }
        return $classname;
    }

    public function wcb_admin_footer() {
        if ( 'product' != get_post_type() ) :
            return;
        endif;

        ?><script type='text/javascript'>
            jQuery( document ).ready( function() {
                jQuery( '.options_group.pricing' ).addClass( 'show_if_variable_canopytour show_if_simple show_if_external' ).show();
                jQuery( 'li.general_options.general_tab' ).addClass( 'show_if_variable_canopytour show_if_simple show_if_external' ).show();
                jQuery( '.variations_options.variations_tab' ).addClass( 'show_if_variable_canopytour' ).show();
                jQuery( '.enable_variation' ).addClass( 'show_if_variable_canopytour' ).show();
            });
        </script><?php
    }

    function hide_wcb_data_panel( $tabs) {
        // Other default values for 'attribute' are; general, inventory, shipping, linked_product, variations, advanced
        $tabs['shipping']['class'][] = 'hide_if_variable_canopytour';
        return $tabs;
    }
}

functions.php

include_once get_template_directory() . 'includes/woocommerce/class-woocommerce-custom-product.php';
$woo_ct = new WCB_Woocommerce_CanopyTour_Product_Type( "wcb", "1.0" );

add_action( 'init', array($woo_ct, 'register_canopytour_product_type') );
add_filter( 'product_type_selector', array($woo_ct, 'add_canopytour_product') );
add_filter( 'woocommerce_product_class', array($woo_ct, 'get_tour_product_class'), 10, 2 ); 
add_action( 'admin_head', array($woo_ct, 'wcb_admin_head') );
add_filter( 'woocommerce_product_data_tabs', array($woo_ct, 'hide_wcb_data_panel') );

我希望有人能帮助我理解发生了什么:(

谢谢!

【问题讨论】:

  • 您没有此自定义产品类型的价格?
  • 是的,我已经配置了它们,但同样的错误不断出现
  • 您是否覆盖了主题中的任何 WooCommerce 模板文件?您可以切换到 WordPress 默认主题并检查仍然出现相同的错误吗?

标签: php wordpress woocommerce


【解决方案1】:

错误来自here。它只是告诉您foreach 循环中使用的$prices 变量不是您可以迭代的类型。价格是使用

获取的
$prices = $this->data_store->read_price_data( $this, $for_display );

因此,从 read_price_data 调用返回的任何内容都不是其余代码所期望的。我不确定这个系统是如何运作的,以及当你扩展WC_Product_Variable 等时需要什么,我无法设置一个系统来调试它。但是,如果您从这一点向后追溯调用堆栈,您可能会发现为什么会从该函数返回此意外数据。

直觉表明,这可能是您在扩展课程或类似内容时忘记添加的重要部分。

【讨论】:

    【解决方案2】:

    问题

    您收到该警告是因为 read_price_data() 方法(在撰写时)WC_Product_Variable_Data_Store_CPT 类中可用,而不是用于自定义产品类型的默认方法,即 @987654322 @。

    然而,尽管默认类没有 read_price_data() 方法,但从类的实例调用它不会导致异常/错误,因为该类是通过具有魔力的 WC_Data_Store 类实例化的方法__call()

    // Case 1: In WC_Product_Variable::get_variation_prices().
    // $this->data_store is an instance of WC_Product_Variable_Data_Store_CPT
    $prices = $this->data_store->read_price_data( $this, $for_display ); // array
    
    // Case 2: In WC_Product_Variable_CanopyTour::get_variation_prices().
    // $this->data_store is an instance of WC_Product_Data_Store_CPT
    $prices = $this->data_store->read_price_data( $this, $for_display ); // null
    

    但是由于 read_price_data() 方法预计会返回 array,但它没有(或者它返回 null),这就是 PHP 抛出 "为 foreach() 提供的无效参数的原因...”警告:

    // The following code throws a warning.
    foreach ( null as $key => $value ) {
        ...
    }
    

    解决方案

    您需要为您的自定义(可变)产品类型使用正确的数据存储

    即向WC_Data_Store::$storesarray 添加一个项目,其中键是前缀为product- 的(变量)产品类型(因此在您的情况下,它将是product-variable_canopytour),值是class处理数据存储(例如WC_Product_Variable_Data_Store_CPT,如下例所示)。

    您可以通过woocommerce_data_stores 过滤器执行此操作,如下所示:(添加到活动主题的functions.php 文件)

    add_filter( 'woocommerce_data_stores', function( $stores ){
        $stores['product-variable_canopytour'] = 'WC_Product_Variable_Data_Store_CPT';
        return $stores;
    } );
    

    补充说明

    WC_Product_Variable_CanopyTour 的构造函数应该定义为 same way 父级 class 定义它,其中 $product 是可选的并且默认为零 (0),如下所示:

    class WC_Product_Variable_CanopyTour extends WC_Product_Variable {
        public function __construct( $product = 0 ) {
            $this->product_type = 'variable_canopytour';
            parent::__construct( $product );
        }
    
        ...
    }
    

    【讨论】:

    • PS:在functions.php 文件中,你得到了add_action( 'admin_head', array($woo_ct, 'wcb_admin_head') );,但我没有看到WCB_Woocommerce_CanopyTour_Product_Type 类中定义的名为wcb_admin_head 的方法。你的意思是add_action( 'admin_footer', array($woo_ct, 'wcb_admin_footer') );
    • 哇,非常感谢!正是这个需要我。我只需要知道如何将模板添加到我的自定义产品类型中。现在,关于您对“admin_head”的评论,我复制错了,发生的情况是只传递了引用产品类型“variable_canopytour”的函数。我希望这不是问题,问候!
    • 不客气@JesúsMagallón。我更新了答案,希望它更有帮助。 ;) 如果您需要进一步的帮助,请告诉我。
    • 令人难以置信的周到和有用的答案。谢谢@SallyCJ ...冒着在互联网上添加更多无意义的迂腐噪音的风险,您不能直接在类中设置 product_type 属性并完全摆脱构造函数吗? public $product_type = 'variable_canopytour'
    • 是的,确实,@KerryRandolph。 :) 但你知道,我当时更关注foreach 错误,错过了你指出的那部分。 :p
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2011-05-17
    • 2011-02-07
    相关资源
    最近更新 更多