View difference between Paste ID: 7NnjPL5S and dF8vGUh6
SHOW: | | - or go back to the newest paste.
1
/**
2-
 * WooCommerce Memberships - Fix double discount issue
2+
 * YITH Bundles - Aelia Currency Switcher Integration (PROTOTYPE)
3-
 * The following code snippet aims to fix the issue of discounts being applied twice by the WooCommerce
3+
 * The following code is a prototype for the development of an integration between the YITH Bundles
4-
 * Memberships plugin when the Aelia Currency Switcher is active.
4+
 * plugin and the Aelia Currency Switcher.
5
 * 
6
 * IMPORTANT
7
 * This code should only be used when the Aelia Currency Switcher is active. Please remember to disable
8
 * or remove it if you deactivate or uninstall our plugin.
9
 *
10
 * DISCLAIMER
11
 * Aelia and any member of its staff are not responsible for any data loss or damage incurred
12
 * when using the code, which you can use at your own risk.
13
 *
14
 * GPL DISCLAIMER
15
 * Because this code program is free of charge, there is no warranty for it, to the extent permitted by applicable law.
16
 * Except when otherwise stated in writing the copyright holders and/or other parties provide the program "as is"
17
 * without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of
18
 * merchantability and fitness for a particular purpose. The entire risk as to the quality and performance of the program
19
 * is with you. should the program prove defective, you assume the cost of all necessary servicing, repair or correction.
20
 *
21
 * Need a consultation, or assistance to customise this code? Find us on Codeable: https://aelia.co/hire_us
22
 */
23-
add_action('wc_memberships_discounts_enable_price_adjustments', function() {
23+
namespace Aelia\WC\CurrencySwitcher\YITH_Bundles;
24-
  // Fetch the instance of the discount calculator used by the Memberships plugin
24+
if(!defined('ABSPATH')) exit; // Exit if accessed directly
25-
  $wcm_discounts = wc_memberships()->get_member_discounts_instance();
25+
26
use \WC_Aelia_CurrencySwitcher;
27-
  // Fetch the priority used by the filters of the Memberships plugin
27+
use \WC_Aelia_CurrencyPrices_Manager;
28-
  $priority = apply_filters('wc_memberships_price_adjustments_filter_priority', 999);
28+
use \WC_Product;
29
use \WC_Product_Yith_Bundle;
30-
  // Remove the filters used by the Memberships plugin to calculate the variation
30+
31-
  // prices for the price range of variable products. Those filters are not
31+
32-
  // needed when the Aelia Currency Switcher is active. The multi-currency price 
32+
 * Implements support for YITH Bundles plugin.
33-
  // calculation triggers the processing of Memberships discounts while converting 
33+
34-
  // the variations' base prices.
34+
class YITH_Bundles_Integration {
35-
  remove_filter('woocommerce_variation_prices_sale_price', array($wcm_discounts, 'get_member_variation_price' ), $priority, 3 );
35+
	protected static $_instance;
36-
  remove_filter('woocommerce_variation_prices_price', array($wcm_discounts, 'get_member_variation_price' ), $priority, 3 );
36+
37-
  remove_filter('woocommerce_variation_prices_regular_price', array($wcm_discounts, 'get_member_variation_regular_price' ), $priority, 3 );
37+
	// @var WC_Aelia_CurrencyPrices_Manager The object that handles Currency Prices for the Products.
38-
}, 99);
38+
	protected static $_currencyprices_manager;
39
40
	/**
41
	 * Returns the singleton instance of this class
42
	 *
43
	 * @return YITH_Bundles_Integration
44
	 */
45
	public static function instance() {
46
		if(empty(self::$_instance)) {
47
			self::$_instance = new static();
48
		}
49
		return self::$_instance;
50
	}
51
52
	/**
53
	 * Returns the instance of the currency prices manager class.
54
	 *
55
	 * @return WC_Aelia_CurrencyPrices_Manager
56
	 */
57
	protected static function currencyprices_manager() {
58
		if(empty(self::$_currencyprices_manager)) {
59
			self::$_currencyprices_manager = \WC_Aelia_CurrencyPrices_Manager::instance();
60
		}
61
		return self::$_currencyprices_manager;
62
	}
63
64
	/**
65
	 * Indicates if a bundle is priced on a per product basis.
66
	 *
67
	 * @param WC_Product product The bundle product to check.
68
	 * @return bool
69
	 */
70
	protected function is_bundle_priced_individually($product) {
71
		return !empty($product->per_items_pricing);
72
	}
73
74
	/**
75
	 * Class constructor
76
	 */
77
	public function __construct() {
78
		$this->set_hooks();
79
	}
80
81
	/**
82
	 * Set the hooks required by the class.
83
	 */
84
	protected function set_hooks() {
85
		add_filter('wc_aelia_currencyswitcher_product_convert_callback', array($this, 'wc_aelia_currencyswitcher_product_convert_callback'), 10, 2);
86
		add_action('woocommerce_process_product_meta_yith_bundle', array($this, 'woocommerce_process_product_meta_yith_bundle'));
87
	}
88
89
	/**
90
	 * Callback to perform the conversion of bundle prices into selected currency.
91
	 *
92
	 * @param callable $convert_callback A callable, or null.
93
	 * @param WC_Product The product to examine.
94
	 * @return callable
95
	 */
96
	public function wc_aelia_currencyswitcher_product_convert_callback($convert_callback, $product) {
97
		$method_keys = array(
98
			'WC_Product_Yith_Bundle' => 'yith_bundle',
99
		);
100
101
		// Determine the conversion method to use
102
		$method_key = isset($method_keys[get_class($product)]) ? $method_keys[get_class($product)] : '';
103
		$convert_method = 'convert_' . $method_key . '_product_prices';
104
105
		if(!method_exists($this, $convert_method)) {
106
			return $convert_callback;
107
		}
108
		return array($this, $convert_method);
109
	}
110
111
	/**
112
	 * Indicates if a product requires conversion.
113
	 *
114
	 * @param WC_Product product The product to process.
115
	 * @param string currency The target currency for which product prices will
116
	 * be requested.
117
	 * @return bool
118
	 */
119
	protected function product_requires_conversion($product, $currency) {
120
		// If the product is already in the target currency, it doesn't require
121
		// conversion
122
		return empty($product->currency) || ($product->currency != $currency);
123
	}
124
125
	/**
126
	 * Converts the prices of a bundle product to the specified currency.
127
	 *
128
	 * @param WC_Product_Yith_Bundle product A variable product.
129
	 * @param string currency A currency code.
130
	 * @return WC_Product_Yith_Bundle The product with converted prices.
131
	 */
132
	public function convert_yith_bundle_product_prices(WC_Product_Yith_Bundle $product, $currency) {
133
		if(!$this->product_requires_conversion($product, $currency)) {
134
			return $product;
135
		}
136
137
		if(!$this->is_bundle_priced_individually($product)) {
138
			$product = self::currencyprices_manager()->convert_simple_product_prices($product, $currency);
139
		}
140
141
		return $product;
142
	}
143
144
	/*** Manual pricing of bundles ***/
145
	/**
146
	 * Event handler fired when a bundle is being saved. It processes and
147
	 * saves the Currency Prices associated with the bundle.
148
	 *
149
	 * @param int post_id The ID of the Post (bundle) being saved.
150
	 */
151
	public function woocommerce_process_product_meta_yith_bundle($post_id) {
152
		self::currencyprices_manager()->process_product_meta($post_id);
153
	}
154
}
155
156
YITH_Bundles_Integration::instance();