Je prends plusieurs valeurs d'emplacement avec chaque message, c'est donc un tableau (toujours). Le champ de mon formulaire de méta est comme ceci:
<select name="<?php echo $project_prefix; ?>offer_locations[]" id="<?php echo $project_prefix; ?>offer_locations" required multiple="multiple">
...
...
...
</select>
Si la publication existe déjà sans aucune valeur pour les emplacements, la valeur existante viendra null
name__, mais comme le champ est obligatoire, la nouvelle valeur d'emplacement [lors de l'enregistrement] sera sûrement un tableau et nous devrions ajouter la valeur postmeta.
Les conditions que j'ai faites avec array_diff()
fonctionnent correctement. J'ai créé un scénario personnalisé et vérifié le code. Même dans WordPress, j'ai vérifié le code ( bloc de code personnalisé ), car vous pouvez voir quelques var_dump()
, echo
et exit()
en ligne. Mais...
<?php
function save_post_specifics_meta( $post_id ) {
global $project_prefix;
// verify nonce
if (!isset($_POST['post_specifics_nonce']) || !wp_verify_nonce($_POST['post_specifics_nonce'], basename(__FILE__)))
return $post_id;
// check autosave
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
return $post_id;
// check permissions
if ( 'post' == $_POST['post_type'] && !current_user_can('edit_post', $post_id) )
return $post_id;
//Location meta data
$existing_locations = get_post_custom_values( "{$project_prefix}post_locations", $post_id );
$new_locations = $_POST["{$project_prefix}post_locations"]; //always an array
var_dump($existing_locations); //for debugging only
var_dump($new_locations); //for debugging only
if( is_array( $existing_locations ) ) {
$new_diff = array_diff( $new_locations, $existing_locations );
$existing_diff = array_diff( $existing_locations, $new_locations );
} else {
$new_diff = $new_locations;
$existing_diff = $existing_locations;
}
var_dump($new_diff); //for debugging only
var_dump($existing_diff); //for debugging only
if( $new_diff ) {
foreach( $new_diff as $new_location ) {
add_post_meta( $post_id, "{$project_prefix}post_locations", $new_location );
echo "New Multiple: ", $new_location, '<br>'; //for debugging only
}
}
if( $existing_locations && $existing_diff ) {
if( is_array( $existing_diff ) ) {
foreach ( $existing_diff as $existing_location ) {
delete_post_meta( $post_id, "{$project_prefix}post_locations", $existing_location );
echo "Delete Multiple: ", $existing_location, '<br>'; //for debugging only
}
} else {
delete_post_meta( $post_id, "{$project_prefix}post_locations", $existing_diff );
echo "Delete Single: ", $existing_diff, '<br>'; //for debugging only
}
}
exit(); //for debugging only
}
add_action( 'save_post', 'save_post_specifics_meta', 10 );
add_action( 'new_to_publish', 'save_post_specifics_meta', 10 );
Lors de la sauvegarde ou de la mise à jour du post, le méta-champ location se déroule comme prévu. Mais si l'opérateur de saisie de données frappe le Preview Changes bouton, la add_post_meta()
se déclenche, même au sein des véritables accolades conditionnelles, et ajoute des entrées en double, Je ne sais pas comment !!! : o
J'ai ensuite ajouté true
au dernier paramètre (ligne 40) pour que la valeur soit unique, afin que je puisse arrêter les entrées en double. Mais l'ajout de true
a cessé d'ajouter toute nouvelle valeur au meta_key
même lors de l'enregistrement.
Comment puis-je arrêter d'ajouter des méta-valeurs sur Preview Changes frappé?
En fait, j'aimerais beaucoup avoir une réponse de @ialocin, car il m'a suggéré le chemin. Mais comme le code est un peu long pour le champ commentaire, je l’affiche ici en guise de réponse. Mais j'aimerais bien accepter une réponse plus appropriée à la situation:
Après la suggestion de @ ialocin, j'ai compris que le $post_id
n'était pas exact pour un Preview Changes hit, donc le $existing_locations
ne recevait pas les informations de base de données correctes. Maintenant j'ai changé la ligne suivante:
$existing_locations = get_post_custom_values( "{$project_prefix}post_locations", $post_id );
dans les lignes conditionnelles suivantes:
if( $_POST[ 'wp-preview' ] === 'dopreview' ) {
//if it's a preview hit, grab the actual post's data
$actual_post_id = wp_get_post_parent_id( $post_id );
$existing_locations = get_post_custom_values( "{$project_prefix}post_locations", $actual_post_id );
} else {
//else, go with the actual post
$existing_locations = get_post_custom_values( "{$project_prefix}post_locations", $post_id );
}
Tout fonctionne comme prévu dans localhost. Bien que parfois, la requête Aperçu échoue avec les preview_id
et preview_nonce
etc. et ne montre pas l'aperçu, mais lorsqu'il est défini, l'aperçu est exactement ce qu'il devrait être.