Вопрос или проблема
Я очень долго искал решение этой проблемы. Я почти справился, но не могу заставить это работать полностью.
Фон
Существует 3 типа постов, которые участвуют в этой функции: Лига, Пользователь и Продукт.
Я пытаюсь написать пользовательскую функцию, чтобы, когда клиент делает заказ в WooCommerce, его добавляют в “Лигу”. Лига определяется в Мета Продукта с использованием Пользовательского Поля Связи (через ACF). Это поле возвращает идентификаторы на основе лиги, с которой связан продукт.
Затем функция использует действие update_field в ACF для обновления ОТДЕЛЬНОГО поля связи, которое связано с Пользователем в Мета Пользователя.
Желаемый рабочий процесс
- Пользователь покупает Продукт A, который имеет поле связи ACF, связанное с Лигой A.
- WooCommerce получает идентификатор Лиги из данных Заказа/Продукта.
- Идентификатор используется для обновления поля ACF в таблице Пользователей.
- Пользователь успешно добавляется в Лигу после покупки.
Где я застрял
Я написал функцию, и она работает, как ожидается, если вы замените $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: Подробное объяснение кода
-
Получение информации о заказе: Мы используем
wc_get_order()
для получения всех данных заказа по его ID. Затем мы извлекаем информацию о покупателе и товарах заказа. -
Инициализация метаданных пользователя: При помощи
get_field()
мы получаем текущее значение метаполя, связанного с пользователем. Обратите внимание, что мы преобразуем его в массив, чтобы гарантировать, что мы можем добавлять в него новые значения. -
Работа с товарами: В цикле
foreach
мы извлекаем информацию о каждом товаре и его связанных лигах. Если у товара есть ID лиги, мы проверяем, является ли он массивом. Если это так, используемarray_merge()
для объединения с существующими значениями. Если нет, просто добавляем его в массив. -
Удаление дубликатов: Для исключения повторяющихся идентификаторов лиг мы используем
array_unique()
, что гарантирует, что в пользовательских метаданных не будет дубликатов. -
Обновление пользовательских данных: Наконец, мы вызываем
update_field()
, чтобы сохранить обновленный массив идентификаторов лиг в метаданных пользователя.
Заключение
Данный код позволяет автоматически добавлять идентификаторы лиг в пользовательские метаданные при каждом оформлении заказа с использованием ACF и WooCommerce. Поддерживается возможность добавления нескольких лиг без потери уже имеющихся значений. Убедитесь, что ваш функционал протестирован на тестовом окружении перед его внедрением на живом сайте.
Если у вас есть дополнительные вопросы или требуется помощь, не стесняйтесь обращаться!