É possível permitir que um colaborador mude o autor de suas próprias postagens? Sei que isso os trancará efetivamente, é isso que eu quero. Quero que eles sejam capazes de alterar o autor depois que terminarem a edição.
É possível permitir que um colaborador mude o autor de suas próprias postagens? Sei que isso os trancará efetivamente, é isso que eu quero. Quero que eles sejam capazes de alterar o autor depois que terminarem a edição.
Respostas:
Estou adicionando uma segunda resposta porque minha primeira abordagem foi rejeitada e esta não recebeu a devida atenção.
A ideia é criar uma caixa meta personalizada que lista todos os usuários e altera o autor no save_post
gancho. Dessa forma, você não mexe com os recursos dos usuários e a alteração do autor acontece quando as postagens já estão salvas. Além disso, o lucro adicional é que você pode controlar a lista de usuários disponíveis no menu suspenso do autor. Passos a seguir:
Registrar a caixa meta:
function wpse313020_add_custom_box() {
// Bail out for users other than contributors
if ( ! user_can( get_current_user_id(), 'contributor' ) ) {
return;
}
// Register custom meta box
add_meta_box(
'wpse313020_author_override',
'Change Author', // metabox title
'wpse313020_author_ovveride_box_html', // callbac function
'post' // a post type you want to show the metabox on
);
}
add_action('add_meta_boxes', 'wpse313020_add_custom_box');
Crie a marcação para sua meta box:
/**
* HTML for custom meta box
*/
function wpse313020_author_ovveride_box_html() {
// you can modify the list of users by passing additional args to get_users()
$users = get_users();
?>
<label for="wpse313020_author_override_id">Select post author</label><br />
<select name="wpse313020_author_override_id" id="wpse313020_author_override_id" class="postbox">
<option value="">Select user...</option>
<?php
// get post ID on admin edit screen and retrieve saved post meta
$post_id = is_admin() && isset( $_GET['post'] ) ? absint( wp_unslash( $_GET['post'] ) ) : '';
$saved_value = ! empty( $post_id ) ? get_post_meta( $post_id, 'wpse313020_author_override', true ) : '';
foreach ( $users as $user ) {
echo sprintf( '<option value="%1$d" %2$s>%3$s</option>', absint( $user->ID ), selected( $saved_value, absint($user->ID, false ) ), esc_html( $user->display_name ) );
}
?>
</select>
<?php
}
Conecte-se a save_post
para salvar dados e substituir o autor:
/**
* Save custom post meta and override the post author
*/
function wpse313020_save_postdata( $post_id ) {
if ( array_key_exists('wpse313020_author_override_id', $_POST ) ) {
// save post meta with author ID
update_post_meta( $post_id, 'wpse313020_author_override', absint( $_POST['wpse313020_author_override_id'] ) );
// now modify the post author, we need to unhook the current function to prevent infinite loop
// you could add additional check here to see if the current author is not the same as chosen author
remove_action( 'save_post', 'wpse313020_save_postdata' );
$updated_data = [
'ID' => $post_id,
'post_author' => absint( $_POST['wpse313020_author_override_id'] ),
];
wp_update_post( $updated_data );
add_action( 'save_post', 'wpse313020_save_postdata' );
}
}
add_action('save_post', 'wpse313020_save_postdata');
NOTA
Lembre-se de adicionar o campo nonce e marque-o no pós-salvamento. Além disso, você pode considerar o uso de outros ganchos em vez de save_post
, pre_post_update
ou seja wp_insert_post_data
, ou para processar os dados no pós-salvamento inicial.
Espero que ajude!
Embora seja possível permitir que um autor (ou colaborador) atribua outro autor à sua própria postagem usando o user_has_cap
gancho de filtro e algum código relacionado, no entanto, essa abordagem em si é fundamentalmente falha . Portanto, mesmo se você tomar todas as medidas de segurança necessárias, ainda será uma vulnerabilidade, pois quebra completamente a arquitetura de recursos.
Deixe-me dar um exemplo de cenário: digamos que um usuário com função de autor tenha uma intenção menos honrosa e spams a outro autor com várias postagens (talvez usando um script). Na próxima vez em que o autor do destino fizer login, ele verá todas as postagens em seu nome! Isso continuará, pois o outro autor não tem como parar! Portanto, precisamos encontrar uma abordagem alternativa que não tenha essa falha.
Se a alteração do autor for um recurso necessário, uma abordagem melhor é envolver o outro autor (ou um usuário avançado como outros editores ou administradores) no processo de alteração do autor, para que o autor inicial não consiga enviar spam para o autor. autor do destino.
Para conseguir isso, deixaremos o autor inicial escolher o autor de destino no editor, mas não mudaremos o autor da postagem de maneira correta. Em vez disso, no momento da alteração do autor, salvaremos uma meta personalizada de postagem que salvará o ID do autor de destino. Em seguida, no painel do administrador, teremos um submenu de postagem, onde todas as postagens com a solicitação de alteração do autor serão exibidas. Somente o autor do destino e os usuários com edit_others_post
capacidade (como editores, administradores, etc.) terão acesso à interface do usuário dessa solicitação de alteração de autor. Na interface do usuário, o usuário com acesso adequado aprovará a alteração e somente então a alteração final do autor ocorrerá.
A implementação do CODE pode variar dependendo do requisito; no entanto, sem nenhuma outra implementação do CODE, os autores iniciantes poderão modificar a postagem ou até reverter a solicitação de alteração do autor na janela do processo de aprovação. Eles serão bloqueados para fora da postagem assim que a solicitação de alteração do autor for aprovada.
A caixa suspensa do autor será exibida apenas quando o usuário tiver edit_others_posts
capacidade. No entanto, você não deseja atribuir esse recurso aos autores por padrão, por razões óbvias. A solução é fornecer esse recurso somente em circunstâncias específicas, a saber, quando ele estiver editando uma de suas próprias postagens. Como o recurso foi gravado no banco de dados, você também deve garantir que ele seja removido em qualquer outra página.
Esta é uma questão de tempo preciso. Você deseja alterar a capacidade depois que o WP decidir que o colaborador tem o direito de editar a postagem, mas antes que o formulário da página de edição ( post.php
) seja gerado. Um gancho adequado é admin_init
.
Como isso:
add_action ('admin_init', 'wpse313020_change_author');
function wpse313020_change_author () {
global $pagenow;
$current_user = wp_get_current_user();
// only do this if current user is contributor
if ('contributor' == $current_user->roles[0]) {
// add capability when we're editing a post, remove it when we're not
if ('post.php' == $pagenow)
$current_user->add_cap('edit_others_posts')
else
$current_user->remove_cap('edit_others_posts');
}
}
Eu não testei o código, então pode ser um bug, mas você entendeu.
Tentei alcançar o que você precisa filtrando os recursos de meta do contribuidor e parece funcionar bem. Tudo o que faço aqui é adicionar a edit_others_posts
capacidade de colaboradores quando o WordPress solicitar.
No entanto, eu diria que é uma solução um pouco hacky para mim e não tenho certeza se é totalmente seguro. Pelo que verifiquei depois de colocar meu filtro no functions.php
WordPress, os contribuidores não podem editar postagens de outros usuários em outros contextos, além do que você solicitou. Parece bom, mas não podemos realmente verificar explicitamente se o usuário atual é o autor da postagem editada atualmente (você não poderá salvar a postagem como usuário diferente se a verificação condicional for adicionada à função) - que Me preocupa.
/**
* author_cap_filter()
*
* Filter on the current_user_can() function.
* This function is used to explicitly allow contributors to change post authors
*
* @param array $allcaps All the capabilities of the user
* @param array $cap [0] Required capability
* @param array $args [0] Requested capability
* [1] User ID
*/
function author_cap_filter( $allcaps, $cap, $args ) {
// Bail out if we're not dealing with right capability:
if ( ! in_array( $args[0], [ 'edit_others_posts' ] ) ) {
return $allcaps;
}
// Bail out for users who are not contributors
if ( ! user_can( $args[1], 'contributor' ) ) {
return $allcaps;
}
// Bail out for users who can already edit others posts:
if ( isset( $allcaps['edit_others_posts'] ) && $allcaps['edit_others_posts'] ) {
return $allcaps;
}
// overwrite 'edit_others_posts' capability
$allcaps[ $args[0] ] = true;
return $allcaps;
}
add_filter( 'user_has_cap', 'author_cap_filter', 100, 3 );
edit_others_posts
capacidade aos autores permitirá que eles editem as postagens de outras pessoas. Nós também podemos transformar o autor em um editor, isso provavelmente é melhor do que oferecer a eles uma capacidade maior. A segunda solução é uma possibilidade, mas precisa de mais trabalho, IMHO.
edit_others_posts
sempre permitir a edição de postagens de outros usuários. Teste o código da minha resposta - mesmo com o filtro no lugar, a verificação de capacidade if ( ! current_user_can( 'edit_post', $post_id ) )
no github.com/WordPress/WordPress/blob/… ainda retorna falso. Mais uma vez, concordo que não é a solução segura, como mencionado na minha resposta, mas achei que vale a pena mencionar, pois realmente funciona. (pena de dois comentários em uma fileira, eu não caber no limite de charachter)
Antes de tudo, instale o plugin User Role Editor ( https://wordpress.org/plugins/user-role-editor/ ).
Segundo, usando o plug-in, crie uma nova função chamada Post Manager, por exemplo:
Após criar a nova função, você poderá editar seus recursos. Agora, é o momento em que você resolve seu problema, mas precisa decidir entre duas opções:
(ainda não se preocupe com a função de colaborador)
Primeiro:
edit_others_posts
e publish_posts
.Segundo:
edit_others_posts
,.Depois de decidir, clique em "Atualizar". Sua nova função agora deve ter a read
capacidade mais aquela que você escolheu.
Agora, acesse sua página de perfil de usuário colaborador e, no final da página, forneça funções extras (recurso Editor de Função de Usuário):
Agora, todo usuário que é Colaborador e Gerente de postagem poderá alterar o autor da postagem de postagens não publicadas. E, dependendo da sua escolha anterior, o usuário também pode publicar postagens e, se o fizer, não poderá mais editar a postagem.
IMPORTANTE!!!
Eu lhe mostrei uma solução criando uma nova função para preservar os recursos padrão do Colaborador. Se desejar (não é aconselhável), pule a criação do Post Manager e, usando o Editor de Função de Usuário, você apenas editaria os recursos do Colaborador diretamente .
E só para constar, por padrão, o WordPress permite apenas a edit_others_posts
capacidade de alterar o autor da postagem. Consulte https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/class-wp-posts-list-table.php linha 1483.