Magento 2 Ottieni l'ID categoria usando il titolo della categoria


11

Vorrei ottenere un ID categoria usando solo il titolo della categoria usando questo tipo di funzione.

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

Caso d'uso: ottieni l'ID categoria per titolo e metti i dati ID nell'array nello script di migrazione.

Risposte:


18

Puoi farlo tramite le raccolte:

Per prima cosa devi iniettare un CategoryFactorynel costruttore della tua classe.

Magento 2.0 e 2.1:

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

Quindi, ovunque nella tua classe puoi fare:

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

Quindi, ovunque nella tua classe puoi fare:

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

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

Errore PHP Errore irreversibile: chiamata al metodo indefinito Magento \ Catalog \ Model \ CategoryFactory :: getCollection ()
kilis

1
@kilis guarda il mio aggiornamento, devi usare DI per iniettare quella classe;)
Raffaello al Pianismo Digitale

Per il mio caso d'uso ho bisogno di questo tipo di funzione $ collection = $ this -> _ objectManager-> create ('\ Magento \ Catalog \ Model \ CategoryFactory') -> getCollection () -> addAttributeToFilter ('title', $ categoryTitle) - > setPageSize (1);
Kilis

1
@kilis bene è una cattiva pratica usare direttamente il gestore degli oggetti, dovresti sempre usare l'iniezione delle dipendenze
Raffaello al Pianismo digitale

si lo so. Il nostro script di aggiornamento del progetto è progettato in questo modo: /
Kilis

4

Questo può essere fatto usando contratti di servizio che sono considerati le migliori pratiche.

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 Per la parte relativa alle migliori pratiche
Akif il

3

Puoi semplicemente farlo usando name,

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

Non per uso FE, è necessaria l'aggiornamento della funzionalità di script.
Kilis

hai appena detto titolo, ho aggiornato la mia risposta.
Rakesh Jesadiya,

2

Prova sotto il codice per il file 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

L'ho preso con l'aiuto del mio collage

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

:) Poiché la raccolta restituirà solo il record desiderato, puoi ottenere l'unico risultato con ->getFirstItem()il codice sopra


0

Per riflettere questo in uno script funzionante, suggerisco di usare quanto segue

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

Modifica: ho realizzato e testato uno script. Ho creato un 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; 
}

Ho provato il tuo codice, ma ho cambiato la prima riga in $ obj = $ this -> _ objectManager; Ottenuto un [Magento \ Framework \ Exception \ LocalizedException] Nome attributo non valido: errore titolo
kilis

Quando hai avuto quell'errore non hai usato il mio script.
Kay Int Veen,

Ho appena aggiunto uno script completamente testato. per favore controlla quello. funzionerà di sicuro!
Kay Int Veen,

0

Sono riuscito a scrivere il mio metodo (più efficiente):

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

Questo codice memorizza nella cache tutti i titoli: id in un array e interroga solo 2 volte.

Ha funzionato per me. Più facile da usare!


0

Innanzitutto, è necessario iniettare la classe factory di raccolta

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

Dopo quello all'interno del tuo metodo, puoi farlo,

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

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.