PluginProbe
MailerLite – WooCommerce integration / 1.8.7
MailerLite – WooCommerce integration v1.8.7
3.1.27 3.1.25 3.1.26 3.1.24 3.1.23 3.1.22 3.1.21 3.1.20 3.1.19 3.1.18 3.1.17 3.1.16 3.1.15 1.8.7 1.8.8 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 All 148 releases
woo-mailerlite / includes / classes / settings / SynchronizeSettings.php

SynchronizeSettings.php in MailerLite – WooCommerce integration 1.8.7, at includes/classes/settings/SynchronizeSettings.php

627 lines 20.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace MailerLite\Includes\Classes\Settings;
4
5 use MailerLite\Includes\Classes\Data\TrackingData;
6 use MailerLite\Includes\Classes\Process\OrderProcess;
7 use MailerLite\Includes\Classes\Process\ProductProcess;
8 use MailerLite\Includes\Classes\Singleton;
9 use MailerLite\Includes\Shared\Api\ApiType;
10 use MailerLite\Includes\Shared\Api\PlatformAPI;
11
12 class SynchronizeSettings extends Singleton
13 {
14
15 /**
16 * Class instance
17 * @var $instance
18 */
19 protected static $instance;
20
21
22 /**
23 * Bulk synchronize untracked products
24 * woo_ml_sync_untracked_products
25 * @return array
26 */
27 public function syncUntrackedProducts()
28 {
29
30 set_time_limit(600);
31
32 $message = 'Oops, we did not manage to sync all of your products, please try again.';
33
34 try {
35
36 $checkProducts = TrackingData::getInstance()->getUntrackedProducts();
37
38 $mailerliteClient = new PlatformAPI(MAILERLITE_WP_API_KEY);
39
40 if (is_array($checkProducts) && sizeof($checkProducts) > 0) {
41
42 $shop = get_option('woo_ml_shop_id', false);
43
44 if ($shop === false) {
45
46 return [
47 'error' => true,
48 'message' => 'Shop is not activated.'
49 ];
50 }
51
52 $syncProducts = [];
53
54 foreach ($checkProducts as $post) {
55
56 if (!isset($post->ID)) {
57 continue;
58 }
59
60 $product = wc_get_product($post->ID);
61
62 $productID = $product->get_id();
63 $productName = $product->get_name() ?: 'Untitled product';
64 $productPrice = floatval($product->get_price('edit'));
65 $productImage = ProductProcess::getInstance()->productImage($product);
66
67 $productURL = $product->get_permalink();
68
69 $categories = get_the_terms($productID, 'product_cat');
70
71 $productCategories = [];
72
73 foreach ($categories as $category) {
74
75 if (isset($category->term_id) && is_numeric($category->term_id)) {
76 if(!in_array((string) $category->term_id, $productCategories)) {
77 $productCategories[] = (string)$category->term_id;
78 }
79 }
80 }
81
82 $exclude_automation = get_post_meta($productID, '_woo_ml_product_ignored', true) === "1";
83
84 $syncProduct = [
85 'resource_id' => (string)$productID,
86 'name' => $productName,
87 'price' => $productPrice,
88 'url' => $productURL,
89 'exclude_from_automations' => $exclude_automation,
90 'categories' => $productCategories
91 ];
92
93 if (!empty($productImage)) {
94
95 $syncProduct['image'] = (string)$productImage;
96 }
97
98
99 $syncProducts[] = $syncProduct;
100 }
101
102 $syncCount = 0;
103
104 if (count($syncProducts) > 0) {
105
106 $result = $mailerliteClient->importProducts($shop, $syncProducts);
107
108 if (empty($result) || $mailerliteClient->responseCode() == 422 || $mailerliteClient->responseCode() == 500) {
109
110 $errorMsg = json_decode($mailerliteClient->getResponseBody());
111 $message = 'Oops, we did not manage to sync all of your products, please try again. (' . $mailerliteClient->responseCode() . ')';
112
113 if ($mailerliteClient->responseCode() == 422 && isset($errorMsg->message)) {
114
115 $message = $errorMsg->message;
116 }
117
118 return [
119 'error' => true,
120 'code' => $mailerliteClient->responseCode(),
121 'message' => $message
122 ];
123 }
124
125 if ($mailerliteClient->responseCode() == 201 || $mailerliteClient->responseCode() == 200) {
126
127 foreach ($syncProducts as $product) {
128
129 MailerLiteSettings::getInstance()->completeProductTracking($product['resource_id']);
130 $syncCount++;
131 }
132 }
133 }
134
135 return [
136 'completed' => $syncCount,
137 'code' => $mailerliteClient->responseCode()
138 ];
139
140 }
141
142 return [];
143 } catch (\Exception $e) {
144 return [
145 'error' => true,
146 'message' => $message
147 ];
148 }
149 }
150
151 /**
152 * Bulk synchronize untracked resources
153 * woo_ml_sync_untracked_resources
154 * @return bool
155 * @throws Exception
156 */
157 public function syncUntrackedResources()
158 {
159 $trackingData = TrackingData::getInstance();
160 if ((int)get_option('woo_mailerlite_platform', 1) === ApiType::CURRENT) {
161 $untracked_categories_count = $trackingData->getUntrackedCategoriesCount();
162
163 if ($untracked_categories_count > 0) {
164
165 return json_encode(array_merge([
166 'allDone' => false,
167 ], $this->syncUntrackedCategories()));
168 }
169
170 $untracked_products_count = $trackingData->getUntrackedProductsCount();
171
172 if ($untracked_products_count > 0) {
173
174 return json_encode(array_merge([
175 'allDone' => false,
176 ], $this->syncUntrackedProducts()));
177 }
178 }
179
180 $untracked_customers_count = $trackingData->getUntrackedCustomersCount();
181
182 if ($untracked_customers_count > 0) {
183 return json_encode(array_merge([
184 'allDone' => false,
185 ], $this->syncUntrackedCustomers()));
186 }
187
188 //reset after all customers are synced
189 WC()->session->set('untracked_customer_page', null);
190 return json_encode([
191 'allDone' => true,
192 'completed' => 0,
193 ]);
194 }
195
196 /**
197 * Bulk synchronize untracked customers
198 * woo_ml_sync_untracked_customers
199 * @return array
200 * @throws Exception
201 */
202 public function syncUntrackedCustomers()
203 {
204
205 set_time_limit(600);
206
207 $message = 'Oops, we did not manage to sync all of your customers, please try again.';
208
209 try {
210
211 $customers = [];
212
213 $page = WC()->session->get('untracked_customer_page');
214 $trackingData = TrackingData::getInstance();
215 if (is_null($page)) {
216 $untracked_customers_count = $trackingData->getUntrackedCustomersCount();
217 $total_customers_count = $trackingData->getCustomersCount();
218
219 if ($total_customers_count == $untracked_customers_count) {
220
221 // start sync all, including guest to initial setup
222 $page = 1;
223
224 $customers = $trackingData->getAllCustomers($page);
225 } else {
226
227 // resume/update sync
228 $customers = $trackingData->getUntrackedCustomers();
229 }
230 } else {
231
232 $customers = $trackingData->getAllCustomers($page);
233
234 }
235
236 $mailerliteClient = new PlatformAPI(MAILERLITE_WP_API_KEY);
237
238 $shop = get_option('woo_ml_shop_id', false);
239
240 if ($shop === false && $mailerliteClient->getApiType() == ApiType::CURRENT) {
241
242 return [
243 'error' => true,
244 'message' => 'Shop is not activated.'
245 ];
246 }
247
248 if (empty($customers)) {
249
250 WC()->session->set('untracked_customer_page', null);
251
252 return [
253 'allDone' => true,
254 'completed' => 0,
255 ];
256 }
257
258 $syncCount = 0;
259
260 $syncCustomers = [];
261
262 foreach ($customers as $customer) {
263
264 //initialise empty sync array
265 $syncCustomer = [];
266
267 // if 'user_id' is not set, set 'id' to 'user_id'
268 if (!isset($customer['user_id']) || ($customer['user_id'] == 0)) {
269 $customer['user_id'] = $customer['id'];
270 }
271
272 $wc_customer = new \WC_Customer($customer['user_id']);
273
274 //set resource id
275 $syncCustomer['resource_id'] = (string) $customer['user_id'];
276
277 // if customer does not contain email key find email by wc_customer
278 if (!isset($customer['email']) && !empty($wc_customer->get_billing_email())) {
279
280 $customerEmail = $wc_customer->get_billing_email();
281 } else {
282 $customerEmail = $customer['email'];
283 }
284
285 // fetch customer by email (to get all customers having same email)
286 $customerWithOrders = \WC_Data_Store::load('report-customers')->get_data([
287 'order_before' => null,
288 'order_after' => null,
289 'searchby' => 'email',
290 'search' => $customerEmail,
291 ])->data;
292
293 // initialise values
294 $syncCustomer['email'] = $customerEmail;
295 $syncCustomer['create_subscriber'] = true;
296 $syncCustomer['orders_count'] = 0;
297 $syncCustomer['total_spent'] = 0;
298
299
300 // loop through customers and get order details
301 foreach ($customerWithOrders as $value) {
302 if (!isset($customer['email'])) {
303 $customer = $value;
304 }
305 // set wc_customer if the customer is registered and use those values for sync
306 if (!isset($value['user_id']) || ($value['user_id'] == 0)) {
307 $value['user_id'] = $value['id'];
308 }
309
310 // initialise $wc_customer to get details of registered customer (if exists)
311 if(empty($wc_customer->get_id())) {
312 $wc_customer = new \WC_Customer($value['user_id']);
313 }
314
315 // set last order date
316 if ( ! isset($customerWithOrders['last_order_date'])) {
317 $customerWithOrders['last_order_date'] = $value['date_last_order'];
318 }
319
320 // update last order date
321 if ($customerWithOrders['last_order_date'] < $value['date_last_order']) {
322 $customerWithOrders['last_order_date'] = $value['date_last_order'];
323 }
324
325 // set orders count and spend
326 $syncCustomer['orders_count'] += $value['orders_count'] ?? 0;
327 $syncCustomer['total_spent'] += $value['total_spend'] ?? 0;
328
329 }
330
331
332 // if customer is registered
333 if (! empty($wc_customer->get_id())) {
334 // get subscriber fields from wc_customer
335 $syncCustomer['subscriber_fields'] = [
336 'name' => $wc_customer->get_first_name(),
337 'last_name' => $wc_customer->get_last_name(),
338 'company' => $wc_customer->get_billing_company(),
339 'city' => $wc_customer->get_billing_city(),
340 'state' => $wc_customer->get_billing_state(),
341 'country' => $wc_customer->get_billing_country(),
342 'phone' => $wc_customer->get_billing_phone()
343 ];
344
345 } else {
346 // get guest checkout customer details
347 $syncCustomer['subscriber_fields'] = [
348 'name' => $customer['name'],
349 'last_name' => $customer['last_name'] ?? '',
350 'company' => $customer['company'] ?? '',
351 'city' => $customer['city'],
352 'state' => $customer['state'],
353 'country' => $customer['country'],
354 'phone' => $customer['phone'] ?? '',
355 ];
356 }
357
358 // classic ZIP field is different
359 if ($mailerliteClient->getApiType() == ApiType::CURRENT) {
360 $syncCustomer['subscriber_fields']['z_i_p'] = $wc_customer->get_billing_postcode() ?? $customer['postcode'];
361 } else {
362 $syncCustomer['subscriber_fields']['zip'] = $wc_customer->get_billing_postcode() ?? $customer['postcode'];
363 }
364
365 // get all orders of customer
366 $orders = wc_get_orders([
367 'email' => $customerEmail,
368 'limit' => -1,
369 ]);
370
371 // initialise array for last order date and id
372 $last_order = [];
373
374 // loop through orders to get last order id and date
375 foreach ($orders as $value) {
376 if ( ! isset($last_order['date'])) {
377 $last_order['date'] = $value->get_date_created()->date_i18n('Y-m-d H:i:s');
378 $last_order['id'] = $value->get_id();
379 }
380
381 if ($last_order['date'] < $value->get_date_created()->date_i18n('Y-m-d H:i:s')) {
382 $last_order['date'] = $value->get_date_created()->date_i18n('Y-m-d H:i:s');
383 $last_order['id'] = $value->get_id();
384 }
385 }
386
387 // set last order date and id
388 $syncCustomer['last_order_id'] = $last_order['id'] ?? 0;
389 $syncCustomer['last_order'] = $last_order['date'] ?? '';
390
391 //update meta fields
392 if ($wc_customer->meta_exists('_woo_ml_subscribe')) {
393 $syncCustomer['accepts_marketing'] = $wc_customer->get_meta('_woo_ml_subscribe');
394 } else {
395 if ($last_order['id']) {
396 $syncCustomer['accepts_marketing'] = OrderProcess::getInstance()->orderCustomerSubscribe($last_order['id']);
397 }
398 }
399
400 // add customer to sync list
401 $syncCustomers[] = $syncCustomer;
402
403 if(!empty($wc_customer->get_id())) {
404 $wc_customer->add_meta_data('_woo_ml_customer_tracked', true, true);
405 $wc_customer->save_meta_data();
406 }
407 }
408
409 if (count($syncCustomers) > 0) {
410
411 if ($mailerliteClient->getApiType() == ApiType::CLASSIC) {
412
413 foreach ($syncCustomers as $syncCustomer) {
414
415 $subscriber_fields = $syncCustomer['subscriber_fields'];
416
417 $subscriber_fields['woo_orders_count'] = $syncCustomer['orders_count'];
418 $subscriber_fields['woo_total_spent'] = $syncCustomer['total_spent'];
419 $subscriber_fields['woo_last_order'] = $syncCustomer['last_order'];
420 $subscriber_fields['woo_last_order_id'] = $syncCustomer['last_order_id'];
421
422 $store = home_url();
423
424 $subscriber_updated = $mailerliteClient->syncCustomer($store, $syncCustomer['resource_id'],
425 $syncCustomer['email'], $subscriber_fields);
426
427 if (isset($subscriber_updated->updated_subscriber)) {
428 // used for updating order meta
429 }
430
431 $syncCount++;
432 }
433 }
434
435 if ($mailerliteClient->getApiType() == ApiType::CURRENT) {
436
437 $result = $mailerliteClient->importCustomers($shop, $syncCustomers);
438
439 if ($mailerliteClient->responseCode() !== 200) {
440
441 $errorMsg = json_decode($mailerliteClient->getResponseBody());
442 $message = 'Oops, we did not manage to sync all of your customers, please try again. (' . $mailerliteClient->responseCode() . ')';
443
444 if ($mailerliteClient->responseCode() == 422 && isset($errorMsg->message)) {
445
446 $message = $errorMsg->message;
447 }
448
449 return [
450 'error' => true,
451 'code' => $mailerliteClient->responseCode(),
452 'message' => $message
453 ];
454 }
455
456 $syncCount += count($result);
457 }
458 }
459
460 return [
461 'completed' => $syncCount,
462 'data' => $syncCustomers
463 ];
464 } catch (\Exception $e) {
465 return [
466 'error' => true,
467 'message' => $message
468 ];
469 }
470 }
471
472 /**
473 * Bulk synchronize untracked categories
474 * woo_ml_sync_untracked_categories
475 * @return array
476 */
477 public function syncUntrackedCategories()
478 {
479
480 set_time_limit(600);
481
482 try {
483
484 $syncCount = 0;
485
486 $checkCategories = TrackingData::getInstance()->getUntrackedCategories();
487
488 $mailerliteClient = new PlatformAPI(MAILERLITE_WP_API_KEY);
489
490 if (is_array($checkCategories) && sizeof($checkCategories) > 0) {
491
492 $shop = get_option('woo_ml_shop_id', false);
493
494 if ($shop === false) {
495
496 return [
497 'error' => true,
498 'message' => 'Shop is not activated.'
499 ];
500 }
501
502 $importCategories = [];
503
504 foreach ($checkCategories as $category) {
505
506 if (!isset($category->term_id)) {
507 continue;
508 }
509
510 $importCategories[] = [
511 'name' => $category->name,
512 'resource_id' => (string)$category->term_id
513 ];
514 }
515
516 if (count($importCategories) > 0) {
517
518 $result = $mailerliteClient->importCategories($shop, $importCategories);
519
520 if ($mailerliteClient->responseCode() !== 200) {
521
522 return [
523 'error' => true,
524 ];
525 }
526
527 foreach ($result as $category) {
528
529 MailerLiteSettings::getInstance()->completeCategoryTracking($category->resource_id,
530 $category->id);
531 $syncCount++;
532 }
533 }
534 }
535
536 return [
537 'completed' => $syncCount,
538 ];
539 } catch (\Exception $e) {
540
541 return [
542 'error' => true,
543 ];
544 }
545 }
546
547 /**
548 * Call to handle product, order and customer restore event
549 * mailerlite_wp_sync_post_restore
550 */
551 public function syncPostRestore($post_id)
552 {
553
554 $post_type = get_post_type($post_id);
555
556 switch ($post_type) {
557 case 'product':
558 case 'shop_order':
559 // Skip, nothing to restore
560 break;
561 default:
562 // skip
563 break;
564 }
565 }
566
567 /**
568 * Call to handle product, order and customer delete event
569 * mailerlite_wp_sync_post_delete
570 */
571 public function syncPostDelete($post_id)
572 {
573
574 $mailerliteClient = new PlatformAPI(MAILERLITE_WP_API_KEY);
575
576 if ($mailerliteClient->getApiType() === ApiType::CURRENT) {
577
578 $post_type = get_post_type($post_id);
579
580 $shop = get_option('woo_ml_shop_id', false);
581
582 if ($shop === false) {
583
584 return false;
585 }
586
587 switch ($post_type) {
588 case 'shop_order':
589
590 $mailerliteClient->deleteOrder($shop, $post_id);
591 break;
592 case 'product':
593
594 $mailerliteClient->deleteProduct($shop, $post_id);
595 break;
596 default:
597 // skip
598 break;
599 }
600 }
601 }
602
603 /**
604 * Call to handle product, order and customer trash event
605 * mailerlite_wp_sync_post_trash
606 */
607 public function syncPostTrash($post_id)
608 {
609
610 $mailerliteClient = new PlatformAPI(MAILERLITE_WP_API_KEY);
611
612 if ($mailerliteClient->getApiType() === ApiType::CURRENT) {
613
614 $post_type = get_post_type($post_id);
615
616 switch ($post_type) {
617 case 'product':
618 case 'shop_order':
619 // Skip trash
620 break;
621 default:
622 // skip
623 break;
624 }
625 }
626 }
627 }