11

I would like get category id by only using category title by using this kind of function.

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

Use case: Get category id by title and put id data to array in migration script.

17

You can do it via collections:

First you need to inject a CategoryFactory in your class constructor.

Magento 2.0 & 2.1:

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

Then anywhere else in your class you can do:

$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(...);
}

Then anywhere else in your class you can do:

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

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}
  • Got an error PHP Fatal error: Call to undefined method Magento\Catalog\Model\CategoryFactory::getCollection() – kilis May 12 '16 at 13:31
  • 1
    @kilis see my update, you need to use DI to inject that class ;) – Raphael at Digital Pianism May 12 '16 at 13:34
  • For my use case i need this kind of function $collection = $this->_objectManager->create('\Magento\Catalog\Model\CategoryFactory') ->getCollection()->addAttributeToFilter('title',$categoryTitle)->setPageSize(1); – kilis May 12 '16 at 13:41
  • 1
    @kilis well it's bad practice to use the object manager directly, you should always use dependency injection – Raphael at Digital Pianism May 12 '16 at 13:42
  • yeah i know. Our project upgrade script is designed like that :/ – kilis May 12 '16 at 13:43
4

This can be done using service contracts which are considered as best practice.

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 For best practice part – Akif Dec 22 '18 at 22:28
3

You can simple do it using name,

$title = 'womens';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$collection = $_categoryFactory->create()->getCollection()->addFieldToFilter('name',$title);
echo "<pre>";
print_r($collection->getData());
exit;
  • Not for FE use, upgrade script functionality needed. – kilis May 12 '16 at 13:53
  • you just have says title, i have updated my answer. – Rakesh Jesadiya May 18 '16 at 9:16
2

Try Below Code For Phtml File:

$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

I got it with help from my collage

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

:) Since the collection will only return the record you want you can grab the only result with ->getFirstItem() on the above code

0

To refactor that in a functioning script i suggest using the following

$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: I made and tested a script. I created a file in /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; 
}
  • Tried your code , but changed first line to $obj = $this->_objectManager; Got an [Magento\Framework\Exception\LocalizedException] Invalid attribute name: title error – kilis May 12 '16 at 13:36
  • When you got that error you did not use my script. – Kay Int Veen May 12 '16 at 14:04
  • I just added a fully tested script. please check that. it will work for sure! – Kay Int Veen May 12 '16 at 14:09
0

I managed to write my own (more efficient) method:

$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;
}

This code caches all title:ids into an array, and only query 2 times.

Worked for me. Easier to use!

0

First, you need to inject collection factory class

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

After that inside your method, you can do this,

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.