Сортировка категорий на основе атрибута товара
В моем проекте по умолчанию у меня есть несколько категорий, которые видны во внешнем интерфейсе, как показано ниже:
category-1
sub-category-1
sub-category-2
category-2
sub-category-1
category-3
category-4
category-5
Вышеуказанные категории должны быть отсортированы на основе значения атрибута item_branch
, которое будет присвоено каждому продукту (не категории или подкатегории). Этот атрибут может иметь следующие значения:
- X
- У
- Z
Итак, отсортированный список продуктов должен выглядеть следующим образом: ( многие ко многим отношения)
X
category-1
sub-category-2
category-2
sub-category-1
category-3
Y
category-1
sub-category-1
sub-category-2
Z
category-2
sub-category-1
category-3
category-4
category-5
Для достижения вышеупомянутой сортировки у меня на уме два подхода.
Первый - создать выпадающий атрибут в панели администратора (с возможными значениями X, Y и Z) и назначить группе в наборах атрибутов.
Во-вторых, добавить новый каталог как
item_branch
с категориямиX
,Y
иZ
и при создании продукта я назначу обе категории. т.е.category-1
иY
( для пример).
В вышеперечисленных подходах, какой из них лучше? или есть еще какой-нибудь лучший подход?
Пожалуйста, объясните это с помощью некоторого кода php.. так как я новичок в php.
1 answers
Хорошо, я пытаюсь объяснить свое решение, я привожу здесь наиболее важные моменты, но у вас должен быть некоторый опыт, такой как макеты magento, блоки, создание пользовательского модуля.
1. Создайте атрибут, который вы предполагали в своем вопросе.
2. Настройте свои продукты, прикрепив их к определенной категории и значению атрибута, созданному выше.
3. Создайте пользовательский блок, приведенный в примере (/app/code/local/Some/Module/Block/Catalog/Navigation.php
):
class Some_Module_Block_Catalog_Navigation extends Mage_Core_Block_Template
{
protected $_attributeCode = 'item_branch';
/**
* @return Mage_Catalog_Model_Resource_Eav_Attribute
*/
public function getAttribute()
{
$attribute = Mage::getModel('catalog/resource_eav_attribute')
->loadByCode(Mage_Catalog_Model_Product::ENTITY, $this->_attributeCode);
return $attribute;
}
protected function _construct()
{
$this->addData(array(
'cache_lifetime' => false,
'cache_tags' => array(Mage_Catalog_Model_Category::CACHE_TAG),
));
}
public function getCacheKeyInfo()
{
$shortCacheId = array(
'CATALOG_NAVIGATION',
Mage::app()->getStore()->getId(),
Mage::getDesign()->getPackageName(),
Mage::getDesign()->getTheme('template'),
'template' => $this->getTemplate(),
'name' => $this->getNameInLayout(),
$this->_attributeCode
);
return $shortCacheId;
}
public function getCategoryUrl($category)
{
if ($category instanceof Mage_Catalog_Model_Category) {
$url = $category->getUrl();
} else {
$url = $this->_getCategoryInstance()
->setData($category->getData())
->getUrl();
}
return $url;
}
public function getTree()
{
$attributeId = $this->getAttribute()->getId();
$websiteId = Mage::app()->getWebsite()->getId();
$resource = new Mage_Catalog_Model_Resource_Setup('core_setup');
$categories = Mage::getModel('catalog/category')->getCollection();
$categories
->addFieldToSelect(array('category_id' => 'entity_id', 'parent_id'))
->getSelect()
->join(array('cp' => $resource->getTable('catalog_category_product')), 'cp.category_id=main_table.entity_id', 'product_id')
->join(array('pw' => $resource->getTable('catalog_product_website')), "pw.product_id=cp.product_id AND pw.website_id = $websiteId", 'website_id')
->join(array('av' => $resource->getTable('catalog_product_entity_int')), "av.entity_id=pw.product_id AND av.attribute_id = $attributeId", array('option_id' => 'value'))
->join(array('ov' => $resource->getTable('eav_attribute_option_value')), 'ov.option_id=av.`value` AND ov.store_id = 0', array('option_value' => 'value'))
->order(array('option_value', 'category_id'));
$query = $categories->getSelectSql(true);
$data = $resource->getConnection()->fetchAll($query);
$tree = array();
foreach ($data as $row) {
$optionValue = $row['option_value'];
if (!isset($tree[$optionValue])) {
$tree[$optionValue] = array(
'label' => $optionValue,
'categories' => array()
);
}
$parentCategory = $row['parent_id'];
if (!isset($tree[$optionValue]['categories'][$parentCategory])) {
$tree[$optionValue]['categories'][$parentCategory] = array(
'category_id' => $parentCategory,
'sub_categories' => array(),
);
}
$categoryId = $row['category_id'];
$tree[$optionValue]['categories'][$parentCategory]['sub_categories'][$categoryId] = $categoryId;
}
return $tree;
}
}
Я создал этот блок для достижения кэширования моей пользовательской навигации по категориям, из-за для построения этой навигации требуется загрузить дополнительные данные из бд. Но вы можете использовать логику построения дерева в коде, приведенном выше, без использования блока.
4. Добавьте эту навигацию во внешний интерфейс с помощью local.xml планировка (/app/design/frontend/default/default/layout/local.xml
):
<?xml version="1.0"?>
<layout version="0.1.0">
<catalog_category_default translate="label">
<reference name="left">
<block type="some_module/catalog_navigation" name="catalog.leftnav" before="currency"
template="catalog/navigation/myleft.phtml"/>
</reference>
</catalog_category_default>
<catalog_category_layered translate="label">
<reference name="left">
<block type="some_module/catalog_navigation" name="catalog.myleft"
template="catalog/navigation/myleft.phtml"/>
</reference>
</catalog_category_layered>
</layout>
5. Создайте шаблон блока навигации (/app/design/frontend/default/default/template/catalog/navigation/myleft.phtml
):
<?php /* @var $this Some_Module_Block_Catalog_Navigation */ ?>
<?php $tree = $this->getTree(); ?>
<?php $categories = Mage::getModel('catalog/category')->getCollection()->addAttributeToSelect('name'); ?>
<?php $_count = count($tree) ?>
<?php if ($_count): ?>
<div class="block block-layered-nav">
<div class="block-title">
<strong><span><?php echo $this->__('Browse By ') . $this->getAttribute()->getFrontendLabel() ?></span></strong>
</div>
<div class="block-content">
<?php foreach ($tree as $label => $optionCategory): ?>
<div>
<h5><?php echo $label ?></h5>
<ul>
<?php foreach ($optionCategory['categories'] as $parent): ?>
<?php $_category = $categories->getItemById($parent['category_id']) ?>
<li>
<a href="<?php echo $this->getCategoryUrl($_category) ?>"><?php echo $this->htmlEscape($_category->getName()) ?></a>
<ul>
<?php foreach ($parent['sub_categories'] as $categoryId): ?>
<?php $_category = $categories->getItemById($categoryId) ?>
<li>
--<a href="<?php echo $this->getCategoryUrl($_category) ?>"><?php echo $this->htmlEscape($_category->getName()) ?></a>
</li>
<?php endforeach ?>
</ul>
</li>
<?php endforeach ?>
</ul>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
6. Вы можете исправить дизайн этого меню, добавив некоторые css-классы и правила по своему усмотрению.
Кстати, ваш тип атрибута должен быть выбран. Попытайтесь понять логику и приспособить ее к вашим магазин, это дает мне идеальный результат, возможно, он не работает с помощью копирования/вставки без понимания и настройки кода. Смотрите мой результат:
P.S: возможно, в этом решении есть некоторые ошибки или проблемы, которые я не почувствовал, комментарии будут оценены.