title: Opencart 2.2.0 Latest page - sorting by two parameters
body: <p>I am using OC 2.2.0 and I made custom Latest page where I display 20 latest products. I managed to make the default sorting to be by date added in decsending order. For some reason, I am struggling to make other sorting options(by name, price and model) work properly. The correct number of products is shown (20 in my case), but they are not latest. They are just products from all products list instead. My </p>
  
  <blockquote>
    <p>controller file latest.php,looks like this:</p>
  </blockquote>
  
  <pre><code>&lt;?php
  class ControllerProductLatest extends Controller {
      public function index() {
          $this-&gt;load-&gt;language('product/latest');
  
          $this-&gt;load-&gt;model('catalog/product');
  
          $this-&gt;load-&gt;model('tool/image');
  
          if (isset($this-&gt;request-&gt;get['sort'])) {
              $sort = $this-&gt;request-&gt;get['sort'];
          } else {
              $sort = 'p.sort_order';
          }
  
          if (isset($this-&gt;request-&gt;get['order'])) {
              $order = $this-&gt;request-&gt;get['order'];
          } else {
              $order = 'DESC';
          }
  
          if (isset($this-&gt;request-&gt;get['page'])) {
              $page = $this-&gt;request-&gt;get['page'];
          } else {
              $page = 1;
          }
  
          if (isset($this-&gt;request-&gt;get['limit'])) {
              $limit = (int)$this-&gt;request-&gt;get['limit'];
          } else {
              $limit = $this-&gt;config-&gt;get($this-&gt;config-&gt;get('config_theme') . '_product_limit');
          }
  
          $this-&gt;document-&gt;setTitle($this-&gt;language-&gt;get('heading_title'));
  
          $data['breadcrumbs'] = array();
  
          $data['breadcrumbs'][] = array(
              'text' =&gt; $this-&gt;language-&gt;get('text_home'),
              'href' =&gt; $this-&gt;url-&gt;link('common/home')
          );
  
          $url = '';
  
          if (isset($this-&gt;request-&gt;get['sort'])) {
              $url .= '&amp;sort=' . $this-&gt;request-&gt;get['sort'];
          }
  
          if (isset($this-&gt;request-&gt;get['order'])) {
              $url .= '&amp;order=' . $this-&gt;request-&gt;get['order'];
          }
  
          if (isset($this-&gt;request-&gt;get['page'])) {
              $url .= '&amp;page=' . $this-&gt;request-&gt;get['page'];
          }
  
          if (isset($this-&gt;request-&gt;get['limit'])) {
              $url .= '&amp;limit=' . $this-&gt;request-&gt;get['limit'];
          }
  
          $data['breadcrumbs'][] = array(
              'text' =&gt; $this-&gt;language-&gt;get('heading_title'),
              'href' =&gt; $this-&gt;url-&gt;link('product/latest', $url)
          );
  
          $data['heading_title'] = $this-&gt;language-&gt;get('heading_title');
          $data['customer_group_id'] = $this-&gt;customer-&gt;getGroupId();
          $data['text_empty'] = $this-&gt;language-&gt;get('text_empty');
          $data['text_quantity'] = $this-&gt;language-&gt;get('text_quantity');
          $data['text_manufacturer'] = $this-&gt;language-&gt;get('text_manufacturer');
          $data['text_model'] = $this-&gt;language-&gt;get('text_model');
          $data['text_price'] = $this-&gt;language-&gt;get('text_price');
          $data['text_wholesale'] = $this-&gt;language-&gt;get('text_wholesale');
          $data['text_tax'] = $this-&gt;language-&gt;get('text_tax');
          $data['text_points'] = $this-&gt;language-&gt;get('text_points');
          $data['text_compare'] = sprintf($this-&gt;language-&gt;get('text_compare'), (isset($this-&gt;session-&gt;data['compare']) ? count($this-&gt;session-&gt;data['compare']) : 0));
          $data['text_sort'] = $this-&gt;language-&gt;get('text_sort');
          $data['text_limit'] = $this-&gt;language-&gt;get('text_limit');
          $data['logged'] = $this-&gt;customer-&gt;isLogged();
          $data['button_cart'] = $this-&gt;language-&gt;get('button_cart');
          $data['button_wishlist'] = $this-&gt;language-&gt;get('button_wishlist');
          $data['button_compare'] = $this-&gt;language-&gt;get('button_compare');
          $data['button_list'] = $this-&gt;language-&gt;get('button_list');
          $data['button_grid'] = $this-&gt;language-&gt;get('button_grid');
          $data['button_continue'] = $this-&gt;language-&gt;get('button_continue');
  
          $data['compare'] = $this-&gt;url-&gt;link('product/compare');
  
          $data['products'] = array();
  
          $filter_data = array(
              'sort'  =&gt; $sort,
              'order' =&gt; $order,
              'start' =&gt; ($page - 1) * 20,
              'limit' =&gt; $limit
          );
  
  
          $product_total = 20;
  
          $results = $this-&gt;model_catalog_product-&gt;getProductLatestS($filter_data);
  
          foreach ($results as $result) {
              if ($result['image']) {
                  $image = $this-&gt;model_tool_image-&gt;resize($result['image'], $this-&gt;config-&gt;get($this-&gt;config-&gt;get('config_theme') . '_image_product_width'), $this-&gt;config-&gt;get($this-&gt;config-&gt;get('config_theme') . '_image_product_height'));
              } else {
                  $image = $this-&gt;model_tool_image-&gt;resize('placeholder.png', $this-&gt;config-&gt;get($this-&gt;config-&gt;get('config_theme') . '_image_product_width'), $this-&gt;config-&gt;get($this-&gt;config-&gt;get('config_theme') . '_image_product_height'));
              }
  
              if ($this-&gt;customer-&gt;isLogged() || !$this-&gt;config-&gt;get('config_customer_price')) {
                  $price = $this-&gt;currency-&gt;format($this-&gt;tax-&gt;calculate($result['price'], $result['tax_class_id'], $this-&gt;config-&gt;get('config_tax')), $this-&gt;session-&gt;data['currency']);
                  $wholesale = $this-&gt;currency-&gt;format($this-&gt;tax-&gt;calculate($result['wholesale'], $result['tax_class_id'], $this-&gt;config-&gt;get('config_tax')), $this-&gt;session-&gt;data['currency']);
              } else {
                  $price = false;
                  $wholesale = false;
              }
  
              if ((float)$result['special']) {
                  $special = $this-&gt;currency-&gt;format($this-&gt;tax-&gt;calculate($result['special'], $result['tax_class_id'], $this-&gt;config-&gt;get('config_tax')), $this-&gt;session-&gt;data['currency']);
              } else {
                  $special = false;
              }
  
              if ($this-&gt;config-&gt;get('config_tax')) {
                  $tax = $this-&gt;currency-&gt;format((float)$result['special'] ? $result['special'] : $result['price'], $this-&gt;session-&gt;data['currency']);
              } else {
                  $tax = false;
              }
  
              if ($this-&gt;config-&gt;get('config_review_status')) {
                  $rating = (int)$result['rating'];
              } else {
                  $rating = false;
              }
  
              $data['products'][] = array(
                  'product_id'  =&gt; $result['product_id'],
                  'thumb'       =&gt; $image,
                  'upc'       =&gt; $result['upc'],
                  'name'        =&gt; $result['name'],
                  'description' =&gt; utf8_substr(strip_tags(html_entity_decode($result['description'], ENT_QUOTES, 'UTF-8')), 0, $this-&gt;config-&gt;get($this-&gt;config-&gt;get('config_theme') . '_product_description_length')) . '..',
                  'price'       =&gt; $price,
                  'wholesale'   =&gt; $wholesale,
                  'special'     =&gt; $special,
                  'tax'         =&gt; $tax,
                  'minimum'     =&gt; $result['minimum'] &gt; 0 ? $result['minimum'] : 1,
                  'rating'      =&gt; $result['rating'],
                  'href'        =&gt; $this-&gt;url-&gt;link('product/product', 'product_id=' . $result['product_id'] . $url)
              );
          }
  
          $url = '';
  
          if (isset($this-&gt;request-&gt;get['limit'])) {
              $url .= '&amp;limit=' . $this-&gt;request-&gt;get['limit'];
          }
  
          $data['sorts'] = array();
  
          $data['sorts'][] = array(
              'text'  =&gt; $this-&gt;language-&gt;get('text_default'),
              'value' =&gt; 'p.date_added-DESC',
              'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=p.date_added&amp;order=DESC' . $url)
          );
  
          $data['sorts'][] = array(
              'text'  =&gt; $this-&gt;language-&gt;get('text_name_asc'),
              'value' =&gt; 'pd.name-ASC',
              'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=pd.name&amp;order=ASC' . $url)
          );
  
          $data['sorts'][] = array(
              'text'  =&gt; $this-&gt;language-&gt;get('text_name_desc'),
              'value' =&gt; 'pd.name-DESC',
              'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=pd.name&amp;order=DESC' . $url)
          );
  
          $data['sorts'][] = array(
              'text'  =&gt; $this-&gt;language-&gt;get('text_price_asc'),
              'value' =&gt; 'p.price-ASC',
              'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=p.price&amp;order=ASC' . $url)
          );
  
          $data['sorts'][] = array(
              'text'  =&gt; $this-&gt;language-&gt;get('text_price_desc'),
              'value' =&gt; 'p.price-DESC',
              'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=p.price&amp;order=DESC' . $url)
          );
  
          if ($this-&gt;config-&gt;get('config_review_status')) {
              $data['sorts'][] = array(
                  'text'  =&gt; $this-&gt;language-&gt;get('text_rating_desc'),
                  'value' =&gt; 'rating-DESC',
                  'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=rating&amp;order=DESC' . $url)
              );
  
              $data['sorts'][] = array(
                  'text'  =&gt; $this-&gt;language-&gt;get('text_rating_asc'),
                  'value' =&gt; 'rating-ASC',
                  'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=rating&amp;order=ASC' . $url)
              );
          }
  
          $data['sorts'][] = array(
                  'text'  =&gt; $this-&gt;language-&gt;get('text_model_asc'),
                  'value' =&gt; 'p.model-ASC',
                  'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=p.model&amp;order=ASC' . $url)
          );
  
          $data['sorts'][] = array(
              'text'  =&gt; $this-&gt;language-&gt;get('text_model_desc'),
              'value' =&gt; 'p.model-DESC',
              'href'  =&gt; $this-&gt;url-&gt;link('product/latest', 'sort=p.model&amp;order=DESC' . $url)
          );
  
          $url = '';
  
          if (isset($this-&gt;request-&gt;get['sort'])) {
              $url .= '&amp;sort=' . $this-&gt;request-&gt;get['sort'];
          }
  
          if (isset($this-&gt;request-&gt;get['order'])) {
              $url .= '&amp;order=' . $this-&gt;request-&gt;get['order'];
          }
  
          $data['limits'] = array();
  
          $limits = array_unique(array($this-&gt;config-&gt;get($this-&gt;config-&gt;get('config_theme') . '_product_limit'), 20));
  
          sort($limits);
  
          foreach($limits as $value) {
              $data['limits'][] = array(
                  'text'  =&gt; $value,
                  'value' =&gt; $value,
                  'href'  =&gt; $this-&gt;url-&gt;link('product/latest', $url . '&amp;limit=' . $value)
              );
          }
  
          $url = '';
  
          if (isset($this-&gt;request-&gt;get['sort'])) {
              $url .= '&amp;sort=' . $this-&gt;request-&gt;get['sort'];
          }
  
          if (isset($this-&gt;request-&gt;get['order'])) {
              $url .= '&amp;order=' . $this-&gt;request-&gt;get['order'];
          }
  
          if (isset($this-&gt;request-&gt;get['limit'])) {
              $url .= '&amp;limit=' . $this-&gt;request-&gt;get['limit'];
          }
  
          $pagination = new Pagination();
          $pagination-&gt;total = $product_total;
          $pagination-&gt;page = $page;
          $pagination-&gt;limit = $limit;
          $pagination-&gt;url = $this-&gt;url-&gt;link('product/latest', $url . '&amp;page={page}');
  
          $data['pagination'] = $pagination-&gt;render();
  
          $data['results'] = sprintf($this-&gt;language-&gt;get('text_pagination'), ($product_total) ? (($page - 1)) + 1 : 0, ((($page - 1)) &gt; ($product_total - $limit)) ? $product_total : ((($page - 1) * $limit) + $limit), $product_total, ceil($product_total / $limit));
  
          // http://googlewebmastercentral.blogspot.com/2011/09/pagination-with-relnext-and-relprev.html
          if ($page == 1) {
              $this-&gt;document-&gt;addLink($this-&gt;url-&gt;link('product/latest', '', true), 'canonical');
          } elseif ($page == 2) {
              $this-&gt;document-&gt;addLink($this-&gt;url-&gt;link('product/latest', '', true), 'prev');
          } else {
              $this-&gt;document-&gt;addLink($this-&gt;url-&gt;link('product/latest', 'page='. ($page - 1), true), 'prev');
          }
  
          if ($limit &amp;&amp; ceil($product_total / $limit) &gt; $page) {
              $this-&gt;document-&gt;addLink($this-&gt;url-&gt;link('product/latest', 'page='. ($page + 1), true), 'next');
          }
  
          $data['sort'] = $sort;
          $data['order'] = $order;
          $data['limit'] = $limit;
  
          $data['continue'] = $this-&gt;url-&gt;link('common/home');
  
          $data['column_left'] = $this-&gt;load-&gt;controller('common/column_left');
          $data['column_right'] = $this-&gt;load-&gt;controller('common/column_right');
          $data['content_top'] = $this-&gt;load-&gt;controller('common/content_top');
          $data['content_bottom'] = $this-&gt;load-&gt;controller('common/content_bottom');
          $data['footer'] = $this-&gt;load-&gt;controller('common/footer');
          $data['header'] = $this-&gt;load-&gt;controller('common/header');
  
          $this-&gt;response-&gt;setOutput($this-&gt;load-&gt;view('product/latest', $data));
      }
  }
  </code></pre>
  
  <p>In </p>
  
  <blockquote>
    <p>model-catalog-product-product.php file I made function getProductLatestS($data = array())</p>
  </blockquote>
  
  <pre><code>public function getProductLatestS($data = array()) {
          $sql = "SELECT DISTINCT p.product_id FROM  oc_product p LEFT JOIN oc_product_description pd ON (p.product_id = pd.product_id) LEFT JOIN oc_product_to_store p2s ON (p.product_id = p2s.product_id) WHERE p.status = '1' AND p.stock_status_id = '7' AND p.date_available &lt;= NOW() AND p2s.store_id = '0' GROUP BY p.product_id";
  
          $sort_data = array(
              'pd.name',
              'p.model',
              'p.date_available',
              'p.date_added',
              'p.price',
              'rating',
              'p.sort_order'
          );
  
          if (isset($data['sort']) &amp;&amp; in_array($data['sort'], $sort_data)) {
              if ($data['sort'] == 'pd.name' || $data['sort'] == 'p.model') {
                  $sql .= " ORDER BY LCASE(" . $data['sort'] . ")";
              } else {
                  $sql .= " ORDER BY " . $data['sort'];
              }
          } else {
              $sql .= " ORDER BY p.date_added";
          }
  
          if (isset($data['order']) &amp;&amp; ($data['order'] == 'DESC')) {
              $sql .= " DESC, LCASE(pd.name) DESC";
          } else {
              $sql .= " ASC, LCASE(pd.name) ASC";
          }
  
          if (isset($data['start']) || isset($data['limit'])) {
              if ($data['start'] &lt; 0) {
                  $data['start'] = 0;
              }
  
              if ($data['limit'] &lt; 1) {
                  $data['limit'] = 20;
              }
  
              $sql .= " LIMIT " . (int)$data['start'] . "," . (int)$data['limit'];
          }
  
          $product_data = array();
  
          $query = $this-&gt;db-&gt;query($sql);
  
          foreach ($query-&gt;rows as $result) {
              $product_data[$result['product_id']] = $this-&gt;getProduct($result['product_id']);
          }
  
          return $product_data;
      }
  </code></pre>
  
  <p>My question is how do I make other sorting to work properly as well (sort by two parameters, with <code>date added</code> being always the first parameter)? Any suggestion is welcome, as I do not know what I am doing wrong here. Thanx.</p>