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

Jes*_*lón 5 php wordpress woocommerce

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

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

我已将问题追溯到文件,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';
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

函数.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') );
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Sal*_* CJ 8

问题

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

然而,尽管默认类没有该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
Run Code Online (Sandbox Code Playgroud)

但是由于该read_price_data()方法应该返回 anarray而它却没有(或者它返回null),这就是 PHP 抛出“ Invalid argument provided for foreach() ... ”警告的原因:

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

解决方案

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

即向 中添加一个项目,其中键是前缀为(因此在您的情况下,它是)的(变量)产品类型,而值是处理数据存储的 (例如,如下例所示)。WC_Data_Store::$stores arrayproduct-product-variable_canopytourclassWC_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;
} );
Run Code Online (Sandbox Code Playgroud)

附加说明

的构造函数的WC_Product_Variable_CanopyTour定义方式应与父级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 );
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)