public function product_period($period, $product) { if (WC_Name_Your_Price_Helpers::is_billing_period_variable($product->id) && !isset($product->subscription_period)) { $period = is_admin() ? WC_Name_Your_Price_Helpers::get_minimum_billing_period($product->id) : WC_Name_Your_Price_Helpers::get_posted_period($product->id); } return $period; }
/** * Tells if a product is a Name Your Price product, provided that the extension is installed. * * @param mixed $product_id product or id to check * @return boolean true if NYP exists and product is a NYP */ public function is_nyp($product_id) { if (!class_exists('WC_Name_Your_Price_Helpers')) { return false; } if (WC_Name_Your_Price_Helpers::is_nyp($product_id)) { return true; } return false; }
/** * Initializes a bundled item for access by the container: Calculates min and max prices, checks availability info, etc. * @return void */ function init() { global $woocommerce_bundles; $product_id = $this->product_id; $bundled_product = $this->product; $quantity = $this->get_quantity(); $discount = $this->get_discount(); $this->add_price_filters(); /*-----------------------------------------------------------------------------------*/ /* Simple Subs /*-----------------------------------------------------------------------------------*/ if ($bundled_product->product_type === 'subscription') { if ($this->is_front_end) { if ($bundled_product->is_sold_individually()) { $this->sold_individually = true; } if (!$bundled_product->is_in_stock() || !$bundled_product->has_enough_stock($quantity)) { $this->stock_status = 'out-of-stock'; } if ($bundled_product->is_on_backorder() && $bundled_product->backorders_require_notification()) { $this->stock_status = 'available-on-backorder'; } } // Sign up price $regular_signup_fee = $bundled_product->get_sign_up_fee(); $signup_fee = $this->get_sign_up_fee($regular_signup_fee, $bundled_product); $this->min_regular_price = $this->max_regular_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($bundled_product, $regular_signup_fee); $this->min_price = $this->max_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($bundled_product, $signup_fee); if ($regular_signup_fee > $signup_fee) { $this->on_sale = true; } // Save prices incl or excl tax if ($woocommerce_bundles->helpers->wc_option_calculate_taxes === 'yes' && $this->is_front_end) { if ($woocommerce_bundles->helpers->wc_option_tax_display_shop === 'incl') { if ($woocommerce_bundles->helpers->wc_option_prices_include_tax === 'yes') { $this->min_price_incl_tax = $signup_fee; $this->min_price_excl_tax = $bundled_product->get_price_excluding_tax($quantity, $signup_fee) / $quantity; } else { $this->min_price_incl_tax = $this->min_price; $this->min_price_excl_tax = $signup_fee; } } else { if ($woocommerce_bundles->helpers->wc_option_prices_include_tax === 'yes') { $this->min_price_incl_tax = $signup_fee; $this->min_price_excl_tax = $this->min_price; } else { $this->min_price_incl_tax = $bundled_product->get_price_including_tax($quantity, $signup_fee) / $quantity; $this->min_price_excl_tax = $signup_fee; } } } // Recurring price $regular_recurring_fee = $bundled_product->get_regular_price(); $recurring_fee = $bundled_product->get_price(); $this->min_regular_recurring_price = $this->max_regular_recurring_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($bundled_product, $regular_recurring_fee); $this->min_recurring_price = $this->max_recurring_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($bundled_product, $recurring_fee); if ($regular_recurring_fee > $recurring_fee) { $this->on_sale = true; } // If there is NO free trial, we need to include the recurring price in the initial amount $trial_length = $bundled_product->subscription_trial_length; if ($trial_length == 0) { $this->min_regular_price = $this->max_regular_price = $this->min_regular_price + $this->min_regular_recurring_price; $this->min_price = $this->max_price = $this->min_price + $this->min_recurring_price; } /*-----------------------------------------------------------------------------------*/ /* Simple Products /*-----------------------------------------------------------------------------------*/ } elseif ($bundled_product->product_type == 'simple') { if ($this->is_front_end) { if ($bundled_product->is_sold_individually()) { $this->sold_individually = true; } if (!$bundled_product->is_in_stock() || !$bundled_product->has_enough_stock($quantity)) { $this->stock_status = 'out-of-stock'; } if ($bundled_product->is_on_backorder() && $bundled_product->backorders_require_notification()) { $this->stock_status = 'available-on-backorder'; } } $regular_price = $bundled_product->get_regular_price(); $price = $bundled_product->get_price(); // Name your price support if ($woocommerce_bundles->compatibility->is_nyp($bundled_product)) { $regular_price = $price = WC_Name_Your_Price_Helpers::get_minimum_price($product_id) ? WC_Name_Your_Price_Helpers::get_minimum_price($product_id) : 0; $this->nyp = true; } $this->min_regular_price = $this->max_regular_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($bundled_product, $regular_price); $this->min_price = $this->max_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($bundled_product, $price); if ($regular_price > $price) { $this->on_sale = true; } // Save prices incl or excl tax if ($woocommerce_bundles->helpers->wc_option_calculate_taxes === 'yes' && $this->is_front_end) { if ($woocommerce_bundles->helpers->wc_option_tax_display_shop === 'incl') { if ($woocommerce_bundles->helpers->wc_option_prices_include_tax === 'yes') { $this->min_price_incl_tax = $price; $this->min_price_excl_tax = $bundled_product->get_price_excluding_tax($quantity, $price) / $quantity; } else { $this->min_price_incl_tax = $this->min_price; $this->min_price_excl_tax = $price; } } else { if ($woocommerce_bundles->helpers->wc_option_prices_include_tax === 'yes') { $this->min_price_incl_tax = $price; $this->min_price_excl_tax = $this->min_price; } else { $this->min_price_incl_tax = $bundled_product->get_price_including_tax($quantity, $price) / $quantity; $this->min_price_excl_tax = $price; } } } /*-----------------------------------------------------------------------------------*/ /* Variable Products /*-----------------------------------------------------------------------------------*/ } elseif ($bundled_product->product_type === 'variable') { $min_variation_regular_price = ''; $min_variation_price = ''; $max_variation_regular_price = ''; $max_variation_price = ''; $min_variation_price_incl_tax = ''; $min_variation_price_excl_tax = ''; // check stock status of variations - if all of them are out of stock, the product cannot be purchased $variation_in_stock_exists = $this->is_front_end ? false : true; $all_variations_on_backorder = $this->is_front_end ? true : false; // sold individually status if ($this->is_front_end && $bundled_product->is_sold_individually() == 'yes') { $this->sold_individually = true; } // Process variations foreach ($bundled_product->get_children() as $child_id) { // Do not continue if variation is filtered if (!empty($this->allowed_variations)) { if (is_array($this->allowed_variations) && !in_array($child_id, $this->allowed_variations)) { continue; } } // Use this to improve performance instead of grabbing it like so: $variation = $bundled_product->get_child( $child_id, $args ) $variation = $woocommerce_bundles->helpers->get_variation($child_id, $bundled_product); if (!empty($variation->variation_id)) { if ($this->is_front_end) { // check stock status of variation - if one of them is in stock, the product can be purchased if (!$variation_in_stock_exists && $variation->is_in_stock() && $variation->has_enough_stock($quantity)) { $variation_in_stock_exists = true; } if ($all_variations_on_backorder && (!$variation->is_on_backorder() || !$bundled_product->backorders_require_notification())) { $all_variations_on_backorder = false; } } // Price info // Calculate min / max variation price only if filters are present. // Otherwise, its much faster to grab those from the parent product. if ($this->is_priced_per_product() && !empty($this->allowed_variations)) { $variation_regular_price_raw = $variation->get_regular_price(); $variation_price_raw = $variation->get_price(); $variation_regular_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($variation, $variation_regular_price_raw); $variation_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($variation, $variation_price_raw); // on sale status if ($variation_regular_price > $variation_price) { $this->on_sale = true; } // Prices incl and excl tax if ($woocommerce_bundles->helpers->wc_option_calculate_taxes == 'yes' && $this->is_front_end) { if ($woocommerce_bundles->helpers->wc_option_tax_display_shop == 'incl') { if ($woocommerce_bundles->helpers->wc_option_prices_include_tax == 'yes') { $variation_price_incl_tax = $variation_price_raw; $variation_price_excl_tax = $bundled_product->get_price_excluding_tax($quantity, $variation_price_raw) / $quantity; } else { $variation_price_incl_tax = $variation_price; $variation_price_excl_tax = $variation_price_raw; } } else { if ($woocommerce_bundles->helpers->wc_option_prices_include_tax == 'yes') { $variation_price_incl_tax = $variation_price_raw; $variation_price_excl_tax = $variation_price; } else { $variation_price_incl_tax = $bundled_product->get_price_including_tax($quantity, $variation_price_raw) / $quantity; $variation_price_excl_tax = $variation_price_raw; } } } // lowest price if (!is_numeric($min_variation_regular_price) || $variation_regular_price < $min_variation_regular_price) { $min_variation_regular_price = $variation_regular_price; } if (!is_numeric($min_variation_price) || $variation_price < $min_variation_price) { $min_variation_price = $variation_price; } // highest price if (!is_numeric($max_variation_regular_price) || $variation_regular_price > $max_variation_regular_price) { $max_variation_regular_price = $variation_regular_price; } if (!is_numeric($max_variation_price) || $variation_price > $max_variation_price) { $max_variation_price = $variation_price; } // taxed if ($woocommerce_bundles->helpers->wc_option_calculate_taxes == 'yes' && $this->is_front_end) { if (!is_numeric($min_variation_price_incl_tax) || $variation_price_incl_tax < $min_variation_price_incl_tax) { $min_variation_price_incl_tax = $variation_price_incl_tax; } if (!is_numeric($min_variation_price_excl_tax) || $variation_price_excl_tax < $min_variation_price_excl_tax) { $min_variation_price_excl_tax = $variation_price_excl_tax; } } } } } if ($variation_in_stock_exists == false) { $this->stock_status = 'out-of-stock'; } if ($all_variations_on_backorder) { $this->stock_status = 'available-on-backorder'; } // When no variation filters are present, its much faster to grab the min/max variation price data from the parent product meta. if (empty($this->allowed_variations)) { if (!empty($discount)) { // Product may need to be synced if ($bundled_product->get_variation_regular_price('min', false) === false) { $bundled_product->variable_product_sync(); } // Grab the min/max regular price variation since discounts are calculated on top of the regular price only. $min_variation_id = get_post_meta($this->product_id, '_min_regular_price_variation_id', true); $min_variation = $woocommerce_bundles->helpers->get_variation($min_variation_id, $bundled_product); $min_variation_price_raw = $min_variation->get_price(); $min_variation_regular_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($min_variation, $min_variation->get_regular_price()); $min_variation_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($min_variation, $min_variation_price_raw); $max_variation_id = get_post_meta($this->product_id, '_max_regular_price_variation_id', true); $max_variation = $woocommerce_bundles->helpers->get_variation($max_variation_id, $bundled_product); $max_variation_regular_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($max_variation, $max_variation->get_regular_price()); $max_variation_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($max_variation, $max_variation->get_price()); $this->on_sale = $max_variation_regular_price > 0 || $max_variation_price > 0; } else { // Product may need to be synced if ($bundled_product->get_variation_price('min', false) === false) { $bundled_product->variable_product_sync(); } // Grab the min/max price variation since there is no discount. $min_variation_id = get_post_meta($this->product_id, '_min_price_variation_id', true); $min_variation = $woocommerce_bundles->helpers->get_variation($min_variation_id, $bundled_product); $min_variation_price_raw = $min_variation->get_price(); $min_variation_regular_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($min_variation, $min_variation->get_regular_price()); $min_variation_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($min_variation, $min_variation_price_raw); $max_variation_id = get_post_meta($this->product_id, '_max_price_variation_id', true); $max_variation = $woocommerce_bundles->helpers->get_variation($max_variation_id, $bundled_product); $max_variation_regular_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($max_variation, $max_variation->get_regular_price()); $max_variation_price = $woocommerce_bundles->helpers->get_product_price_incl_or_excl_tax($max_variation, $max_variation->get_price()); // sale status can be obtained from the parent since all variations are active if ($this->is_priced_per_product()) { $this->on_sale = $bundled_product->is_on_sale(); } } // Prices incl and excl tax if ($woocommerce_bundles->helpers->wc_option_calculate_taxes == 'yes' && $this->is_front_end) { if ($woocommerce_bundles->helpers->wc_option_tax_display_shop == 'incl') { if ($woocommerce_bundles->helpers->wc_option_prices_include_tax == 'yes') { $min_variation_price_incl_tax = $min_variation_price_raw; $min_variation_price_excl_tax = $bundled_product->get_price_excluding_tax($quantity, $min_variation_price_raw) / $quantity; } else { $min_variation_price_incl_tax = $min_variation_price; $min_variation_price_excl_tax = $min_variation_price_raw; } } else { if ($woocommerce_bundles->helpers->wc_option_prices_include_tax == 'yes') { $min_variation_price_incl_tax = $min_variation_price_raw; $min_variation_price_excl_tax = $min_variation_price; } else { $min_variation_price_incl_tax = $bundled_product->get_price_including_tax($quantity, $min_variation_price_raw) / $quantity; $min_variation_price_excl_tax = $min_variation_price_raw; } } } } $this->min_price = $min_variation_regular_price < $min_variation_price ? $min_variation_regular_price : $min_variation_price; $this->min_regular_price = $min_variation_regular_price; $this->max_price = $max_variation_regular_price < $max_variation_price ? $max_variation_regular_price : $max_variation_price; $this->max_regular_price = $max_variation_regular_price; $this->min_price_excl_tax = $min_variation_price_excl_tax; $this->min_price_incl_tax = $min_variation_price_incl_tax; } $this->remove_price_filters(); }
/** * Initialize composited product price data, if needed. * * @return void */ public function init() { // Init prices $this->min_price = 0; $this->max_price = 0; $this->min_regular_price = 0; $this->max_regular_price = 0; $this->min_price_incl_tax = 0; $this->min_price_excl_tax = 0; $id = $this->get_product()->id; // Sold individually status. $this->is_sold_individually = get_post_meta($id, '_sold_individually', true); // Purchasable status. if (!$this->per_product_pricing && $this->product->price === '') { $this->product->price = 0; } $this->is_purchasable = $this->product->is_purchasable(); // Calculate product prices. if ($this->per_product_pricing && $this->is_purchasable) { $composited_product = $this->product; $product_type = $composited_product->product_type; $this->is_nyp = false; /*-----------------------------------------------------------------------------------*/ /* Simple Products and Static Bundles. */ /*-----------------------------------------------------------------------------------*/ if ($product_type === 'simple') { $product_price = $this->get_raw_price(); $product_regular_price = $this->get_raw_regular_price(); // Name your price support. if (WC_CP()->compatibility->is_nyp($composited_product)) { $product_price = $product_regular_price = WC_Name_Your_Price_Helpers::get_minimum_price($id) ? WC_Name_Your_Price_Helpers::get_minimum_price($id) : 0; $this->is_nyp = true; } $this->min_price = $this->max_price = $product_price; $this->min_regular_price = $this->max_regular_price = $product_regular_price; /*-----------------------------------------------------------------------------------*/ /* Variable Products. */ /*-----------------------------------------------------------------------------------*/ } elseif ($product_type === 'variable') { if (WC_CP_Core_Compatibility::is_wc_version_gte_2_4()) { $variation_prices = $composited_product->get_variation_prices(false); if (!empty($this->component_data['discount']) && apply_filters('woocommerce_composited_product_discount_from_regular', true, $this->component_id, $this->composite->id)) { $variation_price_ids = array_keys($variation_prices['regular_price']); } else { $variation_price_ids = array_keys($variation_prices['price']); } $min_variation_price_id = current($variation_price_ids); $max_variation_price_id = end($variation_price_ids); } else { if (!empty($this->component_data['discount']) && apply_filters('woocommerce_composited_product_discount_from_regular', true, $this->component_id, $this->composite->id)) { // Product may need to be synced. if ($composited_product->get_variation_regular_price('min', false) === false) { $composited_product->variable_product_sync(); } $min_variation_price_id = get_post_meta($this->product->id, '_min_regular_price_variation_id', true); $max_variation_price_id = get_post_meta($this->product->id, '_max_regular_price_variation_id', true); } else { // Product may need to be synced. if ($composited_product->get_variation_price('min', false) === false) { $composited_product->variable_product_sync(); } $min_variation_price_id = get_post_meta($this->product->id, '_min_price_variation_id', true); $max_variation_price_id = get_post_meta($this->product->id, '_max_price_variation_id', true); } } $min_variation = $composited_product->get_child($min_variation_price_id); $max_variation = $composited_product->get_child($max_variation_price_id); if ($min_variation && $max_variation) { $this->min_price_product = $this->min_regular_price_product = $min_variation; $this->max_price_product = $this->min_regular_price_product = $max_variation; $this->min_price = $this->get_raw_price($min_variation); $this->max_price = $this->get_raw_price($max_variation); $min_variation_regular_price = $this->get_raw_regular_price($min_variation); $max_variation_regular_price = $this->get_raw_regular_price($max_variation); // The variation with the lowest price may have a higher regular price then the variation with the highest price. if ($max_variation_regular_price < $min_variation_regular_price) { $this->min_regular_price_product = $max_variation; $this->max_regular_price_product = $min_variation; } $this->min_regular_price = min($min_variation_regular_price, $max_variation_regular_price); $this->max_regular_price = max($min_variation_regular_price, $max_variation_regular_price); } /*-----------------------------------------------------------------------------------*/ /* Other Product Types. */ /*-----------------------------------------------------------------------------------*/ } else { $price = $this->get_raw_price(); $this->min_price = apply_filters('woocommerce_composited_product_min_price', $price, $this); $this->max_price = apply_filters('woocommerce_composited_product_max_price', $price, $this); $regular_price = $this->get_raw_regular_price(); $this->min_regular_price = apply_filters('woocommerce_composited_product_min_regular_price', $regular_price, $this); $this->max_regular_price = apply_filters('woocommerce_composited_product_max_regular_price', $regular_price, $this); $this->is_nyp = apply_filters('woocommerce_composited_product_is_nyp', $this->is_nyp, $this); } } }
public static function column_display($column_name, $post_id) { switch ($column_name) { case 'price': /* Custom inline data for nyp */ $nyp = get_post_meta($post_id, '_nyp', true); $suggested = WC_Name_Your_Price_Helpers::get_suggested_price($post_id); $suggested = wc_format_localized_price($suggested); $min = WC_Name_Your_Price_Helpers::get_minimum_price($post_id); $min = wc_format_localized_price($min); $is_nyp_allowed = has_term(array('simple'), 'product_type', $post_id) ? 'yes' : 'no'; echo ' <div class="hidden" id="nyp_inline_' . $post_id . '"> <div class="nyp">' . $nyp . '</div> <div class="suggested_price">' . $suggested . '</div> <div class="min_price">' . $min . '</div> <div class="is_nyp_allowed">' . $is_nyp_allowed . '</div> </div> '; break; } }
public function validate_add_cart_item($passed, $product_id, $quantity, $variation_id = '', $variations = '') { if ($variation_id) { $product_id = $variation_id; } // skip if not a nyp product - send original status back if (!WC_Name_Your_Price_Helpers::is_nyp($product_id)) { return $passed; } $prefix = apply_filters('nyp_field_prefix', '', $product_id); // get the posted price (can be null string) $input = WC_Name_Your_Price_Helpers::get_posted_price($product_id, $prefix); // get minimum price $minimum = WC_Name_Your_Price_Helpers::get_minimum_price($product_id); // null error message $error_message = ''; // the product title $the_product = wc_nyp_get_product($product_id); $product_title = $the_product->get_title(); // check that it is a positive numeric value if (!is_numeric($input) || is_infinite($input) || floatval($input) < 0) { $passed = false; $error_message = WC_Name_Your_Price_Helpers::error_message('invalid', array('%%TITLE%%' => $product_title)); // check that it is greater than minimum price for variable billing subscriptions } elseif ($minimum && WC_Name_Your_Price_Helpers::is_subscription($product_id) && WC_Name_Your_Price_Helpers::is_billing_period_variable($product_id)) { // get the posted billing period, defaults to 'month' $period = WC_Name_Your_Price_Helpers::get_posted_period($product_id, $prefix); // minimum billing period $minimum_period = WC_Name_Your_Price_Helpers::get_minimum_billing_period($product_id); // annual minimum $minimum_annual = WC_Name_Your_Price_Helpers::annualize_price($minimum, $minimum_period); // annual input $input_annual = WC_Name_Your_Price_Helpers::annualize_price($input, $period); // by standardizing the prices over the course of a year we can safely compare them if ($input_annual < $minimum_annual) { $passed = false; $factors = WC_Name_Your_Price_Helpers::annual_price_factors(); // If set period is in the $factors array we can calc the min price shown in the error according to entered period if (isset($factors[$period])) { $error_price = $minimum_annual / $factors[$period]; $error_period = $period; // otherwise, just show the saved minimum price and period } else { $error_price = $minimum; $error_period = $minimum_period; } // the minimum is a combo of price and period $minimum_error = wc_price($error_price) . ' / ' . $error_period; $error_message = WC_Name_Your_Price_Helpers::error_message('minimum', array('%%TITLE%%' => $product_title, '%%MINIMUM%%' => $minimum_error), $the_product); } // check that it is greater than minimum price } elseif ($minimum && floatval(WC_Name_Your_Price_Helpers::standardize_number($input)) < floatval($minimum)) { $passed = false; $minimum_error = wc_price($minimum); $error_message = WC_Name_Your_Price_Helpers::error_message('minimum', array('%%TITLE%%' => $product_title, '%%MINIMUM%%' => $minimum_error), $the_product); } // show the error message if ($error_message) { wc_add_notice($error_message, 'error'); } return $passed; }
/** * Get the min or max variation (active) price. * * @param string $price * @param string $min_or_max - min or max * @param boolean $display Whether the value is going to be displayed * @return string * @since 2.0 */ public function get_variation_price($price, $product, $min_or_max, $display) { if (WC_Name_Your_Price_Helpers::has_nyp($product)) { $price = get_post_meta($product->id, '_' . $min_or_max . '_variation_price', true); } return $price; }
/** * Include required core files used in admin and on the frontend. * * @return void * @since 1.0 */ public function includes() { // check we're running the required version of WC if (!defined('WC_VERSION') || version_compare(WC_VERSION, $this->required_woo, '<')) { add_action('admin_notices', array($this, 'admin_notice')); return false; } // include all helper functions include_once 'includes/class-wc-name-your-price-helpers.php'; // include admin class to handle all backend functions if (is_admin()) { include_once 'includes/admin/class-name-your-price-admin.php'; } // include the front-end functions if (!is_admin() || defined('DOING_AJAX')) { include_once 'includes/class-wc-name-your-price-display.php'; $this->display = new WC_Name_Your_Price_Display(); include_once 'includes/class-wc-name-your-price-cart.php'; $this->cart = new WC_Name_Your_Price_Cart(); } include_once 'includes/class-wc-name-your-price-compatibility.php'; $this->compatibility = new WC_Name_Your_Price_Compatibility(); // minor backcompat issues if (WC_Name_Your_Price_Helpers::is_woocommerce_2_3()) { include_once 'includes/wc-23-functions.php'; } else { include_once 'includes/wc-21-functions.php'; } }
*/ if (!defined('ABSPATH')) { exit; } // Exit if accessed directly ?> <div class="nyp" <?php echo WC_Name_Your_Price_Helpers::get_data_attributes($product_id, $prefix); ?> > <?php do_action('woocommerce_nyp_before_price_input', $product_id); ?> <label for="nyp"> <?php printf(_x('%s ( %s )', 'In case you need to change the order of Name Your Price ( $currency_symbol )', 'wc_name_your_price'), stripslashes(get_option('woocommerce_nyp_label_text', __('Name Your Price', 'wc_name_your_price'))), get_woocommerce_currency_symbol()); ?> </label> <?php echo WC_Name_Your_Price_Helpers::get_price_input($product_id, $prefix); ?> <?php do_action('woocommerce_nyp_after_price_input', $product_id); ?> </div>
/** * Initialize composited product price data, if needed. * * @return void */ public function init() { global $woocommerce_composite_products; // Init prices $this->min_price = 0; $this->max_price = 0; $this->min_regular_price = 0; $this->max_regular_price = 0; $this->min_price_incl_tax = 0; $this->min_price_excl_tax = 0; $id = $this->get_product()->id; // Sold individually status $this->is_sold_individually = get_post_meta($id, '_sold_individually', true); // Calculate product prices if the parent is priced per product if ($this->per_product_pricing) { $composited_product = $this->product; // Get product type $product_type = $composited_product->product_type; $this->is_nyp = false; $this->purchasable = false; if ($composited_product->is_purchasable()) { $this->purchasable = true; /*-----------------------------------------------------------------------------------*/ /* Simple Products and Static Bundles /*-----------------------------------------------------------------------------------*/ if ($product_type == 'simple' || $product_type == 'bundle' && $composited_product->is_priced_per_product() == false) { $product_price = $composited_product->get_price(); $product_regular_price = $composited_product->get_regular_price(); // Name your price support if ($woocommerce_composite_products->compatibility->is_nyp($composited_product)) { $product_price = $product_regular_price = WC_Name_Your_Price_Helpers::get_minimum_price($id) ? WC_Name_Your_Price_Helpers::get_minimum_price($id) : 0; $this->is_nyp = true; } // Modify prices to respect woocommerce_tax_display_shop setting $product_prices = $woocommerce_composite_products->api->get_composited_item_prices($composited_product, $product_price); $product_regular_prices = $woocommerce_composite_products->api->get_composited_item_prices($composited_product, $product_regular_price); $this->min_price = $this->max_price = $product_prices['shop']; $this->min_regular_price = $this->max_regular_price = $product_regular_prices['shop']; // Incl $this->min_price_incl_tax = $product_prices['incl']; // Excl $this->min_price_excl_tax = $product_prices['excl']; /*-----------------------------------------------------------------------------------*/ /* Per-Item Priced Bundles /*-----------------------------------------------------------------------------------*/ } elseif ($product_type == 'bundle') { $this->min_price = $composited_product->get_min_bundle_price(); $this->max_price = $composited_product->get_max_bundle_price(); $this->min_regular_price = $composited_product->min_bundle_regular_price; $this->max_regular_price = $composited_product->max_bundle_regular_price; if ($composited_product->is_nyp() || $composited_product->contains_nyp()) { $this->is_nyp = true; } // Incl $this->min_price_incl_tax = $composited_product->get_min_bundle_price_incl_tax(); // Excl $this->min_price_excl_tax = $composited_product->get_min_bundle_price_excl_tax(); /*-----------------------------------------------------------------------------------*/ /* Variable Products /*-----------------------------------------------------------------------------------*/ } elseif ($product_type == 'variable') { if (!empty($this->component_data['discount'])) { // Product may need to be synced if ($composited_product->get_variation_regular_price('min', false) === false) { $composited_product->variable_product_sync(); } // Grab the min/max regular price variation since discounts are calculated on top of the regular price only. $min_variation_id = get_post_meta($composited_product->id, '_min_regular_price_variation_id', true); $min_variation = $composited_product->get_child($min_variation_id); $min_variation_regular_price = $min_variation->get_regular_price(); $min_variation_price = $min_variation->get_price(); $max_variation_id = get_post_meta($composited_product->id, '_max_regular_price_variation_id', true); $max_variation = $composited_product->get_child($max_variation_id); $max_variation_regular_price = $max_variation->get_regular_price(); $max_variation_price = $max_variation->get_price(); } else { // Product may need to be synced if ($composited_product->get_variation_price('min', false) === false) { $composited_product->variable_product_sync(); } // Grab the min/max price variation since there is no discount. $min_variation_id = get_post_meta($composited_product->id, '_min_price_variation_id', true); $min_variation = $composited_product->get_child($min_variation_id); $min_variation_regular_price = $min_variation->get_regular_price(); $min_variation_price = $min_variation->get_price(); $max_variation_id = get_post_meta($composited_product->id, '_max_price_variation_id', true); $max_variation = $composited_product->get_child($max_variation_id); $max_variation_regular_price = $max_variation->get_regular_price(); $max_variation_price = $max_variation->get_price(); } // Modify prices to respect woocommerce_tax_display_shop setting $min_variation_regular_prices = $woocommerce_composite_products->api->get_composited_item_prices($min_variation, $min_variation_regular_price); $min_variation_prices = $woocommerce_composite_products->api->get_composited_item_prices($min_variation, $min_variation_price); $max_variation_regular_prices = $woocommerce_composite_products->api->get_composited_item_prices($max_variation, $max_variation_regular_price); $max_variation_prices = $woocommerce_composite_products->api->get_composited_item_prices($max_variation, $max_variation_price); $this->min_regular_price = $min_variation_regular_prices['shop']; $this->min_price = $min_variation_prices['shop']; $this->max_regular_price = $max_variation_regular_prices['shop']; $this->max_price = $max_variation_prices['shop']; // Incl $this->min_price_incl_tax = $min_variation_prices['incl']; // Excl $this->min_price_incl_tax = $min_variation_prices['excl']; /*-----------------------------------------------------------------------------------*/ /* Other Product Types /*-----------------------------------------------------------------------------------*/ } else { // Make sure these are incl / excl tax depending on shop settings // If necessary, use 'woocommerce_composite_products->api->get_composited_item_prices' $this->min_price = apply_filters('woocommerce_composited_product_min_price', $this->min_price, $this); $this->max_price = apply_filters('woocommerce_composited_product_max_price', $this->max_price, $this); $this->min_regular_price = apply_filters('woocommerce_composited_product_min_regular_price', $this->min_regular_price, $this); $this->max_regular_price = apply_filters('woocommerce_composited_product_max_regular_price', $this->max_regular_price, $this); // Prices incl or excl tax, regardless of shop settings $this->min_price_incl_tax = apply_filters('woocommerce_composited_product_min_price_incl_tax', $this->min_price_incl_tax, $this); $this->min_price_excl_tax = apply_filters('woocommerce_composited_product_min_price_excl_tax', $this->min_price_excl_tax, $this); } } } }
public static function variable_product_sync($product_id, $children) { if ($children) { $min_price = null; $max_price = null; $min_price_id = null; $max_price_id = null; // Main active prices $min_price = null; $max_price = null; $min_price_id = null; $max_price_id = null; // Regular prices $min_regular_price = null; $max_regular_price = null; $min_regular_price_id = null; $max_regular_price_id = null; // Sale prices $min_sale_price = null; $max_sale_price = null; $min_sale_price_id = null; $max_sale_price_id = null; foreach (array('price', 'regular_price', 'sale_price') as $price_type) { foreach ($children as $child_id) { // if NYP if (WC_Name_Your_Price_Helpers::is_nyp($child_id)) { // Skip hidden variations if ('yes' === get_option('woocommerce_hide_out_of_stock_items')) { $stock = get_post_meta($child_id, '_stock', true); if ($stock !== "" && $stock <= get_option('woocommerce_notify_no_stock_amount')) { continue; } } // get the nyp min price for this variation $child_price = get_post_meta($child_id, '_min_price', true); // if there is no set minimum, technically the min is 0 $child_price = $child_price ? $child_price : 0; // Find min price if (is_null(${"min_{$price_type}"}) || $child_price < ${"min_{$price_type}"}) { ${"min_{$price_type}"} = $child_price; ${"min_{$price_type}_id"} = $child_id; } // Find max price if (is_null(${"max_{$price_type}"}) || $child_price > ${"max_{$price_type}"}) { ${"max_{$price_type}"} = $child_price; ${"max_{$price_type}_id"} = $child_id; } } else { $child_price = get_post_meta($child_id, '_' . $price_type, true); // Skip non-priced variations if ($child_price === '') { continue; } // Skip hidden variations if ('yes' === get_option('woocommerce_hide_out_of_stock_items')) { $stock = get_post_meta($child_id, '_stock', true); if ($stock !== "" && $stock <= get_option('woocommerce_notify_no_stock_amount')) { continue; } } // Find min price if (is_null(${"min_{$price_type}"}) || $child_price < ${"min_{$price_type}"}) { ${"min_{$price_type}"} = $child_price; ${"min_{$price_type}_id"} = $child_id; } // Find max price if ($child_price > ${"max_{$price_type}"}) { ${"max_{$price_type}"} = $child_price; ${"max_{$price_type}_id"} = $child_id; } } } // Store prices update_post_meta($product_id, '_min_variation_' . $price_type, ${"min_{$price_type}"}); update_post_meta($product_id, '_max_variation_' . $price_type, ${"max_{$price_type}"}); // Store ids update_post_meta($product_id, '_min_' . $price_type . '_variation_id', ${"min_{$price_type}_id"}); update_post_meta($product_id, '_max_' . $price_type . '_variation_id', ${"max_{$price_type}_id"}); } // The VARIABLE PRODUCT price should equal the min price of any type update_post_meta($product_id, '_price', $min_price); wc_delete_product_transients($product_id); } }
<?php /** * Minimum Price Template * * @author Kathy Darling * @package WC_Name_Your_Price/Templates * @version 2.0 */ if (!defined('ABSPATH')) { exit; } // Exit if accessed directly ?> <p class="minimum-price"><?php echo WC_Name_Your_Price_Helpers::get_minimum_price_html($product_id); ?> </p>
/** * Initializes a bundled item for access by the container: Calculates min and max prices, checks availability info, etc. * * @return void */ public function init() { $product_id = $this->product_id; $bundled_product = $this->product; $quantity = $this->get_quantity(); $discount = $this->get_discount(); /*------------------------------*/ /* Simple Subs */ /*------------------------------*/ if ($bundled_product->product_type === 'subscription') { if ($this->is_front_end) { if ($bundled_product->is_sold_individually()) { $this->sold_individually = true; } if (!$bundled_product->is_in_stock() || !$bundled_product->has_enough_stock($quantity)) { $this->stock_status = 'out-of-stock'; } if ($bundled_product->is_on_backorder() && $bundled_product->backorders_require_notification()) { $this->stock_status = 'available-on-backorder'; } $this->total_stock = $bundled_product->get_total_stock(); } if ($this->is_priced_per_product()) { // Recurring price. $regular_recurring_fee = $this->get_bundled_product_regular_price(); $recurring_fee = $this->get_bundled_product_price(); $this->min_regular_recurring_price = $this->max_regular_recurring_price = $regular_recurring_fee; $this->min_recurring_price = $this->max_recurring_price = $recurring_fee; if ($regular_recurring_fee > $recurring_fee) { $this->on_sale = true; } // Sign up price. $regular_signup_fee = $bundled_product->get_sign_up_fee(); $signup_fee = $this->get_sign_up_fee($regular_signup_fee, $bundled_product); $regular_up_front_fee = $this->get_prorated_price_for_subscription($regular_recurring_fee, $regular_signup_fee, $bundled_product); $up_front_fee = $this->get_prorated_price_for_subscription($recurring_fee, $signup_fee, $bundled_product); $this->min_regular_price = $this->max_regular_price = $regular_up_front_fee; $this->min_price = $this->max_price = $up_front_fee; if ($regular_up_front_fee > $up_front_fee) { $this->on_sale = true; } } /*-----------------------------------*/ /* Simple Products */ /*-----------------------------------*/ } elseif ($bundled_product->product_type === 'simple') { if ($this->is_front_end) { if ($bundled_product->is_sold_individually()) { $this->sold_individually = true; } if (!$bundled_product->is_in_stock() || !$bundled_product->has_enough_stock($quantity)) { $this->stock_status = 'out-of-stock'; } if ($bundled_product->is_on_backorder() && $bundled_product->backorders_require_notification()) { $this->stock_status = 'available-on-backorder'; } $this->total_stock = $bundled_product->get_total_stock(); } if ($this->is_priced_per_product()) { $regular_price = $this->get_bundled_product_regular_price(); $price = $this->get_bundled_product_price(); // Name your price support. if (WC_PB()->compatibility->is_nyp($bundled_product)) { $regular_price = $price = WC_Name_Your_Price_Helpers::get_minimum_price($product_id) ? WC_Name_Your_Price_Helpers::get_minimum_price($product_id) : 0; $this->nyp = true; } $this->min_regular_price = $this->max_regular_price = $regular_price; $this->min_price = $this->max_price = $price; if ($regular_price > $price) { $this->on_sale = true; } } /*-------------------------------------------*/ /* Variable Products */ /*-------------------------------------------*/ } elseif ($bundled_product->product_type === 'variable' || $bundled_product->product_type === 'variable-subscription') { $calc_prices = $this->is_priced_per_product(); $min_variation = $max_variation = false; if ($bundled_product->is_sold_individually()) { $this->sold_individually = true; } // Without any variation filters present, we can just rely on parent methods. if (empty($this->allowed_variations)) { if ($this->is_front_end) { $this->total_stock = $bundled_product->get_total_stock(); if (!$bundled_product->is_in_stock() || !$bundled_product->backorders_allowed() && $bundled_product->managing_stock() && $this->total_stock < $quantity) { $this->stock_status = 'out-of-stock'; } else { $variation_in_stock_exists = false; foreach ($bundled_product->get_children(true) as $child_id) { if ('yes' === get_post_meta($child_id, '_manage_stock', true)) { $stock = get_post_meta($child_id, '_stock', true); if ($stock >= $quantity) { $variation_in_stock_exists = true; break; } } else { $variation_in_stock_exists = true; break; } } if (!$variation_in_stock_exists) { $this->stock_status = 'out-of-stock'; } } if ($bundled_product->is_on_backorder() && $bundled_product->backorders_require_notification()) { $this->stock_status = 'available-on-backorder'; } } if ($calc_prices) { if ($bundled_product->product_type === 'variable-subscription') { if (!isset($bundled_product->subscription_period) || !isset($bundled_product->subscription_period_interval) || !isset($bundled_product->max_variation_period) || !isset($bundled_product->max_variation_period_interval)) { $bundled_product->variable_product_sync(); } $min_variation_price_id = get_post_meta($bundled_product->id, '_min_price_variation_id', true); $max_variation_price_id = get_post_meta($bundled_product->id, '_max_price_variation_id', true); } else { if (WC_PB_Core_Compatibility::is_wc_version_gte_2_4()) { $variation_prices = $bundled_product->get_variation_prices(false); if (!empty($discount) && apply_filters('woocommerce_bundled_item_discount_from_regular', true, $this)) { $variation_price_ids = array_keys($variation_prices['regular_price']); } else { $variation_price_ids = array_keys($variation_prices['price']); } $min_variation_price_id = current($variation_price_ids); $max_variation_price_id = end($variation_price_ids); } else { if (!empty($discount) && apply_filters('woocommerce_bundled_item_discount_from_regular', true, $this)) { // Product may need to be synced. if ($bundled_product->get_variation_regular_price('min', false) === false) { $bundled_product->variable_product_sync(); } $min_variation_price_id = get_post_meta($this->product_id, '_min_regular_price_variation_id', true); $max_variation_price_id = get_post_meta($this->product_id, '_max_regular_price_variation_id', true); } else { // Product may need to be synced. if ($bundled_product->get_variation_price('min', false) === false) { $bundled_product->variable_product_sync(); } $min_variation_price_id = get_post_meta($this->product_id, '_min_price_variation_id', true); $max_variation_price_id = get_post_meta($this->product_id, '_max_price_variation_id', true); } } } $min_variation = $bundled_product->get_child($min_variation_price_id); $max_variation = $bundled_product->get_child($max_variation_price_id); } // When variation filters are present, we need to iterate over the variations. } else { $variation_in_stock_exists = $this->is_front_end ? false : true; $all_variations_on_backorder = $this->is_front_end ? true : false; $min_variation_price = ''; $max_variation_price = ''; $this->total_stock = max(0, wc_stock_amount($bundled_product->stock)); foreach ($bundled_product->get_children(true) as $child_id) { // Do not continue if variation is filtered. if (is_array($this->allowed_variations) && !in_array($child_id, $this->allowed_variations)) { continue; } $variation = $bundled_product->get_child($child_id); if (!$variation) { continue; } // Stock status. if (!$variation_in_stock_exists) { if ($variation->is_in_stock() && $variation->has_enough_stock($quantity)) { $variation_in_stock_exists = true; } } // Total stock. if ($variation->managing_stock()) { $this->total_stock += max(0, wc_stock_amount($variation->stock)); } // Backorder. if ($all_variations_on_backorder) { if ($bundled_product->backorders_allowed() && $bundled_product->backorders_require_notification()) { if (!$variation->is_on_backorder()) { $all_variations_on_backorder = false; } } else { $all_variations_on_backorder = false; } } // Prices. if ($calc_prices) { if (!empty($discount) && apply_filters('woocommerce_bundled_item_discount_from_regular', true, $this)) { // Lowest price. if ('' === $min_variation_price || $variation->regular_price < $min_variation_price) { $min_variation_price = $variation->regular_price; $min_variation = $variation; } // Highest price. if ('' === $max_variation_price || $variation->regular_price > $max_variation_price) { $max_variation_price = $variation->regular_price; $max_variation = $variation; } } else { // Lowest price. if ('' === $min_variation_price || $variation->price < $min_variation_price) { $min_variation_price = $variation->price; $min_variation = $variation; } // Highest price. if ('' === $max_variation_price || $variation->price > $max_variation_price) { $max_variation_price = $variation->price; $max_variation = $variation; } } } } if (!$variation_in_stock_exists) { $this->stock_status = 'out-of-stock'; } if ($all_variations_on_backorder) { $this->stock_status = 'available-on-backorder'; } } if ($min_variation && $max_variation) { $this->min_price_product = $this->min_regular_price_product = $min_variation; $this->max_price_product = $this->min_regular_price_product = $max_variation; if ($bundled_product->product_type === 'variable-subscription') { $this->min_recurring_price = $this->max_recurring_price = $this->get_bundled_product_price($min_variation); $this->min_regular_recurring_price = $this->max_regular_recurring_price = $this->get_bundled_product_regular_price($min_variation); $min_regular_signup_fee = $min_variation->get_sign_up_fee(); $min_signup_fee = $this->get_sign_up_fee($min_regular_signup_fee, $min_variation); $min_regular_up_front_fee = $this->get_prorated_price_for_subscription($this->min_regular_recurring_price, $min_regular_signup_fee, $min_variation); $min_up_front_fee = $this->get_prorated_price_for_subscription($this->min_recurring_price, $min_signup_fee, $min_variation); $this->min_regular_price = $this->max_regular_price = $min_regular_up_front_fee; $this->min_price = $this->max_price = $min_up_front_fee; } else { $this->min_price = $this->get_bundled_product_price($min_variation); $this->max_price = $this->get_bundled_product_price($max_variation); $min_variation_regular_price = $this->get_bundled_product_regular_price($min_variation); $max_variation_regular_price = $this->get_bundled_product_regular_price($max_variation); // The variation with the lowest price may have a higher regular price then the variation with the highest price. if ($max_variation_regular_price < $min_variation_regular_price) { $this->min_regular_price_product = $max_variation; $this->max_regular_price_product = $min_variation; } $this->min_regular_price = min($min_variation_regular_price, $max_variation_regular_price); $this->max_regular_price = max($min_variation_regular_price, $max_variation_regular_price); } if ($this->min_regular_price > $this->min_price) { $this->on_sale = true; } } } }