PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / trunk
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar vtrunk
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
← All changes | includes/Admin/Notice.php +974 -0 0.2.5.6trunk View file →
@@ -1,0 +1,974 @@
1 +<?php
2 +/**
3 + * Notice Class File.
4 + *
5 + * @package NotificationX\Admin
6 + */
7 +
8 +namespace NotificationX\Admin;
9 +
10 +use NotificationX\CoreInstaller;
11 +
12 +class Notice {
13 + /**
14 + * Instance of Called Class.
15 + *
16 + * @var Notice
17 + */
18 + protected static $instance = null;
19 +
20 + public static function get_instance( $basename, $version ) {
21 + if ( is_null( static::$instance ) || ! static::$instance instanceof self ) {
22 + static::$instance = new static( $basename, $version );
23 + }
24 + return static::$instance;
25 + }
26 + /**
27 + * Admin Notice Key
28 + *
29 + * @var array
30 + */
31 + const ADMIN_UPDATE_NOTICE_KEY = 'wpdeveloper_notices_seen';
32 + public $text_domain = 'notificationx';
33 + /**
34 + * All Data
35 + *
36 + * @var array
37 + */
38 + private $data = array();
39 + private $properties = array(
40 + 'links',
41 + 'message',
42 + 'thumbnail',
43 + );
44 + private $methods = array(
45 + 'message',
46 + 'thumbnail',
47 + 'classes',
48 + );
49 + /**
50 + * cne_day == current_notice_end_day
51 + *
52 + * @var integer
53 + */
54 + public $cne_time = '2 day';
55 + public $maybe_later_time = '7 day';
56 + public $finish_time = [];
57 + /**
58 + * Plugin Name
59 + *
60 + * @var string
61 + */
62 + private $plugin_name;
63 + /**
64 + * Plugin File Name
65 + *
66 + * @var string
67 + */
68 + private $plugin_file;
69 + /**
70 + * First Install Version Of The Plugin
71 + *
72 + * @var string
73 + */
74 + private $version;
75 + /**
76 + * Saved Data in DB
77 + *
78 + * @var array
79 + */
80 + private $options_data;
81 + /**
82 + * Current Timestamp
83 + *
84 + * @var integer
85 + */
86 + public $timestamp;
87 + /**
88 + * Primary Notice Action
89 + *
90 + * @var string
91 + */
92 + private $do_notice_action;
93 + /**
94 + * Default Options Set
95 + *
96 + * @var array
97 + */
98 + public $options_args = array(
99 + // 'first_install' => true,
100 + // 'notice_will_show' => [
101 + // 'opt_in' => true,
102 + // 'first_install' => false,
103 + // 'update' => true,
104 + // 'review' => true,
105 + // 'upsale' => true,
106 + // ]
107 + );
108 + /**
109 + * Notice ID for users.
110 + *
111 + * @var string
112 + */
113 + private $notice_id;
114 + /**
115 + * Upsale Notice Arguments
116 + *
117 + * @var array
118 + */
119 + public $upsale_args;
120 + /**
121 + * Revoke this function when the object is created.
122 + *
123 + * @param string $plugin_name
124 + * @param string $version
125 + */
126 + public function __construct( $plugin_file = '', $version = '' ) {
127 + $this->plugin_file = $plugin_file;
128 + $this->plugin_name = basename( $plugin_file, '.php' );
129 + $this->version = $version;
130 + $this->timestamp = intval( current_time( 'timestamp' ) );
131 + $this->notice_id = 'wpdeveloper_notice_' . str_replace( '.', '_', $this->version );
132 +
133 + $this->do_notice_action = 'wpdeveloper_notices_for_' . $this->plugin_name;
134 +
135 + if ( class_exists( 'CoreInstaller' ) ) {
136 + new CoreInstaller( $this->plugin_name );
137 + }
138 + }
139 + /**
140 + * Initiate The Plugin
141 + *
142 + * @return void
143 + */
144 + public function init() {
145 + add_action( 'init', array( $this, 'first_install_track' ) );
146 + add_action( 'deactivate_' . $this->plugin_file, array( $this, 'first_install_end' ) );
147 + add_action( 'init', array( $this, 'hooks' ) );
148 + }
149 + /**
150 + * All Hooks
151 + *
152 + * @return void
153 + */
154 + public function hooks() {
155 + add_action( 'wpdeveloper_notice_clicked_for_' . $this->plugin_name, array( $this, 'clicked' ) );
156 + add_action( 'wp_ajax_wpdeveloper_upsale_notice_dissmiss_for_' . $this->plugin_name, array( $this, 'upsale_notice_dissmiss' ) );
157 + add_action( 'wp_ajax_wpdeveloper_notice_dissmiss_for_' . $this->plugin_name, array( $this, 'notice_dissmiss' ) );
158 + add_action( 'wpdeveloper_before_notice_for_' . $this->plugin_name, array( $this, 'before' ) );
159 + add_action( 'wpdeveloper_after_notice_for_' . $this->plugin_name, array( $this, 'after' ) );
160 + add_action( 'wpdeveloper_before_upsale_notice_for_' . $this->plugin_name, array( $this, 'before_upsale' ) );
161 + add_action( 'wpdeveloper_after_upsale_notice_for_' . $this->plugin_name, array( $this, 'after' ) );
162 + add_action( $this->do_notice_action, array( $this, 'content' ) );
163 + if ( current_user_can( 'install_plugins' ) ) {
164 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
165 + if ( isset( $_GET['plugin'] ) && $_GET['plugin'] == $this->plugin_name ) {
166 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
167 + if ( isset( $_GET['tab'] ) && $_GET['tab'] === 'plugin-information' ) {
168 + return;
169 + }
170 + do_action( 'wpdeveloper_notice_clicked_for_' . $this->plugin_name );
171 + /**
172 + * Redirect User To the Current URL, but without set query arguments.
173 + */
174 + wp_safe_redirect( $this->redirect_to() );
175 + }
176 + $return_notice = $this->next_notice();
177 + $current_notice = current( $return_notice );
178 + $next_notice = next( $return_notice );
179 +
180 + $deserve_notice = $this->deserve_notice( $current_notice );
181 + $options_data = $this->get_options_data();
182 + $user_notices = $this->get_user_notices();
183 +
184 + $notice_time = isset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] )
185 + ? $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] : $this->timestamp;
186 + $next_notice_time = $next_notice ? $options_data[ $this->plugin_name ]['notice_will_show'][ $next_notice ] : $this->timestamp;
187 + $current_notice_end = $this->makeTime( $notice_time, $this->cne_time );
188 +
189 + if ( ! $deserve_notice ) {
190 + unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
191 + $this->update_options_data( $options_data[ $this->plugin_name ] );
192 + }
193 +
194 + if ( $deserve_notice ) {
195 + /**
196 + * TODO: automatic maybe later setup with time.
197 + */
198 + if ( ( $this->timestamp >= $current_notice_end ) || ( $this->timestamp > $next_notice_time ) ) {
199 + $this->maybe_later( $current_notice );
200 + $notice_time = false;
201 + }
202 +
203 + if ( isset( $this->finish_time[ $current_notice ] ) ) {
204 + if ( $this->timestamp >= strtotime( $this->finish_time[ $current_notice ] ) ) {
205 + unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
206 + $this->update_options_data( $options_data[ $this->plugin_name ] );
207 + $notice_time = false;
208 + }
209 + }
210 +
211 + if ( $notice_time != false ) {
212 + if ( $notice_time <= $this->timestamp ) {
213 + if ( $current_notice === 'upsale' ) {
214 + $upsale_args = $this->get_upsale_args();
215 + if ( empty( $upsale_args ) ) {
216 + unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
217 + $this->update_options_data( $options_data[ $this->plugin_name ] );
218 + } else {
219 + if ( isset( $upsale_args['condition'], $upsale_args['condition']['by'] ) ) {
220 + switch ( $upsale_args['condition']['by'] ) {
221 + case 'class':
222 + if ( isset( $upsale_args['condition']['class'] ) && class_exists( $upsale_args['condition']['class'] ) ) {
223 + unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
224 + $this->update_options_data( $options_data[ $this->plugin_name ] );
225 + return;
226 + }
227 + break;
228 + case 'function':
229 + if ( isset( $upsale_args['condition']['function'] ) && function_exists( $upsale_args['condition']['function'] ) ) {
230 + unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
231 + $this->update_options_data( $options_data[ $this->plugin_name ] );
232 + return;
233 + }
234 + break;
235 + }
236 + }
237 + if ( ! function_exists( 'get_plugins' ) ) {
238 + include ABSPATH . '/wp-admin/includes/plugin.php';
239 + }
240 + $plugins = get_plugins();
241 + $pkey = $upsale_args['slug'] . '/' . $upsale_args['file'];
242 + if ( isset( $plugins[ $pkey ] ) ) {
243 + $this->update( $current_notice );
244 + return;
245 + }
246 + add_action( 'admin_notices', array( $this, 'upsale_notice' ) );
247 + }
248 + } else {
249 + add_action( 'admin_notices', array( $this, 'admin_notices' ) );
250 + }
251 + }
252 + }
253 + }
254 + }
255 + }
256 + /**
257 + * Make time using timestamp and a string like 2 Hour, 2 Day, 30 Minutes, 1 Week, 1 year
258 + *
259 + * @param integer $current
260 + * @param string $time
261 + * @return integer
262 + */
263 + public function makeTime( $current, $time ) {
264 + return intval( strtotime( gmdate( 'r', $current ) . " +$time" ) );
265 + }
266 + /**
267 + * Automatice Maybe Later.
268 + *
269 + * @param string $notice
270 + * @return void
271 + */
272 + private function maybe_later( $notice ) {
273 + if ( empty( $notice ) ) {
274 + return;
275 + }
276 + $options_data = $this->get_options_data();
277 + $options_data[ $this->plugin_name ]['notice_will_show'][ $notice ] = $this->makeTime( $this->timestamp, $this->maybe_later_time );
278 + $this->update_options_data( $options_data[ $this->plugin_name ] );
279 + }
280 + /**
281 + * When links are clicked, this function will invoked.
282 + *
283 + * @return void
284 + */
285 + public function clicked() {
286 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
287 + if ( isset( $_GET['plugin'] ) ) {
288 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
289 + $plugin = sanitize_text_field( wp_unslash( $_GET['plugin'] ) );
290 + if ( $plugin === $this->plugin_name ) {
291 + $options_data = $this->get_options_data();
292 + $clicked_from = current( $this->next_notice() );
293 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
294 + if ( isset( $_GET['plugin_action'] ) ) {
295 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
296 + $plugin_action = sanitize_text_field( wp_unslash( $_GET['plugin_action'] ) );
297 + }
298 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
299 + if ( isset( $_GET['dismiss'] ) ) {
300 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
301 + $dismiss = sanitize_text_field( wp_unslash( $_GET['dismiss'] ) );
302 + }
303 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
304 + if ( isset( $_GET['later'] ) ) {
305 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context.
306 + $later = sanitize_text_field( wp_unslash( $_GET['later'] ) );
307 + }
308 +
309 + $later_time = '';
310 +
311 + switch ( $clicked_from ) {
312 +
313 + case 'opt_in':
314 + $dismiss = ( isset( $plugin_action ) ) ? $plugin_action : false;
315 + $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
316 + break;
317 +
318 + case 'first_install':
319 + $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
320 + break;
321 +
322 + case 'update':
323 + $dismiss = ( isset( $plugin_action ) ) ? $plugin_action : false;
324 + $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
325 + break;
326 +
327 + case 'review':
328 + $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
329 + break;
330 +
331 + case 'upsale':
332 + $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
333 + break;
334 + default:
335 + $dismiss = ( isset( $plugin_action ) ) ? $plugin_action : false;
336 + break;
337 + }
338 +
339 + if ( isset( $later ) && $later == true ) {
340 + $options_data[ $this->plugin_name ]['notice_will_show'][ $clicked_from ] = $later_time;
341 + }
342 + if ( isset( $dismiss ) && $dismiss == true ) {
343 + update_user_meta( get_current_user_id(), $this->plugin_name . '_' . $clicked_from, true );
344 + $this->update( $clicked_from );
345 + }
346 + $this->update_options_data( $options_data[ $this->plugin_name ] );
347 + }
348 + }
349 + }
350 + /**
351 + * For Redirecting Current Page without Arguments!
352 + *
353 + * @return void
354 + */
355 + private function redirect_to() {
356 + $current_uri = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
357 + $request_uri = wp_parse_url( $current_uri, PHP_URL_PATH );
358 + $query_string = wp_parse_url( $current_uri, PHP_URL_QUERY );
359 + parse_str( $query_string, $current_url );
360 +
361 + $unset_array = array( 'dismiss', 'plugin', '_wpnonce', 'later', 'plugin_action', 'marketing_optin' );
362 +
363 + foreach ( $unset_array as $value ) {
364 + if ( isset( $current_url[ $value ] ) ) {
365 + unset( $current_url[ $value ] );
366 + }
367 + }
368 +
369 + $current_url = http_build_query( $current_url );
370 + $redirect_url = $request_uri . '?' . $current_url;
371 + return $redirect_url;
372 + }
373 + /**
374 + * Before Notice
375 + *
376 + * @return void
377 + */
378 + public function before() {
379 + $current_notice = current( $this->next_notice() );
380 + $classes = 'notice notice-info put-dismiss-notice ';
381 + if ( isset( $this->data['classes'] ) ) {
382 + if ( isset( $this->data['classes'][ $current_notice ] ) ) {
383 + $classes = $this->data['classes'][ $current_notice ];
384 + }
385 + }
386 +
387 + if ( $this->has_thumbnail( $current_notice ) ) {
388 + $classes .= ' notice-has-thumbnail';
389 + }
390 +
391 + $classes .= ' ' . $this->plugin_name;
392 + echo '<div class="' . esc_attr( $classes ) . ' wpdeveloper-' . esc_attr( $current_notice ) . '-notice">';
393 + }
394 + /**
395 + * After Notice
396 + *
397 + * @return void
398 + */
399 + public function after() {
400 + echo '</div>';
401 + }
402 + /**
403 + * Content generation & Hooks Funciton.
404 + *
405 + * @return void
406 + */
407 + public function content() {
408 + $options_data = $this->get_options_data();
409 + $notice = current( $this->next_notice() );
410 + switch ( $notice ) {
411 + case 'opt_in':
412 + do_action( 'wpdeveloper_optin_notice_for_' . $this->plugin_name );
413 + break;
414 + case 'first_install':
415 + if ( $options_data[ $this->plugin_name ]['first_install'] !== 'deactivated' ) {
416 + do_action( 'wpdeveloper_first_install_notice_for_' . $this->plugin_name );
417 + $this->get_thumbnail( 'first_install' );
418 + $this->get_message( 'first_install' );
419 + }
420 + break;
421 + case 'update':
422 + do_action( 'wpdeveloper_update_notice_for_' . $this->plugin_name );
423 + $this->get_thumbnail( 'update' );
424 + $this->get_message( 'update' );
425 + $this->dismiss_button_scripts();
426 + break;
427 + case 'review':
428 + do_action( 'wpdeveloper_review_notice_for_' . $this->plugin_name );
429 + $this->get_thumbnail( 'review' );
430 + $this->get_message( 'review' );
431 + break;
432 + default:
433 + do_action( 'wpdeveloper_'. $notice .'_notice_for_' . $this->plugin_name );
434 + $this->get_thumbnail( $notice );
435 + $this->get_message( $notice );
436 + $this->dismiss_button_scripts();
437 + break;
438 + }
439 + }
440 + /**
441 + * Before Upsale Notice
442 + *
443 + * @return void
444 + */
445 + public function before_upsale() {
446 + $classes = '';
447 + if ( $this->has_thumbnail( 'upsale' ) ) {
448 + $classes = 'notice-has-thumbnail';
449 + }
450 + echo '<div class="error notice is-dismissible wpdeveloper-upsale-notice ' . esc_attr( $classes ) . '">';
451 + }
452 + /**
453 + * Upsale Notice
454 + */
455 + public function upsale_notice() {
456 + do_action( 'wpdeveloper_before_upsale_notice_for_' . $this->plugin_name );
457 + do_action( 'wpdeveloper_upsale_notice_for_' . $this->plugin_name );
458 + $this->get_thumbnail( 'upsale' );
459 + $this->get_message( 'upsale' );
460 + do_action( 'wpdeveloper_after_upsale_notice_for_' . $this->plugin_name );
461 + $this->upsale_button_script();
462 + }
463 + /**
464 + * Get upsale arguments.
465 + *
466 + * @return void
467 + */
468 + private function get_upsale_args() {
469 + return ( empty( $this->upsale_args ) ) ? array() : $this->upsale_args;
470 + }
471 + /**
472 + * This function is responsible for making the button visible to the upsale notice.
473 + */
474 + private function upsale_button() {
475 + $upsale_args = $this->get_upsale_args();
476 + $plugin_slug = ( isset( $upsale_args['slug'] ) ) ? $upsale_args['slug'] : '';
477 + if ( empty( $plugin_slug ) ) {
478 + return;
479 + }
480 + echo '<button data-slug="' . esc_attr( $plugin_slug ) . '" id="plugin-install-core-' . esc_attr( $this->plugin_name ) . '" class="button button-primary">' . esc_html__( 'Install Now!', 'notificationx' ) . '</button>';
481 + }
482 + /**
483 + * This methods is responsible for get notice image.
484 + *
485 + * @param string $msg_for
486 + * @return void
487 + */
488 + protected function get_thumbnail( $msg_for ) {
489 + $output = '';
490 + if ( isset( $this->data['thumbnail'] ) && isset( $this->data['thumbnail'][ $msg_for ] ) ) {
491 + $output = '<div class="wpdeveloper-notice-thumbnail">';
492 + $output .= '<img src="' . esc_url( $this->data['thumbnail'][ $msg_for ] ) . '" alt="NotificationX">';
493 + $output .= '</div>';
494 + }
495 + echo wp_kses_post( $output );
496 + }
497 + /**
498 + * Has Thumbnail Check
499 + *
500 + * @param string $msg_for
501 + * @return boolean
502 + */
503 + protected function has_thumbnail( $msg_for = '' ) {
504 + if ( empty( $msg_for ) ) {
505 + return false;
506 + }
507 + if ( isset( $this->data['thumbnail'] ) && isset( $this->data['thumbnail'][ $msg_for ] ) ) {
508 + return true;
509 + }
510 + return false;
511 + }
512 + /**
513 + * This method is responsible for get messages.
514 + *
515 + * @param string $msg_for
516 + * @return void
517 + */
518 + protected function get_message( $msg_for ) {
519 + if ( isset( $this->data['message'] ) && isset( $this->data['message'][ $msg_for ] ) ) {
520 + echo '<div class="wpdeveloper-notice-message">';
521 + echo wp_kses_post( $this->data['message'][ $msg_for ] );
522 + if ( 'upsale' === $msg_for ) {
523 + $this->upsale_button();
524 + }
525 + $this->dismissible_notice( $msg_for );
526 + echo '</div>';
527 + }
528 + }
529 + /**
530 + * Detect which notice will show @ next.
531 + *
532 + * @return array
533 + */
534 + protected function next_notice() {
535 + $options_data = $this->get_options_data();
536 + if ( ! $options_data ) {
537 + $args = $this->get_args();
538 + $return_notice = $args['notice_will_show'];
539 + } else {
540 + $return_notice = $options_data[ $this->plugin_name ]['notice_will_show'];
541 + }
542 +
543 + if ( is_array( $return_notice ) ) {
544 + $return_notice = array_flip( $return_notice );
545 + ksort( $return_notice );
546 + }
547 +
548 + return $return_notice;
549 + }
550 + /**
551 + * Which notice is deserve to show in next slot.
552 + *
553 + * @param string $notice
554 + * @return boolean
555 + */
556 + private function deserve_notice( $notice ) {
557 + $notices = $this->get_user_notices();
558 + if ( $notice === false ) {
559 + return false;
560 + }
561 + if ( empty( $notices ) ) {
562 + return true;
563 + } else {
564 + if ( isset( $notices[ $this->notice_id ] ) && isset( $notices[ $this->notice_id ][ $this->plugin_name ] ) ) {
565 + if ( in_array( $notice, $notices[ $this->notice_id ][ $this->plugin_name ] ) ) {
566 + return false;
567 + } else {
568 + return true;
569 + }
570 + } else {
571 + return true;
572 + }
573 + }
574 + }
575 + /**
576 + * This is the main methods for generate the notice.
577 + *
578 + * @return void
579 + */
580 + public function admin_notices() {
581 + $current_notice = current( $this->next_notice() );
582 + if ( get_user_meta( get_current_user_id(), $this->plugin_name . '_' . $current_notice, true ) ) {
583 + return;
584 + }
585 + if ( $current_notice == 'opt_in' ) {
586 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context.
587 + do_action( $this->do_notice_action );
588 + return;
589 + }
590 + do_action( 'wpdeveloper_before_notice_for_' . $this->plugin_name );
591 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context.
592 + do_action( $this->do_notice_action );
593 + do_action( 'wpdeveloper_after_notice_for_' . $this->plugin_name );
594 + }
595 + /**
596 + * This method is responsible for all dismissible links generation.
597 + *
598 + * @param string $links_for
599 + * @return void
600 + */
601 + public function dismissible_notice( $links_for = '' ) {
602 + if ( empty( $links_for ) ) {
603 + return;
604 + }
605 + $links = isset( $this->data['links'][ $links_for ] ) ? $this->data['links'][ $links_for ] : false;
606 + if ( $links ) :
607 + $output = '<ul class="wpdeveloper-notice-link">';
608 + foreach ( $links as $key => $link_value ) {
609 + if ( ! empty( $link_value['label'] ) ) {
610 + $output .= '<li>';
611 + if ( isset( $link_value['link'] ) ) {
612 + $link = $link_value['link'];
613 + $target = isset( $link_value['target'] ) ? 'target="' . esc_attr( $link_value['target'] ) . '"' : '';
614 + if ( isset( $link_value['data_args'] ) && is_array( $link_value['data_args'] ) ) {
615 + $data_args = [];
616 + foreach ( $link_value['data_args'] as $key => $args_value ) {
617 + $data_args[ $key ] = $args_value;
618 + }
619 + $data_args['plugin'] = $this->plugin_name;
620 + $normal_link = add_query_arg( $data_args, $link );
621 + $link = wp_nonce_url( $normal_link, 'wpdeveloper-nonce' );
622 + }
623 + $class = '';
624 + if ( isset( $link_value['link_class'] ) ) {
625 + $sanitized_classes = array_map( 'esc_attr', $link_value['link_class'] );
626 + $class = 'class="' . implode( ' ', $sanitized_classes ) . '"';
627 + }
628 + $output .= '<a ' . $class . ' href="' . esc_url( $link ) . '" ' . $target . '>';
629 + }
630 + if ( isset( $link_value['icon_class'] ) ) {
631 + $output .= '<span class="' . esc_attr( $link_value['icon_class'] ) . '"></span>';
632 + }
633 + if ( isset( $link_value['icon_img'] ) ) {
634 + $output .= '<img src="' . esc_url( $link_value['icon_img'] ) . '" />';
635 + }
636 + $output .= $link_value['label'];
637 + if ( isset( $link_value['link'] ) ) {
638 + $output .= '</a>';
639 + }
640 + $output .= '</li>';
641 + }
642 + }
643 + $output .= '</ul>';
644 + echo wp_kses_post( $output );
645 + endif;
646 + }
647 + /**
648 + * First Installation Track
649 + *
650 + * @return void
651 + */
652 + public function first_install_track( $args = array() ) {
653 + if ( ! current_user_can( 'manage_options' ) ) {
654 + return;
655 + }
656 + if ( empty( $args ) ) {
657 + $args = array(
658 + 'time' => $this->timestamp,
659 + 'version' => $this->version,
660 + );
661 + }
662 + $options_data = $this->get_options_data();
663 + $args = wp_parse_args( $args, $this->get_args() );
664 + if ( ! isset( $options_data[ $this->plugin_name ] )
665 + || ( isset( $options_data[ $this->plugin_name ]['version'] ) && version_compare( $options_data[ $this->plugin_name ]['version'], $this->version, '!=' ) ) ) {
666 + $this->update_options_data( $args );
667 + }
668 + }
669 + /**
670 + * First Installation Deactive Track
671 + *
672 + * @return void
673 + */
674 + public function first_install_end() {
675 + // $args = array(
676 + // 'first_install' => 'deactivated'
677 + // );
678 + // $options_data = $this->get_options_data();
679 + // if( isset( $options_data[ $this->plugin_name ] ) ) {
680 + // $args = wp_parse_args( $args, $options_data[ $this->plugin_name ] );
681 + // $this->update_options_data( $args );
682 + // }
683 + delete_option( 'wpdeveloper_plugins_data' );
684 + }
685 + /**
686 + * Get all options from database!
687 + *
688 + * @return void
689 + */
690 + protected function get_options_data( $key = '' ) {
691 + $options_data = get_option( 'wpdeveloper_plugins_data' );
692 + if ( empty( $key ) ) {
693 + return $options_data;
694 + }
695 +
696 + if ( isset( $options_data[ $this->plugin_name ][ $key ] ) ) {
697 + return $options_data[ $this->plugin_name ][ $key ];
698 + }
699 + return false;
700 + }
701 + /**
702 + * This will update the options table for plugins.
703 + *
704 + * @param mixed $new_data
705 + * @param array $args
706 + * @return void
707 + */
708 + protected function update_options_data( $args = array() ) {
709 + $options_data = $this->get_options_data();
710 + $options_data[ $this->plugin_name ] = $args;
711 + update_option( 'wpdeveloper_plugins_data', $options_data, 'no' );
712 + }
713 + /**
714 + * Set properties data, for some selected properties.
715 + *
716 + * @param string $name
717 + * @param mixed $value
718 + */
719 + public function __set( $name, $value ) {
720 + if ( in_array( $name, $this->properties ) ) {
721 + $this->data[ $name ] = $value;
722 + }
723 + }
724 + /**
725 + * Invoked when some selected methods are called
726 + *
727 + * @param string $name
728 + * @param array $values
729 + * @return void
730 + */
731 + public function __call( $name, $values ) {
732 + if ( in_array( $name, $this->methods ) ) {
733 + $this->data[ $name ][ $values[0] ] = $values[1];
734 + }
735 + }
736 + /**
737 + * Get all option arguments.
738 + *
739 + * @param string $key
740 + * @return array
741 + */
742 + private function get_args( $key = '' ) {
743 + if ( empty( $key ) ) {
744 + return $this->options_args;
745 + }
746 +
747 + if ( isset( $this->options_args[ $key ] ) ) {
748 + return $this->options_args[ $key ];
749 + }
750 +
751 + return false;
752 + }
753 + /**
754 + * Resetting data on update.
755 + *
756 + * @return void
757 + */
758 + private function set_args_on_update() {
759 + $args = $this->get_args();
760 + $options_data = $this->get_options_data();
761 + $set_data = $options_data[ $this->plugin_name ];
762 + $args = wp_parse_args( $set_data, $args );
763 + $this->update_options_data( $args );
764 + }
765 + /**
766 + * When upgrade is complete. it will fired.
767 + *
768 + * @param WP_Upgrader $upgrader_object
769 + * @param array $options
770 + * @return void
771 + */
772 + public function upgrade_completed( $upgrader_object, $options ) {
773 + // If an update has taken place and the updated type is plugins and the plugins element exists
774 + if ( isset( $options['action'] ) && $options['action'] == 'update' && $options['type'] == 'plugin' ) {
775 + if ( ! isset( $options['plugin'] ) && isset( $options['plugins'] ) ) {
776 + foreach ( $options['plugins'] as $plugin ) {
777 + if ( $plugin == $this->plugin_name ) {
778 + $this->set_args_on_update();
779 + }
780 + }
781 + }
782 +
783 + if ( isset( $options['plugin'] ) && $options['plugin'] == $this->plugin_name ) {
784 + $this->set_args_on_update();
785 + }
786 + }
787 + }
788 + /**
789 + * This function is responsible for get_user_notices
790 + *
791 + * @return void
792 + */
793 + private function get_user_notices() {
794 + $notices = get_user_meta( get_current_user_id(), self::ADMIN_UPDATE_NOTICE_KEY, true );
795 + return ! $notices ? array() : $notices;
796 + }
797 + /**
798 + * This function is responsible for update meta information.
799 + *
800 + * @param string $notice
801 + * @return void
802 + */
803 + private function update( $notice ) {
804 + if ( empty( $notice ) ) {
805 + return;
806 + }
807 + $options_data = $this->get_options_data();
808 + $user_notices = $this->get_user_notices();
809 + $user_notices[ $this->notice_id ][ $this->plugin_name ][] = $notice;
810 + // Remove the upsale from notice_will_show field in options DB.
811 + unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $notice ] );
812 + $this->update_options_data( $options_data[ $this->plugin_name ] );
813 + // Set users meta, not to show again current_version notice.
814 + update_user_meta( get_current_user_id(), self::ADMIN_UPDATE_NOTICE_KEY, $user_notices );
815 + }
816 +
817 + public function notice_dissmiss() {
818 + if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'wpdeveloper_notice_dissmiss' ) ) {
819 + return;
820 + }
821 +
822 + if ( ! isset( $_POST['action'] ) || ( $_POST['action'] !== 'wpdeveloper_notice_dissmiss_for_' . $this->plugin_name ) ) {
823 + return;
824 + }
825 +
826 + $dismiss = isset( $_POST['dismiss'] ) ? sanitize_text_field( wp_unslash( $_POST['dismiss'] ) ) : false;
827 + $notice = isset( $_POST['notice'] ) ? sanitize_text_field( wp_unslash( $_POST['notice'] ) ) : false;
828 + if ( $dismiss ) {
829 + update_user_meta( get_current_user_id(), $this->plugin_name . '_' . $notice, true );
830 + $this->update( $notice );
831 + echo 'success';
832 + } else {
833 + echo 'failed';
834 + }
835 + die();
836 + }
837 +
838 + /**
839 + * This function is responsible for do action when
840 + * the dismiss button clicked in upsale notice.
841 + */
842 + public function upsale_notice_dissmiss() {
843 +
844 + if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'wpdeveloper_upsale_notice_dissmiss' ) ) {
845 + return;
846 + }
847 +
848 + if ( ! isset( $_POST['action'] ) || ( $_POST['action'] !== 'wpdeveloper_upsale_notice_dissmiss_for_' . $this->plugin_name ) ) {
849 + return;
850 + }
851 +
852 + $dismiss = isset( $_POST['dismiss'] ) ? sanitize_text_field( wp_unslash( $_POST['dismiss'] ) ) : false;
853 + if ( $dismiss ) {
854 + $this->update( 'upsale' );
855 + echo 'success';
856 + } else {
857 + echo 'failed';
858 + }
859 + die();
860 + }
861 +
862 + public function dismiss_button_scripts() {
863 + ?>
864 + <script type="text/javascript">
865 + jQuery(document).ready( function($) {
866 + if( $('.notice').length > 0 ) {
867 + if( $('.notice').find('.notice-dismiss').length > 0 ) {
868 + $('.notice.<?php echo esc_js( $this->plugin_name ); ?>').on('click', 'button.notice-dismiss', function(e) {
869 + e.preventDefault();
870 + $.ajax({
871 + url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
872 + type: 'post',
873 + data: {
874 + action: 'wpdeveloper_notice_dissmiss_for_<?php echo esc_js( $this->plugin_name ); ?>',
875 + _wpnonce: '<?php echo esc_js( wp_create_nonce( 'wpdeveloper_notice_dissmiss' ) ); ?>',
876 + dismiss: true,
877 + notice: $(this).data('notice'),
878 + },
879 + success: function(response) {
880 + if( response === 'success' ) {
881 + e.target.offsetParent.style.display = 'none';
882 + }
883 + },
884 + error: function(error) {
885 + console.log('Nx: Something went wrong!');
886 + },
887 + });
888 + });
889 + }
890 + }
891 + } );
892 + </script>
893 + <?php
894 + }
895 +
896 + /**
897 + * Upsale Button Script.
898 + * When install button is clicked, it will do its own things.
899 + * also for dismiss button JS.
900 + *
901 + * @return void
902 + */
903 + public function upsale_button_script() {
904 + $upsale_args = $this->get_upsale_args();
905 +
906 + $plugin_slug = ( isset( $upsale_args['slug'] ) ) ? $upsale_args['slug'] : '';
907 + $plugin_file = ( isset( $upsale_args['file'] ) ) ? $upsale_args['file'] : '';
908 + $page_slug = ( isset( $upsale_args['page_slug'] ) ) ? $upsale_args['page_slug'] : '';
909 +
910 + ?>
911 + <script type="text/javascript">
912 + jQuery(document).ready( function($) {
913 + <?php if ( ! empty( $plugin_slug ) && ! empty( $plugin_file ) ) : ?>
914 + $('#plugin-install-core-<?php echo esc_html( $this->plugin_name ); ?>').on('click', function (e) {
915 + var self = $(this);
916 + e.preventDefault();
917 + self.addClass('install-now updating-message');
918 + self.text('<?php echo esc_html__( 'Installing...', 'notificationx' ); ?>');
919 +
920 + $.ajax({
921 + url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
922 + type: 'POST',
923 + data: {
924 + action: 'wpdeveloper_upsale_core_install_<?php echo esc_attr( $this->plugin_name ); ?>',
925 + _wpnonce: '<?php echo esc_js( wp_create_nonce( 'wpdeveloper_upsale_core_install_' . esc_attr( $this->plugin_name ) ) ); ?>',
926 + slug : '<?php echo esc_html( $plugin_slug ); ?>',
927 + file : '<?php echo esc_html( $plugin_file ); ?>'
928 + },
929 + success: function(response) {
930 + self.text('<?php echo esc_html__( 'Installed', 'notificationx' ); ?>');
931 + <?php if ( ! empty( $page_slug ) ) : ?>
932 + window.location.href = '<?php echo esc_url( admin_url( "admin.php?page={$page_slug}" ) ); ?>';
933 + <?php endif; ?>
934 + },
935 + error: function(error) {
936 + self.removeClass('install-now updating-message');
937 + alert( error );
938 + },
939 + complete: function() {
940 + self.attr('disabled', 'disabled');
941 + self.removeClass('install-now updating-message');
942 + }
943 + });
944 + });
945 +
946 + <?php endif; ?>
947 +
948 + $('.wpdeveloper-upsale-notice').on('click', 'button.notice-dismiss', function (e) {
949 + e.preventDefault();
950 + $.ajax({
951 + url: '<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>',
952 + type: 'post',
953 + data: {
954 + action: 'wpdeveloper_upsale_notice_dissmiss_for_<?php echo esc_attr( $this->plugin_name ); ?>',
955 + _wpnonce: '<?php echo esc_js( wp_create_nonce( 'wpdeveloper_upsale_notice_dissmiss' ) ); ?>',
956 + dismiss: true
957 + },
958 + success: function(response) {
959 + console.log('Successfully saved!');
960 + },
961 + error: function(error) {
962 + console.log('Something went wrong!');
963 + },
964 + complete: function() {
965 + console.log('Its Complete.');
966 + }
967 + });
968 + });
969 + } );
970 + </script>
971 +
972 + <?php
973 + }
974 +}