¿Seleccionar suscriptor como autor de una publicación en el panel de administración?
Quiero poder seleccionar a un suscriptor como autor de una publicación en el panel de administración para que muestre su nombre como autor del artículo, pero no quiero darle ningún privilegio adicional (si inician sesión, lo único que pueden ver es su perfil).
¿Existe una forma sencilla de hacer esto sin tener que cambiar roles y capacidades?
Gracias

Este es un simple truco que escribí en una situación similar. Mostrará todos los Suscriptores
en el menú desplegable de Autor
al editar/agregar una entrada o página, desde donde podrás seleccionar el que desees. Creo que debería funcionar para ti...
add_filter('wp_dropdown_users', 'MySwitchUser');
function MySwitchUser($output)
{
// $post está disponible globalmente aquí, por lo que puedes verificar el tipo de publicación
$users = get_users('role=subscriber');
$output = "<select id=\"post_author_override\" name=\"post_author_override\" class=\"\">";
// Mantener al administrador en la lista
$output .= "<option value=\"1\">Administrador</option>";
foreach($users as $user)
{
$sel = ($post->post_author == $user->ID)?"selected='selected'":'';
$output .= '<option value="'.$user->ID.'"'.$sel.'>'.$user->user_login.'</option>';
}
$output .= "</select>";
return $output;
}
El truco detrás de esto es que, después de enviar esta página, WordPress solo lee el $user->ID de este menú desplegable en el array $_POST y lo asigna como el autor de la publicación. ¡Y eso es exactamente lo que quieres!

¡Muchas gracias Rutwick! Exactamente lo que necesitaba! Solo tuve que cambiar $users = get_users(); de lo contrario no mostraba usuarios con otros roles ahí

¡De nada, colega! :) En realidad lo estaba usando para un rol personalizado, por eso los parámetros... ¡Me alegra haber podido ayudar!

Acabo de encontrar un pequeño problema con esto - cuando vuelvo a la página de edición del post, el menú desplegable se establece por defecto en admin, así que si hago cambios y guardo sin volver a seleccionar el autor, cambia el autor a admin. ¿Alguna idea de cómo solucionarlo?

Sí, obtienes el autor de esta publicación y verificas cuál de los usuarios coincide con el autor, mantén esa opción seleccionada.

Por alguna razón, $post->post_author no devuelve nada en mi pantalla de edición de publicación y no entiendo por qué.

Ten en cuenta que el ID de usuario 1
puede o no ser un administrador. Obtener un administrador real de WordPress funcionaría.

He hecho algunos ajustes menores a esta solución, por si alguien lo necesita. Si quieres mostrar el "nombre para mostrar" en el menú desplegable, solo cambia la segunda línea dentro del foreach por esto: $output .= '<option value="'.$user->ID.'"'.$sel.'>'.$user->display_name.'</option>'; Y si quieres agregar algún usuario específico (con un rol diferente), añade esto antes del foreach: $output .= "<option value=\"[ID]\">Nombre</option>"; (reemplaza [ID] con el ID real)

A partir de WordPress 4.4.0 ahora puedes usar el filtro wp_dropdown_users_args
. El código es mucho más simple ahora:
add_filter( 'wp_dropdown_users_args', 'add_subscribers_to_dropdown', 10, 2 );
function add_subscribers_to_dropdown( $query_args, $r ) {
$query_args['who'] = '';
return $query_args;
}

Esta debería ser la respuesta correcta/aceptada. Directamente del Codex: https://developer.wordpress.org/reference/hooks/wp_dropdown_users_args/#user-contributed-notes

