Немного поиграв, я обнаружил, что фильтр posts_where слишком навязчив для того, что я хотел сделать, поэтому я нашел альтернативу. В рамках действия «save_post», которое я прикрепил для своего пользовательского типа записи, я добавил следующую логику:
$visibility = isset($_POST['visibility']) ? $_POST['visibility'] : '';
$protected = get_option('__protected_posts', array());
if ($visibility === 'password' && !in_array($post->ID, $protected)) {
array_push($protected, $post->ID);
}
if ($visibility === 'public' && in_array($post->ID, $protected)) {
$i = array_search($post->ID, $protected);
unset($protected[$i]);
}
update_option('__protected_posts', $protected);
Это удерживает массив идентификаторов постов в таблице параметров, где пост защищен паролем. Затем в пользовательском запросе я просто передал этот массив как часть опции post__not_in
, например
$query = new WP_Query(array(
'post_type' => 'my_custom_post_type',
'post__not_in' => get_option('__protected_posts'),
));
Таким образом, я мог бы исключить защищенные записи со страницы архива, но все же позволить пользователю войти на защищенную паролем страницу для ввода пароля.