Использование поля связи ACF для установки типа записи в статус черновика или опубликовано

Вопрос или проблема

В настоящее время я использую селектор поля 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);

Объяснение кода

  1. Получение значений: Мы получаем как текущие, так и предыдущие значения из отношения ACF. Это позволит вам сравнить и понять, какие записи были удалены из отношения.

  2. Проверка и изменение статуса: С помощью двух циклов foreach мы проматываем по старым и новым ID. Если было исключено старое значение из нового, мы меняем его статус на ‘draft’. Если новое значение существует в массиве, а его статус ‘draft’, то мы меняем статус на ‘publish’.

  3. Производительность: Это решение позволяет выполнять обновление только в том случае, если были изменения в поле ACF, предотвращая ненужные вызовы функции wp_update_post.

Заключение

Применение данного подхода не только поможет вам управлять статусами публикаций, но и обеспечит пользователям корректный доступ к контенту. Убедитесь, что вы тестируете изменения на тестовой среде перед применением на рабочем сайте, чтобы избежать возможных ошибок.

Если вам понадобятся дополнительные пояснения или помощь, не стесняйтесь обращаться!

Оцените материал
Добавить комментарий

Капча загружается...