define_constants(); add_action('plugins_loaded', [$this, 'init_plugin']); } /** * Define the required plugin constants. * * @return void */ public function define_constants() { define('ADMO_VERSION', self::VERSION); define('ADMO_FILE', __FILE__); define('ADMO_PATH', __DIR__); define('ADMO_URL', plugins_url('', ADMO_FILE)); define('ADMO_ASSETS', ADMO_URL . '/assets'); } /** * Initialize the plugin. * * @return void */ public function init_plugin() { add_action('admin_menu', [$this, 'add_admin_menu']); add_action('admin_enqueue_scripts', [$this, 'enqueue_scripts']); add_action('wp_ajax_admo_save_order', [$this, 'save_order']); add_filter('custom_menu_order', '__return_true'); add_filter('menu_order', [$this, 'apply_custom_order']); // Hook the AJAX handler. add_action('wp_ajax_admo_save_title', [$this, 'save_title']); add_action('admin_menu', [$this, 'apply_custom_titles'], 100); } /** * Add a top-level menu for the plugin. * * @return void */ public function add_admin_menu() { add_menu_page( __('Admin Menu Optimizer', 'admin-menu-optimizer'), __('Menu Optimizer', 'admin-menu-optimizer'), 'manage_options', 'admin-menu-optimizer', [$this, 'settings_page'], 'dashicons-menu', ); } /** * Display the settings page. */ public function settings_page() { global $menu; ?>
admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('admo_nonce'), ]); } } /** * Save menu order via AJAX. * * @return void */ public function save_order() { // Verify nonce first check_ajax_referer('admo_nonce', 'nonce'); // Sanitize the entire $_POST['order'] input $order = isset($_POST['order']) ? array_map('sanitize_text_field', wp_unslash($_POST['order'])) : null; // Additional validation if (!is_array($order) || empty($order)) { wp_send_json_error(esc_html__('Invalid order data.', 'admin-menu-optimizer')); exit; } // Validate that all items are strings or numeric $validated_order = array_filter($order, function($item) { return is_string($item) || is_numeric($item); }); // Ensure the filtered array matches the original if (count($validated_order) !== count($order)) { wp_send_json_error(esc_html__('Invalid order items.', 'admin-menu-optimizer')); exit; } // Save the sanitized order update_option('admo_menu_order', $validated_order); wp_send_json_success(esc_html__('Menu order saved.', 'admin-menu-optimizer')); exit; } /** * Save menu item title via AJAX. * * @return void */ public function save_title() { // Verify nonce first check_ajax_referer('admo_nonce', 'nonce'); // Sanitize and validate inputs in one step $slug = isset($_POST['slug']) ? sanitize_text_field(wp_unslash($_POST['slug'])) : null; $new_title = isset($_POST['new_title']) ? sanitize_text_field(wp_unslash($_POST['new_title'])) : null; // Comprehensive input validation if (empty($slug) || empty($new_title)) { wp_send_json_error(esc_html__('Invalid data. Slug and title are required.', 'admin-menu-optimizer')); exit; } // Additional validation for slug and title if (strlen($slug) > 100 || strlen($new_title) > 100) { wp_send_json_error(esc_html__('Slug or title is too long.', 'admin-menu-optimizer')); exit; } // Retrieve and update stored titles $stored_titles = get_option('admo_menu_titles', []); $stored_titles[$slug] = $new_title; // Update option with sanitized data update_option('admo_menu_titles', $stored_titles); wp_send_json_success(esc_html__('Menu title updated.', 'admin-menu-optimizer')); exit; } /** * Apply custom menu titles. * * @return void */ public function apply_custom_titles() { global $menu; $stored_titles = get_option('admo_menu_titles', []); foreach ($menu as &$item) { $slug = $item[2]; if (!empty($stored_titles[$slug])) { $item[0] = $stored_titles[$slug]; } } } /** * Apply custom menu order. * * @param array $menu_order The current menu order. * * @return array */ public function apply_custom_order($menu_order) { $stored_order = get_option('admo_menu_order', []); if (!empty($stored_order)) { return $stored_order; } return $menu_order; } /** * Run the plugin. * * @return Admo_Admin_Menu_Optimizer */ public static function init() { if (is_null(self::$instance)) { self::$instance = new self(); } return self::$instance; } } /** * Initialize the plugin. * * @return Admo_Admin_Menu_Optimizer */ function admo_admin_menu_optimizer() { return Admo_Admin_Menu_Optimizer::init(); } // Kick-off the plugin. admo_admin_menu_optimizer();