4

am using this function to delete post from front

// Delete from Front-End Link

function wp_delete_post_link($link = 'Delete This', $before = '', $after = '', $title="Move this item to the Trash", $cssClass="delete-post") {
    global $post;
    if ( $post->post_type == 'page' ) {
        if ( !current_user_can( 'edit_page' ) )
            return;
    } else {
        if ( !current_user_can( 'edit_post' ) )
            return;
    }
    $delLink = wp_nonce_url( site_url() . "/wp-admin/post.php?action=trash&post=" . $post->ID, 'trash-' . $post->post_type . '_' . $post->ID);
    $link = '<a class="' . $cssClass . '" href="' . $delLink . '" onclick="javascript:if(!confirm(\'Are you sure you want to move this item to trash?\')) return false;" title="'.$title.'" />'.$link."</a>";
    return $before . $link . $after;
}

its work 100% but am using function to restrict no admin to access wp-admin, using this function :

function restrict_admin(){
//if not administrator, kill WordPress execution and provide a message
    if ( ! current_user_can( 'create_users' ) ) {
        wp_die( __('You are not allowed to access this part of the site') );
    }
}
add_action( 'admin_init', 'restrict_admin', 1 );

my problem , how can i allow user ( not admin ) to delete his post own post ?

3
+25

If you like, that users only can delete his own post, then it is important, that check for the ID of the user and the Author-ID to the post. The follow source example add a Trash button to the admin bar, that the users can easily delete his own post.

The key is the function get_queried_object(). This object stored all values to the post on the front end and you can check to the user id, there is logged in - get_current_user_id(). Also important for a strict comparison is, that you set all values to the same type, like integer.

Also is it possible to use the WP core function current_user_can() with the second param to identifier the rights to each post: current_user_can('edit_post', 123) this check the capability to the post with the ID 123. Maybe a little bid easier as the check about the author object and the post object.

Also useful in my example, that you nit must use the global $post.

add_action( 'admin_bar_menu', 'fb_add_admin_bar_trash_menu', 35 );
function fb_add_admin_bar_trash_menu() {

  if ( ! is_super_admin() || ! is_admin_bar_showing() )
      return;

  $current_object = get_queried_object();

  // check, is the objekt with the value readable
  if ( ! isset( $current_object->post_author ) )
      return;

  // check, if the user id the same as the author-id if the current post
  if ( (int) $current_object->post_author !== (int) get_current_user_id() )
      return;

  if ( empty( $current_object ) )
      return;

  if ( ! empty( $current_object->post_type ) && 
     ( $post_type_object = get_post_type_object( $current_object->post_type ) ) && 
     current_user_can( $post_type_object->cap->edit_post, $current_object->ID ) 
  ) {
    global $wp_admin_bar;

    $wp_admin_bar->add_menu( 
        array(
            'id'    => 'delete', 
            'title' => __( 'Move to Trash' ), 
            'href'  => get_delete_post_link( $current_object->term_id ) 
        ) 
    );
  }
}

For the non access to the admin area of non admin is it easier to write a small function include a rewrite, not a hard die. Use the WordPress function wp_redirect() to rewrite to a specific url or frontend.

add_action( 'admin_init', 'fb_redirect_to_frontend' );
function fb_redirect_to_frontend() {

    if ( ! current_user_can( 'remove_users' ) )
        wp_redirect( site_url() );
}
  • beultge - if you're redirecting users away from the admin area (or using die() for that matter) then get_delete_post_link() won't work. I think that is the original poster's issue. See my solution which allows access to the admin area if the action is set to 'trash' – henrywright Jan 6 '14 at 17:57
  • Yes, I have see your solution for check the globals. But I have understand the question, that he now will, that the users got to back end side. I think a redirect is the better way for close the backend, more secure for all back end pages. But I have not tested the get_delete_post_link() with the rewrite, right and fine hint. But also it is possible to include in the rewrite function your check for the globals. – bueltge Jan 6 '14 at 19:59
  • Definitely agreed a redirect is better than die(). That said - the original question was more to do with get_delete_post_link() not working due to disallowing access to the back-end for users. Making an allowance for 'trash' actions resolves that. Perhaps a combination of both of our answers makes a great approach? :) – henrywright Jan 6 '14 at 20:26
  • 1
    Right, useful for other readers on the post. – bueltge Jan 6 '14 at 20:28
2

The solution to this is to modify your restrict admin function to allow for certain circumstances.

function restrict_admin() {

    // Bail if a user is trying to trash a post.
    if ( isset( $_GET[ 'action'] ) && 'trash' == $_GET[ 'action'] )
        return;

    // Kill execution if not an administrator.
    if ( ! current_user_can( 'create_users' ) )
        wp_die( __( 'You are not allowed to access this part of the site' ) );
}
add_action( 'admin_init', 'restrict_admin', 1 );
  • it's all correct, just a small improvement could be that you take the additional condition if ( isset( $_GET[ 'action'] ) && 'trash' == $_GET[ 'action'] ) before curent_user_can check, that would be more appropriate as in any case if it's a delete link you don't want to proceed. It hardly matters but still I'd suggest. Cheers..! – sven Jan 6 '14 at 7:21
  • Yeah, make Sven's change, but thanks henrywright. I was grinding on non-existent cap issues. – shanebp Jul 30 '14 at 18:03
1

How about changing the user's role as author?? Doing this, the user will have the edit_post capability but only for the post they have created not for other's post.

0

You can use the capability delete_published_posts and delete_published_pages to provide the facility. This capability is provided to Author and upwards by default. This means whether the user can delete his published post(as you are deleting post from front end, so it must be published post).

You can check it like this.

if (!current_user_can('delete_published_posts') {
    return;
}

if (!current_user_can('delete_published_pages') {
    return;
}
  • This doesn't work if you're blocking access to the back end (which is the question i think). – henrywright Jan 8 '14 at 13:05
0

If you need to have very fine-grained permissions checking, you can filter the user_has_cap result. WordPress calls that function whenever it checks for permissions.

You use it like this:

add_filter ('user_has_cap', 'your_function', 10, 3);

function your_function ($allcaps, $caps, $args) {
    if ($allow_this_action == true)
        return $allcaps;
    elseif ($allow_this_action == false) {
        $allcaps[$caps[0]] = false;
        return $allcaps;
    }
}

When a post is being deleted, $args is set to array ('delete_post', $user_id, $post_id). The capabilities required to allow the deletion are stored in the array $caps, and will vary depending on what type of post is being deleted (e.g. ‘delete_published_posts’). Each capability in $caps corresponds to an item in $allcaps. To prevent the post being deleted, all we need to do is modify $allcaps by setting one of the values listed in $caps to false (e.g. $allcaps[$caps[0]] = false).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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