Skip to content
19 changes: 19 additions & 0 deletions src/wp-includes/connectors.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,25 @@ function _wp_connectors_init(): void {
_wp_connectors_register_default_ai_providers( $registry );
}

// Non-AI default connectors.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only this part is relevant the rest is Gutenberg ref update which is included for testing but will not be part of the commit.

$registry->register(
'akismet',
array(
'name' => __( 'Akismet Anti-spam' ),
'description' => __( 'Protect your site from spam.' ),
'type' => 'spam_filtering',
'plugin' => array(
'file' => 'akismet/akismet.php',
),
'authentication' => array(
'method' => 'api_key',
'credentials_url' => 'https://akismet.com/get/',
'setting_name' => 'wordpress_api_key',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have been akismet_api_key, or else wordpresscom_api_key/wpcom_api_key.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bluefuton, what can we do to align on the setting name and const name for Akismet?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gziolo wordpress_api_key has a long history! I believe it was conceived as a single API key for WordPress.com services over 20 years ago. These days it is only used for Akismet.

It seems sensible to migrate to a new option name like akismet_api_key while continuing to provide support for wordpress_api_key on existing installs. We'll start looking at that.

'constant_name' => 'WPCOM_API_KEY',
),
)
);

/**
* Fires when the connector registry is ready for plugins to register connectors.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ public function test_returns_expected_connector_keys(): void {
$this->assertArrayHasKey( 'google', $connectors );
$this->assertArrayHasKey( 'openai', $connectors );
$this->assertArrayHasKey( 'anthropic', $connectors );
$this->assertArrayHasKey( 'akismet', $connectors );
$this->assertArrayHasKey( 'mock-connectors-test', $connectors );
$this->assertCount( 4, $connectors );
$this->assertCount( 5, $connectors );
}

/**
Expand All @@ -56,7 +57,7 @@ public function test_each_connector_has_required_fields(): void {
$this->assertArrayHasKey( 'description', $connector_data, "Connector '{$connector_id}' is missing 'description'." );
$this->assertIsString( $connector_data['description'], "Connector '{$connector_id}' description should be a string." );
$this->assertArrayHasKey( 'type', $connector_data, "Connector '{$connector_id}' is missing 'type'." );
$this->assertContains( $connector_data['type'], array( 'ai_provider' ), "Connector '{$connector_id}' has unexpected type '{$connector_data['type']}'." );
$this->assertContains( $connector_data['type'], array( 'ai_provider', 'spam_filtering' ), "Connector '{$connector_id}' has unexpected type '{$connector_data['type']}'." );
$this->assertArrayHasKey( 'authentication', $connector_data, "Connector '{$connector_id}' is missing 'authentication'." );
$this->assertIsArray( $connector_data['authentication'], "Connector '{$connector_id}' authentication should be an array." );
$this->assertArrayHasKey( 'method', $connector_data['authentication'], "Connector '{$connector_id}' authentication is missing 'method'." );
Expand All @@ -79,11 +80,16 @@ public function test_api_key_connectors_have_setting_name_and_credentials_url():
++$api_key_count;

$this->assertArrayHasKey( 'setting_name', $connector_data['authentication'], "Connector '{$connector_id}' authentication is missing 'setting_name'." );
$this->assertSame(
'connectors_ai_' . str_replace( '-', '_', $connector_id ) . '_api_key',
$connector_data['authentication']['setting_name'] ?? null,
"Connector '{$connector_id}' setting_name does not match expected format."
);

// AI providers use the connectors_ai_{id}_api_key convention.
// Non-AI connectors may use custom setting names.
if ( 'ai_provider' === $connector_data['type'] ) {
$this->assertSame(
'connectors_ai_' . str_replace( '-', '_', $connector_id ) . '_api_key',
$connector_data['authentication']['setting_name'] ?? null,
"Connector '{$connector_id}' setting_name does not match expected format."
);
}
}

$this->assertGreaterThan( 0, $api_key_count, 'At least one connector should use api_key authentication.' );
Expand Down
1 change: 1 addition & 0 deletions tests/phpunit/tests/rest-api/rest-settings-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public function test_get_items() {
'default_ping_status',
'default_comment_status',
'site_icon', // Registered in wp-includes/blocks/site-logo.php
'wordpress_api_key', // Registered by Akismet connector.
'wp_collaboration_enabled',
);

Expand Down
7 changes: 7 additions & 0 deletions tests/qunit/fixtures/wp-api-generated.js
Original file line number Diff line number Diff line change
Expand Up @@ -11011,6 +11011,12 @@ mockedApiResponse.Schema = {
"PATCH"
],
"args": {
"wordpress_api_key": {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jorgefilipecosta, I was thinking about it. Akismet is using a custom setting name, which means they already control it and register themselves. In that case, I think it's fair to assume that WP core doesn't need to handle it. If it is needed for testing purposes, we can always mock it for individual tests.

Concluding, let's auto-register the setting name only when not set explicitly. AI is a bit awkward in that regard, so maybe we can add a special case there, too.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking, does the setting need to be registered before plugin installation for JS to function properly?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigate it further, and it looks like the setting gets registered only if the plugin doesn't do it earlier. It seems like a sound approach. In that case, it's only the fallback in WP core.

Unfortunately, I can't think of a simple way to prevent such registration when Akismet isn't installed. Well, what I said earlier still holds. However, it might not be trivial to achieve such a goal.

"title": "Akismet Anti-spam API Key",
"description": "API key for the Akismet Anti-spam connector.",
"type": "string",
"required": false
},
"title": {
"title": "Title",
"description": "Site title.",
Expand Down Expand Up @@ -14544,6 +14550,7 @@ mockedApiResponse.CommentModel = {
};

mockedApiResponse.settings = {
"wordpress_api_key": "",
"title": "Test Blog",
"description": "",
"url": "http://example.org",
Expand Down
Loading