[Решено] Исключить товар одной категории в новинках (latest)

Тема в разделе "OpenCart", создана пользователем Bnopen, 10 окт 2014.

  1. Bnopen

    Bnopen Команда форума

    Регистрация:
    3 мар 2013
    Сообщения:
    1.264
    Симпатии:
    534
    Всем привет! Есть необходимость сделать так, чтобы в модуле новинки (latest) не отображались товары из одной категории. Все никак не пойму как это сделать, в сети тоже ничего насчет этого. А ставить другой модуль как-то не хочется только из-за этого.
    Нашел только как в контролере этого модуля сделать, чтобы отображались товары только одной категории: добавить 'filter_category_id' => 'id_категории', в $data = array( .....
    Я так понимаю, что надо ковырять тогда модель model/catalog/product.php, там где функция getProducts, я там пробовал добавлять: AND p2c.category_id <> '1' - но чего-то с ошибками получается запрос. Подскажите куда копать...
    Заранее спасибо!
     
  2. nix

    nix php, MySQL, UNIX, MikroTik ROSAPI

    Регистрация:
    16 янв 2013
    Сообщения:
    1.000
    Симпатии:
    890
    ету ф-цию лучше не трогать, она и так ресурсоемкая
    найти в модели ф-цию getLatestProducts
    и заменить ее на
    PHP:
    public function getLatestProducts($limit) {
         if (
    $this->customer->isLogged()) {
           
    $customer_group_id $this->customer->getCustomerGroupId();
         } else {
           
    $customer_group_id $this->config->get('config_customer_group_id');
         }   
             
         
    $product_data $this->cache->get('product.latest.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id') . '.' $customer_group_id '.' . (int)$limit);

         if (!
    $product_data) {
           
    $query $this->db->query("
             SELECT p.product_id
               FROM " 
    DB_PREFIX "product p
               INNER JOIN " 
    DB_PREFIX "product_to_store p2s ON (p.product_id = p2s.product_id)
               INNER JOIN " 
    DB_PREFIX "product_to_category p2c ON (p2s.product_id = p2c.product_id)
             WHERE p.status = '1'
             AND p.date_available <= '" 
    $this->NOW "'
             AND p2s.store_id = '" 
    . (int)$this->config->get('config_store_id') . "'
             AND p2c.category_id != '18'
             ORDER BY p.date_added
             DESC LIMIT " 
    . (int)$limit);
             
           foreach (
    $query->rows as $result) {
             
    $product_data[$result['product_id']] = $this->getProduct($result['product_id']);
           }
           
           
    $this->cache->set('product.latest.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'). '.' $customer_group_id '.' . (int)$limit$product_data);
         }
         
         return 
    $product_data;
       }
    в контролере модуля catalog/controller/module/latest.php
    заменить вызов старой на новую(отредактированую)
    меняем ето
    PHP:
    $results $this->model_catalog_product->getProducts($data);
    на ето
    PHP:
    $results $this->model_catalog_product->getLatestProducts($data['limit']);
     
    Bnopen нравится это.
  3. chukcha

    chukcha

    Регистрация:
    9 окт 2014
    Сообщения:
    448
    Симпатии:
    119
    Возможен вариант и такого решения
    Код:
    public function getLatestProducts($limit,$exclude=false) {
         if ($this->customer->isLogged()) {
           $customer_group_id = $this->customer->getCustomerGroupId();
         } else {
           $customer_group_id = $this->config->get('config_customer_group_id');
         }  
            
         $product_data = $this->cache->get('product.latest.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id') . '.' . $customer_group_id . '.' . (int)$limit);
           if ($exclude && is_array($exclude)) {
                $excludesql =  "AND p2c.category_id not IN (". implode(',',$exclude).")";
          }
         if (!$product_data) {
           $query = $this->db->query("
             SELECT p.product_id
               FROM " . DB_PREFIX . "product p
               INNER JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id)
               INNER JOIN " . DB_PREFIX . "product_to_category p2c ON (p2s.product_id = p2c.product_id)
             WHERE p.status = '1'
             AND p.date_available <= '" . $this->NOW . "'
             AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "'".
             $excludesql . "
             ORDER BY p.date_added
             DESC LIMIT " . (int)$limit);
            
           foreach ($query->rows as $result) {
             $product_data[$result['product_id']] = $this->getProduct($result['product_id']);
           }
          
           $this->cache->set('product.latest.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'). '.' . $customer_group_id . '.' . (int)$limit, $product_data);
         }
        
         return $product_data;
       }
    Вызов
    $results = $this->model_catalog_product->getLatestProducts($data['limit'], array(19,220));
     
    Bnopen нравится это.
  4. chukcha

    chukcha

    Регистрация:
    9 окт 2014
    Сообщения:
    448
    Симпатии:
    119
    По идее, в моем приведенном примере, еще, по хорошему, нужно изменить схему для хранения кеша
    и проинициализировать переменную, что не было сделано :(
    PHP:
    public function getLatestProducts($limit,$exclude=false) {
      if (
    $this->customer->isLogged()) {
      
    $customer_group_id $this->customer->getCustomerGroupId();
      } else {
      
    $customer_group_id $this->config->get('config_customer_group_id');
      }
      
    $excludesql =''$schema =''
      if (
    $exclude && is_array($exclude)) {
           
    $excludesql =  "AND p2c.category_id not IN ("implode(',',$exclude).")";
           
    $schemaimplode('-',$exclude);
        } 
      
    $product_data $this->cache->get('product.latest.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id') . '.' $customer_group_id '.' . (int)$limit). '.' $schema;
      if (!
    $product_data) {
      
    $query $this->db->query("
      SELECT p.product_id
      FROM " 
    DB_PREFIX "product p
      INNER JOIN " 
    DB_PREFIX "product_to_store p2s ON (p.product_id = p2s.product_id)
      INNER JOIN " 
    DB_PREFIX "product_to_category p2c ON (p2s.product_id = p2c.product_id)
      WHERE p.status = '1'
      AND p.date_available <= '" 
    $this->NOW "'
      AND p2s.store_id = '" 
    . (int)$this->config->get('config_store_id') . "'".
      
    $excludesql "
      ORDER BY p.date_added
      DESC LIMIT " 
    . (int)$limit);
     
      foreach (
    $query->rows as $result) {
      
    $product_data[$result['product_id']] = $this->getProduct($result['product_id']);
      }
     
      
    $this->cache->set('product.latest.' . (int)$this->config->get('config_language_id') . '.' . (int)$this->config->get('config_store_id'). '.' $customer_group_id '.' . (int)$limit '.' $schema$product_data);
      }
     
      return 
    $product_data;
      }
     
    Baco нравится это.
  5. chukcha

    chukcha

    Регистрация:
    9 окт 2014
    Сообщения:
    448
    Симпатии:
    119
    Если нет результатов поиска(фильтрации)
    чтобы я сделал
    PHP:
    $sql 
    "
      SELECT p.product_id
      FROM " 
    DB_PREFIX "product p
      INNER JOIN " 
    DB_PREFIX "product_to_store p2s ON (p.product_id = p2s.product_id)
      INNER JOIN " 
    DB_PREFIX "product_to_category p2c ON (p2s.product_id = p2c.product_id)
      WHERE p.status = '1'
      AND p.date_available <= '" 
    $this->NOW "'
      AND p2s.store_id = '" 
    . (int)$this->config->get('config_store_id') . "'".
      
    $excludesql "
      ORDER BY p.date_added
      DESC LIMIT " 
    . (int)$limit;
    echo 
    $sql;
    $query $this->db->query($sql);
    И проанализировал бы полученный код, просмотрев его в консоли sql, возможно где-то ошибка в запросе, или ....
    Код писался на коленке без теста.
    --- Добавлено, 10 окт 2014 ---
    Тем более, что 1.5.4.1
    и там возможно нет $this->NOW, а нужно использовать
    Код:
    AND p.date_available <= NOW()
     
    Bnopen нравится это.
  6. Bnopen

    Bnopen Команда форума

    Регистрация:
    3 мар 2013
    Сообщения:
    1.264
    Симпатии:
    534
    Применил код во втором посте, для 1.5.4.1, действительно, надо:
    только вот эту строку:
    AND p.date_available <= '" . $this->NOW . "'
    поменять на:
    AND p.date_available <= NOW()

    Все ок работает.
    Всем спасибо за помощь! Тему можно закрывать.
     
  7. Bnopen

    Bnopen Команда форума

    Регистрация:
    3 мар 2013
    Сообщения:
    1.264
    Симпатии:
    534
    Подскажите еще с одной проблемой после этих действий с исключением - что-то не выбирается кол-во товаров, равное настройками лимита в модуле. Я ставлю 20, а отображается 17, ставлю 23, а отображается 20. При этом, сначала было, что дивы товаров отображались пустые - это понятно, добавил еще условие выборки по количеству p.quantity > 0. Я вот не могу никак понять, каким образом теряется кол-во из лимита и отображается меньшее кол-во?
     
  8. chukcha

    chukcha

    Регистрация:
    9 окт 2014
    Сообщения:
    448
    Симпатии:
    119
    Хм...
    Так не должно быть

    AND p.date_available <= NOW()
    Это как бы только обрежет товары которые доступны
    p.quantity > 0 с ненулевой ценой


    Грубо - других ограничений нет

    Должно работать

    Попробуйте выполнить такой скрипт в консоли phpmyadmin