Сортировка категорий на основе атрибута товара


В моем проекте по умолчанию у меня есть несколько категорий, которые видны во внешнем интерфейсе, как показано ниже:

 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.

Author: Mr_Green, 2013-10-24

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-классы и правила по своему усмотрению.

Кстати, ваш тип атрибута должен быть выбран. Попытайтесь понять логику и приспособить ее к вашим магазин, это дает мне идеальный результат, возможно, он не работает с помощью копирования/вставки без понимания и настройки кода. Смотрите мой результат:
category navigation

P.S: возможно, в этом решении есть некоторые ошибки или проблемы, которые я не почувствовал, комментарии будут оценены.

 7
Author: mageUz, 2013-10-28 13:55:08