Service Categories > All Services > * All Staff Members > All Bookings > Settings * - Taxonomy page parent/submenu highlight fixed via filter hooks * - Quick Actions link updated (no calendar page) * - Calendar CSS/JS loaded on dashboard hook */ class AumReserva_Admin { private static ?AumReserva_Admin $instance = null; public static function instance(): AumReserva_Admin { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { add_action('admin_menu', [$this, 'register_menus']); add_action('admin_enqueue_scripts', [$this, 'enqueue_assets']); add_filter('plugin_action_links_' . AUMRESERVA_PLUGIN_BASENAME, [$this, 'plugin_action_links']); add_filter('parent_file', [$this, 'fix_taxonomy_parent_file']); add_filter('submenu_file', [$this, 'fix_taxonomy_submenu_file']); } // ------------------------------------------------------------------------- // Menus // ------------------------------------------------------------------------- public function register_menus(): void { // Pending bookings badge — shown on top menu and All Bookings submenu $pending_count = AumReserva_DB::count_bookings(['status' => 'pending']); $badge = $pending_count > 0 ? sprintf( ' %s', $pending_count, $pending_count > 99 ? '99+' : $pending_count ) : ''; add_menu_page( __('Reserva Booking', 'aumreserva'), __('Reserva', 'aumreserva') . $badge, 'manage_options', 'aumreserva-booking', [$this, 'render_dashboard'], 'dashicons-calendar-alt', 26 ); add_submenu_page( 'aumreserva-booking', __('Dashboard', 'aumreserva'), __('Dashboard', 'aumreserva'), 'manage_options', 'aumreserva-booking', [$this, 'render_dashboard'] ); add_submenu_page( 'aumreserva-booking', __('Service Categories', 'aumreserva'), __('Service Categories', 'aumreserva'), 'manage_options', 'edit-tags.php?taxonomy=aumreserva_service_cat&post_type=aumreserva_service' ); add_submenu_page( 'aumreserva-booking', AumReserva_CPT::location_label(true), AumReserva_CPT::location_label(true), 'manage_options', 'edit-tags.php?taxonomy=aumreserva_location&post_type=aumreserva_staff' ); add_submenu_page( 'aumreserva-booking', __('All Bookings', 'aumreserva'), __('All Bookings', 'aumreserva') . $badge, 'manage_options', 'aumreserva-bookings-list', [AumReserva_Bookings_List::instance(), 'render'] ); add_submenu_page( 'aumreserva-booking', __('Settings', 'aumreserva'), __('Settings', 'aumreserva'), 'manage_options', 'aumreserva-settings', [AumReserva_Settings::instance(), 'render'] ); // Staff-role: my bookings page (separate top-level, visible only to aumreserva_staff role) add_menu_page( __('My Bookings', 'aumreserva'), __('My Bookings', 'aumreserva'), 'aumreserva_view_own_bookings', 'aumreserva-my-bookings', [$this, 'render_staff_bookings'], 'dashicons-calendar-alt', 26 ); // Re-sort submenu after WordPress adds CPT auto-entries add_action('admin_menu', [$this, 'sort_submenu'], 999); } /** * Reorders the Reserva sub-menu using the global $submenu array. * Desired order: * Dashboard > Service Categories > All Services (CPT) > * All Staff Members (CPT) > All Bookings > Settings */ public function sort_submenu(): void { global $submenu; if (empty($submenu['aumreserva-booking'])) { return; } $order = [ 'aumreserva-booking', // Dashboard 'edit-tags.php?taxonomy=aumreserva_service_cat&post_type=aumreserva_service', // Service Categories 'edit.php?post_type=aumreserva_service', // All Services (CPT auto) 'post-new.php?post_type=aumreserva_service', // Add Service (CPT auto) 'edit.php?post_type=aumreserva_staff', // All Staff Members (CPT auto) 'post-new.php?post_type=aumreserva_staff', // Add Staff (CPT auto) 'edit-tags.php?taxonomy=aumreserva_location&post_type=aumreserva_staff', // Locations 'aumreserva-bookings-list', // All Bookings 'aumreserva-settings', // Settings ]; $indexed = []; $rest = []; foreach ($submenu['aumreserva-booking'] as $item) { $slug = $item[2]; $pos = array_search($slug, $order, true); if ($pos !== false) { $indexed[$pos] = $item; } else { $rest[] = $item; } } ksort($indexed); /* * Rewriting $submenu is the only way to order submenu entries: the position argument * of `add_submenu_page()` is not honoured consistently within one parent, and core * exposes no API for reordering submenus after registration. Only this plugin's own * parent key is reordered; nothing is added, removed, or read from another plugin's * key. * * The annotation below is load-bearing: with it removed, this line reports * GlobalVariablesOverride. A scan that reports it as unnecessary is a scan restricted * to the security and SQL sniffs, which do not include this one. */ $submenu['aumreserva-booking'] = array_values(array_merge($indexed, $rest)); // phpcs:ignore WordPress.WP.GlobalVariablesOverride } // ------------------------------------------------------------------------- // Taxonomy menu highlight fix // ------------------------------------------------------------------------- public function fix_taxonomy_parent_file(?string $parent_file): ?string { global $current_screen; if ( isset($current_screen->taxonomy) && in_array($current_screen->taxonomy, ['aumreserva_service_cat', 'aumreserva_location'], true) ) { return 'aumreserva-booking'; } return $parent_file; } public function fix_taxonomy_submenu_file(?string $submenu_file): ?string { global $current_screen; if (isset($current_screen->taxonomy) && $current_screen->taxonomy === 'aumreserva_service_cat') { return 'edit-tags.php?taxonomy=aumreserva_service_cat&post_type=aumreserva_service'; } if (isset($current_screen->taxonomy) && $current_screen->taxonomy === 'aumreserva_location') { return 'edit-tags.php?taxonomy=aumreserva_location&post_type=aumreserva_staff'; } return $submenu_file; } // ------------------------------------------------------------------------- // Dashboard (with inline calendar) // ------------------------------------------------------------------------- public function render_dashboard(): void { $total = AumReserva_DB::count_bookings(); $pending = AumReserva_DB::count_bookings(['status' => 'pending']); $confirmed = AumReserva_DB::count_bookings(['status' => 'confirmed']); $today = AumReserva_DB::count_bookings(['booking_date' => gmdate('Y-m-d')]); $recent = AumReserva_DB::get_bookings(['per_page' => 8, 'orderby' => 'created_at', 'order' => 'DESC']); ?>
' . esc_html__('No staff profile linked to your account.', 'aumreserva') . '
'; return; } $bookings = AumReserva_DB::get_bookings([ 'staff_id' => $staff_id, 'per_page' => 50, 'orderby' => 'booking_date', 'order' => 'ASC', 'date_from' => gmdate('Y-m-d'), ]); ?>|
customer_name); ?> customer_phone); ?> |
service_id)); ?> | booking_date))); ?> | start_time) . ' – ' . AumReserva_Helpers::format_time($b->end_time)); ?> | status)); ?> | customer_note); ?> |