WordPress カスタム投稿タイプ・プラグイン「Custom Post Type UI」0.8.1でwith_frontがおかしい

WordpressロゴWordPressのカスタム投稿タイプ(Custom Post Type)は便利ですが、パーマリンクなど不具合(というか、仕様?)が多く、筆者はなるべく使わないようにしているのですが、やむを得ず使う場合は、カスタム投稿タイプをUIで追加・変更・削除可能なプラグイン「Custom Post Type UI」を使っています。

この度、といっても「2013-10-18」に「Custom Post Type UI ver0.8.1」がリリースされたのですが、これにアップデートしたところ、「with_front => false」の設定で「with_front => true」としてカスタム投稿タイプが動作するように変わってしまいました。筆者にとって、痛恨のバグです。

そもそも with_front とは

そもそも「with_front」とは何かご存知のない方にご説明します。そんなの知ってるよという方は、この節は飛ばしてください。「with_front」とは、カスタム投稿タイプのパーマリンク設定のオプションで、この値で下記のようにパーマリンクを変えることができます。

‘rewrite’ => array(‘slug’ => ‘question’, ‘with_front’ => true) の場合

http://www.sample.jp/archives/question/%postname%
※「archives」にあたる部分は、Wordpress全体のパーマリンク構造によって変わります。

‘rewrite’ => array(‘slug’ => ‘question’, ‘with_front’ => false) の場合

http://www.sample.jp/question/%postname%

「archives」にあたる部分があると、カッコ悪いですよね。ちなみに「Custom Post Type UI ver0.8」で設定ができるようになっていて、「with_front => false」の設定でサイト構築しているのに、いきなり「with_front => ture」になってしまうと、サイト内の該当するリンクを全て変更しないといけませんので、筆者としては痛恨なのです。

そもそも、わざわざ「Custom Post Type UI」なんて使わなくても、「functions.php」に記述しとけば、いいじゃんって話もあります。でも、やっぱり、UIで出来るようにしたいんですよね。

「Custom Post Type UI ver0.8.1」の不具合部分の修正

「0」(falseの意味)と「1」(trueの意味)が入ってくる「 $cpt_post_type[“rewrite_withfront”] 」に対して、下記の100行目の empty関数が原因で、 「0」(falseの意味) がempty関数で真となり、どうしても「boolean true」になってしまいます。この度の「Custom Post Type UI ver0.8.1」のリリースノートでいう「* Fixes for potential “undefined index” WP DEBUG log notices.」を目的に、97行目から104行目をはじめ全体的にempty関数がif条件分に追加されているのですが、empty関数は、「変数存在チェック」だけではなく「変数が存在し、かつその値が空や0でなければ FALSE を返す」ことを失念されていらっしゃるように思えます。

