Программное обновление пользовательских атрибутов WooCommerce

17 нояб. 2015 г., 11:54:55
Просмотры: 18.8K
Голосов: 2

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

В моей среде Wordpress (тема Enfold, плагин WooCommerce) я создал систему для использования опроса в качестве входных данных для мгновенного создания постов на фронтенде сайта. Ответы из опроса включаются в автоматически генерируемые посты (тип 'product') вместе с пользовательскими атрибутами WooCommerce.

Я написал пользовательские запросы, реагирующие на триггеры в mySQL - вставляющие и обновляющие wp_posts, wp_terms, wp_postmeta, wp_term_relationships.

Все работает отлично, кроме одного: пользовательские атрибуты товаров WooCommerce не отображаются мгновенно в выпадающих/селект фильтрах на сайте. Однако 'ручное' нажатие кнопки Обновить на странице Wordpress решает проблему.

Я ищу способ точно повторить 'ручное' нажатие Обновить в CMS Wordpress. На данный момент сам пост успешно загружается на сайте, но его атрибуты товара WooCommerce не инициализируются.

До сих пор я пробовал множество обходных путей:

  • Программное установление статуса поста (черновик) и мгновенное изменение на опубликованный пост (publish);
  • Использование встроенного планировщика публикаций Wordpress, устанавливая время публикации;
  • Вызов wp_update_post;
  • Использование плагина Tao Scheduled Updates (https://nl.wordpress.org/plugins/tao-schedule-update/);
  • Использование плагина WordPress PostController (https://github.com/HarriBellThomas/Wordpress_PostController)

Тем не менее, все попытки обновляют только посты в wp_posts, по-видимому, не затрагивая базовые отношения/пользовательские атрибуты товаров.

Моя единственная просьба - программно повторить нажатие на 'Обновить' в среде CMS Wordpress. Это помогло бы мне автоматизировать процесс вместо ручного вмешательства.

Не могли бы вы предложить способ сделать это?

Большое спасибо за ваше время!

ОБНОВЛЕНИЕ:

Привет, Том,

После изучения твоего ответа я все еще не понимаю.

Мои запросы обновляют/вставляют все необходимые таблицы. Они практически повторяют все шаги из упомянутых тобой php-скриптов.

Когда я проверяю товар в CMS, я вижу, что все данные - и особенно атрибуты - загружаются корректно. Когда я вручную нажимаю Обновить в CMS и сравниваю данные в таблицах mySQL до и после обновления, я не вижу значительных различий. Единственное, что я замечаю - это значение _product_attributes в wp_postmeta, которое немного отличается (сериализованная строка).

Однако, когда я экспериментирую с этим значением (очищаю/изменяю его для конкретного поста в wp_postmeta), ничего не меняется в атрибутах - и все по-прежнему работает при фильтрации.

Это приводит меня к вопросам:

  • Что именно происходит при ручном нажатии 'Обновить'?
  • Существует ли какое-то другое хранилище, кроме таблиц mySQL, где части каким-то образом связаны?
  • Можно ли мне 1) принять процедуру 'создания товара', на которую ты ссылаешься, как данность и пропустить ее (так как я запускаю свои запросы), а затем 2) вызвать только точную процедуру, которая выполняется при нажатии Обновить - чтобы она 'связала' все вместе без повторного создания всех записей в базе данных?
  • Если да, то где мне найти эту конкретную процедуру?

Твоя помощь очень ценится. Спасибо! Том

2
Комментарии

Вы добавляете товары в базу данных через свои "пользовательские триггеры" или MySQL-триггеры срабатывают, когда вы вставляете данные в базу через WordPress? Или вы вручную вставляете данные WordPress (товары?) в базу, и они появляются в админке? Если вы уточните, я смогу помочь.

Tom Tom
17 нояб. 2015 г. 13:08:38

Спасибо за быстрый ответ, Том. Процесс работает следующим образом: - Пользователь заполняет опрос в таблице wp_fsq_data - Триггер обнаруживает вставку в эту таблицу опроса и выполняет запрос 1: чтение сериализованной строки из таблицы 'conv1' - Триггер обнаруживает вставку в таблицу conv1 и выполняет запрос 2: преобразование числовых значений в строки во временной таблице 'conv2' - Триггер обнаруживает вставку в таблицу conv2 и выполняет запрос 3: вставку/обновление всех данных в структуре WP (wp_posts, wp_terms, wp_postmeta, wp_relationships) - Запись появляется на фронтенде без атрибутов в выпадающих списках/селекторах.

Thom Rommens Thom Rommens
17 нояб. 2015 г. 13:30:44
Все ответы на вопрос 3
1

Хорошо, у меня была похожая проблема, и я расскажу, как её решить.

Всё работает отлично, за исключением одного: пользовательские атрибуты товаров WooCommerce не отображаются мгновенно в выпадающих списках/фильтрах на сайте. Однако, если вручную нажать "Обновить" в админке WordPress, всё начинает работать.

