Вопрос или проблема
Это сайт аукциона, использующий woocommerce simple auction. Я пытаюсь разработать плагин, который обновляет тип и категорию товара после завершения аукциона. Я пытаюсь сделать это вручную, выбрав все товары, у которых аукцион завершился, и сделать массовое обновление.
Плагин, похоже, “работает”, так как он обновляет тип товара и категорию. Что странно, так это то, что товар не отображается в сетке списка товаров. Это происходит только в том случае, если я вручную открываю товар и нажимаю кнопку “обновить”.
Вот код:
<?php
/**
* Имя плагина: Обновить категорию выбранных продуктов
* Описание: Позволяет администратору выбрать товары в списке и обновить их категорию на конкретную категорию.
* Версия: 1.0
* Автор: filimm
*/
if (!defined('ABSPATH')) {
exit; // Выход, если доступ напрямую
}
// Подключение скрипта для страницы администратора
function acps_enqueue_admin_script($hook) {
if ($hook === 'edit.php' && isset($_GET['post_type']) && $_GET['post_type'] === 'product') {
wp_enqueue_script('acps-admin-js', plugin_dir_url(__FILE__) . 'admin.js', array('jquery'), '1.0', true);
wp_localize_script('acps-admin-js', 'acpsAjax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'security' => wp_create_nonce('acps_nonce') // Создание nonce
));
}
}
add_action('admin_enqueue_scripts', 'acps_enqueue_admin_script');
// Добавить пользовательскую кнопку на страницу списка продуктов
function acps_add_bulk_action_button() {
global $post_type;
if ($post_type === 'product') {
echo '<button id="acps-update-category" class="button action">СДЕЛАТЬ МГНОВЕННЫМ ОПЛАТЫ</button>';
}
}
add_action('restrict_manage_posts', 'acps_add_bulk_action_button');
function alterar_tipo_produto_para_simples($product_id) {
global $wpdb;
// 1. Определить term_id типа 'simple'
$term_id_simple = $wpdb->get_var("SELECT term_id FROM {$wpdb->terms} WHERE slug = 'simple'");
if (!$term_id_simple) {
error_log("Термин 'simple' не найден.");
return;
}
// 2. Удалить запись 'product_type' для этого товара
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->term_relationships}
WHERE object_id = %d AND term_taxonomy_id IN (
SELECT term_taxonomy_id
FROM {$wpdb->term_taxonomy}
WHERE taxonomy = 'product_type'
)",
$product_id
)
);
// 3. Добавить новый тип товара 'simple'
$wpdb->query(
$wpdb->prepare(
"INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id)
SELECT %d, term_taxonomy_id
FROM {$wpdb->term_taxonomy}
WHERE taxonomy = 'product_type' AND term_id = %d",
$product_id, // ID товара
$term_id_simple // ID типа 'simple'
)
);
// 4. Убедиться, что товар опубликован
$wpdb->query(
$wpdb->prepare(
"UPDATE {$wpdb->posts}
SET post_status='publish'
WHERE ID = %d",
$product_id
)
);
// 5. Убедиться, что статус запаса товара 'in stock'
$wpdb->query(
$wpdb->prepare(
"UPDATE {$wpdb->postmeta}
SET meta_value='instock'
WHERE post_id = %d AND meta_key = '_stock_status'",
$product_id
)
);
// 6. Убедиться, что видимость товара 'visible'
update_post_meta($product_id, '_visibility', 'visible'); // Видимость в каталоге
// 7. Обновить пост, чтобы инициировать повторную индексацию товара
wp_update_post(array(
'ID' => $product_id,
'post_status' => 'publish', // Убедиться, что он опубликован
));
// 8. Очистить временные данные товара и инициировать повторную индексацию
wc_delete_product_transients($product_id);
wp_cache_flush();
error_log("Тип изменен на 'simple' в товаре ID: " . $product_id);
}
// JavaScript для обновления категории через AJAX
function acps_update_category_ajax() {
// Проверка nonce
if (!isset($_POST['security']) || !wp_verify_nonce($_POST['security'], 'acps_nonce')) {
wp_send_json_error('Доступ запрещен.');
wp_die();
}
$product_ids = isset($_POST['product_ids']) ? array_map('intval', $_POST['product_ids']) : [];
// Поиск ID категории с slug compra-imediata
$new_category = get_term_by('slug', 'compra-imediata', 'product_cat');
if ($new_category) {
$new_category_id = $new_category->term_id;
}
// Контрольная функция, которая выполняет все изменения
foreach ($product_ids as $product_id) {
// Изменить категорию товара
wp_set_object_terms($product_id, [$new_category_id], 'product_cat');
// Перевести аукционную цену в обычную цену
$auction_start_price = get_post_meta($product_id, '_auction_start_price', true);
$regular_price = get_post_meta($product_id, '_regular_price', true);
if ($auction_start_price) {
update_post_meta($product_id, '_regular_price', $auction_start_price);
update_post_meta($product_id, '_price', $auction_start_price);
} elseif ($regular_price) {
update_post_meta($product_id, '_regular_price', $regular_price);
update_post_meta($product_id, '_price', $regular_price);
} else {
error_log('Не найдены аукционные и обычные цены для товара ID: ' . $product_id);
}
// Изменить тип товара на 'simple'
alterar_tipo_produto_para_simples($product_id);
}
wp_send_json_success('Категории и типы товаров успешно обновлены.');
}
add_action('wp_ajax_acps_update_category', 'acps_update_category_ajax');
Мне действительно нужно выяснить, что я делаю неправильно.
Ответ или решение
Ваша проблема заключается в том, что обновленные товары не отображаются в сетке продуктов после изменения типа продукта и категории. Давайте подробно разберемся с возможными причинами этого поведения и предложим решения.
Проблема
В вашем коде вы используете специальный плагин для изменения типа продуктов и их категорий после окончания аукционов. Однако, несмотря на то что плагин работает, обновленные продукты не видны в админке WooCommerce до тех пор, пока вы вручную не откроете каждый продукт и не нажмете кнопку "Обновить". Это указывает на потенциальные проблемы с кэшированием или обновлением индексации продуктов.
Причины и решения
-
Кэширование и индексация:
- WooCommerce использует кэш и должно обновлять индексированные данные, чтобы отображать измененные продукты. Вы уже вызываете
wc_delete_product_transients($product_id)
для очистки трансентов, однако стоит убедиться, что это выполняется корректно.
Решение: Попробуйте добавить дополнительное обновление и кэширование после внесения всех изменений. После всех манипуляций с продуктами вызывайте:
wp_set_object_terms($product_id, [$new_category_id], 'product_cat', false); wc_delete_product_transients($product_id); update_post_meta($product_id, '_visibility', 'visible'); // Убедитесь, что видимость установлена wp_update_post(array('ID' => $product_id, 'post_status' => 'publish'));
- WooCommerce использует кэш и должно обновлять индексированные данные, чтобы отображать измененные продукты. Вы уже вызываете
-
Проблемы с метаданными:
- Убедитесь, что метаданные, такие как
_stock_status
,_visibility
,_regular_price
и_price
, заданы корректно и в нужном формате. Неправильные метаданные могут влиять на видимость продукта на странице.
- Убедитесь, что метаданные, такие как
-
Правильная работа с терминами:
- Проверьте, правильно ли вы обновляете термины. Необходимо убедиться, что новый термин действительно существует и добавляется корректно.
-
Ошибки в JavaScript:
- Если вы используете AJAX для обновления продуктов, убедитесь, что ваш скрипт выполняется без ошибок, а все необходимые данные передаются корректно. Важно использовать
console.log
для отслеживания возможных ошибок.
- Если вы используете AJAX для обновления продуктов, убедитесь, что ваш скрипт выполняется без ошибок, а все необходимые данные передаются корректно. Важно использовать
-
Проблемы совместимости с другими плагинами:
- Внезапная несовместимость с другими установленными плагинами может нарушить работу вашего кода. Попробуйте отключить другие плагины, чтобы проверить, сохраняется ли проблема.
Заключение
Согласование всех этих аспектов поможет вам устранить проблему с отсутствующими продуктами в сетке. Если проблема не исчезнет, рекомендую выполнить отладку кода с использованием инструментов, таких как error_log
, для более детального анализа выполнения скриптов. Так вы сможете быстро выявить точные места, где возникают ошибки, что упростит процесс поиска решения.