function cpt_create_custom_post_types() {
	//register custom post types
	$cpt_post_types = get_option('cpt_custom_post_types');

	//check if option value is an Array before proceeding
	if ( is_array( $cpt_post_types ) ) {
		foreach ($cpt_post_types as $cpt_post_type) {
			//set post type values
			$cpt_label              = ( !empty( $cpt_post_type["label"] ) ) ? esc_html( $cpt_post_type["label"] ) : esc_html( $cpt_post_type["name"] ) ;
			$cpt_singular           = ( !empty( $cpt_post_type["singular_label"] ) ) ? esc_html( $cpt_post_type["singular_label"] ) : esc_html( $cpt_label );
			$cpt_rewrite_slug       = ( !empty( $cpt_post_type["rewrite_slug"] ) ) ? esc_html( $cpt_post_type["rewrite_slug"] ) : esc_html( $cpt_post_type["name"] );
			$cpt_rewrite_withfront  = ( isset( $cpt_post_type["rewrite_withfront"] ) && !empty( $cpt_post_type["rewrite_withfront"] ) ) ? esc_html( $cpt_post_type["rewrite_withfront"] ) : true;
			$cpt_menu_position      = ( !empty( $cpt_post_type["menu_position"] ) ) ? intval( $cpt_post_type["menu_position"] ) : null; //must be null
			$cpt_menu_icon          = ( !empty( $cpt_post_type["menu_icon"] ) ) ? esc_url( $cpt_post_type["menu_icon"] ) : null; //must be null
			$cpt_taxonomies         = ( !empty( $cpt_post_type[1] ) ) ? $cpt_post_type[1] : array();
			$cpt_supports           = ( !empty( $cpt_post_type[0] ) ) ? $cpt_post_type[0] : array();

			//Show UI must be true

with_front以外、他にもempty関数の地雷で不具合があるかもしれませんが、気になる部分を修正した「custom-post-type-ui.php」のdiffを下記のとおり皆様にご紹介します。必ず、ご自分のWordpressに適しているかご確認ください(くれぐれも自己責任でお願いします)。

===================================================================
--- /custom-post-type-ui/custom-post-type-ui.php
+++ /custom-post-type-ui/custom-post-type-ui.php
@@ -97,7 +97,7 @@
 			$cpt_label              = ( !empty( $cpt_post_type["label"] ) ) ? esc_html( $cpt_post_type["label"] ) : esc_html( $cpt_post_type["name"] ) ;
 			$cpt_singular           = ( !empty( $cpt_post_type["singular_label"] ) ) ? esc_html( $cpt_post_type["singular_label"] ) : esc_html( $cpt_label );
 			$cpt_rewrite_slug       = ( !empty( $cpt_post_type["rewrite_slug"] ) ) ? esc_html( $cpt_post_type["rewrite_slug"] ) : esc_html( $cpt_post_type["name"] );
-			$cpt_rewrite_withfront  = ( isset( $cpt_post_type["rewrite_withfront"] ) && !empty( $cpt_post_type["rewrite_withfront"] ) ) ? esc_html( $cpt_post_type["rewrite_withfront"] ) : true;
+			$cpt_rewrite_withfront  = ( !isset( $cpt_post_type["rewrite_withfront"] ) ) ? '1' : $cpt_post_type["rewrite_withfront"];
 			$cpt_menu_position      = ( !empty( $cpt_post_type["menu_position"] ) ) ? intval( $cpt_post_type["menu_position"] ) : null; //must be null
 			$cpt_menu_icon          = ( !empty( $cpt_post_type["menu_icon"] ) ) ? esc_url( $cpt_post_type["menu_icon"] ) : null; //must be null
 			$cpt_taxonomies         = ( !empty( $cpt_post_type[1] ) ) ? $cpt_post_type[1] : array();
@@ -147,7 +147,7 @@
 				'map_meta_cap' => true,
 				'hierarchical' => get_disp_boolean($cpt_post_type["hierarchical"]),
 				'exclude_from_search' => $cpt_exclude_from_search,
-				'rewrite' => array( 'slug' => $cpt_rewrite_slug, 'with_front' => $cpt_rewrite_withfront ),
+				'rewrite' => array( 'slug' => $cpt_rewrite_slug, 'with_front' => get_disp_boolean( $cpt_rewrite_withfront ) ),
 				'query_var' => get_disp_boolean($cpt_post_type["query_var"]),
 				'description' => esc_html($cpt_post_type["description"]),
 				'menu_position' => $cpt_menu_position,
@@ -730,10 +730,10 @@
 						$custom_post_type .= "'map_meta_cap' => " . disp_boolean( '1' ) . ",\n";
 						$custom_post_type .= "'hierarchical' => " . disp_boolean( $cpt_post_type["hierarchical"] ) . ",\n";

+						if( !isset( $cpt_post_type['rewrite_withfront'] ) ) $cpt_post_type['rewrite_withfront'] = 1;
 						if ( !empty( $cpt_post_type["rewrite_slug"] ) ) {
-							$custom_post_type .= "'rewrite' => array('slug' => '" . $cpt_post_type["rewrite_slug"] . "', 'with_front' => " . $cpt_post_type['rewrite_withfront'] . "),\n";
+							$custom_post_type .= "'rewrite' => array('slug' => '" . $cpt_post_type["rewrite_slug"] . "', 'with_front' => " . disp_boolean( $cpt_post_type['rewrite_withfront'] ) . "),\n";
 						} else {
-							if( empty( $cpt_post_type['rewrite_withfront'] ) ) $cpt_post_type['rewrite_withfront'] = 1;
 							$custom_post_type .= "'rewrite' => array('slug' => '" . $cpt_post_type["name"] . "', 'with_front' => " . disp_boolean( $cpt_post_type['rewrite_withfront'] ) . "),\n";
 						}

@@ -1360,7 +1360,7 @@
 							<td>
 								<select name="cpt_custom_post_type[rewrite_withfront]" tabindex="4">
 									<option value="0" <?php if (isset($cpt_rewrite_withfront)) { if ($cpt_rewrite_withfront == 0 && $cpt_rewrite_withfront != '') { echo 'selected="selected"'; } } ?>><?php _e( 'False', 'cpt-plugin' ); ?></option>
-									<option value="1" <?php if (isset($cpt_rewrite_withfront)) { if ($cpt_rewrite_withfront == 1 || is_null($cpt_rewrite_withfront)) { echo 'selected="selected"'; } } else { echo 'selected="selected"'; } ?>><?php _e( 'True', 'cpt-plugin' ); ?></option>
+									<option value="1" <?php if (isset($cpt_rewrite_withfront)) { if ($cpt_rewrite_withfront != 0 || $cpt_rewrite_withfront == '') { echo 'selected="selected"'; } } else { echo 'selected="selected"'; } ?>><?php _e( 'True', 'cpt-plugin' ); ?></option>
 								</select> <?php _e( '(default: True)', 'cpt-plugin' ); ?>
 							</td>
 							</tr>

「Custom Post Type UI v0.8.2」で、register_post_typeに渡すwith_front値は修正されたようですが、管理画面の[Get Code]で出力される箇所はまだ直っていませんでした。プラグインを自分で修正するとソース管理を自分でしなければなりませんので、筆者は、動作上は問題がないと思われる「Custom Post Type UI v0.8.2」を採用したいと思います。いつかは直るんじゃないかとw今回のようなことがあるので、Wordpress3.7の新機能である自動アップデートで、自分の知らない間に起きたら怖いと感じました(特にプラグインの自動アップデートは)。