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

Полезное дополнение функции show_block module="shop"

  • 25 февраля 2017 г.
  • Как добавить к шаблонному тегу show_block module="shop" аргумент, чтобы он выводил только товары, которые есть в наличии, про том, что в настройках товара не стоит галка "показывать только те товары что есть в наличии" т.е. в листинге товаров у нас будут все товары, а show_block - можно будет настроить чтобы она показывала только то, что есть в наличии?

    Допустим у нас будет что-то вроде <insert name="show_block" module="shop" images="1" count="4" sort="rand" in_stock="true">
    Где *in_stock="true"* - выводить только то что есть в наличии.

    Правим любо используем частичную кастомизацию файла */modules/shop/shop.php*
    В нем правим функцию *public function show_block* где добавляем булевый аргумент in_stock. Заменяем первый блок кода на:

    Код


    $attributes = $this->get_attributes($attributes, 'count', 'site_id', 'cat_id', 'brand_id', 'sort', 'images', 'images_variation', 'param', 'hits_only', 'action_only', 'new_only', 'discount_only', 'only_module', 'only_shop', 'tag', 'template', 'in_stock');

    $count = $attributes["count"] ? intval($attributes["count"]) : 3;
    $site_ids = explode(",", $attributes["site_id"]);
    $cat_ids = explode(",", $attributes["cat_id"]);
    $brand_ids = explode(",", $attributes["brand_id"]);
    $sort = in_array($attributes["sort"], array("date", "rand", "price", "sale")) ? $attributes["sort"] : "";
    $images = intval($attributes["images"]);
    $images_variation = $attributes["images_variation"] ? strval($attributes["images_variation"]) : 'medium';
    $param = $attributes["param"];
    $hits_only = (bool) $attributes["hits_only"];
    $action_only = (bool) $attributes["action_only"];
    $new_only = (bool) $attributes["new_only"];
    $discount_only = (bool) $attributes["discount_only"];
    $tag = $attributes["tag"] && $this->diafan->configmodules('tags', 'shop') ? strval($attributes["tag"]) : '';
    $in_stock = (bool) $attributes["in_stock"];


    теперь функция может принимать аргумент in_stock и мы идем править модельку shop.model.php
    Там правим public function show_block
    Делаем чтобы она сама могла принимать наш новый аргумент in_stock:

    Код
    public function show_block($count, $site_ids, $cat_ids, $brand_ids, $sort, $images, $images_variation, $param, $hits_only, $action_only, $new_only, $discount_only, $tag, $in_stock)


    Далее правим коды mysql запросов:
    ищем
    Код
    $max_count = DB::query
    и правим блок кода на:

    Код


    $max_count = DB::query_result("SELECT COUNT(DISTINCT e.id) FROM {shop} as e"
    .$inner
    .($discount_only ? " INNER JOIN {shop_price} AS pr ON pr.good_id=e.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->diafan->configmodules('where_access_element', 'shop') ? " 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', 'shop') && $this->diafan->configmodules('use_count_goods', 'shop') || $in_stock ? " INNER JOIN {shop_price} AS prh ON prh.good_id=e.id AND prh.count_goods>0" : "")
    ." WHERE e.[act]='1' AND e.trash='0'"
    .$where
    .($this->diafan->_site->module == 'shop' && $this->diafan->_route->show ? " AND e.id<>".$this->diafan->_route->show : '')
    .($hits_only ? " AND e.hit='1' " : "")
    .($action_only ? " AND e.action='1' " : "")
    .($new_only ? " AND e.new='1' " : "")
    .($discount_only ? " AND pr.discount_id>0" : "")
    .($this->diafan->configmodules('where_period_element', 'shop') ? " AND e.date_start<=".$time." AND (e.date_finish=0 OR e.date_finish>=".$time.")" : '')
    .($this->diafan->configmodules('where_access_element', 'shop') ? " AND (e.access='0' OR e.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
    .($this->diafan->configmodules('hide_missing_goods', 'shop') ? " AND e.no_buy='0'" : ""),
    $values
    );



    далее ищем место где начинается
    Код
    foreach ($rands as $rand)
    {
    $rows = DB::query_fetch_all..`


    и правим блок кода чтобы получилось:
    Код


    $rows = DB::query_fetch_all("SELECT e.id, e.[name], e.[anons], e.timeedit, e.site_id, e.brand_id, e.no_buy, e.article,
    e.[measure_unit], e.hit, e.new, e.action, e.is_file".($sort == "sale" ? ", COUNT(g.id) AS count_sale" : "")."
    FROM {shop} AS e"
    . ($sort == "sale" ? " INNER JOIN {shop_order_goods} AS g ON g.good_id=e.id AND g.trash='0'" : '')
    . ($sort == "price" || $discount_only ? " INNER JOIN {shop_price} AS pr ON pr.good_id=e.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).")" : "").")"
    : '')
    .$inner
    .($this->diafan->configmodules('where_access_element', 'shop') ? " 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', 'shop') && $this->diafan->configmodules('use_count_goods', 'shop') || $in_stock ? " INNER JOIN {shop_price} AS prh ON prh.good_id=e.id AND prh.count_goods>0" : "")
    ." WHERE e.[act]='1' AND e.trash='0'"
    .($this->diafan->_site->module == 'shop' && $this->diafan->_route->show ? " AND e.id<>".$this->diafan->_route->show : '')
    .($hits_only ? " AND e.hit='1' " : "")
    .($action_only ? " AND e.action='1' " : "")
    .($new_only ? " AND e.new='1' " : "")
    .($discount_only ? " AND pr.discount_id>0" : "")
    .$where
    .($this->diafan->configmodules('where_period_element', 'shop') ? " AND e.date_start<=".$time." AND (e.date_finish=0 OR e.date_finish>=".$time.")" : '')
    .($this->diafan->configmodules('where_access_element', 'shop') ? " AND (e.access='0' OR e.access='1' AND a.role_id=".$this->diafan->_users->role_id.")" : '')
    .($this->diafan->configmodules('hide_missing_goods', 'shop') ? " AND e.no_buy='0'" : "")
    ." GROUP BY e.id"
    .$order
    .' LIMIT '
    .($sort == "rand" ? $rand : 0).', '
    .($sort == "rand" ? 1 : $count), $values);
    $this->result["rows"] = array_merge($this->result["rows"], $rows);



    жирным пометил то, что добавилось.

    Всем хорошего настроения :)
    • 25 февраля 2017 г.
    • В solution надо выложить, а то на форуме затеряется.Спасибо
      • 26 февраля 2017 г.
      • на модерации )
        • 26 февраля 2017 г. , редакция: 26 февраля 2017 г.
        • Цитата
          на модерации )


          На мой взгляд, задумка логически ошибочна, а соответственно не совсем корректный код.

          Поясню.

          Во-первых, Вы ввели параметр in_stock. Т.е. Вы собираетесь фильтровать товары по их количеству (если кол-во равно нулю, то товар отсутствует). Однако, в своем коде Вы применяете данный параметр без учета другого параметра cms:
          use_count_goods - флаг использования количества товара в cms (устанавливается в админке, настройке модуля shop).
          Таким образом, мне интересно, какой результат Вы хотите получить, используя свой in_stock, если в cms не используются указания на количество товара (use_count_goods).

          Во-вторых, в cms уже есть флаг - hide_missing_goods - скрывать отсутствующий товар (устанавливается в админке, настройке модуля shop). Интересно, как Вы полагаете: Ваш новый параметр in_stock дополняет или дублирует имеющиеся параметры cms?

          Еще раз подчеркну. Это не критика Вашего кода, а изложение мнения о избыточности ввода новых (дублирующих) параметров в cms.
          • 27 февраля 2017 г.
          • Коллега, мнение одного из самых опытных разработчиков данного форума для меня бесценно :)

            Поясню. Мне нужно было средство, которое позволит в лишь в некоторых местах показывать то у чего кол-во больше нуля. Т.е. в листинге у меня показываются ВСЕ товары с сортировкой по наличию (которую), как потребовал наш СЕОшник, а в различных "заманухах" уже использую show block с данным аргументом.
            • 27 февраля 2017 г. , редакция: 27 февраля 2017 г.
            • Полагаю, что необходимость данной модернизации может пригодится только в одном случае: если в настройках модуля активирована возможность использования количества (use_count_goods) и не активировано скрытие отсутствующего товара (hide_missing_goods). Т.е. демонстрируется в списках товар в наличии и не в наличии. Тогда может возникнуть необходимость отобразить отдельным списком товар, который в наличии (in_stock).

              В данном случае Ваше дополнение должно выглядеть не так
              Код
              .($this->diafan->configmodules('hide_missing_goods', 'shop') && $this->diafan->configmodules('use_count_goods', 'shop') || $in_stock ? " INNER JOIN {shop_price} AS prh ON prh.good_id=e.id AND prh.count_goods>0" : "")
              а вот так
              Код
              .(($this->diafan->configmodules('hide_missing_goods', 'shop') || $in_stock) && $this->diafan->configmodules('use_count_goods', 'shop') ? " INNER JOIN {shop_price} AS prh ON prh.good_id=e.id AND prh.count_goods>0" : "")


              Скажу так (почему предложил изменить): если отключить возможность использования количества товара и активировать переменную in_stock, то результат будет неизменным (т.е., что с этой переменной, что без нее, все равно на выходе один и тот же результат), но в запросе MySQL появится лишнее условие (INNER JOIN), которое съест немало процессорного ресурса, а значит страница на определенные доли загрузится медленнее.

              Или же, владелец сначала использовал возможность указания количества, а затем передумал и отключил его. При этом в базе данных остались циферки, указывающие на количество оставшегося товара. Они не удаляются при таком варианте, так как не мешают. А ждут своего часа, если владелец вновь надумает их использовать. Так вот Ваш код в оригинальном исполнении выдаст интересный результат: будет выводить не все товары. Владелец задастся вопросом, а почему в списках выводится только, например, три товара, а не все шесть. Будет грешить на cms. Кто-то будет искать эту ошибку и исправлять. Так зачем до этого доводить? :))

              Как-то так, успехов.
    • 02 ноября 2019 г.
    • День добрый. В нынешнем патче это должно работать? Вроде сделал все, как написано, но товары, которые не в наличии, все равно выводятся
      • 03 ноября 2019 г.
      • Смотрите как админ? Конечно, выведутся. В инкогнито зайдите, как обычный пользователь
        • 03 ноября 2019 г.
        • Попробовал еще раз сделать, зашел через инкогнито потом, и все равно не работает(
          Еще почему-то в папке custom/my/modules/shop есть два файла shop.model.php - который я правил, и shop.model.custom.php - в котором всего 100 строк. Может это как-то влияет, и надо только один оставить файл?

Новости

  • 12 января
  • После выхода сборки 7.1 мы выпустили уже три патча, в каждом из которых улучшаем административную часть сайта. Сборка DIAFAN.CMS 7.1.3 уже доступна к установке. 
  • 15 декабря 2023 г.
  • Подводим итоги 2023 года. Выпустили новую сборку DIAFAN.CMS 7.1.1, вводим новые тарифы на аренду сайта и коммерческую поддержку и автообновления с января 2024 г., строим планы на будущий год.
  • 25 июля 2023 г.
  • Выпустили очередную сборку DIAFAN.CMS 7.0.1. Она уже доступна к установке.

Блоги

  • 15.12.2023
  • В новой сборке DIAFAN.CMS 7.1.1 мы расширили функциональность баннеров, уделили внимание YML-фиду для Яндекс.Маркет, улучшили “Настройки шаблона”, оформили модуль лога действий и разработали “Заметки” для пользователей административной части сайта. Также проработали замечания и предложения наших пользователей, исправили несколько ошибок.

Форум