Set a maximum upload count for users on a specific user role

For users with the Contributor user role, I want to restrict the total amount of images that they are allowed to upload. I found this code posted on an answer here:

add_filter( 'wp_handle_upload', 'wpse47580_update_upload_stats' );
function wpse47580_update_upload_stats( $args ) {

    $user_id = get_current_user_id();

    $upload_count = get_user_meta( $user_id, 'upload_count', $single = true );

    update_user_meta( $user_id, 'upload_count', $upload_count + 1 );
}

add_filter( 'wp_handle_upload_prefilter', 'wpse47580_check_upload_limits' );
function wpse47580_check_upload_limits( $file ) {
    $user_id = get_current_user_id();

    $upload_count = get_user_meta( $user_id, 'upload_count', $single = true );

    $upload_count_limit_reached = apply_filters( 'wpse47580_upload_count_limit_reached', 10 ) > ( $upload_count + 1 );

    if ( $upload_count_limit_reached  )
        $file['error'] = 'Upload limit has been reached for this account!';

    return $file;
}

There are two problems. Firstly, the above code does not function properly, it is supposed to allow 10 uploads but the upload limit message is displayed no matter what. Secondly, it applies to all user roles.

Upon further research, I found this working answer, but the solution applies for total uploads per post, not user.

How can I set an upload count limit for users on a specific user role? Ideally with a solution that deducts the count if user permanently removes an uploaded image.

3 Answers
3

I’m not really sure which is the real problem with code you posted, however I cant understand why use 2 functions when one is enough…

add_filter( 'wp_handle_upload_prefilter', 'limit_uploads_for_user_roles' );

function limit_uploads_for_user_roles( $file ) {
  $user = wp_get_current_user();
  // add the role you want to limit in the array
  $limit_roles = array('contributor');
  $filtered = apply_filters( 'limit_uploads_for_roles', $limit_roles, $user );
  if ( array_intersect( $limit_roles, $user->roles ) ) {
    $upload_count = get_user_meta( $user->ID, 'upload_count', true ) ? : 0;
    $limit = apply_filters( 'limit_uploads_for_user_roles_limit', 10, $user, $upload_count, $file );
    if ( ( $upload_count + 1 ) > $limit ) {
      $file['error'] = __('Upload limit has been reached for this account!', 'yourtxtdomain');
    } else {
      update_user_meta( $user->ID, 'upload_count', $upload_count + 1 );
    }
  }
  return $file;
}

Note that the count start when you add the function and the filter: all previous uploaded files are not counted.

The roles to limit can be altered also via filter.

The limit can be changed via filter (default 10 in my code) and I also pass to filter the user object and the current number of user uploads, in this way the filter can take into accounts more informations…

Edit

To decrease the count when a contributor delete an attachment hook delete_attachment and do some logic:

add_action('delete_attachment', 'decrease_limit_uploads_for_user');

function decrease_limit_uploads_for_user( $id ) {
   $user = wp_get_current_user();
   // add the role you want to limit in the array
   $limit_roles = array('contributor');
   $filtered = apply_filters( 'limit_uploads_for_roles', $limit_roles, $user );
   if ( array_intersect( $limit_roles, $user->roles ) ) {
     $post = get_post( $id);
     if ( $post->post_author != $user->ID ) return;
     $count = get_user_meta( $user->ID, 'upload_count', true ) ? : 0;
     if ( $count ) update_user_meta( $user->ID, 'upload_count', $count - 1 );
   }
}

Note that previous code do not prevent attachment being deleted was uploaded by other users, because this should be handled by the functions/plugin/code that allow contributors to upload files (once by default they can’t do that) and because the 'delete_attachment' hook happens after the attachment was already deleted.
However if the attachment was not uploaded by current user the decrease isn’t performed, just for sure…

Leave a Comment