parent_slug, __( 'Settings', 'albert-ai-butler' ), __( 'Settings', 'albert-ai-butler' ), 'manage_options', $this->page_slug, [ $this, 'render_settings_page' ] ); } /** * Render settings page. * * @return void * @since 1.0.0 */ public function render_settings_page(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'albert-ai-butler' ) ); } ?>

render_mcp_server_section(); ?>

$this->page_slug ], admin_url( 'admin.php' ) ) ); exit; } /** * Revoke all tokens for a user. * * @param int $user_id The user ID. * * @return void * @since 1.0.0 */ public static function revoke_user_tokens( int $user_id ): void { global $wpdb; $tables = Installer::get_table_names(); // Get all access token IDs for this user. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $token_ids = $wpdb->get_col( $wpdb->prepare( 'SELECT token_id FROM %i WHERE user_id = %d', $tables['access_tokens'], $user_id ) ); // Revoke access tokens. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->update( $tables['access_tokens'], [ 'revoked' => 1 ], [ 'user_id' => $user_id ], [ '%d' ], [ '%d' ] ); // Revoke associated refresh tokens. if ( ! empty( $token_ids ) ) { $placeholders = implode( ', ', array_fill( 0, count( $token_ids ), '%s' ) ); // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber $wpdb->query( $wpdb->prepare( "UPDATE %i SET revoked = 1 WHERE access_token_id IN ({$placeholders})", $tables['refresh_tokens'], ...$token_ids ) ); // phpcs:enable } } /** * Enqueue admin assets. * * @param string $hook Current admin page hook. * * @return void * @since 1.0.0 */ public function enqueue_assets( string $hook ): void { // Hook format for submenu is: {parent_slug}_page_{menu_slug}. if ( 'albert_page_' . $this->page_slug !== $hook ) { return; } wp_enqueue_style( 'albert-admin', ALBERT_PLUGIN_URL . 'assets/css/admin-settings.css', [], ALBERT_VERSION ); wp_enqueue_script( 'albert-admin', ALBERT_PLUGIN_URL . 'assets/js/admin-settings.js', [], ALBERT_VERSION, true ); wp_localize_script( 'albert-admin', 'albertAdmin', [ 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'albert_oauth_nonce' ), 'i18n' => [ 'copied' => __( 'Copied!', 'albert-ai-butler' ), 'copyFailed' => __( 'Copy failed', 'albert-ai-butler' ), ], ] ); } }