arrayswordpressmeta-key

Wordpress meta_values in array don't work


I would like someone to help me.

My first problem: The meta_value in array don't work in my function:

'value' => array('English','Spain','German','French'),

It works with one single value, but more value in an array is not working. It simply ignores my array.

My second problem: I would like to list the items in order of sort: 'English', 'Spain', 'German', 'French' after that sorted by 'ratings_score' and after that sorted by "modified". But according to the countries I can only list in alphabetical order. In this line, I'd like to list 'English', 'Spain', 'German', 'French', but ignore it.

Can someone help me with what's wrong?

Here is my function:

function ta_modify_main_query($query) {
      if ( $query->is_main_query() && ( $query->is_home() || $query->is_search() || $query->is_archive() )  ) {

    {
     $query->set('meta_query', array(
            'country' => array(
                'key' => 'country',
                'value' => array('English','Spain','German','French'),
                ),
            'ratings_score' => array(
                    'key' => 'ratings_score',
                ),
            ));
            $query->set('orderby',array(
                'country' => 'ASC', 
                'ratings_score' => 'DESC',
                'modified' => 'DESC'
            ));     
        }

  return $query;       
  }
}
add_action( 'pre_get_posts', 'ta_modify_main_query' );

Solution

  • meta_query

    You're trying to compare a value to an array. The MySQL wrappers in WP don't do this. Change your meta_query set query to this:

    array(
      'key' => 'country'
      'value' => array('English','Spain','German','French'),
      'compare' => 'IN'
    ),
    array(
      'key' => 'ratings_score',
      'compare' => 'EXISTS'
    )
    

    I assumed that you're including the ratings_score meta query because you want to see if it exists or not. If you're trying to check something else, change the compare (and maybe add a value to the query).

    Ordering

    Unfortunately, you cannot use a non-alphabetic ordering on a data set where you only have alphabetic data. You're essentially asking for some way for MySQL to, "know," what order you want it in.

    Ordinarily, with a flat query like in the loop, your best way to order to your specifications is probably to re-order the data after you get them. Since you're working in a declarative scope (basically, SQL), you'll need to do something different.

    Probably the simplest and (as is often the case) worst way to do it is to change your data so that they read ['1English', '2Spain', '3German', '4French'], then cut off the first character anytime you need to use the name. This is truly awful (especially for someone like me with CDO who believes that non-3NF data is evil) but it'll get you to the quickest solution.

    The cleanest and a more normalized way to do it is to join in an order that's keyed correctly. This would probably mean that for each post, you'd have to add a second key, next to country, like country_order, with the value. A post with 'country' = 'English' would have 'country_order' = '1', 'country' = 'German' would have 'country_order' = '3', and so on. Then simply order on country_order. This is probably your best solution although you'll have to maintain parallel metadata for each post.

    The cleanest and most difficult (read: disaster-prone) solution is to hook on WP query generation, look for country meta queries and patch in the data you need. Ask if you need to do it this way; it's neither straightforward nor easily maintainable so I'm not going to list it without explicit need.

    As an aside

    English, German and French are not countries. Countries are denoted by nouns. Those are languages or nationalities (and some other things), hence they are adjectives. Spain is a noun and therefore is an appropriate country. Your data are neither consistent internally (among themselves) nor externally (to their field name). This may not be of your own doing or within your ability to fix due to other constraints. If they are within your ability to fix, you would do well for maintainability to change them.