00001 <?php 00002 /** 00003 * Magento 00004 * 00005 * NOTICE OF LICENSE 00006 * 00007 * This source file is subject to the Open Software License (OSL 3.0) 00008 * that is bundled with this package in the file LICENSE.txt. 00009 * It is also available through the world-wide-web at this URL: 00010 * http://opensource.org/licenses/osl-3.0.php 00011 * If you did not receive a copy of the license and are unable to 00012 * obtain it through the world-wide-web, please send an email 00013 * to license@magentocommerce.com so we can send you a copy immediately. 00014 * 00015 * DISCLAIMER 00016 * 00017 * Do not edit or add to this file if you wish to upgrade Magento to newer 00018 * versions in the future. If you wish to customize Magento for your 00019 * needs please refer to http://www.magentocommerce.com for more information. 00020 * 00021 * @category Mage 00022 * @package Mage_Catalog 00023 * @copyright Copyright (c) 2009 Irubin Consulting Inc. DBA Varien (http://www.varien.com) 00024 * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) 00025 */ 00026 00027 00028 /** 00029 * Catalog view layer model 00030 * 00031 * @category Mage 00032 * @package Mage_Catalog 00033 * @author Magento Core Team <core@magentocommerce.com> 00034 */ 00035 class Mage_Catalog_Model_Layer extends Varien_Object 00036 { 00037 /** 00038 * Product collections array 00039 * 00040 * @var array 00041 */ 00042 protected $_productCollections = array(); 00043 00044 /** 00045 * Key which can be used for load/save aggregation data 00046 * 00047 * @var string 00048 */ 00049 protected $_stateKey = null; 00050 00051 /** 00052 * Get data aggregation object 00053 * 00054 * @return Mage_CatalogIndex_Model_Aggregation 00055 */ 00056 public function getAggregator() 00057 { 00058 return Mage::getSingleton('catalogindex/aggregation'); 00059 } 00060 00061 /** 00062 * Get layer state key 00063 * 00064 * @return string 00065 */ 00066 public function getStateKey() 00067 { 00068 if ($this->_stateKey === null) { 00069 $this->_stateKey = 'STORE_'.Mage::app()->getStore()->getId() 00070 . '_CAT_'.$this->getCurrentCategory()->getId() 00071 . '_CUSTGROUP_' . Mage::getSingleton('customer/session')->getCustomerGroupId(); 00072 } 00073 return $this->_stateKey; 00074 } 00075 00076 /** 00077 * Get default tags for current layer state 00078 * 00079 * @param array $additionalTags 00080 * @return array 00081 */ 00082 public function getStateTags(array $additionalTags = array()) 00083 { 00084 $additionalTags = array_merge($additionalTags, array( 00085 Mage_Catalog_Model_Category::CACHE_TAG.$this->getCurrentCategory()->getId() 00086 )); 00087 return $additionalTags; 00088 } 00089 00090 /** 00091 * Retrieve current layer product collection 00092 * 00093 * @return Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection 00094 */ 00095 public function getProductCollection() 00096 { 00097 if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) { 00098 $collection = $this->_productCollections[$this->getCurrentCategory()->getId()]; 00099 } 00100 else { 00101 $collection = $this->getCurrentCategory()->getProductCollection(); 00102 $this->prepareProductCollection($collection); 00103 $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection; 00104 } 00105 00106 return $collection; 00107 } 00108 00109 /** 00110 * Initialize product collection 00111 * 00112 * @param Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection $collection 00113 * @return Mage_Catalog_Model_Layer 00114 */ 00115 public function prepareProductCollection($collection) 00116 { 00117 $attributes = Mage::getSingleton('catalog/config') 00118 ->getProductAttributes(); 00119 $collection->addAttributeToSelect($attributes) 00120 ->addMinimalPrice() 00121 ->addFinalPrice() 00122 ->addTaxPercents() 00123 //->addStoreFilter() 00124 ; 00125 00126 Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection); 00127 Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection); 00128 $collection->addUrlRewrite($this->getCurrentCategory()->getId()); 00129 00130 return $this; 00131 } 00132 00133 /** 00134 * Apply layer 00135 * Method is colling after apply all filters, can be used 00136 * for prepare some index data before getting information 00137 * about existing intexes 00138 * 00139 * @return Mage_Catalog_Model_Layer 00140 */ 00141 public function apply() 00142 { 00143 $stateSuffix = ''; 00144 foreach ($this->getState()->getFilters() as $filterItem) { 00145 $stateSuffix.= '_'.$filterItem->getFilter()->getRequestVar() 00146 . '_' . $filterItem->getValueString(); 00147 } 00148 if (!empty($stateSuffix)) { 00149 $this->_stateKey = $this->getStateKey().$stateSuffix; 00150 } 00151 return $this; 00152 } 00153 00154 /** 00155 * Retrieve current category model 00156 * If no category found in registry, the root will be taken 00157 * 00158 * @return Mage_Catalog_Model_Category 00159 */ 00160 public function getCurrentCategory() 00161 { 00162 $category = $this->getData('current_category'); 00163 if (is_null($category)) { 00164 if ($category = Mage::registry('current_category')) { 00165 $this->setData('current_category', $category); 00166 } 00167 else { 00168 $category = Mage::getModel('catalog/category')->load($this->getCurrentStore()->getRootCategoryId()); 00169 $this->setData('current_category', $category); 00170 } 00171 } 00172 return $category; 00173 } 00174 00175 /** 00176 * Change current category object 00177 * 00178 * @param mixed $category 00179 * @return Mage_Catalog_Model_Layer 00180 */ 00181 public function setCurrentCategory($category) 00182 { 00183 if (is_numeric($category)) { 00184 $category = Mage::getModel('catalog/category')->load($category); 00185 } 00186 if (!$category instanceof Mage_Catalog_Model_Category) { 00187 Mage::throwException(Mage::helper('catalog')->__('Category must be instance of Mage_Catalog_Model_Category')); 00188 } 00189 if (!$category->getId()) { 00190 Mage::throwException(Mage::helper('catalog')->__('Invalid category')); 00191 } 00192 00193 if ($category->getId() != $this->getCurrentCategory()->getId()) { 00194 $this->setData('current_category', $category); 00195 } 00196 00197 return $this; 00198 } 00199 00200 /** 00201 * Retrieve current store model 00202 * 00203 * @return Mage_Core_Model_Store 00204 */ 00205 public function getCurrentStore() 00206 { 00207 return Mage::app()->getStore(); 00208 } 00209 00210 /** 00211 * Get collection of all filterable attributes for layer products set 00212 * 00213 * @return Mage_Eav_Model_Mysql4_Entity_Attribute_Collection 00214 */ 00215 public function getFilterableAttributes() 00216 { 00217 $entity = Mage::getSingleton('eav/config') 00218 ->getEntityType('catalog_product'); 00219 00220 $setIds = $this->_getSetIds(); 00221 if (!$setIds) { 00222 return array(); 00223 } 00224 00225 $collection = Mage::getModel('eav/entity_attribute') 00226 ->getCollection() 00227 ->setItemObjectClass('catalog/resource_eav_attribute'); 00228 00229 /* @var $collection Mage_Eav_Model_Mysql4_Entity_Attribute_Collection */ 00230 $collection->getSelect()->distinct(true); 00231 $collection 00232 ->setEntityTypeFilter($entity->getId()) 00233 ->setAttributeSetFilter($setIds) 00234 ->setOrder('position', 'ASC'); 00235 $collection = $this->_prepareAttributeCollection($collection); 00236 $collection->load(); 00237 00238 return $collection; 00239 } 00240 00241 /** 00242 * Prepare attribute for use in layered navigation 00243 * 00244 * @param Mage_Eav_Model_Entity_Attribute $attribute 00245 * @return Mage_Eav_Model_Entity_Attribute 00246 */ 00247 protected function _prepareAttribute($attribute) 00248 { 00249 Mage::getResourceSingleton('catalog/product')->getAttribute($attribute); 00250 return $attribute; 00251 } 00252 00253 /** 00254 * Add filters to attribute collection 00255 * 00256 * @param Mage_Eav_Model_Mysql4_Entity_Attribute_Collection $collection 00257 * @return Mage_Eav_Model_Mysql4_Entity_Attribute_Collection 00258 */ 00259 protected function _prepareAttributeCollection($collection) 00260 { 00261 $collection->addIsFilterableFilter(); 00262 return $collection; 00263 } 00264 00265 /** 00266 * Retrieve layer state object 00267 * 00268 * @return Mage_Catalog_Model_Layer_State 00269 */ 00270 public function getState() 00271 { 00272 $state = $this->getData('state'); 00273 if (is_null($state)) { 00274 Varien_Profiler::start(__METHOD__); 00275 $state = Mage::getModel('catalog/layer_state'); 00276 $this->setData('state', $state); 00277 Varien_Profiler::stop(__METHOD__); 00278 } 00279 return $state; 00280 } 00281 00282 /** 00283 * Get attribute sets idendifiers of current product set 00284 * 00285 * @return array 00286 */ 00287 protected function _getSetIds() 00288 { 00289 $key = $this->getStateKey().'_SET_IDS'; 00290 $setIds = $this->getAggregator()->getCacheData($key); 00291 00292 if ($setIds === null) { 00293 $setIds = $this->getProductCollection()->getSetIds(); 00294 $this->getAggregator()->saveCacheData($setIds, $key, $this->getStateTags()); 00295 } 00296 return $setIds; 00297 } 00298 }