Restrict dashboard access for specific user roles to specific actions

I have a script that enables a logged in user (role Author) to delete their own posts using get_delete_post_link(). However, I also want to be able to restrict the author’s access to the dashboard. Any attempt to do so using a plugin (Theme my Login, for example) or a simple script like those linked below disables my ability to use get_delete_post_link(). Is there a way to restrict access to the dashboard for the “Author” user role while still permitting the deletion of posts via get_delete_post_link()?

http://www.tutorialstag.com/restrict-wordpress-dashboard-access.html

Read More

How to restrict dashboard access to Admins only?

Related posts

Leave a Reply

2 comments

  1. This is how I ended up solving this issue. Originally I used this code for the link to delete an individual post:

    <?php if( !(get_post_status() == 'trash') ) : ?>
    <a class="delete-post" onclick="return confirm('Are you sure you wish to delete post: <?php echo get_the_title() ?>?')"href="<?php echo get_delete_post_link( get_the_ID() ); ?>">Delete</a>
    <?php endif; ?>
    

    After checking to see if the user was logged in and if the user was the author of this post. This didn’t work as mentioned in my original post.

    Instead I used a simple delete button (with the same checks as mentioned above):

    <form class="delete-post" action="<?php bloginfo('url'); ?>/edit-post" method="post"> 
        <input id="post_id" type="hidden" name="postid" value="<?php the_ID(); ?>" /> 
        <input type="submit" value="Delete" />
    </form>
    

    and this jQuery script to make an ajax call that will run my php script:

    jQuery(document).ready(function($){  
        $('.delete-post').bind('click', function(e){
    
            e.preventDefault();
    
            var post_id;
            post_id = $("#post_id").val();
            var data = {};
            var obj = {data: data}; 
            data['post_id'] = post_id;
    
            alert('Are you sure you wish to delete this post?');
            process_delete_post();
    
            function process_delete_post() {
                jQuery.ajax({
                    type: "POST",
                    url: run_delete_post.ajaxurl,
                    data: ({
                        post_id : data['post_id'],
                        action : 'run_delete_post_script',
                    }),
                    success: function() {
                         location.href = "";
                    },
    
                    error: function(jqXHR, exception) {
                        if (jqXHR.status === 0) {
                            alert('Not connect.n Verify Network.');
                        } else if (jqXHR.status == 404) {
                            alert('Requested page not found. [404]');
                        } else if (jqXHR.status == 500) {
                            alert('Internal Server Error [500].');
                        } else if (exception === 'parsererror') {
                            alert('Requested JSON parse failed.');
                        } else if (exception === 'timeout') {
                            alert('Time out error.');
                        } else if (exception === 'abort') {
                            alert('Ajax request aborted.');
                        } else {
                            alert('Uncaught Error.n' + jqXHR.responseText);
                        }
                    }
    
                });
            }   
    
        }); 
    
    }); 
    

    In my functions.php file, I set up my ajax call:

    function mytheme_delete_post() {
        if ( is_page_template( 'edit-delete-posts.php' ) ) {
            wp_enqueue_script( 'process-delete-post', get_template_directory_uri().'/js/process-delete-post.js', array('jquery'), true);
            wp_localize_script( 'process-delete-post', 'run_delete_post', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
            }
    }
    add_action('template_redirect', 'mytheme_delete_post');
    
    $dirName = dirname(__FILE__);
    $baseName = basename(realpath($dirName));
    require_once ("$dirName/functions_custom.php");
    
    add_action("wp_ajax_run_delete_post_script", "run_delete_post_script");     
    

    And then, the actual php script to delete the post in my functions_custom.php file:

    function run_delete_post_script() {
        // Test for current user
        mytheme_get_current_user();
    
        //Get the data from the submit page and convert to php variables
        foreach ($_POST as $field => $value) {
            if (isset($_POST[$field])) {
                $$field = $value;
            }
        }
        wp_delete_post( $post_id );
    }
    
  2. How about a targeted redirect when an Author attempts to view the dashboard?

    function restrict_dashboard_access() {
        //Leave AJAX requests alone - their life is hard enough without further scrutany
        if( $_SERVER['PHP_SELF'] == '/wp-admin/admin-ajax.php' )
            return;
    
        if( $_SERVER['PHP_SELF'] == '/wp-admin/post.php' && isset( $_REQUEST['action'] ) ) {
            switch( $_REQUEST['action'] ) {
                case 'trash': //Leave alone requests to delete posts,
                case 'delete'://such as those generated by get_delete_post_link()
                    return;
            }
        }
    
        //For all other admin requests,
    
        //redirect users of the 'author' role to the home_url
        $user = get_userdata( get_current_user_id() );
        if( in_array( 'author', $user->roles ) ) {
            wp_redirect( home_url() );
            exit;  //Force script death to avoid useless script execution post-redirect
        }
    }
    add_action( 'admin_init', 'restrict_dashboard_access', 1 );
    

    (Hacked together from your linked resources and the WP Codex page for the admin_init action)

    EDIT: How to implement post-deletion redirect to a specific URL in light of the additional information provided in the comments:

    function restrict_dashboard_access() {
        //Leave AJAX requests alone - their life is hard enough without further scrutany
        if( $_SERVER['PHP_SELF'] == '/wp-admin/admin-ajax.php' )
            return;
    
        if( $_SERVER['PHP_SELF'] == '/wp-admin/post.php' && isset( $_REQUEST['action'] ) ) {
            switch( $_REQUEST['action'] ) {
                case 'trash': //Leave alone requests to delete posts,
                case 'delete'://such as those generated by get_delete_post_link()
                    return;
            }
        }
    
        //For all other admin requests, redirect users of the 'author' role
        $user = get_userdata( get_current_user_id() );
        if( in_array( 'author', $user->roles ) ) {
    
            if( $_SERVER['PHP_SELF'] == '/wp-admin/edit.php' && ( isset( $_REQUEST['trashed'] ) || isset( $_REQUEST['deleted'] ) ) ) {
                // If an Author has just deleted a post - redirect them to a specific URL.
                wp_redirect( home_url() . '/post-deleted-page' );
            } else {
                // If an Author is viewing any other admin page, drop them back to the homepage
                wp_redirect( home_url() );
            }
    
            exit;  //Force script death to avoid useless script execution post-redirect
        }
    }
    add_action( 'admin_init', 'restrict_dashboard_access', 1 );