Magento 2 Obtener id de categoría usando el título de categoría

11

Me gustaría obtener la identificación de la categoría usando solo el título de la categoría usando este tipo de función.

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

Caso de uso: obtenga la identificación de la categoría por título y coloque los datos de identificación en la matriz en el script de migración.

kilis
fuente

Respuestas:

18

Puedes hacerlo a través de colecciones:

Primero debes inyectar un CategoryFactoryen el constructor de tu clase.

Magento 2.0 y 2.1:

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

Luego, en cualquier otro lugar de tu clase, puedes hacer:

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

Luego, en cualquier otro lugar de tu clase, puedes hacer:

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

if ($collection->getSize()) {
    $categoryId = $collection->getFirstItem()->getId();
}
Raphael en Digital Pianism
fuente
Tengo un error Error fatal de PHP: Llame al método indefinido Magento \ Catalog \ Model \ CategoryFactory :: getCollection ()
kilis
1
@kilis mira mi actualización, necesitas usar DI para inyectar esa clase;)
Raphael en Digital Pianism
Para mi caso de uso, necesito este tipo de función $ collection = $ this -> _ objectManager-> create ('\ Magento \ Catalog \ Model \ CategoryFactory') -> getCollection () -> addAttributeToFilter ('title', $ categoryTitle) - > setPageSize (1);
kilis
1
@kilis bueno, es una mala práctica usar el administrador de objetos directamente, siempre debes usar la inyección de dependencia
Raphael en Digital Pianism
si lo se. Nuestro script de actualización del proyecto está diseñado así: /
kilis
4

Esto se puede hacer mediante contratos de servicio que se consideran las mejores prácticas.

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
fuente
+1 Para la parte de mejores prácticas
Akif
3

Puedes hacerlo simplemente usando 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
fuente
No es para uso FE, se necesita funcionalidad de script de actualización.
kilis
solo tienes el título, he actualizado mi respuesta.
Rakesh Jesadiya
2

Pruebe a continuación el código para el archivo 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
fuente
1

Lo obtuve con la ayuda de mi collage.

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

:) Dado que la colección solo devolverá el registro que desea, puede obtener el único resultado con ->getFirstItem()el código anterior

kilis
fuente
0

Para refactorizar eso en un script funcional, sugiero usar lo siguiente

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

Editar: hice y probé un guión. Creé un archivo en /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
fuente
Intentó su código, pero cambió la primera línea a $ obj = $ this -> _ objectManager; Tengo un [Magento \ Framework \ Exception \ LocalizedException] Nombre de atributo no válido: error de título
kilis
Cuando recibiste ese error, no usaste mi script.
Kay Int Veen
Acabo de agregar un script completamente probado. por favor revisa eso. ¡funcionará seguro!
Kay Int Veen
0

Logré escribir mi propio método (más 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;
}

Este código almacena en caché todos los títulos: identificadores en una matriz, y solo consulta 2 veces.

Trabajó para mi. ¡Más fácil de usar!

Mac A.
fuente
0

Primero, debe inyectar la clase de fábrica de colección

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

Después de eso dentro de su método, puede hacer esto,

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

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