Как получить фильтруемые атрибуты из категории в magento 2

Я создал категорию «Сумка» в magento 2. с атрибутом фильтра:

  1. цвет
  2. Размер

Я пытаюсь получить фильтруемые атрибуты из категории «Сумка».

Я не нашел никакого решения.

Я уже сделал это в magento 1.9:

Mage::app()->setCurrentStore($store);
$layer = Mage::getModel("catalog/layer");
$category = Mage::getModel("catalog/category")->load($categoryid);  
$layer->setCurrentCategory($category);
$attributes = $layer->getFilterableAttributes();

Но я не получил этого в Magento 2.x

Помогите пожалуйста мне


person Vishal Kamal    schedule 19.12.2016    source источник


Ответы (1)


Недавно я столкнулся с той же проблемой.

Я задокументировал свое расследование здесь.

Мне не удалось найти API-интерфейс фреймворка для предоставления фильтруемых атрибутов для определенной категории, однако я поделюсь обходными путями.

В основном все фильтруемые атрибуты в Magento 2 можно получить из FilterableAttributeList:

$filterableAttributes = ObjectManager::getInstance()->get(\Magento\Catalog\Model\Layer\Category\FilterableAttributeList::class);
$attributes = $filterableAttributes->getList();

Пожалуйста, используйте DI вместо ObjectManager::getInstance(). Я использовал его просто для более компактного примера :)

Получение фильтров, задействованных в многоуровневой навигации, немного сложнее.

$filterableAttributes = ObjectManager::getInstance()->get(\Magento\Catalog\Model\Layer\Category\FilterableAttributeList::class);

$appState = ObjectManager::getInstance()->get(\Magento\Framework\App\State::class);
$layerResolver = ObjectManager::getInstance()->get(\Magento\Catalog\Model\Layer\Resolver::class);
$filterList = ObjectManager::getInstance()->create(
\Magento\Catalog\Model\Layer\FilterList::class,
    [
        'filterableAttributes' => $filterableAttributes
    ]
);

$category = 1234;

$appState->setAreaCode('frontend');
$layer = $layerResolver->get();
$layer->setCurrentCategory($category);
$filters = $filterList->getFilters($layer);

Однако это не окончательный результат. Чтобы убедиться, что фильтры актуальны, необходимо проверить количество элементов для каждого фильтра. (эта проверка фактически выполняется во время основной многоуровневой навигации рендеринг)

$finalFilters = [];
foreach ($filters as $filter) {
    if ($filter->getItemsCount()) {
        $finalFilters[] = $filter;
    }
}

Затем вы можете получить имена и значения фильтров. то есть:

$name = $filter->getName();
foreach ($filter->getItems() as $item) {
    $value = $item->getValue();
}

Наконец, я хотел бы добавить альтернативное решение, которое немного жестоко, подумал :)

$categoryId = 1234;

$resource = ObjectManager::getInstance()->get(\Magento\Framework\App\ResourceConnection::class);
$connection = $resource->getConnection();

$select = $connection->select()->from(['ea' => $connection->getTableName('eav_attribute')], 'ea.attribute_id')
->join(['eea' => $connection->getTableName('eav_entity_attribute')], 'ea.attribute_id = eea.attribute_id')
->join(['cea' => $connection->getTableName('catalog_eav_attribute')], 'ea.attribute_id = cea.attribute_id')
->join(['cpe' => $connection->getTableName('catalog_product_entity')], 'eea.attribute_set_id = cpe.attribute_set_id')
->join(['ccp' => $connection->getTableName('catalog_category_product')], 'cpe.entity_id = ccp.product_id')
->where('cea.is_filterable = ?', 1)
->where('ccp.category_id = ?', $categoryId)
->group('ea.attribute_id');

$attributeIds = $connection->fetchCol($select);

Затем можно использовать идентификаторы атрибутов для загрузки коллекции.

 /** @var $collection \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection */
$collection = $this->collectionFactory->create();
$collection->setItemObjectClass('Magento\Catalog\Model\ResourceModel\Eav\Attribute')
        ->addStoreLabel($this->storeManager->getStore()->getId());
$collection->addFieldToFilter('attribute_id', ['in' => $attributeIds]);
person Sergii Ivashchenko    schedule 20.12.2016
comment
@Segey: возвращает только код атрибута. Мне нужны все доступные ярлыки со значением - person Vishal Kamal; 21.12.2016
comment
Для фильтров - используйте $filter->getName(), $filter->getItems()->getValue(). Если вы имеете в виду последнее решение - используйте идентификаторы для загрузки Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection . добавлю строчку в ответ - person Sergii Ivashchenko; 21.12.2016
comment
Хорошо, позвольте мне проверить - person Vishal Kamal; 21.12.2016
comment
Я получаю повторяющееся имя фильтра, используя: $filter->getName() - person Vishal Kamal; 21.12.2016
comment
Ну, это зависит от ваших данных. Во всяком случае, именно так Magento отображает многоуровневую навигацию: github.com/magento/magento2/blob/develop/app/code/Magento/ - person Sergii Ivashchenko; 21.12.2016
comment
Я думаю, это работает для меня. Не могли бы вы сделать еще одну помощь для меня: мне нужен код $filter и frontend_input.. - person Vishal Kamal; 21.12.2016
comment
ребята, вы можете разместить весь этот код на Github или где-нибудь еще? - person Abhishek Panchal; 08.05.2017
comment
@SergeyIvashchenko, не могли бы вы помочь мне заставить его работать и для страницы результатов поиска. Поскольку идентификатор категории не найден на странице результатов поиска. Очень ценю вашу помощь. - person Abhishek Panchal; 25.05.2017
comment
Вы сэкономили мне много времени. Большое тебе спасибо. - person Yonn Trimoreau; 15.12.2017
comment
Для тех, кому нужен фактический код атрибута, используйте $filter->getRequestVar() в приведенных выше примерах. - person Joel Davey; 21.09.2018
comment
Вы столкнетесь с проблемами, если будете использовать $layer->setCurrentCategory($category); глобально, как в моем случае. поэтому каждая страница категории, которую я загружаю, изменит запрос mysql для получения той, которую вы установили. Я пытаюсь найти альтернативу, у кого какие идеи? - person Juliano Vargas; 26.08.2020