PluginProbe
HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce / 2.10.0
HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce v2.10.0
2.15.0 trunk 1.0.0 1.0.1 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1.2 2.1.3 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 All 62 releases
hurrytimer / includes / WCCampaign.php

WCCampaign.php in HurryTimer – An Scarcity and Urgency Countdown Timer for WordPress & WooCommerce 2.10.0, at includes/WCCampaign.php

316 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Hurrytimer;
4
5 class WCCampaign {
6 /**
7 * Returns campaigns with WooCommerce enabled.
8 *
9 * @return array
10 */
11 public function get_wc_campaigns() {
12
13 $args = [
14 'post_type' => HURRYT_POST_TYPE,
15 'numberposts' => -1,
16 'post_status' => 'publish',
17 'meta_query' => [
18 [
19 'key' => 'wc_enable',
20 'value' => C::YES,
21 ]
22 ],
23 ];
24
25 if(defined( 'ICL_SITEPRESS_VERSION' )){
26 $args['suppress_filters'] = false;
27 }
28 $posts = get_posts($args);
29
30 return array_map(function ($post) {
31 return hurryt_get_campaign($post->ID);
32 }, $posts);
33 }
34
35 /**
36 * Run campaign for then given product page.
37 *
38 * @param $product_id
39 */
40 public function run($product_id) {
41 $compaigns = $this->get_wc_campaigns();
42
43 /**
44 * @var Campaign $campaign
45 */
46 foreach ($compaigns as $campaign) {
47 if (!$campaign->is_wc_enabled()) {
48 continue;
49 }
50 if (
51 $this->has_campaign($campaign, $product_id)
52 && $this->met_conditions($campaign, $product_id)
53 ) {
54 do_action('hurryt_pre_render', $campaign);
55 $callback = function () use ($campaign) {
56 $this->render_shortcode($campaign);
57 };
58
59 $position = $campaign->getWcPosition();
60
61
62 // Compatibility with Astra theme v3.9.2 or later
63 if(defined('ASTRA_THEME_VERSION') && version_compare(ASTRA_THEME_VERSION, '3.9.2', '>=')){
64 switch($position) {
65 case C::WC_POSITION_ABOVE_ATC_BUTTON:
66 add_action('astra_woo_single_add_to_cart_before',$callback);
67 break;
68 case C::WC_POSITION_BELOW_ATC_BUTTON:
69 add_action('astra_woo_single_add_to_cart_after',$callback);
70 break;
71 case C::WC_POSITION_BELOW_PRICE:
72 add_action('astra_woo_single_price_after',$callback);
73 break;
74 case C::WC_POSITON_BELOW_REVIEW_RATING:
75 add_action('astra_woo_single_rating_after',$callback);
76 break;
77 case C::WC_POSITION_BELOW_TITLE:
78 add_action('astra_woo_single_title_after',$callback);
79 break;
80 case C::WC_POSITION_ABOVE_TITLE:
81 add_action('astra_woo_single_title_before',$callback);
82 break;
83 default:
84 add_action('woocommerce_single_product_summary', $callback,$position);
85 break;
86 }
87 }
88 else{
89 add_action('woocommerce_single_product_summary', $callback,$position);
90 }
91
92 }
93 }
94 }
95
96 /**
97 * Check if given product has an active campaign.
98 *
99 * @param Campaign $campaign
100 * @param $product_id
101 *
102 * @return bool
103 */
104 public function has_campaign($campaign, $product_id) {
105
106 $cat_ids = $this->get_product_categories($product_id);
107 $type = $campaign->getWcProductsSelectionType();
108 $selection = $campaign->getWcProductsSelection();
109 switch ($type) {
110 case C::WC_PS_TYPE_ALL:
111 return true;
112
113 case C::WC_PS_TYPE_INCLUDE_PRODUCTS:
114 return in_array($product_id, $selection);
115
116 case C::WC_PS_TYPE_EXCLUDE_PRODUCTS:
117 return !in_array($product_id, $selection);
118
119 case C::WC_PS_TYPE_INCLUDE_CATEGORIES:
120 $callback = function ($id) use ($cat_ids) {
121 return in_array($id, $cat_ids);
122 };
123 $results = array_filter($selection, $callback);
124
125 return count($results) > 0;
126
127 case C::WC_PS_TYPE_EXCLUDE_CATEGORIES:
128 $results = array_filter($selection, function ($id) use ($cat_ids) {
129 return !in_array($id, $cat_ids);
130 });
131
132 return count($results) > 0;
133
134 default:
135 return false;
136 }
137 }
138
139 /**
140 * Returns categories ids for the given product.
141 *
142 * @param $product_id
143 *
144 * @return array|\WP_Error
145 */
146 public function get_product_categories($product_id) {
147 return wp_get_object_terms($product_id, 'product_cat', [
148 'fields' => 'ids',
149 ]);
150 }
151
152 /**
153 * Render shortcode for the given campaign ID.
154 *
155 * @param Campaign $campaign
156 */
157 public function render_shortcode($campaign) {
158 $shortcode = '[hurrytimer id=' . $campaign->get_id() . ' ]';
159 echo do_shortcode($shortcode);
160 }
161
162 /**
163 * Change stock status.
164 * TODO: Add support for evergreen campaigns.
165 *
166 * @param Campaign $campaign
167 * @param int $stock_status
168 */
169 public function change_stock_status($campaign, $stock_status) {
170 if (!$campaign->is_wc_enabled()) {
171 return;
172 }
173
174 $products = $this->get_campaign_products($campaign);
175 foreach ($products as $product) {
176 if (
177 $stock_status === C::WC_OUT_OF_STOCK
178 && apply_filters(
179 'hurryt_empty_stock',
180 true,
181 $product->get_id(),
182 $campaign->get_id()
183 )
184 ) {
185 wc_update_product_stock(0); // TODO: test.
186 }
187 if ($product->managing_stock()) {
188 wc_update_product_stock_status($product->get_id(), $stock_status);
189 }
190 }
191 }
192
193 /**
194 * Get campaign's products ID.
195 *
196 * @param Campaign $campaign
197 *
198 * @return array
199 */
200 function get_campaign_products($campaign) {
201 /**
202 * Selected products/categories ids.
203 */
204 $object_ids = $campaign->getWcProductsSelection();
205 /**
206 * @see C
207 */
208 $type = $campaign->getWcProductsSelectionType();
209 /**
210 * @var array $args Products query default args.
211 */
212 $args = ['limit' => -1, 'status' => 'publish'];
213 switch ($type) {
214 case C::WC_PS_TYPE_ALL:
215 return wc_get_products($args);
216 case C::WC_PS_TYPE_EXCLUDE_PRODUCTS:
217 return wc_get_products(array_merge($args, ['exclude' => $object_ids]));
218 case C::WC_PS_TYPE_INCLUDE_PRODUCTS:
219 return wc_get_products(array_merge($args, ['include' => $object_ids]));
220 case C::WC_PS_TYPE_INCLUDE_CATEGORIES:
221 $cat_slugs = get_terms([
222 'taxonomy' => 'product_cat',
223 'include' => $object_ids,
224 'fields' => 'slugs',
225 ]);
226
227 return wc_get_products(array_merge($args, ['category' => $cat_slugs]));
228 case C::WC_PS_TYPE_EXCLUDE_CATEGORIES:
229 $cat_slugs = get_terms([
230 'taxonomy' => 'product_cat',
231 'exclude' => $object_ids,
232 'fields' => 'slugs',
233 ]);
234
235 return wc_get_products(array_merge($args, ['category' => $cat_slugs]));
236 default:
237 return [];
238 }
239 }
240
241 public function met_conditions($campaign, $object_id) {
242 $groups = $campaign->getWcConditions();
243
244 if (empty($groups)) {
245 return true;
246 }
247
248 $product = wc_get_product($object_id);
249 $truthy_conditions = [];
250 $truthy_groups = [];
251 foreach ($groups as $conditions) {
252 foreach ($conditions as $condition) {
253
254 switch ($condition['key']) {
255 case 'stock_status':
256 if ($condition['operator'] === '==') {
257 $truthy_conditions[] = $product->get_stock_status()
258 == $condition['value'];
259 }
260 if ($condition['operator'] === '!=') {
261 $truthy_conditions[] = $product->get_stock_status()
262 != $condition['value'];
263 }
264 break;
265 case 'stock_quantity':
266 if ($condition['operator'] === '==') {
267 $truthy_conditions[] = $product->get_stock_quantity()
268 == $condition['value'];
269 }
270 if ($condition['operator'] === '!=') {
271 $truthy_conditions[] = $product->get_stock_quantity()
272 != $condition['value'];
273 }
274 if ($condition['operator'] === '>') {
275 $truthy_conditions[] = $product->get_stock_quantity()
276 > $condition['value'];
277 }
278 if ($condition['operator'] === '<') {
279 $truthy_conditions[] = $product->get_stock_quantity()
280 < $condition['value'];
281 }
282 break;
283 case 'shipping_class':
284 if ($condition['operator'] === '==') {
285 $truthy_conditions[] = $product->get_shipping_class_id()
286 == $condition['value'];
287 }
288 if ($condition['operator'] === '!=') {
289 $truthy_conditions[] = $product->get_shipping_class_id()
290 != $condition['value'];
291 }
292 break;
293 case 'on_sale':
294 $truthy_conditions[] = filter_var($condition['value'], FILTER_VALIDATE_BOOLEAN) === $product->is_on_sale();
295
296 break;
297
298 default:
299
300 throw new \Exception('Rule [' . $condition['key'] . '] not supported.');
301 }
302 }
303 $is_met = array_filter($truthy_conditions, function ($bool) {
304 return $bool === true;
305 });
306
307 $truthy_groups[] = count($is_met) === count($conditions);
308 }
309 $met = array_filter($truthy_groups, function ($bool) {
310 return $bool === true;
311 });;
312
313 return !empty($met);
314 }
315 }
316