Пользовательская функция WordPress – Добавление элементов из цикла Foreach в массив и обновление поля на основе массива идентификаторов (ACF + WooCommerce)

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

Я очень долго искал решение этой проблемы. Я почти справился, но не могу заставить это работать полностью.

Фон

Существует 3 типа постов, которые участвуют в этой функции: Лига, Пользователь и Продукт.

Я пытаюсь написать пользовательскую функцию, чтобы, когда клиент делает заказ в WooCommerce, его добавляют в “Лигу”. Лига определяется в Мета Продукта с использованием Пользовательского Поля Связи (через ACF). Это поле возвращает идентификаторы на основе лиги, с которой связан продукт.

Затем функция использует действие update_field в ACF для обновления ОТДЕЛЬНОГО поля связи, которое связано с Пользователем в Мета Пользователя.

Желаемый рабочий процесс

  1. Пользователь покупает Продукт A, который имеет поле связи ACF, связанное с Лигой A.
  2. WooCommerce получает идентификатор Лиги из данных Заказа/Продукта.
  3. Идентификатор используется для обновления поля ACF в таблице Пользователей.
  4. Пользователь успешно добавляется в Лигу после покупки.

Где я застрял

Я написал функцию, и она работает, как ожидается, если вы замените $value на $newvalue в действии update_field в коде ниже. Но это полностью заменяет значение в пользовательском поле в таблице Пользователей.

Я понимаю, что мне нужно сначала получить текущие значения, добавить их в массив и обновить массив новыми значениями. Затем выполнить действие update_field.

Что я пробовал

Я получаю новые идентификаторы Лиг из цикла foreach внутри функции. Я не могу вывести идентификаторы Лиг из этого цикла и поместить их в массив для обновления поля.

Код ниже ничего не возвращает, поэтому в массив вообще ничего не добавляется. Но я знаю, что логика работает, потому что если я вручную добавляю идентификаторы Лиг в массив, функция выполняется как ожидается.

Наконец, мой код

add_action( 'woocommerce_payment_complete', 'action_payment_complete', 10, 2 );
function action_payment_complete( $order_id, $order ) {
    $order = wc_get_order( $order_id );
    $items = $order->get_items();
    $user_id = $order->get_user_id();
    $acf_id = 'user_' . $user_id . '';
    // получить текущее значение
    $value = get_field('field_61b9677550d4c', $user_id, false);
    foreach ( $items as $item) {

        $product_id = $item->get_product_id();
        $newvalue = get_field('field_63128891a83f9', $product_id, false);
    }

        $value[] = $newvalue;

    update_field('field_61b9677550d4c',$value, $acf_id);

}

Работающий код с МАНУАЛЬНО добавленными элементами в массив (просто чтобы проиллюстрировать, что действительно работает)

Этот код обновляет Мета Пользователя и добавляет Лиги с ID 125 и 1768 в Мета Пользователя. Это работает правильно, но очевидно не получает идентификаторы Лиг из Мета Продукта.

add_action( 'woocommerce_payment_complete', 'action_payment_complete', 10, 2 );
function action_payment_complete( $order_id, $order ) {
    $order = wc_get_order( $order_id );
    $items = $order->get_items();
    $user_id = $order->get_user_id();
    $acf_id = 'user_' . $user_id . '';
    // получить текущее значение
    $value = get_field('field_61b9677550d4c', $user_id, false);
    foreach ( $items as $item) {

        $product_id = $item->get_product_id();
        $newvalue = get_field('field_63128891a83f9', $product_id, false);
    }

        $value[] = 125;
      $value[] = 1768;

    update_field('field_61b9677550d4c',$value, $acf_id);

}

Вам нужно установить $value как массив, независимо от того, получаете ли вы одно значение или массив. А затем добавлять другие значения в цикле.

function action_payment_complete( $order_id, $order ) {

    $order = wc_get_order( $order_id );
    $items = $order->get_items();
    $user_id = $order->get_user_id();
    $acf_id = 'user_' . $user_id . '';

    // получить текущее значение
    $value = (array)get_field('field_61b9677550d4c', $user_id, false);

    foreach ( $items as $item) {
        $product_id = $item->get_product_id();
        $newvalue = get_field('field_63128891a83f9', $product_id, false);
        if( !empty($newvalue) ){
            // добавление нового значения в массив
            $value[] = $newvalue;
        } 
    }

    update_field('field_61b9677550d4c',$value, $acf_id);
}

Ответ или решение

Чтобы решить вашу задачу по добавлению идентификаторов лиг в пользовательские метаданные при оформлении заказа в WooCommerce с использованием Advanced Custom Fields (ACF), мы можем создать функцию, которая будет аккуратно извлекать значения и обновлять их без потери существующих данных. Давайте поэтапно разберем правильный подход к достижению этого результата.

Шаг 1: Инициализация функции

Наша функция будет срабатывать при завершении оплаты заказа. Используя хук woocommerce_payment_complete, мы получим ID заказа и связанные с ним данные:

add_action('woocommerce_payment_complete', 'action_payment_complete', 10, 1);

function action_payment_complete($order_id) {
    // Получаем данные заказа
    $order = wc_get_order($order_id);
    $items = $order->get_items();
    $user_id = $order->get_user_id();

    // ID поля ACF, связанного с пользователем
    $acf_field_key = 'field_61b9677550d4c';

    // Получаем текущее значение
    $value = (array) get_field($acf_field_key, $user_id, false);

    // Проверяем, есть ли товары в заказе
    foreach ($items as $item) {
        $product_id = $item->get_product_id();

        // Извлекаем ID лиги из ACF поля, связанного с продуктом
        $new_league_ids = get_field('field_63128891a83f9', $product_id, false);

        if (!empty($new_league_ids)) {
            // Проверяем, является ли $new_league_ids массивом, и объединяем с уже существующими значениями
            if (is_array($new_league_ids)) {
                $value = array_merge($value, $new_league_ids);
            } else {
                // Если это не массив, добавляем его как элемент
                $value[] = $new_league_ids;
            }
        }
    }

    // Удаляем дубликаты в массиве
    $value = array_unique($value);

    // Обновляем поле ACF у пользователя
    update_field($acf_field_key, $value, $user_id);
}

Шаг 2: Подробное объяснение кода

  1. Получение информации о заказе: Мы используем wc_get_order() для получения всех данных заказа по его ID. Затем мы извлекаем информацию о покупателе и товарах заказа.

  2. Инициализация метаданных пользователя: При помощи get_field() мы получаем текущее значение метаполя, связанного с пользователем. Обратите внимание, что мы преобразуем его в массив, чтобы гарантировать, что мы можем добавлять в него новые значения.

  3. Работа с товарами: В цикле foreach мы извлекаем информацию о каждом товаре и его связанных лигах. Если у товара есть ID лиги, мы проверяем, является ли он массивом. Если это так, используем array_merge() для объединения с существующими значениями. Если нет, просто добавляем его в массив.

  4. Удаление дубликатов: Для исключения повторяющихся идентификаторов лиг мы используем array_unique(), что гарантирует, что в пользовательских метаданных не будет дубликатов.

  5. Обновление пользовательских данных: Наконец, мы вызываем update_field(), чтобы сохранить обновленный массив идентификаторов лиг в метаданных пользователя.

Заключение

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

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

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

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