'title' => $rule->getTitle(),
'type' => $rule_type,
'discount' => $discount,
];
}
}
return $applied_rule_discounts;
}
/**
* Get applied discount details form cart discount details.
*/
private static function getAppliedRuleDiscountsFromCartDiscountDetails($cart_discount_details, $product_id = 0)
{
$applied_rule_discounts = [];
if (is_array($cart_discount_details)) {
foreach ($cart_discount_details as $rule_id => $details) {
if (!isset(self::$available_rules[$rule_id])) { continue; }
$rule = self::$available_rules[$rule_id];
$rule_type = substr($rule->getRuleDiscountType(), 4); // without prefix (wdr_)
$discount = [
'applied_in' => 'cart_level',
'discount_type' => isset($details['cart_discount_type']) ? $details['cart_discount_type'] : '',
'discount_value' => isset($details['cart_discount']) ? round($details['cart_discount']) : 0,
'discount_label' => isset($details['cart_discount_label']) ? $details['cart_discount_label'] : '',
'discount_price' => isset($details['cart_discount_product_price'][$product_id][$rule_id])
? round($details['cart_discount_product_price'][$product_id][$rule_id], 4)
: 0,
];
$applied_rule_discounts[] = [
'id' => $rule_id,
'title' => $rule->getTitle(),
'type' => $rule_type,
'discount' => $discount,
];
}
}
return $applied_rule_discounts;
}
/**
* Calculate the product's initial and discount price
* @param $product
* @param $quantity
* @param $is_cart
* @param $ajax_price
* @return array|bool
*/
static function calculateInitialAndDiscountedPrice($product, $quantity, $is_cart = false, $ajax_price = false, $cart_item = array(), $on_coupon_validate = false)
{
return self::$calculator->getProductPriceToDisplay($product, $quantity, $is_cart, $ajax_price, $cart_item, $on_coupon_validate);
}
/**
* Re-calculate cart total
* */
public static function reCalculateCartTotal()
{
if (function_exists('WC')) {
if(isset(WC()->cart) && WC()->cart != null){
if (is_object(WC()->cart) && method_exists(WC()->cart, 'calculate_totals')) {
WC()->cart->calculate_totals();
}
}
}
}
/**
* Calculate cart totals if is not calculated already
* */
public static function calculateCartTotalIfIsNotCalculated()
{
if (!did_action('woocommerce_before_calculate_totals')) {
self::reCalculateCartTotal();
}
}
/**
* @param $discount_details
* @param $initial_price
* @param $discounted_price
* @param $product_obj
* @param $price_html
* @param $cart_item_qty
* @param $ajax_price
* @return bool|string
*/
function getSetDiscountItemPriceHtml($discount_details, $initial_price, $discounted_price, $product_obj, $price_html, $cart_item_qty=0, $ajax_price = false)
{
if (is_array($discount_details) && !empty($discount_details)) {
$bogo_cheapest_aditional = array();
$calculator = self::$calculator;
$other_discounts = $total_discount_price = $total_quantity = $current_product_quantity = $discount_operator = $bogo_cheapest_aditional_sum = 0;
$partially_qualified_set = array();
$partially_qualified_set_amount_duplicate = array();
$apply_full_set = false;
$int_increment = 0;
foreach ($discount_details as $detail_key => $detail) {
$bogo_cheapest_discount = $bogo_cheapest_quantity = 0;
//BOGO cheapest discount
$bogo_cheap_in_cart = isset($detail['buy_x_get_y_cheapest_in_cart_discount']) ? $detail['buy_x_get_y_cheapest_in_cart_discount'] : '';
$bogo_cheap_in_products = isset($detail['buy_x_get_y_cheapest_from_products_discount']) ? $detail['buy_x_get_y_cheapest_from_products_discount'] : '';
$bogo_cheap_in_category = isset($detail['buy_x_get_y_cheapest_from_categories_discount']) ? $detail['buy_x_get_y_cheapest_from_categories_discount'] : '';
$bogo_auto_add = isset($detail['buy_x_get_y_discount']) ? $detail['buy_x_get_y_discount'] : '';
$bogo_getx = isset($detail['buy_x_get_x_discount']) ? $detail['buy_x_get_x_discount'] : '';
$buy_x_get_y_cheapest_additional = isset($detail['buy_x_get_y_cheapest_in_cart_discount']['additional_discounts']) ? $detail['buy_x_get_y_cheapest_in_cart_discount']['additional_discounts'] : '';
if(!empty($buy_x_get_y_cheapest_additional)){
$all_matched_rule = self::$config->getConfig('apply_product_discount_to', 'biggest_discount');//all
foreach ($buy_x_get_y_cheapest_additional as $aditional){
if($all_matched_rule != 'all' && $price_html){
$price_html = $this->buy_x_get_y_cheapest_additional_strike_out($product_obj, $bogo_cheap_in_cart, $initial_price, $cart_item_qty);
if(!empty($price_html)){
return $price_html;
}
}
$bogo_cheapest_discount_aditional = isset($aditional['discount_price_per_quantity']) ? $aditional['discount_price_per_quantity'] : 0;
$bogo_cheapest_quantity_aditional = isset($aditional['discount_quantity']) ? $aditional['discount_quantity'] : 0;
$bogo_cheapest_aditional[] = $bogo_cheapest_discount_aditional*$bogo_cheapest_quantity_aditional;
}
if($all_matched_rule == 'all' && !empty($cart_item_qty)){
$bogo_cheapest_discount_extra = isset($bogo_cheap_in_cart['discount_price_per_quantity']) ? $bogo_cheap_in_cart['discount_price_per_quantity'] : 0;
$bogo_cheapest_quantity_extra = isset($bogo_cheap_in_cart['discount_quantity']) ? $bogo_cheap_in_cart['discount_quantity'] : 0;
$bogo_cheapest_aditional_discount = array_sum($bogo_cheapest_aditional);
if($bogo_cheapest_quantity_extra > 1){
$bogo_cheapest_quantity_extra = (int)$bogo_cheapest_quantity_extra - 1;
$bogo_cheapest_aditional_discount += $bogo_cheapest_discount_extra*$bogo_cheapest_quantity_extra;
}
if($cart_item_qty != 0){
$bogo_cheapest_aditional_discount = $bogo_cheapest_aditional_discount / $cart_item_qty;
}
$discounted_price = $discounted_price-$bogo_cheapest_aditional_discount;
$bogo_cheap_in_cart = array();
}else{
$bogo_cheapest_aditional_sum = array_sum($bogo_cheapest_aditional);
}
}
if(!empty($bogo_cheap_in_cart)){
$bogo_cheapest_discount = isset($bogo_cheap_in_cart['discount_price_per_quantity']) ? $bogo_cheap_in_cart['discount_price_per_quantity'] : 0;
$bogo_cheapest_quantity = isset($bogo_cheap_in_cart['discount_quantity']) ? $bogo_cheap_in_cart['discount_quantity'] : 0;
}elseif(!empty($bogo_cheap_in_products)){
$bogo_cheapest_discount = isset($bogo_cheap_in_products['discount_price_per_quantity']) ? $bogo_cheap_in_products['discount_price_per_quantity'] : 0;
$bogo_cheapest_quantity = isset($bogo_cheap_in_products['discount_quantity']) ? $bogo_cheap_in_products['discount_quantity'] : 0;
}elseif (!empty($bogo_cheap_in_category)){
$bogo_cheapest_discount = isset($bogo_cheap_in_category['discount_price_per_quantity']) ? $bogo_cheap_in_category['discount_price_per_quantity'] : 0;
$bogo_cheapest_quantity = isset($bogo_cheap_in_category['discount_quantity']) ? $bogo_cheap_in_category['discount_quantity'] : 0;
}elseif(!empty($bogo_auto_add)){
$bogo_cheapest_discount = isset($bogo_auto_add['discount_price_per_quantity']) ? $bogo_auto_add['discount_price_per_quantity'] : 0;
$bogo_cheapest_quantity = isset($bogo_auto_add['discount_quantity']) ? $bogo_auto_add['discount_quantity'] : 0;
}else{
$bogo_cheapest_discount = isset($bogo_getx['discount_price_per_quantity']) ? $bogo_getx['discount_price_per_quantity'] : 0;
$bogo_cheapest_quantity = isset($bogo_getx['discount_quantity']) ? $bogo_getx['discount_quantity'] : 0;
}
$bogo_partial_set = '';
if(!empty($bogo_cheapest_quantity) && $bogo_cheapest_quantity < $cart_item_qty){
$bogo_partial_set = 'yes';
}elseif($bogo_cheapest_quantity == $cart_item_qty){
$bogo_cheapest_full_matched_set = $bogo_cheapest_discount;
}
$int_increment++;
//per product quantity for set discount
$fully_qualified_set = $discounted_price_per_set = $bogo_cheapest_full_matched_set = 0;
$total_quantity = $cart_item_qty;
$current_product_quantity = $cart_item_qty;
if(!empty($detail['set_discount'])){
$total_quantity = isset($detail['set_discount']['total_quantity']) ? $detail['set_discount']['total_quantity'] : 0;
$discount_operator = isset($detail['set_discount']['discount_operator']) ? $detail['set_discount']['discount_operator'] : "";
//original price quantity for set discount
$original_price_quantity = isset($detail['set_discount']['original_price_quantity']) ? $detail['set_discount']['original_price_quantity'] : 0;
//min set quantity
$discounted_price_quantity = isset($detail['set_discount']['discounted_price_quantity']) ? $detail['set_discount']['discounted_price_quantity'] : 0;
//set discounted price
$discounted_price_per_set = isset($detail['set_discount']['discount_value']) ? $detail['set_discount']['discount_value'] : 0;
$discounted_price_quantities = isset($detail['set_discount']['discounted_price_quantity']) ? $detail['set_discount']['discounted_price_quantity'] : 0;
if (!empty($total_quantity)) {
self::$set_total_quantity = $total_quantity;
}
if (empty($total_quantity)) {
$total_quantity = self::$set_total_quantity;
}
}
//simple discounted price
if(isset($detail['simple_discount']) && is_array($detail['simple_discount'])){
$simple_discount = isset($detail['simple_discount']['discount_price']) ? $detail['simple_discount']['discount_price'] : 0;
} else {
$simple_discount = isset($detail['simple_discount']) ? $detail['simple_discount'] : 0;
}
//bulk discounted price
if(isset($detail['bulk_discount']) && is_array($detail['bulk_discount'])){
$bulk_discounts = isset($detail['bulk_discount']['discount_price']) ? $detail['bulk_discount']['discount_price'] : 0;
} else {
$bulk_discounts = isset($detail['bulk_discount']) ? $detail['bulk_discount'] : 0;
}
//set discounted price quantity
$total_discount_price += $discounted_price_per_set + $simple_discount + $bulk_discounts + $bogo_cheapest_discount;
if (empty($original_price_quantity) && empty($discounted_price_quantity) && empty($bogo_partial_set)) {
if (!empty($discounted_price_per_set)) {
$fully_qualified_set = $discounted_price_per_set;
}
} else {
if(!empty($detail['set_discount']) && !empty($discounted_price_per_set) && !empty($discounted_price_quantities)){
if (isset($partially_qualified_set[$discounted_price_per_set]) && !empty($partially_qualified_set[$discounted_price_per_set])) {
$partially_qualified_set_amount_duplicate[$discounted_price_per_set . '-' . $int_increment] = $discounted_price_quantities;
} else {
$partially_qualified_set[$discounted_price_per_set] = $discounted_price_quantities;
}
}
if(!empty($bogo_partial_set)){
$int_increment++;
if (isset($partially_qualified_set[$bogo_cheapest_discount]) && !empty($partially_qualified_set[$bogo_cheapest_discount])) {
$partially_qualified_set_amount_duplicate[$bogo_cheapest_discount . '-' . $int_increment] = $bogo_cheapest_quantity;
} else {
$partially_qualified_set[$bogo_cheapest_discount] = $bogo_cheapest_quantity;
}
}
}
$other_discounts += $simple_discount + $bulk_discounts + $fully_qualified_set + $bogo_cheapest_full_matched_set + $bogo_cheapest_aditional_sum;
}
$initial_price_with_tax_call = $discounted_price_with_tax_call = 0;
if (empty($partially_qualified_set) || $apply_full_set == true) {
if ($price_html) {
if($ajax_price){
$discounted_price = $initial_price - $discounted_price;
if($discounted_price < 0){
$discounted_price = 0;
}
if(!empty($initial_price)){
$initial_price_with_tax_call = $calculator->mayHaveTax($product_obj, $initial_price);
}
if(!empty($discounted_price)){
$discounted_price_with_tax_call = $calculator->mayHaveTax($product_obj, $discounted_price);
}
$item_price = $this->getStrikeoutPrice($initial_price_with_tax_call, $discounted_price_with_tax_call);
return $item_price.Woocommerce::getProductPriceSuffix($product_obj, $discounted_price_with_tax_call);
}
if(!empty($initial_price)){
$initial_price_with_tax_call = $calculator->mayHaveTax($product_obj, $initial_price);
}
if(!empty($discounted_price)){
$discounted_price_with_tax_call = $calculator->mayHaveTax($product_obj, $discounted_price);
}
$item_price = $this->getStrikeoutPrice($initial_price_with_tax_call, $discounted_price_with_tax_call);
return $item_price.Woocommerce::getProductPriceSuffix($product_obj, $discounted_price_with_tax_call);
} else {
if($discounted_price < 0){
$discounted_price = 0;
}
return $discounted_price;
///return false;
}
} else {
$original_item_price_html = $this->getSetStrikeoutPrice($initial_price, $partially_qualified_set, $total_discount_price, $other_discounts, $total_quantity, $product_obj, $price_html, $current_product_quantity, $discount_operator, $partially_qualified_set_amount_duplicate);
return $original_item_price_html;
}
} else {
return false;
}
}
/**
* buy_x_get_y_cheapest_additional_strike_out
* @param $product_obj
* @param $bogo_cheap_in_cart
* @param $initial_price
* @param $cart_item_qty
* @return string
*/
public function buy_x_get_y_cheapest_additional_strike_out($product_obj, $bogo_cheap_in_cart, $initial_price, $cart_item_qty)
{
$price_html = $original_price_with_tax_call = $discounted_price_with_tax_call = '';
$bogo_cheap_in_cart_first_discount = isset($bogo_cheap_in_cart['discount_price_per_quantity']) ? $bogo_cheap_in_cart['discount_price_per_quantity'] : 0;
$bogo_cheap_in_cart_first_discount_qty = isset($bogo_cheap_in_cart['discount_quantity']) ? $bogo_cheap_in_cart['discount_quantity'] : 0;
$discounted_price = $bogo_cheap_in_cart_first_discount * $bogo_cheap_in_cart_first_discount_qty;
$discounted_price = $initial_price - $discounted_price;
if(!empty($initial_price)){
$original_price_with_tax_call = self::$calculator->mayHaveTax($product_obj, $initial_price);
}
if(!empty($discounted_price)){
$discounted_price_with_tax_call = self::$calculator->mayHaveTax($product_obj, $discounted_price);
}
$price_suffix = Woocommerce::getProductPriceSuffix($product_obj, $discounted_price_with_tax_call);
$price_html .= '' . self::$woocommerce_helper->formatPrice($original_price_with_tax_call) . ' ' . self::$woocommerce_helper->formatPrice($discounted_price_with_tax_call) .$price_suffix. ' x ' . $bogo_cheap_in_cart_first_discount_qty . '
';
$bogo_cheap_in_cart_total_discount_qty[] = $bogo_cheap_in_cart_first_discount_qty;
$bogo_cheap_in_cart_additional_discounts = $bogo_cheap_in_cart['additional_discounts'];
foreach ($bogo_cheap_in_cart_additional_discounts as $additional_discount){
$bogo_cheapest_discount_aditional = isset($additional_discount['discount_price_per_quantity']) ? $additional_discount['discount_price_per_quantity'] : 0;
$bogo_cheapest_quantity_aditional = isset($additional_discount['discount_quantity']) ? $additional_discount['discount_quantity'] : 0;
$discounted_price = $bogo_cheapest_discount_aditional * $bogo_cheapest_quantity_aditional;
$discounted_price = $initial_price - $discounted_price;
if(!empty($discounted_price)){
$discounted_price_with_tax_call = self::$calculator->mayHaveTax($product_obj, $discounted_price);
}
$price_suffix = Woocommerce::getProductPriceSuffix($product_obj, $discounted_price_with_tax_call);
$price_html .= '' . self::$woocommerce_helper->formatPrice($original_price_with_tax_call) . ' ' . self::$woocommerce_helper->formatPrice($discounted_price_with_tax_call) .$price_suffix. ' x ' . $bogo_cheapest_quantity_aditional . '
';
$bogo_cheap_in_cart_total_discount_qty[] = $bogo_cheapest_quantity_aditional;
}
$discount_applied_qty = array_sum($bogo_cheap_in_cart_total_discount_qty);
if($discount_applied_qty < $cart_item_qty){
$not_applied = $cart_item_qty - $discount_applied_qty;
$price_suffix = Woocommerce::getProductPriceSuffix($product_obj, $original_price_with_tax_call);
$price_html .= '' . self::$woocommerce_helper->formatPrice($original_price_with_tax_call) .$price_suffix. ' x ' . $not_applied . '';
}
return $price_html;
}
/**
* Calculate discount for product or calculate discount from custom price
* @param $price
* @param $product
* @param int $quantity
* @param int $custom_price
* @param string $get_only
* @return array|float|false
*/
static function calculateProductDiscountPrice($price, $product, $quantity = 1, $custom_price = 0, $get_only = 'discounted_price', $manual_request = false, $is_cart = true)
{
if (!is_a($product, 'WC_Product')) {
if (is_numeric($product)) {
$product = self::$woocommerce_helper->getProduct($product);
} else {
return false;
}
}
if (!$product) {
return false;
}
$discounts = self::$calculator->mayApplyPriceDiscount($product, $quantity, $custom_price, false, array(), $is_cart, $manual_request);
if ($discounts) {
switch ($get_only) {
case 'all':
$product_id = self::$woocommerce_helper->getProductId($product);
if (isset($discounts['total_discount_details'][$product_id])) {
$discounts['total_discount_details'] = $discounts['total_discount_details'][$product_id];
}
if (isset($discounts['cart_discount_details'])) {
unset($discounts['cart_discount_details']);
}
$price = $discounts;
break;
default:
case 'discounted_price':
$price = isset($discounts['discounted_price']) ? $discounts['discounted_price'] : $price;
break;
}
} else {
return false;
}
return $price;
}
/**
* Get discount price of a product
* @param int|float|false $product_price
* @param int|\WC_Product $product_or_id
* @param int|float $quantity
* @param int|float $custom_price
* @return float|false
* */
static function getDiscountPriceOfAProduct($product_price, $product_or_id, $quantity = 1, $custom_price = 0)
{
$details = self::getDiscountDetailsOfAProduct(false, $product_or_id, $quantity, $custom_price);
if ($details !== false && isset($details['discounted_price'])) {
return (float) $details['discounted_price'];
}
return $product_price;
}
/**
* Get discount details of a product
* @param array|false $discount_details
* @param int|\WC_Product $product_or_id
* @param int|float $quantity
* @param int|float $custom_price
* @return array|false
* */
static function getDiscountDetailsOfAProduct($discount_details, $product_or_id, $quantity = 1, $custom_price = 0)
{
$product = $product_or_id;
if (is_numeric($product)) {
$product = self::$woocommerce_helper->getProduct($product);
}
if (!is_object($product) || !is_a($product, 'WC_Product')) {
return false;
}
if (Woocommerce::productTypeIs($product, array('variable'))) {
$variation_product = Woocommerce::getFirstChildOfVariableProduct($product);
if (is_object($variation_product)) {
$product = $variation_product;
}
}
$discounts = self::calculateProductDiscountPrice(false, $product, $quantity, $custom_price, 'all', true, false);
if ($discounts !== false && is_array($discounts)) {
return self::prepareDiscountDetails($discounts);
}
return $discount_details;
}
/**
* Get discount percentage of a product
* @param int|float|false $discount_percentage
* @param int|\WC_Product $product_or_id
* @return float|false
* */
static function getDiscountPercentageOfAProduct($discount_percentage, $product_or_id)
{
$details = self::getDiscountDetailsOfAProduct(false, $product_or_id);
if ($details !== false && is_array($details) && !empty($details['initial_price']) && isset($details['discounted_price'])) {
return round((($details['initial_price'] - $details['discounted_price']) / $details['initial_price']) * 100, 4);
}
return $discount_percentage;
}
/**
* Get save amount of a product
* @param int|float|false $save_amount
* @param int|\WC_Product $product_or_id
* @return float|false
* */
static function getSaveAmountOfAProduct($save_amount, $product_or_id)
{
if ($details = self::getDiscountDetailsOfAProduct(false, $product_or_id)) {
if (is_array($details) && !empty($details['initial_price_based_on_tax_settings']) && isset($details['discounted_price_based_on_tax_settings'])) {
return round($details['initial_price_based_on_tax_settings'] - $details['discounted_price_based_on_tax_settings'], 4);
}
}
return $save_amount;
}
/**
* Get discount price of a product in cart
* @param int|float|false $product_price
* @param string|array $cart_item_or_key
* @return float|false
* */
static function getDiscountPriceFromCartItem($product_price, $cart_item_or_key)
{
if ($data = self::getDiscountDetailsFromCartItem(false, $cart_item_or_key)) {
if (is_array($data) && isset($data['discounted_price'])) {
return (float) $data['discounted_price'];
}
}
return $product_price;
}
/**
* Get discount details of a product in cart
* @param array|false $discount_details
* @param string|array $cart_item_or_key
* @return array|false
* */
static function getDiscountDetailsFromCartItem($discount_details, $cart_item_or_key)
{
if (is_array($cart_item_or_key) && isset($cart_item_or_key['key'])) {
$cart_item = $cart_item_or_key;
$key = (string) $cart_item['key'];
} elseif (is_string($cart_item_or_key)) {
$key = $cart_item_or_key;
$cart_item = self::$woocommerce_helper->getCartItem($key);
}
if (empty($key) || empty($cart_item) || !is_array($cart_item)) {
return false;
}
$product_id = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
if (isset(self::$calculated_cart_item_discount[$key])) {
$cart_item_discounts = self::$calculated_cart_item_discount[$key];
}
if (empty($cart_item_discounts) && $free_item_discounts = apply_filters('advanced_woo_discount_rules_get_auto_add_discount_details_from_cart_item', array(), $cart_item, $key)) {
$cart_item_discounts = $free_item_discounts;
}
if (!empty($cart_item_discounts)) {
return self::prepareDiscountDetails($cart_item_discounts, $product_id, 1, $key);
}
return $discount_details;
}
/**
* Get save amount of a product in cart
* @param int|float|false $saved_amount
* @param string|array $cart_item_or_key
* @return float|false
* */
static function getSavedAmountFromCartItem($saved_amount, $cart_item_or_key)
{
if ($details = self::getDiscountDetailsFromCartItem(false, $cart_item_or_key)) {
if (is_array($details) && !empty($details['initial_price_based_on_tax_settings']) && isset($details['discounted_price_based_on_tax_settings'])) {
return round($details['initial_price_based_on_tax_settings'] - $details['discounted_price_based_on_tax_settings'], 4);
}
}
return $saved_amount;
}
/**
* Get discount of a product in order
* @param int|float|false $product_price
* @param int|\WC_Order_Item $order_item_or_id
* @return float|false
* */
static function getDiscountPriceFromOrderItem($product_price, $order_item_or_id)
{
if ($details = self::getDiscountDetailsFromOrderItem(false, $order_item_or_id)) {
if (is_array($details) && isset($details['discounted_price'])) {
return (float) $details['discounted_price'];
}
}
return $product_price;
}
/**
* Get discount details of a product in order
* @param array|false $discount_details
* @param int|\WC_Order_Item $order_item_or_id
* @return array|false
* */
static function getDiscountDetailsFromOrderItem($discount_details, $order_item_or_id)
{
if (is_object($order_item_or_id) && is_a($order_item_or_id, '\WC_Order_Item')) {
$order_item = $order_item_or_id;
} elseif (is_numeric($order_item_or_id)) {
$order_item = self::$woocommerce_helper->getOrderItem($order_item_or_id);
} else {
return false;
}
if (is_object($order_item) && method_exists($order_item, 'get_meta')) {
$data = $order_item->get_meta('_wdr_discounts');
if (empty($data)) {
$data = $order_item->get_meta('_advanced_woo_discount_item_total_discount');
if (!empty($data) && is_array($data)) {
$data['initial_price_with_tax'] = $data['initial_price_based_on_tax_settings'];
$data['discounted_price_with_tax'] = $data['discounted_price_based_on_tax_settings'];
return self::prepareDiscountDetails($data);
}
}
if (!empty($data) && is_array($data)) {
return $data;
}
return $discount_details;
}
return false;
}
/**
* Get save amount of a product in order
* @param int|float|false $saved_amount
* @param int|\WC_Order_Item $order_item_or_id
* @return float|false
* */
static function getSavedAmountFromOrderItem($saved_amount, $order_item_or_id)
{
if ($details = self::getDiscountDetailsFromOrderItem(false, $order_item_or_id)) {
if (is_array($details) && !empty($details['initial_price_based_on_tax_settings']) && isset($details['discounted_price_based_on_tax_settings'])) {
return round($details['initial_price_based_on_tax_settings'] - $details['discounted_price_based_on_tax_settings'], 4);
}
}
return $saved_amount;
}
/**
* Get discount details from order
* @param array|false $discount_details
* @param int|\WC_Order $order_or_id
* @return array|false
* */
static function getDiscountDetailsFromOrder($discount_details, $order_or_id)
{
if (is_object($order_or_id) && is_a($order_or_id, '\WC_Order')) {
$order = $order_or_id;
} elseif (is_numeric($order_or_id)) {
$order = self::$woocommerce_helper->getOrder($order_or_id);
} else {
return false;
}
if (is_object($order) && method_exists($order, 'get_meta')) {
$data = $order->get_meta('_wdr_discounts');
if (!empty($data) && is_array($data)) {
return $data;
}
return $discount_details;
}
return false;
}
/**
* Get save amount from order
* @param int|float|false $saved_amount
* @param int|\WC_Order $order_or_id
* @return float|false
* */
static function getSavedAmountFromOrder($saved_amount, $order_or_id)
{
if ($details = self::getDiscountDetailsFromOrder(false, $order_or_id)) {
if (is_array($details) && isset($details['saved_amount']['total_based_on_tax_settings'])) {
return $details['saved_amount']['total_based_on_tax_settings'];
}
}
return $saved_amount;
}
/**
* Change the default template for sale badge
*
* @param $located string
* @param $template_name string
* @param $args array
* @param $template_path string
* @param $default_path string
* @return string
* */
public static function changeTemplateForSaleTag($located, $template_name, $args, $template_path, $default_path){
if($template_name == 'single-product/sale-flash.php'){
$located = Helper::getTemplatePath('sale-flash.php', WDR_PLUGIN_PATH . 'App/Views/Templates/single-product/sale-flash.php', 'single-product');
} else if($template_name == 'loop/sale-flash.php'){
$located = Helper::getTemplatePath('sale-flash.php', WDR_PLUGIN_PATH . 'App/Views/Templates/loop/sale-flash.php', 'loop');
}
return $located;
}
/**
* Remove on sale flash except our hooks
* */
function removeOnSaleFlashEvent(){
$allowed_hooks = array(
//Filters
"woocommerce_sale_flash" => array( "Wdr\App\Controllers\ManageDiscount|replaceSaleTagText" ),
);
$this->removeOtherEvents($allowed_hooks);
}
/**
* Suppress third party discount plugins from accessing the discount data
*/
function suppressOtherDiscountPlugins()
{
$allowed_hooks = array(
//Filters
"woocommerce_get_price_html" => array("Wdr\App\Controllers\ManageDiscount|getPriceHtml", "Wdr\App\Controllers\ManageDiscount|getPriceHtmlSalePriceAdjustment"),
"woocommerce_product_is_on_sale" => array("Wdr\App\Controllers\ManageDiscount|isProductInSale"),
"woocommerce_product_get_sale_price" => array(),
"woocommerce_product_get_regular_price" => array(),
"woocommerce_variable_price_html" => array("Wdr\App\Controllers\ManageDiscount|getVariablePriceHtml"),
"woocommerce_cart_item_price" => array("Wdr\App\Controllers\ManageDiscount|getCartPriceHtml"),
"woocommerce_cart_item_subtotal" => array("Wdr\App\Controllers\ManageDiscount|getCartProductSubtotalPriceHtml"),
//Actions
"woocommerce_checkout_order_processed" => array(),
"woocommerce_before_calculate_totals" => array("Wdr\App\Controllers\ManageDiscount|applyCartProductDiscount"), //nothing allowed!
);
$allowed_hooks = apply_filters('advanced_woo_discount_rules_exclude_hooks_from_removing', $allowed_hooks);
$this->removeOtherEvents($allowed_hooks);
}
/**
* Remove methods from the event
* Exclude from the list
*
* @param $allowed_hooks array
* */
function removeOtherEvents($allowed_hooks){
global $wp_filter;
foreach ($wp_filter as $hook_name => $hook_obj) {
if (preg_match('#^woocommerce_#', $hook_name)) {
if (isset($allowed_hooks[$hook_name])) {
$wp_filter[$hook_name] = $this->removeWrongCallbacks($hook_obj, $allowed_hooks[$hook_name]);
}
}
}
}
/**
* Remove the third party call backs
* @param $hook_obj
* @param $allowed_hooks
* @return mixed
*/
function removeWrongCallbacks($hook_obj, $allowed_hooks)
{
if (method_exists($hook_obj, 'offsetSet') && method_exists($hook_obj, 'offsetUnset')) {
foreach ($hook_obj->callbacks as $priority => $callbacks) {
$priority_callbacks = array();
foreach ($callbacks as $idx => $callback_details) {
if ($this->isCallbackMatch($callback_details, $allowed_hooks)) {
$priority_callbacks[$idx] = $callback_details;
}
}
$hook_obj->offsetUnset($priority);
if ($priority_callbacks) {
$hook_obj->offsetSet($priority, $priority_callbacks);
}
}
} else {
$new_callbacks = array();
foreach ($hook_obj->callbacks as $priority => $callbacks) {
$priority_callbacks = array();
foreach ($callbacks as $idx => $callback_details) {
if ($this->isCallbackMatch($callback_details, $allowed_hooks)) {
$priority_callbacks[$idx] = $callback_details;
}
}
if ($priority_callbacks) {
$new_callbacks[$priority] = $priority_callbacks;
}
}
$hook_obj->callbacks = $new_callbacks;
}
return $hook_obj;
}
/**
* check the call back matched or not
* @param $callback_details
* @param $allowed_hooks
* @return bool
*/
function isCallbackMatch($callback_details, $allowed_hooks)
{
$result = false;
foreach ($allowed_hooks as $callback_name) {
list($class_name, $func_name) = explode("|", $callback_name);
if(empty($callback_details['function'])){
continue;
}
if(is_string($callback_details['function'])){
continue;
}
if(is_object($callback_details['function'])){
if($this->is_closure($callback_details['function'])){
continue;
}
}
if (count($callback_details['function']) != 2) {
continue;
}
if(!is_object($callback_details['function'][0])){
continue;
}
if ($class_name == get_class($callback_details['function'][0]) AND $func_name == $callback_details['function'][1]) {
$result = true;
break;// done!
}
}
return $result;
}
function is_closure($t) {
if(class_exists('\Closure')){
return $t instanceof \Closure;
} else {
return false;
}
}
/**
* Display you saved text in order pages
* @param $total
* @param $order
* @return string
*/
function displayTotalSavingsInOrderAfterOrderTotal($total, $order)
{
if (!is_object($order)) {
if (!empty($order) && is_int($order)) {
$order = self::$woocommerce_helper->getOrder($order);
}
}
$items = $order->get_items();
$total_discount = $this->getItemTotalDiscount($items);
$save_text = NULL;
if (!empty($total_discount)) {
$total_discounted_price = self::$woocommerce_helper->formatPrice($total_discount, array('currency' => self::$woocommerce_helper->getOrderCurrency($order)));
$subtotal_additional_text = $this->getYouSavedText($total_discounted_price);
$save_text = apply_filters('advanced_woo_discount_rules_order_saved_text', $subtotal_additional_text, $total_discounted_price, $total_discount,['filter_type'=>'complete_order_total','order'=>$order, 'item'=>$items]);
}
return $total . $save_text;
}
/**
* Calculate items total discount
* @param $items
* @return float|int
*/
function getItemTotalDiscount($items)
{
$total_discount = 0;
if (!empty($items)) {
foreach ($items as $key => $item) {
$discount_details = $item->get_meta('_advanced_woo_discount_item_total_discount');
if (!empty($discount_details)) {
$total_discount += $this->getDiscountPerItem($discount_details);
}
}
}
return $total_discount;
}
/**
* order line item saved text
* @param $subtotal
* @param $item
* @param $order
* @return string
*/
function orderSubTotalDiscountDetails($subtotal, $item, $order)
{
$discount_details = self::$woocommerce_helper->getOrderItemMeta($item, '_advanced_woo_discount_item_total_discount');
if (!empty($discount_details)) {
$total_discount = $this->getDiscountPerItem($discount_details);
if (!empty($total_discount)) {
$total_discounted_price = self::$woocommerce_helper->formatPrice($total_discount, array('currency' => self::$woocommerce_helper->getOrderCurrency($order)));
$subtotal_additional_text = $this->getYouSavedText($total_discounted_price);
$subtotal .= apply_filters('advanced_woo_discount_rules_order_saved_text', $subtotal_additional_text, $total_discounted_price, $total_discount,['filter_type'=>'complete_order_line_item','order'=> $order, 'item'=>$item]);
}
}
return $subtotal;
}
/**
* Show order discount details
* @param $item_id
* @param $item
* @param $product
*/
public function orderItemMetaDiscountDetails($item_id, $item, $product)
{
$discount_details = self::$woocommerce_helper->getOrderItemMeta($item, '_advanced_woo_discount_item_total_discount');
if (!empty($discount_details)) {
$total_discount = $this->getDiscountPerItem($discount_details);
$order = self::$woocommerce_helper->getOrderByItem($item);
if (!empty($order) && !empty($total_discount)) {
$total_discounted_price = self::$woocommerce_helper->formatPrice($total_discount, array('currency' => self::$woocommerce_helper->getOrderCurrency($order)));
$subtotal_additional_text = $this->getYouSavedText($total_discounted_price);
echo wp_kses_post(apply_filters('advanced_woo_discount_rules_order_saved_text', $subtotal_additional_text, $total_discounted_price, $total_discount,['filter_type'=>'woo_order_line_item','order'=>$order, 'item'=>$item]));
}
}
}
/**
* Hide Zero Coupon Value
* @param $coupon_html
* @param $coupon
* @return mixed
*/
public function hideZeroCouponValue($coupon_html, $coupon)
{
$hide_zero_value_coupon = apply_filters('advanced_woo_discount_rules_hide_zero_value_coupon', true, $coupon);
if ($hide_zero_value_coupon) {
$rule_helper = new Rule();
$original_coupon_html = $coupon_html;
$all_coupon_codes = $rule_helper->getCouponsFromDiscountRules();
$coupon_code = self::$woocommerce_helper->getCouponCode($coupon);
$virtual_coupon = (isset($all_coupon_codes['custom_coupons']) && !empty($all_coupon_codes['custom_coupons'])) ? array_map('strtolower',$all_coupon_codes['custom_coupons']) : [];
$woo_coupons = (isset($all_coupon_codes['woo_coupons'][0]) && !empty($all_coupon_codes['woo_coupons'][0])) ? $all_coupon_codes['woo_coupons'][0] : [];
if (!empty($woo_coupons) && in_array($coupon_code, $woo_coupons)) {
$zero_price_html = '-' . self::$woocommerce_helper->formatPrice(0);
$coupon_html = str_replace($zero_price_html, '', $coupon_html);
} else if (!empty($virtual_coupon) && in_array(strtolower($coupon_code), $virtual_coupon)) {
$zero_price_html = '-' . self::$woocommerce_helper->formatPrice(0);
$coupon_html = str_replace($zero_price_html, '', $coupon_html);
}
$coupon_html = apply_filters('advanced_woo_discount_rules_hide_zero_value_coupon_html', $coupon_html, $original_coupon_html, $coupon);
}
return $coupon_html;
}
/**
* Display promotional messages
* */
public function displayPromotionMessages(){
$cart = Woocommerce::getCart();
$messages = Helper::getPromotionMessages();
$messages = empty($cart) ? '' : $messages;
if(!empty($messages) && is_array($messages)) {
foreach ($messages as $message) {
self::$woocommerce_helper->printNotice($message, "notice");
}
}
}
/**
* Load outer div for displaying promotional message in check out
* */
public function displaySubTotalPromotionMessagesInCheckoutContainer(){
echo "