options = $options; add_action( 'wp_print_styles', array( $this, 'load_frontend_assets' ) ); $this->price_display = new WDP_Price_Display(); if ( $this->price_display->is_enabled() ) { $this->price_display->init_hooks(); } if ( $options['show_matched_bulk_table'] ) { $product_bulk_table_action = isset( $options['product_bulk_table_action'] ) ? $options['product_bulk_table_action'] : ""; add_action( 'wp_loaded', function () use ( $product_bulk_table_action ) { $product_bulk_table_actions = (array) apply_filters( 'wdp_product_bulk_table_action', $product_bulk_table_action ); if ( is_array( $product_bulk_table_actions ) && $product_bulk_table_actions ) { foreach ( $product_bulk_table_actions as $action ) { add_action( $action, array( $this, 'print_table_with_product_bulk_rules' ), 50, 2 ); } } } ); } add_action( 'woocommerce_checkout_order_processed', array( $this, 'checkout_order_processed' ), 10, 3 ); add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'woocommerce_cart_loaded_from_session' ), 100 ); add_action( 'woocommerce_checkout_update_order_review', array( $this, 'woocommerce_checkout_update_order_review' ), 100 ); // strike prices for items if ( $options['show_striked_prices'] ) { add_filter( 'woocommerce_cart_item_price', array( $this, 'woocommerce_cart_item_price_and_price_subtotal' ), 10, 3 ); add_filter( 'woocommerce_cart_item_subtotal', array( $this, 'woocommerce_cart_item_price_and_price_subtotal' ), 10, 3 ); } if ( $options['show_category_bulk_table'] ) { $category_bulk_table_action = isset( $options['category_bulk_table_action'] ) ? $options['category_bulk_table_action'] : ""; add_action( 'wp_loaded', function () use ( $category_bulk_table_action ) { $category_bulk_table_action = apply_filters( 'wdp_category_bulk_table_action', $category_bulk_table_action ); if ( $category_bulk_table_action ) { add_action( $category_bulk_table_action, array( $this, 'print_table_with_category_bulk_rules' ), 50, 2 ); } } ); } if ( $options['is_show_amount_saved_in_mini_cart'] ) add_action( 'woocommerce_mini_cart_contents', array( $this, 'output_amount_save' ) ); if ( $options['is_show_amount_saved_in_cart'] ) add_action( 'woocommerce_cart_totals_before_order_total', array( $this, 'output_amount_save' ) ); if ( $options['is_show_amount_saved_in_checkout_cart'] ) add_action( 'woocommerce_review_order_after_cart_contents', array( $this, 'output_amount_save' ) ); //SHORTCODES add_shortcode( 'adp_product_bulk_rules_table', array( $this, 'print_table_with_product_bulk_rules' ) ); add_shortcode( 'adp_category_bulk_rules_table', array( $this, 'print_table_with_category_bulk_rules' ) ); // hooking nopriv ajax methods foreach ( self::get_nopriv_ajax_actions() as $ajax_action_name ) { add_action( "wp_ajax_nopriv_{$ajax_action_name}", array( $this, "ajax_{$ajax_action_name}" ) ); add_action( "wp_ajax_{$ajax_action_name}", array( $this, "ajax_{$ajax_action_name}" ) ); } if ( $options['suppress_other_pricing_plugins'] AND !is_admin() ) { add_action( "wp_loaded", array( $this, 'remove_hooks_set_by_other_plugins' ) ); } add_filter( 'woocommerce_add_to_cart_sold_individually_found_in_cart', array($this, 'woocommerce_add_to_cart_sold_individually_found_in_cart'), 10 ,5 ); /** Additional css class for free item line */ add_filter( 'woocommerce_cart_item_class', function ( $str_classes, $cart_item, $cart_item_key ) { $classes = explode( ' ', $str_classes ); if ( ! empty( $cart_item['wdp_gifted'] ) ) { $classes[] = 'wdp_free_product'; } if ( ! empty( $cart_item['wdp_original_price'] ) && (float) $cart_item['data']->get_price() == 0 ) { $classes[] = 'wdp_zero_cost_product'; } return implode( ' ', $classes ); }, 10, 3 ); /** PHONE ORDER HOOKS START */ if ( ! $options['allow_to_edit_prices_in_po'] ) { add_filter( 'wpo_set_original_price_after_calculation', function ( $price, $cart_item ) { return ! empty( $cart_item["wdp_original_price"] ) ? $cart_item["wdp_original_price"] : false; }, 10, 2 ); add_filter( 'wpo_cart_item_is_price_readonly', '__return_true', 10, 1 ); } else { add_filter( 'wpo_prepare_item', function ( $item, $product ) { /** * @var $product WC_Product */ if ( empty( $item['cost_updated_manually'] ) && ( $item['item_cost'] != $product->get_price() ) ) { $item['item_cost'] = $product->get_price(); } return $item; }, 10, 2 ); add_filter( 'wpo_update_cart_cart_item_meta', function ( $cart_item_meta, $item ) { if ( ! empty( $item['cost_updated_manually'] ) ) { $cart_item_meta['immutable'] = true; } return $cart_item_meta; }, 10, 2 ); add_filter( 'wdp_cart_item_before_insert', function ( $item, $wc_cart_item ) { /** * @var $item WDP_Cart_Item */ if ( ! empty( $wc_cart_item['immutable'] ) ) { $item->make_immutable(); } return $item; }, 10, 2 ); add_filter( 'wpo_cart_item_is_price_readonly', '__return_false', 10, 1 ); } add_filter( 'wpo_must_switch_cart_user', '__return_true', 10, 1 ); add_filter( 'wpo_skip_add_to_cart_item', function ( $skip, $item ) { return ! empty( $item['wdp_gifted'] ) ? (boolean) $item['wdp_gifted'] : $skip; }, 10, 2 ); /** PHONE ORDER HOOKS FINISH */ } public static function is_catalog_view() { return is_product_tag() || is_product_category() || is_shop(); } public function ajax_get_table_with_product_bulk_table() { $product_id = ! empty( $_REQUEST['product_id'] ) ? $_REQUEST['product_id'] : false; if ( ! $product_id ) { wp_send_json_error(); } wp_send_json_success( $this->make_table_with_product_bulk_table( $product_id ) ); } public function ajax_get_price_product_with_bulk_table() { $product_id = ! empty( $_REQUEST['product_id'] ) ? $_REQUEST['product_id'] : false; $qty = ! empty( $_REQUEST['qty'] ) ? (int) $_REQUEST['qty'] : false; if ( ! $product_id || ! $qty ) { wp_send_json_error(); } wp_send_json_success( array( 'price_html' => $this->get_price_html_product_with_bulk_table( $product_id, $qty ) ) ); } private function get_price_html_product_with_bulk_table( $product_id, $qty ) { try { $wdp_product = new WDP_Product( $product_id ); } catch ( Exception $e ) { return ""; } return $this->price_display->get_product_price_html( $wdp_product, $qty ); } public function print_table_with_product_bulk_rules() { /** * @var $product WC_Product */ global $product; if ( ! empty( $product ) ) { $available_products_ids = array(); $available_products_ids[] = $product->get_id(); $available_products_ids = array_merge( $available_products_ids, $product->get_children() ); echo ''; echo $this->make_table_with_product_bulk_table( $product->get_id() ); echo ''; } } /** * @param $product_id integer * * @return string */ private function make_table_with_product_bulk_table( $product_id ) { $calc = self::make_wdp_calc_from_wc(); $cart = self::make_wdp_cart_from_wc(); $matched_rules = $calc->find_product_matches( $cart, $product_id ); $bulk_rules = $matched_rules->with_bulk(); if ( $bulk_rules->is_empty() ) { return ""; } $rule = $bulk_rules->get_first(); $data = $rule->get_bulk_details($cart->get_context()); $data['discount'] = str_replace( "set_", "", $data['discount'] ); $options = WDP_Helpers::get_settings(); $price_mode = $options['discount_for_onsale']; $product = wc_get_product( $product_id ); if ( ! $product ) { return ""; } if ( $product->is_type( 'variable' ) ) { foreach ( $data['ranges'] as &$line ) { if ( 'price__fixed' === $data['discount'] ) { $line['value'] = wc_get_price_to_display( $product, array( 'price' => $line['value'] ) ); } unset( $line['discounted_price'] ); } } else { if ( $product->is_on_sale( 'edit' ) ) { if ( 'sale_price' === $price_mode ) { $price = $product->get_sale_price( '' ); } elseif ( 'discount_sale' === $price_mode ) { $price = $product->get_sale_price( '' ); } else { $price = $product->get_regular_price( '' ); } } else { $price = $product->get_price(); } foreach ( $data['ranges'] as &$line ) { if ( 'price__fixed' === $data['discount'] ) { $line['discounted_price'] = (float) $price - (float) $line['value']; $line['value'] = wc_get_price_to_display( $product, array( 'price' => $line['value'] ) ); } elseif ( 'discount__amount' === $data['discount'] ) { $line['discounted_price'] = (float) $price - (float) $line['value']; } elseif ( 'discount__percentage' === $data['discount'] ) { $line['discounted_price'] = (float) $price - (float) $price * (float) $line['value'] / 100; } $line['discounted_price'] = wc_price( wc_get_price_to_display( $product, array( 'price' => $line['discounted_price'] ) ) ) /*. $product->get_price_suffix()*/; } } if ( empty( $data['table_message'] ) ) { $dependencies = $rule->get_product_dependencies(); foreach ( $dependencies as &$dependency ) { foreach ( $dependency['values'] as $id ) { $dependency['titles'][] = WDP_Helpers::get_title_by_type($id, $dependency['type']); $dependency['links'][] = WDP_Helpers::get_permalink_by_type($id, $dependency['type']); } } unset( $dependency ); } $args = apply_filters( 'wdp_args_before_product_bulk_table_template', array( 'data' => $data, 'dependencies' => isset( $dependencies ) ? $dependencies : array(), 'table_type' => 'product', ) ); $content = $this->wdp_get_template( 'bulk-table.php', $args ); return $content; } public function print_table_with_category_bulk_rules() { if ( is_tax() ) { global $wp_query; if ( isset( $wp_query->queried_object->term_id ) ) { $term_id = $wp_query->queried_object->term_id; } else { return false; } $active_rules = WDP_Rules_Registry::get_instance()->get_active_rules()->with_bulk()->to_array(); foreach ( $active_rules as $index => $rule ) { $data = $rule->get_bulk_details( self::make_wdp_cart_context_from_wc() ); $dependencies = $rule->get_product_dependencies(); $delete = true; foreach ( $dependencies as &$dependency ) { foreach ( $dependency['values'] as $id ) { $dependency['titles'][] = WDP_Helpers::get_title_by_type($id, $dependency['type']); $dependency['links'][] = WDP_Helpers::get_permalink_by_type($id, $dependency['type']); if ( 'product_categories' === $dependency['type'] AND $term_id == $id) { $delete = false; } } } if ( $delete ) { unset( $active_rules[ $index ] ); continue; } $content = $this->wdp_get_template( 'bulk-table.php', array( 'data' => $data, 'dependencies' => isset( $dependencies ) ? $dependencies : null, 'table_type' => 'category', ) ); echo '' . $content . ''; break; } } } /** * @param int $product_id * * @return WDP_Rules_Collection */ public function get_matched_offers( $product_id ) { $calc = self::make_wdp_calc_from_wc(); // $context = $this->make_wdp_cart_context_from_wc(); // $coupons = $this->get_wc_cart_coupons(); // $cart = new WDP_Cart( array(), $coupons, $context ); $cart = self::make_wdp_cart_from_wc(); $rules = $calc->find_product_matches( $cart, $product_id ); return $rules; } /** * Change cart item display price * * @access public * * @param string $price_html * @param array $cart_item * @param string $cart_item_key * * @return string */ public function cart_item_price( $price_html, $cart_item, $cart_item_key ) { if ( isset( $cart_item['wdp_data']['initial_price'] ) ) { /** @var WC_Product $product */ $product = $cart_item['data']; $intial_price = $cart_item['wdp_data']['initial_price']; $processed_price = $product->get_price(); if ( $intial_price != $processed_price ) { $price_html = '' . wc_price( $intial_price ) . ''; $price_html .= '' . wc_price( $processed_price ) . ''; } } return $price_html; } public function woocommerce_cart_loaded_from_session() { if ( ! empty( $_GET['wc-ajax'] ) AND $_GET['wc-ajax'] === "update_order_review") return; $this->process_cart(); } public function woocommerce_checkout_update_order_review() { add_action( 'woocommerce_before_data_object_save', array( $this, 'process_cart' ), 100 ); } public function process_cart() { remove_action( 'woocommerce_before_data_object_save', array( $this, 'process_cart' ), 100 ); $wc_customer = WC()->cart->get_customer(); $wc_session = WC()->session; // store tax exempt value if ( ! isset( $wc_session->wdp_old_tax_exempt ) ) { $wc_session->set( 'wdp_old_tax_exempt', $wc_customer->get_is_vat_exempt() ); } else { $wc_customer->set_is_vat_exempt( $wc_session->wdp_old_tax_exempt ); } $calc = self::make_wdp_calc_from_wc(); $cart = self::make_wdp_cart_from_wc(); $this->price_display->attach_calc( $calc ); $newcart = $calc->process_cart_new( $cart ); if( $newcart ) { $newcart->apply_to_wc_cart(); } else { unset( $wc_session->wdp_old_tax_exempt ); //try delete gifted products ? $wc_cart_items = WC()->cart->get_cart(); $store_keys = apply_filters( 'wdp_save_cart_item_keys', array() ); foreach ( $wc_cart_items as $wc_cart_item_key => $wc_cart_item ) { $changed = false; if ( isset( $wc_cart_item['wdp_gifted'] ) ) { $wdp_gifted = $wc_cart_item['wdp_gifted']; unset( $wc_cart_item['wdp_gifted'] ); $changed = true; if ( $wdp_gifted ) { WC()->cart->remove_cart_item( $wc_cart_item_key ); continue; } } if ( isset( $wc_cart_item['wdp_original_price'] ) ) { unset( $wc_cart_item['wdp_original_price'] ); $changed = true; } if ( isset( $wc_cart_item['wdp_history'] ) ) { unset( $wc_cart_item['wdp_history'] ); $changed = true; } if ( isset( $wc_cart_item['wdp_rules'] ) ) { unset( $wc_cart_item['wdp_rules'] ); $changed = true; } if ( isset( $wc_cart_item['rules'] ) ) { unset( $wc_cart_item['rules'] ); $changed = true; } if ( isset( $wc_cart_item['wdp_rules_for_singular'] ) ) { unset( $wc_cart_item['wdp_rules_for_singular'] ); $changed = true; } $product_id = $wc_cart_item['product_id']; $qty = $wc_cart_item['quantity']; $variation_id = $wc_cart_item['variation_id']; $variation = $wc_cart_item['variation']; $cart_item_data = array(); foreach ( $store_keys as $key ) { if ( isset( $wc_cart_item[ $key ] ) ) { $cart_item_data[ $key ] = $wc_cart_item[ $key ]; } } if ( $changed ) { WC()->cart->remove_cart_item( $wc_cart_item_key ); $exclude_hooks = apply_filters('wdp_exclude_hooks_when_add_to_cart_after_disable_pricing', array(), $wc_cart_item); self::process_without_hooks( function () use ( $product_id, $qty, $variation_id, $variation, $cart_item_data ) { WC()->cart->add_to_cart( $product_id, $qty, $variation_id, $variation, $cart_item_data ); }, $exclude_hooks ); } } // clear shipping in session for triggering full calculate_shipping to replace 'wdp_free_shipping' when needed foreach ( WC()->session->get_session_data() as $key => $value ) { if ( preg_match( '/(shipping_for_package_).*/', $key, $matches ) === 1 ) { if ( ! isset( $matches[0] ) ) { continue; } $stored_rates = WC()->session->get( $matches[0] ); if ( ! isset( $stored_rates['rates'] ) ) { continue; } if ( is_array( $stored_rates['rates'] ) ) { foreach ( $stored_rates['rates'] as $rate ) { if ( isset( $rate->get_meta_data()['wdp_free_shipping'] ) ) { unset( WC()->session->$key ); break; } } } } } }// if no rules } /** * @return WDP_Cart_Calculator */ private static function make_wdp_calc_from_wc() { $rule_collection = WDP_Rules_Registry::get_instance()->get_active_rules(); $calc = new WDP_Cart_Calculator( $rule_collection ); return $calc; } /** * @param bool $use_empty_cart * * @return WDP_Cart */ private static function make_wdp_cart_from_wc( $use_empty_cart = false ) { $context = self::make_wdp_cart_context_from_wc(); if ( $use_empty_cart ) { $cart = new WDP_Cart( $context ); } else { $cart = new WDP_Cart( $context, WC()->cart ); } return $cart; } /** * @return array */ private function get_wc_cart_coupons() { $external_coupons = array(); foreach ( WC()->cart->get_coupons() as $coupon ) { /** * @var $coupon WC_Coupon */ if ( $coupon->get_id() ) { $external_coupons[] = $coupon->get_code(); } } return $external_coupons; } /** * @return WDP_Cart_Context */ public static function make_wdp_cart_context_from_wc() { //test code $environment = array( 'timestamp' => current_time( 'timestamp' ), 'prices_includes_tax' => wc_prices_include_tax(), ); $settings = WDP_Helpers::get_settings(); if ( ! is_null( WC()->customer ) ) { $customer = new WDP_User_Impl( new WP_User( WC()->customer->get_id() ) ); $customer->set_shipping_country( WC()->customer->get_shipping_country( '' ) ); $customer->set_shipping_state( WC()->customer->get_shipping_state( '' ) ); $customer->set_is_vat_exempt( WC()->customer->get_is_vat_exempt() ); } else { $customer = new WDP_User_Impl( new WP_User() ); } if ( ! is_null( WC()->session ) ) { if ( is_checkout() ) $customer->set_payment_method( WC()->session->get('chosen_payment_method') ); if ( is_checkout() OR !self::is_catalog_view() ) $customer->set_shipping_methods( WC()->session->get('chosen_shipping_methods') ); } $context = new WDP_Cart_Context( $customer, $environment, $settings ); return $context; } public function checkout_order_processed( $order_id, $posted_data, $order ) { list( $order_stats, $product_stats ) = $this->collect_wc_cart_stats( WC() ); $order_date = current_time( 'mysql' ); foreach ( $order_stats as $rule_id => $stats_item ) { $stats_item = array_merge( array( 'order_id' => $order_id, 'rule_id' => $rule_id, 'amount' => 0, 'extra' => 0, 'shipping' => 0, 'is_free_shipping' => 0, 'gifted_amount' => 0, 'gifted_qty' => 0, 'date' => $order_date, ), $stats_item ); WDP_Database::add_order_stats( $stats_item ); } foreach ( $product_stats as $product_id => $by_rule ) { foreach ( $by_rule as $rule_id => $stats_item ) { $stats_item = array_merge( array( 'order_id' => $order_id, 'product_id' => $product_id, 'rule_id' => $rule_id, 'qty' => 0, 'amount' => 0, 'gifted_amount' => 0, 'gifted_qty' => 0, 'date' => $order_date, ), $stats_item ); WDP_Database::add_product_stats( $stats_item ); } } } /** * @param WooCommerce $wc * * @return array */ private function collect_wc_cart_stats( $wc ) { $order_stats = array(); $product_stats = array(); $wc_cart = $wc->cart; $cart_items = $wc_cart->get_cart(); foreach ( $cart_items as $cart_item ) { $rules = isset( $cart_item['wdp_rules'] ) ? $cart_item['wdp_rules'] : ''; if ( empty( $rules ) ) { continue; } $product_id = $cart_item['product_id']; foreach ( $rules as $rule_id => $amount ) { //add stat rows if( !isset( $order_stats[ $rule_id ] ) ) { $order_stats[ $rule_id ] = array( 'amount'=>0, 'qty'=>0, 'gifted_qty'=>0, 'gifted_amount'=>0, 'shipping'=>0, 'is_free_shipping'=>0, 'extra'=>0 ); } if( !isset( $product_stats[ $product_id ][ $rule_id ] ) ) { $product_stats[ $product_id ][ $rule_id ] = array( 'amount'=>0, 'qty'=>0, 'gifted_qty'=>0, 'gifted_amount'=>0 ); } $prefix = !empty( $cart_item['wdp_gifted'] ) ? 'gifted_' : ""; // order $order_stats[ $rule_id ][$prefix . 'qty'] += $cart_item['quantity']; $order_stats[ $rule_id ][$prefix . 'amount'] += $amount; // product $product_stats[ $product_id ][ $rule_id ][$prefix . 'qty'] += $cart_item['quantity']; $product_stats[ $product_id ][ $rule_id ][$prefix . 'amount'] += $amount; } } $this->inject_wc_cart_coupon_stats( $wc_cart, $order_stats ); $this->inject_wc_cart_fee_stats( $wc_cart, $order_stats ); $this->inject_wc_cart_shipping_stats( $wc, $order_stats ); return array( $order_stats, $product_stats ); } /** * @param WC_Cart $wc_cart * @param array $order_stats */ private function inject_wc_cart_coupon_stats( $wc_cart, &$order_stats ) { $totals = $wc_cart->get_totals(); $wdp_coupons = isset( $totals['wdp_coupons'] ) ? $totals['wdp_coupons'] : array(); if ( empty( $wdp_coupons ) ) { return; } foreach ( $wc_cart->get_coupon_discount_totals() as $coupon_code => $amount ) { if ( isset( $wdp_coupons['grouped'][ $coupon_code ] ) ) { foreach ( $wdp_coupons['grouped'][ $coupon_code ] as $rule_id => $amount_per_rule ) { $order_stats[ $rule_id ]['extra'] += $amount_per_rule; } } elseif ( isset( $wdp_coupons['single'][ $coupon_code ] ) ) { $rule_id = $wdp_coupons['single'][ $coupon_code ]; $order_stats[ $rule_id ]['extra'] += $amount; } } } /** * @param WC_Cart $wc_cart * @param array $order_stats */ private function inject_wc_cart_fee_stats( $wc_cart, &$order_stats ) { $totals = $wc_cart->get_totals(); $wdp_fees = isset( $totals['wdp_fees'] ) ? $totals['wdp_fees'] : ''; if ( empty( $wdp_fees ) ) { return; } foreach ( $wc_cart->get_fees() as $fee ) { $fee_name = $fee->name; if ( isset( $wdp_fees[ $fee_name ] ) ) { foreach ( $wdp_fees[ $fee_name ] as $rule_id => $fee_amount_per_rule ) { $order_stats[ $rule_id ]['extra'] -= $fee_amount_per_rule; } } } } /** * @param WooCommerce $wc * @param array $order_stats */ private function inject_wc_cart_shipping_stats( $wc, &$order_stats ) { $shippings = $wc->session->get( 'chosen_shipping_methods' ); if ( empty( $shippings ) ) { return; } foreach ( $shippings as $package_id => $shipping_rate_key ) { $packages = $wc->shipping()->get_packages(); if ( isset( $packages[ $package_id ]['rates'][ $shipping_rate_key ] ) ) { /** @var WC_Shipping_Rate $sh_rate */ $sh_rate = $packages[ $package_id ]['rates'][ $shipping_rate_key ]; $sh_rate_meta = $sh_rate->get_meta_data(); if ( isset( $sh_rate_meta['wdp_rule'] ) ) { $rule_id = $sh_rate_meta['wdp_rule']; $amount = $sh_rate_meta['wdp_amount']; $is_free_shipping = $sh_rate_meta['wdp_free_shipping']; $order_stats[ $rule_id ]['shipping'] += $amount; $order_stats[ $rule_id ]['is_free_shipping'] = $is_free_shipping; } } } } private function wdp_get_template( $template_name , $args = array(), $template_path = '' ) { if ( ! empty( $args ) && is_array( $args ) ) { extract( $args ); } $full_template_path = trailingslashit( WC_ADP_PLUGIN_PATH . 'templates' ); if ( $template_path ) { $full_template_path .= trailingslashit( $template_path ); } $full_external_template_path = locate_template( array( 'advanced-dynamic-pricing-for-woocommerce/' . trailingslashit( $template_path ) . $template_name, 'advanced-dynamic-pricing-for-woocommerce/' . $template_name, ) ); if ( $full_external_template_path ) { $full_template_path = $full_external_template_path; } else { $full_template_path .= $template_name; } ob_start(); include $full_template_path; $template_content = ob_get_clean(); return $template_content; } public function load_frontend_assets() { $options = WDP_Helpers::get_settings(); wp_enqueue_style( 'wdp_pricing-table', WC_ADP_PLUGIN_URL . '/assets/css/pricing-table.css', array(), WC_ADP_VERSION ); wp_enqueue_style( 'wdp_deals-table', WC_ADP_PLUGIN_URL . '/assets/css/deals-table.css', array(), WC_ADP_VERSION ); if ( is_product() || woocommerce_product_loop() ) { wp_enqueue_script( 'wdp_deals', WC_ADP_PLUGIN_URL . '/assets/js/frontend.js', array(), WC_ADP_VERSION ); } if ( WDP_Database::is_condition_type_active( array( 'customer_shipping_method' ) ) ) { wp_enqueue_script( 'wdp_update_cart', WC_ADP_PLUGIN_URL . '/assets/js/update-cart.js' , array( 'wc-cart' ), WC_ADP_VERSION ); } $script_data = array( 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'update_price_with_qty' => wc_string_to_bool( $options['update_price_with_qty'] ) && ! wc_string_to_bool($options['do_not_modify_price_at_product_page']), 'js_init_trigger' => apply_filters( 'wdp_bulk_table_js_init_trigger', "" ), ); wp_localize_script( 'wdp_deals', 'script_data', $script_data ); } public function output_amount_save() { $amount_saved = self::get_amount_save_from_items(); if ( 0 >= $amount_saved ) { return null; } $options = WDP_Helpers::get_settings(); $templates = array( 'woocommerce_mini_cart_contents' => 'mini-cart.php', 'woocommerce_cart_totals_before_order_total' => 'cart-totals.php', 'woocommerce_review_order_after_cart_contents' => 'cart-totals-checkout.php', ); $template_content = ''; foreach ( $templates as $hook_name => $template_name ) { if ( current_action() == $hook_name ) { $template_content = $this->wdp_get_template( $template_name, array( 'amount_saved' => $amount_saved, 'title' => $options['amount_saved_label'], ), 'amount-saved' ); } } echo $template_content; } public static function get_amount_save_from_items() { $cart_items = WC()->cart->cart_contents; $amount_saved = 0; foreach ( $cart_items as $cart_item_key => $cart_item ) { if ( ! isset( $cart_item['rules'] ) AND ! isset( $cart_item['wdp_rules'] ) ) { return 0; } $cart_item_rules = isset( $cart_item['rules'] ) ? $cart_item['rules'] : $cart_item['wdp_rules']; foreach ( $cart_item_rules as $id => $amount_saved_by_rule ) { $amount_saved += $amount_saved_by_rule * $cart_item['quantity']; } } return $amount_saved; } /** * @param string $price formatted price after wc_price() * @param array $cart_item * @param string $cart_item_key * * @return string */ public function woocommerce_cart_item_price_and_price_subtotal( $price, $cart_item, $cart_item_key ) { $product = wc_get_product( $cart_item['product_id'] ); if ( ! $product ) { return $price; } $new_price = (float) $cart_item['data']->get_price( 'edit' ); $new_price = $this->price_display->get_cart_item_price_to_display( $product, array( 'price' => $new_price ) ); $new_price_html = $price; if ( ! isset( $cart_item['wdp_original_price'] ) ) { return $price; } $old_price = $cart_item['wdp_original_price']; $old_price = $this->price_display->get_cart_item_price_to_display( $product, array( 'price' => $old_price ) ); if ( 'woocommerce_cart_item_subtotal' == current_filter() ) { $new_price = $new_price * $cart_item['quantity']; $old_price = $old_price * $cart_item['quantity']; } if ( $new_price !== false AND $old_price !== false ) { if ( $new_price < $old_price ) { $price_html = wc_format_sale_price( $old_price, $new_price ); } else { $price_html = $new_price_html; } } else { $price_html = $new_price_html; } return $price_html; } function remove_hooks_set_by_other_plugins() { global $wp_filter; $allowed_hooks = array( //Filters "woocommerce_get_price_html" => array( "WDP_Price_Display|hook_get_price_html" ), "woocommerce_product_is_on_sale" => array( "WDP_Price_Display|hook_product_is_on_sale" ), "woocommerce_product_get_sale_price" => array( "WDP_Price_Display|hook_product_get_sale_price" ), "woocommerce_product_get_regular_price" => array( "WDP_Price_Display|hook_product_get_regular_price" ), "woocommerce_variable_price_html" => array(), "woocommerce_cart_item_price" => array( "WDP_Frontend|woocommerce_cart_item_price_and_price_subtotal" ), "woocommerce_cart_item_subtotal" => array( "WDP_Frontend|woocommerce_cart_item_price_and_price_subtotal" ), //Actions "woocommerce_checkout_order_processed" => array( "WDP_Frontend|checkout_order_processed" ), "woocommerce_before_calculate_totals" => array(), //nothing allowed! ); 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->remove_wrong_callbacks( $hook_obj, $allowed_hooks[ $hook_name ] ); } else { } } } } public static function remove_callbacks( $hook_obj, $hooks ) { $new_callbacks = array(); foreach ( $hook_obj->callbacks as $priority => $callbacks ) { $priority_callbacks = array(); foreach ( $callbacks as $idx => $callback_details ) { if ( ! self::is_callback_match( $callback_details, $hooks ) ) { $priority_callbacks[ $idx ] = $callback_details; } } if ( $priority_callbacks ) { $new_callbacks[ $priority ] = $priority_callbacks; } } $hook_obj->callbacks = $new_callbacks; return $hook_obj; } function remove_wrong_callbacks( $hook_obj, $allowed_hooks ) { $new_callbacks = array(); foreach ( $hook_obj->callbacks as $priority => $callbacks ) { $priority_callbacks = array(); foreach ( $callbacks as $idx => $callback_details ) { if ( self::is_callback_match( $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 class + function name! public static function is_callback_match( $callback_details, $allowed_hooks ) { $result = false; foreach ( $allowed_hooks as $callback_name ) { list( $class_name, $func_name ) = explode( "|", $callback_name ); if ( count( $callback_details['function'] ) != 2 ) { continue; } if ( $class_name == get_class( $callback_details['function'][0] ) AND $func_name == $callback_details['function'][1] ) { $result = true; break;// done! } } return $result; } public function woocommerce_add_to_cart_sold_individually_found_in_cart( $found, $product_id, $variation_id, $cart_item_data, $cart_id ) { foreach ( WC()->cart->get_cart() as $cart_item ) { if ( $cart_item['product_id'] == $product_id ) { return true; } } return false; } private static function get_nopriv_ajax_actions() { return array( 'get_table_with_product_bulk_table', 'get_price_product_with_bulk_table', ); } public static function is_nopriv_ajax_processing() { return wp_doing_ajax() && ! empty( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], self::get_nopriv_ajax_actions() ); } //HELPERS for programmers // public static function get_gifted_cart_products() { $products = array(); foreach ( WC()->cart->get_cart() as $wc_cart_item_key => $wc_cart_item ) { if ( ! empty( $wc_cart_item['wdp_gifted'] ) ) { $product_id = isset( $wc_cart_item['data'] ) ? $wc_cart_item['data']->get_id() : 0; if ( $product_id ) { if ( isset( $products[ $product_id ] ) ) { $products[ $product_id ] += $wc_cart_item['wdp_gifted']; } else { $products[ $product_id ] = $wc_cart_item['wdp_gifted']; } } } } return $products; } public static function get_active_rules_for_product( $product_id, $qty = 1, $use_empty_cart = false ) { $calc = self::make_wdp_calc_from_wc(); $cart = self::make_wdp_cart_from_wc( $use_empty_cart ); return $calc->get_active_rules_for_product( $cart, $product_id, $qty ); } /** * * @param array $array_of_products * array[]['product_id'] * array[]['qty'] * @param boolean $plain Type of returning array. With False returns grouped by rules * * @throws Exception * * @return array */ public static function get_discounted_products_for_cart( $array_of_products, $plain = false ) { if ( ! did_action( 'wp_loaded' ) ) { _doing_it_wrong( __FUNCTION__, sprintf( __( '%1$s should not be called before the %2$s action.', 'woocommerce' ), 'get_discounted_products_for_cart', 'wp_loaded' ), WC_ADP_VERSION ); return array(); } // make calculator $rule_collection = WDP_Rules_Registry::get_instance()->get_active_rules(); $calc = new WDP_Cart_Calculator( $rule_collection ); // make context if ( ! is_null( WC()->customer ) ) { $customer = new WDP_User_Impl( new WP_User( WC()->customer->get_id() ) ); $customer->apply_wc_customer( WC()->customer ); $customer->apply_wc_session( WC()->session ); } else { $customer = new WDP_User_Impl( new WP_User() ); } $environment = array( 'timestamp' => current_time( 'timestamp' ), 'prices_includes_tax' => wc_prices_include_tax(), ); $settings = WDP_Helpers::get_settings(); $context = new WDP_Cart_Context( $customer, $environment, $settings ); // make and fill standalone wc cart include_once WC_ADP_PLUGIN_PATH . 'classes/class-wdp-standalone-cart.php'; $wc_cart = new WDP_Standalone_Cart(); foreach ( $array_of_products as $product_data ) { if ( ! isset( $product_data['product_id'], $product_data['qty'] ) ) { continue; } $product_id = (int) $product_data['product_id']; $qty = (int) $product_data['qty']; $result = $wc_cart->add_to_cart( $product_id, $qty ); } $cart = new WDP_Cart( $context, $wc_cart ); return self::get_matched_products( $calc, $cart, $plain ); } /** * @param WDP_Cart_Calculator $calc * @param WDP_Cart $cart * @param bool $plain * * @return array * @throws Exception */ private static function get_matched_products( $calc, $cart, $plain = false ) { $result = array(); $initial_cart = $cart; foreach ( $calc->get_rule_array() as $rule ) { $rule_result = array(); $cart = clone $initial_cart; // we need conditions! if ( ! $rule->has_conditions() || ! $rule->is_rule_matched_cart($cart) ) { continue; } $dependencies = $rule->get_product_dependencies(); if ( ! count( $dependencies ) ) { continue; } $products_to_add = array(); foreach ( $dependencies as $filter ) { if ( 'products' !== $filter['type'] || 'in_list' !== $filter['method'] ) { continue; } $products_to_add[] = array( 'product_ids' => $filter['values'], 'qty' => $filter['qty'], ); } if ( ! $products_to_add ) { continue; } $products = array(); foreach ( $products_to_add as $product_to_add ) { $product_ids = $product_to_add['product_ids']; $qty = $product_to_add['qty']; foreach ( $product_ids as $product_id ) { if ( ! isset( $products[ $product_id ] ) ) { $product_obj = wc_get_product( $product_id ); $products[ $product_id ] = $product_obj; } else { $product_obj = $products[ $product_id ]; } if ( ! $product_obj ) { continue; } $cart->add_product_to_calculate( $product_obj, $qty ); } } if ( $plain ) { $cart = $calc->process_cart_new( $cart ); } elseif ( ! $calc->process_cart_use_exact_rules( $cart, array( $rule ) ) ) { continue; } foreach ( $products as $product ) { $cart_items = $cart->get_temporary_items_by_product( $product ); foreach ( $cart_items as $cart_item ) { /** * @var $cart_item WDP_Cart_Item */ $rule_result[] = array_merge( array( 'product_id' => $product->get_id() ), array( 'original_price' => $cart_item->get_initial_price(), 'discounted_price' => $cart_item->get_price(), ) ); } } if ( ! $rule_result ) { continue; } if ( $plain ) { if ( ! $result ) { $result = $rule_result; } else { foreach ( $result as &$result_item ) { foreach ( $rule_result as $k => $rule_item ) { if ( $rule_item['product_id'] == $result_item['product_id'] ) { $result_item['discounted_price'] = $result_item['discounted_price'] > $rule_item['discounted_price'] ? $rule_item['discounted_price'] : $result_item['discounted_price']; $result_item['original_price'] = $result_item['original_price'] < $rule_item['original_price'] ? $rule_item['original_price'] : $result_item['original_price']; unset( $rule_result[ $k ] ); $rule_result = array_values( $rule_result ); break; } } } $result = array_merge( $result, $rule_result ); } } else { $result[] = $rule_result; } } return $result; } /** * @param int|WC_product $the_product * @param int $qty * @param bool $use_empty_cart * * @return float|array|null * float for simple product * array is (min, max) range for variable * null if product is incorrect */ public static function get_discounted_product_price( $the_product, $qty, $use_empty_cart = true ) { $price_display = new WDP_Price_Display(); $price_display->apply_calc(); if ( $use_empty_cart ) { $price_display->apply_empty_cart( 'nofilter' ); } else { $price_display->apply_cart( 'nofilter' ); } $wdp_product = $price_display->process_product( $the_product, $qty ); if ( is_null( $wdp_product ) ) { return null; } return $wdp_product->is_variable() ? array( $wdp_product->get_min_price(), $wdp_product->get_max_price() ) : $wdp_product->get_new_price(); } public static function process_without_hooks( $callback, $hooks_list ) { if ( ! $hooks_list ) { return $callback(); } global $wp_filter; $stored_actions = array(); foreach ( $hooks_list as $key ) { if ( isset( $wp_filter[ $key ] ) ) { $stored_actions[ $key ] = $wp_filter[ $key ]; unset( $wp_filter[ $key ] ); } } $result = $callback(); // restore hook foreach ( $hooks_list as $key ) { if ( isset( $stored_actions[ $key ] ) ) { $wp_filter[ $key ] = $stored_actions[ $key ]; } } return $result; } }