Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move wpcom/v2/publicize/connections endpoint to publicize package #40607

Merged
Merged
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
8 changes: 5 additions & 3 deletions projects/packages/publicize/.phan/baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@
*/
return [
// # Issue statistics:
// PhanTypeMismatchArgument : 7 occurrences
// PhanPluginDuplicateConditionalNullCoalescing : 6 occurrences
// PhanTypeMismatchArgument : 6 occurrences
// PhanTypeMismatchArgumentNullable : 3 occurrences
// PhanDeprecatedFunction : 2 occurrences
// PhanPluginMixedKeyNoKey : 2 occurrences
// PhanPossiblyUndeclaredVariable : 2 occurrences
// PhanTypeMismatchReturnProbablyReal : 2 occurrences
// PhanTypeMissingReturn : 2 occurrences
// PhanImpossibleCondition : 1 occurrence
// PhanNoopNew : 1 occurrence
// PhanParamSignatureMismatch : 1 occurrence
// PhanPluginDuplicateExpressionAssignmentOperation : 1 occurrence
// PhanPluginMixedKeyNoKey : 1 occurrence
// PhanPluginSimplifyExpressionBool : 1 occurrence
// PhanSuspiciousMagicConstant : 1 occurrence
// PhanTypeMismatchArgumentNullableInternal : 1 occurrence
Expand All @@ -33,10 +34,11 @@
'src/class-connections-post-field.php' => ['PhanPluginDuplicateConditionalNullCoalescing'],
'src/class-keyring-helper.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanTypeMismatchDefault'],
'src/class-publicize-base.php' => ['PhanImpossibleCondition', 'PhanPluginDuplicateConditionalNullCoalescing', 'PhanPluginSimplifyExpressionBool', 'PhanSuspiciousMagicConstant', 'PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchReturn'],
'src/class-publicize-setup.php' => ['PhanTypeMismatchArgument'],
'src/class-publicize-setup.php' => ['PhanNoopNew', 'PhanTypeMismatchArgument'],
'src/class-publicize-ui.php' => ['PhanPluginDuplicateExpressionAssignmentOperation', 'PhanTypeMismatchReturnProbablyReal'],
'src/class-publicize.php' => ['PhanParamSignatureMismatch', 'PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgument', 'PhanTypeMissingReturn'],
'src/class-rest-controller.php' => ['PhanPluginDuplicateConditionalNullCoalescing', 'PhanTypeMismatchReturnProbablyReal'],
'src/rest-api/class-connections-controller.php' => ['PhanPluginMixedKeyNoKey'],
'src/social-image-generator/class-post-settings.php' => ['PhanPluginDuplicateConditionalNullCoalescing'],
'src/social-image-generator/class-rest-settings-controller.php' => ['PhanPluginMixedKeyNoKey'],
'src/social-image-generator/class-settings.php' => ['PhanPluginDuplicateConditionalNullCoalescing'],
Expand Down
1 change: 1 addition & 0 deletions projects/packages/publicize/.phan/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
__DIR__ . '/../../../plugins/jetpack/_inc/lib/admin-pages/class.jetpack-admin-page.php', // class Jetpack_Admin_Page
__DIR__ . '/../../../plugins/jetpack/modules/subscriptions.php', // class Jetpack_Subscriptions
__DIR__ . '/../../../plugins/jetpack/functions.global.php', // function jetpack_render_tos_blurb
__DIR__ . '/../../../plugins/jetpack/_inc/lib/core-api/load-wpcom-endpoints.php', // function wpcom_rest_api_v2_load_plugin
),
)
);
4 changes: 2 additions & 2 deletions projects/packages/publicize/actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
// If WordPress's plugin API is available already, use it. If not,
// drop data into `$wp_filter` for `WP_Hook::build_preinitialized_hooks()`.
if ( function_exists( 'add_action' ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm happier with this approach as I can see a number of the other packages doing it in the same way, but I wonder if we should restrict this to just WPCOM, similar to the Connection package

if ( function_exists( 'is_admin' ) && ! is_admin() && ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) ) {

It might again be something we do in a follow-up but this means we're circumventing the Config mechanisms. I'll add another comment in class-publicize-setup.php to explain what I mean

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, we can use that approach. We can do that in a follow up to unblock other tasks here.

add_action( 'plugins_loaded', array( Automattic\Jetpack\Publicize\Publicize_Assets::class, 'configure' ), 1 );
add_action( 'plugins_loaded', array( Automattic\Jetpack\Publicize\Publicize_Setup::class, 'pre_initialization' ), 1 );
} else {
global $wp_filter;
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$wp_filter['plugins_loaded'][1][] = array(
'accepted_args' => 0,
'function' => array( Automattic\Jetpack\Publicize\Publicize_Assets::class, 'configure' ),
'function' => array( Automattic\Jetpack\Publicize\Publicize_Setup::class, 'pre_initialization' ),
manzoorwanijk marked this conversation as resolved.
Show resolved Hide resolved
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Moved wpcom/v2/publicize/connections endpoint to publicize package
40 changes: 29 additions & 11 deletions projects/packages/publicize/src/class-publicize-base.php
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,8 @@ public function get_profile_link( $service_name, $connection ) {
return 'https://instagram.com/' . $cmeta['connection_data']['meta']['username'];
}

if ( 'threads' === $service_name && isset( $connection['external_name'] ) ) {
return 'https://www.threads.net/@' . $connection['external_name'];
if ( 'threads' === $service_name && isset( $cmeta['external_name'] ) ) {
return 'https://www.threads.net/@' . $cmeta['external_name'];
}

if ( 'mastodon' === $service_name && isset( $cmeta['external_name'] ) ) {
Expand Down Expand Up @@ -527,7 +527,7 @@ public function get_profile_link( $service_name, $connection ) {
}

$profile_url_query = wp_parse_url( $cmeta['connection_data']['meta']['profile_url'], PHP_URL_QUERY );
$profile_url_query_args = null;
$profile_url_query_args = array();
wp_parse_str( $profile_url_query, $profile_url_query_args );

$id = null;
Expand Down Expand Up @@ -589,17 +589,35 @@ public function get_display_name( $service_name, $connection ) {
* @return string
*/
public function get_username( $service_name, $connection ) {
$handle = $this->get_external_handle( $service_name, $connection );

return $handle ?? $this->get_display_name( $service_name, $connection );
}

/**
* Returns the external handle for the Connection.
*
* @param string $service_name 'facebook', 'linkedin', etc.
* @param object|array $connection The Connection object (WordPress.com) or array (Jetpack).
* @return string|null
*/
public function get_external_handle( $service_name, $connection ) {
$cmeta = $this->get_connection_meta( $connection );

if ( 'mastodon' === $service_name && isset( $cmeta['external_display'] ) ) {
return $cmeta['external_display'];
}
switch ( $service_name ) {
case 'mastodon':
return $cmeta['external_display'] ?? null;

if ( isset( $cmeta['connection_data']['meta']['username'] ) ) {
return $cmeta['connection_data']['meta']['username'];
}
case 'bluesky':
case 'threads':
return $cmeta['external_name'] ?? null;

return $this->get_display_name( $service_name, $connection );
case 'instagram-business':
return $cmeta['connection_data']['meta']['username'] ?? null;

default:
return null;
}
}

/**
Expand All @@ -608,7 +626,7 @@ public function get_username( $service_name, $connection ) {
* @param object|array $connection The Connection object (WordPress.com) or array (Jetpack).
* @return string
*/
private function get_profile_picture( $connection ) {
public function get_profile_picture( $connection ) {
$cmeta = $this->get_connection_meta( $connection );

if ( isset( $cmeta['profile_picture'] ) ) {
Expand Down
27 changes: 27 additions & 0 deletions projects/packages/publicize/src/class-publicize-setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace Automattic\Jetpack\Publicize;

use Automattic\Jetpack\Publicize\REST_API\Connections_Controller;
use Automattic\Jetpack\Status\Host;

/**
* The class to configure and initialize the publicize package.
*/
Expand All @@ -26,6 +29,30 @@ public static function configure() {
add_action( 'jetpack_feature_publicize_enabled', array( __CLASS__, 'on_jetpack_feature_publicize_enabled' ) );
}

/**
* Initialization of publicize logic that should always be loaded.
*/
public static function pre_initialization() {

$is_wpcom = ( new Host() )->is_wpcom_simple();

// Assets are to be loaded in all cases.
Publicize_Assets::configure();

$rest_controllers = array(
Connections_Controller::class,
);

// Load the REST controllers.
foreach ( $rest_controllers as $controller ) {
if ( $is_wpcom ) {
wpcom_rest_api_v2_load_plugin( $controller );
} else {
new $controller();
}
}
Comment on lines +37 to +53
Copy link
Contributor

Choose a reason for hiding this comment

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

This should really be part of on_jetpack_feature_publicize_enabled, which is where we're initialising the other REST API elements, as well as registering the site options, which we'll need if we're bringing those features to WPCOM.

We could move this in there and then call on_jetpack_feature_publicize_enabled, but that would register the Connections_Post_Field and REST_Controller on WPCOM, as well as other things that might conflict.

What do you think about calling pre_initialization in on_jetpack_feature_publicize_enabled and then only using the pattern in actions.php for WPCOM? If we did that, we might want to rename the pre_initialization method or something.

Copy link
Member Author

Choose a reason for hiding this comment

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

Let us improve that initialization in a follow up PR

Copy link
Member Author

Choose a reason for hiding this comment

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

I have created a task for it and added it to our backlog.

}

manzoorwanijk marked this conversation as resolved.
Show resolved Hide resolved
/**
* To configure the publicize package, when called via the Config package.
*/
Expand Down
85 changes: 85 additions & 0 deletions projects/packages/publicize/src/rest-api/class-base-controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php
/**
* Base Controller class.
*
* @package automattic/jetpack-publicize
*/

namespace Automattic\Jetpack\Publicize\REST_API;

use Automattic\Jetpack\Status\Host;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Request;
use WP_REST_Response;

/**
* Base controller for Publicize endpoints.
*/
abstract class Base_Controller extends WP_REST_Controller {

/**
* Constructor.
*/
public function __construct() {
$this->wpcom_is_wpcom_only_endpoint = true;
}

/**
* Check if we are on WPCOM.
*
* @return bool
*/
public static function is_wpcom() {
return ( new Host() )->is_wpcom_simple();
}

/**
* Filters out data based on ?_fields= request parameter
*
* @param array $item Item to prepare.
* @param WP_REST_Request $request Full details about the request.
*
* @return WP_REST_Response filtered item
*/
public function prepare_item_for_response( $item, $request ) {

$fields = $this->get_fields_for_response( $request );

$response_data = array();
foreach ( $item as $field => $value ) {
if ( rest_is_field_included( $field, $fields ) ) {
$response_data[ $field ] = $value;
}
}

return rest_ensure_response( $response_data );
}

/**
* Verify that user can access Publicize data
*
* @return true|WP_Error
*/
public function get_items_permission_check() {
global $publicize;

if ( ! $publicize ) {
return new WP_Error(
'publicize_not_available',
__( 'Sorry, Jetpack Social is not available on your site right now.', 'jetpack-publicize-pkg' ),
array( 'status' => rest_authorization_required_code() )
);
}

if ( $publicize->current_user_can_access_publicize_data() ) {
return true;
}

return new WP_Error(
'invalid_user_permission_publicize',
__( 'Sorry, you are not allowed to access Jetpack Social data on this site.', 'jetpack-publicize-pkg' ),
array( 'status' => rest_authorization_required_code() )
);
}
}
Loading
Loading