Magento 2 Obtenir l'identifiant de catégorie en utilisant le titre de catégorie

11

Je voudrais obtenir l'identifiant de catégorie en utilisant uniquement le titre de catégorie en utilisant ce type de fonction.

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

Cas d'utilisation: obtenez l'ID de catégorie par titre et placez les données d'ID dans le tableau dans le script de migration

kilis
la source

Réponses:

18

Vous pouvez le faire via des collections:

Vous devez d'abord injecter un CategoryFactorydans votre constructeur de classe.

Magento 2.0 et 2.1:

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

Ensuite, n'importe où ailleurs dans votre classe, vous pouvez faire:

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

Ensuite, n'importe où ailleurs dans votre classe, vous pouvez faire:

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

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}
Raphael chez Digital Pianism
la source
Got a error PHP Fatal error: Appel à une méthode non définie Magento \ Catalog \ Model \ CategoryFactory :: getCollection ()
kilis
1
@kilis voir ma mise à jour, vous devez utiliser DI pour injecter cette classe;)
Raphael au Digital Pianism
Pour mon cas d'utilisation, j'ai besoin de ce type de fonction $ collection = $ this -> _ objectManager-> create ('\ Magento \ Catalog \ Model \ CategoryFactory') -> getCollection () -> addAttributeToFilter ('title', $ categoryTitle) - > setPageSize (1);
kilis
1
@kilis bien c'est une mauvaise pratique d'utiliser le gestionnaire d'objets directement, vous devez toujours utiliser l'injection de dépendances
Raphael au Digital Pianism
Ouais je sais. Notre script de mise à niveau de projet est conçu comme ça: /
kilis
4

Cela peut être fait en utilisant des contrats de service qui sont considérés comme les meilleures pratiques.

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
la source
+1 Pour la partie des meilleures pratiques
Akif
3

Vous pouvez simplement le faire en utilisant 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
la source
Pas pour l'utilisation FE, mise à niveau de la fonctionnalité de script nécessaire.
kilis
vous venez de dire le titre, j'ai mis à jour ma réponse.
Rakesh Jesadiya
2

Essayez ci-dessous le code pour le fichier 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
la source
1

Je l'ai obtenu avec l'aide de mon collage

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

:) Étant donné que la collection ne renverra que l'enregistrement que vous souhaitez, vous pouvez récupérer le seul résultat avec ->getFirstItem()le code ci-dessus

kilis
la source
0

Pour refactoriser cela dans un script fonctionnel, je suggère d'utiliser ce qui suit

$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: j'ai fait et testé un script. J'ai créé un fichier dans /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
la source
J'ai essayé votre code, mais changé la première ligne en $ obj = $ this -> _ objectManager; Vous avez un [Magento \ Framework \ Exception \ LocalizedException] Nom d'attribut non valide: erreur de titre
kilis
Lorsque vous avez obtenu cette erreur, vous n'avez pas utilisé mon script.
Kay Int Veen
Je viens d'ajouter un script entièrement testé. veuillez vérifier cela. cela fonctionnera à coup sûr!
Kay Int Veen
0

J'ai réussi à écrire ma propre méthode (plus efficace):

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

Ce code met en cache tous les titres: id dans un tableau et interroge seulement 2 fois.

A travaillé pour moi. Plus simple d'utilisation!

Mac A.
la source
0

Tout d'abord, vous devez injecter la classe d'usine de collecte

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

Après cela, dans votre méthode, vous pouvez le faire,

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

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}
Arshad Syed
la source