PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.3.1
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.3.1
3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 All 156 releases
notificationx / includes / Extensions / Tutor / Tutor.php

Tutor.php in NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar 3.3.1, at includes/Extensions/Tutor/Tutor.php

551 lines 19.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Tutor Extension
5 *
6 * @package NotificationX\Extensions
7 */
8
9 namespace NotificationX\Extensions\Tutor;
10
11 use NotificationX\Core\Helper;
12 use NotificationX\Core\Rules;
13 use NotificationX\GetInstance;
14 use NotificationX\Extensions\Extension;
15 use NotificationX\Extensions\GlobalFields;
16
17 /**
18 * Tutor Extension
19 * @method static Tutor get_instance($args = null)
20 */
21 class Tutor extends Extension {
22 /**
23 * Instance of Admin
24 *
25 * @var Admin
26 */
27 use GetInstance;
28
29 public $priority = 5;
30 public $id = 'tutor';
31 public $img = NOTIFICATIONX_ADMIN_URL . 'images/extensions/sources/tutor.png';
32 public $doc_link = 'https://notificationx.com/docs/tutor-lms/';
33 public $types = 'elearning';
34 public $module = 'modules_tutor';
35 public $module_priority = 7;
36 public $function = 'tutor_lms';
37
38 /**
39 * Initially Invoked when initialized.
40 */
41 public function __construct() {
42 parent::__construct();
43 }
44
45 public function init_extension()
46 {
47 $this->title = __('Tutor', 'notificationx');
48 $this->module_title = __('Tutor LMS', 'notificationx');
49 }
50
51 /**
52 * This functions is hooked
53 *
54 * @hooked nx_public_action
55 * @return void
56 */
57 public function public_actions() {
58 parent::public_actions();
59
60 $monetize_by = 'free';
61 $temp_monetize_by = tutils()->get_option('monetize_by');
62 if (!empty($temp_monetize_by)) {
63 $monetize_by = $temp_monetize_by;
64 }
65 // public actions will be here
66 if (class_exists('WooCommerce') && $monetize_by === 'wc') {
67 add_action('woocommerce_new_order_item', array($this, 'save_new_enrollment'), 10, 3);
68 }
69 // public actions will be here
70 if (class_exists('Easy_Digital_Downloads') && $monetize_by === 'edd') {
71 add_action('edd_update_payment_status', array($this, 'save_new_enroll_payment_status'), 10, 3);
72 }
73
74 if (
75 $monetize_by === 'free' ||
76 (!class_exists('WooCommerce') && $monetize_by === 'wc') ||
77 (!class_exists('Easy_Digital_Downloads') && $monetize_by === 'edd')
78 ) {
79 add_action('tutor_after_enroll', array($this, 'do_enroll'), 10, 2);
80 }
81 }
82
83 /**
84 * This functions is hooked
85 *
86 * @hooked nx_admin_action
87 * @return void
88 */
89 public function admin_actions() {
90 parent::admin_actions();
91 $monetize_by = tutils()->get_option('monetize_by');
92 // admin actions will be here ...
93 if (class_exists('WooCommerce') && $monetize_by == 'wc') {
94 add_action('woocommerce_order_status_changed', array($this, 'status_transition'), 10, 4);
95 }
96 }
97
98 /**
99 * Image action callback
100 *
101 * @param array $image_data
102 * @param array $data
103 * @param array $settings
104 * @return array
105 */
106 // @todo Something
107 public function notification_image($image_data, $data, $settings) {
108 if(!$settings['show_default_image']){
109 switch ($settings['show_notification_image']) {
110 case 'featured_image':
111 $image_data['url'] = get_the_post_thumbnail_url($data['product_id'], 'thumbnail');
112 $image_data['alt'] = !empty($data['title']) ? $data['title'] : '';
113 break;
114 case 'gravatar':
115 if(!empty($data['user_id'])){
116 $image_data['url'] = get_avatar_url($data['user_id'], array('size' => '100'));
117 $image_data['alt'] = !empty($data['name']) ? $data['name'] : '';
118 }
119 }
120 }
121 return $image_data;
122 }
123
124 public function source_error_message($messages) {
125 if (!$this->class_exists()) {
126 $url = admin_url('plugin-install.php?s=tutor&tab=search&type=term');
127 $messages[$this->id] = [
128 'message' => sprintf( '%s <a href="%s" target="_blank">%s</a> %s',
129 __( 'You have to install', 'notificationx' ),
130 $url,
131 __( 'Tutor LMS', 'notificationx' ),
132 __( 'plugin first.', 'notificationx' )
133 ),
134 'html' => true,
135 'type' => 'error',
136 'rules' => Rules::is('source', $this->id),
137 ];
138 }
139 return $messages;
140 }
141
142 /**
143 * This function is generate and save a new notification when user enroll in a new course
144 *
145 * @param int $user_id
146 * @param int $course_id
147 * @return void
148 */
149 public function save_new_enrollment($item_id, $item, $order_id) {
150 $single_notification = $this->ordered_product($item_id, $item, $order_id);
151 if (!empty($single_notification)) {
152 $key = $order_id . '-' . $item_id;
153 $this->update_notification(
154 array(
155 'source' => $this->id,
156 'entry_key' => $key,
157 'data' => $single_notification,
158 )
159 );
160 return true;
161 }
162 return false;
163 }
164
165 public function save_new_enroll_payment_status($payment_id, $new_status, $old_status) {
166 if ($new_status !== 'publish') {
167 return;
168 }
169
170 $data = array();
171 $offset = get_option('gmt_offset');
172 $payment = new \EDD_Payment($payment_id);
173 $cart_details = $payment->cart_details;
174 $user_info = $payment->user_info;
175
176 unset($user_info['id']);
177 unset($user_info['discount']);
178 unset($user_info['address']);
179
180 $user_info['name'] = $this->name($user_info['first_name'], $user_info['last_name']);
181 $user_info['timestamp'] = strtotime($payment->date) - ($offset * 60 * 60);
182 $user_info['ip'] = $payment->ip;
183
184 if (is_array($cart_details)) {
185 foreach ($cart_details as $cart_index => $download) {
186 $if_has_course = tutor_utils()->product_belongs_with_course($download['id']);
187 if ($if_has_course) {
188 $data['title'] = $download['name'];
189 $course_id = $if_has_course->post_id;
190 $data['link'] = get_permalink($course_id);
191 $data['product_id'] = $course_id;
192 $key = $payment->key . '-' . $download['id'];
193 $notification = array_merge($user_info, $data);
194 return $this->update_notification(
195 array(
196 'source' => $this->id,
197 'entry_key' => $key,
198 'data' => $notification,
199 )
200 );
201 }
202 }
203 }
204 }
205
206 public function do_enroll($course_id, $isEnrolled) {
207 $user_id = get_current_user_id();
208 $userdata = get_userdata($user_id);
209 $data = array();
210 if (isset($_SERVER['REMOTE_ADDR'])) {
211 $user_ip = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
212 $data['ip'] = $user_ip;
213 }
214 $data['first_name'] = $userdata->first_name;
215 $data['last_name'] = $userdata->last_name;
216 $data['name'] = $userdata->display_name;
217 $data['email'] = $userdata->user_email;
218 $data['title'] = get_the_title($course_id);
219 $data['link'] = get_permalink($course_id);
220 $data['product_id'] = $course_id;
221 $data['timestamp'] = time();
222
223 if (!empty($data)) {
224 $key = $course_id . '-' . $isEnrolled;
225 return $this->update_notification(
226 array(
227 'source' => $this->id,
228 'entry_key' => $key,
229 'data' => $data,
230 )
231 );
232 }
233 }
234
235 public function ready_enrolled_data($enrolled_data) {
236 $userdata = get_userdata($enrolled_data->post_author);
237 $data = array();
238
239 $meta_info = metadata_exists('post', $enrolled_data->ID, '_tutor_enrolled_by_order_id');
240 $order_id = 0;
241 if ($meta_info == true) {
242 $order_id = get_post_meta($enrolled_data->ID, '_tutor_enrolled_by_order_id', true);
243 }
244 $user_data = $this->user_data_by($enrolled_data->post_author, $order_id);
245
246 $data['title'] = get_the_title($enrolled_data->post_parent);
247 $data['link'] = get_permalink($enrolled_data->post_parent);
248 $data['product_id'] = $enrolled_data->post_parent;
249 $data['timestamp'] = get_gmt_from_date($enrolled_data->post_date);
250 $data = array_merge($data, $user_data);
251
252 if (!empty($data)) {
253 return $data;
254 }
255 }
256
257 protected function user_data_by($user_id = 0, $order_id = 0) {
258 $data = array();
259
260 if ($user_id != 0 && $order_id === 0) {
261 $userdata = get_userdata($user_id);
262 $data['first_name'] = $userdata->first_name;
263 $data['last_name'] = $userdata->last_name;
264 $data['name'] = $this->name($userdata->first_name, $userdata->last_name);
265
266 $data['email'] = $userdata->user_email;
267 }
268
269 if ($order_id && class_exists('WC_Order')) {
270 $order = wc_get_order($order_id);
271 if ($order) {
272 $date = $order->get_date_created();
273 $first_name = $last_name = $email = '';
274 $first_name = $order->get_billing_first_name();
275 $last_name = $order->get_billing_last_name();
276 $email = $order->get_billing_email();
277 $data['first_name'] = $first_name;
278 $data['last_name'] = $last_name;
279 $data['name'] = $this->name($first_name, $last_name);
280 $data['email'] = $email;
281 $data['timestamp'] = $date->getTimestamp();
282 }
283 }
284 if ($order_id && function_exists('edd_get_payment_meta')) {
285 $offset = get_option('gmt_offset');
286 $payment_meta = edd_get_payment_meta($order_id);
287 if (is_array($payment_meta)) {
288 $user_info = $payment_meta['user_info'];
289 $date = $payment_meta['date'];
290
291 $data['name'] = $this->name($user_info['first_name'], $user_info['last_name']);
292 $data['first_name'] = $user_info['first_name'];
293 $data['last_name'] = $user_info['last_name'];
294 $data['email'] = $user_info['email'];
295 $data['timestamp'] = strtotime($date) - ($offset * 60 * 60);
296 }
297 }
298
299 return $data;
300 }
301
302 public function status_transition($id, $from, $to, $order) {
303 $items = $order->get_items();
304 $if_has_course = true;
305 $status = array('on-hold', 'cancelled', 'refunded', 'failed', 'pending', 'wcf-main-order');
306 $done = array('completed', 'processing');
307
308 if (in_array($from, $done) && in_array($to, $status)) {
309 foreach ($items as $item) {
310 if (function_exists('tutor_utils')) {
311 $if_has_course = tutor_utils()->product_belongs_with_course($item->get_product_id());
312 }
313 if (!$if_has_course) {
314 continue;
315 }
316 $key = $id . '-' . $item->get_id();
317 $this->delete_notification($key);
318 }
319 }
320
321 if (in_array($from, $status) && in_array($to, $done)) {
322 $orders = array();
323
324 foreach ($items as $item) {
325 $key = $id . '-' . $item->get_id();
326 if (function_exists('tutor_utils')) {
327 $if_has_course = tutor_utils()->product_belongs_with_course($item->get_product_id());
328 }
329 if (!$if_has_course) {
330 continue;
331 }
332
333 if (isset($this->notifications[$key])) {
334 continue;
335 }
336 $single_notification = $this->ordered_product($item->get_id(), $item, $order);
337 if (!empty($single_notification)) {
338 $this->update_notification(
339 array(
340 'source' => $this->id,
341 'entry_key' => $key,
342 'data' => $single_notification,
343 )
344 );
345 }
346 }
347 }
348
349 return;
350 }
351
352 /**
353 * This function is responsible for making ready the orders data.
354 *
355 * @param int $item_id
356 * @param WC_Order_Item_Product $item
357 * @param int $order_id
358 * @return void
359 */
360 public function ordered_product($item_id, $item, $order_id) {
361 if (!$item instanceof \WC_Order_Item_Product) {
362 return false;
363 }
364
365 $product_id = $item->get_product_id();
366 $if_has_course = tutor_utils()->product_belongs_with_course($product_id);
367 if (!$if_has_course) {
368 return false;
369 }
370
371 $new_order = array();
372 if (is_int($order_id)) {
373 $order = new \WC_Order($order_id);
374 $status = $order->get_status();
375 $done = array('completed', 'processing', 'pending');
376 if (!in_array($status, $done)) {
377 return false;
378 }
379 } else {
380 $order = $order_id;
381 }
382
383 $date = $order->get_date_created();
384 $countries = new \WC_Countries();
385 $shipping_country = $order->get_billing_country();
386 if (empty($shipping_country)) {
387 $shipping_country = $order->get_shipping_country();
388 }
389 if (!empty($shipping_country)) {
390 $new_order['country'] = isset($countries->countries[$shipping_country]) ? $countries->countries[$shipping_country] : '';
391 $shipping_state = $order->get_shipping_state();
392 if (!empty($shipping_state)) {
393 $new_order['state'] = isset($countries->states[$shipping_country], $countries->states[$shipping_country][$shipping_state]) ? $countries->states[$shipping_country][$shipping_state] : $shipping_state;
394 }
395 }
396 $new_order['city'] = $order->get_billing_city();
397 if (empty($new_order['city'])) {
398 $new_order['city'] = $order->get_shipping_city();
399 }
400
401 $new_order['ip'] = $order->get_customer_ip_address();
402 $product_data = $this->ready_product_data($item->get_data());
403 $course_id = $if_has_course->post_id;
404 if (!empty($product_data)) {
405 $new_order['id'] = is_int($order_id) ? $order_id : $order_id->get_id();
406 $new_order['product_id'] = $course_id;
407 $new_order['title'] = $product_data['title'];
408 }
409 $new_order['timestamp'] = $date->getTimestamp();
410 $new_order['link'] = get_permalink($course_id);
411
412 $data = array_merge($new_order, $this->buyer($order));
413 return $data;
414 }
415
416 /**
417 * It will take an array to make data clean
418 *
419 * @param array $data
420 * @return void
421 */
422 protected function ready_product_data($data) {
423 if (empty($data)) {
424 return;
425 }
426 return array(
427 'title' => $data['name'],
428 );
429 }
430
431 /**
432 * This function is responsible for getting
433 * the buyer name from order.
434 *
435 * @param WC_Order $order
436 * @return void
437 */
438 protected function buyer(\WC_Order $order) {
439 $first_name = $last_name = $email = '';
440 $buyer_data = array();
441
442 if (empty($first_name)) {
443 $first_name = $order->get_billing_first_name();
444 }
445
446 if (empty($last_name)) {
447 $last_name = $order->get_billing_last_name();
448 }
449
450 if (empty($email)) {
451 $email = $order->get_billing_email();
452 }
453
454 $buyer_data['first_name'] = $first_name;
455 $buyer_data['last_name'] = $last_name;
456 $buyer_data['name'] = $this->name($first_name, $last_name);
457 $buyer_data['email'] = $email;
458
459 return $buyer_data;
460 }
461
462 public function saved_post($post, $data, $nx_id) {
463 $this->delete_notification(null, $nx_id);
464 $this->get_notification_ready($data);
465 }
466
467 /**
468 * This function is responsible for making the notification ready for first time we make the notification.
469 *
470 * @param string $type
471 * @param array $data
472 * @return void
473 */
474 public function get_notification_ready($data = array()) {
475 $enrollments = $this->get_purchased_course($data);
476 if (!empty($enrollments)) {
477 // $enrollments = NotificationX_Helper::sortBy( $enrollments, 'tutor' );
478 $entries = [];
479 foreach ($enrollments as $key => $enrollment) {
480 $entries[] = array(
481 'nx_id' => $data['nx_id'],
482 'source' => $this->id,
483 'entry_key' => $key,
484 'data' => $enrollment,
485 );
486 }
487 $this->update_notifications($entries);
488 }
489 }
490 /**
491 * Get all the orders from database using a date query
492 * for limitation.
493 *
494 * @param array $data
495 * @return array
496 */
497 public function get_purchased_course($data = array()) {
498 if (empty($data)) {
499 return null;
500 }
501 $orders = array();
502 // $from = date(get_option('date_format'), strtotime('-' . intval($data['display_from']) . ' days'));
503 $from = gmdate('Y-m-d H:i:s', Helper::generate_time_string($data));
504 $enrolled = get_posts(
505 array(
506 'post_type' => 'tutor_enrolled',
507 'post_status' => 'completed',
508 'date_query' => array(
509 array(
510 'after' => $from,
511 ),
512 ),
513 'numberposts' => -1,
514 'posts_per_page' => -1,
515 )
516 );
517 foreach ($enrolled as $single_enroll) {
518 $orders[$single_enroll->post_parent . '-' . $single_enroll->ID] = $this->ready_enrolled_data($single_enroll);
519 }
520 wp_reset_postdata();
521 return $orders;
522 }
523
524 /**
525 * @param array $data
526 * @param array $saved_data
527 * @param stdClass $settings
528 * @return array
529 */
530 public function fallback_data($data, $saved_data, $settings) {
531 $data['name'] = __('Someone', 'notificationx');
532 $data['first_name'] = __('Someone', 'notificationx');
533 $data['last_name'] = __('Someone', 'notificationx');
534 $data['anonymous_title'] = __('Anonymous Product', 'notificationx');
535 $data['course_title'] = $saved_data['title'];
536 return $data;
537 }
538
539 public function doc(){
540 /* translators: %1$s: Tutor LMS installed & configured link URL, %2$s: documentation link URL, %3$s: video tutorial link URL, %4$s: Integration with Tutor LMS link URL */
541 return sprintf(__('<p>Make sure that you have <a href="%1$s" target="_blank">Tutor LMS installed & configured</a> to use its campaign & course selling data. For further assistance, check out our step by step <a target="_blank" href="%2$s">documentation</a>.</p>
542 <p>🎦 Watch <a target="_blank" href="%3$s">video tutorial</a> to learn quickly</p>
543 <p>👉 NotificationX <a target="_blank" href="%4$s">Integration with Tutor LMS</a></p>', 'notificationx'),
544 'https://wordpress.org/plugins/tutor/',
545 'https://notificationx.com/docs/tutor-lms/',
546 'https://www.youtube.com/watch?v=EMrjLfL563Q',
547 'https://notificationx.com/integrations/tutor-lms/'
548 );
549 }
550 }
551