Подскажите как сделать сортировку товаров сразу по двум атрибутам, т.е. аналог SQL запроса
ORDER BY sku ASC, name DESC
Подозреваю, что надо поправить что-то тут:
app/design/frontend/default/default/template/catalog/product/list.phtml
Но что конкретно нагуглить так и не удалось (
Соответственно нужно отключить выбор типа сортировки в теме, это как сделать вообще не нашел.
Заранее благодарен
Шаблона мало. Надо править блоки. Точнее можно сделать оверрайд блока Mage_Catalog_Block_Product_List поменяв метод _getProductCollection(). Шаблон кстати при этом трогать вообще не надо.
evmedvedev, спасибо за совет!
Можно чуть-чуть подробнее? Я в Magento новичек, уж простите )
Где мне найти блок Mage_Catalog_Block_Product_List ? И не хотелось бы конечно в core лезть, чтобы при обновлении не слетело, как правильно в magento override сделать?
Заранее благодарен!!!
Тогда вам будет не просто разобраться. Вообще указанный файл нужно искать в /app/code/core/Mage/Catalog/Block/Product и он там фигурирует как List.php (в нем и декларируется класс Mage_Catalog_Block_Product_List). Как видите приведенный выше класс формируется из /Mage/Catalog/Block/Product заменой слэшей на "_" и добавлением через него же List. Такой подход к организации кода заложен в Zend Framework на котором и построен движок и который желательно изучить получше. Для замены функционала ядра без его перезаписывания нужно положить файл List.php в каталог /app/code/local/Mage/Catalog/Block/Product (обратите внимание на замену core на local) и после этого можете экспериментировать с указанными функциями.
Спасибо, evmedvedev!
В принципе получается, подскажите только один нюанс:
В методе _getProductCollection перед
return $this->_productCollection;
добавляю
$this->_productCollection->getSelect()->reset( Zend_Db_Select::ORDER ); $this->_productCollection->getSelect()->joinLeft('eav_attribute_option', 'eav_attribute_option.option_id = e.seasons', array('eav_attribute_option.sort_order')); $this->_productCollection->getSelect()->joinLeft('eav_attribute', join(' AND ', array('eav_attribute.attribute_code = "seasons"', 'eav_attribute.attribute_id = eav_attribute_option.attribute_id')), array()); $this->_productCollection->getSelect()->order(array('e.seasons DESC', 'e.importance ASC'));
Почему-то JOIN-ы он добавляет в запрос 2 раза:
SELECT 1 AS `status`, `e`.`entity_id`, `e`.`type_id`, `e`.`attribute_set_id`, `cat_index`.`position` AS `cat_index_position`, `e`.`name`, `e`.`short_description`, `e`.`sku`, `e`.`price`, `e`.`special_price`, `e`.`special_from_date`, `e`.`special_to_date`, `e`.`small_image`, `e`.`thumbnail`, `e`.`news_from_date`, `e`.`news_to_date`, `e`.`url_key`, `e`.`required_options`, `e`.`image_label`, `e`.`small_image_label`, `e`.`thumbnail_label`, `e`.`msrp_enabled`, `e`.`msrp_display_actual_price_type`, `e`.`msrp`, `e`.`price_type`, `e`.`weight_type`, `e`.`price_view`, `e`.`shipment_type`, `e`.`links_purchased_separately`, `e`.`links_exist`, `e`.`razmery`, `e`.`manufacturer_my`, `e`.`manufacturer_my_value`, `e`.`color_my`, `e`.`razmer_chashechki_2`, `e`.`obhvat_pod_grudyu_my`, `e`.`seasons`, `e`.`seasons_value`, `e`.`importance`, `e`.`importance_value`, `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`, `eav_attribute_option`.`sort_order`, `eav_attribute_option`.`sort_order` FROM `catalog_product_flat_1` 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 = '6' 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 LEFT JOIN `eav_attribute_option` ON eav_attribute_option.option_id = e.seasons LEFT JOIN `eav_attribute` ON eav_attribute.attribute_code = "seasons" AND eav_attribute.attribute_id = eav_attribute_option.attribute_id LEFT JOIN `eav_attribute_option` AS `eav_attribute_option_2` ON eav_attribute_option.option_id = e.seasons LEFT JOIN `eav_attribute` AS `eav_attribute_2` ON eav_attribute.attribute_code = "seasons" AND eav_attribute.attribute_id = eav_attribute_option.attribute_id ORDER BY `eav_attribute_option`.`sort_order` ASC, `e`.`importance_value` DESC, `cat_index_position` ASC, `cat_index`.`position` ASC LIMIT 12
Если бы он не добавлял JOIN по два раза, то получился бы такой запрос:
SELECT 1 AS `status`, `e`.`entity_id`, `e`.`type_id`, `e`.`attribute_set_id`, `cat_index`.`position` AS `cat_index_position`, `e`.`name`, `e`.`short_description`, `e`.`sku`, `e`.`price`, `e`.`special_price`, `e`.`special_from_date`, `e`.`special_to_date`, `e`.`small_image`, `e`.`thumbnail`, `e`.`news_from_date`, `e`.`news_to_date`, `e`.`url_key`, `e`.`required_options`, `e`.`image_label`, `e`.`small_image_label`, `e`.`thumbnail_label`, `e`.`msrp_enabled`, `e`.`msrp_display_actual_price_type`, `e`.`msrp`, `e`.`price_type`, `e`.`weight_type`, `e`.`price_view`, `e`.`shipment_type`, `e`.`links_purchased_separately`, `e`.`links_exist`, `e`.`razmery`, `e`.`manufacturer_my`, `e`.`manufacturer_my_value`, `e`.`color_my`, `e`.`razmer_chashechki_2`, `e`.`obhvat_pod_grudyu_my`, `e`.`seasons`, `e`.`seasons_value`, `e`.`importance`, `e`.`importance_value`, `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`, `eav_attribute_option`.`sort_order`, `eav_attribute_option`.`sort_order` FROM `catalog_product_flat_1` 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 = '6' 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 LEFT JOIN `eav_attribute_option` ON eav_attribute_option.option_id = e.seasons LEFT JOIN `eav_attribute` ON eav_attribute.attribute_code = "seasons" AND eav_attribute.attribute_id = eav_attribute_option.attribute_id ORDER BY `eav_attribute_option`.`sort_order` ASC, `e`.`importance_value` DESC, `cat_index_position` ASC, `cat_index`.`position` ASC LIMIT 12
который работает на ура
В чем косяк?
Так ничего и не получилось ((
Mage/Catalog/Block/Product/List.php перестал мучать,
пробую зайти через
app/design/frontend/default/theme/template/catalog/product/list.phtml
таким образом:
$_productCollection=$this->getLoadedProductCollection(); $_productCollection->getSelect()->joinLeft('eav_attribute_option', 'eav_attribute_option.option_id = e.seasons', array('eav_attribute_option.sort_order')); $_productCollection->getSelect()->joinLeft('eav_attribute', join(' AND ', array('eav_attribute.attribute_code = "seasons"', 'eav_attribute.attribute_id = eav_attribute_option.attribute_id')), array()); $_productCollection->getSelect()->reset( Zend_Db_Select::ORDER ); $_productCollection->getSelect()->order(array('eav_attribute_option.sort_order ASC', 'e.importance_value DESC'));
Получаю такую ошибку:
a:5:{i:0;s:836:"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.seasons' in 'on clause', query was: SELECT FLOOR((ROUND((e.min_price) * 1, 2)) / 1000) + 1 AS `range`, COUNT(*) AS `count` FROM `catalog_product_index_price` 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 = '38' LEFT JOIN `eav_attribute_option` ON eav_attribute_option.option_id = e.seasons LEFT JOIN `eav_attribute` ON eav_attribute.attribute_code = "seasons" AND eav_attribute.attribute_id = eav_attribute_option.attribute_id WHERE ( e.website_id = '1' ) AND ( e.customer_group_id = 0) AND (e.min_price IS NOT NULL) GROUP BY FLOOR((ROUND((e.min_price) * 1, 2)) / 1000) + 1 ORDER BY FLOOR((ROUND((e.min_price) * 1, 2)) / 1000) + 1 ASC";i:1;s:5575:"#0 /var/htdocs/happymam.new/public_html/lib/Varien/Db/Statement/Pdo/Mysql.php(110): Zend_Db_Statement_Pdo->_execute(Array)
Откуда этот запрос взялся - вообще мне не понятно ((, потому что
$fw = fopen('/var/htdocs/happymam.new/public_html/media/dump.txt', 'a'); ob_start(); var_dump($_productCollection->getSelect()->__toString()); fwrite($fw, "-------------------\n\n\n\n" . ob_get_contents()); ob_end_clean(); fclose($fw);
Дает такой результат:
SELECT 1 AS `status`, `e`.`entity_id`, `e`.`type_id`, `e`.`attribute_set_id`, `cat_index`.`position` AS `cat_index_position`, `e`.`name`, `e`.`short_description`, `e`.`sku`, `e`.`price`, `e`.`special_price`, `e`.`special_from_date`, `e`.`special_to_date`, `e`.`small_image`, `e`.`thumbnail`, `e`.`news_from_date`, `e`.`news_to_date`, `e`.`url_key`, `e`.`required_options`, `e`.`image_label`, `e`.`small_image_label`, `e`.`thumbnail_label`, `e`.`msrp_enabled`, `e`.`msrp_display_actual_price_type`, `e`.`msrp`, `e`.`price_type`, `e`.`weight_type`, `e`.`price_view`, `e`.`shipment_type`, `e`.`links_purchased_separately`, `e`.`links_exist`, `e`.`razmery`, `e`.`manufacturer_my`, `e`.`manufacturer_my_value`, `e`.`color_my`, `e`.`razmer_chashechki_2`, `e`.`obhvat_pod_grudyu_my`, `e`.`seasons`, `e`.`seasons_value`, `e`.`importance`, `e`.`importance_value`, `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`, `eav_attribute_option`.`sort_order` FROM `catalog_product_flat_1` 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 = '38' 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 LEFT JOIN `eav_attribute_option` ON eav_attribute_option.option_id = e.seasons LEFT JOIN `eav_attribute` ON eav_attribute.attribute_code = "seasons" AND eav_attribute.attribute_id = eav_attribute_option.attribute_id ORDER BY `eav_attribute_option`.`sort_order` ASC, `e`.`importance_value` DESC LIMIT 12
Откуда у меня ошибка вылазит? ((
Может я могу в конце файла удалить как-то свои LEFT JOIN-ы ???
Ну тут на вскидку ни чего сказать не могу. У меня таких проблем не было. Остатется только методом проб и ошибок :-).
Ура, получилось )
В List.php добавил:
$this->_productCollection->getSelect()->joinLeft('eav_attribute_option', 'eav_attribute_option.option_id = e.seasons', array('eav_attribute_option.sort_order')); $this->_productCollection->getSelect()->joinLeft('eav_attribute', join(' AND ', array('eav_attribute.attribute_code = "seasons"', 'eav_attribute.attribute_id = eav_attribute_option.attribute_id')), array()); $this->_productCollection->getSelect()->reset( Zend_Db_Select::ORDER ); $this->_productCollection->getSelect()->order(array('eav_attribute_option.sort_order ASC', 'e.importance_value DESC'));
А в шаблоне выключил указание количества товаров по фильтрам (фильтр в сайдбаре по цене и атрибутам - именно в запросе подсчета был конфликт)