Перейти к содержанию
Официальный форум поддержки Simpla

Рекомендуемые сообщения

Пытаюсь сделать, чтобы в products.tpl выбирался только первый вариант для каждого товара. (У меня по 30 вариантов у каждого товара, но я их показываю только на странице товара, а в общем каталоге только первый. Из-за того, что выбираются все варианты, страницы каталога грузятся дольше.)

 

Полагаю, что надо в api/Variants.php в функцию get_variants добавить фильтр по количеству, но не понимаю как.

 

Как это сделать?

Ссылка на сообщение
Поделиться на другие сайты

Мне нужно, что они из базы не выбирались.

 

Попробуйте дописать в view/ProductsView.php 'only_first'=>true

$variants = $this->variants->get_variants(array('product_id'=>$products_ids, 'in_stock'=>true, 'only_first'=>true));

В api/Variants.php после

public function get_variants($filter = array())
    {        
        $product_id_filter = '';
        $variant_id_filter = '';
        $instock_filter = '';

дописать

        $only_first_filter = '';

        if(!empty($filter['only_first']))
            $only_first_filter = $this->db->placehold('GROUP BY v.product_id');

и чуть ниже дописать

$only_first_filter

перед

ORDER BY v.position

 

Ссылка на сообщение
Поделиться на другие сайты

Так будет выбираться один довольно случайный вариант, но не обязательно первый...

 

А как сделать, чтобы именно первый?

Ссылка на сообщение
Поделиться на другие сайты

Совсем легкого способа не вижу. Надо писать запрос более хитро, для чего вносить изменения в API. А возможно, и запрос будет тяжеловат и будет тормозить - по-хорошему надо все проверять...

Ссылка на сообщение
Поделиться на другие сайты

Если кому понадобится, сделал так. Добавил в функцию get_variants фильтр по позиции:

if(!empty($filter['variant_first']))
    $variant_first_filter = $this->db->placehold('AND (v.position=1)');

 

И в запрос к базе:

$variant_first_filter

 

Из ProductsView передаю 'variant_first'=>true при обращении к get_variants.

 

Чтобы это работало, нужно исправить косячную логику назначения позиций вариантов. Им по умолчанию ставится позиция, равная айди варианта.

 

В файле simpla/ProductAdmin.php изменить (~188):

$this->variants->update_variant($variants_ids[$i], array('position'=>$variant_id));

на

$this->variants->update_variant($variants_ids[$i], array('position'=>$i+1));

 

Тогда position будет начинаться с единицы, как и при импорте.

 

Поправьте меня, если где-то налажал.

Изменено пользователем bananovsv
Ссылка на сообщение
Поделиться на другие сайты

У меня получилось вот так

public function get_variants($filter = array())
    {        
        $product_id_filter = '';
        $variant_id_filter = '';
        $instock_filter = '';
        $only_first_filter = '';
        
        if(!empty($filter['product_id']))
            $product_id_filter = $this->db->placehold('AND v.product_id in(?@)', (array)$filter['product_id']);
        
        if(!empty($filter['id']))
            $variant_id_filter = $this->db->placehold('AND v.id in(?@)', (array)$filter['id']);

        if(!empty($filter['in_stock']) && $filter['in_stock'])
            $instock_filter = $this->db->placehold('AND (v.stock>0 OR v.stock IS NULL)');

        if(!empty($filter['only_first']))
            $only_first_filter = $this->db->placehold('GROUP BY x.product_id');

        if(!$product_id_filter && !$variant_id_filter)
            return array();
        
        $query = $this->db->placehold("
            SELECT 
                *
            FROM (
                SELECT
                    v.id, 
                    v.product_id,
                    v.price, 
                    NULLIF(v.compare_price, 0) as compare_price, 
                    v.sku, 
                    IFNULL(v.stock, ?) as stock, 
                    (v.stock IS NULL) as infinity,
                    v.name, 
                    v.attachment, 
                    v.position
                FROM
                    __variants AS v
                WHERE 
                    1
                    $product_id_filter          
                    $variant_id_filter  
                    $instock_filter 
                ORDER BY v.position  
            )
            AS x
            $only_first_filter
        ", $this->settings->max_order_amount);
        
        $this->db->query($query);    
        return $this->db->results();
    }
Ссылка на сообщение
Поделиться на другие сайты

 

У меня получилось вот так

public function get_variants($filter = array())
    {        
        $product_id_filter = '';
        $variant_id_filter = '';
        $instock_filter = '';
        $only_first_filter = '';
        
        if(!empty($filter['product_id']))
            $product_id_filter = $this->db->placehold('AND v.product_id in(?@)', (array)$filter['product_id']);
        
        if(!empty($filter['id']))
            $variant_id_filter = $this->db->placehold('AND v.id in(?@)', (array)$filter['id']);

        if(!empty($filter['in_stock']) && $filter['in_stock'])
            $instock_filter = $this->db->placehold('AND (v.stock>0 OR v.stock IS NULL)');

        if(!empty($filter['only_first']))
            $only_first_filter = $this->db->placehold('GROUP BY x.product_id');

        if(!$product_id_filter && !$variant_id_filter)
            return array();
        
        $query = $this->db->placehold("
            SELECT 
                *
            FROM (
                SELECT
                    v.id, 
                    v.product_id,
                    v.price, 
                    NULLIF(v.compare_price, 0) as compare_price, 
                    v.sku, 
                    IFNULL(v.stock, ?) as stock, 
                    (v.stock IS NULL) as infinity,
                    v.name, 
                    v.attachment, 
                    v.position
                FROM
                    __variants AS v
                WHERE 
                    1
                    $product_id_filter          
                    $variant_id_filter  
                    $instock_filter 
                ORDER BY v.position  
            )
            AS x
            $only_first_filter
        ", $this->settings->max_order_amount);
        
        $this->db->query($query);    
        return $this->db->results();
    }

 

Вы разве так всё равно не выбираете из базы все варианты?

Ссылка на сообщение
Поделиться на другие сайты

Вы разве так всё равно не выбираете из базы все варианты?

 

Ну да, но на выходе получаем только первый вариант в наличии.

 

Ваш запрос конечно легче, при условии что первый вариант всегда в наличии и у всех проставлены позиции начиная с 1

Ссылка на сообщение
Поделиться на другие сайты

Чтобы это работало, нужно исправить косячную логику назначения позиций вариантов. Им по умолчанию ставится позиция, равная айди варианта.

 

Эту логику Вы поправили лишь в одном месте. А надо учитывать и другие возможности.

 

Например, если у варианта с position=1 возникнет наличие 0, то товар будет показываться в списке некорректно. Выходит, надо следить за изменениями кол-ва и соответственно менять position.

 

Тогда position будет начинаться с единицы, как и при импорте.

 

Кстати, это далеко не всегда так, и лишь в простейших случаях.

Ссылка на сообщение
Поделиться на другие сайты

Ну да, но на выходе получаем только первый вариант в наличии.

 

Ваш запрос конечно легче, при условии что первый вариант всегда в наличии и у всех проставлены позиции начиная с 1

 

Задача просто была таким образом снизить нагрузку на базу, потому что вариантов и товаров много. А так оптимизации не получается, только визуальная разница.

Ссылка на сообщение
Поделиться на другие сайты

 Кстати, это далеко не всегда так, и лишь в простейших случаях.

 

А в каких случаях импорт может иначе повести себя с позициями вариантов?

Ссылка на сообщение
Поделиться на другие сайты

А в каких случаях импорт может иначе повести себя с позициями вариантов?

 

Например, когда уже ЕСТЬ товар с одним вариантом с position=8, а импорт добавляет другой вариант к этому товару, то добавится вариант с position=9.

Ссылка на сообщение
Поделиться на другие сайты

Например, когда уже ЕСТЬ товар с одним вариантом с position=8, а импорт добавляет другой вариант к этому товару, то добавится вариант с position=9.

 

Ну так ведь так и должно быть. Или вы имеете в виду, что он с единицы должен был начать?

Изменено пользователем bananovsv
Ссылка на сообщение
Поделиться на другие сайты

Ну так ведь так и должно быть. Или вы имеете в виду, что он с единицы должен был начать?

 

Не имел в виду никаких намеков. Просто сделал мимоходом замечание к Вашему утверждению, которое, по-моему, неверно.

Но это вопрос мелкий и довольно расплывчатый. Куда интереснее, справились ли Вы с основным:

 

Эту логику Вы поправили лишь в одном месте. А надо учитывать и другие возможности.

 

Например, если у варианта с position=1 возникнет наличие 0, то товар будет показываться в списке некорректно. Выходит, надо следить за изменениями кол-ва и соответственно менять position.

Ссылка на сообщение
Поделиться на другие сайты

 

Не имел в виду никаких намеков. Просто сделал мимоходом замечание к Вашему утверждению, которое, по-моему, неверно.

Но это вопрос мелкий и довольно расплывчатый. Куда интереснее, справились ли Вы с основным.

 

 

Не пытался справляться. У меня функциональность наличия не используется, а позиции вариантов проставлены верно. Но я согласен, что решение далеко от идеального и подойдет не всем. Было бы здорово, если бы брался наименьший доступный вариант товара. Если знаете, как сделать — поделитесь решением.

Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...