Categorize meta data from a get_results call in WordPress (Part 2)

This is part 2: Check out Part 1, where I detail how to reduce 101 database calls to just 2.

In a previous article I wrote about how do reduce 101 database calls to just one, simply by using a bit of SQL instead of standard get_posts and get_post_meta. In this article, I’m going to focus mostly on how to consume the results of the array that we get back from that function.

First of all, a short recap. We were trying to get specific fields from all the product post types to display on a page. Since no magical unicorn function like get_multiple_posts_meta exists to get all the meta for multiple posts, we had to resort to using SQL. Finally, when we got the data, if we output it with print_r it looks something like this:

Array
(
    [0] => stdClass Object
        (
            [post_id] => 1234
            [meta_key] => product_profile
            [meta_value] => http://docs.example.com/path/to/doc.pdf
        )
    [2] => stdClass Object
        (
            [post_id] => 1239
            [meta_key] => research_info
            [meta_value] => http://docs.example.com/path/to/doc.pdf
        )
    [3] => stdClass Object
        (
            [post_id] => 1234
            [meta_key] => product_profile_description
            [meta_value] => Description of the file goes here 
        )
    [3] ... and so on ...

Since we effectively want to group all the different kinds of documents together, we’ll need to rearrange this array. Let’s get started. For starters, we know that any field that is a URL does NOT end in _description.

foreach( $document_fields as $d ) {
  // If meta_key is NOT a description field, it should be URL
  $description_position = strpos( $d->meta_key, '_description' );
  $is_url_field = $description_position === FALSE;
    if( $is_url_field ) {
      // ...code here
    }
}

We’re not doing anything really special here. Just looping through the results and checking to see if it contains _description. If it doesn’t, then we perform some logic on it. We care mostly about the url field. If, for some reason the url field is empty and the description field is not, we don’t want to display it.

  $categorized_docs[ $d->meta_key ][ $d->post_id ][ 'url' ] = $d->meta_value;
}
else {
      // Get the name of the category by stripping of _description from end
  $category_name = substr( $d->meta_key, 0, $description_position );

// Add document name to appropriate area of array:
$categorized_docs[ $category_name ][ $d->post_id ][ 'title' ] = $d->meta_value;

And now that you have your categorized meta data you can simply loop through the $categorized_docs array or call a specific subset of it to output as you wish. If you used standard WordPress methods, you’d be looping through posts and then getting post meta for each post, which is wasteful and SLOW. Although it’s a bit more work, using the techniques in this post and the previous post which details how to get the meta data in just 2 round trips to the database you reduce 1000s of posts to just 2.

Happy optimizing!

 

Leave a Reply

Your email address will not be published. Required fields are marked *