Unable to load and filter using type_id in product collection

I want to overwrite the prepareProductCollection ($ collection) function of the catalog / layer model.

Because I want to show only simple products, so I want:

public function prepareProductCollection($collection) { $collection ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes()) ->addMinimalPrice() ->addFinalPrice() ->addTaxPercents() ->addUrlRewrite($this->getCurrentCategory()->getId()); Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection); Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection); $collection ->addAttributeToSelect('type_id') ->addAttributeToFilter('type_id','simple'); echo $collection->getSelect()->__toString(); } 

But when I do this, I have this error:

 SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.type_id' in 'where clause' Trace: #0 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array) #1 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Zend/Db/Statement.php(300): Varien_Db_Statement_Pdo_Mysql->_execute(Array) #2 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Zend/Db/Adapter/Abstract.php(479): Zend_Db_Statement->execute(Array) #3 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('SELECT FLOOR((R...', Array) #4 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Varien/Db/Adapter/Pdo/Mysql.php(419): Zend_Db_Adapter_Pdo_Abstract->query('SELECT FLOOR((R...', Array) #5 /Users/Ditchou/Documents/ProjetsWeb/lolote/lib/Zend/Db/Adapter/Abstract.php(808): Varien_Db_Adapter_Pdo_Mysql->query(Object(Varien_Db_Select), Array) #6 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Resource/Layer/Filter/Price.php(274): Zend_Db_Adapter_Abstract->fetchPairs(Object(Varien_Db_Select)) #7 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(158): Mage_Catalog_Model_Resource_Layer_Filter_Price->getCount(Object(Mage_Catalog_Model_Layer_Filter_Price), 10) #8 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(115): Mage_Catalog_Model_Layer_Filter_Price->getRangeItemCounts(10) #9 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(314): Mage_Catalog_Model_Layer_Filter_Price->getPriceRange() #10 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(151): Mage_Catalog_Model_Layer_Filter_Price->_getItemsData() #11 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(120): Mage_Catalog_Model_Layer_Filter_Abstract->_initItems() #12 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Model/Layer/Filter/Abstract.php(109): Mage_Catalog_Model_Layer_Filter_Abstract->getItems() #13 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/Block/Layer/Filter/Abstract.php(132): Mage_Catalog_Model_Layer_Filter_Abstract->getItemsCount() #14 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/design/frontend/decostore/default/template/catalog/layer/view.phtml(49): Mage_Catalog_Block_Layer_Filter_Abstract->getItemsCount() #15 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(241): include('/Users/Ditchou/...') #16 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(272): Mage_Core_Block_Template->fetchView('frontend/decost...') #17 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(286): Mage_Core_Block_Template->renderView() #18 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Core_Block_Template->_toHtml() #19 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Text/List.php(43): Mage_Core_Block_Abstract->toHtml() #20 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Core_Block_Text_List->_toHtml() #21 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(582): Mage_Core_Block_Abstract->toHtml() #22 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(526): Mage_Core_Block_Abstract->_getChildHtml('left', true) #23 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/design/frontend/decostore/default/template/page/2columns-left.phtml(19): Mage_Core_Block_Abstract->getChildHtml('left') #24 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(241): include('/Users/Ditchou/...') #25 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(272): Mage_Core_Block_Template->fetchView('frontend/decost...') #26 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Template.php(286): Mage_Core_Block_Template->renderView() #27 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Block/Abstract.php(863): Mage_Core_Block_Template->_toHtml() #28 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Model/Layout.php(555): Mage_Core_Block_Abstract->toHtml() #29 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Controller/Varien/Action.php(390): Mage_Core_Model_Layout->getOutput() #30 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Catalog/controllers/CategoryController.php(159): Mage_Core_Controller_Varien_Action->renderLayout() #31 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Controller/Varien/Action.php(419): Mage_Catalog_CategoryController->viewAction() #32 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('view') #33 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Controller/Varien/Front.php(176): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http)) #34 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch() #35 /Users/Ditchou/Documents/ProjetsWeb/lolote/app/Mage.php(683): Mage_Core_Model_App->run(Array) #36 /Users/Ditchou/Documents/ProjetsWeb/lolote/index.php(87): Mage::run('', 'store') #37 {main} 

It seems like an error occurs here: # 6 / Users / Ditchou / Documents / ProjetsWeb / lolote / app / code / core / Mage / Catalog / Model / Resource / Layer / Filter / Price.php (274): Zend_Db_Adapter_Abstract-> fetchPairs ( Object (Varien_Db_Select))

I do not understand, because when I just do

 $collectionSimple = Mage::getResourceModel('catalog/product_collection') ->addAttributeToFilter('type_id', array('eq' => 'simple')); 

The sql query echo gives me:

 SELECT `e`.*, `cat_index`.`position` AS `cat_index_position`, `price_index`.`price`, `price_index`.`tax_class_id`, `price_index`.`final_price`, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS `minimal_price`, `price_index`.`min_price`, `price_index`.`max_price`, `price_index`.`tier_price` FROM `catalog_product_entity` AS `e` INNER JOIN `catalog_category_product_index` AS `cat_index` ON cat_index.product_id=e.entity_id AND cat_index.store_id=1 AND cat_index.visibility IN(2, 4) AND cat_index.category_id='3' INNER JOIN `catalog_product_index_price` AS `price_index` ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0 WHERE (`e`.`type_id` = 'simple') 

it works.

Why is the layer model collection different?

+4
source share
3 answers

Are you sure the error you are getting? In Magento 1.7.x, when I replace the body of the prepareProductCollection method prepareProductCollection one above, I get this error

 SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.min_price' in 'where clause' 

This is because my prepareProductCollection did not set the same properties as the original. To get started, make sure you have one. If you do this using configuration-based rewriting, call

 parent::prepareProductCollection($collection); 

at the beginning of your method. If you use override of the local or community pool, then you need to copy / paste the code from the core file. In 1.7.1 it will look like

  $collection ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes()) ->addMinimalPrice() ->addFinalPrice() ->addTaxPercents() ->addUrlRewrite($this->getCurrentCategory()->getId()); Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection); Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection); $collection ->addAttributeToSelect('type_id') ->addAttributeToFilter('type_id','simple'); 

If this does not help you, trace your column - if your error is really 1054 Unknown column 'e.type_id' in 'where clause' , then I assume that you have some kind of custom code that works somewhere that copies collection filters to another collection.

Alternatively, you can get the initial SQL collection query using

 echo $collection->getSelect()->__toString(); 

This should give you enough debugging information.

Update: OK, in accordance with the new information above, this is displayed only when there is a price filter and / or when the indices are in a certain state.

Here is your problem. Take a look at this call stack line.

 #7 app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php(158): Mage_Catalog_Model_Resource_Layer_Filter_Price->getCount(Object(Mage_Catalog_Model_Layer_Filter_Price), 10) 

If you go to getCount method, you will see _getSelect call

 #File: app/code/core/Mage/Catalog/Model/Resource/Layer/Filter/Price.php public function getCount($filter, $range) { $select = $this->_getSelect($filter); 

If you look at the definition of _getSelect ,

 #partial method reproduction #File: app/code/core/Mage/Catalog/Model/Resource/Layer/Filter/Price.php protected function _getSelect($filter) { $collection = $filter->getLayer()->getProductCollection(); $collection->addPriceData($filter->getCustomerGroupId(), $filter->getWebsiteId()); if (!is_null($collection->getCatalogPreparedSelect())) { $select = clone $collection->getCatalogPreparedSelect(); } else { $select = clone $collection->getSelect(); } 

you will see that Magento is cloning a selection from a collection, and then changing it to select from an index table

  // processing FROM part $priceIndexJoinPart = $fromPart[Mage_Catalog_Model_Resource_Product_Collection::INDEX_TABLE_ALIAS]; $priceIndexJoinConditions = explode('AND', $priceIndexJoinPart['joinCondition']); $priceIndexJoinPart['joinType'] = Zend_Db_Select::FROM; $priceIndexJoinPart['joinCondition'] = null; $fromPart[Mage_Catalog_Model_Resource_Product_Collection::MAIN_TABLE_ALIAS] = $priceIndexJoinPart; unset($fromPart[Mage_Catalog_Model_Resource_Product_Collection::INDEX_TABLE_ALIAS]); $select->setPart(Zend_Db_Select::FROM, $fromPart); foreach ($fromPart as $key => $fromJoinItem) { $fromPart[$key]['joinCondition'] = $this->_replaceTableAlias($fromJoinItem['joinCondition']); } $select->setPart(Zend_Db_Select::FROM, $fromPart); 

Since there is no type_id column in the index table, the Magento stock code above is not compatible with your change. If I was going to continue this, I would

  • Switch to rewrite based approach

  • Create a conversation that will add your type_id filter instead of your override

  • Create a second rewrite using the _getSelect method above, which checks the selection for the type_id filter, and if it finds it, removes it

Alternatively, you can try to find another method to overwrite the collection object, which is closer to where it was used.

Good luck

+8
source

I had the same problem 2-3 weeks ago when I tried to add layer navigation to user collections (and not to a collection dependent collection or search collections). I had the same problem that you encountered that comes from the price filter processing used in multi-level navigation. As Alan suggested, in Magento 1.7 they did the optimization on the selected sql, which is used for price filtering options. They remove the sql FROM part (which is the product object that contains the type_id attribute), and makes the price-related table the main reference — the one used in the FROM part of the request. Thus, basically the table from which the data is selected is no longer a product entity table (you lose all the basic product attributes), the main table becomes the product index. This is a basic update that the Magento team has added since version 1.7.

I also have a fix for this, I will share it with him tomorrow, now I do not have access to this code.

+1
source

I had problems with the extension of the _getSelect function, which does not return the correct set for price filters in the sidebar, when I deleted the fields that cause an error from the select statement.

So, to get around the problem with fields that don't exist, I used a field that exists, entity_id. I expanded Mage_Catalog_Model_Category by changing the getProductCollection function:

 $collection = Mage::getResourceModel('catalog/product_collection') ->setStoreId($this->getStoreId()) ->addAttributeToFilter('type_id', array('eq' => 'simple')); // Get the product ids of the filtered collection $entityIds = $collection->getAllIds(); $collection = Mage::getResourceModel('catalog/product_collection') ->setStoreId($this->getStoreId()) ->addCategoryFilter($this) // Apply the product ids as a filter ->addIdFilter($entityIds,false); return $collection; 
0
source

All Articles