ワイヤード・パンチ

元・大阪人が、岡山の山奥でも生きていけることを証明するためのブログ。

WordPressで、カテゴリなしのカスタム投稿タイプの投稿のみ抽出する方法。

仕事のうえでWordpressを使ったサイトを制作していますが、全投稿件数と、各カテゴリの投稿の合計件数が合わないと言われてしまいました。

投稿はもれなくいずれかのカテゴリに登録する運用にしているはずなのに、数が合わないということは、何のカテゴリにも登録されていない投稿が存在する恐れがあります。

しかし、標準の投稿タイプを使っていれば未分類というカテゴリに移動してくれるのですが、カスタム投稿タイプを使っているため、カテゴリ登録のない投稿はそのままカテゴリなしということになってしまいます。

広告

カテゴリ未登録だけを抽出できないの?

今回はget_postsを使って、カテゴリ登録のない投稿だけを抽出したいと思います。

カテゴリに関する抽出条件を指定したいときは、引数にtax_queryを用いることになります。

しかし、それを使っても、カテゴリなしという条件の指定方法がなかったのです。

冒頭でも書いたように、標準投稿タイプであれば「未分類」というカテゴリがあるので、それを指定すればいいのですが、カスタム投稿タイプにはないので、未分類を指定という方法が使えません。

よってここはやり方を変えて、特定のカテゴリを含まない投稿だけを抽出する方法を用いることにします。

しかし、もし何十個も何百個もカテゴリが存在した場合、それをいちいち除外条件に書いていては、とんでもなく時間がかかります。

それを短縮するため、今回は下記のようなコードを使います。

$ids = [];
for($i = 0; $i <= 20000; ++$i) {
	array_push($ids, $i);
}
$args = [
	"post_type" => "hogehoge",
	"tax_query" => [
		"relation" => "AND",
		[
			"taxonomy" => "fugafuga",
			"field" => "term_id",
			"terms" => $ids,
			"operator" => "NOT IN",
		],
	]
];
$posts = get_posts($args);
var_dump($posts);

特定のカテゴリを省くにはNOT INを使い、カテゴリはスラッグではなくIDで指定します。

そして、省きたいIDすべてが入った配列を作るのに、for文を用いています。

上記の場合だと、ID1~20000のカテゴリに登録されている投稿は抽出されません。

もしカテゴリIDが20000以下のものしか存在しない場合は、これですべてのカテゴリを除外できます。

これで投稿が抽出された場合は、それがカテゴリなしの投稿というわけです。

あとはこのカテゴリ登録し忘れの投稿に、カテゴリを設定してやることで、全投稿数とカテゴリ登録ありの登録数の合計が一致するでしょう。

追記。(2018/9/8)

情報提供していただき、もっと簡単にカテゴリなしを抽出するコードがありました。

$args = [
	"post_type" => "hogehoge",
	"tax_query" => [
		"relation" => "AND",
		[
			"taxonomy" => "fugafuga",
			"operator" => "NOT EXISTS",
		],
	]
];
$posts = get_posts($args);
var_dump($posts);

NOT EXISTSを使えばOKです。

関数リファレンス/WP Query – WordPress Codex 日本語版

ただし、日本語Codexなどを見ていると、NOT EXISTSというものが使えるということは書かれているものの、そのNOT EXISTSがどういう意味なのかはわからないんですよね…。

まさか長年やっているはずのWordpressで、情報不足に悩まされることになるとは。