From 2f322d7f02224adc301ced66c2f66e39a8b236a5 Mon Sep 17 00:00:00 2001 From: Paul Bunkham Date: Thu, 12 Dec 2024 23:41:19 +0000 Subject: [PATCH] Publicize: Use get_all_connections_for_user in wpcom/v2 endpoints Expanding on #40589 this attempts to refactor the wpcom/v2 endpoints and bring the get_all_connections_for_user method to publicize-base. It means we start relying on the XMLRPC calls entirely, which could be a performance problem with testing the connections. There's probably some more refactoring we could do to proxy the endpoints and use those within Publicize, by overriding some of the methods, like get_publicize_conns_test_results --- .../publicize/src/class-publicize-base.php | 75 ++++++++++++++++++- .../src/class-publicize-script-data.php | 2 +- .../publicize/src/class-publicize.php | 61 +-------------- .../publicize-connection-test-results.php | 36 +-------- .../wpcom-endpoints/publicize-connections.php | 36 ++++----- 5 files changed, 90 insertions(+), 120 deletions(-) diff --git a/projects/packages/publicize/src/class-publicize-base.php b/projects/packages/publicize/src/class-publicize-base.php index 899ebceb218fa..af3da5f9cdc66 100644 --- a/projects/packages/publicize/src/class-publicize-base.php +++ b/projects/packages/publicize/src/class-publicize-base.php @@ -402,7 +402,80 @@ abstract public function get_connections( $service_name, $_blog_id = false, $_us * * @param array $args Arguments to run operations such as force refresh and connection test results. */ - abstract public function get_all_connections_for_user( $args = array() ); + public function get_all_connections_for_user( $args = array() ) { + + $items = array(); + + foreach ( (array) $this->get_services( 'connected' ) as $service_name => $connections ) { + foreach ( $connections as $connection ) { + $connection_meta = $this->get_connection_meta( $connection ); + $connection_data = $connection_meta['connection_data']; + $user_id = (int) $connection_data['user_id']; + + $items[] = array( + 'id' => (string) $this->get_connection_unique_id( $connection ), + 'connection_id' => (string) $this->get_connection_id( $connection ), + 'service_name' => $service_name, + 'display_name' => $this->get_display_name( $service_name, $connection ), + 'username' => $this->get_username( $service_name, $connection ), + 'profile_display_name' => ! empty( $connection_meta['profile_display_name'] ) ? $connection_meta['profile_display_name'] : '', + 'profile_picture' => ! empty( $connection_meta['profile_picture'] ) ? $connection_meta['profile_picture'] : '', + // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual -- We expect an integer, but do loose comparison below in case some other type is stored. + 'global' => 0 == $connection_data['user_id'], + 'external_id' => $connection_meta['external_id'] ?? '', + 'external_handle' => $this->get_external_handle( $service_name, $connection ), + 'profile_link' => $this->get_profile_link( $service_name, $connection ), + 'service_label' => $this->get_service_label( $service_name ), + 'shared' => ! $user_id, + 'status' => 'ok', + 'user_id' => $user_id, + ); + } + } + + if ( $this->use_admin_ui_v1() && isset( $args['test_connections'] ) && $args['test_connections'] && count( $items ) > 0 ) { + $items = $this->add_connection_test_results( $items ); + } + + return $items; + } + + /** + * To add the connection test results to the connections. + * + * @param array $connections The Jetpack Social connections. + + * @return array + */ + public function add_connection_test_results( $connections ) { + $test_results = $this->get_publicize_conns_test_results(); + $test_results_by_unique_id = array(); + foreach ( $test_results as $test_result ) { + $test_results_by_unique_id[ $test_result['connectionID'] ] = $test_result; + } + + $mapping = array( + 'test_success' => 'connectionTestPassed', + 'test_message' => 'connectionTestMessage', + 'error_code' => 'connectionTestErrorCode', + 'can_refresh' => 'userCanRefresh', + 'refresh_text' => 'refreshText', + 'refresh_url' => 'refreshURL', + 'connection_id' => 'connectionID', + ); + + foreach ( $connections as &$item ) { + $test_result = $test_results_by_unique_id[ $item['connection_id'] ]; + + foreach ( $mapping as $field => $test_result_field ) { + $item[ $field ] = $test_result[ $test_result_field ]; + } + // Compare to `true` because the API returns a 'must_reauth' for LinkedIn. + $item['status'] = true === $test_result['connectionTestPassed'] ? 'ok' : 'broken'; + } + + return $connections; + } /** * Get a single Connection of a Service diff --git a/projects/packages/publicize/src/class-publicize-script-data.php b/projects/packages/publicize/src/class-publicize-script-data.php index ef9ee9f3a3639..5e3d39f86f23f 100644 --- a/projects/packages/publicize/src/class-publicize-script-data.php +++ b/projects/packages/publicize/src/class-publicize-script-data.php @@ -263,7 +263,7 @@ public static function get_api_paths() { } return array( - 'refreshConnections' => '/jetpack/v4/publicize/connections?test_connections=1', + 'refreshConnections' => '/wpcom/v2/publicize/connection-test-results', 'resharePost' => '/jetpack/v4/publicize/{postId}', ); } diff --git a/projects/packages/publicize/src/class-publicize.php b/projects/packages/publicize/src/class-publicize.php index fb75b8cc71277..bef5690606c9d 100644 --- a/projects/packages/publicize/src/class-publicize.php +++ b/projects/packages/publicize/src/class-publicize.php @@ -7,10 +7,8 @@ namespace Automattic\Jetpack\Publicize; -use Automattic\Jetpack\Connection\Client; use Automattic\Jetpack\Connection\Tokens; use Jetpack_IXR_Client; -use Jetpack_Options; use WP_Error; use WP_Post; @@ -237,65 +235,8 @@ public function get_all_connections_for_user( $args = array() ) { || ( isset( $args['test_connections'] ) && $args['test_connections'] ) ) { $this->clear_connections_transient(); } - $connections = $this->get_all_connections(); - $connections_to_return = array(); - if ( ! empty( $connections ) ) { - foreach ( (array) $connections as $service_name => $connections_for_service ) { - foreach ( $connections_for_service as $connection ) { - $user_id = (int) $connection['connection_data']['user_id']; - - $connection_meta = $this->get_connection_meta( $connection ); - // phpcs:ignore WordPress.PHP.YodaConditions.NotYoda - if ( $user_id === 0 || $this->user_id() === $user_id ) { - $connections_to_return[] = array( - 'connection_id' => (string) $this->get_connection_id( $connection ), - 'display_name' => $this->get_display_name( $service_name, $connection ), - 'external_handle' => $this->get_external_handle( $service_name, $connection ), - 'external_id' => $connection_meta['external_id'] ?? '', - 'profile_link' => $this->get_profile_link( $service_name, $connection ), - 'profile_picture' => $this->get_profile_picture( $connection ), - 'service_label' => $this->get_service_label( $service_name ), - 'service_name' => $service_name, - 'shared' => ! $user_id, - 'status' => 'ok', - 'user_id' => $user_id, - ); - } - } - } - } - - if ( self::use_admin_ui_v1() && isset( $args['test_connections'] ) && $args['test_connections'] && count( $connections_to_return ) > 0 ) { - $connections_to_return = $this->add_connection_test_results( $connections_to_return ); - } - - return $connections_to_return; - } - - /** - * To add the connection test results to the connections. - * - * @param array $connections The Jetpack Social connections. - - * @return array - */ - public function add_connection_test_results( $connections ) { - $path = sprintf( '/sites/%d/publicize/connection-test-results', absint( Jetpack_Options::get_option( 'id' ) ) ); - $response = Client::wpcom_json_api_request_as_user( $path, '2', array(), null, 'wpcom' ); - $connection_results = json_decode( wp_remote_retrieve_body( $response ), true ); - $connection_results_map = array(); - - foreach ( $connection_results as $connection_result ) { - $connection_results_map[ $connection_result['connection_id'] ] = $connection_result['test_success'] ? 'ok' : 'broken'; - } - foreach ( $connections as $key => $connection ) { - if ( isset( $connection_results_map[ $connection['connection_id'] ] ) ) { - $connections[ $key ]['status'] = $connection_results_map[ $connection['connection_id'] ]; - } - } - - return $connections; + return parent::get_all_connections_for_user( $args ); } /** diff --git a/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connection-test-results.php b/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connection-test-results.php index 5468da5a6e328..90b160439fcea 100644 --- a/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connection-test-results.php +++ b/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connection-test-results.php @@ -104,41 +104,7 @@ public function get_item_schema() { public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable global $publicize; - $items = $this->get_connections(); - - $test_results = $publicize->get_publicize_conns_test_results(); - $test_results_by_unique_id = array(); - foreach ( $test_results as $test_result ) { - $test_results_by_unique_id[ $test_result['connectionID'] ] = $test_result; - } - - $mapping = array( - 'test_success' => 'connectionTestPassed', - 'test_message' => 'connectionTestMessage', - 'error_code' => 'connectionTestErrorCode', - 'can_refresh' => 'userCanRefresh', - 'refresh_text' => 'refreshText', - 'refresh_url' => 'refreshURL', - 'connection_id' => 'connectionID', - ); - - foreach ( $items as &$item ) { - $test_result = $test_results_by_unique_id[ $item['connection_id'] ]; - - foreach ( $mapping as $field => $test_result_field ) { - $item[ $field ] = $test_result[ $test_result_field ]; - } - // Compare to `true` because the API returns a 'must_reauth' for LinkedIn. - $item['status'] = true === $test_result['connectionTestPassed'] ? 'ok' : 'broken'; - } - - if ( - isset( $item['id'] ) - && 'linkedin' === $item['id'] - && 'must_reauth' === $test_result['connectionTestPassed'] - ) { - $item['test_success'] = 'must_reauth'; - } + $items = $publicize->get_all_connections_for_user( array( 'test_connections' => true ) ); $response = rest_ensure_response( $items ); diff --git a/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connections.php b/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connections.php index 67fa5b25ced9e..e6e347e34e77f 100644 --- a/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connections.php +++ b/projects/plugins/jetpack/_inc/lib/core-api/wpcom-endpoints/publicize-connections.php @@ -127,29 +127,19 @@ public function get_item_schema() { protected function get_connections() { global $publicize; - $items = array(); - - foreach ( (array) $publicize->get_services( 'connected' ) as $service_name => $connections ) { - foreach ( $connections as $connection ) { - $connection_meta = $publicize->get_connection_meta( $connection ); - $connection_data = $connection_meta['connection_data']; - - $items[] = array( - 'id' => (string) $publicize->get_connection_unique_id( $connection ), - 'connection_id' => (string) $publicize->get_connection_id( $connection ), - 'service_name' => $service_name, - 'display_name' => $publicize->get_display_name( $service_name, $connection ), - 'username' => $publicize->get_username( $service_name, $connection ), - 'profile_display_name' => ! empty( $connection_meta['profile_display_name'] ) ? $connection_meta['profile_display_name'] : '', - 'profile_picture' => ! empty( $connection_meta['profile_picture'] ) ? $connection_meta['profile_picture'] : '', - // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual -- We expect an integer, but do loose comparison below in case some other type is stored. - 'global' => 0 == $connection_data['user_id'], - 'external_id' => $connection_meta['external_id'] ?? '', - ); - } - } - - return $items; + $items = $publicize->get_all_connections_for_user(); + $keys = array( + 'id', + 'connection_id', + 'service_name', + 'display_name', + 'username', + 'profile_display_name', + 'profile_picture', + 'global', + 'external_id', + ); + return array_intersect_key( $items, array_flip( $keys ) ); } /**