woocommerce/classes/class-wc-product-variation.php

408 lines
12 KiB
PHP
Raw Normal View History

2011-08-09 15:16:18 +00:00
<?php
/**
* Product Variation Class
2012-08-10 13:21:10 +00:00
*
2011-08-10 17:11:11 +00:00
* The WooCommerce product variation class handles product variation data.
2011-08-09 15:16:18 +00:00
*
2012-01-27 16:38:39 +00:00
* @class WC_Product_Variation
2012-08-14 19:42:38 +00:00
* @version 1.6.4
2012-08-14 22:43:48 +00:00
* @package WooCommerce/Classes
2012-08-14 19:42:38 +00:00
* @author WooThemes
2011-08-09 15:16:18 +00:00
*/
2012-01-27 16:38:39 +00:00
class WC_Product_Variation extends WC_Product {
2012-08-10 13:21:10 +00:00
2012-08-15 17:08:42 +00:00
/** @var array Stores variation data (attributes) for the current variation. */
2011-08-09 15:16:18 +00:00
var $variation_data;
2012-08-15 17:08:42 +00:00
/** @var int ID of the variable product. */
2011-08-09 15:16:18 +00:00
var $variation_id;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has a length. */
var $variation_has_length;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has a width. */
var $variation_has_width;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has a height. */
var $variation_has_height;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has a weight. */
2011-08-09 15:16:18 +00:00
var $variation_has_weight;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has a price. */
2011-08-09 15:16:18 +00:00
var $variation_has_price;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has a sale price. */
2011-08-09 15:16:18 +00:00
var $variation_has_sale_price;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has stock and is managing stock. */
2011-08-09 15:16:18 +00:00
var $variation_has_stock;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has a sku. */
2011-08-09 15:16:18 +00:00
var $variation_has_sku;
2012-08-15 17:08:42 +00:00
/** @var string Stores the shipping class of the variation. */
var $variation_shipping_class;
2012-08-15 17:08:42 +00:00
/** @var int Stores the shipping class ID of the variation. */
2012-06-26 12:17:08 +00:00
var $variation_shipping_class_id;
2012-08-15 17:08:42 +00:00
/** @var bool True if the variation has a tax class. */
var $variation_has_tax_class;
2012-08-10 13:21:10 +00:00
2011-08-09 15:16:18 +00:00
/**
* Loads all product data from custom fields
*
2012-08-14 19:42:38 +00:00
* @access public
* @param mixed $variation_id ID of the variation to load
* @param int $parent_id (default: '') ID of the parent product
* @param array $parent_custom_fields (default: '') Array of the parent products meta data
* @return void
2011-08-09 15:16:18 +00:00
*/
2012-01-27 16:38:39 +00:00
function __construct( $variation_id, $parent_id = '', $parent_custom_fields = '' ) {
2012-08-10 13:21:10 +00:00
2011-08-09 15:16:18 +00:00
$this->variation_id = $variation_id;
2012-08-10 13:21:10 +00:00
2011-08-09 15:16:18 +00:00
$product_custom_fields = get_post_custom( $this->variation_id );
2012-08-10 13:21:10 +00:00
2011-08-09 15:16:18 +00:00
$this->variation_data = array();
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
foreach ( $product_custom_fields as $name => $value ) {
2012-08-10 13:21:10 +00:00
if ( ! strstr( $name, 'attribute_' ) ) continue;
2012-08-10 13:21:10 +00:00
2011-08-09 15:16:18 +00:00
$this->variation_data[$name] = $value[0];
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
}
2011-08-09 15:16:18 +00:00
/* Get main product data from parent */
$this->id = ($parent_id>0) ? $parent_id : wp_get_post_parent_id( $this->variation_id );
if (!$parent_custom_fields) $parent_custom_fields = get_post_custom( $this->id );
2012-08-10 13:21:10 +00:00
// Define the data we're going to load from the parent: Key => Default value
2011-08-20 15:41:42 +00:00
$load_data = array(
2012-02-13 00:34:09 +00:00
'sku' => '',
2011-08-20 15:41:42 +00:00
'price' => 0,
'visibility' => 'hidden',
'stock' => 0,
'stock_status' => 'instock',
'backorders' => 'no',
'manage_stock' => 'no',
'sale_price' => '',
'regular_price' => '',
'weight' => '',
'length' => '',
'width' => '',
'height' => '',
2011-08-20 15:41:42 +00:00
'tax_status' => 'taxable',
'tax_class' => '',
'upsell_ids' => array(),
'crosssell_ids' => array()
);
2012-08-10 13:21:10 +00:00
2011-08-20 15:41:42 +00:00
// Load the data from the custom fields
2012-08-10 13:21:10 +00:00
foreach ( $load_data as $key => $default )
$this->$key = ( isset( $parent_custom_fields['_' . $key][0] ) && $parent_custom_fields['_' . $key][0] !== '' ) ? $parent_custom_fields['_' . $key][0] : $default;
2011-08-09 15:16:18 +00:00
$this->product_type = 'variable';
2012-08-10 13:21:10 +00:00
$this->variation_has_sku = $this->variation_has_stock = $this->variation_has_weight = $this->variation_has_length = $this->variation_has_width = $this->variation_has_height = $this->variation_has_price = $this->variation_has_sale_price = false;
2012-08-10 13:21:10 +00:00
2011-08-20 15:41:42 +00:00
/* Override parent data with variation */
if ( isset( $product_custom_fields['_sku'][0] ) && ! empty( $product_custom_fields['_sku'][0] ) ) {
2011-08-09 15:16:18 +00:00
$this->variation_has_sku = true;
$this->sku = $product_custom_fields['_sku'][0];
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_stock'][0] ) && $product_custom_fields['_stock'][0] !== '' ) {
2011-08-09 15:16:18 +00:00
$this->variation_has_stock = true;
$this->manage_stock = 'yes';
$this->stock = $product_custom_fields['_stock'][0];
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_weight'][0] ) && $product_custom_fields['_weight'][0] !== '' ) {
2011-08-09 15:16:18 +00:00
$this->variation_has_weight = true;
$this->weight = $product_custom_fields['_weight'][0];
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_length'][0] ) && $product_custom_fields['_length'][0] !== '' ) {
$this->variation_has_length = true;
$this->length = $product_custom_fields['_length'][0];
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_width'][0] ) && $product_custom_fields['_width'][0] !== '' ) {
$this->variation_has_width = true;
$this->width = $product_custom_fields['_width'][0];
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_height'][0] ) && $product_custom_fields['_height'][0] !== '' ) {
$this->variation_has_height = true;
$this->height = $product_custom_fields['_height'][0];
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_price'][0] ) && $product_custom_fields['_price'][0] !== '' ) {
2011-08-09 15:16:18 +00:00
$this->variation_has_price = true;
$this->price = $product_custom_fields['_price'][0];
$this->regular_price = $product_custom_fields['_price'][0];
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_sale_price'][0] ) && $product_custom_fields['_sale_price'][0] !== '' ) {
2011-08-09 15:16:18 +00:00
$this->variation_has_sale_price = true;
$this->sale_price = $product_custom_fields['_sale_price'][0];
2011-08-20 15:41:42 +00:00
if ($this->sale_price < $this->price) $this->price = $this->sale_price;
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_downloadable'][0] ) && $product_custom_fields['_downloadable'][0] == 'yes' ) {
$this->downloadable = 'yes';
} else {
$this->downloadable = 'no';
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_virtual'][0] ) && $product_custom_fields['_virtual'][0] == 'yes' ) {
$this->virtual = 'yes';
} else {
$this->virtual = 'no';
}
2012-08-10 13:21:10 +00:00
if ( isset( $product_custom_fields['_tax_class'][0] ) ) {
$this->variation_has_tax_class = true;
$this->tax_class = $product_custom_fields['_tax_class'][0];
}
2012-08-10 13:21:10 +00:00
$this->total_stock = $this->stock;
2011-08-09 15:16:18 +00:00
}
2012-08-14 19:42:38 +00:00
/**
* Returns whether or not the variation is visible.
*
* @access public
* @return bool
*/
function is_visible() {
2012-08-10 13:21:10 +00:00
$visible = true;
2012-08-10 13:21:10 +00:00
// Out of stock visibility
2012-08-10 13:21:10 +00:00
if ( get_option('woocommerce_hide_out_of_stock_items') == 'yes' && ! $this->is_in_stock() )
$visible = false;
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
return apply_filters( 'woocommerce_product_is_visible', $visible, $this->id );
}
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
/**
* Returns whether or not the variations parent is visible.
*
* @access public
* @return bool
*/
function parent_is_visible() {
2012-08-10 13:21:10 +00:00
return parent::is_visible();
}
2012-08-10 13:21:10 +00:00
2011-08-22 11:57:50 +00:00
/**
* Get variation ID
2012-08-10 13:21:10 +00:00
*
2011-08-22 11:57:50 +00:00
* @return int
*/
function get_variation_id() {
return (int) $this->variation_id;
}
2012-08-10 13:21:10 +00:00
2011-08-22 11:57:50 +00:00
/**
* Get variation attribute values
2012-08-10 13:21:10 +00:00
*
2011-08-22 11:57:50 +00:00
* @return array of attributes and their values for this variation
*/
function get_variation_attributes() {
return $this->variation_data;
}
2012-08-10 13:21:10 +00:00
2011-08-22 11:57:50 +00:00
/**
* Get variation attribute values
2012-08-10 13:21:10 +00:00
*
2011-08-22 11:57:50 +00:00
* @return string containing the formatted price
*/
2011-08-09 15:16:18 +00:00
function get_price_html() {
2011-08-20 15:41:42 +00:00
if ($this->variation_has_price || $this->variation_has_sale_price) :
2011-08-09 15:16:18 +00:00
$price = '';
2012-08-10 13:21:10 +00:00
if ($this->price!=='') :
2011-08-09 15:16:18 +00:00
if ($this->variation_has_sale_price) :
2011-08-20 15:41:42 +00:00
$price .= '<del>'.woocommerce_price( $this->regular_price ).'</del> <ins>'.woocommerce_price( $this->sale_price ).'</ins>';
2012-01-14 16:42:04 +00:00
$price = apply_filters('woocommerce_variation_sale_price_html', $price, $this);
2011-08-09 15:16:18 +00:00
else :
2011-08-10 17:11:11 +00:00
$price .= woocommerce_price( $this->price );
2012-01-14 16:42:04 +00:00
$price = apply_filters('woocommerce_variation_price_html', $price, $this);
2011-08-09 15:16:18 +00:00
endif;
endif;
2012-08-10 13:21:10 +00:00
2011-08-09 15:16:18 +00:00
return $price;
else :
2011-08-10 17:11:11 +00:00
return woocommerce_price(parent::get_price());
2011-08-09 15:16:18 +00:00
endif;
}
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
/**
* Gets the main product image.
*
* @access public
* @param string $size (default: 'shop_thumbnail')
* @return string
2012-08-10 13:21:10 +00:00
*/
function get_image( $size = 'shop_thumbnail' ) {
global $woocommerce;
2012-08-10 13:21:10 +00:00
$image = '';
if ( $this->variation_id && has_post_thumbnail( $this->variation_id ) ) {
$image = get_the_post_thumbnail( $this->variation_id, $size );
} elseif ( has_post_thumbnail( $this->id ) ) {
$image = get_the_post_thumbnail( $this->id, $size );
} elseif ( $parent_id = wp_get_post_parent_id( $this->id ) && has_post_thumbnail( $parent_id ) ) {
$image = get_the_post_thumbnail( $parent_id, $size );
} else {
$image = '<img src="' . woocommerce_placeholder_img_src() . '" alt="Placeholder" width="' . $woocommerce->get_image_size( 'shop_thumbnail_image_width' ) . '" height="' . $woocommerce->get_image_size( 'shop_thumbnail_image_height' ) . '" />';
}
return $image;
}
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
2011-08-09 15:16:18 +00:00
/**
2012-08-14 19:42:38 +00:00
* Reduce stock level of the product.
2011-08-09 15:16:18 +00:00
*
2012-08-14 19:42:38 +00:00
* @access public
* @param int $by (default: 1) Amount to reduce by
* @return int stock level
2011-08-09 15:16:18 +00:00
*/
function reduce_stock( $by = 1 ) {
2012-03-07 13:38:51 +00:00
global $woocommerce;
2012-08-10 13:21:10 +00:00
if ( $this->variation_has_stock ) {
if ( $this->managing_stock() ) {
2012-08-10 13:21:10 +00:00
2012-06-29 19:40:18 +00:00
$this->stock = $this->stock - $by;
$this->total_stock = $this->total_stock - $by;
update_post_meta( $this->variation_id, '_stock', $this->stock );
2012-06-29 19:40:18 +00:00
$woocommerce->clear_product_transients( $this->id ); // Clear transient
2012-08-10 13:21:10 +00:00
2012-06-29 19:40:18 +00:00
// Check parents out of stock attribute
if ( ! $this->is_in_stock() ) {
2012-08-10 13:21:10 +00:00
2011-08-21 16:47:49 +00:00
// Check parent
2012-01-27 16:38:39 +00:00
$parent_product = new WC_Product( $this->id );
2012-08-10 13:21:10 +00:00
2012-06-29 19:40:18 +00:00
// Only continue if the parent has backorders off
if ( ! $parent_product->backorders_allowed() && $parent_product->get_total_stock() <= 0 ) {
2012-08-10 13:21:10 +00:00
2012-06-29 19:40:18 +00:00
update_post_meta( $this->id, '_stock_status', 'outofstock' );
2012-08-10 13:21:10 +00:00
}
2011-08-21 16:47:49 +00:00
}
2012-08-10 13:21:10 +00:00
2011-08-21 16:47:49 +00:00
return $this->stock;
}
} else {
2011-08-09 15:16:18 +00:00
return parent::reduce_stock( $by );
}
2011-08-09 15:16:18 +00:00
}
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
2011-08-09 15:16:18 +00:00
/**
2012-08-14 19:42:38 +00:00
* Increase stock level of the product.
2011-08-09 15:16:18 +00:00
*
2012-08-14 19:42:38 +00:00
* @access public
* @param int $by (default: 1) Amount to increase by
* @return int stock level
2011-08-09 15:16:18 +00:00
*/
function increase_stock( $by = 1 ) {
2012-06-29 19:40:18 +00:00
global $woocommerce;
2012-08-10 13:21:10 +00:00
2011-08-09 15:16:18 +00:00
if ($this->variation_has_stock) :
if ($this->managing_stock()) :
2011-08-21 16:47:49 +00:00
2012-06-29 19:40:18 +00:00
$this->stock = $this->stock + $by;
$this->total_stock = $this->total_stock + $by;
update_post_meta( $this->variation_id, '_stock', $this->stock );
$woocommerce->clear_product_transients( $this->id ); // Clear transient
2012-08-10 13:21:10 +00:00
2011-08-21 16:47:49 +00:00
// Parents out of stock attribute
2012-08-10 13:21:10 +00:00
if ( $this->is_in_stock() )
2012-06-29 19:40:18 +00:00
update_post_meta( $this->id, '_stock_status', 'instock' );
2012-08-10 13:21:10 +00:00
2011-08-21 16:47:49 +00:00
return $this->stock;
2011-08-09 15:16:18 +00:00
endif;
else :
return parent::increase_stock( $by );
endif;
}
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
/**
2012-08-14 19:42:38 +00:00
* Get the shipping class, and if not set, get the shipping class of the parent.
*
* @access public
* @return string
*/
function get_shipping_class() {
if (!$this->variation_shipping_class) :
$classes = get_the_terms( $this->variation_id, 'product_shipping_class' );
if ($classes && !is_wp_error($classes)) $this->variation_shipping_class = current($classes)->slug; else $this->variation_shipping_class = parent::get_shipping_class();
endif;
return $this->variation_shipping_class;
}
2012-08-10 13:21:10 +00:00
2012-08-14 19:42:38 +00:00
/**
* Returns the product shipping class ID.
*
* @access public
* @return int
*/
2012-06-26 12:17:08 +00:00
function get_shipping_class_id() {
if ( ! $this->variation_shipping_class_id ) {
2012-08-10 13:21:10 +00:00
2012-06-26 12:17:08 +00:00
$classes = get_the_terms( $this->variation_id, 'product_shipping_class' );
2012-08-10 13:21:10 +00:00
if ( $classes && ! is_wp_error( $classes ) )
$this->variation_shipping_class_id = current( $classes )->term_id;
else
2012-06-26 12:17:08 +00:00
$this->variation_shipping_class_id = parent::get_shipping_class_id();
2012-08-10 13:21:10 +00:00
2012-06-26 12:17:08 +00:00
}
return (int) $this->variation_shipping_class_id;
}
2012-08-10 13:21:10 +00:00
/**
* Check if downloadable product has a file attached.
*
* @return bool Whether downloadable product has a file attached.
*/
function has_file() {
if ( ! $this->is_downloadable() )
return false;
2012-08-10 13:21:10 +00:00
if ( apply_filters( 'woocommerce_file_download_path', get_post_meta( $this->variation_id, '_file_path', true ), $this->variation_id ) )
return true;
return false;
}
2012-01-27 16:38:39 +00:00
}
2012-08-14 19:42:38 +00:00
/**
* woocommerce_product_variation class.
*
2012-08-15 17:08:42 +00:00
* @extends WC_Product_Variation
* @deprecated 1.4
* @package WooCommerce/Classes
2012-08-14 19:42:38 +00:00
*/
2012-01-27 16:38:39 +00:00
class woocommerce_product_variation extends WC_Product_Variation {
2012-08-10 13:21:10 +00:00
public function __construct( $variation_id, $parent_id = '', $parent_custom_fields = '' ) {
2012-01-27 16:38:39 +00:00
_deprecated_function( 'woocommerce_product_variation', '1.4', 'WC_Product_Variation()' );
2012-08-10 13:21:10 +00:00
parent::__construct( $variation_id, $parent_id, $parent_custom_fields );
}
2011-08-09 15:16:18 +00:00
}