Permitir que o Colaborador altere o autor de sua própria postagem?

9

É 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.

Michael Rogers
fonte
Apenas imaginando aqui se existe outra maneira de alcançar a necessidade do negócio. Dar a um não-editor / administrador a capacidade de atribuir a qualquer outro autor sua postagem parece um pouco amplo. Existe uma lista predefinida de autores que eles podem atribuir como 'autor'? Existe alguma relação definida entre o colaborador e os autores permitidos? Ou eles podem escolher qualquer autor que gostem?
anmari 6/09/18
Também observo que isso não 'publicará' sua postagem. Portanto, parece que a intenção é imitar algum tipo de fluxo de trabalho em que o colaborador está atribuindo a postagem a um autor, em vez de dizer um editor selecionando as postagens 'pendentes' para revisão. Se seus autores puderem ser editores, talvez use wp como está e talvez use tags para comunicar ou destacar quais editores devem selecionar quais postagens?
anmari 6/09/18
Ah, você diz "bloqueie-os para fora do correio, é isso que eu quero". Isso é mais importante? Que depois que eles 'enviam para revisão', não conseguem mais editar? É necessário mexer com 'autores'? Ou algum status não público funcionaria? Talvez usando codex.wordpress.org/Post_Status#Custom_Status
anmari

Respostas:

1

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_postgancho. 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_postpara 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_updateou seja wp_insert_post_data, ou para processar os dados no pós-salvamento inicial.

Espero que ajude!

Levi Dulstein
fonte
1

Armadilhas:

Embora seja possível permitir que um autor (ou colaborador) atribua outro autor à sua própria postagem usando o user_has_capgancho 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.

Uma abordagem melhor:

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_postcapacidade (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á.

O que acontece com as postagens na fila de aprovação?

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.

Fayaz
fonte
0

A caixa suspensa do autor será exibida apenas quando o usuário tiver edit_others_postscapacidade. 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.

cjbj
fonte
-1

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_postscapacidade 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.phpWordPress, 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 );
Levi Dulstein
fonte
2
Observe que, conceder edit_others_postscapacidade 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.
Scott
Sinto que o voto negativo aqui não é justo, na verdade estou apontando as duas coisas na minha resposta, afirmando que a primeira solução não é segura e apontando que a segunda precisa de mais trabalho, mas acredito que é útil, pois mostra uma solução em funcionamento que o OP pode melhorar (não acho que responder a uma pergunta no WPSE deva significar fornecer trechos de código prontos para produção). Além disso, seria útil se você pudesse ser mais preciso e apontar o que poderia ser melhorado ou até mesmo editar meu post, se você quiser fazer pequenos ajustes. Felicidades!
Levi Dulstein
Além disso, você não está totalmente certo sobre edit_others_postssempre 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)
Levi Dulstein
-2

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:

insira a descrição da imagem aqui

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:

  • Dê ao seu novo papel dois recursos extras edit_others_postse publish_posts.
  • Dessa forma, seu colaborador poderá editar apenas postagens que não são publicadas (apenas postagens pendentes e de rascunho). Portanto, se o colaborador alterar o autor da postagem, ele ainda poderá editá-la. Eles somente serão impedidos de editar a postagem após a publicação. Isso também significa que, se o colaborador publicar a postagem e esquecer de mudar o autor, eles perderão a oportunidade de mudar o autor da postagem.

Segundo:

  • Dê ao seu novo papel apenas uma capacidade extra edit_others_posts,.
  • Dessa forma, funciona como o primeiro, MAS aqui seu colaborador não pode publicar, o que significa que não pode publicar e se esqueça de alterar o autor. Aqui, alguém teria que publicar a postagem.

Depois de decidir, clique em "Atualizar". Sua nova função agora deve ter a readcapacidade 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):

insira a descrição da imagem aqui

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_postscapacidade 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.

filipecsweb
fonte
1
isso torna o usuário um editor, não é necessário instalar plugins para isso, basta usar o administrador do usuário. De qualquer forma, não é isso que o OP pede.
27468 Mark Kaplun #
Esta solução permite explicitamente que o Colaborador altere o autor da postagem. Então, sim, é o que ele pediu. Segundo, por padrão, o Editor possui mais de 20 recursos atribuídos a ele. Minha solução não faz do Colaborador um editor. Deixe quem pediu decidir se minha resposta resolve o problema deles. Por favor, pense duas vezes sobre o seu voto negativo.
Filipecsweb
o OP pede que um colaborador ausente faça as coisas. Sua solução é fazê-lo editor que pode alterar os autores em todos os lugares e aqueles que violam a segurança
274 Mark Kaplun