WordPress Meta Query Arrays

I'm building a way form my users to "like" a post.

I'll have an array of users that have liked posts:

$user_ids = array(60, 61, 62, 63);

And then a post will have a post_meta that saves the user ID when the "like" button is clicked on a post, like so:

// Build array of user IDs that have liked this post
$likes = array(61, 62);

// Save array
update_post_meta($post->ID, likes, $likes);

So how can I return all posts liked by the users. This is how I'm doing it currently, which doesn't work.

$args = array(
    'post_type'         => 'post',
    'post_status'       => 'publish',
    'posts_per_page'    => -1,
    'orderby'           => 'rand',
    'meta_query'        => array(
        'relation'  => 'AND',
        array(
            'key'       => 'likes',
            'value'     => $user_ids,
            'compare'   => 'IN'
        )
    )
);
$posts = get_posts($args);

This should return all posts that have '60, 61, 62, 63' saved in the posts 'likes' meta. But it returns 0 results.

Now, I think this is because WordPress serializes arrays when they are saved in a post_meta.

So, how do I a do a query like this? Is it even possible? Maybe I have to use the $wpdb class.

Thanks!

Answers


Try this one with WP_Query no need of relation just use the compare part with IN

 $user_ids = array(60, 61, 62, 63);
 $args = array(
   'post_type' => 'post',
   'meta_key' => 'likes',
   'post_status'       => 'publish',
   'posts_per_page'    => -1,
   'orderby'           => 'rand',       
   'order' => 'ASC',
   'meta_query' => array(
       array(
           'key' => 'likes',
           'value' => $user_ids, //array
           'compare' => 'IN',
       )
   )
 );
 $query = new WP_Query($args);

See the given example above "Time Parameters" Heading WP_Query

OR by get_posts try this

$args = array(
    'post_type'         => 'post',
    'post_status'       => 'publish',
    'posts_per_page'    => -1,
    'orderby'           => 'rand',
    'meta_query'        => array(

        array(
            'key'       => 'likes',
            'value'     => $user_ids,
            'compare'   => 'IN'
        )
    )
);
$posts = get_posts($args);

OR by a custom query you can do as follows

global $wpdb;

$liked_posts=$wpdb->get_results("SELECT * FROM `wp_posts` WHERE 
post_type='post' AND post_status ='publish' AND ID
 IN(
SELECT post_id FROM `wp_postmeta` WHERE meta_key='likes' 
AND meta_value IN (".join(',',$user_ids).")
) ORDER BY RAND()");

Also don't store array of ids in one row instead loop through ids array and normalize your likes data manually Don't serialize data into a database field. That's what Database_normalization is for and insert each id in new row because

Wordpress stores the meta values as strings. When you pass update_post_meta an array, it automatically converts it to a string. What you'll need to do is unserialize it when you attempt to read the data but in mysql you can't unserialize column data in the query because mysql doesn't about the serialization of php

$likes = array(61, 62);

foerach($likes as $l){

update_post_meta($post->ID, "likes", $l);

}

And below is the query you have asked for in bounty comments

If a $wpdb answer is given, then please elaborate on how to factor in category (include and exclude), and ignore posts by an array of IDs

$liked_posts=$wpdb->get_results("
SELECT * FROM `wp_posts` wp
INNER JOIN `wp_term_relationships` wtr ON (wp.`ID`=wtr.`object_id`)
INNER JOIN  `wp_term_taxonomy` wtt ON (wtr.`term_taxonomy_id` =wtt.`term_taxonomy_id`)
WHERE  wp.post_type='post' AND wp.post_status ='publish' AND wp.ID
 IN(
SELECT post_id FROM `wp_postmeta` WHERE meta_key='likes' 
AND meta_value IN (".join(',',$user_ids).")
)  AND wp.ID NOT IN (100,101,102)
AND wtt.`term_id` IN(1,2,3) AND wtt.`term_id` NOT IN (4,5,6,)    
ORDER BY RAND() ");

I have used the INNER JOINs on wp_term_relationships and wp_term_taxonomy the table wp_term_relationshipsstores the relation of posts and the taxonomy of category and the table wp_term_taxonomy have the taxonomy of the category and also the category id

Here is the part which covers the

1. category (include and exclude)

AND wtt.`term_id` IN(1,2,3) AND wtt.`term_id` NOT IN (4,5,6,) 

2. ignore posts by an array of IDs

AND wp.ID NOT IN (100,101,102) 
or $postids =array(100,101,102);
AND wp.ID NOT IN (".join(',',$postids).")

Need Your Help

Is there a way to load Django template modules from code instead of templates?

django django-templates

For example we need to have this {% load staticfiles %} in the template to be able to use static files.

Access REST API protected with Spring Security

spring rest spring-security

Here is my configuration (using Spring Security 3.2.5):

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.