WP_Queryのカスタマイズ

サブクラスにおいてWP_Queryを使うことのメリットは、拡張(継承)してカスタムクラスを作れることです。Rakhitha Nimesh Ratnayake(ラーキサ・ニーメシュ・ラーネヤク)は、その著書「WordPressによるWebアプリケーション開発」の中で、WP_Queryクラスの継承の用例を示しています。*1

リスト37188は、ラーネヤク氏が示した用例を本書のテーマに即してアレンジしたものです。
通常、WP_Queryを使うときは、次のように配列にすべてのフィルタリング条件を記述しなければなりませんが、リスト37188では、Modelクラスの中にこの記述を書いているので、呼び出す側は、1行のコードのみで済みます。

たしかに、同じフィルタリング条件を何度も繰り返し使う場合はこの方法が有効であり、クラスを継承すれば、少し異なる条件の場合も含めて抽象化できるかもしれません。

しかし、あらゆるパターンのサブクエリー(投稿の場合、タームの場合、親子の場合)と表示をすべて網羅的に抽象化するためには、もう一工夫必要です。

リスト36618は、リスト37188をアレンジし、この課題を解決するための方法です。

呼び出す側に、フィルタリング条件を羅列しますが、そこには値を直接記述します。これを受け取ったModelクラスは、その値をWP_Queryのフィルタリング条件にあてはめます。
この方法のメリットは、面倒なWP_Queryの記述から解放されるということです。
さらに、表示するViewクラスの名称なども呼び出す側の条件に加えることにより、サブクエリーから表示までを一貫して抽象化することができそうです。

参考記事

※1 PHPのコードをパーツ化する方法(2)クラスを使う方法2020-04-30

コード例

事例1:WP_Queryの拡張①Ratnayake氏の方法

呼び出す側

$the_query = new Model37188();
//ループ
if($the_query->have_posts()){
	While($the_query->have_posts()){
		$the_query->the_post();
		//Viewの記述	
		$view_obj = new View37188($par2) ;			
	}
	wp_reset_postdata();
}//endif

Modelクラス

class Model37188 extends WP_Query
{
	public function __construct( $args = array() )
	{
//クエリー	
		$args = wp_parse_args( $args, array(
			'post_type' => 'glossary',
			'meta_query' => array(
			'relation' => 'AND',
				array(
					'key' => 'gloss_type',
					'value' => '9851',
				),
				array(
					'key' => 'region',
					'value' => '9790',
				)
			)
		)
		);
		parent::__construct($args) ;
		
	}
}

Viewクラス

class View37188
{
	public function __construct($par2)
	{
		the_title() ;
		echo "<br>\n" ;	
	}//endfunction
}//endclass
築地
銀座
京橋
日本橋
新川
新富町
人形町

事例2:WP_Queryの拡張②アレンジした方法

呼び出す側

$args = array(
	'post_type' => 'glossary',
	'key' => array('gloss_type','region'),
	'value' => array('9851','9790')	
	);
$query = new Model36618($args);

Modelクラス

class Model36618 extends WP_Query
{
	public function __construct($var)
	{
//配列をオブジエクトに変換。
	$par =(object)$var;
//クエリー	
		$args = array(	
			'post_type' => $par->post_type,
			'meta_query' => array(
			'relation' => 'AND',
				array(
					'key' => $par->key[0],
					'value' => $par->value[0],
				),
				array(
					'key' => $par->key[1],
					'value' => $par->value[1],
				)
			)
		);
		
		$the_query = new WP_Query($args) ;
//ループ
		if($the_query->have_posts()){
			While($the_query->have_posts()){
				$the_query->the_post();
				//Viewの記述	
				$view_obj = new View36618($par2) ;			
			}
			wp_reset_postdata();
		}//endif
		
	}
}

Viewクラス

class View36618
{
	public function __construct($par2)
	{
		the_title() ;
		echo "<br>\n" ;	
	}//endfunction
}//endclass
築地
銀座
京橋
日本橋
新川
新富町
人形町

コメントよろしくお願いします。