Установка записей произвольного типа постов как приватных по умолчанию
Допустим, я создал произвольный тип записей 'Private Posts' ($post_type
= itsme_private_posts
) и хочу, чтобы все записи этого типа автоматически получали статус 'Private' при публикации (т.е. по умолчанию). Как это реализовать?
Основываясь на ответе @brasofilo на похожий вопрос на StackOverflow, я попробовал это:
add_filter( 'wp_insert_post_data', 'itsme_cpt_private', '99', 2 );
function itsme_cpt_private( $data , $postarr ) {
if( $postarr['post_type'] == 'itsme_private_posts' ) {
$data['post_status'] = 'private';
}
return $data;
}
Это не работает, т.е. ничего не меняется; все остается как было до добавления функции. Создается впечатление, что функция либо не существует, либо просто ничего не делает.
Затем, основываясь на статье "Принудительное установление произвольного типа записей как приватного", я попробовал это:
add_filter( 'wp_insert_post_data', 'itsme_cpt_private' );
function itsme_cpt_private( $post ) {
if( $post['post_type'] == 'itsme_private_posts' ) {
$post['post_status'] = 'private';
}
return $post;
}
Это работает в том смысле, что когда я публикую или обновляю запись, она становится приватной. Хорошо! Но когда я создаю новую запись ('Добавить новую') и ухожу, ничего не делая, система создает 'приватный' (авто-)черновик и сохраняет его. Более того, я даже не могу удалить эту запись!
По сути, я не могу понять, как это сделать правильно. Итак, как установить записи произвольного типа постов как приватные по умолчанию?

Проблема с кодом в вашем вопросе заключается в том, что он всегда перехватывает. Вы полностью теряете возможность не публиковать, черновики становятся невозможными. Почему это приводит к невозможности восстановить пост из корзины, я не проверял. В любом случае, это не то, что нужно.
Я рад, что решение с JavaScript работает для вас, но лично у меня две проблемы с ним: во-первых, вы можете сохранить пост как публичный, во-вторых, это усложняет работу с черновиками — поскольку скрипт всегда устанавливает переключатель в режим "приватный". В некотором смысле, теперь есть два решения для ответа.
1. Принудительное установление типа поста как приватного с визуальным указанием:
Поэтому я снова взглянул на использование переходов статуса поста и, как я уже сказал, это можно сделать с помощью Post Status Transitions.
Код:
add_action( 'transition_post_status', 'wpse118970_post_status_new', 10, 3 );
function wpse118970_post_status_new( $new_status, $old_status, $post ) {
if ( $post->post_type == 'itsme_private_posts' && $new_status == 'publish' && $old_status != $new_status ) {
$post->post_status = 'private';
wp_update_post( $post );
}
}
Это принудительно делает опубликованные посты вашего типа приватными, не мешая при этом сохранять черновики. Этого достаточно для решения проблемы приватного типа поста.
Но, конечно, было бы неплохо отразить приватную природу типа поста в метабоксе публикации. Для этого я немного изменил JavaScript. В основном, не устанавливая флажок по умолчанию, но все же меняя отображаемый текст, также я добавил заметку.
Код:
add_action( 'post_submitbox_misc_actions' , 'wpse118970_change_visibility_metabox' );
function wpse118970_change_visibility_metabox(){
global $post;
if ($post->post_type != 'post')
return;
$message = __('<strong>Примечание:</strong> Опубликованные посты всегда <strong>приватные</strong>.');
$post->post_password = '';
$visibility = 'private';
$visibility_trans = __('Приватный');
?>
<style type="text/css">
.priv_pt_note {
background-color: lightgreen;
border: 1px solid green;
border-radius: 2px;
margin: 4px;
padding: 4px;
}
</style>
<script type="text/javascript">
(function($){
try {
$('#post-visibility-display').text('<?php echo $visibility_trans; ?>');
$('#hidden-post-visibility').val('<?php echo $visibility; ?>');
} catch(err){}
}) (jQuery);
</script>
<div class="priv_pt_note">
<?php echo $message; ?>
</div>
<?php
}
Источник: Как установить видимость новых постов как приватную по умолчанию?
Примечание: По сравнению с кодом ниже я убрал установку переключателя и добавил код для сообщения.
Конечно, JavaScript не нужен для того, чтобы сделать ваш тип поста приватным, но всегда приятно иметь визуальные указания. По этой причине это хорошее дополнение.
2. Установка приватного режима как стандартного в метабоксе публикации:
Я оставляю это, потому что @its_me принял этот ответ как решение. Как я уже говорил в комментарии, я нашел полезный фрагмент кода, который устанавливает видимость в метабоксе на приватную, подключаясь к post_submitbox_misc_actions
. Как я сказал в начале: »У меня две проблемы с этим: во-первых, вы можете сохранить пост как публичный, во-вторых, это усложняет работу с черновиками — поскольку скрипт всегда устанавливает переключатель в режим "приватный"«. Все еще возможно иметь и работать с черновиками, просто это менее интуитивно, чем раньше, но статус приватной публикации никоим образом не принудительный.
Код:
add_action( 'post_submitbox_misc_actions' , 'wpse118970_change_visibility_metabox_value' );
function wpse118970_change_visibility_metabox_value(){
global $post;
if ($post->post_type != 'itsme_private_posts')
return;
$post->post_password = '';
$visibility = 'private';
$visibility_trans = __('Приватный');
?>
<script type="text/javascript">
(function($){
try {
$('#post-visibility-display').text('<?php echo $visibility_trans; ?>');
$('#hidden-post-visibility').val('<?php echo $visibility; ?>');
$('#visibility-radio-<?php echo $visibility; ?>').attr('checked', true);
} catch(err){}
}) (jQuery);
</script>
<?php
}
Источник: Как установить видимость новых постов как приватную по умолчанию?
Примечание: Я сократил код, чтобы он соответствовал потребностям здесь.

