Делал магазин одежды на Ubercart для Drupal 6. Хотел было в этот раз сделать все таки на Drupal 7, но практически сразу же случился затык с добавлением картинок к опциям товаров. Т.е. модуль uc_option_image для 7-ки толком не работает. Поэтому пришлось идти по старой протоптанной дорожке.
Как видно из заголовка сайт состоит из двух частей. Первый сайт - это сайт производителя(для оптовиков), второй сайт - это розничный магазин. Товары должны быть общими, а вот цены разные, при чем цены хранятся в опциях атрибута Размер.
Ключевой вопрос в данном случае - это таблица с опциями и ценами товаров "uc_product_options". Тут возможны два варианта:
- Делать эту таблицу общей между двумя сайтами и тогда активно пользуемся хуками типа hook_uc_price_handler и (или) hook_cart_item)
- Делать разные таблицы с соответствующими префиксами и дублировать в них данные.
Первый вариант на первый взгляд кажется более правильным, но чреват осложнениями, т.к. не можно где-то что-то не учесть и цена выскочит не так, которую ждешь. Кроме того у меня еще был задействован модуль со скидками uc_discounts_alt и я все таки побоялся идти этим путем.
Итак, я выбрал второй вариант. Но тут тоже не все так просто, т.к. нужно было организовать механизм автоматической синхронизации данных в двух таблицах "uc_product_options". Никаких хуков, которые бы позволили мне вклинится в процесс добавления/обновления/удаления опций от модуля uc_attribute я не нашел. Хук nodeapi при редактировании опций товаров тоже не подошел, т.к. не срабатывает.
Делать синхронизацию по крону - мягко говоря не очень хорошо. Поэтому вынужден был хакать друпаловское ядро, а если точнее то в файле database.mysql-common.inc изменяем функцию db_query:
function db_query($query) { // XA global $db_prefix; global $uc_update_price_process; // Для модуля обновления цен static $counter = 0; $original_query=$query; // XA $args = func_get_args(); $original_args = $args; // XA array_shift($args); $query = db_prefix_tables($query); if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax $args = $args[0]; } _db_query_callback($args, TRUE); $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); // XA if (!$uc_update_price_process && $counter==0 && strtoupper(substr(trim($original_query),0,6)) != 'SELECT') { $pos = strpos($original_query, "uc_product_options"); if ($pos === false) { // not found... } else{ $counter = 1; // Временно подменим префиксы $original_prefix = $db_prefix; if ($db_prefix == '') { $db_prefix = array ( 'default' => '', 'uc_product_options'=>'shop_' ); } else{ if (is_array($db_prefix) && $db_prefix['uc_product_options'] == 'shop_') { $db_prefix = ''; } else{ // Что-то не то $counter = 0; return ""; } } call_user_func_array("db_query", $original_args); // Вернем префиксы обратно $db_prefix = $original_prefix; } } $counter = 0; // XA return _db_query($query); }
Описание начну с того, что таблицы основного сайта у меня без префикса, а таблицы розничного магазина с префиксом "shop_". Идея такая, что запросы на изменение таблицы "uc_product_options" (т.е. все запросы кроме SELECT) должны производится по двум таблицам(с префиксом и без). А запросы SELECT в свою очередь выполняются по таблице с соответствующим префиксом из настроек сайта(переменная $db_prefix из settings.php).
Преимущества данного подхода в том, что не надо думать над тем, откуда будет запрос на изменение данных.
Все запросы здесь будут перехвачены и таблицы будут синхронизированы. Недостаток, конечно, это то, что пришлось трогать ядро. Кроме того, необходимо предусмотреть механизм обновления цен, т.к. в данном случае при изменении цен товара на одном сайте, такие же цены автоматом перекинутся и на второй. Лично я принял за правило, что цены будут устанавливаться на оптовом сайте. В розничном магазине при этом на странице с редактированием опций товаров я заблокировал кнопку сохранения (с помощью jQuery):
<script> $(document).ready(function (){ $("#uc-object-options-form .form-submit").attr("disabled", true); }) </script>
Что касается самого механизма изменения цен. В PHP коде фигурирует переменная $uc_update_price_process. Это как раз для моего отдельного модуля для установки цен. Заказчик захотел, чтобы цены можно было проставлять не на каждый товар и каждую опцию (каждый размер в данном случае), а на всю группу товаров(термин таксономии) по размерам. Кроме того, цены в розничном магазине высчитываются автоматом от цен оптового магазина, увеличиваясь на процент. Так что обновление цен в таблице "uc_product_options" я делаю из своего модуля и лишняя движуха с синхронизацией таблиц в данном случае мне не нужна, поэтому в своем модуле я пишу $uc_update_price_process = true и только после этого делаю запрос UPDATE. На этом заострять внимание не буду, т.к. у каждого,наверное, будет свой механизм установки цен.
Отправить комментарий