При отображении атрибутов WooCommerce использует функцию: wc_get_attribute_taxonomies() (http://woocommerce.wp-a2z.org/oik_api/wc_get_attribute_taxonomies/)

Вы заметите, что эта функция получает данные из 'транзиента' (это кешированные данные, см. http://codex.wordpress.org/Transients_API).

Если вы вручную загружаете данные в базу данных, возможно, вы пропустили загрузку транзиента (который, кстати, хранится в таблице wp_options). Когда вы нажимаете "Обновить" в админке WordPress, запускается функция, которая обновляет транзиент, и поэтому атрибуты начинают отображаться.

Чтобы это исправить, убедитесь, что при ручном обновлении MySQL вы также обновляете транзиент. В моём случае, при ручном добавлении атрибутов товаров в WooCommerce, мне пришлось добавить строку в таблицу wp_options с options_name равным _transient_wc_attribute_taxonomies и моими атрибутами в сериализованном массиве в колонке option_value (плюс ID с автозагрузкой, установленной в 'yes'). Но есть и другие транзиенты, поэтому всё зависит от того, какая функция вызывает проблему и что именно вы пытаетесь отобразить. Вы можете определить, какой транзиент отсутствует, выполнив поиск в MySQL по %transient% в таблице wp_options до нажатия кнопки "Обновить" в админке WordPress и после, а затем сравнить данные.

1 апр. 2016 г. 18:29:15
Комментарии

Транзиенты — это именно то, в чем проблема, и почему изменения не отображаются на фронтенде. Чёртовы транзиенты!

Solomon Closson Solomon Closson
9 сент. 2016 г. 18:28:34
2

Обновляете ли вы также термины внутри товара WooCommerce? И wp_term_taxonomy, и wp_woocommerce_attribute_taxonomies должны быть обновлены вашими таксономическими терминами, чтобы товар WooCommerce мог отображать выпадающие списки вариаций "Цвет" или "Размер".

При программном создании товара WooCommerce, вариации продукта необходимо вставить и привязать к существующим атрибутам (таксономиям, созданным в WooCommerce).

Обратите внимание на мета-ключ поста "_product_attributes", который хранит данные атрибутов. Вам все равно нужно будет связать термины (атрибуты) с вашим товаром (внутри wp_term_taxonomy), но, надеюсь, это даст вам направление для дальнейших действий.

Также посмотрите функции create_product (https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-products.php#L237) и save_variations (https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-products.php#L1692), в которых описано, как выполняется создание товара и его вариаций.

17 нояб. 2015 г. 13:46:42
Комментарии

Ещё раз спасибо, Том. Да, забыл упомянуть wp_term_taxonomy. Да, я тоже вставляю/обновляю эту таблицу.

Поскольку набор атрибутов не меняется и в wp_woocommerce_attribute_taxonomies не регистрируется количество, что именно там нужно обновлять?

Спасибо за ссылки. Я изучу их и дам вам знать!

С уважением, Том

Thom Rommens Thom Rommens
17 нояб. 2015 г. 15:02:01

Том, это сработало у тебя?

Tom Tom
18 окт. 2017 г. 15:35:46
0
-1

Это один из вариантов с PHP кодом:

function change_price_by_type( $product_id, $price, $price_type) {
   update_post_meta( $product_id, '_' . $price_type, $price );
}

function change_price_all_types( $product_id, $price ) {
    change_price_by_type( $product_id, $price, 'price' );
    change_price_by_type( $product_id, $price, 'sale_price' );
    change_price_by_type( $product_id, $price, 'regular_price');
}


function change_product_price( $product_id, $price ) {
    change_price_all_types( $product_id, $price ); 
    $product = wc_get_product( $product_id ); // Обработка вариативных товаров

    if ( $product->is_type( 'variable' ) ) {
        // RM: Получаем вариации, включая те, которых нет в наличии
        $args = array(
        'post_type'     => 'product_variation',
        'post_status'   => array( 'private', 'publish' ),
        'numberposts'   => -1,
        'orderby'       => 'menu_order',
        'order'         => 'asc',
        'post_parent'   => $product_id // $post->ID 
        );
        $variations = get_posts( $args ); 
        foreach ( $variations as $variation ) {
                change_price_all_types( $variation->ID, $price );
        }
    }
}

$args     = array( 'post_type' => 'product', 'posts_per_page' => 3000);
$products = get_posts( $args ); 

foreach($products as $product) {
    change_product_price($product->ID, 9.99);
    echo $product->ID;
}

exit;

затем перейдите в phpMyAdmin и выполните следующие SQL запросы (возможно, вам потребуется изменить название таблицы вместо wp_).

UPDATE `wp_postmeta`
SET `meta_value` = ''
WHERE `meta_key` IN ('_sale_price', '_sale_price_dates_from', '_sale_price_dates_to')
  AND `post_id` IN
    (SELECT `ID`
     FROM `wp_posts`
     WHERE `post_type` = 'product'
       AND `post_status` = 'publish' );

Очистить кеш:

DELETE
FROM `wp_options`
WHERE (`option_name` LIKE '_transient_wc_var_prices_%'
    OR `option_name` LIKE '_transient_timeout_wc_var_prices_%')

SQL код взят с: http://www.technoedu.com/forums/topic/wordpress-solved-copy-woocommerce-products-sale-prices-to-regular-prices-and-reset-sale-prices/

12 сент. 2017 г. 16:10:03