Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://develop.svn.wordpress.org/trunk"
},
"gutenberg": {
"sha": "0d133bf7e7437d65d68a06551f3d613a7d8e4361",
"sha": "6230e952d12131bd2d0aecff2f2a912ff2b976c1",
"ghcrRepo": "WordPress/gutenberg/gutenberg-wp-develop-build"
},
"engines": {
Expand Down
8 changes: 4 additions & 4 deletions src/wp-includes/assets/script-loader-packages.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
'import' => 'dynamic'
)
),
'version' => 'd72ed53f961f90f21ed4'
'version' => '67d1a681ec0100a25d78'
),
'block-serialization-default-parser.js' => array(
'dependencies' => array(
Expand Down Expand Up @@ -428,7 +428,7 @@
'import' => 'static'
)
),
'version' => 'a688ac97344ffdfcca99'
'version' => 'd36eb0c37b644e4cd4c8'
),
'edit-widgets.js' => array(
'dependencies' => array(
Expand Down Expand Up @@ -519,7 +519,7 @@
'import' => 'static'
)
),
'version' => '49ff59c135229f1cc371'
'version' => '63782008412a6163c9f0'
),
'element.js' => array(
'dependencies' => array(
Expand Down Expand Up @@ -817,7 +817,7 @@
'wp-hooks',
'wp-private-apis'
),
'version' => '89ec294039260fd01952'
'version' => '4dd69327b706ab4df8f3'
),
'theme.js' => array(
'dependencies' => array(
Expand Down
2 changes: 1 addition & 1 deletion src/wp-includes/assets/script-modules-packages.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
'import' => 'static'
)
),
'version' => '105defe2f1526f8a43e8'
'version' => '42d3f09bba14cce3054d'
),
'connectors/index.js' => array(
'dependencies' => array(
Expand Down
43 changes: 35 additions & 8 deletions src/wp-includes/build/routes/connectors-home/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -703,9 +703,9 @@ var import_i18n = __toESM(require_i18n());
import { speak } from "@wordpress/a11y";
function useConnectorPlugin({
pluginSlug,
pluginFile: pluginFileFromServer,
settingName,
connectorName,
isInstalled,
isActivated,
keySource = "none",
initialIsConnected = false
Expand Down Expand Up @@ -740,7 +740,7 @@ function useConnectorPlugin({
canInstallPlugins: canCreate
};
}
const pluginId = `${pluginSlug}/plugin`;
const pluginId = pluginFileFromServer ?? `${pluginSlug}/plugin`;
const plugin = store2.getEntityRecord(
"root",
"plugin",
Expand Down Expand Up @@ -769,7 +769,7 @@ function useConnectorPlugin({
let status = "not-installed";
if (isActivated) {
status = "active";
} else if (isInstalled) {
} else if (pluginFileFromServer) {
status = "inactive";
}
return {
Expand All @@ -779,7 +779,7 @@ function useConnectorPlugin({
canInstallPlugins: canCreate
};
},
[pluginSlug, settingName, isInstalled, isActivated]
[pluginSlug, pluginFileFromServer, settingName, isActivated]
);
const pluginStatus = pluginStatusOverride ?? derivedPluginStatus;
const canActivatePlugins = canManagePlugins;
Expand Down Expand Up @@ -831,7 +831,10 @@ function useConnectorPlugin({
await saveEntityRecord(
"root",
"plugin",
{ plugin: `${pluginSlug}/plugin`, status: "active" },
{
plugin: pluginFileFromServer ?? `${pluginSlug}/plugin`,
status: "active"
},
{ throwOnError: true }
);
setPluginStatusOverride("active");
Expand Down Expand Up @@ -1030,6 +1033,27 @@ var DefaultConnectorLogo = () => /* @__PURE__ */ React.createElement(
}
)
);
var AkismetLogo = () => /* @__PURE__ */ React.createElement(
"svg",
{
width: "40",
height: "40",
viewBox: "0 0 44 44",
fill: "none",
xmlns: "http://www.w3.org/2000/svg",
"aria-hidden": "true"
},
/* @__PURE__ */ React.createElement("rect", { width: "44", height: "44", fill: "#357B49", rx: "6" }),
/* @__PURE__ */ React.createElement(
"path",
{
fill: "#fff",
fillRule: "evenodd",
d: "m29.746 28.31-6.392-16.797c-.152-.397-.305-.672-.789-.675-.673 0-1.408.611-1.746 1.316l-7.378 16.154c-.072.16-.143.311-.214.454-.5.995-1.045 1.546-2.357 1.626a.399.399 0 0 0-.16.033l-.01.004a.399.399 0 0 0-.23.392v.01c0 .054.01.106.03.155l.004.01a.416.416 0 0 0 .394.252h6.212a.417.417 0 0 0 .307-.12.416.416 0 0 0 .124-.305.398.398 0 0 0-.105-.302.399.399 0 0 0-.294-.127c-.757 0-2.197-.062-2.197-1.164.02-.318.103-.63.245-.916l1.399-3.152c.52-1.163 1.654-1.163 2.572-1.163h5.843c.023 0 .044 0 .062.003.13.014.16.081.214.242l1.534 4.07a2.857 2.857 0 0 1 .216 1.04c0 .054-.003.104-.01.153-.09.726-.831.887-1.49.887a.4.4 0 0 0-.294.127l-.007.008-.007.008a.401.401 0 0 0-.092.286v.01c0 .054.01.106.03.155l.005.01a.42.42 0 0 0 .395.252h7.011a.413.413 0 0 0 .279-.13.412.412 0 0 0 .11-.297.387.387 0 0 0-.09-.294.388.388 0 0 0-.277-.135c-1.448-.122-2.295-.643-2.847-2.08Zm-11.985-5.844 2.847-6.304c.361-.728.659-1.486.889-2.265 0-.06.03-.092.06-.092s.061.032.061.091c.02.122.045.247.073.374.197.888.584 1.878.914 2.723l.176.453 1.684 4.529a.927.927 0 0 1 .092.4.473.473 0 0 1-.009.094c-.041.202-.228.272-.602.272h-6.063c-.122 0-.184-.03-.184-.092a.36.36 0 0 1 .062-.183Zm17.107-.721c0 .786-.446 1.231-1.25 1.231-.806 0-1.125-.409-1.125-1.034 0-.786.465-1.231 1.25-1.231.785 0 1.125.427 1.125 1.034ZM9.629 23.002c.803 0 1.25-.447 1.25-1.231 0-.607-.343-1.036-1.128-1.036-.785 0-1.25.447-1.25 1.231 0 .625.325 1.036 1.128 1.036Z",
clipRule: "evenodd"
}
)
);
var GeminiLogo = () => /* @__PURE__ */ React.createElement(
"svg",
{
Expand Down Expand Up @@ -1123,7 +1147,8 @@ function getConnectorData() {
var CONNECTOR_LOGOS = {
google: GeminiLogo,
openai: OpenAILogo,
anthropic: ClaudeLogo
anthropic: ClaudeLogo,
akismet: AkismetLogo
};
function getConnectorLogo(connectorId, logoUrl) {
if (logoUrl) {
Expand Down Expand Up @@ -1185,9 +1210,9 @@ function ApiKeyConnector({
removeApiKey
} = useConnectorPlugin({
pluginSlug,
pluginFile: plugin?.pluginFile,
settingName,
connectorName: name,
isInstalled: plugin?.isInstalled,
isActivated: plugin?.isActivated,
keySource: auth?.keySource,
initialIsConnected: auth?.isConnected
Expand Down Expand Up @@ -1264,11 +1289,12 @@ function registerDefaultConnectors() {
const args = {
name: data.name,
description: data.description,
type: data.type,
logo: getConnectorLogo(connectorId, data.logoUrl),
authentication,
plugin: data.plugin
};
if (data.type === "ai_provider" && authentication.method === "api_key") {
if (authentication.method === "api_key") {
args.render = ApiKeyConnector;
}
registerConnector(connectorName, args);
Expand Down Expand Up @@ -1562,6 +1588,7 @@ function ConnectorsPage() {
slug: connector.slug,
name: connector.name,
description: connector.description,
type: connector.type,
logo: connector.logo,
authentication: connector.authentication,
plugin: connector.plugin
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-private-apis', 'wp-theme', 'wp-url'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/connectors', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => 'e598f70e4e13735c7300');
<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives', 'wp-private-apis', 'wp-theme', 'wp-url'), 'module_dependencies' => array(array('id' => '@wordpress/a11y', 'import' => 'static'), array('id' => '@wordpress/connectors', 'import' => 'static'), array('id' => '@wordpress/route', 'import' => 'static')), 'version' => 'ea1ef07414b58402d8ff');

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions src/wp-includes/connectors.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,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(
'slug' => 'akismet',
),
'authentication' => array(
'method' => 'api_key',
'credentials_url' => 'https://akismet.com/get/',
'setting_name' => 'wordpress_api_key',
'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": {
"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