Вопрос или проблема
В настоящее время я использую селектор поля ACF Relationship для запроса через пользовательский тип записи для местоположений, чтобы отображать различные страницы. Эти страницы – это страницы “услуг”, которые могут быть показаны или скрыты от конечного пользователя. Проблема в том, что если человек снимет отметку с страницы услуги, она технически все равно будет видна пользователю, если он знает ссылку. Мне нужно иметь возможность установить статус страницы в черновик или опубликованную при обновлении этой опции. Вот что у меня есть на основе других примеров, связанных с аналогичным запросом.
function my_acf_update_value( $value, $post_id, $field ) {
$ids = get_field('our_services', 'options');
$services = get_posts(array(
'post_type' => 'services',
'post_status' => 'draft',
'post__not_in' => $ids,
));
wp_update_post($services);
}
add_filter('acf/update_value/key=field_5c37e435', 'my_acf_update_value', 10, 4);
Когда я сделал это в первый раз, это сразу установило их все в черновик без обновления опции поля ACF relationship. Мне нужно ли подключаться к кнопке “обновить” в моих опциях?
Нет смысла использовать хук init, потому что этот хук будет вызываться при каждой загрузке страницы.
Если вы хотите обновлять статус страниц каждый раз, когда кто-то обновляет поле, вы можете использовать любой из следующих хуков:
- acf/update_field – этот фильтр срабатывает каждый раз, когда поле обновляется перед его сохранением в базу данных. Этот хук является частью плагина ACF.
- update_post_meta – этот экшен срабатывает каждый раз, когда поле обновляется перед его сохранением в базу данных, но он является частью ядра WordPress.
- updated_post_meta – этот экшен срабатывает каждый раз, когда поле обновляется после его сохранения в базу данных. Этот хук также является частью ядра WordPress.
Первый передает четыре аргумента своему обработчику: $value, $post_id, $field, $original. Вы можете узнать больше об этом здесь.
А последние два хука передают четыре аргумента своим обработчикам: $meta_id, $object_id, $meta_key, $meta_value. Вы можете узнать больше о них здесь и здесь.
Ответ или решение
Проблема, с которой вы столкнулись, действительно актуальна для многих разработчиков, работающих с плагином Advanced Custom Fields (ACF) и пользовательскими типами записей в WordPress. Ваша цель — автоматизировать процесс изменения статуса записей с "опубликованных" на "черновики" при их исключении из отношения ACF, чтобы предотвратить доступ к скрытым страницам через прямые ссылки.
Настройка статуса записей с использованием ACF Relationship
Чтобы решить эту задачу, необходимо правильно использовать хуки ACF и WordPress. Ранее вы пытались использовать хук acf/update_value
, однако это может изменять статус записей слишком рано, не дожидаясь завершения обновления ACF. Вместо этого целесообразно использовать следующие хуки:
-
acf/update_field: Этот хук срабатывает перед сохранением изменения поля и позволит вам осуществить необходимые проверки.
-
updated_post_meta: Этот хук вызовется после сохранения данных и позволит вам изменять статус записей на основании полученных значений.
Ниже представлен пример реализации, который отвечает вашей задаче:
function update_service_post_status( $value, $post_id, $field, $original ) {
// Получаем массив ID услуг из поля ACF
$current_ids = $value; // обновленные значения
$previous_ids = $original; // предыдущие значения
// Убираем ненужные значения из массива
if ( is_array($previous_ids) ) {
foreach ( $previous_ids as $old_id ) {
if ( !in_array($old_id, $current_ids) ) {
// Если ID услуги исключен, меняем статус на 'draft'
$service_post = array(
'ID' => $old_id,
'post_status' => 'draft',
);
wp_update_post($service_post);
}
}
}
// Устанавливаем все новые ID на 'publish'
if ( is_array($current_ids) ) {
foreach ( $current_ids as $new_id ) {
// Меняем статус на 'publish', если он 'draft'
$service_post = array(
'ID' => $new_id,
'post_status' => 'publish',
);
wp_update_post($service_post);
}
}
return $value; // Возвращаем обновленное значение
}
add_filter('acf/update_value/key=field_5c37e435', 'update_service_post_status', 10, 4);
Объяснение кода
-
Получение значений: Мы получаем как текущие, так и предыдущие значения из отношения ACF. Это позволит вам сравнить и понять, какие записи были удалены из отношения.
-
Проверка и изменение статуса: С помощью двух циклов
foreach
мы проматываем по старым и новым ID. Если было исключено старое значение из нового, мы меняем его статус на ‘draft’. Если новое значение существует в массиве, а его статус ‘draft’, то мы меняем статус на ‘publish’. -
Производительность: Это решение позволяет выполнять обновление только в том случае, если были изменения в поле ACF, предотвращая ненужные вызовы функции
wp_update_post
.
Заключение
Применение данного подхода не только поможет вам управлять статусами публикаций, но и обеспечит пользователям корректный доступ к контенту. Убедитесь, что вы тестируете изменения на тестовой среде перед применением на рабочем сайте, чтобы избежать возможных ошибок.
Если вам понадобятся дополнительные пояснения или помощь, не стесняйтесь обращаться!