WP_Query 是 WordPress 用来从数据库中获取文章的类,这个类非常强大。使用这个类,我们可以根据文章分类、标签、时间、评论、作者、文章 ID、文章状态、自定义字段等信息来获取文章,几乎所有的文章查询都可以通过这个类实现。但是总有一些情况,我们只使用 WP_Query 是实现不了的。
这段时间我们开发了一个 WordPress 文章订阅系统,用户可以同时订阅网站中的作者、分类、标签这三个信息。订阅了这些信息后,用户可以在自己的订阅页面查看自己订阅的所有包含这些信息的文章,也可以分别查看自己订阅的分类、标签或作者的文章。如果是查询 “在某些分类或者标签中的文章” 中的文章,使用 WP_Query 的 “tax_query” ,relation 设置为 “or” 即可实现。
在所有订阅结果页面,我们需要的是“某些作者发表的、或者在某些分类或标签中的文章”,如果使用和 “tax_query” 和 “author__in” 参数查询文章,查询的结果是 “某作者发表的,并且在某个分类中的文章”,显然,这并不是我们需要的。我们的解决办法是先用原始 SQL 语句把符合这种情况的文章 ID 查询出来,然后再使用 post__in 参数来构造一个新的 WP_Query 查询。示例代码如下:
首先使用原始 SQL 查询获取符合条件的文章 ID
$sql_query = "SELECT wp_posts.ID
FROM wp_posts
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
WHERE 1=1
AND (
wp_term_relationships.term_taxonomy_id IN (" . implode(',', $followed_categories_ids) . ")
OR
wp_term_relationships.term_taxonomy_id IN (" . implode(',', $followed_tags_ids) . ")
)
OR wp_posts.post_author IN (" . implode(',', $followed_authors_ids) . ")
AND wp_posts.post_type = 'post'
AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC
";
$result = array_values(wp_list_pluck($wpdb->get_results($sql_query, OBJECT_K), 'ID'));
然后通过使用上面的查询结果构造一个标签的 WP_Query 查询
获得文章 ID 后,再使用 “post__in” 参数构造一个标准的 WP_Query 查询,用来适配主题的一些功能、实现分页等。
$args = [
'post_type' => 'post',
'posts_per_page' => $per_page,
'paged' => $paged,
'post__in' => $result;
];
除了上述的情况,WP_Query 肯定还会有不能满足我们需求的情况存在,遇到类似问题的时候,可以参考上面的方式来实现自定义查询,解决我们的问题。