CMS Drupal

Делал магазин одежды на 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. На этом заострять внимание не буду, т.к. у каждого,наверное, будет свой механизм установки цен.

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступны HTML теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Строки и параграфы переносятся автоматически.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <1c7>, <drupal5>, <drupal6>, <javascript>, <php>. Beside the tag style "<foo>" it is also possible to use "[foo]".