Cómo cargar productos por SKU en magento 2

29

Es bastante básico, pero no puedo encontrar un ejemplo de trabajo en Stackexchange o google. Quiero cargar un producto de un ayudante o bloque. Ya probé algunas cosas como:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); 

$product = $objectManager->create('\Magento\Catalog\Api\Data\ProductInterface');

$product->get('<SKU>');

$product->getName();

Esto no devuelve nada. También intenté cargar todos los modelos y API disponibles, pero nada parece funcionar con los SKU.

Dennis van Schaik
fuente

Respuestas:

56

La forma correcta, de acuerdo con los contratos de servicio de Magento 2, es mediante repositorios:

$product = $this->productRepositoryInterface->get($sku);

Use Magento\Catalog\Api\ProductRepositoryInterfacepara obtenerlo en su constructor.

Ejemplo completo:

...
private $productRepository; 
...
public function __construct(
    ...
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
    ...
) {
    ...
    $this->productRepository = $productRepository;
    ...
}

public function loadMyProduct($sku)
{
    return $this->productRepository->get($sku);
}
...

Nota:

Si el producto no existe, este método desencadena un NoSuchEntityExceptionerror como sería en la mejor práctica de Magento2.

Entonces, si necesita manejar de alguna manera, envuélvala en un bloque try / catch.

Phoenix128_RiccardoT
fuente
99
Este método da un error cuando no se encuentra ningún producto. Entonces, para verificar si existe un producto, parece que la solución de @ fschmengler podría ser la mejor manera de hacerlo.
Dennis van Schaik
1
¿puedes añadir más detalles sobre Use Magento\Catalog\Api\ProductRepositoryInterface to get it in your constructor.? ¿Qué debo hacer? Muchas gracias
davideghz
Vea mi publicación actualizada
Phoenix128_RiccardoT
La forma real de Magento 2 de usar los contratos de servicio es más complicada. Repository-> get () sigue siendo una llamada modelo que no debe usarse. La forma correcta es usar el repositorio-> getList () con SearchCriteriaBuilder. Vea mi respuesta en Pedidos (casi el mismo método): magento.stackexchange.com/questions/140374/…
Jacques
1
@JaccoAmersfoort, confirmo que "obtener" es la forma correcta. En su ejemplo, se ha sugerido porque "get" en el repositorio de pedidos requiere "id de pedido" y ese usuario estaba buscando "id de incremento". En ese caso, getList es la mejor opción, pero si puede usar "get", debe usarlo.
Phoenix128_RiccardoT
27

En lugar de usar el administrador de objetos directamente, inyecte ProductFactory:

public function __construct(\Magento\Catalog\Model\ProductFactory $productFactory)
{
    $this->productFactory = $productFactory;
}

Entonces úsalo así:

$product = $this->productFactory->create();
$product->loadByAttribute('sku', $sku);

o para hacer una carga completa (lo anterior lo carga usando una colección):

$product = $this->productFactory->create();
$product->load($product->getIdBySku($sku));
Fabian Schmengler
fuente
77
En realidad, mientras esto sigue funcionando, el uso load()y las colecciones es la forma "Magento 1", mejor use el repositorio como lo sugiere @RiccardoT.
Fabian Schmengler
1
Además, su método devolverá un modelo de Producto , mientras que el uso del Repositorio le dará un modelo de datos de Producto ( Api/Data/Product), que es un modelo de Producto convertido en un DTO tonto. Algo a considerar, ya que son bastante diferentes.
nevvermind
@FabianSchmengler: Intenté usar $product = $this->productFactory->create(); $product->load($product->getIdBySku($sku)); $product->getThumbnailUrl()para mostrar la imagen en miniatura del producto, pero no funciona.
Slimshadddyyy
@FabianSchmengler sí, la recomendación del repositorio es buena como respuesta de @RiccardoT. pero lo que si que entré mal SKU entonces se romperá toda la operación y excepción tiro, por lo que en este caso hay que tener que dependerproductFactory
Himanshu
@Himanshu captura la excepción. Y si necesita una nueva instancia de producto en ese caso, aún puede crearla usando la fábrica
Fabian Schmengler
7

