【WordPress】get_posts(‘category=-3’)がおかしい(MySQLが古い環境で)
問題
「このカテゴリ以外」の一覧を表示したくてget_posts(array('category' => -3))
をしたんだけど、順番も取得できている記事も正しくない。
どうなってるのかな?
答え
そのとき、WordPressはこんなSQLを実行している。
SELECT wp_posts.ID FROM wp_posts WHERE 1=1 AND ( wp_posts.ID NOT IN ( SELECT object_id FROM wp_term_relationships WHERE term_taxonomy_id IN (3) ) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10;
この辺が怪しい。
GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC
MySQLなら文句を言わずに実行するのだろうけど、GROUP BY しているのだから、本来は何らかの集計関数を入れて、例えばこうするべきところ?
GROUP BY wp_posts.ID ORDER BY max(wp_posts.post_date) DESC
MySQL5.0で発生したが、MySQL5.1、5.5では発生しなかったので、あまり古くない環境の人は困っていないのかもしれない。
で、MySQL5.0の人はどうしたらよいのか。
ピンポイントで問題のSQLだけ書き換えてしまおう
今回おかしいのは ORDER BY 句。
posts取得のSQLのORDER BY句の書き換えは posts_orderby というフィルターでできる。add_filter('posts_orderby', '関数名')
である。
一時的にフィルターをかけるとこんな感じ。
//どこかで定義しておいて function hoge($orderby) { return 'max(wp_posts.post_date) DESC'; } //フィルターを追加 add_filter('posts_orderby', 'hoge', 1000); //投稿を取得 $posts = get_posts(array('category' => -3, 'suppress_filters' => false)); //フィルターを削除 remove_filter('posts_orderby', 'hoge', 1000); //以降通常通り foreach ($posts as $post) { //記事一覧のループなど }
get_posts()で各種フィルターが効かない!という場合は、あわてず suppress_filters を false にすること。デフォルトはtrueとなっており、フィルターが効かない。
コメント