PluginProbe
MailerLite – WooCommerce integration / 1.8.8
MailerLite – WooCommerce integration v1.8.8
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.8, at includes/classes/settings/SynchronizeSettings.php

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