Este es un enfoque similar al de @brasofilo. Pero solo funciona en la pantalla de edición de entradas, no en la edición rápida, e incluye a todos los usuarios (no solo autores y suscriptores).
/* Eliminar el metabox de Autor de la edición de entradas */
function wpse50827_author_metabox_remove() {
remove_meta_box('authordiv', 'post', 'normal');
}
add_action('admin_menu', 'wpse50827_author_metabox_remove');
/* Reemplazar con un metabox de Autor personalizado */
function wpse39084_custom_author_metabox() {
add_meta_box( 'authordiv', __('Autor'), 'wpse39084_custom_author_metabox_insdes','post');
}
add_action( 'add_meta_boxes', 'wpse39084_custom_author_metabox');
/* Incluir todos los usuarios en el dropdown de autor de la entrada */
/* Imita el metabox por defecto http://core.trac.wordpress.org/browser/trunk/wp-admin/includes/meta-boxes.php#L514 */
function wpse39084_custom_author_metabox_insdes() {
global $user_ID;
global $post;
?>
<label class="screen-reader-text" for="post_author_override"><?php _e('Autor'); ?></label>
<?php
wp_dropdown_users( array(
'name' => 'post_author_override',
'selected' => empty($post->ID) ? $user_ID : $post->post_author,
'include_selected' => true
) );
}
Esto imita el metabox de autor por defecto pero la llamada wp_dropdown_users
omite el argumento who=>'editors'
. Por defecto usa el único otro valor disponible que es todos los usuarios.

Gracias Stephen. Terminé usando la solución de Rutwick porque ya funciona con CPTs, pero agradezco tu respuesta :)

Este es un código vinculado por @Innate en un comentario (solución) a su propia pregunta, solo lo he adaptado un poco y probado en WP 3.3.2 (función wpse39084). Mostrará los suscriptores en las ediciones de entradas y en la Edición Rápida.
También añadí un par de acciones (funciones wpse50827) para mover el meta box del Autor dentro del meta box de Acciones de Publicación, para facilitar su gestión.
Todo está relacionado con entradas, no con páginas ni CPTs...
foreach( array( 'edit.php', 'post.php' ) as $hook )
add_action( "load-$hook", 'wpse39084_replace_post_meta_author' );
/* Mostrar Suscriptores en los desplegables de autor de entradas - edición y edición rápida */
function wpse39084_replace_post_meta_author()
{
global $typenow;
if( 'post' != $typenow )
return;
add_action( 'admin_menu', 'wpse50827_author_metabox_remove' );
add_action( 'post_submitbox_misc_actions', 'wpse50827_author_metabox_move' );
add_filter( 'wp_dropdown_users', 'wpse39084_showme_dropdown_users' );
}
/* Modificar el desplegable de autores */
function wpse39084_showme_dropdown_users( $args = '' )
{
$post = get_post();
$selected = $post->post_author;
$siteusers = get_users( 'orderby=nicename&order=ASC' ); // puedes pasar filtros y opciones
$re = '';
if( count( $siteusers ) > 0 )
{
$re = '<select name="post_author_override" id="post_author_override">';
foreach( $siteusers as $user )
{
$re .= '<option value="' . $user->ID . '">' . $user->user_nicename . '</option>';
}
$re .= '</select>';
$re = str_replace( 'value="' . $selected . '"', 'value="' . $selected . '" selected="selected"', $re );
}
echo $re;
}
/* Eliminar el meta box de Autor de la edición de entradas */
function wpse50827_author_metabox_remove()
{
remove_meta_box( 'authordiv', 'post', 'normal' );
}
/* Mover el meta box de Autor dentro del meta box de Acciones de Publicación */
function wpse50827_author_metabox_move()
{
global $post;
echo '<div id="author" class="misc-pub-section" style="border-top-style:solid; border-top-width:1px; border-top-color:#EEEEEE; border-bottom-width:0px;">Autor: ';
post_author_meta_box( $post );
echo '</div>';
}

Una mejor manera de hacerlo...
add_filter('wp_dropdown_users', 'MySwitchUser');
function MySwitchUser()
{
global $post; // eliminar si no es necesario
// global $post está disponible aquí, por lo que puedes verificar el tipo de publicación aquí
$users = get_users('role=subscriber');
echo'<select id="post_author_override" name="post_author_override" class="">';
echo'<option value="1">Administrador</option>';
foreach($users as $user)
{
echo '<option value="'.$user->ID.'"';
if ($post->post_author == $user->ID){ echo 'selected="selected"'; }
echo'>';
echo $user->user_login.'</option>';
}
echo'</select>';
}

