Ejemplo n.º 1
0
 /**
  * @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);
 }
Ejemplo n.º 2
0
 /**
  * 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);
 }
Ejemplo n.º 3
0
 /**
  * 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);
 }
Ejemplo n.º 4
0
 /**
  * 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);
 }
Ejemplo n.º 6
0
 /**
  * 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);
 }
Ejemplo n.º 7
0
 /**
  * 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);
 }
Ejemplo n.º 8
0
 /**
  * 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);
 }
Ejemplo n.º 9
0
 /**
  * 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;
 }
Ejemplo n.º 10
0
 /**
  * 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;
 }
Ejemplo n.º 12
0
 /**
  * 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;
 }
Ejemplo n.º 13
0
 /**
  * 
  *
  * @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);
 }