Можете, пожалуйста, привести пример, как я могу использовать это для достижения желаемого? Я не совсем уверен.

Теперь вы меня заинтересовали :) Проверя это сам. @its_me

Я понял, что $new_status
имеет значение auto-draft
, а $old_status
- new
- я соответственно изменил код. @its_me Кроме того, я нашел еще один полезный фрагмент кода, который добавляю в ответ.

Решение на JavaScript сработало, но первое — нет. Отметил как ответ, потому что оно решает мою проблему, но было бы здорово, если бы вы разобрались, что не так с первым блоком кода. Если не получится — пожалуйста, удалите его (чтобы не вводить других в заблуждение). Большое спасибо за ваше время!

Обновил ответ, не уверен, что вы получите уведомление после принятия ответа. @its_me

Да, я услышал вас и хотел сообщить, что новое решение, кажется, работает. Огромное спасибо за ваше время!

Это самый "стандартный" способ, который я нашел, чтобы установить видимость записей как приватные по умолчанию:
function wp_118970_force_type_private($post) {
if ($post['post_status'] != 'trash' && $post['post_status'] != "draft" && $post['post_status'] != "auto-draft") {
$post['post_status'] = 'private';
}
return $post;
}
add_filter('wp_insert_post_data', 'wp_118970_force_type_private');
Обратите внимание, что необходимо убедиться, что post_status не равен "trash", иначе вы не сможете удалить запись. Также мы проверяем статусы "draft" и "auto-draft", чтобы избежать установки записей как "private" во время их редактирования.
С этим кодом нет необходимости добавлять JavaScript — видимость будет установлена как приватная с самого начала.
Если вы хотите указать определенный тип записи, можно сделать так:
function wp_118970_force_type_private($post) {
if ($post['post_status'] != 'trash' && $post['post_status'] != "draft" && $post['post_status'] != "auto-draft" && $post['post_type'] == 'my_post_type') {
$post['post_status'] = 'private';
}
return $post;
}
add_filter('wp_insert_post_data', 'wp_118970_force_type_private');
Впервые я нашел это решение здесь: http://wpsnipp.com/index.php/functions-php/force-custom-post-type-to-be-private/

Это очень хорошая идея, но следует учитывать, что она делает вновь созданные записи сразу теряющими статус "черновика" и делает их "приватно опубликованными", вместо того чтобы оставлять их "черновиками" с предварительно выбранной опцией "приватно". Например, это сразу присваивает им slug (а именно slug auto-draft
), что может быть неудобно.

Вы абсолютно правы! Некоторое время после публикации этого ответа я заметил проблему и исправил свой код, но забыл обновить ответ. Теперь это сделано! Спасибо!

На основе приведенного выше ответа, вот что у меня получилось для клиентской части (javascript):
add_action( 'post_submitbox_misc_actions' , 'ourcpt_change_visibility_metabox' );
function ourcpt_change_visibility_metabox() {
global $post;
if ( 'ourcpt' != $post->post_type ) { return; }
//иначе
$post->post_password = '';
?>
<script type="text/javascript">
(function($){
try {
$( "<div class='misc-pub-section'><em>(при публикации статус становится приватным)</em></div>" ).insertAfter( $('#post-visibility-select') );
$('a.edit-visibility').css({'display': 'none'});
} catch(err){}
}) (jQuery);
</script>
<?php
}
Потому что мне нравится видеть, что именно происходит со статусом. Код для add_filter( 'wp_insert_post_data'
я использовал без изменений.
Большое спасибо за ваши решения!
