Skip to content

Commit 09f7588

Browse files
committed
Connectors: Remove redundant helper and improve PHPDoc
Remove `_wp_connectors_get_connector_settings()` and inline `ksort()` into `_wp_connectors_get_connector_script_module_data()`. Expand `@return` and `@phpstan-return` array shapes for `wp_get_connector()` and `wp_get_connectors()`. Make `logo_url` and `credentials_url` truly optional. Rename test class to `wpGetConnectors`. Developed in #11227. Follow-up to [61943]. Props gziolo, westonruter. Fixes #64791. git-svn-id: https://develop.svn.wordpress.org/trunk@61983 602fd350-edb4-49c9-b593-d223f7449a82
1 parent cc19ca7 commit 09f7588

File tree

3 files changed

+117
-89
lines changed

3 files changed

+117
-89
lines changed

src/wp-includes/class-wp-connector-registry.php

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@
1616
* @access private
1717
*
1818
* @phpstan-type Connector array{
19-
* name: string,
20-
* description: string,
21-
* logo_url?: string|null,
22-
* type: string,
19+
* name: non-empty-string,
20+
* description: non-empty-string,
21+
* logo_url?: non-empty-string,
22+
* type: 'ai_provider',
2323
* authentication: array{
24-
* method: string,
25-
* credentials_url?: string|null,
26-
* setting_name?: string
24+
* method: 'api_key'|'none',
25+
* credentials_url?: non-empty-string,
26+
* setting_name?: non-empty-string
2727
* },
2828
* plugin?: array{
29-
* slug: string
29+
* slug: non-empty-string
3030
* }
3131
* }
3232
*/
@@ -62,15 +62,15 @@ final class WP_Connector_Registry {
6262
*
6363
* @type string $name Required. The connector's display name.
6464
* @type string $description Optional. The connector's description. Default empty string.
65-
* @type string|null $logo_url Optional. URL to the connector's logo image. Default null.
65+
* @type string $logo_url Optional. URL to the connector's logo image.
6666
* @type string $type Required. The connector type. Currently, only 'ai_provider' is supported.
6767
* @type array $authentication {
6868
* Required. Authentication configuration.
6969
*
70-
* @type string $method Required. The authentication method: 'api_key' or 'none'.
71-
* @type string|null $credentials_url Optional. URL where users can obtain API credentials.
70+
* @type string $method Required. The authentication method: 'api_key' or 'none'.
71+
* @type string $credentials_url Optional. URL where users can obtain API credentials.
7272
* }
73-
* @type array $plugin {
73+
* @type array $plugin {
7474
* Optional. Plugin data for install/activate UI.
7575
*
7676
* @type string $slug The WordPress.org plugin slug.
@@ -158,8 +158,10 @@ public function register( string $id, array $args ): ?array {
158158
}
159159

160160
if ( 'api_key' === $args['authentication']['method'] ) {
161-
$connector['authentication']['credentials_url'] = $args['authentication']['credentials_url'] ?? null;
162-
$connector['authentication']['setting_name'] = "connectors_ai_{$id}_api_key";
161+
if ( ! empty( $args['authentication']['credentials_url'] ) && is_string( $args['authentication']['credentials_url'] ) ) {
162+
$connector['authentication']['credentials_url'] = $args['authentication']['credentials_url'];
163+
}
164+
$connector['authentication']['setting_name'] = "connectors_ai_{$id}_api_key";
163165
}
164166

165167
if ( ! empty( $args['plugin'] ) && is_array( $args['plugin'] ) ) {
@@ -206,7 +208,8 @@ public function unregister( string $id ): ?array {
206208
*
207209
* @see wp_get_connectors()
208210
*
209-
* @return array<string, array> The array of registered connectors keyed by connector ID.
211+
* @return array Connector settings keyed by connector ID.
212+
*
210213
* @phpstan-return array<string, Connector>
211214
*/
212215
public function get_all_registered(): array {

src/wp-includes/connectors.php

Lines changed: 81 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,41 @@ function wp_is_connector_registered( string $id ): bool {
3737
* @see WP_Connector_Registry::get_registered()
3838
*
3939
* @param string $id The connector identifier.
40-
* @return array|null The registered connector data, or null if not registered.
40+
* @return array|null {
41+
* Connector data, or null if not registered.
42+
*
43+
* @type string $name The connector's display name.
44+
* @type string $description The connector's description.
45+
* @type string $logo_url Optional. URL to the connector's logo image.
46+
* @type string $type The connector type. Currently, only 'ai_provider' is supported.
47+
* @type array $authentication {
48+
* Authentication configuration. When method is 'api_key', includes
49+
* credentials_url and setting_name. When 'none', only method is present.
50+
*
51+
* @type string $method The authentication method: 'api_key' or 'none'.
52+
* @type string $credentials_url Optional. URL where users can obtain API credentials.
53+
* @type string $setting_name Optional. The setting name for the API key.
54+
* }
55+
* @type array $plugin {
56+
* Optional. Plugin data for install/activate UI.
57+
*
58+
* @type string $slug The WordPress.org plugin slug.
59+
* }
60+
* }
61+
* @phpstan-return ?array{
62+
* name: non-empty-string,
63+
* description: non-empty-string,
64+
* logo_url?: non-empty-string,
65+
* type: 'ai_provider',
66+
* authentication: array{
67+
* method: 'api_key'|'none',
68+
* credentials_url?: non-empty-string,
69+
* setting_name?: non-empty-string
70+
* },
71+
* plugin?: array{
72+
* slug: non-empty-string
73+
* }
74+
* }
4175
*/
4276
function wp_get_connector( string $id ): ?array {
4377
$registry = WP_Connector_Registry::get_instance();
@@ -55,7 +89,45 @@ function wp_get_connector( string $id ): ?array {
5589
*
5690
* @see WP_Connector_Registry::get_all_registered()
5791
*
58-
* @return array[] An array of registered connectors keyed by connector ID.
92+
* @return array {
93+
* Connector settings keyed by connector ID.
94+
*
95+
* @type array ...$0 {
96+
* Data for a single connector.
97+
*
98+
* @type string $name The connector's display name.
99+
* @type string $description The connector's description.
100+
* @type string $logo_url Optional. URL to the connector's logo image.
101+
* @type string $type The connector type. Currently, only 'ai_provider' is supported.
102+
* @type array $authentication {
103+
* Authentication configuration. When method is 'api_key', includes
104+
* credentials_url and setting_name. When 'none', only method is present.
105+
*
106+
* @type string $method The authentication method: 'api_key' or 'none'.
107+
* @type string $credentials_url Optional. URL where users can obtain API credentials.
108+
* @type string $setting_name Optional. The setting name for the API key.
109+
* }
110+
* @type array $plugin {
111+
* Optional. Plugin data for install/activate UI.
112+
*
113+
* @type string $slug The WordPress.org plugin slug.
114+
* }
115+
* }
116+
* }
117+
* @phpstan-return array<string, array{
118+
* name: non-empty-string,
119+
* description: non-empty-string,
120+
* logo_url?: non-empty-string,
121+
* type: 'ai_provider',
122+
* authentication: array{
123+
* method: 'api_key'|'none',
124+
* credentials_url?: non-empty-string,
125+
* setting_name?: non-empty-string
126+
* },
127+
* plugin?: array{
128+
* slug: non-empty-string
129+
* }
130+
* }>
59131
*/
60132
function wp_get_connectors(): array {
61133
$registry = WP_Connector_Registry::get_instance();
@@ -324,41 +396,6 @@ function _wp_connectors_get_real_api_key( string $option_name, callable $mask_ca
324396
return (string) $value;
325397
}
326398

327-
/**
328-
* Gets the registered connector settings.
329-
*
330-
* @since 7.0.0
331-
* @access private
332-
*
333-
* @return array {
334-
* Connector settings keyed by connector ID.
335-
*
336-
* @type array ...$0 {
337-
* Data for a single connector.
338-
*
339-
* @type string $name The connector's display name.
340-
* @type string $description The connector's description.
341-
* @type string $type The connector type. Currently, only 'ai_provider' is supported.
342-
* @type array $plugin Optional. Plugin data for install/activate UI.
343-
* @type string $slug The WordPress.org plugin slug.
344-
* }
345-
* @type array $authentication {
346-
* Authentication configuration. When method is 'api_key', includes
347-
* credentials_url and setting_name. When 'none', only method is present.
348-
*
349-
* @type string $method The authentication method: 'api_key' or 'none'.
350-
* @type string|null $credentials_url Optional. URL where users can obtain API credentials.
351-
* @type string $setting_name Optional. The setting name for the API key.
352-
* }
353-
* }
354-
* }
355-
*/
356-
function _wp_connectors_get_connector_settings(): array {
357-
$connectors = wp_get_connectors();
358-
ksort( $connectors );
359-
return $connectors;
360-
}
361-
362399
/**
363400
* Validates connector API keys in the REST response when explicitly requested.
364401
*
@@ -396,7 +433,7 @@ function _wp_connectors_validate_keys_in_rest( WP_REST_Response $response, WP_RE
396433
return $response;
397434
}
398435

399-
foreach ( _wp_connectors_get_connector_settings() as $connector_id => $connector_data ) {
436+
foreach ( wp_get_connectors() as $connector_id => $connector_data ) {
400437
$auth = $connector_data['authentication'];
401438
if ( 'ai_provider' !== $connector_data['type'] || 'api_key' !== $auth['method'] || empty( $auth['setting_name'] ) ) {
402439
continue;
@@ -431,7 +468,7 @@ function _wp_connectors_validate_keys_in_rest( WP_REST_Response $response, WP_RE
431468
function _wp_register_default_connector_settings(): void {
432469
$ai_registry = AiClient::defaultRegistry();
433470

434-
foreach ( _wp_connectors_get_connector_settings() as $connector_id => $connector_data ) {
471+
foreach ( wp_get_connectors() as $connector_id => $connector_data ) {
435472
$auth = $connector_data['authentication'];
436473
if ( 'ai_provider' !== $connector_data['type'] || 'api_key' !== $auth['method'] || empty( $auth['setting_name'] ) ) {
437474
continue;
@@ -485,7 +522,7 @@ function _wp_register_default_connector_settings(): void {
485522
function _wp_connectors_pass_default_keys_to_ai_client(): void {
486523
try {
487524
$ai_registry = AiClient::defaultRegistry();
488-
foreach ( _wp_connectors_get_connector_settings() as $connector_id => $connector_data ) {
525+
foreach ( wp_get_connectors() as $connector_id => $connector_data ) {
489526
if ( 'ai_provider' !== $connector_data['type'] ) {
490527
continue;
491528
}
@@ -521,12 +558,12 @@ function _wp_connectors_pass_default_keys_to_ai_client(): void {
521558
* @since 7.0.0
522559
* @access private
523560
*
524-
* @param array $data Existing script module data.
525-
* @return array Script module data with connectors added.
561+
* @param array<string, mixed> $data Existing script module data.
562+
* @return array<string, mixed> Script module data with connectors added.
526563
*/
527564
function _wp_connectors_get_connector_script_module_data( array $data ): array {
528565
$connectors = array();
529-
foreach ( _wp_connectors_get_connector_settings() as $connector_id => $connector_data ) {
566+
foreach ( wp_get_connectors() as $connector_id => $connector_data ) {
530567
$auth = $connector_data['authentication'];
531568
$auth_out = array( 'method' => $auth['method'] );
532569

@@ -548,6 +585,7 @@ function _wp_connectors_get_connector_script_module_data( array $data ): array {
548585

549586
$connectors[ $connector_id ] = $connector_out;
550587
}
588+
ksort( $connectors );
551589
$data['connectors'] = $connectors;
552590
return $data;
553591
}

tests/phpunit/tests/connectors/wpConnectorsGetConnectorSettings.php

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,36 @@
33
require_once dirname( __DIR__, 2 ) . '/includes/wp-ai-client-mock-provider-trait.php';
44

55
/**
6-
* Tests for _wp_connectors_get_connector_settings().
6+
* Tests for wp_get_connectors().
77
*
88
* @group connectors
9-
* @covers ::_wp_connectors_get_connector_settings
9+
* @covers ::wp_get_connectors
1010
*/
11-
class Tests_Connectors_WpConnectorsGetConnectorSettings extends WP_UnitTestCase {
11+
class Tests_Connectors_WpGetConnectors extends WP_UnitTestCase {
1212

1313
use WP_AI_Client_Mock_Provider_Trait;
1414

1515
/**
1616
* Registers the mock provider once before any tests in this class run.
1717
*/
18-
public static function set_up_before_class() {
18+
public static function set_up_before_class(): void {
1919
parent::set_up_before_class();
2020
self::register_mock_connectors_provider();
2121
}
2222

2323
/**
2424
* Unregisters the mock provider setting added by `init`.
2525
*/
26-
public static function tear_down_after_class() {
26+
public static function tear_down_after_class(): void {
2727
self::unregister_mock_connector_setting();
2828
parent::tear_down_after_class();
2929
}
3030

3131
/**
3232
* @ticket 64730
3333
*/
34-
public function test_returns_expected_connector_keys() {
35-
$connectors = _wp_connectors_get_connector_settings();
34+
public function test_returns_expected_connector_keys(): void {
35+
$connectors = wp_get_connectors();
3636

3737
$this->assertArrayHasKey( 'google', $connectors );
3838
$this->assertArrayHasKey( 'openai', $connectors );
@@ -44,8 +44,8 @@ public function test_returns_expected_connector_keys() {
4444
/**
4545
* @ticket 64730
4646
*/
47-
public function test_each_connector_has_required_fields() {
48-
$connectors = _wp_connectors_get_connector_settings();
47+
public function test_each_connector_has_required_fields(): void {
48+
$connectors = wp_get_connectors();
4949

5050
$this->assertNotEmpty( $connectors, 'Connector settings should not be empty.' );
5151

@@ -67,8 +67,8 @@ public function test_each_connector_has_required_fields() {
6767
/**
6868
* @ticket 64730
6969
*/
70-
public function test_api_key_connectors_have_setting_name_and_credentials_url() {
71-
$connectors = _wp_connectors_get_connector_settings();
70+
public function test_api_key_connectors_have_setting_name_and_credentials_url(): void {
71+
$connectors = wp_get_connectors();
7272
$api_key_count = 0;
7373

7474
foreach ( $connectors as $connector_id => $connector_data ) {
@@ -81,10 +81,9 @@ public function test_api_key_connectors_have_setting_name_and_credentials_url()
8181
$this->assertArrayHasKey( 'setting_name', $connector_data['authentication'], "Connector '{$connector_id}' authentication is missing 'setting_name'." );
8282
$this->assertSame(
8383
"connectors_ai_{$connector_id}_api_key",
84-
$connector_data['authentication']['setting_name'],
84+
$connector_data['authentication']['setting_name'] ?? null,
8585
"Connector '{$connector_id}' setting_name does not match expected format."
8686
);
87-
$this->assertArrayHasKey( 'credentials_url', $connector_data['authentication'], "Connector '{$connector_id}' authentication is missing 'credentials_url'." );
8887
}
8988

9089
$this->assertGreaterThan( 0, $api_key_count, 'At least one connector should use api_key authentication.' );
@@ -93,8 +92,8 @@ public function test_api_key_connectors_have_setting_name_and_credentials_url()
9392
/**
9493
* @ticket 64730
9594
*/
96-
public function test_featured_provider_names_match_expected() {
97-
$connectors = _wp_connectors_get_connector_settings();
95+
public function test_featured_provider_names_match_expected(): void {
96+
$connectors = wp_get_connectors();
9897

9998
$this->assertSame( 'Google', $connectors['google']['name'] );
10099
$this->assertSame( 'OpenAI', $connectors['openai']['name'] );
@@ -104,27 +103,15 @@ public function test_featured_provider_names_match_expected() {
104103
/**
105104
* @ticket 64730
106105
*/
107-
public function test_includes_registered_provider_from_registry() {
108-
$connectors = _wp_connectors_get_connector_settings();
106+
public function test_includes_registered_provider_from_registry(): void {
107+
$connectors = wp_get_connectors();
109108
$mock = $connectors['mock_connectors_test'];
110109

111110
$this->assertSame( 'Mock Connectors Test', $mock['name'] );
112111
$this->assertSame( '', $mock['description'] );
113112
$this->assertSame( 'ai_provider', $mock['type'] );
114113
$this->assertSame( 'api_key', $mock['authentication']['method'] );
115-
$this->assertNull( $mock['authentication']['credentials_url'] );
116-
$this->assertSame( 'connectors_ai_mock_connectors_test_api_key', $mock['authentication']['setting_name'] );
117-
}
118-
119-
/**
120-
* @ticket 64730
121-
*/
122-
public function test_connectors_are_sorted_alphabetically() {
123-
$connectors = _wp_connectors_get_connector_settings();
124-
$keys = array_keys( $connectors );
125-
$sorted = $keys;
126-
sort( $sorted );
127-
128-
$this->assertSame( $sorted, $keys, 'Connectors should be sorted alphabetically by ID.' );
114+
$this->assertNull( $mock['authentication']['credentials_url'] ?? null );
115+
$this->assertSame( 'connectors_ai_mock_connectors_test_api_key', $mock['authentication']['setting_name'] ?? null );
129116
}
130117
}

0 commit comments

Comments
 (0)