PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.2.20
Adminify – White Label, Admin Menu Editor, Login Customizer v4.2.20
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 / Notifications / Latest_Updates.php

Latest_Updates.php in Adminify – White Label, Admin Menu Editor, Login Customizer 4.2.20, at Inc/Classes/Notifications/Latest_Updates.php

457 lines 13.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PXLBSAdminify\Inc\Classes\Notifications;
4
5 if ( ! defined( 'ABSPATH' ) ) {
6 exit; // Exit if accessed directly.
7 }
8
9 use PXLBSAdminify\Inc\Classes\Notifications\Model\Notice;
10
11 if (!class_exists('Latest_Updates')) {
12 /**
13 * Latest Pugin Updates Notice Class
14 *
15 * Jewel Theme <support@jeweltheme.com>
16 */
17 class Latest_Updates extends Notice
18 {
19 public $type = 'notice';
20 public $color = 'info';
21
22 /**
23 * Check if we're on the WP Adminify settings page
24 *
25 * @return bool
26 */
27 private function is_adminify_settings_page() {
28 global $pagenow;
29 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check, no state change.
30 return is_admin() && $pagenow === 'admin.php' && isset( $_GET['page'] ) && $_GET['page'] === 'wp-adminify-settings';
31 }
32
33 /**
34 * Latest Updates Notice
35 *
36 * @return void
37 */
38 public function __construct()
39 {
40 parent::__construct();
41 if(is_admin()){
42 // TODO: Need to check about conflicts with other plugins
43 // add_action( 'admin_footer', array( $this, 'pxlbsadminify_handle_plugin_update_notice_dismiss' ),99999 );
44 add_action( 'wp_ajax_pxlbsadminify_plugin_update_info', array( $this, 'pxlbsadminify_plugin_update_info' ) );
45 }
46 }
47
48 /**
49 * Handles the AJAX request for the plugin update info notice dismissal.
50 *
51 * Triggered when the user clicks the Dismiss button in the notice.
52 *
53 * @since 1.0
54 *
55 * @return void
56 */
57 public function pxlbsadminify_plugin_update_info() {
58 if (!current_user_can('install_plugins')) {
59 return;
60 }
61
62 // Verify nonce for security.
63 check_ajax_referer( 'dismiss_notice_nonce', 'nonce' );
64
65 $action_type = isset( $_POST['action_type'] ) ? sanitize_text_field( wp_unslash( $_POST['action_type'] ) ) : 'dismiss';
66 $option_value = ( 'forever' === $action_type ) ? 'forever' : 'dismissed';
67
68 wp_send_json_success( array( 'message' => 'Notice dismissed.', 'data' => update_option('pxlbsadminify_plugin_update_info_notice', $option_value ) ) );
69 }
70
71
72 /**
73 * Notice Content
74 *
75 * @author Jewel Theme <support@jeweltheme.com>
76 */
77 public function notice_content()
78 {
79 if ( ! $this->is_adminify_settings_page() ) {
80 return;
81 }
82
83 $forever_notice = get_option('pxlbsadminify_plugin_update_info_notice', true );
84 if( 'forever' === $forever_notice ){
85 return;
86 }
87
88 if("dismissed" !== $forever_notice){
89 $pxlbsadminify_changelog_items =
90 __('<span class="dashicons dashicons-yes"></span> <span class="adminify-changes-list"> <strong>Improved:</strong> "Disable Site Health checks" now hides Site Health completely - the Tools > Site Health page, the dashboard widget, and the weekly background check are all turned off, so your clients never see it. </span><br>', 'adminify');
91
92 $pxlbsadminify_changelog_message = sprintf(
93 /* translators: %1$s: changelogs page URL. %2$s: link anchor text. %3$s: plugin update heading HTML. %4$s: changelog list items HTML. */
94 __('%3$s %4$s <br> <strong>Check Changelogs for </strong> <a href="%1$s" target="__blank">%2$s</a>', 'adminify'),
95 esc_url_raw('https://wpadminify.com/changelogs'),
96 __('More about Updates ', 'adminify'),
97 /** Changelog Items
98 * Starts from: %3$s
99 */
100
101 '<h3 class="adminify-update-head">' . PXLBSADMINIFY . ' <span><small><em>v' . esc_html(PXLBSADMINIFY_VER) . '</em></small>' . __(' has some updates..', 'adminify') . '</span></h3><br>', // %3$s
102 // changelogs
103 $pxlbsadminify_changelog_items
104 );
105 printf(wp_kses_post($pxlbsadminify_changelog_message));
106 }
107
108 $this->pxlbsadminify_handle_plugin_update_notice_dismiss();
109 }
110
111 /**
112 * Notice Header
113 *
114 * @author Jewel Theme <support@jeweltheme.com>
115 */
116 public function notice_header() {
117 if ( ! $this->is_adminify_settings_page() ) {
118 echo '<div class="wp-adminify-notice-hidden" style="display:none;"><div>';
119 return;
120 }
121
122 $notice_status = get_option('pxlbsadminify_plugin_update_info_notice', true );
123 if ( 'forever' === $notice_status ) {
124 echo '<div class="wp-adminify-notice-hidden" style="display:none;"><div>';
125 return;
126 }
127
128 if("dismissed" !== $notice_status){
129 $border_colors = array(
130 'info' => '#72aee6',
131 'success' => '#00a32a',
132 'warning' => '#dba617',
133 'error' => '#d63638',
134 );
135 $border_color = isset( $border_colors[ $this->color ] ) ? $border_colors[ $this->color ] : $border_colors['info'];
136 ?>
137 <div class="wp-adminify-notice--ignored wp-adminify-notice wp-adminify-notice-<?php echo esc_attr( $this->color ); ?> wp-adminify-notice-<?php echo esc_attr( $this->get_id() ); ?> wp-adminify-notice-plugin-update-info" style="background: #fff; border-left: 4px solid <?php echo esc_attr( $border_color ); ?>; padding: 10px 12px; margin: 5px 15px 2px 0; box-shadow: 0 1px 1px rgba(0,0,0,.04); position: relative;">
138 <button type="button" class="wp-adminify-notice-dismiss" data-notice-type="plugin_update_notice" style="position: absolute; top: 0; right: 1px; border: none; margin: 0; padding: 9px; background: none; color: #787c82; cursor: pointer;">
139 <span class="dashicons dashicons-no-alt"></span>
140 </button>
141 <div class="wp-adminify-notice-content">
142 <?php
143 }else{ echo '<div class="wp-adminify-notice-hidden" style="display:none;"><div>';}
144 }
145
146 public function pxlbsadminify_handle_plugin_update_notice_dismiss() { ?>
147
148 <!-- Update Notice Confirmation Modal -->
149 <div id="wp-adminify-update-notice-modal" class="wp-adminify-update-modal-overlay">
150 <div class="wp-adminify-update-modal">
151 <button type="button" class="wp-adminify-update-modal-close" id="wp-adminify-modal-close">
152 <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
153 <path d="M13 1L1 13M1 1L13 13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
154 </svg>
155 </button>
156 <div class="wp-adminify-update-modal-icon">
157 <div class="wp-adminify-update-modal-icon-ring">
158 <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
159 <path d="M12 16V12M12 8H12.01M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
160 </svg>
161 </div>
162 </div>
163 <h3 class="wp-adminify-update-modal-title"><?php echo esc_html__('Want to see future updates?', 'adminify'); ?></h3>
164 <p class="wp-adminify-update-modal-desc"><?php echo esc_html__('Stay informed about new features and improvements.', 'adminify'); ?></p>
165 <div class="wp-adminify-update-modal-buttons">
166 <button type="button" id="wp-adminify-notice-yes" class="wp-adminify-update-btn wp-adminify-update-btn-primary">
167 <span><?php echo esc_html__('Yes, notify me', 'adminify'); ?></span>
168 </button>
169 <button type="button" id="wp-adminify-notice-forever" class="wp-adminify-update-btn wp-adminify-update-btn-secondary">
170 <span><?php echo esc_html__("Don't show again", 'adminify'); ?></span>
171 </button>
172 </div>
173 </div>
174 </div>
175
176 <style>
177 .wp-adminify-update-modal-overlay {
178 --modal-accent: #5046e5;
179 --modal-accent-light: #6366f1;
180 --modal-accent-glow: rgba(80, 70, 229, 0.35);
181 --modal-text: #1e293b;
182 --modal-text-muted: #64748b;
183 --modal-bg: #ffffff;
184 --modal-border: #e2e8f0;
185 --modal-danger: #ef4444;
186
187 display: none;
188 position: fixed;
189 top: 0;
190 left: 0;
191 width: 100%;
192 height: 100%;
193 background: rgba(15, 23, 42, 0.5);
194 backdrop-filter: blur(8px);
195 -webkit-backdrop-filter: blur(8px);
196 z-index: 999999;
197 align-items: center;
198 justify-content: center;
199 }
200
201 .wp-adminify-update-modal {
202 background: var(--modal-bg);
203 padding: 48px 44px 44px;
204 border-radius: 20px;
205 max-width: 460px;
206 width: calc(100% - 32px);
207 text-align: center;
208 box-shadow:
209 0 0 0 1px rgba(0, 0, 0, 0.03),
210 0 2px 4px rgba(0, 0, 0, 0.02),
211 0 12px 24px rgba(0, 0, 0, 0.06),
212 0 32px 64px rgba(0, 0, 0, 0.12);
213 position: relative;
214 animation: wpAdminifyModalAppear 0.35s cubic-bezier(0.16, 1, 0.3, 1);
215 }
216
217 @keyframes wpAdminifyModalAppear {
218 from {
219 opacity: 0;
220 transform: scale(0.92) translateY(8px);
221 }
222 to {
223 opacity: 1;
224 transform: scale(1) translateY(0);
225 }
226 }
227
228 .wp-adminify-update-modal-close {
229 position: absolute;
230 top: 18px;
231 right: 18px;
232 width: 36px;
233 height: 36px;
234 border: none;
235 background: transparent;
236 color: var(--modal-danger);
237 cursor: pointer;
238 display: flex;
239 align-items: center;
240 justify-content: center;
241 border-radius: 10px;
242 transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
243 opacity: 0.7;
244 }
245
246 .wp-adminify-update-modal-close:hover {
247 background: #fef2f2;
248 opacity: 1;
249 transform: scale(1.05);
250 }
251
252 .wp-adminify-update-modal-close:active {
253 transform: scale(0.95);
254 }
255
256 .wp-adminify-update-modal-icon {
257 margin-bottom: 24px;
258 display: flex;
259 justify-content: center;
260 }
261
262 .wp-adminify-update-modal-icon-ring {
263 width: 64px;
264 height: 64px;
265 border-radius: 50%;
266 border: 2px solid var(--modal-accent);
267 display: flex;
268 align-items: center;
269 justify-content: center;
270 color: var(--modal-accent);
271 background: linear-gradient(135deg, rgba(80, 70, 229, 0.04) 0%, rgba(99, 102, 241, 0.08) 100%);
272 animation: wpAdminifyIconPulse 2s ease-in-out infinite;
273 }
274
275 @keyframes wpAdminifyIconPulse {
276 0%, 100% {
277 box-shadow: 0 0 0 0 rgba(80, 70, 229, 0.15);
278 }
279 50% {
280 box-shadow: 0 0 0 8px rgba(80, 70, 229, 0);
281 }
282 }
283
284 .wp-adminify-update-modal-title {
285 margin: 0 0 8px;
286 font-size: 22px;
287 font-weight: 600;
288 color: var(--modal-text);
289 letter-spacing: -0.02em;
290 line-height: 1.3;
291 }
292
293 .wp-adminify-update-modal-desc {
294 margin: 0 0 32px;
295 font-size: 15px;
296 color: var(--modal-text-muted);
297 line-height: 1.6;
298 }
299
300 .wp-adminify-update-modal-buttons {
301 display: flex;
302 flex-direction: row;
303 gap: 12px;
304 }
305
306 .wp-adminify-update-btn {
307 position: relative;
308 padding: 16px 24px;
309 border: none;
310 border-radius: 12px;
311 cursor: pointer;
312 font-size: 15px;
313 font-weight: 600;
314 letter-spacing: -0.01em;
315 transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
316 flex: 1;
317 overflow: hidden;
318 white-space: nowrap;
319 }
320
321 .wp-adminify-update-btn span {
322 position: relative;
323 z-index: 1;
324 }
325
326 .wp-adminify-update-btn-primary {
327 background: linear-gradient(135deg, var(--modal-accent-light) 0%, var(--modal-accent) 100%);
328 color: #fff;
329 }
330
331 .wp-adminify-update-btn-primary:hover {
332 background: linear-gradient(135deg, var(--modal-accent) 0%, #4338ca 100%);
333 }
334
335 .wp-adminify-update-btn-primary:active {
336 background: linear-gradient(135deg, #4338ca 0%, #3730a3 100%);
337 }
338
339 .wp-adminify-update-btn-secondary {
340 background: #fef2f2;
341 color: #dc2626;
342 }
343
344 .wp-adminify-update-btn-secondary:hover {
345 background: #fee2e2;
346 color: #b91c1c;
347 }
348
349 .wp-adminify-update-btn-secondary:active {
350 background: #fecaca;
351 color: #991b1b;
352 }
353
354 /* Responsive adjustments */
355 @media (max-width: 520px) {
356 .wp-adminify-update-modal {
357 padding: 40px 28px 32px;
358 border-radius: 16px;
359 }
360 .wp-adminify-update-modal-title {
361 font-size: 20px;
362 }
363 .wp-adminify-update-modal-buttons {
364 flex-direction: column;
365 }
366 .wp-adminify-update-btn {
367 padding: 14px 20px;
368 flex: none;
369 width: 100%;
370 }
371 }
372 </style>
373
374 <script>
375 (function($) {
376 var $modal = $('#wp-adminify-update-notice-modal');
377 var $noticeContainer = null;
378
379 function pxlbsadminify_run_dismiss_ajax(action_type) {
380 $.post('<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>', {
381 action: 'pxlbsadminify_plugin_update_info',
382 _wpnonce: '<?php echo esc_js( wp_create_nonce( 'dismiss_notice_nonce' ) ); ?>',
383 action_type: action_type
384 }).then(function(response) {
385 console.log(response);
386 });
387 }
388
389 function closeModal() {
390 $modal.css('display', 'none');
391 }
392
393 // Notice Dismiss - Show Modal
394 $(document).on('click', '.wp-adminify-notice-plugin-update-info .wp-adminify-notice-dismiss', function(evt) {
395 evt.preventDefault();
396 evt.stopImmediatePropagation();
397 $noticeContainer = $(this).closest('.wp-adminify-notice-plugin-update-info');
398 $modal.css('display', 'flex');
399 });
400
401 // "Yes" button - Dismiss temporarily
402 $(document).on('click', '#wp-adminify-notice-yes', function(evt) {
403 evt.preventDefault();
404 if ($noticeContainer) {
405 $noticeContainer.slideUp(200);
406 }
407 pxlbsadminify_run_dismiss_ajax('dismiss');
408 closeModal();
409 });
410
411 // "Don't show me again" button - Dismiss forever
412 $(document).on('click', '#wp-adminify-notice-forever', function(evt) {
413 evt.preventDefault();
414 if ($noticeContainer) {
415 $noticeContainer.slideUp(200);
416 }
417 pxlbsadminify_run_dismiss_ajax('forever');
418 closeModal();
419 });
420
421 // Close modal on X button click
422 $(document).on('click', '#wp-adminify-modal-close', function(evt) {
423 evt.preventDefault();
424 closeModal();
425 });
426
427 // Close modal on overlay click
428 $modal.on('click', function(evt) {
429 if (evt.target === this) {
430 closeModal();
431 }
432 });
433
434 // Close modal on Escape key
435 $(document).on('keydown', function(evt) {
436 if (evt.key === 'Escape' && $modal.is(':visible')) {
437 closeModal();
438 }
439 });
440 })(jQuery);
441 </script>
442
443 <?php
444 }
445
446 /**
447 * Intervals
448 *
449 * @author Jewel Theme <support@jeweltheme.com>
450 */
451 public function intervals()
452 {
453 return array(0);
454 }
455 }
456 }
457