Excludes posts that don’t have attachments in the_content()

First, please don’t use query_posts() (emphasis mine)!

Note: This function isn’t meant to be used by plugins or themes. As
explained later, there are better, more performant options to alter
the main query. query_posts() is overly simplistic and problematic way
to modify main query of a page by replacing it with new instance of
the query. It is inefficient (re-runs SQL queries) and will outright
fail
in some circumstances (especially often when dealing with posts
pagination). Any modern WP code should use more reliable methods, like
making use of pre_get_posts hook, for this purpose
.

http://codex.wordpress.org/Function_Reference/query_posts

Second, this isn’t going to work:

$gotimages = get_children( array(
  'post_type'      => 'attachment',
  'post_mime_type' => 'image',
  'post_parent'    => get_the_ID()
)),

array(
  'key' => implode(', ', $gotimages),
  'compare' => '='
),

This line…

 'post_parent'    => get_the_ID()

… is probably going to be a problem as it will return the current post ID in the Loop, but your Loop doesn’t start until later. Given how your code is written I think you are trying to construct a kind of sub-query, but it doesn’t work like that.

This line …

'key' => implode(', ', $gotimages),

… will definitely be a problem. $gotimages, if it has results, is going to be an array of objects. When you try to implode that you will get something like:

Catchable fatal error: Object of class WP_Post could not be converted
to string…

Try it with a post ID know to have attachments:

$gotimages = get_children( array(
    'post_type'      => 'attachment',
    'post_mime_type' => 'image',
    'post_parent'    => 1
));
var_dump(implode(', ', $gotimages));

And additionally, I am fairly sure that the key argument of a meta_query does not take a comma delimited string even if that object were to implode() correctly.

Third, get_children() is going to return all attachments, one of which is the featured image, but, additionally, WordPress handles attachments badly and once an image is attached to a post it is hard to unattach it. You will get images that where once displayed in the post body but are no longer displayed. So, logically, even if all of the code worked, what you are attempting won’t work.

In fact, what you are trying to do is tricky and labor intensive as it is going to require a regex on the post body to search for images. If you have galleries involved it become more complicated still.

So, how close can I get you?

I need to do a query of all students with a gallery or attachment in
their content area. NOT their featured image.

This, if I’ve done it right, should get you close to “all students with a gallery or attachment in their content area”:

$args = array( 
  'post_type'      => 'attachment',
  'post_mime_type' => 'image',
  'post_status' => 'inherit',
  'posts_per_page' => -1,
  'post_parent__not_in' => array(0),
  'meta_query' => array(
    array(
      'key' => '_thumbnail_id',
      'value' => 'x',
      'compare' => 'NOT EXISTS'
    )
  ),
  'fields' => 'post_parent'
);
$atts = new WP_Query($args);

$parents = array_unique(wp_list_pluck($atts->posts,'post_parent'));

// get your students posts
$args = array( 
  'post_type' => 'students',
  'post__in' => $parents
);
$students = new WP_Query($args);

// see some results
var_dump($students->request);
var_dump($students->posts);

What it doesn’t do is:

  • Compensate for cases where images where attached and then deleted
    from the post body. Those will still show up.
  • And cases where images where manually written into the post body.
    Those will not show up.

Your other option would be to search your post type for some plausibly identifiable string:

$args = array( 
  'post_type' => 'students',
  's' => '<img '
);
$students = new WP_Query($args);

I am not sure how robust that will be but it does return some reasonable results when I try it.

Leave a Comment