/** * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @return array */ public function getCount($filter) { // clone select from collection with filters $select = clone $filter->getLayer()->getProductCollection()->getSelect(); // reset columns, order and limitation conditions $select->reset(Zend_Db_Select::COLUMNS); $select->reset(Zend_Db_Select::ORDER); $select->reset(Zend_Db_Select::LIMIT_COUNT); $select->reset(Zend_Db_Select::LIMIT_OFFSET); // Redefining join type to allow multiple attribute values on currently filtered attribute $fromPart = $select->getPart(Zend_Db_Select::FROM); foreach ($fromPart as $key => &$part) { if ($key == $filter->getAttributeModel()->getAttributeCode() . '_idx') { $part['joinType'] = Zend_Db_Select::LEFT_JOIN; } } unset($part); $select->reset(Zend_Db_Select::FROM); $select->setPart(Zend_Db_Select::FROM, $fromPart); $connection = $this->_getReadAdapter(); $attribute = $filter->getAttributeModel(); $tableAlias = sprintf('%s_index', $attribute->getAttributeCode()); $conditions = array("{$tableAlias}.entity_id = e.entity_id", $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()), $connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId())); $select->join(array($tableAlias => $this->getMainTable()), join(' AND ', $conditions), array('value', 'count' => new Zend_Db_Expr("COUNT(DISTINCT {$tableAlias}.entity_id)")))->group("{$tableAlias}.value"); return $connection->fetchPairs($select); }
/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @return array */ public function getCount($filter) { $connection = $this->_getReadAdapter(); $attribute = $filter->getAttributeModel(); $tableAlias = $attribute->getAttributeCode() . '_idx'; $base_select = $filter->getLayer()->getBaseSelect(); if (isset($base_select[$attribute->getAttributeCode()])) { $select = $base_select[$attribute->getAttributeCode()]; } else { $select = clone $filter->getLayer()->getProductCollection()->getSelect(); } // reset columns, order and limitation conditions $select->reset(Zend_Db_Select::COLUMNS); $select->reset(Zend_Db_Select::ORDER); $select->reset(Zend_Db_Select::LIMIT_COUNT); $select->reset(Zend_Db_Select::LIMIT_OFFSET); $select->reset(Zend_Db_Select::GROUP); $conditions = array("{$tableAlias}.entity_id = e.entity_id", $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()), $connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId())); $select->join(array($tableAlias => $this->getMainTable()), join(' AND ', $conditions), array('value', 'count' => "COUNT(DISTINCT {$tableAlias}.entity_id)"))->group("{$tableAlias}.value"); $_collection = clone $filter->getLayer()->getProductCollection(); $searched_entity_ids = $_collection->load()->getSearchedEntityIds(); if ($searched_entity_ids && is_array($searched_entity_ids) && count($searched_entity_ids)) { $select->where('e.entity_id IN (?)', $searched_entity_ids); } return $connection->fetchPairs($select); }
/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter The current catalog filter * * @return array */ public function getCount($filter) { $catalogResource = Mage::getResourceModel("catalog/product"); $attribute = $filter->getAttributeModel(); /** * For legacy SQL based attributes, Magento based the query on "catalog/product_index_eav", let him do */ if (in_array($attribute->getAttributeCode(), $catalogResource->getSqlAttributesCodes())) { return parent::getCount($filter); } /** * Since we have MongoDB, nothing is stored on eav index table for other attributes * Let's build the query with an aggregation * * @see http://docs.mongodb.org/manual/reference/operator/aggregation/ */ $collection = clone $filter->getLayer()->getProductCollection(); /** @var Smile_MongoCore_Model_Resource_Connection_Adapter $adapter */ $adapter = Mage::getSingleton('mongocore/resource_connection_adapter'); $queryBuilder = $adapter->getQueryBuilder(); $collectionName = Mage::getResourceModel('catalog/product')->getEntityTable(); $docCollection = $adapter->getCollection($collectionName); /** Build a condition to have all products which have the specified attribute as "notnull" AND not an empty string */ $scopedAttributeName = 'attr_' . $filter->getStoreId() . '.' . $attribute->getAttributeCode(); $globalAttributeName = 'attr_' . Mage_Core_Model_App::ADMIN_STORE_ID . '.' . $attribute->getAttributeCode(); $filterCascade = array('$or' => array(array('$and' => array(array($scopedAttributeName => array('$exists' => 1)))), array('$and' => array(array($scopedAttributeName => array('$exists' => 0)), array($globalAttributeName => array('$exists' => 1)))))); $documentFilter = $filterCascade; $documentFilter['$or'][0]['$and'][] = array($scopedAttributeName => array('$' . "ne" => 'null')); $documentFilter['$or'][0]['$and'][] = array($scopedAttributeName => array('$' . "ne" => '')); $documentFilter['$or'][1]['$and'][] = array($globalAttributeName => array('$' . "ne" => 'null')); $documentFilter['$or'][1]['$and'][] = array($globalAttributeName => array('$' . "ne" => '')); /** First, the matching, current product ids, and our calculated document filter **/ $match = array('$and' => array($queryBuilder->getIdsFilter($collection->getAllIds()), $documentFilter)); /** And then, the grouping, by attribute values, and calculating a sum */ $group = array("_id" => array("{$scopedAttributeName}" => '$' . $scopedAttributeName, "{$globalAttributeName}" => '$' . $globalAttributeName), "total" => array('$sum' => 1)); /** Building aggregation pipeline based on match and group previously built */ $pipeline = array(array('$match' => $match), array('$group' => $group)); $aggregation = $docCollection->aggregate($pipeline); /** * Now parse the aggregation result * Goal is to obtain an array like this : * * <attribute option id> => <total number of occurences> */ $aggregationResult = array(); if ($aggregation['ok'] == 1 && isset($aggregation["result"])) { foreach ($aggregation["result"] as $aggregate) { if (isset($aggregate["_id"]) && isset($aggregate['total'])) { $option = null; foreach ($aggregate["_id"] as $value) { $option = $value; } if (!is_null($option)) { $aggregationResult[$option] = $aggregate['total']; } } } } return ksort($aggregationResult); }
/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter Filter * @return array */ public function getCount($filter) { // clone select from collection with filters $select = clone $filter->getLayer()->getProductCollection()->getSelect(); // reset columns, order and limitation conditions $select->reset(Zend_Db_Select::COLUMNS); $select->reset(Zend_Db_Select::ORDER); $select->reset(Zend_Db_Select::LIMIT_COUNT); $select->reset(Zend_Db_Select::LIMIT_OFFSET); $select->reset(Zend_Db_Select::GROUP); $connection = $this->_getReadAdapter(); $attribute = $filter->getAttributeModel(); $tableAlias = sprintf('%s_idx', $attribute->getAttributeCode()); $conditions = array("{$tableAlias}.entity_id = e.entity_id", $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()), $connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId())); $conditions = join(' AND ', $conditions); $fromParts = $select->getPart(Zend_Db_Select::FROM); if (isset($fromParts[$tableAlias])) { $conditionArray = explode(' AND ', $fromParts[$tableAlias]['joinCondition']); unset($conditionArray[count($conditionArray) - 1]); $conditions = implode(' AND ', $conditionArray); unset($fromParts[$tableAlias]); $select->setPart(Zend_Db_Select::FROM, $fromParts); } $select->join(array($tableAlias => $this->getMainTable()), $conditions, array('value', 'count' => new Zend_Db_Expr("COUNT(distinct {$tableAlias}.entity_id)")))->group("{$tableAlias}.value"); return $connection->fetchPairs($select); }
/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @return array */ public function getCount($filter) { // clone select from collection with filters $select = clone $filter->getLayer()->getProductCollection()->getSelect(); // reset columns, order and limitation conditions $select->reset(Zend_Db_Select::COLUMNS); $select->reset(Zend_Db_Select::ORDER); $select->reset(Zend_Db_Select::LIMIT_COUNT); $select->reset(Zend_Db_Select::LIMIT_OFFSET); // Removed below as this was causing wrong counts // Not sure if this will break other functionality // $select->reset(Zend_Db_Select::WHERE); $connection = $this->_getReadAdapter(); $attribute = $filter->getAttributeModel(); $tableAlias = sprintf('%s_idx', $attribute->getAttributeCode()); $conditions = array("{$tableAlias}.entity_id = e.entity_id", $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()), $connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId())); $from = $select->getPart('from'); if (array_key_exists($tableAlias, $from)) { $select->reset(Zend_Db_Select::FROM); unset($from[$tableAlias]); $select->setPart(Zend_Db_Select::FROM, $from); } $select->join(array($tableAlias => $this->getMainTable()), join(' AND ', $conditions), array('value', 'count' => new Zend_Db_Expr("COUNT({$tableAlias}.entity_id)")))->group("{$tableAlias}.value"); return $connection->fetchPairs($select); }
/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @return array */ public function getCount($filter) { // clone select from collection with filters $select = clone $filter->getLayer()->getProductCollection()->getSelect(); // reset columns, order and limitation conditions $select->reset(Zend_Db_Select::COLUMNS); $select->reset(Zend_Db_Select::ORDER); $select->reset(Zend_Db_Select::LIMIT_COUNT); $select->reset(Zend_Db_Select::LIMIT_OFFSET); $connection = $this->_getReadAdapter(); $attribute = $filter->getAttributeModel(); $tableAlias = $attribute->getAttributeCode() . '_idx'; $conditions = array("{$tableAlias}.entity_id = e.entity_id", $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()), $connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId())); $select->join(array($tableAlias => $this->getMainTable()), join(' AND ', $conditions), array('value', 'count' => "COUNT({$tableAlias}.entity_id)"))->group("{$tableAlias}.value"); return $connection->fetchPairs($select); }
/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @return array */ public function getCount($filter, $requestVar = null) { // clone select from collection with filters $select = clone $filter->getLayer()->getProductCollection()->getSelect(); // reset columns, order and limitation conditions $select->reset(Zend_Db_Select::COLUMNS); $select->reset(Zend_Db_Select::ORDER); $select->reset(Zend_Db_Select::LIMIT_COUNT); $select->reset(Zend_Db_Select::LIMIT_OFFSET); $connection = $this->_getReadAdapter(); $attribute = $filter->getAttributeModel(); $tableAlias = sprintf('%s_idxcount', $attribute->getAttributeCode()); $conditions = array("{$tableAlias}.entity_id = e.entity_id", $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId()), $connection->quoteInto("{$tableAlias}.store_id = ?", $filter->getStoreId())); if (isset($requestVar)) { $options = $select->getPart('from'); $select->reset(Zend_Db_Select::FROM); unset($options[$requestVar . '_idx']); $select->forFrom($options); } $select->join(array($tableAlias => $this->getMainTable()), join(' AND ', $conditions), array('value', 'count' => new Zend_Db_Expr("COUNT({$tableAlias}.entity_id)")))->group("{$tableAlias}.value"); return $connection->fetchPairs($select); }
/** * Retrieve array with products counts per attribute option * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @return array */ public function getCount($filter) { // clone select from collection with filters $select = clone $filter->getLayer()->getProductCollection()->getSelect(); // reset columns, order and limitation conditions // $fromPart = $select->getPart(Zend_Db_Select::FROM); if (!empty($fromPart['cat_index']['joinCondition'])) { $fromPart['cat_index']['joinCondition'] = str_replace('cat_index.visibility IN(2, 4)', 'cat_index.visibility IN(2, 3, 4)', $fromPart['cat_index']['joinCondition']); } $select->setPart(Zend_Db_Select::FROM, $fromPart); // $select->reset(Zend_Db_Select::COLUMNS); $select->reset(Zend_Db_Select::ORDER); $select->reset(Zend_Db_Select::LIMIT_COUNT); $select->reset(Zend_Db_Select::LIMIT_OFFSET); $connection = $this->_getReadAdapter(); $attribute = $filter->getAttributeModel(); $tableAlias = $attribute->getAttributeCode() . '_idx'; $conditions = array("{$tableAlias}.entity_id = e.entity_id", $connection->quoteInto("{$tableAlias}.attribute_id = ?", $attribute->getAttributeId())); $select->join(array($tableAlias => $this->textfieldTable), join(' AND ', $conditions), array('value', 'count' => "COUNT({$tableAlias}.entity_id)"))->group("{$tableAlias}.value"); return $connection->fetchPairs($select); }
/** * In case we could not find a fitting dataset in database we generate a new one from given filter and option_id. * The current store's normalized and lowercased option label is used as speaking url segment for the current url. * * The process checks, whether the given option_id value belongs to the given filter's attribute model and whether * the attribute model is filterable (though this should work anyways as only filterable attributes can be used to * create attribute filters). * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter The given attribute Filter. * @param int $optionId The wanted option id. * @param int $storeId Id of the currently active store * @return Flagbit_FilterUrls_Model_Rewrite|false On success Self, otherwise false. */ public function generateNewRewrite($filter, $optionId, $storeId) { if (empty($filter) || !(int) $optionId) { return FALSE; } // load option from option_id $optionCollection = Mage::getResourceModel('eav/entity_attribute_option_collection')->setStoreFilter($storeId, true); // normally this should be done using the setIdFilter option of the collection. Unfortunately this results in an // error in Magento version 1.6.2.0 $optionCollection->getSelect()->where('`main_table`.`option_id` = ?', $optionId); $option = $optionCollection->getFirstItem(); // get all currently filterable attributes $category = Mage::registry('current_category'); $filterableAttributes = Mage::getSingleton('filterurls/catalog_layer')->setCurrentCategory($category)->getFilterableAttributes()->getItems(); // failure, if current attribute not filterable or the option does not belong to the given attribute model if (!in_array($option['attribute_id'], array_keys($filterableAttributes)) || $filterableAttributes[$option['attribute_id']]->getAttributeCode() != $filter->getAttributeModel()->getAttributeCode()) { return FALSE; } // get normalized and lowercased version of the options label $label = mb_strtolower(Mage::helper('filterurls')->normalize($option->getValue())); // try to load the label, try to avoid duplication of rewrite strings by simple alternations $rewrite = Mage::getModel('filterurls/rewrite')->loadByRewriteString($label); $addition = 0; while ($rewrite->getId()) { $rewrite = Mage::getModel('filterurls/rewrite')->loadByRewriteString($label . '_' . ++$addition); } if ($addition) { $label .= '_' . $addition; } //set data, save to database and return new values $this->setAttributeCode($filter->getAttributeModel()->getAttributeCode())->setOptionId($optionId)->setRewrite($label)->setStoreId($storeId)->save(); return $this; }
/** * Apply attribute filter to solr query * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @param int $value */ public function applyFilterToCollection($filter, $value) { if (empty($value)) { $value = array(); } else { if (!is_array($value)) { $value = array($value); } } $productCollection = $this->getLayer()->getProductCollection(); $attribute = $filter->getAttributeModel(); $param = Mage::helper('enterprise_search')->getSearchParam($productCollection, $attribute, $value); $productCollection->addSearchQfFilter($param); return $this; }
/** * Apply attribute filter to solr query * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @param int $value * * @return Enterprise_Search_Model_Catalog_Layer_Filter_Attribute */ public function applyFilterToCollection($filter, $value) { if (empty($value) || isset($value['from']) && empty($value['from']) && isset($value['to']) && empty($value['to'])) { $value = array(); } if (!is_array($value)) { $value = array($value); } $attribute = $filter->getAttributeModel(); $options = $attribute->getSource()->getAllOptions(); foreach ($value as &$valueText) { foreach ($options as $option) { if ($option['label'] == $valueText) { $valueText = $option['value']; } } } $fieldName = Mage::getResourceSingleton('enterprise_search/engine')->getSearchEngineFieldName($attribute, 'nav'); $this->getLayer()->getProductCollection()->addFqFilter(array($fieldName => $value)); return $this; }
/** * Apply attribute filter to solr query * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @param int $value * * @return Celebros_Conversionpro_Model_Catalog_Layer_Filter_Attribute */ public function applyFilterToCollection($filter, $value) { if (empty($value) || isset($value['from']) && empty($value['from']) && isset($value['to']) && empty($value['to'])) { $value = array(); } if (!is_array($value)) { $value = array($value); } $collection = Mage::helper('conversionpro')->getCurrentLayer()->getProductCollection(); $engine = Mage::getResourceSingleton('conversionpro/fulltext_engine'); $fieldName = $engine->getSearchEngineFieldName($filter->getAttributeModel(), 'nav'); foreach ($value as $answerId) { $collection->addFqFilter(array($fieldName => $answerId)); } return $this; }
/** * * * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter * @return array */ public function getCountAttribute($filter) { $ret = array(); if (empty($filter)) { return $ret; } $attribute = $filter->getAttributeModel(); if (empty($attribute)) { return $ret; } $label = 'attribute_' . $attribute->getId(); if (!$this->checkAttributesCountLabel($label)) { $vals = array(); $res = $this->getSearchResult(); if (!empty($res['facets'])) { foreach ($res['facets'] as $facet) { if ($facet['attribute'] == $label) { if (!empty($facet['buckets'])) { foreach ($facet['buckets'] as $bucket) { if ($bucket['count'] > 0) { $vals[$bucket['value']] = $bucket['count']; } } } } } } $this->setAttributesCountLabel($vals, $label); } return $this->getAttributesCountLabel($label); }