База знаний

25.02.2017

Проблема

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

Решение

Допустим у нас будет что-то вроде <insert name="show_block" module="shop" images="1" count="9" template="rel" cat_id="current" 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);

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

Автор решения: Андрей (R4W)