Вход • Регистрация

Сортировка товара

  • 07 октября 2016 г.
  • Добрый день. Как сделать так что бы товар в магазине сортировался по наличию. Товар которого нет в наличии был в конце списка?
    • 07 октября 2016 г.
    • В файле shop.model.php корректируете сортировку при обращении к базе данных (это если делать по уму) в следующих функциях:
      Код
      private function first_page_elements_query($time, $cat_ids){ ... }

      Код
      private function list_elements_query_count($time, $cat_ids){ ... }

      Есле не по уму, то можно сортировать во вьюшке.

      Успехов.
  • 07 октября 2016 г. , редакция: 07 октября 2016 г.
  • Немного разобрался и понял что товар сортируется по значению no_buy. Но так как товар выгружается со склада то эти значения не меняются. Поэтому сортировка не срабатывает. То есть у всего товара значение no_buy = 0
    • 07 октября 2016 г. , редакция: 07 октября 2016 г.
    • М-да, чего-то Вас не туда несет. Ну, например, берем функцию
      Код
      private function list_elements_query_count($time, $cat_ids){ ... }
      и излагаем ее вот так
      Код
      /**
      * Получает из базы данных элементы для списка элементов
      *
      * @param integer $time текущее время, округленное до минут, в формате UNIX
      * @param array $cat_ids номера категорий, элементы из которых выбираются
      * @return array
      */
      private function list_elements_query($time, $cat_ids)
      {
      switch($this->diafan->configmodules("sort"))
      {
      case 1:
      $order = 's.id DESC';
      break;
      case 2:
      $order = 's.id ASC';
      break;
      case 3:
      $order = 's.name'._LANG.' ASC';
      break;
      default:
      $order = 's.sort DESC, s.id DESC';
      }
      $rows = DB::query_range_fetch_all(
      "SELECT s.id, s.[name], s.timeedit, s.[anons], s.site_id, s.brand_id, s.no_buy, s.article, s.[measure_unit], "
      ." s.hit, s.new, s.action, s.is_file, pr.count_goods FROM {shop} AS s"
      .($this->diafan->_route->sort == 1 || $this->diafan->_route->sort == 2 ?
      " LEFT JOIN {shop_price} AS pr ON pr.good_id=s.id AND pr.trash='0'"
      ." AND pr.date_start<=".time()." AND (pr.date_start=0 OR pr.date_finish>=".time().")"
      ." AND pr.currency_id=0"
      ." AND pr.role_id".($this->diafan->_users->role_id ? " IN (0,".$this->diafan->_users->role_id.")" : "=0")
      ." AND (pr.person='0'".($this->person_discount_ids ? " OR pr.discount_id IN(".implode(",", $this->person_discount_ids).")" : "").")"
      : '')
      .($this->sort_config['use_params_for_sort'] ? " LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
      .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")
      .($this->diafan->configmodules('hide_missing_goods') && $this->diafan->configmodules('use_count_goods') ? " INNER JOIN {shop_price} AS prh ON prh.good_id=s.id AND prh.count_goods>0" : "")
      .($cat_ids ? " INNER JOIN {shop_category_rel} AS r ON s.id=r.element_id" : '')
      ." WHERE s.[act]='1' AND s.trash='0' "
      .($cat_ids ? "AND r.cat_id IN (".implode(',', $cat_ids).")" : 'AND s.site_id='.$this->diafan->_site->id)
      .($this->diafan->configmodules('where_period_element') ? " AND s.date_start<=".$time." AND (s.date_finish=0 OR s.date_finish>=".$time.")" : '')
      .($this->diafan->_route->brand ? " AND s.brand_id=".$this->diafan->_route->brand : '')
      .($this->diafan->configmodules('where_access_element') ? " AND (s.access='0' OR s.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
      .($this->diafan->configmodules('hide_missing_goods') ? " AND s.no_buy='0'" : "")
      ." GROUP BY s.id ORDER BY "."pr.count_goods ASC, "
      .($this->diafan->_route->sort ? $this->sort_config['sort_directions'][$this->diafan->_route->sort].',' : '')
      ."s.no_buy ASC, ".$order,
      $this->diafan->_paginator->polog, $this->diafan->_paginator->nastr
      );
      return $rows;
      }

      Жирным шрифтом выделил то, что добавил. Т.е. то, что необходимо добавить в данной функции для решения поставленной задачи. Тоже самое для функции
      Код
      private function first_page_elements_query($time, $cat_ids){ ... }
      Конечно, если это нужно.
      Код
      /**
      * Получает из базы данных элементы для первой страницы модуля, если категории используются
      *
      * @param integer $time текущее время, округленное до минут, в формате UNIX
      * @param array $cat_ids номера категорий, элементы из которых выбираются
      * @return array
      */
      private function first_page_elements_query($time, $cat_ids)
      {
      switch($this->diafan->configmodules("sort"))
      {
      case 1:
      $order = 'e.id DESC';
      break;
      case 2:
      $order = 'e.id ASC';
      break;
      case 3:
      $order = 'e.name'._LANG.' ASC';
      break;
      default:
      $order = 'e.sort DESC, e.id DESC';
      }
      $rows = DB::query_range_fetch_all(
      "SELECT e.id, e.[name], e.timeedit, e.[anons], e.site_id, e.brand_id, e.no_buy, e.article, e.hit,"
      ." e.[measure_unit], e.new, e.action, e.is_file, prh.count_goods FROM {shop} AS e"
      ." INNER JOIN {shop_category_rel} AS r ON e.id=r.element_id"
      .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=e.id AND a.module_name='shop' AND a.element_type='element'" : "")
      .($this->diafan->configmodules('hide_missing_goods') && $this->diafan->configmodules('use_count_goods') ? " INNER JOIN {shop_price} AS prh ON prh.good_id=e.id AND prh.count_goods>0" : "")
      ." WHERE r.cat_id IN (%s) AND e.[act]='1' AND e.trash='0'"
      .($this->diafan->configmodules('where_period_element') ? " AND e.date_start<=".$time." AND (e.date_finish=0 OR e.date_finish>=".$time.")" : '')
      .($this->diafan->configmodules('where_access_element') ? " AND (e.access='0' OR e.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
      .($this->diafan->configmodules('hide_missing_goods') ? " AND e.no_buy='0'" : "")
      ." GROUP BY e.id ORDER BY "."prh.count_goods ASC, "."e.no_buy ASC, ".$order,
      implode(',', $cat_ids),
      0, $this->diafan->configmodules("count_list")
      );
      return $rows;
      }


      Проверяйте :)
  • 07 октября 2016 г. , редакция: 07 октября 2016 г.
  • Как обещал, вот правильный код
    Код
    /**
    * Получает из базы данных элементы для первой страницы модуля, если категории используются
    *
    * @param integer $time текущее время, округленное до минут, в формате UNIX
    * @param array $cat_ids номера категорий, элементы из которых выбираются
    * @return array
    */
    private function first_page_elements_query($time, $cat_ids)
    {
    switch($this->diafan->configmodules("sort"))
    {
    case 1:
    $order = 'e.id DESC';
    break;
    case 2:
    $order = 'e.id ASC';
    break;
    case 3:
    $order = 'e.name'._LANG.' ASC';
    break;
    default:
    $order = 'e.sort DESC, e.id DESC';
    }
    $rows = DB::query_range_fetch_all(
    "SELECT e.id, e.[name], e.timeedit, e.[anons], e.site_id, e.brand_id, e.no_buy, e.article, e.hit,"
    ." e.[measure_unit], e.new, e.action, e.is_file, prh.count_goods FROM {shop} AS e"
    ." INNER JOIN {shop_category_rel} AS r ON e.id=r.element_id"
    .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=e.id AND a.module_name='shop' AND a.element_type='element'" : "")
    .($this->diafan->configmodules('hide_missing_goods') && $this->diafan->configmodules('use_count_goods') ? " INNER JOIN {shop_price} AS prh ON prh.good_id=e.id AND prh.count_goods>0" : "")
    ." WHERE r.cat_id IN (%s) AND e.[act]='1' AND e.trash='0'"
    .($this->diafan->configmodules('where_period_element') ? " AND e.date_start<=".$time." AND (e.date_finish=0 OR e.date_finish>=".$time.")" : '')
    .($this->diafan->configmodules('where_access_element') ? " AND (e.access='0' OR e.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
    .($this->diafan->configmodules('hide_missing_goods') ? " AND e.no_buy='0'" : "")
    ." GROUP BY e.id ORDER BY ".($this->diafan->configmodules('hide_missing_goods') && $this->diafan->configmodules('use_count_goods') ? "prh.count_goods ASC, " : "")."e.no_buy ASC, ".$order,
    implode(',', $cat_ids),
    0, $this->diafan->configmodules("count_list")
    );
    return $rows;
    }

    Код
    /**
    * Получает из базы данных элементы для списка элементов
    *
    * @param integer $time текущее время, округленное до минут, в формате UNIX
    * @param array $cat_ids номера категорий, элементы из которых выбираются
    * @return array
    */
    private function list_elements_query($time, $cat_ids)
    {
    switch($this->diafan->configmodules("sort"))
    {
    case 1:
    $order = 's.id DESC';
    break;
    case 2:
    $order = 's.id ASC';
    break;
    case 3:
    $order = 's.name'._LANG.' ASC';
    break;
    default:
    $order = 's.sort DESC, s.id DESC';
    }
    $rows = DB::query_range_fetch_all(
    "SELECT s.id, s.[name], s.timeedit, s.[anons], s.site_id, s.brand_id, s.no_buy, s.article, s.[measure_unit], "
    ." s.hit, s.new, s.action, s.is_file, pr.count_goods FROM {shop} AS s"
    .($this->diafan->_route->sort == 1 || $this->diafan->_route->sort == 2 ?
    " LEFT JOIN {shop_price} AS pr ON pr.good_id=s.id AND pr.trash='0'"
    ." AND pr.date_start<=".time()." AND (pr.date_start=0 OR pr.date_finish>=".time().")"
    ." AND pr.currency_id=0"
    ." AND pr.role_id".($this->diafan->_users->role_id ? " IN (0,".$this->diafan->_users->role_id.")" : "=0")
    ." AND (pr.person='0'".($this->person_discount_ids ? " OR pr.discount_id IN(".implode(",", $this->person_discount_ids).")" : "").")"
    : '')
    .($this->sort_config['use_params_for_sort'] ? " LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
    .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")
    .($this->diafan->configmodules('hide_missing_goods') && $this->diafan->configmodules('use_count_goods') ? " INNER JOIN {shop_price} AS prh ON prh.good_id=s.id AND prh.count_goods>0" : "")
    .($cat_ids ? " INNER JOIN {shop_category_rel} AS r ON s.id=r.element_id" : '')
    ." WHERE s.[act]='1' AND s.trash='0' "
    .($cat_ids ? "AND r.cat_id IN (".implode(',', $cat_ids).")" : 'AND s.site_id='.$this->diafan->_site->id)
    .($this->diafan->configmodules('where_period_element') ? " AND s.date_start<=".$time." AND (s.date_finish=0 OR s.date_finish>=".$time.")" : '')
    .($this->diafan->_route->brand ? " AND s.brand_id=".$this->diafan->_route->brand : '')
    .($this->diafan->configmodules('where_access_element') ? " AND (s.access='0' OR s.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
    .($this->diafan->configmodules('hide_missing_goods') ? " AND s.no_buy='0'" : "")
    ." GROUP BY s.id ORDER BY ".($this->diafan->configmodules('hide_missing_goods') && $this->diafan->configmodules('use_count_goods') ? "prh.count_goods ASC, " : "")
    .($this->diafan->_route->sort ? $this->sort_config['sort_directions'][$this->diafan->_route->sort].',' : '')
    ."s.no_buy ASC, ".$order,
    $this->diafan->_paginator->polog, $this->diafan->_paginator->nastr
    );
    return $rows;
    }

    Поясняю, чтобы увидеть результат такой сортировки, необходимо, чтобы параметры hide_missing_goods (не показывать отсутствующие товары) и use_count_goods (использовать количество товаров) были включены

    ИЛИ другой вариант этих функций (без использования параметров hide_missing_goods и use_count_goods)
    Код
    /**
    * Получает из базы данных элементы для первой страницы модуля, если категории используются
    *
    * @param integer $time текущее время, округленное до минут, в формате UNIX
    * @param array $cat_ids номера категорий, элементы из которых выбираются
    * @return array
    */
    private function first_page_elements_query($time, $cat_ids)
    {
    switch($this->diafan->configmodules("sort"))
    {
    case 1:
    $order = 'e.id DESC';
    break;
    case 2:
    $order = 'e.id ASC';
    break;
    case 3:
    $order = 'e.name'._LANG.' ASC';
    break;
    default:
    $order = 'e.sort DESC, e.id DESC';
    }
    $rows = DB::query_range_fetch_all(
    "SELECT e.id, e.[name], e.timeedit, e.[anons], e.site_id, e.brand_id, e.no_buy, e.article, e.hit,"
    ." e.[measure_unit], e.new, e.action, e.is_file, prh.count_goods FROM {shop} AS e"
    ." INNER JOIN {shop_category_rel} AS r ON e.id=r.element_id"
    .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=e.id AND a.module_name='shop' AND a.element_type='element'" : "")
    ." INNER JOIN {shop_price} AS prh ON prh.good_id=e.id AND prh.count_goods>0"
    ." WHERE r.cat_id IN (%s) AND e.[act]='1' AND e.trash='0'"
    .($this->diafan->configmodules('where_period_element') ? " AND e.date_start<=".$time." AND (e.date_finish=0 OR e.date_finish>=".$time.")" : '')
    .($this->diafan->configmodules('where_access_element') ? " AND (e.access='0' OR e.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
    .($this->diafan->configmodules('hide_missing_goods') ? " AND e.no_buy='0'" : "")
    ." GROUP BY e.id ORDER BY ".($this->diafan->configmodules('hide_missing_goods') && $this->diafan->configmodules('use_count_goods') ? "prh.count_goods ASC, " : "")."e.no_buy ASC, ".$order,
    implode(',', $cat_ids),
    0, $this->diafan->configmodules("count_list")
    );
    return $rows;
    }

    Код
    /**
    * Получает из базы данных элементы для списка элементов
    *
    * @param integer $time текущее время, округленное до минут, в формате UNIX
    * @param array $cat_ids номера категорий, элементы из которых выбираются
    * @return array
    */
    private function list_elements_query($time, $cat_ids)
    {
    switch($this->diafan->configmodules("sort"))
    {
    case 1:
    $order = 's.id DESC';
    break;
    case 2:
    $order = 's.id ASC';
    break;
    case 3:
    $order = 's.name'._LANG.' ASC';
    break;
    default:
    $order = 's.sort DESC, s.id DESC';
    }
    $rows = DB::query_range_fetch_all(
    "SELECT s.id, s.[name], s.timeedit, s.[anons], s.site_id, s.brand_id, s.no_buy, s.article, s.[measure_unit], "
    ." s.hit, s.new, s.action, s.is_file, pr.count_goods FROM {shop} AS s"
    .($this->diafan->_route->sort == 1 || $this->diafan->_route->sort == 2 ?
    " LEFT JOIN {shop_price} AS pr ON pr.good_id=s.id AND pr.trash='0'"
    ." AND pr.date_start<=".time()." AND (pr.date_start=0 OR pr.date_finish>=".time().")"
    ." AND pr.currency_id=0"
    ." AND pr.role_id".($this->diafan->_users->role_id ? " IN (0,".$this->diafan->_users->role_id.")" : "=0")
    ." AND (pr.person='0'".($this->person_discount_ids ? " OR pr.discount_id IN(".implode(",", $this->person_discount_ids).")" : "").")"
    : '')
    .($this->sort_config['use_params_for_sort'] ? " LEFT JOIN {shop_param_element} AS sp ON sp.element_id=s.id AND sp.trash='0' AND sp.param_id=".$this->sort_config['param_ids'][$this->diafan->_route->sort] : '')
    .($this->diafan->configmodules('where_access_element') ? " LEFT JOIN {access} AS a ON a.element_id=s.id AND a.module_name='shop' AND a.element_type='element'" : "")
    ." INNER JOIN {shop_price} AS prh ON prh.good_id=s.id AND prh.count_goods>0"
    .($cat_ids ? " INNER JOIN {shop_category_rel} AS r ON s.id=r.element_id" : '')
    ." WHERE s.[act]='1' AND s.trash='0' "
    .($cat_ids ? "AND r.cat_id IN (".implode(',', $cat_ids).")" : 'AND s.site_id='.$this->diafan->_site->id)
    .($this->diafan->configmodules('where_period_element') ? " AND s.date_start<=".$time." AND (s.date_finish=0 OR s.date_finish>=".$time.")" : '')
    .($this->diafan->_route->brand ? " AND s.brand_id=".$this->diafan->_route->brand : '')
    .($this->diafan->configmodules('where_access_element') ? " AND (s.access='0' OR s.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
    .($this->diafan->configmodules('hide_missing_goods') ? " AND s.no_buy='0'" : "")
    ." GROUP BY s.id ORDER BY ".($this->diafan->configmodules('hide_missing_goods') && $this->diafan->configmodules('use_count_goods') ? "prh.count_goods ASC, " : "")
    .($this->diafan->_route->sort ? $this->sort_config['sort_directions'][$this->diafan->_route->sort].',' : '')
    ."s.no_buy ASC, ".$order,
    $this->diafan->_paginator->polog, $this->diafan->_paginator->nastr
    );
    return $rows;
    }

    Здесь жирным шрифтом то, что добавлено, а подчеркнуто то, что изменено.

    Успехов, коллега.
    • 15 февраля 2017 г.
    • Виталий спасибо за готовый код.
      При экспресс-внедрении на 6.4 в состоянии ночного тупняка у меня возникло 2 проблемы:

      1. Функция которая делает подсчет элементов для пагинации - делала подсчет по умолчанию т.е. кол-во элементов в выдаче и в пагинации разное.
      2. Обе кастомизации кода фактически исключают из выборки товары которых нет в наличии, но как сделать чтобы те что в наличии просто шли за теми что в наличии т.е. 1й порядок сортировки по наличию (кол-ву), 2й по параметру сортировки указанному в настройках.

      Заранее спасибо!
      • 16 февраля 2017 г.
      • Виталий, ну где же ты
        • 16 февраля 2017 г. , редакция: 16 февраля 2017 г.
        • К сожалению на текущий момент очень занят. Постараюсь кратко.
          Цитата
          1. Функция которая делает подсчет элементов для пагинации - делала подсчет по умолчанию т.е. кол-во элементов в выдаче и в пагинации разное.
          Обратите внимание на функцию
          Код
          private function list_elements_query_count($time, $cat_ids){ ... }
          В этой и приведенных выше функциях, запросы должны быть аналогичными, так как одни функции выводят список (то что выше приведено), а эта функция определяет количество элементов, которые используются в пагинации.
          Цитата
          2. Обе кастомизации кода фактически исключают из выборки товары которых нет в наличии, но как сделать чтобы те что в наличии просто шли за теми что в наличии т.е. 1й порядок сортировки по наличию (кол-ву), 2й по параметру сортировки указанному в настройках.
          Обратите внимание в приведенном выше коде вот на это
          Код
          private function list_elements_query_count($time, $cat_ids)

          Да и не забывайте сбрасывать кеш, так как эти функции находятся в его зоне.
          Все это очень просто, но нет времени расписывать.
          Успехов.
  • 18 декабря 2018 г.
  • Приветствую знатоков.
    Получил в "наследство" сайт на Diafan. Стоит задача сортировать товары в категории. В настройках стоит ручная сортировка, но она не работает(((
    Как отсортировать товары по прайсу заказчика?
    Сайт perila.inoxhub.com
    • 18 декабря 2018 г.
    • Товары выводятся не в том порядке что в админке?

Новости

  • 18 июня
  • В сборке большое обновление demo-шаблона, дополнительная защита от спама, улучшение YML-импорта и еще много важного и интересного.
  • 24 апреля
  • В новой сборке совершили революцию в структурировании кастомизированной информации в шаблонах, добавили авторегистрацию пользователей, усовершенствовали защиту от спама, актуализировали накопительную скидку, а также улучшили производительность и стабильность работы системы.
  • 12 января
  • После выхода сборки 7.1 мы выпустили уже три патча, в каждом из которых улучшаем административную часть сайта. Сборка DIAFAN.CMS 7.1.3 уже доступна к установке. 

Форум