Grouped product class

This commit is contained in:
Mike Jolley 2016-10-18 18:38:42 +01:00
parent 92e016f68e
commit f58829a316
1 changed files with 96 additions and 69 deletions

View File

@ -1,7 +1,6 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
/**
@ -10,15 +9,38 @@ if ( ! defined( 'ABSPATH' ) ) {
* Grouped products cannot be purchased - they are wrappers for other products.
*
* @class WC_Product_Grouped
* @version 2.3.0
* @version 2.7.0
* @package WooCommerce/Classes/Products
* @category Class
* @author WooThemes
*/
class WC_Product_Grouped extends WC_Product {
/** @public array Array of child products/posts/variations. */
public $children;
/**
* Stores product data.
*
* @var array
*/
protected $extra_data = array(
'children' => array(),
);
/**
* Merges grouped product data into the parent object.
* @param int|WC_Product|object $product Product to init.
*/
public function __construct( $product = 0 ) {
$this->data = array_merge( $this->data, $this->extra_data );
parent::__construct( $product );
}
/*
|--------------------------------------------------------------------------
| Getters
|--------------------------------------------------------------------------
|
| Methods for getting data from the product object.
*/
/**
* Get internal type.
@ -28,6 +50,15 @@ class WC_Product_Grouped extends WC_Product {
return 'grouped';
}
/**
* Return the children of this product.
*
* @return array
*/
public function get_children() {
return $this->data['children'];
}
/**
* Get the add to cart button text.
*
@ -38,79 +69,20 @@ class WC_Product_Grouped extends WC_Product {
return apply_filters( 'woocommerce_product_add_to_cart_text', __( 'View products', 'woocommerce' ), $this );
}
/**
* Return the products children posts.
*
* @access public
* @return array
*/
public function get_children() {
if ( ! is_array( $this->children ) || empty( $this->children ) ) {
$transient_name = 'wc_product_children_' . $this->id;
$this->children = array_filter( array_map( 'absint', (array) get_transient( $transient_name ) ) );
if ( empty( $this->children ) ) {
$args = apply_filters( 'woocommerce_grouped_children_args', array(
'post_parent' => $this->id,
'post_type' => 'product',
'orderby' => 'menu_order',
'order' => 'ASC',
'fields' => 'ids',
'post_status' => 'publish',
'numberposts' => -1,
) );
$this->children = get_posts( $args );
set_transient( $transient_name, $this->children, DAY_IN_SECONDS * 30 );
}
}
return (array) $this->children;
}
/**
* Returns whether or not the product has any child product.
*
* @access public
* @return bool
*/
public function has_child() {
return sizeof( $this->get_children() ) ? true : false;
}
/**
* Returns whether or not the product is on sale.
*
* @access public
* @return bool
*/
public function is_on_sale() {
$is_on_sale = false;
if ( $this->has_child() ) {
foreach ( $this->get_children() as $child_id ) {
$sale_price = get_post_meta( $child_id, '_sale_price', true );
if ( '' !== $sale_price && $sale_price >= 0 ) {
$is_on_sale = true;
}
}
} else {
if ( $this->sale_price && $this->sale_price == $this->price ) {
$is_on_sale = true;
}
}
return apply_filters( 'woocommerce_product_is_on_sale', $is_on_sale, $this );
global $wpdb;
$on_sale = 1 === $wpdb->get_var( "SELECT 1 FROM $wpdb->postmeta WHERE meta_key='_sale_price' AND meta_value>0 AND post_id IN (" . implode( ',', array_map( 'esc_sql', $this->get_children() ) ) . ");" );
return apply_filters( 'woocommerce_product_is_on_sale', $on_sale, $this );
}
/**
* Returns false if the product cannot be bought.
*
* @access public
* @return bool
*/
public function is_purchasable() {
@ -118,7 +90,7 @@ class WC_Product_Grouped extends WC_Product {
}
/**
* Returns the price in html format.
* Returns the price in html format. @todo consider moving to template function
*
* @access public
* @param string $price (default: '')
@ -129,7 +101,7 @@ class WC_Product_Grouped extends WC_Product {
$child_prices = array();
foreach ( $this->get_children() as $child_id ) {
$child = wc_get_product( $child_id );
$child = wc_get_product( $child_id );
if ( '' !== $child->get_price() ) {
$child_prices[] = 'incl' === $tax_display_mode ? $child->get_price_including_tax() : $child->get_price_excluding_tax();
}
@ -158,4 +130,59 @@ class WC_Product_Grouped extends WC_Product {
return apply_filters( 'woocommerce_get_price_html', $price, $this );
}
/*
|--------------------------------------------------------------------------
| Setters
|--------------------------------------------------------------------------
|
| Methods for getting data from the product object.
*/
/**
* Return the children of this product.
*
* @param array $children
*/
public function set_children( $children ) {
$this->data['children'] = array_filter( wp_parse_id_list( (array) $children ) );
}
/*
|--------------------------------------------------------------------------
| CRUD methods
|--------------------------------------------------------------------------
*/
/**
* Reads a product from the database and sets its data to the class.
*
* @since 2.7.0
* @param int $id Product ID.
*/
public function read( $id ) {
parent::read( $id );
$transient_name = 'wc_product_children_' . $this->get_id();
$grouped_products = array_filter( wp_parse_id_list( (array) get_transient( $transient_name ) ) );
if ( empty( $grouped_products ) ) {
$grouped_products = get_posts( apply_filters( 'woocommerce_grouped_children_args', array(
'post_parent' => $this->get_id(),
'post_type' => 'product',
'orderby' => 'menu_order',
'order' => 'ASC',
'fields' => 'ids',
'post_status' => 'publish',
'numberposts' => -1,
) ) );
set_transient( $transient_name, $grouped_products, DAY_IN_SECONDS * 30 );
}
$this->set_props( array(
'children' => $grouped_products,
) );
do_action( 'woocommerce_product_loaded', $this );
do_action( 'woocommerce_product_' . $this->get_type() . '_loaded', $this );
}
}