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.

kilis
fonte

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();
}
Raphael na Digital Pianism
fonte
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;
    }
Yogesh Agarwal
fonte
+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;
Rakesh Jesadiya
fonte
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();
}
Govind Ram Bhatt
fonte
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

kilis
fonte
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; 
}
Kay Int Veen
fonte
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!

Mac A.
fonte
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();
}
Arshad Syed
fonte