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

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