plugin_name = $plugin_name; $this->version = $version; add_action('admin_menu', [$this,'menu']); add_action('admin_enqueue_scripts', [$this,'assets']); add_action('admin_head', [$this,'adjust_menu_icon_markup']); // AJAX add_action('wp_ajax_ability_run_scan', [$this,'ajax_run_scan']); add_action('wp_ajax_ability_save_settings', [$this,'ajax_save_settings']); } public function menu(){ // Use sidebar icon (20x20px) for admin menu, main icon for other uses $icon = defined('ABILITY_ICON_SIDEBAR_URL') ? ABILITY_ICON_SIDEBAR_URL : ABILITY_ICON_URL; $main_page = add_menu_page( __('ABILITY Dashboard','ability'), __('ABILITY','ability'), 'manage_options', 'ability-dashboard', [$this,'page_dashboard'], $icon, 2 ); add_submenu_page( 'ability-dashboard', __('Dashboard','ability'), __('Dashboard','ability'), 'manage_options', 'ability-dashboard', [$this,'page_dashboard'] ); add_submenu_page( 'ability-dashboard', __('Scan Results','ability'), __('Scan Results','ability'), 'manage_options', 'ability-scans', [$this,'page_scans'] ); add_submenu_page( 'ability-dashboard', __('Settings','ability'), __('Settings','ability'), 'manage_options', 'ability-settings', [$this,'page_settings'] ); add_submenu_page( 'ability-dashboard', __('Learning & Resources','ability'), __('Learning & Resources','ability'), 'manage_options', 'ability-learning', [$this,'page_learning'] ); add_submenu_page( 'ability-dashboard', __('Community & Support','ability'), __('Community & Support','ability'), 'manage_options', 'ability-community', [$this,'page_community'] ); } public function assets($hook){ if (strpos($hook,'ability-')===false) return; // Add body class for background styling add_filter('admin_body_class', function($classes) { return $classes . ' ability-admin-page'; }); // Add critical CSS early to prevent FOUC (Flash of Unstyled Content) for logo add_action('admin_head', function() { ?> version . '.' . (file_exists(ABILITY_PATH . 'assets/css/admin.css') ? filemtime(ABILITY_PATH . 'assets/css/admin.css') : time()); wp_enqueue_style('ability-admin', ABILITY_URL.'assets/css/admin.css', [], $css_version); wp_enqueue_script('ability-admin', ABILITY_URL.'assets/js/admin.js', ['jquery'], $this->version, true); wp_localize_script('ability-admin', 'ABILITY_ADMIN', [ 'ajaxurl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('ability_admin'), 'tier' => function_exists('ability_get_tier') ? ability_get_tier() : 'basic', 'isPro' => function_exists('ability_is_pro') ? ability_is_pro() : false, 'adminUrl' => admin_url(), ]); } /** * Adjust top-level admin menu icon HTML to match requested markup. */ public function adjust_menu_icon_markup() { ?>

= 10): ?>

0

0

0

0%

  • ✓
  • ✓
  • ✓
  • ✓
prefix . $table_name; $status = 'pending'; $total_issues = (int) $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM `{$table}` WHERE status = %s", $status )); } ?>

0): ?>


prefix . $table_name; $pages_scanned = (int) $wpdb->get_var("SELECT COUNT(DISTINCT file_path) FROM `{$table}`"); $errors_count = (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM `{$table}` WHERE severity = %s", 'error')); $warnings_count = (int) $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM `{$table}` WHERE severity = %s", 'warning')); // Calculate compliance score (100 - errors*2 - warnings*1, minimum 0) $compliance_score = max(0, 100 - ($errors_count * 2) - ($warnings_count * 1)); // Get last scan date $last_scan = $wpdb->get_var("SELECT MAX(created_at) FROM `{$table}`"); if ($last_scan) { $last_scan_date = date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($last_scan)); } } ?>

' . esc_html($last_scan_date) . ''); ?>

  • ' . esc_html($last_scan_date) . ''); ?>

0 && preg_match('/^[a-zA-Z0-9_]+$/', $table_name)): ?> prefix . $table_name; $status = 'pending'; $limit = 50; $issues = $wpdb->get_results( $wpdb->prepare("SELECT * FROM `{$table}` WHERE status = %s ORDER BY created_at DESC LIMIT %d", $status, $limit), ARRAY_A ); ?>


__('Insufficient permissions', 'ability')]); } if (class_exists('ABILITY\Scanner')) { $scanner = new \ABILITY\Scanner(); $results = $scanner->scan(ABSPATH); wp_send_json_success($results); } wp_send_json_error(['message' => __('Scanner not available', 'ability')]); } public function ajax_save_settings() { check_ajax_referer('ability_admin', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error(['message' => __('Insufficient permissions', 'ability')]); } $settings = isset($_POST['settings']) ? (array) $_POST['settings'] : []; if (class_exists('ABILITY\Config')) { \ABILITY\Config::update_settings($settings); wp_send_json_success(['message' => __('Settings saved', 'ability')]); } wp_send_json_error(['message' => __('Failed to save settings', 'ability')]); } }