Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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

How to restrict dashboard access to Admins only?

share|improve this question
4  
How do the authors write the posts? –  toscho Jan 3 '13 at 20:55
    
I've created a submit form on the front end that allows users to add a post. When the form is submitted it runs a script that uses wp_insert_post(). –  clampdesign Jan 4 '13 at 20:18
1  
Toscho, this got me thinking that I should try to create a function using a similar method to the insert post function on my submit form to delete the post and it worked like a charm. Thanks for getting me to think about this a little differently! –  clampdesign Jan 4 '13 at 20:21
1  
Good to see you found a way. :) May I ask you to share your solution with us? Write an answer ↓, collect upvotes. –  toscho Jan 4 '13 at 20:27

2 Answers 2

up vote 1 down vote accepted

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 );
}
share|improve this answer

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 );
share|improve this answer
    
Unfortunately, this doesn't work either. It still redirects me when I try to delete a post as an author. –  clampdesign Jan 4 '13 at 20:15
    
@clampdesign I believe it works exactly as I intended it, and furthermore fulfills the parameters of your question. Author users will still be redirected because a successful post deletion request sent to wp-admin/post.php?action=delete will redirected to wp-admin/edit.php. As access to edit.php has been entirely restricted from the Author user role by this very block of code, they are immediately kicked back to home_url(). Regardless of the redirect, I think you'll find that the post has indeed been successfully deleted. –  boscho Jan 7 '13 at 17:21
    
Adding a case to check if the page is wp-admin/edit.php in order to redirect to your choice of URL after a successful deletion is a minor modification. I have appended the necessary edits to do so. –  boscho Jan 7 '13 at 17:21
    
I did try this and it did not delete the post, unfortunately. –  clampdesign Jan 9 '13 at 23:46
    
Strangeness my friend - it works on my end. Sorry to hear it, but glad you found a functional solution :) –  boscho Jan 10 '13 at 16:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.