He hecho algo similar a la respuesta aceptada aquí, pero solo quería mostrar a los administradores y en mi caso, un rol personalizado de 'productores', juntos.
add_filter('wp_dropdown_users', 'custom_author_select');
function custom_author_select($output){
// Aquí está disponible el global $post, por lo que puedes verificar el tipo de publicación aquí
$admins = get_users('role=administrator');
$producers = get_users('role=producer');
$users = array_merge($admins, $producers);
$output = "<select id=\"post_author_override\" name=\"post_author_override\" class=\"\">";
// Mantener al admin en la lista
$output .= "<option value=\"1\">Admin</option>";
foreach($users as $user){
$sel = ($post->post_author == $user->ID)?"selected='selected'":'';
$output .= '<option value="'.$user->ID.'"'.$sel.'>'.$user->user_login.'</option>';
}
$output .= "</select>";
return $output;
}

Esta podría ser una solución para evitar el error en la edición rápida, donde "cpt_slug" debe ser reemplazado con el slug de tu tipo de contenido personalizado
add_filter('wp_dropdown_users', 'MySwitchUser');
function MySwitchUser($output)
{
global $typenow;
if ((is_edit_page('edit') && "cpt_slug" == $typenow)||(is_edit_page('new') && "cpt_slug" == $typenow)){
global $post;
$users = get_users();
$output = "<select id=\"post_author_override\" name=\"post_author_override\" class=\"\">";
foreach($users as $user)
{
$sel = ($post->post_author == $user->ID)?"selected='selected'":'';
$output .= '<option value="'.$user->ID.'"'.$sel.'>'.$user->user_login.'</option>';
}
$output .= "</select>";
}
return $output;
}
function is_edit_page($new_edit = null){
global $pagenow;
if (!is_admin()) return false;
if($new_edit == "edit")
return in_array( $pagenow, array( 'post.php' ) );
elseif($new_edit == "new")
return in_array( $pagenow, array( 'post-new.php' ) );
else
return in_array( $pagenow, array( 'post.php', 'post-new.php' ) );
}

Es un poco desordenado. Parece que hay 3 formas de abordarlo, y depende de si estás usando el Editor Clásico o Gutenberg.
Si estás usando el Editor Clásico:
- Puedes sobrescribir el HTML usando el filtro
wp_dropdown_users
como sugieren otras respuestas - O sobrescribir los parámetros de consulta usando
wp_dropdown_users_args
Si estás usando Gutenberg, el desplegable de Autores se implementa de manera diferente.
Como señaló Thomas Levy en este issue de GitHub:
- La función del editor de bloques utilizada para poblar el desplegable de autores es wodpress/data/select( ‘core’ ).getAuthors()
- Esto llama al endpoint de la API REST: /wp/v2/users/?who=authors&per_page=-1
- Este endpoint de API pasa datos a WP_User_Query
- Un WP_User_Query con el parámetro "who=>author" agregará una consulta de metadatos de usuario a la mezcla.
- Esto extraerá cualquier usuario con un user_level no igual a 0
Para que el rol personalizado aparezca en el desplegable de autores, necesitas agregar la capacidad level_1
al rol. Los niveles fueron reemplazados por capacidades en WordPress 2.0 en 2005, pero este comportamiento/error se mantuvo todo este tiempo.
$role = add_role( 'mycustomrole', 'Mi Rol Personalizado' );
$role->add_cap( 'level_1' );
Para agregar esta capacidad a usuarios existentes, ejecuta esto una vez:
$custom_role = get_users( 'role=mycustomrole' );
foreach ( $custom_role as $role ) {
$role->add_cap( 'level_1' );
}

Probé todas las soluciones aquí y algunas otras, pero esta de las notas contribuidas por los usuarios en el Wordpress Codex fue la única que funcionó para mí.
Dice que necesitas dar capacidad a los suscriptores para usarlo, pero en mi caso, no lo quería. Solo quería poder seleccionarlos en el cuadro de selección de autores.
// Mostrar Suscriptores en el menú desplegable de 'autor' en el editor clásico de entradas
function wpdocs_add_subscribers_to_dropdown( $query_args ) {
$query_args['who'] = ''; // reiniciar la consulta
$query_args['capability'] = ''; // reiniciar la consulta
$query_args['role__in'] = array( 'administrator', 'subscriber', 'author', 'editor' );
$query_args['capability__in'] = array( 'edit_own_posts' ); // Capacidad personalizada para suscriptores
return $query_args;
}
add_filter( 'wp_dropdown_users_args', 'wpdocs_add_subscribers_to_dropdown' );
El enlace a la página del codex: https://developer.wordpress.org/reference/hooks/wp_dropdown_users_args/#user-contributed-notes
