Magento 2 Obtenha o ID da categoria usando o título da categoria


11

Eu gostaria de obter o ID da categoria usando apenas o título da categoria usando esse tipo de função.

->load($categoryTitle, 'title')
->getId();

Caso de uso: obtenha o ID da categoria por título e coloque os dados do ID na matriz no script de migração.

Respostas:


18

Você pode fazer isso através de coleções:

Primeiro você precisa injetar um CategoryFactoryno seu construtor de classe.

Magento 2.0 e 2.1:

public function __construct(
    ...
    \Magento\Catalog\Model\CategoryFactory $categoryFactory
) {
    $this->_categoryFactory = $categoryFactory;
    parent::__construct(...);
}

Em qualquer outro lugar da sua classe, você pode:

$collection = $this->_categoryFactory->create()->getCollection()->addAttributeToFilter('name',$categoryTitle)->setPageSize(1);

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}

Magento 2.2:

public function __construct(
    ...
    \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collecionFactory
) {
    $this->_collectionFactory = $collecionFactory;
    parent::__construct(...);
}

Em qualquer outro lugar da sua classe, você pode:

$collection = $this->collecionFactory
                ->create()
                ->addAttributeToFilter('name',$categoryTitle)
                ->setPageSize(1);

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}

Ocorreu um erro Erro fatal do PHP: Chame para o método indefinido Magento \ Catalog \ Model \ CategoryFactory :: getCollection ()
kilis

1
@kilis ver a minha atualização, você precisa usar DI para injetar essa classe;)
Raphael em Digital pianismo

Para o meu caso de uso, eu preciso desse tipo de função $ collection = $ this -> _ objectManager-> create ('\ Magento \ Catalog \ Model \ CategoryFactory') -> getCollection () -> addAttributeToFilter ('title', $ categoryTitle) - > setPageSize (1);
kilis

1
@kilis bem, é má prática para usar o gerenciador de objeto diretamente, você deve sempre usar injeção de dependência
Raphael em Digital pianismo

sim, eu sei. Nosso script de atualização do projeto foi desenvolvido assim: /
kilis 12/16

4

Isso pode ser feito usando contratos de serviço considerados melhores práticas.

protected $categoryList;

    /**
     * @var SearchCriteriaBuilder
     */
    protected $searchCriteriaBuilder;

    /**
     * @var FilterBuilder
     */
    protected $filterBuilder;

public function __construct(
        ------------
        CategoryListInterface $categoryList,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        FilterBuilder $filterBuilder,
        -----------------
    )
    {
        $this->categoryList = $categoryList;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
        $this->filterBuilder         = $filterBuilder;
        parent::__construct(----------);
    }

public function getNameCategory()
    {
        $enableFilter[] = $this->filterBuilder
            ->setField(\Magento\Catalog\Model\Category::KEY_NAME)
            ->setConditionType('like')
            ->setValue(self::CATEGORY_NAME_HELP) // name of the categroy on const
            ->create();


        $searchCriteria = $this->searchCriteriaBuilder
            ->addFilters($enableFilter)
            ->create();

        $items = $this->categoryList->getList($searchCriteria)->getItems();

        if(count($items) == 0)
        {
            return FALSE;
        }

        foreach ($items as $helpCategory)
        {
            $CategoryId = $helpCategory->getId()
        }
return $CategoryId;
    }

+1 Para a parte das melhores práticas
Akif

3

Você pode fazer isso usando simples name,

$title = 'womens';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$collection = $_categoryFactory->create()->getCollection()->addFieldToFilter('name',$title);
echo "<pre>";
print_r($collection->getData());
exit;

Não é para uso do FE, é necessário atualizar a funcionalidade do script.
kilis

você acabou de dizer o título, eu atualizei minha resposta.
Rakesh Jesadiya

2

Tente abaixo o código para o arquivo phtml:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

$_categoryFactory = $objectManager->get('Magento\Catalog\Model\CategoryFactory');

$categoryTitle = 'Outdoor'; // Category Name

$collection = $_categoryFactory->create()->getCollection()->addFieldToFilter('name', ['in' => $categoryTitle]);

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}

1

Consegui com a ajuda da minha colagem

$this->_objectManager->get('Magento\Catalog\Model\CategoryFactory')->create()->getCollection()
        ->addFieldToSelect('name')
        ->addFieldToFilter('name', ['in' => $categoryTitle]);

:) Como a coleção retornará apenas o registro desejado, você poderá obter o único resultado ->getFirstItem()no código acima


0

Para refatorar isso em um script em funcionamento, sugiro usar o seguinte

$obj = $bootstrap->getObjectManager();
$_categoryFactory = $obj->get('Magento\Catalog\Model\CategoryFactory');
$collection = $_categoryFactory->create()->getCollection()->addAttributeToFilter('title',$categoryTitle)->setPageSize(1);

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getCategoryId();
}

Edit: Eu criei e testei um script. Criei um arquivo em /scripts/file.php

<?php
use Magento\Framework\App\Bootstrap;
require __DIR__ . '/../app/bootstrap.php';

$bootstrap = Bootstrap::create(BP, $_SERVER);

$obj = $bootstrap->getObjectManager();

// Set the state (not sure if this is neccessary)
$obj = $bootstrap->getObjectManager();
$_categoryFactory = $obj->get('Magento\Catalog\Model\CategoryFactory');
$categoryTitle = 'Test';
$collection = $_categoryFactory->create()->getCollection()->addAttributeToFilter('name',$categoryTitle)->setPageSize(1);
if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
    echo $categoryId; 
}

Tentei seu código, mas alterou a primeira linha para $ obj = $ this -> _ objectManager; Obteve um nome de atributo [Magento \ Framework \ Exception \ LocalizedException] inválido: error do título
kilis 12/16/16

Quando você recebeu esse erro, você não usou meu script.
Kay Int Veen

Acabei de adicionar um script totalmente testado. por favor verifique isso. funcionará com certeza!
21816 Kay Int Veen

0

Consegui escrever meu próprio método (mais eficiente):

$entityTypeId = \Magento\Catalog\Setup\CategorySetup::CATEGORY_ENTITY_TYPE_ID;
$row = $this->queryF("SELECT * FROM `eav_attribute` WHERE `entity_type_id` = $entityTypeId AND `attribute_code` = 'name'", 1);
$nameAttributeId = $row['attribute_id'];
$categoryNames = $this->queryF("SELECT * FROM `catalog_category_entity_varchar` WHERE `attribute_id` = '$nameAttributeId'");
$this->categoryNameIdMap = [];
foreach ($categoryNames as $item) {
    $id = $item['entity_id'];
    $title = $item['value'];
    $this->categoryNameIdMap[$title] = $id;
}

Esse código armazena em cache todos os títulos: ids em uma matriz e consulta apenas duas vezes.

Trabalhou para mim. Mais fácil de usar!


0

Primeiro, você precisa injetar a classe de fábrica de coleta

public function __construct(
    ...
    \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collecionFactory ) {
    $this->_collectionFactory = $collecionFactory;
    parent::__construct(...); }

Depois disso dentro do seu método, você pode fazer isso,

$categoryTitle = 'Men';
$collection = $this->_categoryCollectionFactory->create()->addAttributeToFilter('name',$categoryTitle)->setPageSize(1);

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.