Files
woocommerce-subscriptions/includes/legacy/class-wc-product-variable-subscription-legacy.php
Prospress Inc 0691aa36da 2.2.3
2017-04-11 09:25:24 +02:00

382 lines
15 KiB
PHP

<?php
/**
* Variable Subscription Product Legacy Class
*
* Extends WC_Product_Variable_Subscription to provide compatibility methods when running WooCommerce < 3.0.
*
* @class WC_Product_Variable_Subscription_Legacy
* @package WooCommerce Subscriptions
* @category Class
* @since 2.2.0
*
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class WC_Product_Variable_Subscription_Legacy extends WC_Product_Variable_Subscription {
var $subscription_price;
var $subscription_period;
var $max_variation_period;
var $subscription_period_interval;
var $max_variation_period_interval;
var $product_type;
protected $prices_array;
/**
* Create a simple subscription product object.
*
* @access public
* @param mixed $product
*/
public function __construct( $product ) {
parent::__construct( $product );
$this->parent_product_type = $this->product_type;
$this->product_type = 'variable-subscription';
// Load all meta fields
$this->product_custom_fields = get_post_meta( $this->id );
// Convert selected subscription meta fields for easy access
if ( ! empty( $this->product_custom_fields['_subscription_price'][0] ) ) {
$this->subscription_price = $this->product_custom_fields['_subscription_price'][0];
}
if ( ! empty( $this->product_custom_fields['_subscription_sign_up_fee'][0] ) ) {
$this->subscription_sign_up_fee = $this->product_custom_fields['_subscription_sign_up_fee'][0];
}
if ( ! empty( $this->product_custom_fields['_subscription_period'][0] ) ) {
$this->subscription_period = $this->product_custom_fields['_subscription_period'][0];
}
if ( ! empty( $this->product_custom_fields['_subscription_period_interval'][0] ) ) {
$this->subscription_period_interval = $this->product_custom_fields['_subscription_period_interval'][0];
}
if ( ! empty( $this->product_custom_fields['_subscription_length'][0] ) ) {
$this->subscription_length = $this->product_custom_fields['_subscription_length'][0];
}
if ( ! empty( $this->product_custom_fields['_subscription_trial_length'][0] ) ) {
$this->subscription_trial_length = $this->product_custom_fields['_subscription_trial_length'][0];
}
if ( ! empty( $this->product_custom_fields['_subscription_trial_period'][0] ) ) {
$this->subscription_trial_period = $this->product_custom_fields['_subscription_trial_period'][0];
}
$this->subscription_payment_sync_date = 0;
$this->subscription_one_time_shipping = ( ! isset( $this->product_custom_fields['_subscription_one_time_shipping'][0] ) ) ? 'no' : $this->product_custom_fields['_subscription_one_time_shipping'][0];
$this->subscription_limit = ( ! isset( $this->product_custom_fields['_subscription_limit'][0] ) ) ? 'no' : $this->product_custom_fields['_subscription_limit'][0];
}
/**
* Get the min or max variation (active) price.
*
* This is a copy of WooCommerce < 2.4's get_variation_price() method, because 2.4.0 introduced a new
* transient caching system which assumes asort() on prices yields correct results for min/max prices
* (which it does for prices alone, but that's not the full story for subscription prices). Unfortunately,
* the new caching system is also hard to hook into so we'll just use the old system instead as the
* @see self::variable_product_sync() uses the old method also.
*
* @param string $min_or_max - min or max
* @param boolean $display Whether the value is going to be displayed
* @return string
*/
public function get_variation_price( $min_or_max = 'min', $display = false ) {
$variation_id = get_post_meta( $this->id, '_' . $min_or_max . '_price_variation_id', true );
if ( $display ) {
if ( $variation = wc_get_product( $variation_id ) ) {
if ( 'incl' == get_option( 'woocommerce_tax_display_shop' ) ) {
$price = wcs_get_price_including_tax( $variation );
} else {
$price = wcs_get_price_excluding_tax( $variation );
}
} else {
$price = '';
}
} else {
$price = get_post_meta( $variation_id, '_price', true );
}
return apply_filters( 'woocommerce_get_variation_price', $price, $this, $min_or_max, $display );
}
/**
* Get an array of all sale and regular prices from all variations re-ordered after WC has done a standard sort, to reflect subscription terms.
* The first and last element for each price type is the least and most expensive, respectively.
*
* @see WC_Product_Variable::get_variation_prices()
* @param bool $include_taxes Should taxes be included in the prices.
* @return array() Array of RAW prices, regular prices, and sale prices with keys set to variation ID.
* @since 2.2.0
*/
public function get_variation_prices( $display = false ) {
$price_hash = $this->get_price_hash( $this, $display );
$this->prices_array[ $price_hash ] = parent::get_variation_prices( $display );
$children = array_keys( $this->prices_array[ $price_hash ]['price'] );
sort( $children );
$min_max_data = wcs_get_min_max_variation_data( $this, $children );
$min_variation_id = $min_max_data['min']['variation_id'];
$max_variation_id = $min_max_data['max']['variation_id'];
// Reorder the variable price arrays to reflect the min and max values so that WooCommerce will find them in the correct order
foreach ( $this->prices_array as $price_hash => $prices ) {
// Loop over sale_price, regular_price & price values to update them on main array
foreach ( $prices as $price_key => $variation_prices ) {
$min_price = $prices[ $price_key ][ $min_variation_id ];
$max_price = $prices[ $price_key ][ $max_variation_id ];
unset( $prices[ $price_key ][ $min_variation_id ] );
unset( $prices[ $price_key ][ $max_variation_id ] );
// append the minimum variation and prepend the maximum variation
$prices[ $price_key ] = array( $min_variation_id => $min_price ) + $prices[ $price_key ];
$prices[ $price_key ] += array( $max_variation_id => $max_price );
$this->prices_array[ $price_hash ][ $price_key ] = $prices[ $price_key ];
}
}
$this->subscription_price = $min_max_data['min']['price'];
$this->subscription_period = $min_max_data['min']['period'];
$this->subscription_period_interval = $min_max_data['min']['interval'];
$this->max_variation_price = $min_max_data['max']['price'];
$this->max_variation_period = $min_max_data['max']['period'];
$this->max_variation_period_interval = $min_max_data['max']['interval'];
$this->min_variation_price = $min_max_data['min']['price'];
$this->min_variation_regular_price = $min_max_data['min']['regular_price'];
return $this->prices_array[ $price_hash ];
}
/**
* Create unique cache key based on the tax location (affects displayed/cached prices), product version and active price filters.
* DEVELOPERS should filter this hash if offering conditonal pricing to keep it unique.
*
* @since 2.2.0
* @param WC_Product
* @param bool $display Are prices for display? If so, taxes will be calculated.
* @return string
*/
protected function get_price_hash( $display = false ) {
global $wp_filter;
if ( $display ) {
$price_hash = array( get_option( 'woocommerce_tax_display_shop', 'excl' ), WC_Tax::get_rates() );
} else {
$price_hash = array( false );
}
$filter_names = array( 'woocommerce_variation_prices_price', 'woocommerce_variation_prices_regular_price', 'woocommerce_variation_prices_sale_price' );
foreach ( $filter_names as $filter_name ) {
if ( ! empty( $wp_filter[ $filter_name ] ) ) {
$price_hash[ $filter_name ] = array();
foreach ( $wp_filter[ $filter_name ] as $priority => $callbacks ) {
$price_hash[ $filter_name ][] = array_values( wp_list_pluck( $callbacks, 'function' ) );
}
}
}
$price_hash = md5( json_encode( apply_filters( 'woocommerce_get_variation_prices_hash', $price_hash, $this, $display ) ) );
return $price_hash;
}
/**
* Sync variable product prices with the childs lowest/highest prices.
*
* @access public
* @return void
*/
public function variable_product_sync( $product_id = '' ) {
WC_Product_Variable::variable_product_sync( $product_id );
$child_variation_ids = $this->get_children( true );
if ( $child_variation_ids ) {
$min_max_data = wcs_get_min_max_variation_data( $this, $child_variation_ids );
update_post_meta( $this->id, '_min_price_variation_id', $min_max_data['min']['variation_id'] );
update_post_meta( $this->id, '_max_price_variation_id', $min_max_data['max']['variation_id'] );
update_post_meta( $this->id, '_price', $min_max_data['min']['price'] );
update_post_meta( $this->id, '_min_variation_price', $min_max_data['min']['price'] );
update_post_meta( $this->id, '_max_variation_price', $min_max_data['max']['price'] );
update_post_meta( $this->id, '_min_variation_regular_price', $min_max_data['min']['regular_price'] );
update_post_meta( $this->id, '_max_variation_regular_price', $min_max_data['max']['regular_price'] );
update_post_meta( $this->id, '_min_variation_sale_price', $min_max_data['min']['sale_price'] );
update_post_meta( $this->id, '_max_variation_sale_price', $min_max_data['max']['sale_price'] );
update_post_meta( $this->id, '_min_variation_period', $min_max_data['min']['period'] );
update_post_meta( $this->id, '_max_variation_period', $min_max_data['max']['period'] );
update_post_meta( $this->id, '_min_variation_period_interval', $min_max_data['min']['interval'] );
update_post_meta( $this->id, '_max_variation_period_interval', $min_max_data['max']['interval'] );
update_post_meta( $this->id, '_subscription_price', $min_max_data['min']['price'] );
update_post_meta( $this->id, '_subscription_sign_up_fee', $min_max_data['subscription']['signup-fee'] );
update_post_meta( $this->id, '_subscription_period', $min_max_data['min']['period'] );
update_post_meta( $this->id, '_subscription_period_interval', $min_max_data['min']['interval'] );
update_post_meta( $this->id, '_subscription_trial_period', $min_max_data['subscription']['trial_period'] );
update_post_meta( $this->id, '_subscription_trial_length', $min_max_data['subscription']['trial_length'] );
update_post_meta( $this->id, '_subscription_length', $min_max_data['subscription']['length'] );
$this->subscription_price = $min_max_data['min']['price'];
$this->subscription_period = $min_max_data['min']['period'];
$this->subscription_period_interval = $min_max_data['min']['interval'];
$this->subscription_sign_up_fee = $min_max_data['subscription']['signup-fee'];
$this->subscription_trial_period = $min_max_data['subscription']['trial_period'];
$this->subscription_trial_length = $min_max_data['subscription']['trial_length'];
$this->subscription_length = $min_max_data['subscription']['length'];
if ( function_exists( 'wc_delete_product_transients' ) ) {
wc_delete_product_transients( $this->id );
} else {
WC()->clear_product_transients( $this->id );
}
} else { // No variations yet
$this->subscription_price = '';
$this->subscription_sign_up_fee = '';
$this->subscription_period = 'day';
$this->subscription_period_interval = 1;
$this->subscription_trial_period = 'day';
$this->subscription_trial_length = 1;
$this->subscription_length = 0;
}
}
/**
* Returns the price in html format.
*
* @access public
* @param string $price (default: '')
* @return string
*/
public function get_price_html( $price = '' ) {
if ( ! isset( $this->subscription_period ) || ! isset( $this->subscription_period_interval ) || ! isset( $this->max_variation_period ) || ! isset( $this->max_variation_period_interval ) ) {
$this->variable_product_sync();
}
// Only create the subscription price string when a price has been set
if ( $this->subscription_price !== '' ) {
$price = '';
if ( $this->is_on_sale() && isset( $this->min_variation_price ) && $this->min_variation_regular_price !== $this->get_price() ) {
if ( ! $this->min_variation_price || $this->min_variation_price !== $this->max_variation_price ) {
$price .= wcs_get_price_html_from_text( $this );
}
$variation_id = get_post_meta( $this->id, '_min_price_variation_id', true );
$variation = wc_get_product( $variation_id );
$tax_display_mode = get_option( 'woocommerce_tax_display_shop' );
$sale_price_args = array( 'qty' => 1, 'price' => $variation->get_sale_price() );
$regular_price_args = array( 'qty' => 1, 'price' => $variation->get_regular_price() );
if ( 'incl' == $tax_display_mode ) {
$sale_price = wcs_get_price_including_tax( $variation, $sale_price_args );
$regular_price = wcs_get_price_including_tax( $variation, $regular_price_args );
} else {
$sale_price = wcs_get_price_excluding_tax( $variation, $sale_price_args );
$regular_price = wcs_get_price_excluding_tax( $variation, $regular_price_args );
}
$price .= $this->get_price_html_from_to( $regular_price, $sale_price );
} else {
if ( $this->min_variation_price !== $this->max_variation_price ) {
$price .= wcs_get_price_html_from_text( $this );
}
$price .= wc_price( $this->get_variation_price( 'min', true ) );
}
// Make sure the price contains "From:" when billing schedule differs between variations
if ( false === strpos( $price, wcs_get_price_html_from_text( $this ) ) ) {
if ( $this->subscription_period !== $this->max_variation_period ) {
$price = wcs_get_price_html_from_text( $this ) . $price;
} elseif ( $this->subscription_period_interval !== $this->max_variation_period_interval ) {
$price = wcs_get_price_html_from_text( $this ) . $price;
}
}
$price .= $this->get_price_suffix();
$price = WC_Subscriptions_Product::get_price_string( $this, array( 'price' => $price ) );
}
return apply_filters( 'woocommerce_variable_subscription_price_html', $price, $this );
}
/**
* Provide the WC_Data::get_meta() function when WC < 3.0 is active.
*
* @param string $meta_key
* @param bool $single
* @param string $context
* @return object WC_Product_Subscription or WC_Product_Subscription_Variation
*/
function get_meta( $meta_key = '', $single = true, $context = 'view' ) {
return get_post_meta( $this->get_id(), $meta_key, $single );
}
/**
* get_child function.
*
* @access public
* @param mixed $child_id
* @return object WC_Product_Subscription or WC_Product_Subscription_Variation
*/
public function get_child( $child_id ) {
return wc_get_product( $child_id, array(
'product_type' => 'Subscription_Variation',
'parent_id' => $this->id,
'parent' => $this,
) );
}
/**
* Get default attributes.
*
* @since 2.2.0
* @param string $context
* @return array
*/
public function get_default_attributes( $context = 'view' ) {
return $this->get_variation_default_attributes();
}
}