5

I want to prevent users from being able to set a Featured Image from the media library if its width is less than 100px. Originally I thought to use the ajax_query_attachments_args filter, but it filters a WP_Query() object which effectively cannot be used for this purpose because the meta_query's meta_key—which is _wp_attachment_metadata—contains serialized data. This is what I'm currently trying:

function restrict_media_library_by_width($response, $attachment, $meta) {
  if(isset($response['width']) && isset($response['height']) && $response['width'] >= 100) {
    return $response;
  }
  return false;
}
add_filter('wp_prepare_attachment_for_js', 'restrict_media_library_by_width', 10, 3);

The result I see is that the Media Library modal pops up, loads an "empty" thumbnail, and the AJAX loader continues intermittently appearing and disappearing:

enter image description here

However, if I change the last conditional in my if statement to use == instead of >= then it appears to work as expected for certain values:

function restrict_media_library_by_width($response, $attachment, $meta) {
  if(isset($response['width']) && isset($response['height']) && $response['width'] == 100) {
    return $response;
  }
  return false;
}
add_filter('wp_prepare_attachment_for_js', 'restrict_media_library_by_width', 10, 3);

It doesn't always work but I suspect I'm missing something here. Can someone please shed some light on this? Thanks!

  • 1
    You should consider filing a core ticket. I tested your snippet and got some weird behavior too, that included a blank list item and an infinite request loop. This #31116 ticket might be related, but changing floor() to round() in media-models.min.js didn't fix the issue you describe. We also have to make sure we don't have plugins that are using this filter, like the ACF. In that case we have to increase the priority number. Otherwise the array_filter( $posts ) part won't strip out the empty items. – birgire Mar 9 '15 at 11:34
  • 1
    ps: on another install, I got the blank item in the first image row and infinite request loop, only when I scrolled down to the bottom of the media library, when choosing a featured image. – birgire Mar 9 '15 at 11:40
  • 1
    Thanks for confirming. Bug submitted as #31570. – cfx Mar 9 '15 at 13:49
2

So far, the only workable solution I've come up with is to run a new query within the ajax_query_attachments_args filter.

It's definitely not ideal but works as expected in the absence of a more efficient alternative:

function restrict_media_library_by_width($query) {
  $include = array();
  $exclude = array();
  $temp_query = new WP_Query($query);
  if($temp_query->have_posts()) {
    while($temp_query->have_posts()) {
      $temp_query->the_post();
      $meta = wp_get_attachment_metadata(get_the_ID());
      $meta['mime-type'] = get_post_mime_type(get_the_ID());
      if(isset($meta['mime-type']) &&
        ($meta['mime-type'] == 'image/jpeg' && isset($meta['width']) && $meta['width'] >= 100) ||
         $meta['mime-type'] == 'image/svg+xml') {
        $include[] = get_the_ID();
      } else {
        $exclude[] = get_the_ID();
      }
    }
  }
  wp_reset_query();

  $query['post__in']     = $include;
  $query['post__not_in'] = $exclude;

  return $query;
}
add_filter('ajax_query_attachments_args', 'restrict_media_library_by_width');

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.