我们有一个相当大的网站网络。 所有这些都需要显示正确的作者信息。 我看到,截至目前,Distributor 会将分布式帖子作者设置为经过身份验证的用户 ID。 我想改变这一点(并且愿意自己做这项工作)。 这里有两种可能的解决方案:
dt_item_mapping
进行拉取或使用dt_push_post_args
进行推送过滤器)以允许根据现有的帖子作者 ID 和站点传递“正确的”作者 ID我们发布到。 这将要求最终用户具有当前站点作者 ID 到外部站点作者 ID 的映射或数据库。 对于很多管理员来说,这并不是世界上最难的事情,但仍然是一个相当高的标准。 如果人们认为这是最好的路线,我很可能会编写自己的解决方案并将其记录在README.md
中。 最终,可以在 Distributor 中创建一个 UI 来管理它。无论如何,寻找关于走哪条路或完全不同的路的反馈。 我希望尽快完成这项工作,当然会提交对插件的任何更改。
我们编写了自己的联合应用程序,并使用作者的电子邮件地址向接收站点查询 ID。 这假设作者在网络中的所有站点上使用相同的电子邮件地址。
感谢@dleeward的提示,我刚刚完成了一些代码,这些代码可以存在于您的主题 functions.php 中,以便在推送期间同步作者。 它将尝试通过传递的电子邮件地址找到作者。 如果找不到现有用户,则使用来自推送 WP 的属性创建用户。 这还没有经过很好的测试,不应该在生产中使用。
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);
}
@robbiet480您不应该假设原作者的 user_login 和 user_nicename 尚未被使用。 我们创建一个当前 unix 时间的任意用户名,并以一个短文本字符串为前缀,例如 ABC1519562843。 这确实假设您每秒创建的用户不超过一个。 您可以使用 microtime 或添加随机后缀。
我们已经讨论了很多。
通常,我们认为以经过身份验证的用户身份发布是对每个人来说最安全、最兼容的解决方案。 我们肯定看到不同的出版商可能有不同的要求。 在远程站点上创建新用户会引发大量难题。 新用户角色是什么? 原作者是否可以访问该帐户?
当然,这是开放的讨论,我们很想听听其他意见,但现在我们能做的最好的就是添加额外的钩子/过滤器,以使@robbiet480更容易完成。
需要注意的一点是,许多出版物需要支持多个作者的内容,在这些情况下,“用户”通常甚至不用于作者 <-> 内容关系。
当我在 DFM 处理联合内容时,我们使用了 Co-Authors Plus,它是一种混合的帖子类型/分类解决方案,用于将许多作者添加到帖子中,因此在我们的案例中,我们实际上_想要_将经过身份验证的用户连接到帖子作为联合内容的作者,所以我们有一个用户触发联合的线索,我们联合了额外的数据来处理作者<->内容关系(有点类似于如何处理与媒体的关系)
感谢您的反馈,杰森!
所以我现在更进一步,实际上通过钩子向分发者添加了对 Co-Authors Plus 的支持。 这是我的代码,供其他对集成感兴趣的人使用。 我在#131 中询问了有关包含在分销商中的信息。
<?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);
回复:关于与作者一起分发的原始查询,我想说 CAP 可能是一个很好的权宜之计,允许分发者确保正确的作者被记入,而不必担心@tlovett1提到的事情,比如应该新的角色用户有等等。 此外,我认为添加更多模板标签以向前端公开诸如原始作者之类的信息会很有意义,就像我们现在能够公开原始站点名称一样。
我想通过#131 中的决定来阻止这个问题。 如果这个决定是 Distributor 将支持外部插件而不是通过钩子/过滤器,那么我们可以继续使用 Co-Authors Plus 调查这个特定问题,以及如何最好地与 Distributor 一起优雅地包含它。 如果 Distributor 采用仅挂钩/过滤器的方法,那么我们很可能会关闭此问题(并希望链接到 Co-Authors Plus 扩展代码的示例存储库)。