ワイヤード・パンチ

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

Advanced Custom Fieldsで、フィールドタイプをユーザにしたときの戻り値がおかしいときの対処法。

WordPressでサイトを作ったことあるならご存知の方は多いと思いますが、「Advanced Custom Fields」というプラグインが存在します。

これを使えば、投稿タイプごとにカスタムフィールドを追加することが、簡単に行えます。

さらにフィールドタイプを「ユーザ」にすると、サイト内に登録されているユーザ情報も紐付けることができるのですが、値を取得する関数を実行したときの戻り値がおかしいことがあります。

広告

今回の環境。

記事作成時点では、Wordpressのバージョンは4.9.7、Advanced Custom Fields(以下、ACF)のバージョンは4.4.12です。

今後、バージョンアップにより状況が変わる可能性があります。

そもそもカスタムフィールドに関数で値を登録するには?

管理画面から投稿編集を開いて、そこでカスタムフィールドに値を入れることもできます。

しかし今回は、一般ユーザには管理画面に入らせない会員制サイトを作りたいので、公開画面上からカスタムフィールドの値を登録したいです。

よって、カスタムフィールドに値を登録するには、関数を用いることになります。

ACFで追加したカスタムフィールドであっても、投稿に値を登録するときには、WordPress標準で搭載されている関数を用いることになります。

関数リファレンス/update post meta – WordPress Codex 日本語版

update_post_meta($post_id, $meta_key, $meta_value);

上記サイトに詳細がありますが、簡単に言ってしまえば、$post_idには投稿ID、$meta_keyにはカスタムフィールドの名前、$meta_valueには値となります。

フィールドタイプがユーザだと、update_post_metaの$meta_valueに入れる値はユーザIDになります。

なおACFにも、カスタムフィールドに値を登録するための関数は、いちおう用意されています。

ACF | update_field()

update_field($selector, $value, $post_id);

ただ、このupdate_fieldを使った場合、公開画面上で値を表示させてもなぜか取得できないことがありました。

その場合、update_field使用後、管理画面の方で投稿を開いてからそのまま上書き保存することで、ようやく公開画面上でも表示できるようになりました。

しかし、このような不具合がある関数をさすがに使うわけにはいかず、update_post_metaでも値を登録できることに代わりはないので、update_fieldは使用しません。

戻り値の型が一定じゃない?

カスタムフィールドに登録されている値を取得するには、Wordpress標準の関数を用いる場合は、get_post_metaを使用します。

ACFで作られたカスタムフィールドであっても使用可能です。

関数リファレンス/get post meta – WordPress Codex 日本語版

get_post_meta($post_id, $key, $single);

ただ、ACFのようで用意されているget_fieldを使っても同じ結果となり、こちらの方が入力する必要のある引数が少なくて済むので、今回はこちらを使います。

ACF | get_field()

get_field($selector, $post_id, $format_value);

そして実際にフィールドタイプがユーザのカスタムフィールドをget_fieldによる戻り値を変数に入れ、var_dumpで結果を出力してみます。

すると上記写真のように、投稿ごとに戻り値がなぜかIDだけの文字列だったり、ユーザ情報がまるごと入った配列だったりするのです。

今回のサイトではこのカスタムフィールド取得処理のあと、ユーザIDに基づいた処理をしたかったのに、戻り値の型が違っていては、同じ処理をかけられません。

なぜ戻り値の型が変わってしまうのかは、原因はわかりませんでした。

また、管理画面上でカスタムフィールドの戻り値の型を設定しようにも、フィールドタイプがユーザのときは、指定できませんでした。

フィールドタイプが投稿とかであれば、戻り値をIDにするかオブジェクトにするか指定できるのですが、なぜユーザだけ…。

こればっかりは、ACFの仕様あるいは不具合としか言えないところです。

解決法。

プラグインの仕様だかなんだかとなれば、こちら側ではどうしようもありません。

ならばもう、投稿ごとに一定ではない戻り値の型であろうと、それを使うまでです。

つまり、戻り値がIDだけだった場合はそのまま用いて、配列だった場合はIDだけ抜き出して用いるということです。

$value = get_field("value", $post->ID);
if($value) {
	if(is_array($value)) {
		$value = $value["ID"];
	}
	$user = get_userdata($value);
}

ただ単純に、is_arrayによって配列かどうかの判定をかけているだけです。

配列でない場合はIDが返ってくるのがわかっているので、そのまま戻り値をのちの処理に使います。

配列だった場合も、配列の中の構成は決まっているので、その中からIDだけを抜き取ります。

ユーザIDさえあれば、ユーザ情報に関する処理はだいたい行えます。

これでOKです。

先程も書いたとおり、本当は管理画面側で戻り値の型を指定できるようにしてくれる方が、望ましいんですけどね…。

同じ保存処理をかけているのに、戻り値の型がバラバラになってしまうのは、やはり不具合としか言いようがありません。