$page, 'albert_connect' => '1', ], admin_url( 'admin.php' ) ); } /** * Add the page; administrators keep using Connections. * * For an administrator the page is registered without a menu item and * forwards to Connections, so a Connect link still lands somewhere * useful. Removing the menu item instead would make WordPress refuse * the page outright. * * @return void * @since 1.5.0 */ public function add_menu_page(): void { if ( current_user_can( 'manage_options' ) ) { $hook = add_submenu_page( '', __( 'Connect', 'albert-ai-butler' ), '', 'manage_options', self::PAGE_SLUG, '__return_null' ); if ( $hook !== false ) { add_action( 'load-' . $hook, [ $this, 'forward_administrator' ] ); } return; } add_submenu_page( Menu::PARENT_SLUG, __( 'Connect', 'albert-ai-butler' ), __( 'Connect', 'albert-ai-butler' ), ConnectCapability::CAPABILITY, self::PAGE_SLUG, [ $this, 'render_page' ] ); } /** * Send an administrator to Connections, keeping a request to open the dialog. * * @return void * @since 1.5.0 */ public function forward_administrator(): void { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Only forwards a flag that opens a dialog. $open = isset( $_GET['albert_connect'] ); wp_safe_redirect( $open ? self::setup_url( wp_get_current_user() ) : admin_url( 'admin.php?page=albert-connections' ) ); exit; } /** * Load the dialog on this page. * * @param string $hook The current admin page hook. * * @return void * @since 1.5.0 */ public function enqueue_assets( string $hook ): void { if ( ! str_ends_with( $hook, '_page_' . self::PAGE_SLUG ) ) { return; } wp_enqueue_style( 'albert-connections', ALBERT_PLUGIN_URL . 'assets/css/admin-connections.css', [ Assets::PRIMITIVES_HANDLE ], Assets::version( 'assets/css/admin-connections.css' ) ); wp_enqueue_script( 'albert-admin', ALBERT_PLUGIN_URL . 'assets/js/admin-settings.js', [ 'albert-admin-utils' ], Assets::version( 'assets/js/admin-settings.js' ), true ); wp_localize_script( 'albert-admin', 'albertAdmin', [ 'i18n' => [ 'copied' => __( 'Copied!', 'albert-ai-butler' ), 'copyFailed' => __( 'Copy failed', 'albert-ai-butler' ), ], ] ); ConnectDialog::enqueue(); } /** * Render the page. * * @return void * @since 1.5.0 */ public function render_page(): void { if ( ! current_user_can( ConnectCapability::CAPABILITY ) ) { wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'albert-ai-butler' ) ); } $endpoint = McpServer::get_endpoint_url(); $user_id = get_current_user_id(); $guides = ClientSetupGuides::for_location( $endpoint, SiteLocation::current() ); ?>