Users can’t upload images on frontend if they haven’t got access to the wp backend

I let users create posts and upload/attach images to that post via the frontend. This works fine. However, when I restrict the access to the WordPress backend (/wp-admin/) via a code snippet like this one

function wpse_11244_restrict_admin() {
    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( __('You are not allowed to access this part of the site') );
    }
}
add_action( 'admin_init', 'wpse_11244_restrict_admin', 1 );

or (EDIT) with a redirect code

Read More
function redirect_non_admin_users() {
    if ( ! current_user_can( 'manage_options' ) && '/wp-admin/admin-ajax.php' != $_SERVER['PHP_SELF'] ) {
        wp_redirect( home_url() );
        exit;
    }
}
add_action( 'admin_init', 'redirect_non_admin_users' );

the Media Upload does not work anymore (“Error” Message). This problem has been discussed elsewhere:

I figured out that if the role didn’t have that access [to the backend], it also killed
their ability to upload files on the front end.

Is there a way to prevent users to access the backend without killing their ability to upload images on the frontend?

Thank you!

Related posts

Leave a Reply

2 comments

  1. First, it is important to consider why you are restricting access to wp-admin. If you are doing this mainly for aesthetic purposes, then the solution provided below is fine. However, if you are doing it because you don’t want your users to be able to perform certain functions provided via the back-end, you should be using WordPress’s built-in roles and capabilities API instead. Give your users a role with only those capabilities that you want them to have. Otherwise, granting access to the Ajax actions will probably allow them to do things that you were trying to prevent them from doing.

    Which brings us to the cause of your problem. Ajax is involved in uploading the image, and the Ajax handler (wp-admin/admin-ajax.php) is technically back-end, even when called from the front end. So your code hooked to 'admin_init' is being triggered. What you need to do is check if the request is an Ajax request in that function, and only exit/redirect if it is not. Since WP 4.7, you can now use the wp_doing_ajax() function for this.

    function redirect_non_admin_users() {
        if ( wp_doing_ajax() ) {
            return; // Don't block Ajax requests.
        }
    
        if ( ! current_user_can( 'manage_options' ) && '/wp-admin/admin-ajax.php' != $_SERVER['PHP_SELF'] ) {
            wp_redirect( home_url() );
            exit;
        }
    }
    add_action( 'admin_init', 'redirect_non_admin_users' );
    

    If you only want to allow your users access to uploading attachments, you could probably change the condition to this:

        if ( wp_doing_ajax() && isset( $_POST['action'] ) && 'upload-attachment' === $_POST['action'] ) {
            return; // Don't block attachment upload requests.
        }
    

    However, note that many plugins provide their own Ajax actions as well, which would be blocked in this case. So you will be better off using the role and capability API, as stated above.

  2. Keeping it simple, there are two plugins that I use to achieve the same thing you seek effectively:

    1. WP Admin No SHow : https://wordpress.org/plugins/wp-admin-no-show/

    2. Redirect After Login: https://wordpress.org/plugins/redirect-after-login/

    The first option allows you to select multiple roles and redirect them when they seek to access wp-admin
    The second option gives you the option to redirect individual roles when they login.

    Hope this helps.