get_comments で複数の投稿タイプを取得する

複数のカスタム投稿タイプのコメントをまとめて取得したい での回答した内容の備忘録(と、若干のコードリファクタリング)

get_comments で指定できるパラメーターは、文字列形式のみで、配列やカンマ区切りによる複数指定はできません。
これは、内部でSQL文を構成する際に、prepare メソッドを用いて文字列や数字にはめ込んでいるためです。
ただし、comments_clauses というフィルターフックが用意されていて、SQL文のほぼ全ての句を変更することができるようになっています。

function multi_post_type_comments_where( $clauses, $comment_query ) {
	global $wpdb;
	if ( is_array( $comment_query->query_vars['post_type'] ) ) {
		$post_types = $wpdb->_escape( $comment_query->query_vars['post_type'] );
		$search = $wpdb->prepare( " AND {$wpdb->posts}.post_type = %s", $comment_query->query_vars['post_type'] );
		$replace = " AND {$wpdb->posts}.post_type IN ( '" . implode( "','", $post_types ) . "' )";
		$clauses['where'] = str_replace( $search, $replace, $clauses['where'] );
	}
	return $clauses;
}
add_filter( 'comments_clauses', 'multi_post_type_comments_where', 10, 2 );

回答は、投稿タイプのパラメーター固定ですが、パラメーターを foreach などでループ処理させることで、他のパラメーターについても、配列での複数指定に対応させることは可能なはずです。

WordPress のカスタムフィールドをプレビュー対象にする

カスタムフィールドを使って、使いやすくはしてみたものの、「プレビューに反映されないんですけど!?」と言われてお嘆きの貴方に。

function get_preview_id( $post_id ) {
	global $post;
	$preview_id = 0;
	if ( $post->ID == $post_id && is_preview() && $preview = wp_get_post_autosave( $post->ID ) ) {
		$preview_id = $preview->ID;
	}
	return $preview_id;
}


function get_preview_postmeta( $return, $post_id, $meta_key, $single ) {
	if ( $preview_id = get_preview_id( $post_id ) ) {
		if ( $post_id != $preview_id ) {
			$return = get_post_meta( $preview_id, $meta_key, $single );
		}
	}
	return $return;
}
add_filter( 'get_post_metadata', 'get_preview_postmeta', 10, 4 );


function save_preview_postmeta( $post_ID ) {
	global $wpdb;

	if ( wp_is_post_revision( $post_ID ) ) {
		$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE post_id = $post_ID" );
		$post_metas = apply_filters( 'preview_post_meta_keys', array( 'meta' ) );
		foreach ( $post_metas as $post_meta ) {
			foreach ( $_POST[$post_meta] as $meta_id => $meta_arr ) {
				add_metadata( 'post', $post_ID, $meta_arr['key'], $meta_arr['value'] );
			}
		}
		do_action( 'save_preview_postmeta', $post_ID );
	}
}
add_action( 'wp_insert_post', 'save_preview_postmeta' );

デフォルトのUIに対応させただけのものなので、Custom Field TemplateEditor TemplatesAdvanced Custom Fields での入力値に対応させたい場合は、save_preview_postmeta フックで、それぞれのプラグインの送信形式に合わせて、add_metadata(add_post_meta だと、公開中のデータを上書きしちゃうので注意)を実行するようにしてください。

※ 画像表示に影響が出るため、コードを一部修正しました。(2013/1/8)

WordPress のメディアをアーカイブ表示してみる

リライトルールを追加して、post_status の指定をすると、メディアもアーカイブ表示ができるんですよ。奥さん。
ただし、is_home が true になるので、そのままだと home.php か、index.php での表示になってしまうのですけどね。

function add_attachiment_archive_rule() {
	$add_rules = array(
		'top' => array(
			'attachment/page/[0-9]{1,}/?$' => 'index.php?post_type=attachment&paged=$matches[1]',
			'attachment/?$' => 'index.php?post_type=attachment'
		),
		'bottom' => array(
		)
	);
	foreach ( $add_rules as $position => $rules ) {
		foreach ( $rules as $rewrite => $rule ) {
			add_rewrite_rule( $rewrite, $rule, $position );
		}
	}
}
add_action( 'init', 'add_attachiment_archive_rule' );

function attachment_archve_post_status( $wp_query ) {
	if ( ! is_admin() && $wp_query->is_main_query() ) {
		if ( ! is_singular() && $wp_query->get( 'post_type' ) == 'attachment' ) {
			$wp_query->set( 'post_status', 'inherit' );
		}
	}
}
add_action( 'pre_get_posts', 'attachment_archve_post_status' );

WordPress を扱う上で憶えておいて欲しい3つのesc #wacja2012

わんばんこ。2012 WordPress アドベントカレンダーの3日目をむゆうさん( @anticyborg )と共に担当させていただきます。本当は、アドベントよりおべんt(以下略

WordPress で実現系のコードを紹介する記事は、よく目にしますし、セキュリティに関する関心も高いようですが、意外に基本的な所が抜け落ちているケースが多いように感じたので、テーマやプラグイン開発時に憶えておいて欲しい WordPress 関数、esc_htmlesc_attresc_url について、つらつらと書いてみたいと思います。

“WordPress を扱う上で憶えておいて欲しい3つのesc #wacja2012” の続きを読む

WordPress のメディア表示をアップロードしたユーザーのみに限定する

WordPress で、サイトによっては、自分のアップロードした画像しか利用させたくない場合などもありますよね。
そんなときでも、ちょこっとカスタマイズするだけで、メディアライブラリで表示されるものを制限できることができてしまいます。

“WordPress のメディア表示をアップロードしたユーザーのみに限定する” の続きを読む