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

Feat/distribute authors #17

Merged
merged 22 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
80e2e36
feat: distribute authors on push
leogermani Nov 28, 2023
6f87c64
feat: handle posts distributed via pull
leogermani Nov 28, 2023
f5790b6
Merge branch 'master' into feat/distribute-authors
leogermani Dec 1, 2023
37aa016
feat: update code with user update watcher
leogermani Dec 1, 2023
5e70c99
Merge branch 'master' into feat/distribute-authors
leogermani Dec 6, 2023
2a69117
Merge branch 'master' into feat/distribute-authors
leogermani Dec 7, 2023
fe05bb1
feat: use utils class
leogermani Dec 7, 2023
42f7fac
Merge branch 'master' into feat/distribute-authors
leogermani Dec 13, 2023
bf84a87
Update includes/distributor-customizations/class-author-distribution.php
leogermani Dec 13, 2023
c477fb1
Update includes/distributor-customizations/class-author-ingestion.php
leogermani Dec 13, 2023
b413ee1
Update includes/distributor-customizations/class-author-ingestion.php
leogermani Dec 13, 2023
7e8e827
Update includes/distributor-customizations/class-author-ingestion.php
leogermani Dec 13, 2023
df7f3d8
fix: add users only once
leogermani Dec 13, 2023
92c6b32
docs: fix docs explanation
leogermani Dec 13, 2023
2e26d03
feat: add debug messages in case of errors
leogermani Dec 13, 2023
b529b36
fix: pass users props on user creation
leogermani Dec 13, 2023
6636656
fix: improve param name
leogermani Dec 13, 2023
2a908c4
feat: add better debugging
leogermani Dec 13, 2023
6bce598
docs: minor adjustment in a doc block
leogermani Dec 14, 2023
b25a1ec
Update includes/distributor-customizations/class-author-distribution.php
leogermani Dec 14, 2023
68f5fab
fix: create users as authors
leogermani Dec 14, 2023
3160cd1
fix: do not trigger auto updates when ingesting
leogermani Dec 14, 2023
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: 2 additions & 0 deletions includes/class-distributor-customizations.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Distributor_Customizations {
public static function init() {
require_once NEWSPACK_NETWORK_PLUGIN_DIR . '/includes/distributor-customizations/global.php';
Distributor_Customizations\Canonical_Url::init();
Distributor_Customizations\Author_Distribution::init();
Distributor_Customizations\Author_Ingestion::init();
}


Expand Down
13 changes: 6 additions & 7 deletions includes/class-user-update-watcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
class User_Update_Watcher {

/**
* Flag to indicate if the processing of the user updated event is in progress.
* If true, this class won't fire any events to avoid an infinite loop in author updates.
* Flag to indicate if the watcher should watch.
* If false, this class won't fire any events to avoid an infinite loop in author updates.
*
* @var boolean
*/
public static $processing_user_updated_event = false;
public static $enabled = true;

/**
* Holds information about the users that were updated in this request, if any.
Expand Down Expand Up @@ -73,7 +73,6 @@ class User_Update_Watcher {
public static $user_props = [
'display_name',
'user_email',
'ID',
'user_url',
];

Expand Down Expand Up @@ -126,7 +125,7 @@ private static function add_change( $user_id, $type, $key, $value ) {
* @return void
*/
public static function update_user_meta( $meta_id, $user_id, $meta_key, $meta_value ) {
if ( self::$processing_user_updated_event ) {
if ( ! self::$enabled ) {
return;
}

Expand All @@ -144,7 +143,7 @@ public static function update_user_meta( $meta_id, $user_id, $meta_key, $meta_va
* @return void
*/
public static function profile_update( $user_id, $old_user_data, $user_data ) {
if ( self::$processing_user_updated_event ) {
if ( ! self::$enabled ) {
return;
}

Expand All @@ -161,7 +160,7 @@ public static function profile_update( $user_id, $old_user_data, $user_data ) {
* @return void
*/
public static function maybe_trigger_event() {
if ( self::$processing_user_updated_event ) {
if ( ! self::$enabled ) {
return;
}
foreach ( self::$updated_users as $author ) {
Expand Down
202 changes: 202 additions & 0 deletions includes/distributor-customizations/class-author-distribution.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
<?php
/**
* Newspack Network author distribution.
*
* @package Newspack
*/

namespace Newspack_Network\Distributor_Customizations;

use Newspack\Data_Events;
use Newspack_Network\Debugger;
use Newspack_Network\User_Update_Watcher;

/**
* Class to handle author distribution.
*
* Every time a post is distributed, we also send all the information about the author (or authors if CAP is enabled)
* On the target site, the plugin will create the authors if they don't exist, and override the byline
*/
class Author_Distribution {

/**
* Initializes the class
*
* @return void
*/
public static function init() {
add_filter( 'dt_push_post_args', [ __CLASS__, 'add_author_data_to_push' ], 10, 2 );
add_filter( 'rest_prepare_post', [ __CLASS__, 'add_author_data_to_pull' ], 10, 3 );
}

/**
* Filters the post data sent on a push to add the author data.
*
* @param array $post_body The post data.
* @param WP_Post $post The post object.
* @return array
*/
public static function add_author_data_to_push( $post_body, $post ) {
$authors = self::get_authors_for_distribution( $post );
if ( ! empty( $authors ) ) {
$post_body['newspack_network_authors'] = $authors;
}
return $post_body;
}

/**
* Filters the post data for a REST API response.
*
* This acts on requests made to pull a post from this site.
*
* @param WP_REST_Response $response The response object.
* @param WP_Post $post Post object.
* @param WP_REST_Request $request Request object.
*/
public static function add_author_data_to_pull( $response, $post, $request ) {
if (
empty( $request->get_param( 'distributor_request' ) ) ||
'GET' !== $request->get_method() ||
'edit' !== $request->get_param( 'context' ) ||
empty( $request->get_param( 'id' ) )
) {
return $response;
}

$authors = self::get_authors_for_distribution( $post );

if ( ! empty( $authors ) ) {
$data = $response->get_data();
$data['newspack_network_authors'] = $authors;
$response->set_data( $data );
}

return $response;

}

/**
* Get the authors of a post to be added to the distribution payload.
*
* @param WP_Post $post The post object.
* @return array An array of authors.
*/
private static function get_authors_for_distribution( $post ) {
$author = self::get_wp_user_for_distribution( $post->post_author );

if ( ! function_exists( 'get_coauthors' ) ) {
if ( is_wp_error( $author ) ) {
Debugger::log( 'Error getting author ' . $post->post_author . ' for distribution on post ' . $post->ID . ': ' . $author->get_error_message() );
return [];
}
return [ $author ];
}

$co_authors = get_coauthors( $post->ID );
if ( empty( $co_authors ) ) {
if ( is_wp_error( $author ) ) {
Debugger::log( 'Error getting author ' . $post->post_author . ' for distribution on post ' . $post->ID . ': ' . $author->get_error_message() );
return [];
}
return [ $author ];
}

$authors = [];

foreach ( $co_authors as $co_author ) {
if ( is_a( $co_author, 'WP_User' ) ) {
// This will never return an error because we are checking for is_a() first.
$authors[] = self::get_wp_user_for_distribution( $co_author );
continue;
}

$guest_author = self::get_guest_author_for_distribution( $co_author );
if ( is_wp_error( $guest_author ) ) {
Debugger::log( 'Error getting guest author for distribution on post ' . $post->ID . ': ' . $guest_author->get_error_message() );
Debugger::log( $co_author );
continue;
}
$authors[] = $guest_author;
}

return $authors;

}

/**
* Gets the user data of a WP user to be distributed along with the post.
*
* @param int|WP_Post $user The user ID or object.
* @return WP_Error|array
*/
private static function get_wp_user_for_distribution( $user ) {
if ( ! is_a( $user, 'WP_User' ) ) {
$user = get_user_by( 'ID', $user );
}

if ( ! $user ) {
return new WP_Error( 'Error getting WP User details for distribution. Invalid User' );
}

$author = [
'type' => 'wp_user',
'id' => $user->ID,
];


foreach ( User_Update_Watcher::$user_props as $prop ) {
if ( isset( $user->$prop ) ) {
$author[ $prop ] = $user->$prop;
}
}

// CoAuthors' guest authors have a 'website' property.
if ( isset( $user->website ) ) {
$author['website'] = $user->website;
}

foreach ( User_Update_Watcher::$watched_meta as $meta_key ) {
$author[ $meta_key ] = get_user_meta( $user->ID, $meta_key, true );
}

return $author;
}

/**
* Get the guest author data to be distributed along with the post.
*
* @param object $guest_author The Guest Author object.
* @return WP_Error|array
*/
private static function get_guest_author_for_distribution( $guest_author ) {

if ( ! is_object( $guest_author ) || ! isset( $guest_author->type ) || 'guest-author' !== $guest_author->type ) {
return new WP_Error( 'Error getting guest author details for distribution. Invalid Guest Author' );
}

$author = [
'type' => 'guest_author',
'id' => $guest_author->ID,
];

foreach ( User_Update_Watcher::$user_props as $prop ) {
if ( isset( $guest_author->$prop ) ) {
$author[ $prop ] = $guest_author->$prop;
}
}

// CoAuthors' guest authors have a 'website' property.
if ( isset( $guest_author->website ) ) {
$author['website'] = $guest_author->website;
}

foreach ( User_Update_Watcher::$watched_meta as $meta_key ) {
if ( isset( $guest_author->$meta_key ) ) {
$author[ $meta_key ] = $guest_author->$meta_key;
}
}

return $author;
}

}
Loading