web-dev-qa-db-ja.com

"変更のプレビュー"に追加された同じmeta_keyの複数のメタ値はヒットしますが、投稿の保存や更新にはヒットしません

私は各投稿で複数の位置の値を取っているので、それは(常に)配列です。私の投稿メタフォームフィールドはこんな感じです:

<select name="<?php echo $project_prefix; ?>offer_locations[]" id="<?php echo $project_prefix; ?>offer_locations" required multiple="multiple">
    ...
    ...
    ...
</select>

投稿に位置の値がなくても既に存在する場合、既存の値はnullになりますが、このフィールドは必須なので、新しい保存場所の値[保存時]は必ず配列になるので、postmetaの値を追加する必要があります。

私がarray_diff()で作った条件はうまく働いています。カスタムシナリオを作成してコードをチェックし、WordPressでもコードをチェックしました( カスタムコードブロック )。var_dump()echo、およびexit()がインラインで表示されます。しかし...

<?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 );

投稿を保存または更新したときに、場所のメタフィールドが正しく機能しています。しかし、データ入力オペレータが Preview Changes ボタン、add_post_meta()は真の条件付き括弧内でさえもトリガーしていて、重複したエントリーを追加しています、どうやっていいのかわからない!!!:o

次に、最後のパラメータ(40行目)にtrueを追加して値を一意にし、重複したエントリを停止できるようにしました。しかし、trueを追加すると、保存してもmeta_keyに新しい値が追加されなくなりました。

にメタ値を追加するのをやめるにはどうすればよいですか。 Preview Changes ヒット?

3
Mayeenul Islam

実は私は@ialocinからの回答を希望しています。しかし、コードはコメント欄には少し長いので、私は答えとしてここに投稿しています。しかし、私は状況にもっと適した答えを受け入れたいと思います。

@ ialocinの提案の後、私はそれを得ました、$post_idは、 Preview Changes ヒットしたので、$existing_locationsは正しいdb情報を得ていませんでした。今、私は次の行を変更しました:

$existing_locations = get_post_custom_values( "{$project_prefix}post_locations", $post_id );

次の条件行に入れます。

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 );
}

Localhostでは期待通りにすべてが動作しています。時々、Previewヒットはpreview_idpreview_nonceなどに失敗してプレビューを表示しませんが、それらが設定されているとき、プレビューはまさにそれがあるべき姿です。

2
Mayeenul Islam