PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.2.22
Adminify – White Label, Admin Menu Editor, Login Customizer v4.2.22
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.22, at Inc/Classes/Notifications/Latest_Updates.php

458 lines 14.0 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>Fixed:</strong> The "Last Login" column on the Users page now shows the time in your site\'s own time zone and date format, instead of a different time. </span><br>', 'adminify')
91 . __('<span class="dashicons dashicons-yes"></span> <span class="adminify-changes-list"> <strong>Fixed:</strong> The profile picture in the top bar no longer shows a broken image when a user has no picture; a default one is shown instead. </span><br>', 'adminify');
92
93 $pxlbsadminify_changelog_message = sprintf(
94 /* translators: %1$s: changelogs page URL. %2$s: link anchor text. %3$s: plugin update heading HTML. %4$s: changelog list items HTML. */
95 __('%3$s %4$s <br> <strong>Check Changelogs for </strong> <a href="%1$s" target="__blank">%2$s</a>', 'adminify'),
96 esc_url_raw('https://wpadminify.com/changelogs'),
97 __('More about Updates ', 'adminify'),
98 /** Changelog Items
99 * Starts from: %3$s
100 */
101
102 '<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
103 // changelogs
104 $pxlbsadminify_changelog_items
105 );
106 printf(wp_kses_post($pxlbsadminify_changelog_message));
107 }
108
109 $this->pxlbsadminify_handle_plugin_update_notice_dismiss();
110 }
111
112 /**
113 * Notice Header
114 *
115 * @author Jewel Theme <support@jeweltheme.com>
116 */
117 public function notice_header() {
118 if ( ! $this->is_adminify_settings_page() ) {
119 echo '<div class="wp-adminify-notice-hidden" style="display:none;"><div>';
120 return;
121 }
122
123 $notice_status = get_option('pxlbsadminify_plugin_update_info_notice', true );
124 if ( 'forever' === $notice_status ) {
125 echo '<div class="wp-adminify-notice-hidden" style="display:none;"><div>';
126 return;
127 }
128
129 if("dismissed" !== $notice_status){
130 $border_colors = array(
131 'info' => '#72aee6',
132 'success' => '#00a32a',
133 'warning' => '#dba617',
134 'error' => '#d63638',
135 );
136 $border_color = isset( $border_colors[ $this->color ] ) ? $border_colors[ $this->color ] : $border_colors['info'];
137 ?>
138 <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;">
139 <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;">
140 <span class="dashicons dashicons-no-alt"></span>
141 </button>
142 <div class="wp-adminify-notice-content">
143 <?php
144 }else{ echo '<div class="wp-adminify-notice-hidden" style="display:none;"><div>';}
145 }
146
147 public function pxlbsadminify_handle_plugin_update_notice_dismiss() { ?>
148
149 <!-- Update Notice Confirmation Modal -->
150 <div id="wp-adminify-update-notice-modal" class="wp-adminify-update-modal-overlay">
151 <div class="wp-adminify-update-modal">
152 <button type="button" class="wp-adminify-update-modal-close" id="wp-adminify-modal-close">
153 <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
154 <path d="M13 1L1 13M1 1L13 13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
155 </svg>
156 </button>
157 <div class="wp-adminify-update-modal-icon">
158 <div class="wp-adminify-update-modal-icon-ring">
159 <svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
160 <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"/>
161 </svg>
162 </div>
163 </div>
164 <h3 class="wp-adminify-update-modal-title"><?php echo esc_html__('Want to see future updates?', 'adminify'); ?></h3>
165 <p class="wp-adminify-update-modal-desc"><?php echo esc_html__('Stay informed about new features and improvements.', 'adminify'); ?></p>
166 <div class="wp-adminify-update-modal-buttons">
167 <button type="button" id="wp-adminify-notice-yes" class="wp-adminify-update-btn wp-adminify-update-btn-primary">
168 <span><?php echo esc_html__('Yes, notify me', 'adminify'); ?></span>
169 </button>
170 <button type="button" id="wp-adminify-notice-forever" class="wp-adminify-update-btn wp-adminify-update-btn-secondary">
171 <span><?php echo esc_html__("Don't show again", 'adminify'); ?></span>
172 </button>
173 </div>
174 </div>
175 </div>
176
177 <style>
178 .wp-adminify-update-modal-overlay {
179 --modal-accent: #5046e5;
180 --modal-accent-light: #6366f1;
181 --modal-accent-glow: rgba(80, 70, 229, 0.35);
182 --modal-text: #1e293b;
183 --modal-text-muted: #64748b;
184 --modal-bg: #ffffff;
185 --modal-border: #e2e8f0;
186 --modal-danger: #ef4444;
187
188 display: none;
189 position: fixed;
190 top: 0;
191 left: 0;
192 width: 100%;
193 height: 100%;
194 background: rgba(15, 23, 42, 0.5);
195 backdrop-filter: blur(8px);
196 -webkit-backdrop-filter: blur(8px);
197 z-index: 999999;
198 align-items: center;
199 justify-content: center;
200 }
201
202 .wp-adminify-update-modal {
203 background: var(--modal-bg);
204 padding: 48px 44px 44px;
205 border-radius: 20px;
206 max-width: 460px;
207 width: calc(100% - 32px);
208 text-align: center;
209 box-shadow:
210 0 0 0 1px rgba(0, 0, 0, 0.03),
211 0 2px 4px rgba(0, 0, 0, 0.02),
212 0 12px 24px rgba(0, 0, 0, 0.06),
213 0 32px 64px rgba(0, 0, 0, 0.12);
214 position: relative;
215 animation: wpAdminifyModalAppear 0.35s cubic-bezier(0.16, 1, 0.3, 1);
216 }
217
218 @keyframes wpAdminifyModalAppear {
219 from {
220 opacity: 0;
221 transform: scale(0.92) translateY(8px);
222 }
223 to {
224 opacity: 1;
225 transform: scale(1) translateY(0);
226 }
227 }
228
229 .wp-adminify-update-modal-close {
230 position: absolute;
231 top: 18px;
232 right: 18px;
233 width: 36px;
234 height: 36px;
235 border: none;
236 background: transparent;
237 color: var(--modal-danger);
238 cursor: pointer;
239 display: flex;
240 align-items: center;
241 justify-content: center;
242 border-radius: 10px;
243 transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
244 opacity: 0.7;
245 }
246
247 .wp-adminify-update-modal-close:hover {
248 background: #fef2f2;
249 opacity: 1;
250 transform: scale(1.05);
251 }
252
253 .wp-adminify-update-modal-close:active {
254 transform: scale(0.95);
255 }
256
257 .wp-adminify-update-modal-icon {
258 margin-bottom: 24px;
259 display: flex;
260 justify-content: center;
261 }
262
263 .wp-adminify-update-modal-icon-ring {
264 width: 64px;
265 height: 64px;
266 border-radius: 50%;
267 border: 2px solid var(--modal-accent);
268 display: flex;
269 align-items: center;
270 justify-content: center;
271 color: var(--modal-accent);
272 background: linear-gradient(135deg, rgba(80, 70, 229, 0.04) 0%, rgba(99, 102, 241, 0.08) 100%);
273 animation: wpAdminifyIconPulse 2s ease-in-out infinite;
274 }
275
276 @keyframes wpAdminifyIconPulse {
277 0%, 100% {
278 box-shadow: 0 0 0 0 rgba(80, 70, 229, 0.15);
279 }
280 50% {
281 box-shadow: 0 0 0 8px rgba(80, 70, 229, 0);
282 }
283 }
284
285 .wp-adminify-update-modal-title {
286 margin: 0 0 8px;
287 font-size: 22px;
288 font-weight: 600;
289 color: var(--modal-text);
290 letter-spacing: -0.02em;
291 line-height: 1.3;
292 }
293
294 .wp-adminify-update-modal-desc {
295 margin: 0 0 32px;
296 font-size: 15px;
297 color: var(--modal-text-muted);
298 line-height: 1.6;
299 }
300
301 .wp-adminify-update-modal-buttons {
302 display: flex;
303 flex-direction: row;
304 gap: 12px;
305 }
306
307 .wp-adminify-update-btn {
308 position: relative;
309 padding: 16px 24px;
310 border: none;
311 border-radius: 12px;
312 cursor: pointer;
313 font-size: 15px;
314 font-weight: 600;
315 letter-spacing: -0.01em;
316 transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
317 flex: 1;
318 overflow: hidden;
319 white-space: nowrap;
320 }
321
322 .wp-adminify-update-btn span {
323 position: relative;
324 z-index: 1;
325 }
326
327 .wp-adminify-update-btn-primary {
328 background: linear-gradient(135deg, var(--modal-accent-light) 0%, var(--modal-accent) 100%);
329 color: #fff;
330 }
331
332 .wp-adminify-update-btn-primary:hover {
333 background: linear-gradient(135deg, var(--modal-accent) 0%, #4338ca 100%);
334 }
335
336 .wp-adminify-update-btn-primary:active {
337 background: linear-gradient(135deg, #4338ca 0%, #3730a3 100%);
338 }
339
340 .wp-adminify-update-btn-secondary {
341 background: #fef2f2;
342 color: #dc2626;
343 }
344
345 .wp-adminify-update-btn-secondary:hover {
346 background: #fee2e2;
347 color: #b91c1c;
348 }
349
350 .wp-adminify-update-btn-secondary:active {
351 background: #fecaca;
352 color: #991b1b;
353 }
354
355 /* Responsive adjustments */
356 @media (max-width: 520px) {
357 .wp-adminify-update-modal {
358 padding: 40px 28px 32px;
359 border-radius: 16px;
360 }
361 .wp-adminify-update-modal-title {
362 font-size: 20px;
363 }
364 .wp-adminify-update-modal-buttons {
365 flex-direction: column;
366 }
367 .wp-adminify-update-btn {
368 padding: 14px 20px;
369 flex: none;
370 width: 100%;
371 }
372 }
373 </style>
374
375 <script>
376 (function($) {
377 var $modal = $('#wp-adminify-update-notice-modal');
378 var $noticeContainer = null;
379
380 function pxlbsadminify_run_dismiss_ajax(action_type) {
381 $.post('<?php echo esc_url( admin_url( 'admin-ajax.php' ) ); ?>', {
382 action: 'pxlbsadminify_plugin_update_info',
383 _wpnonce: '<?php echo esc_js( wp_create_nonce( 'dismiss_notice_nonce' ) ); ?>',
384 action_type: action_type
385 }).then(function(response) {
386 console.log(response);
387 });
388 }
389
390 function closeModal() {
391 $modal.css('display', 'none');
392 }
393
394 // Notice Dismiss - Show Modal
395 $(document).on('click', '.wp-adminify-notice-plugin-update-info .wp-adminify-notice-dismiss', function(evt) {
396 evt.preventDefault();
397 evt.stopImmediatePropagation();
398 $noticeContainer = $(this).closest('.wp-adminify-notice-plugin-update-info');
399 $modal.css('display', 'flex');
400 });
401
402 // "Yes" button - Dismiss temporarily
403 $(document).on('click', '#wp-adminify-notice-yes', function(evt) {
404 evt.preventDefault();
405 if ($noticeContainer) {
406 $noticeContainer.slideUp(200);
407 }
408 pxlbsadminify_run_dismiss_ajax('dismiss');
409 closeModal();
410 });
411
412 // "Don't show me again" button - Dismiss forever
413 $(document).on('click', '#wp-adminify-notice-forever', function(evt) {
414 evt.preventDefault();
415 if ($noticeContainer) {
416 $noticeContainer.slideUp(200);
417 }
418 pxlbsadminify_run_dismiss_ajax('forever');
419 closeModal();
420 });
421
422 // Close modal on X button click
423 $(document).on('click', '#wp-adminify-modal-close', function(evt) {
424 evt.preventDefault();
425 closeModal();
426 });
427
428 // Close modal on overlay click
429 $modal.on('click', function(evt) {
430 if (evt.target === this) {
431 closeModal();
432 }
433 });
434
435 // Close modal on Escape key
436 $(document).on('keydown', function(evt) {
437 if (evt.key === 'Escape' && $modal.is(':visible')) {
438 closeModal();
439 }
440 });
441 })(jQuery);
442 </script>
443
444 <?php
445 }
446
447 /**
448 * Intervals
449 *
450 * @author Jewel Theme <support@jeweltheme.com>
451 */
452 public function intervals()
453 {
454 return array(0);
455 }
456 }
457 }
458