'; /** * Admin pages: slug suffix => [menu label, page id passed to the SPA]. * * @return array */ private function pages(): array { return array( '' => array( __( 'Dashboard', 'agentyllo' ), 'dashboard' ), '-kb' => array( __( 'Knowledge Base', 'agentyllo' ), 'kb' ), '-conversations' => array( __( 'Conversations', 'agentyllo' ), 'conversations' ), '-agents' => array( __( 'Agents', 'agentyllo' ), 'agents' ), '-models' => array( __( 'AI Models', 'agentyllo' ), 'models' ), '-stats' => array( __( 'Statistics', 'agentyllo' ), 'stats' ), '-privacy' => array( __( 'Privacy & Legal', 'agentyllo' ), 'privacy' ), '-addons' => array( __( 'Addons', 'agentyllo' ), 'addons' ), '-settings' => array( __( 'Settings', 'agentyllo' ), 'settings' ), '-help' => array( __( 'Help', 'agentyllo' ), 'help' ), ); } /** * Register menu + submenus. Hooked on admin_menu. */ public function register(): void { if ( ! Caps::can( 'agyl_manage' ) ) { return; } /** * Filter the real capability required for the Agentyllo admin menu. * * @param string $capability Default 'manage_options'. * @param string $permission Agentyllo permission id being mapped. */ $menu_cap = (string) apply_filters( 'agyl_capability_map', 'manage_options', 'agyl_manage' ); add_menu_page( __( 'Agentyllo', 'agentyllo' ), __( 'Agentyllo', 'agentyllo' ), $menu_cap, self::SLUG, array( $this, 'render' ), 'data:image/svg+xml;base64,' . base64_encode( self::ICON_SVG ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode 58 ); foreach ( $this->pages() as $suffix => [ $label ] ) { add_submenu_page( self::SLUG, $label . ' — Agentyllo', $label, $menu_cap, self::SLUG . $suffix, array( $this, 'render' ) ); } } /** * SPA mount point. The React app reads data-page to route. */ public function render(): void { $page = 'dashboard'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- routing only, no state change. $slug = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( (string) $_GET['page'] ) ) : self::SLUG; foreach ( $this->pages() as $suffix => [ , $page_id ] ) { if ( self::SLUG . $suffix === $slug ) { $page = $page_id; break; } } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only welcome flag. $welcome = isset( $_GET['welcome'] ) ? '1' : '0'; printf( '
', esc_attr( $page ), esc_attr( $welcome ) ); } /** * Whether the given admin page hook belongs to Agentyllo. * * @param string $hook Hook suffix from admin_enqueue_scripts. */ public static function is_agentyllo_screen( string $hook ): bool { return str_contains( $hook, 'agentyllo' ); } }