답변 에서 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를 포함하도록 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는 $_POST
AJAX 요청에서 ID를 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}
포스트 메타에서 힘 워드 프레스로드 옵션 필터) :
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가 사용자 정의 데이터를 인식 하도록 하는 데 사용 합니다. 만 너무 많이 좋아하지 않는 생각의 사용이다wp_get_referer
정말로 그$_SERVER
의 VAR 정말 신뢰할 수 없습니다는 하지만 난이 "큰 문제"를 극복하는 아이디어가 생각)