PluginProbe
Code Engine – PHP Snippets, AI Functions & Automation for WordPress / trunk
Code Engine – PHP Snippets, AI Functions & Automation for WordPress vtrunk
0.5.6 0.5.5 0.5.4 0.5.3 0.5.2 0.5.1 0.5.0 0.4.9 0.4.8 0.4.7 0.4.6 trunk 0.0.1 0.0.2 0.2.8 0.2.9 0.3.0 0.3.1 0.3.2 0.3.3 0.3.4 0.3.5 0.3.6 0.3.7 0.3.8 All 32 releases
← All changes | common/admin.php +66 -19 0.4.6trunk View file →
@@ -160,9 +160,9 @@
160 160
161 161 // Promote AI Engine on the WordPress 7 Connectors page when AI Engine
162 162 // itself isn't installed. When AI Engine is active, its own banner
163 163 // takes over — so this path only runs on "bare" Meow Apps installs.
164 - add_action( 'admin_footer', [ $this, 'maybe_render_wpai_promo' ] );
164 + add_action( 'admin_enqueue_scripts', [ $this, 'maybe_render_wpai_promo' ] );
165 165
166 166 MeowKit_MWCODE_Admin::$loaded = true;
167 167 }
168 168
@@ -272,9 +272,11 @@
272 272 <button type="button" id="meowapps-license-submit" class="button button-primary">Validate & Register</button>
273 273 </div>
274 274 </div>
275 275 </div>
276 - <script>
276 + <?php
277 + ob_start();
278 + ?>
277 279 (function() {
278 280 var modal = document.getElementById('meowapps-network-license-modal');
279 281 var input = document.getElementById('meowapps-license-key-input');
280 282 var message = document.getElementById('meowapps-license-message');
@@ -384,10 +386,10 @@
384 386 submitBtn.textContent = 'Validate & Register';
385 387 });
386 388 });
387 389 })();
388 - </script>
389 390 <?php
391 + wp_print_inline_script_tag( ob_get_clean() );
390 392 }
391 393
392 394 public function request_verify_ssl() {
393 395 return get_option( 'force_sslverify', false );
@@ -405,9 +407,12 @@
405 407 return $file;
406 408 }
407 409
408 410 public function admin_notices_licensed_free() {
409 - if ( isset( $_POST[$this->prefix . '_reset_sub'] ) ) {
411 + // Verify the nonce before removing the license from a POST request (CSRF protection).
412 + if ( isset( $_POST[$this->prefix . '_reset_sub'] )
413 + && isset( $_POST[ $this->prefix . '_reset_sub_nonce' ] )
414 + && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[ $this->prefix . '_reset_sub_nonce' ] ) ), $this->prefix . '_reset_sub' ) ) {
410 415 delete_option( $this->prefix . '_pro_serial' );
411 416 delete_option( $this->prefix . '_license' );
412 417 return;
413 418 }
@@ -417,9 +422,9 @@
417 422 $this->nice_name_from_file( $this->mainfile )
418 423 );
419 424 $html .= '<p>
420 425 <form method="post" action="">
421 - <input type="hidden" name="' . $this->prefix . '_reset_sub" value="true">
426 + <input type="hidden" name="' . $this->prefix . '_reset_sub" value="true"><input type="hidden" name="' . $this->prefix . '_reset_sub_nonce" value="' . esc_attr( wp_create_nonce( $this->prefix . '_reset_sub' ) ) . '">
422 427 <input type="submit" name="submit" id="submit" class="button" value="'
423 428 . __( 'Remove the license', $this->domain ) . '">
424 429 </form>
425 430 </p>';
@@ -429,19 +434,23 @@
429 434
430 435 public function admin_menu_start() {
431 436 // Hide the admin if user doesn't like Meow much
432 437 if ( get_option( 'meowapps_hide_meowapps', false ) ) {
433 - register_setting( 'general', 'meowapps_hide_meowapps' );
438 + register_setting( 'general', 'meowapps_hide_meowapps', [ 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean' ] );
434 439 add_settings_field( 'meowapps_hide_ads', 'Meow Apps Menu', [ $this, 'meowapps_hide_dashboard_callback' ], 'general' );
435 440 return;
436 441 }
437 442
438 - // Create standard menu if it does not already exist
443 + // Create standard menu if it does not already exist.
444 + // The cat logo is injected as an <img> inside the menu title (rather than passed as
445 + // the $icon_url argument) so the original SVG fills are preserved — passing it via
446 + // $icon_url makes WordPress add the .svg class and the admin color scheme strips
447 + // the colors to a single fill.
439 448 global $submenu;
440 449 if ( !isset( $submenu[ 'meowapps-main-menu' ] ) ) {
441 450 add_menu_page(
442 451 'Meow Apps',
443 - '<img alt="Meow Apps" style="width: 21px; margin-left: -28px; position: absolute; margin-top: 2px;" src="' . MeowKit_MWCODE_Admin::$logo . '" />Meow Apps',
452 + '<img alt="Meow Apps" class="meowapps-menu-icon" src="' . MeowKit_MWCODE_Admin::$logo . '" />Meow Apps',
444 453 'manage_options',
445 454 'meowapps-main-menu',
446 455 [ $this, 'admin_meow_apps' ],
447 456 '',
@@ -456,15 +465,46 @@
456 465 [ $this, 'admin_meow_apps' ]
457 466 );
458 467 }
459 468
460 - // Add CSS to hide the default icon
461 - add_action( 'admin_head', function () {
462 - echo '<style>
463 - #toplevel_page_meowapps-main-menu .wp-menu-image {
464 - display: none;
465 - }
466 - </style>';
469 + // Position the cat icon so it sits in the standard icon column in both the
470 + // expanded and the collapsed (folded) sidebar.
471 + //
472 + // The image lives inside the .wp-menu-name title (where the original code
473 + // put it) so the <img> renders with its native SVG fills. When the sidebar
474 + // is collapsed, WP hides .wp-menu-name (and everything inside it), so a
475 + // small JS snippet below clones the same <img> into the .wp-menu-image
476 + // slot — which WP keeps visible in both states. We use a real <img>
477 + // (not a background-image) on purpose: at small sizes WP's admin renders
478 + // background-image SVGs noticeably lighter than the equivalent <img>,
479 + // and we want the colored cat in both states.
480 + //
481 + // The !important rules also override an older "display: none" style that
482 + // previous-generation Meow Apps common copies inject for .wp-menu-image;
483 + // if any of them load first, ours still wins.
484 + // Enqueue the menu-icon CSS/JS through the assets API instead of echoing inline tags.
485 + add_action( 'admin_enqueue_scripts', function () {
486 + $css = '
487 + #toplevel_page_meowapps-main-menu .meowapps-menu-icon { width: 20px; height: auto; position: absolute; margin-left: -28px; margin-top: 3px; }
488 + #toplevel_page_meowapps-main-menu .wp-menu-image { display: block !important; position: relative; }
489 + #toplevel_page_meowapps-main-menu .wp-menu-image::before { display: none !important; }
490 + #toplevel_page_meowapps-main-menu .wp-menu-image .meowapps-menu-icon-folded { display: none; position: absolute; top: 50%; left: 50%; transform: translate(-50%, calc(-50% - 3px)); width: 20px; height: auto; }
491 + body.folded #toplevel_page_meowapps-main-menu .wp-menu-image .meowapps-menu-icon-folded { display: block; }
492 + body.folded #toplevel_page_meowapps-main-menu .meowapps-menu-icon { display: none; }
493 + @media only screen and (max-width: 960px) {
494 + body.auto-fold #toplevel_page_meowapps-main-menu .wp-menu-image .meowapps-menu-icon-folded { display: block; }
495 + body.auto-fold #toplevel_page_meowapps-main-menu .meowapps-menu-icon { display: none; }
496 + }';
497 + wp_add_inline_style( 'admin-menu', $css );
498 +
499 + // Clone the in-title cat icon into the .wp-menu-image slot (CSS shows it only when folded).
500 + $js = 'document.addEventListener("DOMContentLoaded", function () {'
501 + . 'var li = document.getElementById("toplevel_page_meowapps-main-menu"); if ( !li ) { return; }'
502 + . 'var src = li.querySelector(".meowapps-menu-icon"); var slot = li.querySelector(".wp-menu-image");'
503 + . 'if ( !src || !slot || slot.querySelector(".meowapps-menu-icon-folded") ) { return; }'
504 + . 'var clone = src.cloneNode(); clone.className = "meowapps-menu-icon-folded"; clone.removeAttribute("style"); slot.appendChild(clone);'
505 + . '});';
506 + wp_add_inline_script( 'common', $js );
467 507 } );
468 508 }
469 509
470 510 public function meowapps_hide_dashboard_callback() {
@@ -564,10 +604,12 @@
564 604 'installUrl' => $install_url,
565 605 'wporgUrl' => $wporg_url,
566 606 'learnUrl' => $learn_url,
567 607 );
608 + wp_register_style( 'meowapps-common-inline', false );
609 + wp_enqueue_style( 'meowapps-common-inline' );
610 + ob_start();
568 611 ?>
569 - <style>
570 612 .meowapps-wpai-promo {
571 613 margin: 0 0 16px; padding: 14px 18px;
572 614 display: flex; align-items: flex-start; gap: 14px;
573 615 background: #f0f4ff; border: 1px solid #d6deff; border-radius: 4px;
@@ -610,10 +652,15 @@
610 652 background: transparent; color: #6b7280;
611 653 font-weight: 500; padding: 7px 10px;
612 654 }
613 655 .meowapps-wpai-promo-btn-dismiss:hover { color: #1e1e1e; background: rgba(0,0,0,0.04); }
614 - </style>
615 - <script>
656 + <?php
657 + wp_add_inline_style( 'meowapps-common-inline', ob_get_clean() );
658 +
659 + wp_register_script( 'meowapps-common-inline', false, array(), false, true );
660 + wp_enqueue_script( 'meowapps-common-inline' );
661 + ob_start();
662 + ?>
616 663 (function () {
617 664 var D = <?php echo wp_json_encode( $payload ); ?>;
618 665 try { if (localStorage.getItem('meowapps-wpai-promo-dismissed') === '1') return; } catch (e) {}
619 666
@@ -694,9 +741,9 @@
694 741 if (app && 'MutationObserver' in window) {
695 742 new MutationObserver(ensure).observe(app, { childList: true, subtree: true });
696 743 }
697 744 })();
698 - </script>
699 745 <?php
746 + wp_add_inline_script( 'meowapps-common-inline', ob_get_clean() );
700 747 }
701 748 }
702 749 }