Woocommerce:为class-wc-product-variable.php文件中的foreach()提供了无效的参数

时间:2018-10-04 19:23:20

标签: php wordpress woocommerce

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

  

警告:为中的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') );

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

谢谢!

2 个答案:

答案 0 :(得分:2)

问题

之所以收到警告,是因为WC_Product_Variable_Data_Store_CPT类中的re.sub(r"(?m)\s+#\w+(?=\n)", " ", text) 方法(在编写时)仅 可用,而不是用于自定义产品类型的默认方法,就是WC_Product_Data_Store_CPT

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

read_price_data()

但是由于期望// 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),所以这就是PHP抛出“ Invalid为foreach()提供的参数... “警告:

null

解决方案

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

即在WC_Data_Store::$stores // The following code throws a warning. foreach ( null as $key => $value ) { ... } 中添加一个项目,其中的键是(变量)产品类型以array为前缀(因此,在您的情况下为product-),并且值是处理数据存储的product-variable_canopytour(例如下面的示例中的class)。

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

functions.php

附加说明

add_filter( 'woocommerce_data_stores', function( $stores ){ $stores['product-variable_canopytour'] = 'WC_Product_Variable_Data_Store_CPT'; return $stores; } ); 的构造函数应在same way上定义,父WC_Product_Variable_CanopyTour对其进行定义,其中class是可选的,并且默认为零({{1} }),像这样:

$product

答案 1 :(得分:0)

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

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

因此,read_price_data调用返回的结果与其余代码所期望的不一样。我不确定该系统如何运行以及扩展WC_Product_Variable等时需要什么,并且我无法设置系统来对其进行调试。但是,如果从此点向后追溯调用堆栈,则可能会发现为什么从此函数返回此意外数据的原因。

直觉认为这可能是您在扩展课程或类似内容时忘记添加的一些重要内容。