Permitir que el rol elimine publicaciones pero le bloquea el wp-admin

2

Tengo un rol de usuario personalizado: Fotografía.

Este rol no debe poder iniciar sesión en el back-office, pero debe poder eliminar sus propias publicaciones desde el front-end.

Estoy usando este código para evitar que todos los usuarios que no son administradores se conecten al backoffice con esta (function.php):

add_action( 'init', 'blockusers_init' );
function blockusers_init() {
    if ( is_admin() && ! current_user_can( 'administrator' ) &&
         ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
        wp_redirect( home_url() );
        exit;
    }
}

Y estoy usando este código para eliminar publicaciones (portfolio.php):

<a href="<?php echo get_delete_post_link( $post->ID ) ?>">Delete post</a>

He probado algunas otras opciones, pero nunca he podido permitir que los fotógrafos eliminen sus publicaciones (o publicaciones globales porque de todos modos solo pueden ver las suyas)

¡Gracias!

    
pregunta Relisora 01.06.2017 - 15:37

3 respuestas

2

Suponiendo que está hablando de una función de usuario llamada " fotógrafo ", creo que algo como esto debería agregar la capacidad delete_posts a esa función.

function add_delete_cap_to_photog_role() {
    $role = get_role( 'photographer' );

    $role->add_cap( 'delete_posts' );
}
add_action( 'admin_init', 'add_delete_cap_to_photog_role');

Después de agregar los límites a la función, para resolver el resto, cualquiera podría

  1. mantenga blockusers_init y ditch get_delete_post_link para eliminar ajax.
  2. descarte la función blockusers_init y realice una redirección condicional.

Voy a dar algunas ideas sobre cada uno. Prefiero deshacerme de get_delete_post_link en esta instancia.

Varios pasos a continuación, tenga en cuenta que el código se proporciona solo como una guía. Reescriba y cambie el nombre de las cosas según sea necesario.

Eliminar AJAX Ditch get_delete_post_link aka

reemplaza la línea get_delete_post_link con algo como esto:

<?php if( current_user_can( 'delete_post' ) ) : ?>
    <a href="#" data-id="<?php the_ID() ?>" data-nonce="<?php echo wp_create_nonce('ajax_delete_post_nonce') ?>" class="delete-post">delete</a>
<?php endif ?>

Poner en cola algunos JS

en el archivo: functions.php

