Make WordPress Core


Ignore:
Timestamp:
03/30/2026 02:25:32 PM (6 months ago)
Author:
jorgefilipecosta
Message:

Connectors: Fix and generalize the API for custom connector types.

Validate setting_name, constant_name, and env_var_name in connector
registration — reject invalid values with _doing_it_wrong() instead of
silently falling back.
Change the auto-generated setting_name pattern from
connectors_ai_{$id}_api_key to connectors_{$type}_{$id}_api_key so it
works for any connector type. Built-in AI providers infer their names using
the existing connectors_ai_{$id}_api_key convention, preserving backward
compatibility.
Add constant_name and env_var_name as optional authentication fields,
allowing connectors to declare explicit PHP constant and environment
variable names for API key lookup. AI providers auto-generate these using
the {CONSTANT_CASE_ID}_API_KEY convention.
Refactor _wp_connectors_get_api_key_source() to accept explicit
env_var_name and constant_name parameters instead of deriving them from
the provider ID. Environment variable and constant checks are skipped when
not provided.
Generalize REST dispatch, settings registration, and script module data to
work with all connector types, not just ai_provider. Settings
registration skips already-registered settings. Non-AI connectors determine
isConnected based on key source.
Replace isInstalled with pluginFile in script module data output to fix
plugin entity ID resolution on the frontend.
Update PHPDoc to reflect current behavior — widen type from literal
'ai_provider' to non-empty-string, document new authentication fields,
and use Anthropic examples throughout.

Props gziolo, jorgefilipecosta.
Fixes #64957.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-connector-registry.php

    r62116 r62180  
    3232 *     description: non-empty-string,
    3333 *     logo_url?: non-empty-string,
    34  *     type: 'ai_provider',
     34 *     type: non-empty-string,
    3535 *     authentication: array{
    3636 *         method: 'api_key'|'none',
    3737 *         credentials_url?: non-empty-string,
    38  *         setting_name?: non-empty-string
     38 *         setting_name?: non-empty-string,
     39 *         constant_name?: non-empty-string,
     40 *         env_var_name?: non-empty-string
    3941 *     },
    4042 *     plugin?: array{
    … …  
    6769         *
    6870         * Validates the provided arguments and stores the connector in the registry.
    69          * For connectors with `api_key` authentication, a `setting_name` is automatically
    70          * generated using the pattern `connectors_ai_{$id}_api_key`, with hyphens in the ID
    71          * normalized to underscores (e.g., connector ID `openai` produces
    72          * `connectors_ai_openai_api_key`, and `azure-openai` produces
    73          * `connectors_ai_azure_openai_api_key`). This setting name is used for the Settings
    74          * API registration and REST API exposure.
     71         * For connectors with `api_key` authentication, a `setting_name` can be provided
     72         * explicitly. If omitted, one is automatically generated using the pattern
     73         * `connectors_{$type}_{$id}_api_key`, with hyphens in the type and ID normalized
     74         * to underscores (e.g., connector type `spam_filtering` with ID `akismet` produces
     75         * `connectors_spam_filtering_akismet_api_key`). This setting name is used for the
     76         * Settings API registration and REST API exposure.
    7577         *
    7678         * Registering a connector with an ID that is already registered will trigger a
    … …  
    9092         *     @type string $description    Optional. The connector's description. Default empty string.
    9193         *     @type string $logo_url       Optional. URL to the connector's logo image.
    92          *     @type string $type           Required. The connector type. Currently, only 'ai_provider' is supported.
     94         *     @type string $type           Required. The connector type, e.g. 'ai_provider'.
    9395         *     @type array  $authentication {
    9496         *         Required. Authentication configuration.
    … …  
    9698         *         @type string $method          Required. The authentication method: 'api_key' or 'none'.
    9799         *         @type string $credentials_url Optional. URL where users can obtain API credentials.
     100         *         @type string $setting_name    Optional. The setting name for the API key.
     101         *                                       When omitted, auto-generated as
     102         *                                       `connectors_{$type}_{$id}_api_key`.
     103         *                                       Must be a non-empty string when provided.
     104         *         @type string $constant_name   Optional. PHP constant name for the API key
     105         *                                       (e.g. 'ANTHROPIC_API_KEY'). Only checked when provided.
     106         *         @type string $env_var_name    Optional. Environment variable name for the API key
     107         *                                       (e.g. 'ANTHROPIC_API_KEY'). Only checked when provided.
    98108         *     }
    99109         *     @type array  $plugin         {
    … …  
    193203                                $connector['authentication']['credentials_url'] = $args['authentication']['credentials_url'];
    194204                        }
    195                         if ( ! empty( $args['authentication']['setting_name'] ) && is_string( $args['authentication']['setting_name'] ) ) {
     205                        if ( isset( $args['authentication']['setting_name'] ) ) {
     206                                if ( ! is_string( $args['authentication']['setting_name'] ) || '' === $args['authentication']['setting_name'] ) {
     207                                        _doing_it_wrong(
     208                                                __METHOD__,
     209                                                /* translators: %s: Connector ID. */
     210                                                sprintf( __( 'Connector "%s" authentication setting_name must be a non-empty string.' ), esc_html( $id ) ),
     211                                                '7.0.0'
     212                                        );
     213                                        return null;
     214                                }
    196215                                $connector['authentication']['setting_name'] = $args['authentication']['setting_name'];
    197216                        } else {
    198                                 $connector['authentication']['setting_name'] = 'connectors_ai_' . str_replace( '-', '_', $id ) . '_api_key';
     217                                $connector['authentication']['setting_name'] = str_replace( '-', '_', "connectors_{$connector['type']}_{$id}_api_key" );
     218                        }
     219                        if ( isset( $args['authentication']['constant_name'] ) ) {
     220                                if ( ! is_string( $args['authentication']['constant_name'] ) || '' === $args['authentication']['constant_name'] ) {
     221                                        _doing_it_wrong(
     222                                                __METHOD__,
     223                                                /* translators: %s: Connector ID. */
     224                                                sprintf( __( 'Connector "%s" authentication constant_name must be a non-empty string.' ), esc_html( $id ) ),
     225                                                '7.0.0'
     226                                        );
     227                                        return null;
     228                                }
     229                                $connector['authentication']['constant_name'] = $args['authentication']['constant_name'];
     230                        }
     231                        if ( isset( $args['authentication']['env_var_name'] ) ) {
     232                                if ( ! is_string( $args['authentication']['env_var_name'] ) || '' === $args['authentication']['env_var_name'] ) {
     233                                        _doing_it_wrong(
     234                                                __METHOD__,
     235                                                /* translators: %s: Connector ID. */
     236                                                sprintf( __( 'Connector "%s" authentication env_var_name must be a non-empty string.' ), esc_html( $id ) ),
     237                                                '7.0.0'
     238                                        );
     239                                        return null;
     240                                }
     241                                $connector['authentication']['env_var_name'] = $args['authentication']['env_var_name'];
    199242                        }
    200243                }
Note: See TracChangeset for help on using the changeset viewer.