以下のように私はupdate_post_meta()
を使用して複数の選択オプションとして私のナビゲーションメニュー項目内に新しいカスタムフィールドを作成しました
function YPE_update_custom_fields($menu_id, $menu_item_db_id, $menu_item_data) {
if (is_array($_REQUEST['menu-item-content-multiple'])) {
update_post_meta($menu_item_db_id, '_menu_item_content_multiple', $_REQUEST['menu-item-content-multiple'][$menu_item_db_id]);
}
}
add_action('wp_update_nav_menu_item', 'YPE_update_custom_fields', 10, 3);
function YPE_setup_custom_fields($item) {
$item->content_multiple = get_post_meta($item->ID, '_menu_item_content_multiple', true);
return $item;
}
add_filter('wp_setup_nav_menu_item', 'YPE_setup_custom_fields');
それから私は以下のようにWalker_Nav_Menu_Edit
ファイルに新しいフィールドを追加します
_編集済み_
<?php
$select_options = array (
'key_1' => 'option1',
'key_2' => 'option2',
'key_3' => 'option3'
);
?>
<p class="field-content-multiple description description-thin">
<label for="edit-menu-item-content-multiple-<?php echo $item_id; ?>">
<?php _e( 'Multiple Content' ); ?><br />
<select name="menu-item-content-multiple[<?php echo $item_id; ?>][]" id="edit-menu-item-content-multiple-<?php echo $item_id; ?>" class="widefat code edit-menu-item-content-multiple" multiple="multiple">
<?php foreach ($select_options as $key => $value): ?>
<option value="<?php echo $key; ?>" <?php echo selected(in_array($key, $item->content_multiple)); ?>><?php echo $value;?></option>
<?php endforeach ?>
</select>
</label>
</p>
私のコードは問題なく単一の選択ボックスで動作しますが、複数の選択ケースでin_array()
を使用するとこのエラーが返されます。
Warning: in_array() expects parameter 2 to be array, null given
これをして:
$item->content_multiple = get_post_meta($item->ID, '_menu_item_content_multiple', true);
get_post_meta()
の3番目のパラメータをtrue
に設定する方法に注意してください。これは、1つの値のみが返されることを意味します。 もしあなたがdocs を読んだなら、3番目のパラメータがfalse
であれば、そのメタフィールドのすべての値を含むarray)が得られるでしょう。
メタフィールドは一意でも複数でもかまいません。あるいは、シリアル化されたデータ文字列で一意になることもあります。
実際のところ、あなたのコードはselect multipleからすべての値を一つの単一のメタフィールドに格納しているようです。そのため、リクエストで配列を取得し、それをメタフィールドの単一の値として渡します。メタフィールドの値が配列の場合、WordPress データベースに格納される前にシリアル化された文字列に変換されます。これは関数maybe_serialize()
を使って内部的に行われます。メタフィールド、それがシリアル化された文字列である場合、WordPressはそれをmaybe_unserialize()
を介して渡します。そのため、シリアル化された文字列は配列に戻ります。
一般的な例で説明しましょう。
これはデータベースに格納される値の配列になります。
$values = [ 'red', 'yellow', 'blue', 'pink' ];
メタキーが「カラー」の場合、2つの選択肢があります。
$values = [ 'red', 'yellow', 'blue', 'pink' ];
foreach( $values as $value ) {
// This method uses `add_post_meta()` instead of `update_post_meta()`
add_post_meta( $item_id, 'color', $value );
}
これで、$item_id
で識別される項目には、color
メタキーのエントリがいくつかあります。次に、3番目のパラメータをfalse
に設定してget_post_meta()
を使用すると、すべての値を含む配列が得られます。
// You don't really need the set the third parameter
// because it is false vay default
$colors = get_post_meta( $item_id, 'color' );
// $colors should an array with all the meta values for the color meta key
var_dump( $colors );
この場合、値の配列はデータベースに格納される前にシリアル化されます。
$values = [ 'red', 'yellow', 'blue', 'pink' ];
// WordPress does this automatically when an array is passed as meta value
// $values = maybe_serialize( $values );
update_post_meta( $item_id, 'color', $values );
これで、$item_id
で識別される項目は、color
メタキーのエントリを1つだけ持つようになります。値は元の配列を表す直列化された文字列です。次に、エントリが1つしかないため、3番目のパラメータをtrueに設定してget_post_meta()
を使用してから、文字列をシリアル化解除して配列を取得します。
$colors = get_post_meta( $item_id, 'color', true );
// WordPress does this automatically when the meta value is a serialized array
// $colors = maybe_unserialize( $colors );
// $colors should be an array
var_dump( $colors );
あなたはあなたのフォームの選択倍数で同じアプローチに従うことができます。
メタキーのエントリが1つだけの場合:
if( ! empty( $_REQUEST['menu-item-content-multiple'][$menu_item_db_id] ) ) {
$meta_field_value = $_REQUEST['menu-item-content-multiple'][$menu_item_db_id];
// $meta_field_value will be serialized automatically by WordPress
update_post_meta( $menu_item_db_id, '_menu_item_content_multiple', $meta_field_value );
}
それから、あなたは配列として値を使うことができます:
// The value returned by get_post_meta() is unserialized automatically by WordPress
$item->content_multiple = get_post_meta( $item->ID, '_menu_item_content_multiple', true );
複数のエントリがある場合:
ここでの概念は少し異なります。データベースには同じメタキーを持つ複数のエントリがあるので、各値に新しいエントリを追加するには、add_post_meta()
ではなくupdate_post_meta()
を使用する必要があります。
if( ! empty( $_REQUEST['menu-item-content-multiple'][$menu_item_db_id] ) ) {
$values = $_REQUEST[ 'menu-item-content-multiple' . $menu_item_db_id ];
foreach( $values as $value ) {
add_post_meta( $menu_item_db_id, '_menu_item_content_multiple', $value );
}
}
これで、3番目のパラメータをfalse
に設定してget_post_meta()
を使用できます(これがデフォルト値なので、省略できます)。
$item->content_multiple = get_post_meta( $item->ID, '_menu_item_content_multiple', false );
どちらの方法でも問題ありません。どちらを使用するのがプロジェクト内のデータを整理するのに適しているかを判断する必要があります。
補足:入力データを使用する前に、いくつかの量子化を行う必要がありますが、私はあなたの要件を知りません。ここでは例を示します。
array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['menu-item-content-multiple'][$menu_item_db_id] ) );
selected()
関数を正しく使っていません。 selected()
には1つの必須パラメータと2つのオプションが必要です。あなたの場合は、$ selectedと$ currentを使うのが良いでしょう。
選択名のメタフィールド名の前にアンダースコアがありません。
選択()の場合:
selected( $selected, $current, $echo);
これについてもっと読むことができますコーデックス 選択された関数参照()
あなたの選択は次のようになります。
<select name="_menu-item-content-multiple[]" multiple>
<?php
foreach ($select_options as $key => $value) {
echo '<option value="'.$key.'" '.selected(in_array($key, $item->content_multiple), $key).'>'.$value.'</option>';
}
?>
</select>