彼の回答でbirgireが指摘したように、WordPressはAJAXを使用してメタボックスのステータスを更新し、AJAXリクエストで渡されたデータには投稿IDが含まれていないため、投稿ごとにボックスのステータスを更新することは困難です。
WordPressで使用されているAJAXアクションがであることがわかったら'closed-postboxes'
、admin jsフォルダーでこの文字列を検索して、WordPressがAJAXリクエストを作成する方法を見つけました。
私はそれがpostbox.js
118行目で起こっているのを見つけました。
それはそのように見えます:
save_state : function(page) {
var closed = $('.postbox').filter('.closed').map(function() {
return this.id;
}).get().join(',');
var hidden = $('.postbox').filter(':hidden').map(function() {
return this.id;
}).get().join(',');
$.post(ajaxurl, {
action: 'closed-postboxes',
closed: closed,
hidden: hidden,
closedpostboxesnonce: jQuery('#closedpostboxesnonce').val(),
page: page
});
}
基本的に、WordPressはクラス「postbox」とクラス「closed」のDOMアイテムを調べ、IDのコンマ区切りリストを作成します。クラス 'postbox'の隠されたDOMアイテムについても同じことが行われます。
したがって、私の考えは次のとおりです。適切なクラスがあり、非表示になっている偽のメタボックスを作成し、そのIDを投稿IDを含むように設定して、AJAXリクエストで取得できます。
これは私がやったことです:
add_action( 'dbx_post_sidebar', function() {
global $post;
if ( $post->post_type === 'mycpt' ) {
$id = $post->ID;
$f = '<span id="fakebox_pid_%d" class="postbox closed" style="display:none;"></span>';
printf( $f, $id );
}
});
このようにして、常に閉じて常に非表示のメタボックスを作成しました。そのため、WordPressはそのIDを$_POST
AJAXリクエストでvar として送信します。偽のボックスIDに予測可能な方法で投稿IDが含まれると、投稿を認識できます。
その後、WordPressがAJAXタスクを実行する方法を確認しました。
admin-ajax.php
線72で、ワードプレスは、フック'wp_ajax_closed-postboxes'
優先順位1と。
したがって、WordPressの前に行動するために、同じアクションを優先度0でフックすることができました。
add_action( 'wp_ajax_closed-postboxes', function() {
// check if we are in right post type: WordPress passes it in 'page' post var
$page = filter_input( INPUT_POST, 'page', FILTER_SANITIZE_STRING );
if ( $page !== 'mycpt' ) return;
// get post data
$data = filter_input_array( INPUT_POST, array(
'closed' => array( 'filter' => FILTER_SANITIZE_STRING ),
'hidden' => array( 'filter' => FILTER_SANITIZE_STRING )
) );
// search among closed boxes for the "fake" one, and return if not found
$look_for_fake = array_filter( explode( ',', $data[ 'closed' ] ), function( $id ) {
return strpos( $id, 'fakebox_pid_' ) === 0;
} );
if ( empty( $look_for_fake ) ) return;
$post_id = str_replace( 'fakebox_pid_', '', $look_for_fake[0] );
$user_id = get_current_user_id();
// remove fake id from values
$closed = implode(',', array_diff( explode(',', $data['closed'] ), $look_for_fake ) );
$hidden = implode(',', array_diff( explode(',', $data['hidden'] ), $look_for_fake ) );
// save metabox status on a per-post and per-user basis in a post meta
update_post_meta( $post_id, "_mycpt_closed_boxes_{user_id}", $closed );
update_post_meta( $post_id, "_mycpt_hidden_boxes_{user_id}", $hidden );
}, 0 );
ポストメタに保存されたデータを持つことは、フィルターにそれが可能になったget_user_option_closedpostboxes_mycpt
とget_user_option_metaboxhidden_mycpt
(の両方のバリエーションget_user_option_{$option}
ポストメタからWordPressのロードオプションを強制的にフィルター):
add_filter( 'get_user_option_closedpostboxes_mycpt', function ( $result, $key, $user ) {
global $post;
$meta = get_post_meta( $post->ID, "_mycpt_closed_boxes_{$user->ID}", TRUE );
if ( ! empty( $meta ) ) {
$result = $meta;
}
return $result;
}, 10, 3 );
そして
add_filter( 'get_user_option_metaboxhidden_mycpt', function ( $result, $key, $user ) {
global $post;
$meta = get_post_meta( $post->ID, "_mycpt_hidden_boxes_{$user->ID}", TRUE );
if ( ! empty( $meta ) ) {
$result = $meta;
}
return $result;
}, 10, 3 );
'get_user_option_*_post'
WPにカスタムデータを認識させるための2番目のアイデア。私があまり好きではないと思うのは、本当に信頼できない varでの使用ですwp_get_referer
が、「主な問題」を克服するためのアイデアがあると思います;)$_SERVER