PluginProbe
Adminify – White Label, Admin Menu Editor, Login Customizer / 4.3.2
Adminify – White Label, Admin Menu Editor, Login Customizer v4.3.2
4.3.2 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 All 165 releases
← All changes | Inc/Classes/Assets.php +335 -51 4.2.54.3.2 View file →
@@ -27,16 +27,43 @@
27 27 $global_dark_mode = !empty($this->options['light_dark_mode']['admin_ui_mode']) ? $this->options['light_dark_mode']['admin_ui_mode'] : 'light';
28 28 $this->dark_mode = empty(get_user_meta(get_current_user_id(), 'color_mode', true)) ? $global_dark_mode : get_user_meta(get_current_user_id(), 'color_mode', true);
29 29 add_action('admin_enqueue_scripts', array($this, 'pxlbsadminify_admin_scripts'), 100);
30 30 add_action('wp_ajax_pxlbsadminify_addons_install_active', array( $this, 'pxlbsadminify_addons_install_active' ) );
31 + add_action('wp_ajax_pxlbsadminify_ssl_check', array( $this, 'pxlbsadminify_ssl_check' ) );
31 32
32 - if ($this->is_dark_mode() || $this->classic_editor || $this->block_editor) {
33 - add_action('admin_head', array($this, 'header_scripts'));
34 - }
33 + // Always hooked: header_scripts() prints the dark-mode loader, which the
34 + // topbar toggle needs even on pages that booted in light mode.
35 + add_action('admin_head', array($this, 'header_scripts'));
35 36 }
36 37
37 38
38 39 /**
40 + * Resolved light/dark mode for the current user, normalised to
41 + * 'light' | 'dark' | 'system'. The settings UI has used 'auto' as a
42 + * synonym for 'system', so fold that in here.
43 + *
44 + * @return string
45 + */
46 + public function color_mode()
47 + {
48 + $mode = !empty($this->dark_mode) ? $this->dark_mode : 'light';
49 +
50 + return ('auto' === $mode) ? 'system' : $mode;
51 + }
52 +
53 +
54 + /**
55 + * URL of the dark mode (Darkreader) bundle.
56 + *
57 + * @return string
58 + */
59 + private function dark_mode_url()
60 + {
61 + return PXLBSADMINIFY_ASSETS . 'admin/js/wp-adminify-dark-mode' . Utils::assets_ext('.js');
62 + }
63 +
64 +
65 + /**
39 66 * Function: Ajax Call for Install and Activate WP Adminify Plugin
40 67 */
41 68 function pxlbsadminify_addons_install_active()
42 69 {
@@ -148,8 +175,25 @@
148 175 }
149 176 return $adminify_dark_mode;
150 177 }
151 178
179 + /**
180 + * Print the dark-mode loader and boot it for the resolved mode.
181 + *
182 + * The Darkreader bundle is ~110 KB, so it is no longer enqueued on every admin
183 + * page. What ships on every page instead is `window.PXLBSADMINIFYDarkMode`, a few hundred
184 + * bytes that know how to pull the bundle into a window on demand:
185 + *
186 + * - 'dark' the bundle is already enqueued in the head by
187 + * pxlbsadminify_admin_scripts(), so this only calls enable().
188 + * - 'system' nothing is enqueued; the browser decides. When the OS prefers dark
189 + * the loader fetches the bundle, with a pre-paint guard so the page
190 + * does not flash white while it streams in.
191 + * - 'light' nothing is fetched at all.
192 + *
193 + * The topbar toggle (classic admin bar and the React frame alike) calls
194 + * PXLBSADMINIFYDarkMode.load() so switching to dark works without a page reload.
195 + */
152 196 public function header_scripts()
153 197 {
154 198 // Skip on excluded pages
155 199 if ( $this->should_skip_adminify_scripts() ) {
@@ -155,46 +199,120 @@
155 199 if ( $this->should_skip_adminify_scripts() ) {
156 200 return;
157 201 }
158 202
159 - if (!empty($this->dark_mode) && $this->dark_mode == 'dark') { ?>
203 + $mode = $this->color_mode();
204 + ?>
205 + <script id="adminify-dark-mode-loader">
206 + window.PXLBSADMINIFYDarkMode = window.PXLBSADMINIFYDarkMode || (function () {
207 + var url = <?php echo wp_json_encode( $this->dark_mode_url() ); ?>;
160 208
209 + // Pulls the bundle into `win` (defaults to this window) and hands
210 + // AdminifyDarkMode to `cb`. Repeat calls while a fetch is in flight
211 + // queue up behind it instead of requesting the file again.
212 + function load(win, cb) {
213 + win = win || window;
214 + cb = cb || function () {};
215 +
216 + var doc;
217 + try {
218 + doc = win.document;
219 + } catch (e) {
220 + return;
221 + }
222 + if (!doc) {
223 + return;
224 + }
225 +
226 + if (win.AdminifyDarkMode) {
227 + cb(win.AdminifyDarkMode);
228 + return;
229 + }
230 +
231 + if (win.__pxlbsadminifyDarkModeQueue) {
232 + win.__pxlbsadminifyDarkModeQueue.push(cb);
233 + return;
234 + }
235 + win.__pxlbsadminifyDarkModeQueue = [cb];
236 +
237 + var script = doc.createElement('script');
238 + script.src = url;
239 + script.async = false;
240 + script.onload = function () {
241 + var queue = win.__pxlbsadminifyDarkModeQueue || [];
242 + win.__pxlbsadminifyDarkModeQueue = null;
243 + for (var i = 0; i < queue.length; i++) {
244 + try {
245 + queue[i](win.AdminifyDarkMode);
246 + } catch (e) {}
247 + }
248 + };
249 + script.onerror = function () {
250 + win.__pxlbsadminifyDarkModeQueue = null;
251 + };
252 + (doc.head || doc.documentElement).appendChild(script);
253 + }
254 +
255 + function enable(win) {
256 + load(win, function (dm) {
257 + if (dm) {
258 + dm.enable({ brightness: 120 });
259 + }
260 + });
261 + }
262 +
263 + function disable(win) {
264 + win = win || window;
265 + // Nothing to undo when the bundle was never fetched.
266 + if (win.AdminifyDarkMode) {
267 + win.AdminifyDarkMode.disable();
268 + }
269 + }
270 +
271 + return { url: url, load: load, enable: enable, disable: disable };
272 + }());
273 + </script>
274 + <?php if ( 'dark' === $mode ) { ?>
161 275 <script>
162 - window.AdminifyDarkMode.enable({
163 - brightness: 120
164 - })
165 -
166 - addEventListener("load", (event) => {
167 - window.AdminifyDarkMode.enable({
168 - brightness: 120
169 - })
276 + window.PXLBSADMINIFYDarkMode.enable();
277 + addEventListener("load", function () {
278 + window.PXLBSADMINIFYDarkMode.enable();
170 279 });
171 280 </script>
172 - <?php }
281 + <?php } elseif ( 'system' === $mode ) { ?>
282 + <script>
283 + (function () {
284 + if (!(window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
285 + return;
286 + }
173 287
174 - if (!empty($this->dark_mode) && $this->dark_mode == 'system') { ?>
175 - <script>
176 - const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
177 - if(!!isDark) {
178 - window.AdminifyDarkMode.enable({
179 - brightness: 120
180 - })
288 + // The bundle is fetched rather than blocking in the head, so paint
289 + // the page dark up front and drop the guard once Darkreader owns it.
290 + var guard = document.createElement('style');
291 + guard.textContent = 'html,body{background-color:#181a1b!important;color:#e8e6e3!important}';
292 + (document.head || document.documentElement).appendChild(guard);
181 293
182 - addEventListener("load", (event) => {
183 - window.AdminifyDarkMode.enable({
184 - brightness: 120
185 - })
294 + var dropGuard = function () {
295 + if (guard && guard.parentNode) {
296 + guard.parentNode.removeChild(guard);
297 + }
298 + };
299 +
300 + window.PXLBSADMINIFYDarkMode.load(window, function (dm) {
301 + if (dm) {
302 + dm.enable({ brightness: 120 });
303 + }
304 + dropGuard();
186 305 });
187 - } else {
188 - window.AdminifyDarkMode.disable()
189 306
190 - addEventListener("load", (event) => {
191 - window.AdminifyDarkMode.disable()
307 + // Failsafe: never leave the guard behind if the fetch never lands.
308 + setTimeout(dropGuard, 5000);
309 +
310 + addEventListener("load", function () {
311 + window.PXLBSADMINIFYDarkMode.enable();
192 312 });
193 - }
194 -
313 + }());
195 314 </script>
196 -
197 315 <?php }
198 316
199 317 }
200 318
@@ -241,8 +359,120 @@
241 359 return false;
242 360 }
243 361
244 362
363 + /**
364 + * Matches a Font Awesome class in any of the shapes Adminify stores:
365 + * "fa fa-gear", "fas fa-rocket", and the URL-encoded "fas%20fa-rocket" that
366 + * WordPress produces when an icon class is handed to add_menu_page().
367 + */
368 + const FONTAWESOME_CLASS_PATTERN = '/(?:^|[^a-z0-9-])fa[bsrl]?(?:\s|%20|-)fa-/i';
369 +
370 +
371 + /**
372 + * Whether Font Awesome has anything to paint on the current screen.
373 + *
374 + * The stylesheet plus its webfonts weigh well over a megabyte, so it is only
375 + * worth loading where Adminify actually renders an icon with it:
376 + *
377 + * - Adminify's own screens, whose section headers and field UI use hardcoded
378 + * `fas fa-*` classes.
379 + * - The dashboard, but only when a widget is actually configured with a Font
380 + * Awesome class.
381 + * - Any screen at all when an admin menu item carries a Font Awesome icon,
382 + * because the sidebar renders on every screen.
383 + *
384 + * Framework option, metabox, taxonomy, widget, customizer, nav-menu, profile
385 + * and comment screens are deliberately not listed: the framework scopes and
386 + * enqueues Font Awesome itself in ADMINIFY::add_admin_enqueue_scripts().
387 + *
388 + * @param \WP_Screen|null $screen Current screen.
389 + * @return bool
390 + */
391 + private function needs_fontawesome( $screen ) {
392 +
393 + if ( isset( $screen->id ) && false !== strpos( $screen->id, 'wp-adminify' ) ) {
394 + return true;
395 + }
396 +
397 + if ( isset( $screen->id ) && 'dashboard' === $screen->id && $this->has_fontawesome_dashboard_widget() ) {
398 + return true;
399 + }
400 +
401 + // Falls through on the dashboard too: the admin menu renders there as well.
402 + return $this->has_fontawesome_menu_icon();
403 + }
404 +
405 +
406 + /**
407 + * Whether any dashboard widget is configured with a Font Awesome class.
408 + *
409 + * Widget icons come from the framework icon field, whose list is still Font
410 + * Awesome (Libs/adminify-framework/functions/actions.php), and the editor and
411 + * script widget types can hold arbitrary markup — so scan the whole saved
412 + * option rather than just the icon keys, or a widget whose body contains
413 + * `<i class="fas fa-star">` would render a blank square.
414 + *
415 + * The option is the one read by DashboardWidgetModel::$prefix, which the
416 + * Dashboard Widget module already loads on every admin page, so this is an
417 + * options-cache hit rather than a query. Only ever called on the dashboard.
418 + *
419 + * @return bool
420 + */
421 + private function has_fontawesome_dashboard_widget() {
422 +
423 + $settings = get_option( 'pxlbsadminify_dasboard_widgets' );
424 +
425 + if ( empty( $settings ) ) {
426 + return false;
427 + }
428 +
429 + // Arrays and objects come back as a serialized string; scalars pass through.
430 + $settings = maybe_serialize( $settings );
431 +
432 + if ( ! is_string( $settings ) || '' === $settings ) {
433 + return false;
434 + }
435 +
436 + return (bool) preg_match( self::FONTAWESOME_CLASS_PATTERN, $settings );
437 + }
438 +
439 +
440 + /**
441 + * Look for a Font Awesome class stored as an admin menu icon.
442 + *
443 + * Pro admin pages pass the picked icon class straight to add_menu_page()
444 + * (Pro/Modules/AdminPages/AdminPages_Output.php), where WordPress treats it as
445 + * an image URL and prints `http://fas%20fa-rocket`; wp-adminify.js turns that
446 + * back into a class. Either shape counts as a hit.
447 + *
448 + * $menu is built during admin_menu, which runs before admin_enqueue_scripts,
449 + * so it is fully populated by the time this is called.
450 + *
451 + * @return bool
452 + */
453 + private function has_fontawesome_menu_icon() {
454 + global $menu;
455 +
456 + if ( empty( $menu ) || ! is_array( $menu ) ) {
457 + return false;
458 + }
459 +
460 + foreach ( $menu as $item ) {
461 +
462 + if ( empty( $item[6] ) || ! is_string( $item[6] ) ) {
463 + continue;
464 + }
465 +
466 + if ( preg_match( self::FONTAWESOME_CLASS_PATTERN, $item[6] ) ) {
467 + return true;
468 + }
469 + }
470 +
471 + return false;
472 + }
473 +
474 +
245 475 public function pxlbsadminify_admin_scripts()
246 476 {
247 477 // Skip loading scripts on excluded pages (customize.php, login, etc.)
248 478 if ( $this->should_skip_adminify_scripts() ) {
@@ -254,25 +484,13 @@
254 484
255 485 // Register Styles
256 486 wp_register_style('adminify-admin', PXLBSADMINIFY_ASSETS . 'css/wp-adminify' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
257 487 wp_register_style('adminify-default-ui', PXLBSADMINIFY_ASSETS . 'css/wp-adminify-default-ui' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
258 - // wp_register_style('wp-adminify-admin-bar', PXLBSADMINIFY_ASSETS . 'css/admin-bar' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
259 - wp_register_style('adminify-menu-editor', PXLBSADMINIFY_ASSETS . 'css/adminify-menu-editor' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
260 - // wp_register_style('wp-adminify-dark-mode', PXLBSADMINIFY_ASSETS . 'css/dark-mode' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
261 - // wp_register_style('wp-adminify-rtl', PXLBSADMINIFY_ASSETS . 'css/adminify-rtl' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
262 - // wp_register_style('wp-adminify-responsive', PXLBSADMINIFY_ASSETS . 'css/adminify-responsive' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
263 - // wp_register_style('wp-adminify-animate', PXLBSADMINIFY_ASSETS . 'vendors/animatecss/animate' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
264 - wp_register_style('adminify-tokenize2', PXLBSADMINIFY_ASSETS . 'vendors/tokenize/tokenize2' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
265 - wp_register_style('adminify-select2', PXLBSADMINIFY_ASSETS . 'vendors/select2/select2' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
266 488
267 489
268 490 // Register Scripts
269 - wp_register_script('adminify-tokenize2', PXLBSADMINIFY_ASSETS . 'vendors/tokenize/tokenize2.min.js', array('jquery'), PXLBSADMINIFY_VER, false);
270 - wp_register_script('adminify-select2', PXLBSADMINIFY_ASSETS . 'vendors/select2/select2.min.js', array('jquery'), PXLBSADMINIFY_VER, true);
271 491 wp_register_script('adminify-admin', PXLBSADMINIFY_ASSETS . 'admin/js/wp-adminify' . Utils::assets_ext('.js'), array('jquery'), PXLBSADMINIFY_VER, true);
272 492
273 - // wp_register_script('wp-adminify-realtime-server', PXLBSADMINIFY_ASSETS . 'js/adminify-realtime-server.js', array('jquery'), PXLBSADMINIFY_VER, true);
274 -
275 493 // Adminify Icon Picker
276 494 wp_register_style('adminify-simple-line-icons', PXLBSADMINIFY_ASSETS . 'vendors/font-icons/simple-line-icons/css/simple-line-icons' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
277 495 wp_register_style('adminify-icon-picker', PXLBSADMINIFY_ASSETS . 'vendors/adminify-icon-picker/css/style' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
278 496 wp_register_script('adminify-icon-picker', PXLBSADMINIFY_ASSETS . 'vendors/adminify-icon-picker/js/adminify-icon-picker' . Utils::assets_ext('.js'), array('jquery'), PXLBSADMINIFY_VER, true);
@@ -277,13 +495,10 @@
277 495 wp_register_style('adminify-icon-picker', PXLBSADMINIFY_ASSETS . 'vendors/adminify-icon-picker/css/style' . Utils::assets_ext('.css'), false, PXLBSADMINIFY_VER);
278 496 wp_register_script('adminify-icon-picker', PXLBSADMINIFY_ASSETS . 'vendors/adminify-icon-picker/js/adminify-icon-picker' . Utils::assets_ext('.js'), array('jquery'), PXLBSADMINIFY_VER, true);
279 497
280 498 // Dark Mode
281 - wp_register_script('adminify--dark-mode', PXLBSADMINIFY_ASSETS . 'admin/js/wp-adminify-dark-mode' . Utils::assets_ext('.js'), array(), PXLBSADMINIFY_VER, false);
499 + wp_register_script('adminify--dark-mode', $this->dark_mode_url(), array(), PXLBSADMINIFY_VER, false);
282 500
283 - // Menu Editor
284 - wp_register_script('adminify-menu-editor', PXLBSADMINIFY_ASSETS . 'admin/js/wp-adminify-menu-editor' . Utils::assets_ext('.js'), array('jquery', 'jquery-ui-sortable', 'adminify-icon-picker'), PXLBSADMINIFY_VER, true);
285 -
286 501 // Styles Enqueue
287 502 if (!empty($this->options['admin_ui'])) {
288 503 // wp_enqueue_style('wp-adminify-animate');
289 504 wp_enqueue_style('adminify-admin');
@@ -288,9 +503,8 @@
288 503 // wp_enqueue_style('wp-adminify-animate');
289 504 wp_enqueue_style('adminify-admin');
290 505 // Commented on: 9-6-24
291 506 // wp_enqueue_style('wp-adminify-admin-bar');
292 - // wp_enqueue_style('wp-adminify-responsive');
293 507 } else {
294 508 wp_enqueue_style('adminify-default-ui');
295 509 }
296 510
@@ -302,11 +516,17 @@
302 516
303 517
304 518 // Dark Mode Style
305 519 // wp_enqueue_style('adminify-dark-mode');
306 - wp_enqueue_script('adminify--dark-mode');
307 520
521 + // Only a user who is actually in dark mode gets the ~110 KB bundle up front.
522 + // 'system' is resolved in the browser and 'light' never needs it at all; both
523 + // go through the loader printed by header_scripts().
524 + if ('dark' === $this->color_mode()) {
525 + wp_enqueue_script('adminify--dark-mode');
526 + }
308 527
528 +
309 529 // Get local fonts data for frontend - download if not exists
310 530 $local_fonts = GoogleFontsLocal::get_instance();
311 531 $local_fonts_urls = [];
312 532
@@ -349,9 +569,9 @@
349 569 'admin_ajax' => admin_url('admin-ajax.php'),
350 570 'settings' => [
351 571 'adminify_ui' => !empty($this->options['admin_ui']) ? true : false,
352 572 ],
353 - 'admin_nonce' => wp_create_nonce('adminify_nonce'),
573 + 'admin_nonce' => wp_create_nonce('pxlbsadminify_frame_nonce'),
354 574 'is_pro' => (class_exists('\\PXLBSAdminify\\Pro\\Adminify_Pro') && !empty(\PXLBSAdminify\Pro\Adminify_Pro::is_premium())) ? true : false,
355 575 'local_fonts' => $local_fonts_data
356 576 ];
357 577
@@ -363,9 +583,14 @@
363 583 // Scripts Enqueue
364 584 wp_enqueue_script('adminify-admin');
365 585 wp_localize_script( 'adminify-admin', 'PXLBSADMINIFY_ADMIN', $localize_array_data );
366 586
367 - if (!wp_script_is('adminify-fa', 'enqueued') || !wp_script_is('adminify-fa5', 'enqueued')) {
587 + // Font Awesome, only on screens that actually paint an icon with it. The
588 + // old guard called wp_script_is() on what are styles, so it always passed
589 + // and every admin page paid for the font. wp_enqueue_style() is a no-op on
590 + // an already-enqueued handle, so no guard is needed against the framework
591 + // having enqueued these first.
592 + if ($this->needs_fontawesome($screen)) {
368 593 if (apply_filters('adminify_fa4', false)) {
369 594 wp_enqueue_style('adminify-fa', PXLBSADMINIFY_ASSETS . 'vendors/fontawesome/fa4/css/font-awesome.min.css', array(), '4.7.0', 'all');
370 595 } else {
371 596 wp_enqueue_style('adminify-fa5', PXLBSADMINIFY_ASSETS . 'vendors/fontawesome/fa5/css/all.min.css', array(), '5.15.4', 'all');
@@ -373,8 +598,30 @@
373 598 }
374 599 }
375 600 wp_enqueue_style('adminify-simple-line-icons');
376 601
602 + // Adminify UI HTTPS gate — only on the main settings screen where the switcher lives.
603 + if (isset($screen->id) && false !== strpos($screen->id, 'wp-adminify-settings')) {
604 + wp_enqueue_script('adminify-ui-ssl-check', PXLBSADMINIFY_ASSETS . 'admin/js/adminify-ui-ssl-check.js', array('jquery'), PXLBSADMINIFY_VER, true);
605 + wp_localize_script(
606 + 'adminify-ui-ssl-check',
607 + 'PXLBSADMINIFY_SSL',
608 + array(
609 + 'ajax_url' => admin_url('admin-ajax.php'),
610 + 'nonce' => wp_create_nonce('pxlbsadminify_frame_nonce'),
611 + 'field_id' => 'admin_ui',
612 + 'i18n' => array(
613 + 'label' => esc_html__('Adminify UI needs HTTPS:', 'adminify'),
614 + 'generic_error' => esc_html__('Could not verify HTTPS right now. Please try again.', 'adminify'),
615 + ),
616 + )
617 + );
618 +
619 + // Adminify UI live theme preset changer
620 + wp_enqueue_script('adminify-theme-presetter', PXLBSADMINIFY_ASSETS . 'admin/js/wp-adminify-theme-presetter' . Utils::assets_ext('.js'), ['jquery'], PXLBSADMINIFY_VER, true);
621 + wp_localize_script('adminify-theme-presetter', 'PXLBSADMINIFY_PRESET_THEMES', Utils::get_theme_presets());
622 + }
623 +
377 624 if ($screen->id === 'adminify_page_wp-adminify-addons-plugins' || $screen->id === 'adminify-pro_page_wp-adminify-addons-plugins') {
378 625 // JS Files .
379 626 wp_enqueue_script('adminify-addons', PXLBSADMINIFY_ASSETS . 'admin/js/wp-adminify-addons' . Utils::assets_ext('.js'), array('jquery'), PXLBSADMINIFY_VER, true);
380 627 wp_localize_script(
@@ -386,8 +633,45 @@
386 633 'plugin_key' => 'pxlbsadminify'
387 634 )
388 635 );
389 636 }
637 + }
638 +
639 + /**
640 + * AJAX: verify the site is HTTPS-ready before enabling the Adminify UI.
641 + *
642 + * Called from assets/admin/js/adminify-ui-ssl-check.js when the user flips
643 + * the "Adminify UI" switcher on. Returns success only when the dashboard
644 + * frame would actually load (see Utils::adminify_ui_https_status()).
645 + */
646 + public function pxlbsadminify_ssl_check()
647 + {
648 + $nonce = isset($_POST['nonce']) ? sanitize_text_field(wp_unslash($_POST['nonce'])) : '';
649 +
650 + if (!wp_verify_nonce($nonce, 'pxlbsadminify_frame_nonce')) {
651 + wp_send_json_error(array(
652 + 'https_ready' => false,
653 + 'message' => esc_html__('Security check failed. Please reload the page and try again.', 'adminify'),
654 + ));
655 + }
656 +
657 + if (!current_user_can('manage_options')) {
658 + wp_send_json_error(array(
659 + 'https_ready' => false,
660 + 'message' => esc_html__('You do not have permission to change this setting.', 'adminify'),
661 + ));
662 + }
663 +
664 + $status = Utils::adminify_ui_https_status();
665 +
666 + if (!empty($status['ready'])) {
667 + wp_send_json_success(array('https_ready' => true));
668 + }
669 +
670 + wp_send_json_error(array(
671 + 'https_ready' => false,
672 + 'message' => $status['message'],
673 + ));
390 674 }
391 675
392 676 // WP Adminify Options Page Style
393 677 public function pxlbsadminify_admin_script()