xandeadx.ru Блог музицирующего веб-девелопера

Drupal → Самые продаваемые товары (способ с полем и кроном)

Опубликовано в

В посте Вывести самые продаваемые/популярные товары в Commerce предлагал альтернативный способ вывода популярных товаров, лишённый недостатков Views способа — поле у продукт дисплея с обновляемым по крону значением. Чтобы это реализовать нужно:

1. Добавить продукт дисплею числовое поле "Число покупок" с именем field_sales_count.

2. Создать модуль с кодом:

/**
 * Implements hook_cron().
 */
function MODULENAME_cron() {
  if (variable_get('product_popularity_update_day') != date('d')) {
    // Получаем все продукт-дисплеи
    $query = new EntityFieldQuery();
    $query->entityCondition('entity_type', 'node');
    $query->propertyCondition('type', 'product_display');
    $result = $query->execute();
 
    if ($result) {
      $field_sales_count_info = field_info_field('field_sales_count');
      $fields = array($field_sales_count_info['id']);
 
      // Обновляем значение поле field_sales_count без вызова entity_save()
      // http://xandeadx.ru/blog/drupal/634
      foreach ($result['node'] as $row) {
        $node = (object)array(
          'nid' => $row->nid,
          'vid' => $row->vid,
          'type' => 'product_display',
        );
        $node->field_sales_count['und'][0]['value'] = MODULENAME_get_product_display_sales_count($row->nid);
        field_sql_storage_field_storage_write('node', $node, 'update', $fields);
      }
 
      cache_clear_all('field:node:', 'cache_field', TRUE);
    }
 
    variable_set('product_popularity_update_day', date('d'));
    watchdog('modulename', 'Product popularity updated.');
  }
}
 
/**
 * http://xandeadx.ru/blog/drupal/804
 */
function MODULENAME_get_product_display_sales_count($product_display_nid) {
  $query = db_select('node', 'n');
  $query->addExpression('COUNT(*)');
  $query->innerJoin('field_data_field_product', 'ffp', 'ffp.entity_id = n.nid');
  $query->innerJoin('field_data_commerce_product', 'fcp', 'fcp.commerce_product_product_id = ffp.field_product_product_id');
  $query->innerJoin('commerce_line_item', 'l', 'l.line_item_id = fcp.entity_id');
  $query->innerJoin('commerce_order', 'o', 'o.order_id = l.order_id');
  $query->condition('o.status', 'completed');
  $query->condition('n.nid', $product_display_nid);
  return $query->execute()->fetchField();
}

3. Сбросить кэш, запустить крон.

В MODULENAME_get_product_display_sales_count можно добавить условие на дату заказа, чтобы например считать только заказы за последний месяц:

$query->condition('o.created', strtotime('-1 month'), '>');

По производительности — при 2000 товарах и 2000 заказов крон отрабатывает за 4-5 секунд. При значительно бОльших количествах или при необходимости использовать node_save() (например для индексации в Search API) есть смысл переписать на Queue API.

Написанное актуально для Commerce 1
Похожие записи

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

Здравствуйте,

Создал view, отсортировал по полю field_sales_count.

Не подскажите как сделать разные выводы этой вьюхи: 1) за всё время 2) за месяц 3) за неделю?

Спасибо

создать три поля

Я не силён в php. Не подскажите, как надо изменить ваш код, чтобы добавить 3 условия к 3 разным полям? (ведь не делать же 3 модуля отдельных для этого)

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

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании