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

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