public function check_is_valid_rule() { if (isset($this->set_data['collector']['args'])) { if (WC_Dynamic_Pricing_Counter::categories_in_cart($this->set_data['collector']['args']['cats']) || WC_Dynamic_Pricing_Counter::categories_in_cart($this->targets)) { $this->is_valid_rule = true; } } }
public function adjust_cart($temp_cart) { if ($this->adjustment_sets && count($this->adjustment_sets)) { $valid_sets = wp_list_filter($this->adjustment_sets, array('is_valid_rule' => true, 'is_valid_for_user' => true)); if (empty($valid_sets)) { return; } foreach ($temp_cart as $cart_item_key => $values) { $temp_cart[$cart_item_key] = $values; $temp_cart[$cart_item_key]['available_quantity'] = $values['quantity']; } //Process block discounts first foreach ($valid_sets as $set_id => $set) { if ($set->mode != 'block') { continue; } //check if this set is valid for the current user; $is_valid_for_user = $set->is_valid_for_user(); if (!$is_valid_for_user) { continue; } //Lets actuall process the rule. //Setup the matching quantity $targets = $set->targets; $collector = $set->get_collector(); $q = 0; if (isset($collector['args']) && isset($collector['args']['cats']) && is_array($collector['args']['cats'])) { foreach ($collector['args']['cats'] as $cat_id) { $q += WC_Dynamic_Pricing_Counter::get_category_count($cat_id); } } else { continue; //no categories } $rule = reset($set->pricing_rules); //block rules can only have one line item. if ($q < $rule['from']) { //continue; } if ($rule['repeating'] == 'yes') { $b = floor($q / $rule['from']); //blocks - this is how many times has the required amount been met. } else { $b = 1; } $ct = 0; //clean targets $mt = 0; $cq = 0; //matched clean quantity; $mq = 0; //matched mixed quantity; foreach ($temp_cart as $cart_item_key => &$cart_item) { $terms = wp_get_post_terms($cart_item['product_id'], 'product_cat', array('fields' => 'ids')); if (count(array_intersect($collector['args']['cats'], $terms)) > 0) { if (count(array_intersect($targets, $terms)) > 0) { $mq += $cart_item['available_quantity']; } else { $cq += $cart_item['available_quantity']; } } if (count(array_intersect($targets, $terms)) > 0) { if (count(array_intersect($collector['args']['cats'], $terms)) == 0) { $ct += $cart_item['quantity']; } else { $mt += $cart_item['quantity']; } } } $rt = $ct + $mt; //remaining targets. $rcq = $cq; //remaining clean quantity $rmq = $mq; //remaining mixed quantity $tt = 0; //the total number of items we can discount. //for each block reduce the amount of remaining items which can make up a discount by the amount required. if ($rcq || $rmq) { for ($x = 0; $x < $b; $x++) { //If the remaining clean quantity minus what is required to make a block is greater than 0 there are more clean quantity items remaining. //This means we don't have to eat into mixed quantities yet. if ($rcq - $rule['from'] >= 0) { $rcq -= $rule['from']; $tt += $rule['adjust']; //If the total items that can be dicsounted is greater than the number of clean items to be discounted, reduce the //mixed quantity by the difference, because those items will be discounted and can not count towards making another discounted item. if ($tt > $ct) { $rmq -= $tt - $ct; } if ($tt > $mt + $ct) { $tt = $mt + $ct; } $rt -= $ct + $mt - $tt; } else { //how many items left over from clean quantities. if we have a buy two get one free, we may have one quantity of clean item, and two mixed items. $l = $rcq ? $rule['from'] - $rcq : 0; if ($rcq > 0) { //If the remaining mixed quantity minus the left overs trigger items is more than 0, we have another discount available if ($rt - $l > 0) { $tt += min($rt - $l, $rule['adjust']); } $rt -= $ct + $mt - $tt; } elseif ($rmq > 0) { $rt -= $rule['from']; //$rt -= ($ct + $mt) - $tt; if ($rt > 0) { $tt += min($rt, $rule['adjust']); $rt -= min($rt, $rule['adjust']); $rmq = $rmq - $l - ($rule['adjust'] + $rule['from']); } } $rcq = 0; } } foreach ($temp_cart as $cart_item_key => $ctitem) { $price_adjusted = false; $original_price = $this->get_price_to_discount($ctitem, $cart_item_key); //Check if the original price is free, we don't want to apply any of these discounts, or use any of them up by //applying a discount to a free item. $op_check = floatval($original_price); if (empty($op_check) && $rule['type'] != 'fixed_adjustment') { continue; } $terms = wp_get_post_terms($ctitem['product_id'], 'product_cat', array('fields' => 'ids')); if (count(array_intersect($targets, $terms)) > 0) { $price_adjusted = $this->get_block_adjusted_price($ctitem, $original_price, $rule, $tt); if ($tt > $ctitem['quantity']) { $tt -= $ctitem['quantity']; $temp_cart[$cart_item_key]['available_quantity'] = 0; } else { $temp_cart[$cart_item_key]['available_quantity'] = $ctitem['quantity'] - $tt; $tt = 0; } if ($price_adjusted !== false && floatval($original_price) != floatval($price_adjusted)) { WC_Dynamic_Pricing::apply_cart_item_adjustment($cart_item_key, $original_price, $price_adjusted, 'advanced_category', $set_id); } } } } } //Now process bulk rules foreach ($valid_sets as $set_id => $set) { if ($set->mode != 'bulk') { continue; } //check if this set is valid for the current user; $is_valid_for_user = $set->is_valid_for_user(); if (!$is_valid_for_user) { continue; } //Lets actuall process the rule. //Setup the matching quantity $targets = $set->targets; //Get the quantity to compare $collector = $set->get_collector(); $q = 0; foreach ($temp_cart as $t_cart_item_key => $t_cart_item) { $process_discounts = apply_filters('woocommerce_dynamic_pricing_process_product_discounts', true, $t_cart_item['data'], 'advanced_category', $this, $t_cart_item); if (!$process_discounts) { continue; } $terms = wp_get_post_terms($t_cart_item['product_id'], 'product_cat', array('fields' => 'ids')); if (count(array_intersect($targets, $terms)) > 0) { if (!$this->is_cumulative($t_cart_item, $t_cart_item_key)) { if ($this->is_item_discounted($t_cart_item, $t_cart_item_key)) { continue; } } if (isset($collector['type']) && $collector['type'] == 'cat_product') { $q = $t_cart_item['quantity']; } else { $q = 0; if (isset($collector['args']) && isset($collector['args']['cats']) && is_array($collector['args']['cats'])) { foreach ($temp_cart as $lck => $l_cart_item) { if (is_object_in_term($l_cart_item['product_id'], 'product_cat', $collector['args']['cats'])) { if (apply_filters('woocommerce_dynamic_pricing_count_categories_for_cart_item', true, $l_cart_item, $lck)) { $q += (int) $l_cart_item['quantity']; } } } } } $price_adjusted = false; $original_price = $this->get_price_to_discount($t_cart_item, $t_cart_item_key); if (is_array($set->pricing_rules) && sizeof($set->pricing_rules) > 0) { foreach ($set->pricing_rules as $rule) { $price_adjusted = $this->get_bulk_adjusted_price($t_cart_item, $original_price, $rule, $q); if ($price_adjusted !== false) { break; } } } if ($price_adjusted !== false && floatval($original_price) != floatval($price_adjusted)) { WC_Dynamic_Pricing::apply_cart_item_adjustment($t_cart_item_key, $original_price, $price_adjusted, 'advanced_category', $set_id); } } } } } }
public static function register() { if (self::$instance == null) { self::$instance = new WC_Dynamic_Pricing_Counter(); } }
protected function get_quantity_to_compare($cart_item, $collector) { global $woocommerce_pricing, $woocommerce; $quantity = 0; switch ($collector['type']) { case 'cart_item': $quantity = $cart_item['quantity']; break; case 'cat': if (isset($collector['args']) && isset($collector['args']['cats']) && is_array($collector['args']['cats'])) { $quantity = 0; if (isset($collector['args']) && isset($collector['args']['cats']) && is_array($collector['args']['cats'])) { $temp_cart = WC_Dynamic_Pricing_Compatibility::WC()->cart->cart_contents; foreach ($temp_cart as $lck => $cart_item) { if (is_object_in_term($cart_item['product_id'], 'product_cat', $collector['args']['cats'])) { if (apply_filters('woocommerce_dynamic_pricing_count_categories_for_cart_item', true, $cart_item, $lck)) { $quantity += (int) $cart_item['quantity']; } } } } } break; case 'product': if (WC_Dynamic_Pricing_Counter::get_product_count($cart_item['product_id'])) { $quantity += WC_Dynamic_Pricing_Counter::get_product_count($cart_item['product_id']); } break; case 'variation': if (WC_Dynamic_Pricing_Counter::get_variation_count($cart_item['variation_id'])) { $quantity += WC_Dynamic_Pricing_Counter::get_variation_count($cart_item['variation_id']); } break; } return $quantity; }
public function __construct() { add_action('woocommerce_cart_loaded_from_session', array(&$this, 'on_cart_loaded_from_session'), 99, 1); //Add the actions dynamic pricing uses to trigger price adjustments add_action('woocommerce_before_calculate_totals', array(&$this, 'on_calculate_totals'), 99, 1); if (is_admin()) { require 'admin/admin-init.php'; } //Include additional integrations if (wc_dynamic_pricing_is_groups_active()) { include 'integrations/groups/groups.php'; } //Paypal express include 'integrations/paypal-express.php'; include 'classes/class-wc-dynamic-pricing-compatibility.php'; if (!is_admin() || defined('DOING_AJAX')) { //Include helper classes include 'classes/class-wc-dynamic-pricing-counter.php'; include 'classes/class-wc-dynamic-pricing-tracker.php'; include 'classes/class-wc-dynamic-pricing-cart-query.php'; include 'classes/class-wc-dynamic-pricing-adjustment-set.php'; include 'classes/class-wc-dynamic-pricing-adjustment-set-category.php'; include 'classes/class-wc-dynamic-pricing-adjustment-set-product.php'; include 'classes/class-wc-dynamic-pricing-adjustment-set-totals.php'; //The base pricing module. include 'classes/modules/class-wc-dynamic-pricing-module-base.php'; //Include the advanced pricing modules. include 'classes/modules/class-wc-dynamic-pricing-advanced-base.php'; include 'classes/modules/class-wc-dynamic-pricing-advanced-product.php'; include 'classes/modules/class-wc-dynamic-pricing-advanced-category.php'; include 'classes/modules/class-wc-dynamic-pricing-advanced-totals.php'; //Include the simple pricing modules. include 'classes/modules/class-wc-dynamic-pricing-simple-base.php'; include 'classes/modules/class-wc-dynamic-pricing-simple-product.php'; include 'classes/modules/class-wc-dynamic-pricing-simple-category.php'; include 'classes/modules/class-wc-dynamic-pricing-simple-membership.php'; //Include the UX module - This controls the display of discounts on cart items and products. include 'classes/class-wc-dynamic-pricing-frontend-ux.php'; //Boot up the instances of the pricing modules $modules['advanced_product'] = WC_Dynamic_Pricing_Advanced_Product::instance(); $modules['advanced_category'] = WC_Dynamic_Pricing_Advanced_Category::instance(); $modules['simple_product'] = WC_Dynamic_Pricing_Simple_Product::instance(); $modules['simple_category'] = WC_Dynamic_Pricing_Simple_Category::instance(); $modules['simple_membership'] = WC_Dynamic_Pricing_Simple_Membership::instance(); if (wc_dynamic_pricing_is_groups_active()) { include 'integrations/groups/class-wc-dynamic-pricing-simple-group.php'; $modules['simple_group'] = WC_Dynamic_Pricing_Simple_Group::instance(); } $modules['advanced_totals'] = WC_Dynamic_Pricing_Advanced_Totals::instance(); $this->modules = apply_filters('wc_dynamic_pricing_load_modules', $modules); /* Boot up required classes */ //Initialize the dynamic pricing counter. Records various counts when items are restored from session. WC_Dynamic_Pricing_Counter::register(); //Initialize the FrontEnd UX modifications WC_Dynamic_Pricing_FrontEnd_UX::init(); //Filters for simple adjustment types //add_filter( 'woocommerce_grouped_price_html', array(&$this, 'on_price_html'), 10, 2 ); //add_filter( 'woocommerce_sale_price_html', array(&$this, 'on_price_html'), 10, 2 ); //add_filter( 'woocommerce_price_html', array(&$this, 'on_price_html'), 10, 2 ); //add_filter( 'woocommerce_empty_price_html', array(&$this, 'on_price_html'), 10, 2 ); //Dont think the following filter is required, because regular get price filter is also called. //add_filter( 'woocommerce_variable_price_html', array($this, 'on_price_html'), 10, 2 ); //add_filter( 'woocommerce_variable_sale_price_html', array($this, 'on_price_html'), 10, 2 ); //Filters the variation price displayed when a variation is selected. add_filter('woocommerce_variation_price_html', array(&$this, 'on_price_html'), 10, 2); //add_filter( 'woocommerce_variation_sale_price_html', array(&$this, 'on_price_html'), 10, 2 ); add_filter('woocommerce_get_variation_price', array($this, 'on_get_variation_price'), 10, 4); add_filter('woocommerce_get_price_html', array(&$this, 'on_price_html'), 10, 2); add_filter('woocommerce_get_price', array($this, 'on_get_price'), 10, 2); } add_filter('woocommerce_dynamic_pricing_get_rule_amount', array($this, 'convert_decimals'), 99, 4); }