ACFでフィールド名から内部キーを取り出す、など色々

Advanced Custom Fields を使ってカスタマイズする際、メタキーだけでなく、内部的に使われるキー(field_xxxxxxxという名前になっている)が欲しい時がある。

さてそのkeyをどうやって知るのだろうか?
ドキュメントを見てもそのような関数はなさそうだ(get_key()みたいな)

そこで自分は以下のコードを使って、全部のフィールド名とキーを対にしたデータを吐き出し、使っている。

 

/*
ACFフィールド名を得る
*/

function get_field_names($name){

$fg = get_posts(array('name'=>'acf_'.$name , 'post_type'=>'acf'));
$cf = array();
$fgmeta = get_post_meta($fg[0]->ID);
foreach($fgmeta as $key => $field) {
if(substr($key, 0, 6) == 'field_') {
$field = unserialize($field[0]);
$cf[$field['name']] = $field['key'];
}
}
return $cf;
}

その後の考察

気になってACFのデータをちょっと解析してみたところ、いろいろ誤解していたことが分かった。

これまでは「ACFのnameはpostmetaのキーではなく、実際は内部キーを使っている」と信じ込んでいたが、まず、単一データのフィールドの場合(おそらく複数データでも同じ)ACFのフィールド名はやはりそのまま、postmetaのkeyに該当する。なのでget_post_meta()もマジックメソッド$post->hogeも使えるはず。

では、ネイティブ名である「field_xxxxxxxxx」は一体どういう役割を持つのか?

まず。例えばキーはmykeyだとするとpostmetaには

meta_key => ‘_mykey’

meta_value => ”fieldxxxxxxxxx’

と入ってくる。つまりキーとネイティブ名の対応を示している。update_field()を使用するこれがセットされる。なのでupdate_post_meta()を使うとこれがセットされず、おそらく管理画面には反映されない

※この行を削除しても管理画面には反映されることを確認。おそらく繰り返しフィールドなど複雑なデータで生きてくるのだろう。

先日書いた保存ルーチンでは、この対応関係に整合性が取れなくなり複数のフィールドに同じ値が入っていくという珍現象が起きてしまった。

とりあえず、保存はともかく読み出しにはget_post_meta()が使えるということでひとまず安心した。

後日談———————————–

get_field()

update_field()

この二つがどうも曲者で、なぜか特定のフィールドだけ保存・読み出しができないということが判明した。

従来通り

get_post_meta()

update_post_meta()

を使えば問題はなく、管理画面へも反映される。ただこの場合fieldxxxxxxxというキーとの紐付けが行われず、いずれ不具合が起こる可能も出てくる。

そういうこともあり、自作部分が多い場合ACFの使用を避けたい。問題はクライアントが納得するかどうか。

もうひとつ、テキストエリアでget_field()を使用時に、勝手に<br />を挿入されてしまう現象があった。おそらく内部でnl2brが行われている模様。これはフィールド設定時に変更できると思うが要注意。

出力時はget_field、フォームの規定値にはget_post_metaを使うべし。

後日談part2———————————–

ACFのフォームと自前フォームを混在させる場合、注意しなければいけない点がある。

ご存知のようにACFは複数の値を持つカスタムフィールドを保存する場合、配列として保存する。ここがいつも問題になるところだ。なので、取り出すときはget_post_meta()の第3パラーメータはtrueだ。

ここで、ひとつの値を持つチェックボックスを付けた時にハマった。

自前フォームの場合、仮にkeyを’check’、valueを’yes’とした場合、stringの’yes’ が保存され、出てくる。

なぜならば、inputのnameにブラケットを不要と思ってつけなかったので、普通に単独の値として処理された。

ところがACFで同じ項目を保存したら

array([0] => ‘yes’)

と出てくるではないか。チェックボックスは問答無用でarrayにされてしまうのだ。

これが誤動作を起こした。

解決策としては、自前フォームでもnameにブラケットをつけて、arrayで保存する。hiddenを設置してチェックしなかった場合の値を送りたい時(常套手段ですね)も、ブラケットをつける。

自作フォームヘルパーを使っていたので、自然にブラケットが外れてしまっていた。(というか付けない仕様にしていた。単独選択なら必要ないですね)

自分は保存ルーチンで強制的にarrayで保存するようにした(ダーティ)

結論:ACFは色々大変。独自世界を行ってる。

コメント

タイトルとURLをコピーしました