function delete_post_ajax() {
    wp_enqueue_script(  'delete_ajax', get_template_directory_uri() . '/js/my_script.js', array( 'jquery' ), '1.0.0', true );
    wp_localize_script( 'delete_ajax', 'TheAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}

add_action( 'wp_enqueue_scripts', 'delete_post_ajax' );

Haz clic para pasar los datos para eliminar el método

en el archivo: /js/my_script.js

jQuery( document ).ready( function($) {
    $(document).on( 'click', '.delete-post', function() {
        var id = $(this).data('id');
        var nonce = $(this).data('nonce');
        var post = $(this).parents('.post:first');
        $.ajax({
            type: 'post',
            url: TheAjax.ajaxurl,
            data: {
                action: 'wpse_ajax_delete_post',
                nonce: nonce,
                id: id
            },
            success: function( result ) {
                if( result == 'success' ) {
                    post.fadeOut( function(){
                        post.remove();
                    });
                }
            }
        })
        return false;
    })
})

el método de eliminación

en el archivo: functions.php (el enlace que necesitamos es simplemente " wp_ajax " antes del nombre de action en el archivo js)

add_action( 'wp_ajax_wpse_ajax_delete_post', 'wpse_ajax_delete_post_func' );
function wpse_ajax_delete_post_func(){

    $permission = check_ajax_referer( 'ajax_delete_post_nonce', 'nonce', false );
    if( $permission == false ) {
        echo 'error';
    }
    else {
        wp_delete_post( $_REQUEST['id'] );
        echo 'success';
    }

    die();

}

Para hacer lo anterior pasando uri params:

Cambie el lugar donde cambiamos get_delete_posts_link por esto:

<?php if( current_user_can( 'delete_post' ) ) : ?>
    <?php $nonce = wp_create_nonce('ajax_delete_post_nonce') ?>
    <a href="<?php echo admin_url( 'admin-ajax.php?action=wpse_ajax_delete_post&id=' . get_the_ID() . '&nonce=' . $nonce ) ?>" data-id="<?php the_ID() ?>" data-nonce="<?php echo $nonce ?>" class="delete-post">delete</a>
<?php endif ?>

Vea esto para un tutorial más complejo que explica cada paso

Ditch blockusers_init (también conocido como redirección condicional)

Esto establece una redirección en wp-admin si el usuario no tiene manage_options cap, que es un rol de administrador. Pero primero pseudo-oculta cosas y agrega un mensaje al usuario con algunos css:

El bit CSS

en el archivo: functions.php

add_action('admin_head', 'hide_admin_via_css');
function hide_admin_via_css() {
    if (!current_user_can( 'manage_options' )) {
        echo '<style>body * {visibility:hidden !important;} body:before {content:"Give it a second...";}
';
    }
}

Poner en cola el archivo JS

en el archivo: functions.php

function my_enqueue( $hook ) {
    if (!current_user_can( 'manage_options' )) {
        wp_enqueue_script( 'my_custom_script', get_template_directory_uri() '/js/block-admin.js' );
    }
}
add_action('admin_enqueue_scripts', 'my_enqueue');

Configura el JS para redirigir inmediatamente

archivo: raíz de tema/js/block-admin.js

window.location.href = "/";

O una redirección cronometrada

setTimeout(function () {
   window.location.href = "/";
}, 2000);

Este enfoque proviene de clicknathan, y ofrece más detalles aquí.

    
respondido por el hwl 06.06.2017 - 22:46
1

La respuesta de hwl es correcta, pero agregaré una verificación si el usuario actual es el autor de la publicación.

<?php
$current_user = wp_get_current_user();
if ( $current_user->ID == $post->post_author ) { ?>
    <a href="<?php echo get_delete_post_link( $post->ID ) ?>">Delete post</a>
<?php } ?>

Ya que podría estar agregando la posibilidad de 'delete_posts ', que podría eliminar cualquier publicación, esto podría ser una garantía. < Eso no estaba bien.

De esa manera, el enlace solo aparece en las publicaciones que pueden eliminar, propias.

    
respondido por el socki03 07.06.2017 - 00:03
1

Hay tres requisitos en tu pregunta:

  1. El rol no debe poder iniciar sesión en el backend
  2. El rol debe poder eliminar sus propias publicaciones
  3. Un requisito implícito es que deben poder eliminar las publicaciones publicadas

Es de suponer que tiene un método en el lugar donde el usuario puede publicar y publicar sus publicaciones sin acceso al servidor. Si es así, entonces puedes manipular el rol:

  1. Eliminando la capacidad read
  2. Agregar la capacidad delete_posts
  3. Agregue delete_published_posts capabilty

Dado que el rol no tiene delete_others_posts , no podrán eliminar las publicaciones de otros usuarios, incluso si están publicadas.

Las capacidades de los roles se almacenan en la base de datos, por lo que debe agregarlos y eliminarlos en la activación del tema o del complemento. Aquí hay un complemento de ejemplo que agrega las capacidades requeridas en la activación y las elimina en la desactivación.

/**
 * Plugin Name: WordPress StackExchange Question 268755
 * Description: Allow subscribers to delete their own posts
 **/

//* On activation, add the capabilities to the subscriber role
register_activation_hook( __FILE__, 'wpse_268755_activation' );
function wpse_268755_activation() {
  $photograph = get_role( 'photograph' );
  $photograph->remove_cap( 'read' );
  $photograph->add_cap( 'delete_posts' );
  $photograph->add_cap( 'delete_published_posts' );
}

//* On deactivation, remove the capabilities from the subscriber role
register_deactivation_hook( __FILE__, 'wpse_268755_deactivation' );
function wpse_268755_deactivation() {
  $photograph = get_role( 'photograph' );
  $photograph->remove_cap( 'delete_posts' );
  $photograph->remove_cap( 'delete_published_posts' );
}

Entonces necesitas una forma de eliminar realmente la publicación. Si el usuario tuviera acceso al back-end, podría usar get_delete_post_link .

<a href="<?php echo get_delete_post_link( $post->ID ) ?>">Delete post</a>

Entonces, lo que debe hacer es escribir un javascript que al hacer clic en ese enlace, impida el comportamiento predeterminado y envíe un AJAX Solicitud para eliminar la publicación.

    
respondido por el Nathan Johnson 07.06.2017 - 01:40

Lea otras preguntas en las etiquetas