Comment charger un produit par SKU dans Magento 2

29

C'est assez basique, mais je ne trouve pas d'exemple de travail sur Stackexchange ou google. Je veux charger un produit depuis un assistant ou un bloc. J'ai déjà essayé des choses comme:

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

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

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

$product->getName();

Cela ne renvoie rien. J'ai également essayé de charger les modèles et les API disponibles, mais rien ne semble fonctionner avec les SKU.

Dennis van Schaik
la source

Réponses:

56

La bonne façon, selon les contrats de service Magento 2, utilise les référentiels:

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

Utilisez Magento\Catalog\Api\ProductRepositoryInterfacepour l'obtenir dans votre constructeur.

Exemple complet:

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

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

Remarque:

Si le produit n'existe pas, cette méthode déclenche une NoSuchEntityExceptionerreur comme elle le serait dans la meilleure pratique Magento2.

Donc, si vous devez gérer d'une manière ou d'une autre, enveloppez-le dans un bloc try / catch.

Phoenix128_RiccardoT
la source
9
Cette méthode donne une erreur quand aucun produit n'est trouvé. Donc, pour vérifier si un produit existe, il semble que la solution de @ fschmengler soit la meilleure solution.
Dennis van Schaik
1
pouvez-vous ajouter plus de détails Use Magento\Catalog\Api\ProductRepositoryInterface to get it in your constructor.? Que dois-je faire? Merci beaucoup
davideghz
Voir mon article mis à jour
Phoenix128_RiccardoT
La véritable méthode Magento 2 pour utiliser les contrats de service est plus compliquée. Repository-> get () est toujours un appel de modèle qui ne devrait pas être utilisé. La bonne façon est d'utiliser repository-> getList () avec SearchCriteriaBuilder. Voir ma réponse sur les commandes (à peu près la même méthode): magento.stackexchange.com/questions/140374/…
Jacques
1
@JaccoAmersfoort, je confirme que "get" est la bonne façon. Dans votre exemple, cela a été suggéré parce que "get" dans le référentiel d'ordre nécessite "id de commande" et que l'utilisateur recherchait "id d'incrémentation". Dans ce cas, une getList est la meilleure option, mais si vous pouvez utiliser "get", vous devez l'utiliser.
Phoenix128_RiccardoT
27

Au lieu d'utiliser directement le gestionnaire d'objets, injectez ProductFactory:

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

Ensuite, utilisez-le comme ceci:

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

ou pour effectuer un chargement complet (ce qui précède le charge à l'aide d'une collection):

$product = $this->productFactory->create();
$product->load($product->getIdBySku($sku));
Fabian Schmengler
la source
7
En fait, alors que cela fonctionne toujours, l'utilisation load()et les collections sont la méthode "Magento 1", mieux utiliser le référentiel comme suggéré par @RiccardoT.
Fabian Schmengler
1
De plus, votre méthode retournera un modèle de produit , tandis que l'utilisation du référentiel vous donnera un modèle de données de produit ( Api/Data/Product), qui est un modèle de produit converti en un DTO simplifié. Quelque chose à considérer, car ils sont très différents.
nevvermind
@FabianSchmengler: J'ai essayé d'utiliser $product = $this->productFactory->create(); $product->load($product->getIdBySku($sku)); $product->getThumbnailUrl()pour afficher l'image miniature du produit, mais cela ne fonctionne pas.
Slimshadddyyy
@FabianSchmengler oui la recommandation du référentiel est bonne comme réponse @RiccardoT. mais que se passe-t-il si j'entre une mauvaise référence, alors cela cassera toute l'opération et lancera l'exception, donc dans ce cas, nous devons dépendre deproductFactory
Himanshu
@Himanshu attrape l'exception. Et si vous avez besoin d'une nouvelle instance de produit dans ce cas, vous pouvez toujours la créer en utilisant l'usine
Fabian Schmengler
7

J'aime la réponse de @ phoenix128-riccardot, mais ajouterais une exception, juste au cas où le produit n'existe pas:

essayez {
    $ product = $ this-> productRepositoryInterface-> get ($ sku);
} catch (\ Magento \ Framework \ Exception \ NoSuchEntityException $ e) {
    // insérez votre gestion des erreurs ici
}

Je n'ai pas pu l'ajouter en tant que commentaire (réputation trop faible), désolé.


la source
4

Vous pouvez essayer ça

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

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

echo $productObj->getId();
Nadeem0035
la source
3

Essaye ça:

/** @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
obscur
la source
J'ai besoin d'obtenir le product_id de sku (colonne de csv) lors de l'importation csv et de ne sauvegarder que le product_id..Comment réaliser?
Sushivam
0

Utilisation de l'injection de dépendance (DI)

Voici l'exemple de code pour obtenir les informations produit par ID de produit et SKU dans Magento 2 à l'aide de l'injection de dépendance.

Dans ce cas, nous pourrions avoir besoin d'injecter l'objet de la classe \ Magento \ Catalog \ Model \ ProductRepository dans le constructeur de la classe de bloc de notre module et d'y accéder à partir du fichier de vue (.phtml).

Exemple de chemin de fichier: 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);
    }
}

Maintenant, nous pouvons utiliser les fonctions de notre fichier de vue (.phtml) comme suit.

// 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>';

Utilisation du gestionnaire d'objets

Voici l'exemple de code pour obtenir les informations produit par ID produit et SKU dans Magento 2 à l'aide du gestionnaire d'objets.

$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
la source
-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
la source