私は各投稿で複数の位置の値を取っているので、それは(常に)配列です。私の投稿メタフォームフィールドはこんな感じです:
<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 ヒット?
実は私は@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_id
やpreview_nonce
などに失敗してプレビューを表示しませんが、それらが設定されているとき、プレビューはまさにそれがあるべき姿です。