J'ai créé un nouveau champ personnalisé dans les éléments de mon menu de navigation sous forme d'options de sélection multiples. J'ai utilisé update_post_meta()
comme ci-dessous.
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');
Puis j'ajoute un nouveau champ dans le fichier Walker_Nav_Menu_Edit
comme ci-dessous
ÉDITÉ
<?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>
Mon code fonctionne avec la zone de sélection unique sans problème, mais lorsque j'utilise in_array()
dans plusieurs cas, cette erreur est renvoyée.
Warning: in_array() expects parameter 2 to be array, null given
Tu fais cela:
$item->content_multiple = get_post_meta($item->ID, '_menu_item_content_multiple', true);
Notez que vous définissez le troisième paramètre de get_post_meta()
sur true
, ce qui signifie qu'une seule valeur sera renvoyée. Si vous lisez la documentation , vous verrez que si le troisième paramètre est false
, vous obtiendrez un array avec toutes les valeurs de ce champ méta.
Rappelez-vous que les méta-champs peuvent être uniques ou multiples. Ou il peut être unique avec une chaîne de données sérialisée.
Dans l’état actuel, votre code semble stocker toutes les valeurs du multiple de sélection dans un seul champ méta. Ainsi, vous obtenez un tableau dans la demande et le transmettez en tant que valeur unique du champ méta. Lorsque la valeur d'un méta-champ est un tableau, WordPress le convertit en chaîne sérialisée avant son stockage dans la base de données ; cela se fait en interne avec la fonction maybe_serialize()
. Ensuite, lorsque vous essayez d’obtenir la valeur du champ méta, s’il s’agit d’une chaîne sérialisée, WordPress la transmet à travers maybe_unserialize()
, de sorte que la chaîne sérialisée soit reconvertie dans le tableau:
Expliquons avec un exemple générique.
Ce sera le tableau de valeurs à stocker dans la base de données:
$values = [ 'red', 'yellow', 'blue', 'pink' ];
Si votre clé méta est "couleur", vous avez deux options:
$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 );
}
Maintenant, l'élément identifié avec $item_id
aura plusieurs entrées pour la clé méta color
. Ensuite, vous pouvez utiliser get_post_meta()
avec le troisième paramètre défini sur false
et vous obtiendrez un tableau avec toutes les valeurs:
// 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 );
Dans ce cas, le tableau de valeurs est sérialisé avant d'être écrit dans la base de données:
$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 );
Désormais, l'élément identifié par $item_id
n'aura qu'une entrée pour la clé méta color
; la valeur est une chaîne sérialisée représentant le tableau d'origine. Ensuite, vous pouvez utiliser get_post_meta()
, avec le troisième paramètre défini sur true, car vous n’avez qu’une entrée, puis désérialiser la chaîne pour récupérer le tableau:
$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 );
Vous pouvez suivre la même approche avec le multiple de sélection de votre formulaire.
Avec une seule entrée pour la clé méta:
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 );
}
Ensuite, vous pouvez utiliser la valeur en tant que tableau:
// 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 );
Avec des entrées multiples:
Le concept ici est un peu différent; vous aurez plusieurs entrées dans la base de données avec la même clé méta, vous devez donc utiliser add_post_meta()
au lieu de update_post_meta()
afin d’ajouter une nouvelle entrée pour chaque valeur.
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 );
}
}
Maintenant, vous pouvez utiliser get_post_meta()
avec le troisième paramètre défini sur false
(c'est la valeur par défaut, vous pouvez donc l'omettre):
$item->content_multiple = get_post_meta( $item->ID, '_menu_item_content_multiple', false );
Les deux options sont acceptables, vous devez décider laquelle est la meilleure pour organiser les données dans votre projet.
Note latérale : vous devriez faire une désinstallation avant d'utiliser les données d'entrée, mais je ne connais pas vos exigences, voici un exemple:
array_map( 'sanitize_text_field', wp_unslash( $_REQUEST['menu-item-content-multiple'][$menu_item_db_id] ) );
Vous n'utilisez pas la fonction selected()
correctement. selected()
nécessite 1 paramètre obligatoire et 2 options. Dans votre cas, il vaut mieux utiliser $ selection et $ current.
Vous manquez le trait de soulignement avant le nom de votre méta-champ dans le nom de sélection.
Pour sélectionné ():
selected( $selected, $current, $echo);
vous pouvez en savoir plus à ce sujet dans le codex référence de la fonction selected ()
Votre sélection doit être comme ça:
<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>