Comments (9)
We wrote our own syndication application and used the author's email address to query the receiving site for the ID. This assumes authors use the same email address on all sites in the network.
from distributor.
@robbiet480 You shouldn't assume that the original author's user_login and user_nicename aren't already being used. We create an arbitrary username of the current unix time prefixed with a short text string such as ABC1519562843. This does assume you aren't creating more than one user per second. You could use microtime or add a random suffix instead .
from distributor.
One thing to note, is that many publications have the need to support multiple authors for content, and in those cases, "Users" are often not even used for the author <-> content relationship.
When I was working on syndicating content at DFM, we used Co-Authors Plus which was a hybrid post-type/taxonomy solution for adding many authors to posts, so in our case we actually wanted the authenticated user to be connected to the post as the author of the syndicated content, so we had a trail of what user triggered the syndication, and we syndicated additional data to handle the authors<->content relationship (somewhat similar to how relationships to media is handled)
from distributor.
So i've taken this a step further now and actually added support for Co-Authors Plus to Distributor via hooks. Here's my code for anyone else interested in the integration. I've inquired in #131 about inclusion in Distributor.
<?php
function handle_dt_process_distributor_attributes( $post, $request, $update ) {
if ( empty( $post ) || is_wp_error( $post ) ) {
return;
}
if ( is_plugin_active( 'co-authors-plus/co-authors-plus.php' ) && ! empty( $request['distributor_coauthors'] ) ) {
global $coauthors_plus;
$author_logins = array();
foreach ( $request['distributor_coauthors'] as $coauthor ) {
$existing_guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'user_login', $coauthor['user_login'] );
if ( ! $existing_guest_author ) {
$guest_author_id = $coauthors_plus->guest_authors->create( array(
'display_name' => $coauthor['display_name'],
'first_name' => $coauthor['first_name'],
'last_name' => $coauthor['last_name'],
'user_login' => $coauthor['user_login'],
'user_nicename' => $coauthor['user_nicename']
) );
if ( is_wp_error( $guest_author_id ) ) {
error_log("Error creating co-author during Distributor push ".$guest_author_id->get_error_message());
return;
}
if ( !$guest_author_id ) {
error_log( '-- Failed to create guest author.' );
}
if ( ! empty($coauthor['avatar_url']) ) {
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
$thumbnail_id = media_sideload_image($coauthor['avatar_url'], $guest_author_id, null, 'id');
set_post_thumbnail($guest_author_id, $thumbnail_id);
}
$guest_author = $coauthors_plus->guest_authors->get_guest_author_by( 'ID', $guest_author_id );
array_push($author_logins, $guest_author->user_login);
} else {
array_push($author_logins, $existing_guest_author->user_login);
}
}
clean_post_cache($post->ID);
$coauthors_plus->guest_authors->delete_guest_author_cache($author_logins[0]);
}
}
add_action( 'dt_process_distributor_attributes', 'handle_dt_process_distributor_attributes', 10, 3 );
if ( is_plugin_active( 'co-authors-plus/co-authors-plus.php' ) ) {
function distributor_coauthors_get_avatar_url( $coauthor ) {
global $coauthors_plus;
if ( ! is_object( $coauthor ) ) {
return '';
}
if ( isset( $coauthor->type ) && 'guest-author' == $coauthor->type ) {
if ( ! has_post_thumbnail( $coauthor->ID ) ) {
return '';
}
$large_image_url = wp_get_attachment_image_src( get_post_thumbnail_id( $coauthor->ID ), 'large' );
return $large_image_url[0];
}
// Make sure we're dealing with an object for which we can retrieve an email
if ( isset( $coauthor->user_email ) ) {
return get_avatar( $coauthor->user_email, $size, $default, $alt );
}
// Nothing matched, an invalid object was passed.
return '';
}
}
function add_dt_push_post_args($post_body, $post, $that) {
if ( is_plugin_active( 'co-authors-plus/co-authors-plus.php' ) ) {
$post_body['distributor_coauthors'] = array();
foreach ( $coauthors as $coauthor ) {
if( array_key_exists("data", $coauthor) ) {
// Don't include real WP_Users
continue;
}
$coauthor_arr = (array) $coauthor;
$coauthor_arr['avatar_url'] = distributor_coauthors_get_avatar_url($coauthor);
array_push($post_body['distributor_coauthors'], $coauthor_arr);
}
}
return $post_body;
}
add_filter('dt_push_post_args', 'add_dt_push_post_args', 1, 3);
add_filter('dt_push_post_timeout', function($default_timeout, $post) {
return 30;
}, 1, 2);
from distributor.
Thanks for the tip @dleeward, I just finished hacking together some code that can live in your theme functions.php to sync authors during a push. It will attempt to find the author by the passed email address. If an existing user can not be found, a user is created with the properties from the pushing WP. This hasn't been well tested yet and should not yet be used in production.
if ( defined( 'DT_VERSION' ) ) {
function setup_distributor_replacements() {
$post_types = get_post_types(array('show_in_rest' => true));
foreach ( $post_types as $post_type ) {
add_action( "rest_insert_{$post_type}", 'process_original_author', 10, 3 );
}
}
function process_original_author( $post, $request, $update ) {
if ( empty( $post ) || is_wp_error( $post ) ) {
return;
}
if ( ! empty( $request['distributor_original_author'] ) ) {
$author_obj = $request['distributor_original_author'];
$new_author = get_user_by( 'email', $author_obj['email'] );
$author_id = 0;
if ( ! empty( $new_author ) && ! is_wp_error( $new_author ) ) {
$author_id = $new_author->ID;
} else {
$create_user = wp_insert_user(array(
'display_name' => $author_obj['display_name'],
'first_name' => $author_obj['first_name'],
'last_name' => $author_obj['last_name'],
'nickname' => $author_obj['nickname'],
'user_displayname' => $author_obj['user_displayname'],
'user_email' => $author_obj['user_email'],
'user_login' => $author_obj['user_login'],
'user_nicename' => $author_obj['user_nicename'],
'user_pass' => NULL
));
if ( is_wp_error( $create_user ) ) {
error_log("Error creating user during Distributor push ".$create_user->get_error_message());
return;
}
$author_id = $create_user;
}
wp_update_post( array( 'ID' => $post->ID, 'post_author' => $author_id ) );
}
}
add_action('init', 'setup_distributor_replacements');
function add_original_author($post_body, $post, $that) {
$post_author = get_user_by( 'id', $post->post_author );
$author_obj = array(
'display_name' => $post_author->display_name,
'first_name' => get_user_meta($post->post_author, 'first_name', true),
'first_name' => get_user_meta($post->post_author, 'first_name', true),
'last_name' => get_user_meta($post->post_author, 'last_name', true),
'user_email' => $post_author->user_email,
'user_login' => $post_author->user_login,
'user_nicename' => $post_author->user_nicename,
);
$post_body['distributor_original_author'] = $author_obj;
return $post_body;
}
add_filter('dt_push_post_args', 'add_original_author', 1, 3);
}
from distributor.
We'd discussed this one a lot.
Generally, we believe posting as the authenticated user is the safest most compatible solution for everyone. We definitely see different publishers may have different requirements. Creating a new user on the remote site opens up a ton of hard questions. What is the new users role? Should that account be accessible by the original author?
Of course this is open for discussion, and we'd love to hear other opinions, but for now the best we can do is to add additional hooks/filters to make what @robbiet480 accomplished easier.
from distributor.
Appreciate the feedback, Jason!
from distributor.
Re: the original query about distributing with authors, I'd say that CAP could be a good stop gap solution to allow for Distributor to ensure the proper author is credited while not having to worry about things that @tlovett1 mentioned like what role should new users have and such. Furthermore, I think it would make a lot of sense to add more template tags to expose information like original author to the frontend just like how we are now able to expose original site name.
from distributor.
I'd like to block this issue by the decision-to-be-made in #131. If that decision turns out to be that Distributor will support external plugins more than via hooks/filters, then we can continue investigating this specific issue with Co-Authors Plus and how it can best be gracefully included with/alongside Distributor. If Distributor takes the hooks/filters-only approach, then its likely we'll close this issue (and hopefully link out to an example repo for the Co-Authors Plus extension code).
from distributor.
Related Issues (20)
- E2E Tests: migrate TestLodge tests to Cypress
- Parent of a distributed page is not saved
- The plugin hasn't been tested with the latest version of WordPress HOT 1
- Update admin menu icon to have the same width & height HOT 2
- List formerly-linked posts in pull UI with option to reassociate HOT 6
- Distributor UI disappears HOT 5
- Feature request: Add filter to allow for arbitrary media to be included in push/pull
- Upgrade Cypress to version 13
- [Block themes] Pulled posts author details are not replaced as author is unset HOT 1
- Cannot pull posts after update HOT 5
- Featured image not distributed/pushed after update HOT 6
- Is there a way to stop the auto sync of linked posts?
- Unpublish ditributed post HOT 1
- Connection Issues HOT 7
- Variable products pull as simple products HOT 1
- webp images dont pull for woocommerce
- lost connections when update the WordPress in version 6.3.2
- The plugin hasn't been tested with the latest version of WordPress HOT 2
- Filter to allow push/pull of draft/scheduled posts in network/external connected sites HOT 3
- Limited connection established. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from distributor.