PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.1.17
Adminify – White Label, Admin Menu Editor, Login Customizer v4.1.17
4.3.1 4.3.0 4.2.26 4.2.25 4.2.24 4.2.23 4.2.22 4.2.21 4.2.20 4.2.19 4.2.18 4.2.17 4.2.16 4.2.15 4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 4.1.17 All 164 releases
adminify / Inc / Classes / Pro_Upgrade.php

Pro_Upgrade.php in Adminify – White Label, Admin Menu Editor, Login Customizer 4.1.17, at Inc/Classes/Pro_Upgrade.php

640 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 namespace WPAdminify\Inc\Classes;
4
5 use WPAdminify\Inc\Classes\Helper;
6 use WPAdminify\Inc\Classes\Notifications\Base\Date;
7 // No, Direct access Sir !!!
8 if ( !defined( 'ABSPATH' ) ) {
9 exit;
10 }
11 /**
12 * Upgrade to Pro Class
13 *
14 * Jewel Theme <support@jeweltheme.com>
15 */
16 class Pro_Upgrade {
17 use Date;
18 public $slug;
19
20 protected $data = array();
21
22 /**
23 * Construct method
24 */
25 public function __construct() {
26 $this->slug = Helper::jltwp_adminify_slug_cleanup();
27 $this->maybe_sync_remote_data();
28 $this->register_sync_hook();
29 $this->set_data();
30 add_action( 'admin_footer', array($this, 'display_popup') );
31 add_action( 'wp_dashboard_setup', array($this, 'dashboard_widget') );
32 add_action( 'wp_network_dashboard_setup', array($this, 'dashboard_widget') );
33 }
34
35 /**
36 * Register Dashboard widget
37 *
38 * @return void
39 * @author Jewel Theme <support@jeweltheme.com>
40 */
41 public function dashboard_widget() {
42 wp_add_dashboard_widget(
43 'jltwp_adminify_dashboard_widget',
44 // Widget slug.
45 esc_html__( 'Adminify News & Updates', 'adminify' ),
46 // Title.
47 array($this, 'dashboard_widget_render')
48 );
49 // Globalize the metaboxes array, this holds all the widgets for wp-admin.
50 global $wp_meta_boxes;
51 // Get the regular dashboard widgets array
52 // (which already has our new widget but appended at the end).
53 if ( is_network_admin() ) {
54 $default_dashboard = $wp_meta_boxes['dashboard-network']['normal']['core'];
55 } else {
56 $default_dashboard = $wp_meta_boxes['dashboard']['normal']['core'];
57 }
58 // Backup and delete our new dashboard widget from the end of the array.
59 $example_widget_backup = array(
60 'jltwp_adminify_dashboard_widget' => $default_dashboard['jltwp_adminify_dashboard_widget'],
61 );
62 unset($default_dashboard['jltwp_adminify_dashboard_widget']);
63 // Merge the two arrays together so our widget is at the beginning.
64 $sorted_dashboard = array_merge( $example_widget_backup, $default_dashboard );
65 // Save the sorted array back into the original metaboxes .
66 if ( is_network_admin() ) {
67 $wp_meta_boxes['dashboard-network']['normal']['core'] = $sorted_dashboard;
68 } else {
69 $wp_meta_boxes['dashboard']['normal']['core'] = $sorted_dashboard;
70 }
71 }
72
73 /**
74 * Render dashboard widget
75 *
76 * @author Jewel Theme <support@jeweltheme.com>
77 */
78 public function dashboard_widget_render() {
79 include_once ABSPATH . WPINC . '/feed.php';
80 $feed_url = 'https://jeweltheme.com/feed.xml';
81 // Get a SimplePie feed object from the specified feed source .
82 $rss = fetch_feed( $feed_url );
83 $maxitems = 0;
84 if ( !is_wp_error( $rss ) ) {
85 // Checks that the object is created correctly .
86 // Figure out how many total items there are, and choose a limit .
87 $maxitems = $rss->get_item_quantity( 5 );
88 // Build an array of all the items, starting with element 0 (first element).
89 $rss_items = $rss->get_items( 0, $maxitems );
90 // Get RSS title .
91 $rss_title = '<a href="' . $rss->get_permalink() . '" target="_blank">' . strtoupper( $rss->get_title() ) . '</a>';
92 }
93 // Display the container .
94 echo '<div class="wp-adminify-rss-widget">';
95 if ( wp_validate_boolean( $this->get_content( 'is_live' ) ) ) {
96 ?>
97
98 <div class="wp-adminify-dashboard-promo" style="--wp-adminify-popup-color: <?php
99 echo esc_attr( $this->get_content( 'btn_color' ) );
100 ?>;">
101 <a target="_blank" href="<?php
102 echo esc_url( $this->get_content( 'button_url' ) );
103 ?>">
104 <img src="<?php
105 echo esc_url( $this->get_content( 'image_url' ) );
106 ?>" alt="Adminify Promo Image" style="width: 100%; height: auto;">
107 </a>
108
109 <a class="wp-adminify-popup-button" style="color: #fff!important;" target="_blank" href="<?php
110 echo esc_url( $this->get_content( 'button_url' ) );
111 ?>">
112 <?php
113 echo esc_html( $this->get_content( 'button_text' ) );
114 ?>
115 </a>
116 </div>
117
118 <?php
119 }
120 // Starts items listing within <ul> tag
121 // Check items .
122 if ( !empty( $maxitems ) ) {
123 echo '<ul>';
124 // Loop through each feed item and display each item as a hyperlink.
125 foreach ( $rss_items as $item ) {
126 // Uncomment line below to display non human date
127 // $item_date = $item->get_date( get_option('date_format').' @ '.get_option('time_format') ); .
128 // Get human date (comment if you want to use non human date) .
129 // $item_date = human_time_diff( $item->get_date( 'U' ), current_time( 'timestamp' ) ) . ' ' . __( 'ago', 'adminify' );
130 // Start displaying item content within a <li> tag .
131 echo '<li>';
132 // create item link .
133 echo '<a href="' . esc_url( $item->get_permalink() ) . '" title="' . esc_attr( $item->get_title() ) . '" target="_blank">';
134 // Get item title .
135 echo esc_html( $item->get_title() );
136 echo '</a>';
137 // Display date .
138 // echo ' <span class="rss-date">' . esc_html( $item_date ) . '</span><br />';
139 // Get item content .
140 $content = $item->get_content();
141 // Shorten content .
142 $content = wp_html_excerpt( $content, 120 ) . ' ';
143 // Display content .
144 echo esc_html( $content );
145 // End <li> tag .
146 echo '</li>';
147 }
148 echo '</ul>';
149 // End <ul> tag .
150 }
151 ?>
152
153 <div class="wp-adminify-dashboard_footer">
154 <ul>
155 <li class="wp-adminify-overview__blog">
156 <a href="https://wpadminify.com/blog" target="_blank">
157 Blog
158 <span class="screen-reader-text">
159 <?php
160 echo esc_html__( '(opens in a new window)', 'adminify' );
161 ?>
162 </span>
163 <span aria-hidden="true" class="dashicons dashicons-external"></span>
164 </a>
165 </li>
166 <li class="wp-adminify-overview__help">
167 <a href="https://wpadminify.com/docs" target="_blank">
168 Help
169 <span class="screen-reader-text">
170 <?php
171 echo esc_html__( '(opens in a new window)', 'adminify' );
172 ?>
173 </span>
174 <span aria-hidden="true" class="dashicons dashicons-external"></span>
175 </a>
176 </li>
177 <li class="wp-adminify-overview__upgrade">
178 <a href="https://wpadminify.com/pricing" target="_blank">
179 Upgrade
180 <span class="screen-reader-text">
181 <?php
182 echo esc_html__( '(opens in a new window)', 'adminify' );
183 ?>
184 </span>
185 <span aria-hidden="true" class="dashicons dashicons-external"></span>
186 </a>
187 </li>
188
189 </ul>
190 </div>
191 <style>
192 /* News Dashboard Widget */
193 .wp-adminify-rss-widget .hndle.ui-sortable-handle img {
194 margin: -5px 10px -5px 0;
195 }
196
197 .wp-adminify-rss-widget .wp-adminify-dashboard_footer {
198 margin: 0 -12px -12px;
199 padding: 0 12px;
200 border-top: 1px solid #eee;
201 }
202
203 .wp-adminify-rss-widget .wp-adminify-dashboard_footer ul {
204 display: flex;
205 list-style: none;
206 }
207
208 .wp-adminify-rss-widget .wp-adminify-dashboard_footer ul li:first-child {
209 padding-left: 0;
210 border: none;
211 }
212
213 .wp-adminify-rss-widget .wp-adminify-dashboard_footer li {
214 padding: 0 10px;
215 margin: 0;
216 border-left: 1px solid #ddd;
217 }
218
219 .wp-adminify-rss-widget .wp-adminify-overview__go-pro a {
220 color: #FCB92C;
221 font-weight: 500;
222 }
223 </style>
224
225 <?php
226 echo '</div>';
227 }
228
229 /**
230 * Set merged data
231 *
232 * @return void
233 * @author Jewel Theme <support@jeweltheme.com>
234 */
235 public function set_data() {
236 $this->data = Helper::get_merged_data( self::get_data() );
237 }
238
239 /**
240 * Get Sheet data
241 *
242 * @author Jewel Theme <support@jeweltheme.com>
243 */
244 public static function get_data() {
245 return get_option( 'jltwp_adminify_sheet_promo_data' );
246 }
247
248 /**
249 * Get Contents
250 *
251 * @param [type] $key .
252 *
253 * @author Jewel Theme <support@jeweltheme.com>
254 */
255 public function get_content( $key ) {
256 if ( empty( $this->data ) ) {
257 return;
258 }
259 return $this->data[$key];
260 }
261
262 /**
263 * Get Option has data
264 *
265 * @author Jewel Theme <support@jeweltheme.com>
266 */
267 public function get_data_hash() {
268 return get_option( 'jltwp_adminify_sheet_promo_data_hash' );
269 }
270
271 /**
272 * Sync to remote data
273 *
274 * @author Jewel Theme <support@jeweltheme.com>
275 */
276 public function maybe_sync_remote_data() {
277 $data = self::get_data();
278 if ( empty( $data ) ) {
279 $this->sheet_data_remote_sync();
280 }
281 }
282
283 /**
284 * Register Sync hook
285 *
286 * @return void
287 * @author Jewel Theme <support@jeweltheme.com>
288 */
289 public function register_sync_hook() {
290 $hook_action = 'jltwp_adminify_sheet_promo_data_remote_sync';
291 add_action( $hook_action, array($this, 'sheet_data_remote_sync') );
292 if ( !wp_next_scheduled( $hook_action ) ) {
293 wp_schedule_event( time(), 'daily', $hook_action );
294 }
295 register_deactivation_hook( WP_ADMINIFY_FILE, array($this, 'clear_register_sync_hook') );
296 }
297
298 /**
299 * Clear register sync hook
300 *
301 * @return void
302 * @author Jewel Theme <support@jeweltheme.com>
303 */
304 public function clear_register_sync_hook() {
305 wp_clear_scheduled_hook( 'jltwp_adminify_sheet_promo_data_remote_sync' );
306 }
307
308 /**
309 * Data sync with remote
310 *
311 * @return void
312 * @author Jewel Theme <support@jeweltheme.com>
313 */
314 public function sheet_data_remote_sync() {
315 $data = self::get_data();
316 $force = empty( $data );
317 $remote_data = $this->get_update_remote_data();
318 // Don't clobber stored data when the API is unreachable / returned nothing.
319 if ( false === $remote_data ) {
320 return;
321 }
322 $stored_hash = $this->get_data_hash();
323 $remote_hash = base64_encode( json_encode( $remote_data ) );
324 if ( $force || $stored_hash !== $remote_hash ) {
325 update_option( 'jltwp_adminify_sheet_promo_data', $remote_data );
326 update_option( 'jltwp_adminify_sheet_promo_data_hash', $remote_hash );
327 do_action( 'jltwp_adminify_sheet_promo_data_reset' );
328 }
329 }
330
331 /**
332 * Update REST API base URL
333 *
334 * Development points to the local update service; production uses the
335 * Jewel Theme API endpoint. Override either with the `jltwp_adminify_endpoint` filter.
336 *
337 * @author Jewel Theme <support@jeweltheme.com>
338 */
339 public function get_api_base() {
340 $base = 'https://pixarlabs.com/';
341 return trailingslashit( apply_filters( 'jltwp_adminify_endpoint', $base ) );
342 }
343
344 /**
345 * Update endpoint URL for this plugin
346 *
347 * @author Jewel Theme <support@jeweltheme.com>
348 */
349 public function get_update_url() {
350 return esc_url( $this->get_api_base() . 'api/plugin/update/' . Helper::jltwp_adminify_slug_cleanup() );
351 }
352
353 /**
354 * Promotional remote data (REST API)
355 *
356 * Expects a single JSON object describing the update, e.g.
357 * { product_name, product_slug, image_url, start_date, end_date,
358 * button_text, button_url, btn_color, notice, show_for_premium, is_live }
359 *
360 * @return array|false
361 * @author Jewel Theme <support@jeweltheme.com>
362 */
363 public function get_update_remote_data() {
364 $response = wp_remote_get( $this->get_update_url(), array(
365 'timeout' => 15,
366 'headers' => array(
367 'Accept' => 'application/json',
368 ),
369 ) );
370 if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
371 return false;
372 }
373 $body = wp_remote_retrieve_body( $response );
374 if ( !$body ) {
375 return false;
376 }
377 $data = json_decode( $body, true );
378 if ( !is_array( $data ) || JSON_ERROR_NONE !== json_last_error() ) {
379 return false;
380 }
381 // API may return the update directly, or wrapped (e.g. { data: {...} }) / as a list.
382 if ( isset( $data['data'] ) && is_array( $data['data'] ) ) {
383 $data = $data['data'];
384 }
385 if ( isset( $data[0] ) && is_array( $data[0] ) ) {
386 $data = wp_list_filter( $data, array(
387 'product_slug' => Helper::jltwp_adminify_slug_cleanup(),
388 ) );
389 $data = ( $data ? array_values( $data )[0] : array() );
390 }
391 if ( empty( $data ) || empty( $data['product_slug'] ) ) {
392 return false;
393 }
394 // Only accept a update that targets this plugin.
395 if ( Helper::jltwp_adminify_slug_cleanup() !== $data['product_slug'] ) {
396 return false;
397 }
398 // API sends dates as "d/m/Y h:i a" — normalise so PHP/JS date parsers don't choke.
399 foreach ( array('start_date', 'end_date') as $key ) {
400 if ( !empty( $data[$key] ) ) {
401 $data[$key] = $this->normalize_date( $data[$key] );
402 }
403 }
404 return $data;
405 }
406
407 /**
408 * Normalise a update date string to 'Y-m-d H:i:s'
409 *
410 * Accepts d/m/Y (optionally with 12h time) and a few common fallbacks.
411 * Returns the original value untouched if it cannot be parsed.
412 *
413 * @param string $value .
414 * @author Jewel Theme <support@jeweltheme.com>
415 */
416 public function normalize_date( $value ) {
417 $value = trim( (string) $value );
418 $formats = array(
419 'd/m/Y h:i a',
420 'd/m/Y H:i',
421 'd/m/Y',
422 'd-m-Y H:i:s',
423 'd-m-Y'
424 );
425 foreach ( $formats as $format ) {
426 $dt = \DateTime::createFromFormat( $format, $value );
427 if ( $dt instanceof \DateTime ) {
428 return $dt->format( 'Y-m-d H:i:s' );
429 }
430 }
431 $ts = strtotime( $value );
432 return ( $ts ? gmdate( 'Y-m-d H:i:s', $ts ) : $value );
433 }
434
435 /**
436 * Display popup contents
437 *
438 * @author Jewel Theme <support@jeweltheme.com>
439 */
440 public function display_popup() {
441 if ( empty( $this->get_content( 'is_live' ) ) ) {
442 $image_url = WP_ADMINIFY_ASSETS_IMAGE . 'promo-image.png';
443 $notice = 'Use "SPECIAL40" to Get Flat 40% OFF';
444 $btn_url = 'https://wpadminify.com/pricing/';
445 $btn_text = 'GET THE DEAL';
446 } else {
447 $image_url = $this->get_content( 'image_url' );
448 $notice = $this->get_content( 'notice' );
449 $btn_url = $this->get_content( 'button_url' );
450 $btn_text = $this->get_content( 'button_text' );
451 }
452 ?>
453
454 <div class="wp-adminify-popup wp-adminify-upgrade-popup" id="wp-adminify-popup" data-plugin="<?php
455 echo esc_attr( $this->slug );
456 ?>" tabindex="1" style="display: none;">
457
458 <div class="wp-adminify-popup-overlay"></div>
459
460 <div class="wp-adminify-popup-modal" style="background-image: url('<?php
461 echo esc_url( $image_url );
462 ?>'); --wp-adminify-popup-color: <?php
463 echo esc_attr( $this->get_content( 'btn_color' ) );
464 ?>;">
465
466 <!-- close -->
467 <div class="wp-adminify-popup-modal-close popup-dismiss">×</div>
468
469 <!-- content section -->
470 <div class="wp-adminify-popup-modal-footer">
471 <!-- countdown -->
472 <div class="wp-adminify-popup-countdown" style="display: none;">
473
474 <?php
475 if ( !empty( $notice ) ) {
476 ?>
477 <span data-counter="notice" style="color:#F4B740; font-size:14px; padding-bottom:20px; font-style:italic;"><?php
478 echo esc_html__( 'Notice:', 'adminify' );
479 ?> <?php
480 echo wp_kses_post( $notice );
481 ?></span>
482 <?php
483 }
484 ?>
485
486 <span class="wp-adminify-popup-countdown-text"><?php
487 echo esc_html__( 'Deal Ends In', 'adminify' );
488 ?></span>
489 <div class="wp-adminify-popup-countdown-time">
490 <div>
491 <span data-counter="days">00</span>
492 <span><?php
493 echo esc_html__( 'Days', 'adminify' );
494 ?></span>
495 </div>
496 <span>:</span>
497 <div>
498 <span data-counter="hours">00</span>
499 <span><?php
500 echo esc_html__( 'Hours', 'adminify' );
501 ?></span>
502 </div>
503 <span>:</span>
504 <div>
505 <span data-counter="minutes">00</span>
506 <span><?php
507 echo esc_html__( 'Minutes', 'adminify' );
508 ?></span>
509 </div>
510 <span>:</span>
511 <div>
512 <span data-counter="seconds">00</span>
513 <span><?php
514 echo esc_html__( 'Seconds', 'adminify' );
515 ?></span>
516 </div>
517 </div>
518 </div>
519
520 <!-- button -->
521 <a class="wp-adminify-popup-button" style="color: #fff!important;" target="_blank" href="<?php
522 echo esc_url( $btn_url );
523 ?>"><?php
524 echo esc_html( $btn_text );
525 ?></a>
526 </div>
527 </div>
528 </div>
529
530 <script>
531 var $container = jQuery('#wp-adminify-popup'),
532 plugin_data = <?php
533 echo wp_json_encode( $this->data );
534 ?>,
535 events = {}; //Events
536
537 // Update Counter
538 function updateCounter(seconds) {
539 const $counter = $container.find(".wp-adminify-popup-countdown-time");
540 const $days = $counter.find("[data-counter='days']");
541 const $hours = $counter.find("[data-counter='hours']");
542 const $minutes = $counter.find("[data-counter='minutes']");
543 const $seconds = $counter.find("[data-counter='seconds']");
544 const days = Math.floor(seconds / (3600 * 24));
545 seconds -= days * 3600 * 24;
546 const hrs = Math.floor(seconds / 3600);
547 seconds -= hrs * 3600;
548 const mnts = Math.floor(seconds / 60);
549 seconds -= mnts * 60;
550
551 $days.text(days);
552 $hours.text(hrs);
553 $minutes.text(mnts);
554 $seconds.text(seconds);
555 }
556
557 // Trigger Event
558 function trigger(event, args = []) {
559 if (typeof(events[event]) !== 'undefined') {
560 events[event].forEach(callback => {
561 callback.apply(this, args);
562 });
563 }
564 }
565
566 // initCounter
567 function initCounter(last_date) {
568 $container.find(".wp-adminify-popup-countdown-time").show();
569
570 const countdown = () => {
571
572 // system time
573 const now = new Date().getTime();
574
575 // set end time to 11:59:59 PM
576 const endDate = new Date(last_date);
577 endDate.setHours(23);
578 endDate.setMinutes(59);
579 endDate.setSeconds(59);
580
581 const seconds = Math.floor((endDate.getTime() - now) / 1000);
582
583 if (seconds < 0) {
584 return false;
585 }
586
587 updateCounter(seconds);
588
589 return true;
590 }
591
592 let result = countdown();
593
594
595 if (result) {
596 trigger("countdownStart", [plugin_data]);
597 $container.find(".wp-adminify-popup-countdown").show(0);
598 } else {
599 trigger("countdownFinish", [plugin_data]);
600 $container.find(".wp-adminify-popup-countdown").hide(0);
601 }
602
603 // update counter every 1 second
604 const counter = setInterval(() => {
605
606 const result = countdown();
607
608 if (!result) {
609 clearInterval(counter);
610 trigger("counter_end", [plugin_data]);
611 $container.find(".wp-adminify-popup-countdown").hide(0);
612 }
613
614 }, 1000);
615 }
616
617 initCounter('<?php
618 echo esc_attr( $this->counter_date() );
619 ?>');
620 </script>
621
622 <?php
623 }
624
625 /**
626 * Counter Date
627 *
628 * @author Jewel Theme <support@jeweltheme.com>
629 */
630 public function counter_date() {
631 $endDate = $this->get_content( 'end_date' );
632 $is_active = $this->date_is_current_or_next( $endDate );
633 if ( $is_active ) {
634 return $endDate;
635 }
636 return $this->date_increment( $this->current_time(), 3 );
637 }
638
639 }
640