3

I have some trouble with WordPress and the WP_Query. I would like to get posts filtered by meta_query and/or category, but I have the following problem: The first type of posts has a custom field named "type" which must be filled with "exercise" and the post has to be in a category named "Level" (this will be set before). The second type of posts has only the custom field named "type" which must be filled with "test".

I don't know how to get these two conditions together. Because of that I've tried to split it into two Queries, and merge it afterward, like this:

$firstArgs = array(
        'posts_per_page'=> -1,
        'category_name' => $level,
        'meta_key'      => 'duration',
        'orderby'       => 'meta_value_num',
        'order'         => 'DESC',
        'meta_query' => array(
             'key' => 'type',
             'value' => 'exercise'
        )     
);

$secondArgs = array(
        'posts_per_page' => -1,
        'meta_key'       => 'duration',
        'orderby'        => 'meta_value_num',
        'order'          => 'DESC',
        'meta_query' => array(
             'key' => 'type',
             'value' => 'test'
        )
);
$first_query = new WP_Query( $firstArgs );
$second_query = new WP_Query( $secondArgs );
$result = new WP_Query();
$result->posts = array_merge($first_query->posts, $second_query->posts);

The Problem with this method is, that I would like to sort the posts by the custom field "duration" DESC. If I merge these two arrays, the sorting isn't that way I would like to.

Does anyone know a better way of doing this? If it would be one query, the sorting would work and I think it is more efficient.

Thanks for your help!

2 Answers2

1
$firstArgs = array(
        'posts_per_page'=> -1,
        'category_name' => $level,
        'meta_key'      => 'duration',
        'orderby'       => 'meta_value_num',
        'order'         => 'DESC',
        'meta_query' => array(
             'key' => 'type',
             'value' => 'exercise'
        )     
);

$secondArgs = array(
        'posts_per_page' => -1,
        'meta_key'       => 'duration',
        'orderby'        => 'meta_value_num',
        'order'          => 'DESC',
        'meta_query' => array(
             'key' => 'type',
             'value' => 'test'
        )
);

$firstArgs = get_posts($firstArgs);
$secondArgs = get_posts($secondArgs);
$your_posts = array_unique(array_merge($firstArgs,$secondArgs),SORT_REGULAR);

_e('<pre>');
print_r($your_posts);   
_e('</pre>');

For your better understanding visit here

Dhruv
  • 612
  • 7
  • 15
  • Thank you for your answer, but unfortunately, it isn't working as I would like to. Let's say: the firstArgs Query returns three posts - Post A (duration: 30 min), Post B (duration 10 min) and Post C (duration: 5 min). The second query gives you two posts: Post D (duration 40 min) and Post E (duration: 10 min). The result should be in this order: Post D, A, B, E, C (because I want to order by duration). Or do I have a thinking error? –  Nov 22 '19 at 07:21
  • @noobhoch100 have you tried with print_r($firstArgs); what is the output.? – Dhruv Nov 22 '19 at 07:53
  • The output with $firstArgs is correct. This query gives all posts from the category "level" with the custom field type="exercise". And these posts were sorted by duration (Post A, B, C - in the previous example). The second one is correct as well, but if I merge these two, the posts won't be sorted again. But that's the point I. :-( Post A, B, C and post D, E will be merged to A, B, C, D, E and not D, A, B, E, C. –  Nov 22 '19 at 15:07
0

I found an answer that worked for me. First of all, I retrieve the data as Dhruv told me and then, I sorted the result with the usort-function, but with an anonymous function.

usort($your_posts, function($a, $b)
{
      $val1 = get_post_meta($a->ID, 'duration', true );
      $val2 = get_post_meta($b->ID, 'duration', true );
      return  -1*($val1 - $val2); // sort desc
});

Maybe it is not the best method, but it worked for me. :-)