title: How to show only per attribute
body: <p>I'm trying to make a optics shop with <strong><em>PRESTASHOP</em></strong>, but I'm facing a problem. I've create <strong>4 new columns</strong> in <strong>product and customer table</strong> (left eye diopter, right eye diopter, bridge length, leg length), the same in both tables.</p>
  
  <p>What I want to do is when the shop load the products, compare this variables and if they are the same then show the product. This is to try to filter glasses to the client, only showing him the glasses that are compatible with him.</p>
  
  <p>The original query is the next:</p>
  
  <pre><code>$sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) AS quantity'.(Combination::isFeatureActive() ? ', IFNULL(product_attribute_shop.id_product_attribute, 0) AS id_product_attribute,
                      product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity' : '').', pl.`description`, pl.`description_short`, pl.`available_now`,
                      pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, image_shop.`id_image` id_image,
                      il.`legend` as legend, m.`name` AS manufacturer_name, cl.`name` AS category_default,
                      DATEDIFF(product_shop.`date_add`, DATE_SUB("'.date('Y-m-d').' 00:00:00",
                      INTERVAL '.(int)$nb_days_new_product.' DAY)) &gt; 0 AS new, product_shop.price AS orderprice
                  FROM `'._DB_PREFIX_.'category_product` cp
                  LEFT JOIN `'._DB_PREFIX_.'product` p
                      ON p.`id_product` = cp.`id_product`
                  '.Shop::addSqlAssociation('product', 'p').
                  (Combination::isFeatureActive() ? ' LEFT JOIN `'._DB_PREFIX_.'product_attribute_shop` product_attribute_shop
                  ON (p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$context-&gt;shop-&gt;id.')':'').'
                  '.Product::sqlStock('p', 0).'
                  LEFT JOIN `'._DB_PREFIX_.'category_lang` cl
                      ON (product_shop.`id_category_default` = cl.`id_category`
                      AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')
                  LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
                      ON (p.`id_product` = pl.`id_product`
                      AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').')
                  LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop
                      ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context-&gt;shop-&gt;id.')
                  LEFT JOIN `'._DB_PREFIX_.'image_lang` il
                      ON (image_shop.`id_image` = il.`id_image`
                      AND il.`id_lang` = '.(int)$id_lang.')
                  LEFT JOIN `'._DB_PREFIX_.'manufacturer` m
                      ON m.`id_manufacturer` = p.`id_manufacturer`
                  WHERE product_shop.`id_shop` = '.(int)$context-&gt;shop-&gt;id.'
                      AND cp.`id_category` = '.(int)$this-&gt;id
                      .($active ? ' AND product_shop.`active` = 1' : '')
                      .($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '')
                      .($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : '');
  </code></pre>
  
  <p>I'm trying to modify it, but I don't have very clear how to. And in consecuence, I'm doing wrong things. I've added the next left joins to the query.</p>
  
  <pre><code>LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON pa.`id_product` = p.`id_product`
  LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
  LEFT JOIN `'._DB_PREFIX_.'attribute` attr ON attr.`id_attribute` = pac.`id_attribute`
  LEFT JOIN `'._DB_PREFIX_.'attribute_lang` attr_lang ON (attr_lang.`id_attribute` = pac.`id_attribute` AND attr_lang.`id_lang` = '.(int)$id_lang.')LEFT JOIN `'._DB_PREFIX_.'attribute_group` attr_group ON attr_group.`id_attribute_group` = attr.`id_attribute_group`
  LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` attr_group_lang ON attr_group_lang.`id_attribute_group` = attr.`id_attribute_group`
  </code></pre>
  
  <p>Thank you for any advice.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>The new fields of the products are features inside prestashop (there aren't inside product table) sorry for the mistake.</p>
  
  <p>I put the data model of prestashop for your info.</p>
  
  <p><a href="https://i.stack.imgur.com/8RJDL.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8RJDL.jpg" alt="DataModel"></a></p>
  
  <p><strong>EDIT 2:</strong></p>
  
  <p>I'm trying now to achieve this by using a module, so my php file of my module has the next code. I've follow the code from CategoryController.php, but I don't know how to remove a product if the conditions are not satisfied.</p>
  
  <pre><code>&lt;?php
  
  if (!defined('_PS_VERSION_'))
      exit;
  
  class glassOptics extends Module
  {
      /* @var boolean error */
      protected $_errors = false;
  
      public function __construct()
      {
          $this-&gt;name = 'glassOptics';
          $this-&gt;tab = 'front_office_features';
          $this-&gt;version = '1.0';
          $this-&gt;author = 'MAOL';
          $this-&gt;need_instance = 0;
  
          parent::__construct();
  
          $this-&gt;displayName = $this-&gt;l('glassOptics');
          $this-&gt;description = $this-&gt;l('...');
      }
  
      public function install()
      {
          if (!parent::install() OR
              !$this-&gt;veopticasCustomerDB('add') OR
              !$this-&gt;veopticasProductDB('add') OR            
              !$this-&gt;registerHook('hookActionProductListOverride')
              return false;
          return true;
      }
  
      public function uninstall()
      {
          if (!parent::uninstall() OR !$this-&gt;veopticasCustomerDB('remove') OR !$this-&gt;veopticasProductDB('remove'))
              return false;
          return true;
      }
  
  
      public function veopticasCustomerDB($method)
      {
          switch ($method) {
              case 'add': 
                  $sql = 'CREATE TABLE IF EXISTS `'._DB_PREFIX_.'customer_optics_data` (
                  `id_customer` int(10) UNSIGNED NOT NULL,
                  `left_dioptrics` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `right_dioptrics` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `bridge` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `leg` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `glass_width` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `glass_height` decimal(20,6) NOT NULL DEFAULT '0.000000'
                  ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8';
  
                  break;
  
              case 'remove':
                  $sql = 'DROP TABLE IF EXISTS `'._DB_PREFIX_ . 'customer_optics_data`';
                  break;
          }
  
          if(!Db::getInstance()-&gt;Execute($sql))
              return false;
          return true;
      }
  
      public function veopticasProductDB($method)
      {
          switch ($method) {
              case 'add': 
                  $sql = 'CREATE TABLE IF EXISTS `'._DB_PREFIX_.'product_optics_data` (
                  `id_product` int(10) UNSIGNED NOT NULL,
                  `left_dioptrics` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `right_dioptrics` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `bridge` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `leg` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `glass_width` decimal(20,6) NOT NULL DEFAULT '0.000000',
                  `glass_height` decimal(20,6) NOT NULL DEFAULT '0.000000'
                  ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8';
  
                  break;
  
              case 'remove':
                  $sql = 'DROP TABLE IF EXISTS `'._DB_PREFIX_ . 'product_optics_data`';
                  break;
          }
  
          if(!Db::getInstance()-&gt;Execute($sql))
              return false;
          return true;
      }
  
  
      public function hookActionProductListOverride($params)
      {
          $customer_settings = glassOptics::getCustomerSettings($this-&gt;context-&gt;customer);
  
          if ($customer_settings) {
              // Inform the hook was executed
              $params['hookExecuted'] = true;
  
              // Filter products here, you are now overriding the default
              // functionality of CategoryController class.
              // You can see blocklayered module for more details.
  
              if ((isset($this-&gt;context-&gt;controller-&gt;display_column_left) &amp;&amp; !$this-&gt;context-&gt;controller-&gt;display_column_left)
              &amp;&amp; (isset($this-&gt;context-&gt;controller-&gt;display_column_right) &amp;&amp; !$this-&gt;context-&gt;controller-&gt;display_column_right))
              return false;
  
              global $smarty;
              if (!Configuration::getGlobalValue('PS_LAYERED_INDEXED'))
                  return;
  
              $categories_count = Db::getInstance()-&gt;getValue('
                  SELECT COUNT(*)
                  FROM '._DB_PREFIX_.'layered_category
                  WHERE id_category = '.(int)Tools::getValue('id_category', Tools::getValue('id_category_layered', Configuration::get('PS_HOME_CATEGORY'))).'
                  AND id_shop = '.(int) Context::getContext()-&gt;shop-&gt;id
              );
  
              if ($categories_count == 0)
                  return;
  
  
              // List of product to overrride categoryController
              $params['catProducts'] = array();
              $selected_filters = $this-&gt;getSelectedFilters();
              $filter_block = $this-&gt;getFilterBlock($selected_filters);
              $title = '';
  
              if (is_array($filter_block['title_values']))
                  foreach ($filter_block['title_values'] as $key =&gt; $val)
                      $title .= ' &gt; '.$key.' '.implode('/', $val);
  
              $smarty-&gt;assign('categoryNameComplement', $title);
              $this-&gt;getProducts($selected_filters, $params['catProducts'], $params['nbProducts'], $p, $n, $pages_nb, $start, $stop, $range);
              // Need a nofollow on the pagination links?
              $smarty-&gt;assign('no_follow', $filter_block['no_follow']);
  
              foreach ($params['nbProducts'] as $product) {
  
                  $product_settings = glassOptics::getProductSettings($product);
  
                  if($product_settings){
                      $same_bridge            = ($product_settings-&gt;bridge == $customer_settings-&gt;bridge ? true : false);
                      $same_leg           = ($product_settings-&gt;leg == $customer_settings-&gt;leg ? true : false);
                      $same_glass_width   = ($product_settings-&gt;glass_width == $customer_settings-&gt;glass_width ? true : false);
                      $same_glass_heigth      = ($product_settings-&gt;glass_heigth == $customer_settings-&gt;glass_heigth ? true : false);
                  }
  
              }
  
          }
      }
  }
  </code></pre>