12

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.

kilis
  • 489
  • 2
  • 6
  • 21

9 Answers9

21

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();
}
Raphael at Digital Pianism
  • 70,385
  • 34
  • 188
  • 352
6

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

Edit: The original answer did not show the full paths to the included classes, I had to find the relevant namespaces, so updated the example slightly with a full class and namespaces.

<?php

namespace Vendor\Module\Model\Categories;

use \Magento\Catalog\Api\CategoryListInterface; use \Magento\Framework\Api\SearchCriteriaInterface; use \Magento\Framework\Api\Search\FilterGroup; use \Magento\Framework\Api\FilterBuilder; use \Magento\Framework\Api\Search\SearchCriteriaBuilder;

class CategoriesFilterSearchService { protected $categoryList; /** * @var SearchCriteriaBuilder */ protected $searchCriteriaBuilder;

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

public function __construct(
    CategoryListInterface $categoryList,
    SearchCriteriaBuilder $searchCriteriaBuilder,
    FilterBuilder $filterBuilder,
) {
    $this-&gt;categoryList = $categoryList;
    $this-&gt;searchCriteriaBuilder = $searchCriteriaBuilder;
    $this-&gt;filterBuilder         = $filterBuilder;
}

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

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

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

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

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

}

CvRChameleon
  • 713
  • 6
  • 24
Yogesh Agarwal
  • 1,162
  • 11
  • 22
3

You can simple do it using name,

$title = 'womens';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$_categoryFactory = $objectManager->get('Magento\Catalog\Model\CategoryFactory');

$collection = $_categoryFactory->create()->getCollection()->addFieldToFilter('name',$title); echo "<pre>"; print_r($collection->getData()); exit;

Rakesh Jesadiya
  • 42,221
  • 18
  • 132
  • 183
3

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();
}
Haritha
  • 666
  • 5
  • 14
2

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

Jacques
  • 1,026
  • 10
  • 21
kilis
  • 489
  • 2
  • 6
  • 21
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; 
}
Kay Int Veen
  • 1,503
  • 2
  • 15
  • 26
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();
}
Arshad Syed
  • 553
  • 5
  • 14
0

You can use the method loadByAttribute

/** @var \Magento\Catalog\Model\CategoryFactory $this->_categoryFactory */
$category = $this->_categoryFactory->create()->loadByAttribute('name', $name);
MeChris99
  • 11
  • 2
-1

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!

Mac A.
  • 280
  • 1
  • 4
  • 19