web-dev-qa-db-ja.com

役割に投稿の削除を許可するが、彼にはwp-adminをブロックさせる

私はカスタムユーザーロールを持っています:写真。

このロールはバックオフィスにログインすることはできませんが、フロントエンドから自分の投稿を削除することができる必要があります。

このコードを使用して、管理者以外のすべてのユーザーがバックオフィスに接続できないようにします(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;
    }
}

そして私は投稿を削除するためにこのコードを使っています(portfolio.php):

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

他の方法をいくつか試しましたが、写真家に自分の投稿を削除することを許可することはできませんでした。

ありがとうございました !

2
Relisora

あなたがカスタムユーザroleという名前の "photographer")について話していると仮定すると、私はこのようなものがその役割にdelete_posts機能を追加するべきだと思います。

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');

役割に上限を追加した後、残りを解決するには、次のいずれかを実行します。

  1. ajaxを削除する場合はblockusers_initを残し、get_delete_post_linkを捨ててください。
  2. blockusers_init関数を捨てて条件付きリダイレクトを行います。

それぞれについていくつかアイデアを出します。この場合はget_delete_post_linkを捨てることを好みます。

以下のいくつかのステップ。コードはガイドとしてのみ提供されています。必要に応じて書き換えて名前を変更してください。


get_delete_post_link別名AJAX削除

get_delete_post_link行を次のように置き換えます。

<?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 ?>

JSをエンキューする

ファイル内: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' );

onClickをクリックして、削除メソッドにデータを渡します

ファイル内:/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;
    })
})

削除メソッド

functions.php(必要なフックは、jsファイルのactionの名前の前に「wp_ajax」を付けるだけです)

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();

}

Uri paramsを渡して上記を実行するには:

このためにget_delete_posts_linkを置き換えた場所を変更します。

<?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 ?>

これを参照してください 各ステップを説明するより複雑なチュートリアル


blockusers_init別名条件付きリダイレクト)

ユーザーが管理者ロールであるmanage_options capを持っていない場合、これはwp-adminにリダイレクトを設定します。しかし、最初にそれはものを疑似隠して、いくつかのcssでユーザーにメッセージを追加します:

_(CSSビット

ファイル内: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...";}
';
    }
}

JSファイルのエンキュー

ファイル内: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');

JSをただちにリダイレクトするように設定

ファイル:theme_root/js/block-admin.js

window.location.href = "/";

OR時限リダイレクト

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

このアプローチ clicknathanから来ました、そして彼はここでより詳細を提供します。

3
hwl

hwlの答えは正しいですが、現在のユーザーが投稿の作者であるかどうかを確認するつもりです。

<?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 } ?>

投稿を削除する可能性がある'delete_posts 'の機能を追加する可能性があるので、これは保護手段となる可能性があります。 <そうではありませんでした。

そうすれば、リンクは自分が削除できる投稿にしか表示されません。

1
socki03

質問には3つの要件があります。

  1. ロールはバックエンドにログインできないはずです
  2. ロールは自分の投稿を削除できるはずです
  3. 暗黙の要件は、彼らが公開された投稿を削除できるべきであるということです

おそらく、バックエンドにアクセスしなくてもユーザーが自分の投稿を投稿および公開できるような方法があります。もしそうなら、あなたはそれによって役割を操作することができます:

  1. read機能を削除する
  2. delete_posts機能を追加する
  3. delete_published_postsの機能を追加する

このロールにはdelete_others_postsがないため、他のユーザーが投稿した投稿を削除することはできません - たとえ公開されていても。

ロール機能はデータベースに格納されているため、プラグインまたはテーマのアクティブ化時にそれらを追加および削除する必要があります。これは、アクティベーション時に必要な機能を追加し、非アクティベーション時にそれらを削除するサンプルプラグインです。

/**
 * 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' );
}

その後、実際に投稿を削除する方法が必要です。ユーザーがバックエンドにアクセスできる場合はget_delete_post_linkを使用できます。

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

そのため、リンクをクリックするとデフォルトの動作が妨げられ、 _ ajax _ というリクエストを送信して投稿を削除するようなJavaScriptを記述する必要があります。

1
Nathan Johnson