distributor
distributor copied to clipboard
Post author uses API user instead of author.
Describe the bug We have selected the option in Setting: For linked distributed posts, replace the author name and link with the original site name and link.
but when a new post is distributed the Author is the API user and not the post author.
Steps to Reproduce 1.create new post 2. distributed it
Expected behavior created post to be distributed with the original Author
Screenshots
Environment information
- Device: PC
- OS: Windows 10
- Browser and version: Chrome Version 89.0.4389.128
- WordPress version: 5.7.1
@siniger, can you share with us the Site Health Debug Info? I can't reproduce your issue on my end which uses WP 5.7.1 (both single site and multisite).
Also, what does the API user
mean?
but when a new post is distributed the Author is the API user and not the post author.
Note that when you check the option, the post author and link are replaced by the Site name and site URL, not the post author.
By accident I was researching an issue with the current logged in user and saw this ticket. Does @siniger refer to this line of code? https://github.com/10up/distributor/blob/develop/includes/classes/ExternalConnections/WordPressExternalConnection.php#L907
While InternalConnections can re-use the author_id of the original author because it's a Network site?
Hi I have the same issue and by API he means the user that the application password is being used from on the remote website. So that the remote website user-name that has the application password gets added as the author to posts.
Has anyone found a solution to this issue yet?
Thanks
Luke
@siniger @jmslbam @ldollard Can you please help me test the #767 to see if it fixes your issue?
@siniger can you please confirm from your original description if you have the Override Author Byline
setting checked?:
...or unchecked?:
Thanks! Jeff.
@dinhtungdu not sure what happened, but i replied to this that it wasn't working correctly after updating the includes file, it seems to do something, but is not changing the user in the backend of metadata, but weirdly a plugin I use called simple author partially picks up the change as seen in these images.
https://we.tl/t-7GsPQeM2ig
I also have this checked:

@ldollard The PR #767 doesn't fully resolve this issue and our team is reviewing this issue again. So there won't be updated to #767 until further notice.
In the meantime, you can follow this workaround to have the author display correctly:
- For each author on the original site, create user accounts with the same information on the remote site.
- Create multiple connections to the same remote site, use the use in the step above as the API user.
- When pushing post to the remote site, choose the connection authorized with the respective user.
I am interested in this feature as well. The client I work for has asked me to create a solution, for which I've added this file to the mu-plugins.
/**
* Extends features for the distributor plugin.
*/
class DistributorExt {
/**
* Initialise any hooks.
*/
public function setup() {
add_action( 'dt_pull_post', [ $this, 'pull_post' ], 99, 3 );
}
/**
* Update the post author.
*
* Action triggered when a post is pulled via distributor.
* Fires after a post is pulled via Distributor and after `restore_current_blog()`.
*
* @param int $new_post_id The new post ID that was pulled.
* @param \Distributor\Connection $connection The Distributor connection pulling the post.
* @param array $post_array The original post data retrieved via the connection.
*
*/
function pull_post( $new_post_id, $connection, $post_array ) {
$post = get_post( $new_post_id );
// Bail early.
if ( ! $post || ! isset( $post_array['post_author'] ) ) {
return;
}
// Get the original author id from the blog.
$author_id = (int) sanitize_text_field( $post_array['post_author'] );
// Check if the user is on this blog, if not add them.
$author_id = $this->check_and_add_blog_author( $author_id );
// Author not given access to this blog.
if ( ! $author_id ) {
return;
}
$this->update_post_author( $post, $author_id );
}
/**
* Check the user is already on this blog, if not and they exist on another, add them.
*
* @param int $author_id The author ID.
*
* @return int
*/
protected function check_and_add_blog_author( $author_id ) {
// Bail early.
if ( ! is_multisite() ) {
return 0;
}
$user = get_user_by( 'id', $author_id );
// Bail early.
if ( ! $user ) {
return 0;
}
$current_blog_id = get_current_blog_id();
$blogs_of_user = get_blogs_of_user( $user->ID );
// The user doesnt belong on any other blogs, but exist within the User base.
// Add them to this blog, with the "editor" role.
if ( ! $blogs_of_user ) {
add_user_to_blog( $current_blog_id, $user->ID, 'editor' );
return $user->ID;
}
$user_blog_roles = [];
// Check if the user exists on the blog and bail early.
foreach ( $blogs_of_user as $blog_of_user ) {
if ( $blog_of_user->userblog_id === $current_blog_id ) {
// Bail early, the user exists on this blog.
return $user->ID;
} else {
// Switch to the users blog, and get their role ready for latter.
switch_to_blog( $blog_of_user->userblog_id );
$blog_user = get_user_by( 'id', $user->ID );
if ( $blog_user->roles ) {
$user_blog_roles[] = $blog_user->roles;
}
restore_current_blog();
}
}
$user_blog_roles = $this->combine_roles( $user_blog_roles );
// Bail early.
if ( ! $user_blog_roles ) {
return $user->ID;
}
$allowed_roles = [
'editor',
'us_syndicated_author',
];
foreach ( $allowed_roles as $role ) {
// Add the user and bail early if the role matches an allowed role.
if ( in_array( $role, $user_blog_roles, true ) ) {
add_user_to_blog( $current_blog_id, $user->ID, $role );
break;
}
}
return $user->ID;
}
/**
* Process a the post without using wp_update_post(), this prevents changes to the post dates in teh database.
*
* @param WP_Post|int $post The Post object or ID of the post to process.
* @param int $author_id The author id for the post.
*/
protected function update_post_author( $post, $author_id ) {
global $wpdb;
if ( (int) $post->post_author !== $author_id ) {
$wpdb->update( // phpcs:ignore
$wpdb->posts,
[ 'post_author' => $author_id ],
[ 'ID' => $post->ID ],
[ '%d' ],
[ '%d' ]
);
}
}
/**
* Combine roles from all user blogs.
*
* @param $array
*
* @return array|false
*/
protected function combine_roles( $array ) {
foreach ( $array as $index => $roles ) {
foreach ( $roles as $roles_index => $role ) {
$array[ $index ][ $role ] = $role;
unset( $array[ $index ][ $roles_index ] );
}
}
$array = call_user_func_array( 'array_merge', $array ? : [ [] ] );
return is_array( $array ) ? $array : [];
}
}
// Load the extension.
add_action( 'plugins_loaded', function () {
// Bail early if the plugin is not active.
if ( ! is_plugin_active( 'distributor-stable/distributor.php' ) ) {
return;
}
( new DistributorExt() )->setup();
}, 11 );
This of course is tailored to my usage, and I am yet to test updating authors on the linked post, on the original blog.