web-dev-qa-db-fra.com

Plusieurs méta-valeurs pour la même méta_key ajouter le bouton "Aperçu des modifications", mais ne pas enregistrer ou mettre à jour un message

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 nullname__, 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(), echoet 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é trueau 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 truea 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é?

3
Mayeenul Islam

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.

2
Mayeenul Islam