Me gusta la respuesta de @ phoenix128-riccardot, pero agregaría una excepción, en caso de que el producto no exista:

tratar {
    $ product = $ this-> productRepositoryInterface-> get ($ sku);
} catch (\ Magento \ Framework \ Exception \ NoSuchEntityException $ e) {
    // inserta aquí tu manejo de errores
}

No pude agregarlo como comentario (reputación muy baja), lo siento.

dónde
fuente
4

Puedes probar eso

$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); 

$productRepository = $objectManager->get('\Magento\Catalog\Model\ProductRepository');
$productObj = $productRepository->get('<SKU>');

echo $productObj->getId();
Nadeem0035
fuente
3

Prueba esto:

/** @var \Magento\Catalog\Model\ProductFactory $productFactory */
$product = $productFactory->create();
$product->loadByAttribute('sku', 'my sku');

// $product->load($product->getId()); // may need to do this too,
// see \Magento\Framework\Api\AttributeValueFactory\AbstractModel::loadByAttribute
oscuro
fuente
Necesito obtener el product_id de sku (columna de csv) durante la importación de csv y guardar solo el product_id..¿Cómo lograrlo?
Sushivam
0

Uso de la inyección de dependencia (DI)

Aquí está el código de ejemplo para obtener la información del producto por Id. De producto y SKU en Magento 2 mediante inyección de dependencia.

En esto, podríamos necesitar inyectar el objeto de la clase \ Magento \ Catalog \ Model \ ProductRepository en el constructor de la clase de bloque de nuestro módulo y acceder a él desde el archivo de vista (.phtml).

Ruta de archivo de muestra: app / code / YourCompanyName / YourModuleName / Block / YourCustomBlock.php

<?php
namespace YourCompanyName\YourModuleName\Block;

class YourCustomBlock extends \Magento\Framework\View\Element\Template
{ 
    protected $_productRepository;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context, 
        \Magento\Catalog\Model\ProductRepository $productRepository,
        array $data = []
    ) {
        $this->_productRepository = $productRepository;
        parent::__construct($context, $data);
    }

    public function getProductById($id) {
        return $this->_productRepository->getById($id);
    }

    public function getProductBySku($sku) {
        return $this->_productRepository->get($sku);
    }
}

Ahora, podemos usar las funciones en nuestro archivo de vista (.phtml) de la siguiente manera.

// get product by id
$product = $block->getProductById(15);

// get product by sku
$product = $block->getProductBySku('MT12');

echo $product->getEntityId() . '<br>';
echo $product->getName() . '<br>';
echo $product->getSKU() . '<br>';
echo $product->getPrice() . '<br>';
echo $product->getSpecialPrice() . '<br>';
echo $product->getTypeId() . '<br>';
echo $product->getProductUrl() . '<br>';

Usando Object Manager

Aquí está el código de ejemplo para obtener la información del producto por ID de producto y SKU en Magento 2 usando el administrador de objetos.

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();

$productRepository = $objectManager->get('\Magento\Catalog\Model\ProductRepository');

// get product by product id 
$product = $productRepository->getById(15);

// get product by product sku 
$product = $productRepository->get('MT12');

echo $product->getEntityId() . '<br>';
echo $product->getName() . '<br>';
echo $product->getSKU() . '<br>';
echo $product->getPrice() . '<br>';
echo $product->getSpecialPrice() . '<br>';
echo $product->getTypeId() . '<br>';
echo $product->getProductUrl() . '<br>';
Amir Hosseinzadeh
fuente
-3
<?php
use Magento\Framework\App\Bootstrap;
require __DIR__ . '/app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$obj = $bootstrap->getObjectManager();
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');


$sku ='24-MB01';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productObject = $objectManager->get('Magento\Catalog\Model\Product');
$product = $productObject->loadByAttribute('sku', $sku);
echo $product->getName();

?>
Nagaraju K
fuente