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

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