PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.3.3
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.3.3
3.3.3 3.3.2 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 All 158 releases
← All changes | includes/Extensions/Tutor/Tutor.php +550 -0 0.2.5.7 → 3.3.3 View file →
@@ -1,0 +1,550 @@
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 +}