Comment obtenir l'image du produit et l'URL dans Magento 2?

16

Voici mon observateur:

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $orderIds = $observer->getEvent()->getOrderIds();
    $order = $this->_orderRepositoryInterface->get($orderIds[0]);
    $items =$order->getAllVisibleItems();
    $productQuantity = array();
    $productPrice = array();
    $productName = array();
    $productIds = array();
    foreach($items as $item) {
        $productIds[]= $item->getProductId();
        $productName[]= $item->getSku(); 
        $productPrice[] = $item->getPrice();
        $productQuantity[]= floor($item->getQtyOrdered());
    }
}

Comment puis-je obtenir l'image du produit et l'URL du produit à partir de l'article?

Ramkishan Suthar
la source
Quel événement avez-vous attrapé?
Khoa TruongDinh
checkout_onepage_controller_success_action
Ramkishan Suthar

Réponses:

23

Cette méthode n'est peut-être pas la meilleure façon d'obtenir une image de produit.

Injectez \Magento\Catalog\Api\ProductRepositoryInterfaceFactorydans notre constructeur.

protected $_productRepositoryFactory;

public function __construct(
        \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory
) {

    $this->_productRepositoryFactory = $productRepositoryFactory;
}

Nous pouvons obtenir l'image:

$product = $this->_productRepositoryFactory->create()->getById($item->getProductId());
$product->getData('image');
$product->getData('thumbnail');
$product->getData('small_image');
Khoa TruongDinh
la source
votre réponse est juste, mais que dois-je faire si j'ai plus d'un produit dans le panier, comment puis-je afficher plus d'une image de produit
Ramkishan Suthar
ok je l'ai eu @khoa. si j'ai plus d'une image de production. merci beaucoup
Ramkishan Suthar
Ça ne marche pas. La valeur renvoyée est une sorte de chaîne comme celle-ci "/w/s/wsh10-orange_main.jpg"
Hoang Trinh
2
@piavgh c'est le chemin de l'image:pub/media/catalog/product
Khoa TruongDinh
1
alors comment utiliser /w/s/wsh10-orange_main.jpg dans l'attribut <img src = "" /> pour pouvoir charger l'image réelle
Lachezar Raychev
18

Si vous voulez que l'URL frontend publiée / cache d'une image pour une vue de magasin spécifique (comme je l'ai fait), cela fonctionne pour moi:

/**
 * @var \Magento\Store\Model\App\Emulation
 */
protected $appEmulation;

/**
 * @var \Magento\Store\Model\StoreManagerInterface
 */
protected $storeManager;

/**
 * @var \Magento\Catalog\Api\ProductRepositoryInterfaceFactory
 */
protected $productRepositoryFactory;

/**
 * @var \Magento\Catalog\Helper\ImageFactory
 */
protected $imageHelperFactory;

/**
 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 * @param \Magento\Store\Model\App\Emulation $appEmulation
 * @param \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory
 * @param \Magento\Catalog\Helper\ImageFactory $helperFactory
 */
public function __construct(
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Store\Model\App\Emulation $appEmulation,
    \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory,
    \Magento\Catalog\Helper\ImageFactory $imageHelperFactory
)
{
    $this->storeManager = $storeManager;
    $this->appEmulation = $appEmulation;
    $this->productRepositoryFactory = $productRepositoryFactory;
    $this->imageHelperFactory = $imageHelperFactory;
}

Ensuite, partout où vous avez besoin d'obtenir l'URL du frontend de l'image:

$sku = "my-sku";
// get the store ID from somewhere (maybe a specific store?)
$storeId = $this->storeManager->getStore()->getId();
// emulate the frontend environment
$this->appEmulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND, true);
// load the product however you want
$product = $this->productRepositoryFactory->create()->get($sku);
// now the image helper will get the correct URL with the frontend environment emulated
$imageUrl = $this->imageHelperFactory->create()
  ->init($product, 'product_thumbnail_image')->getUrl();
// end emulation
$this->appEmulation->stopEnvironmentEmulation();

Vous pouvez également sélectionner d'autres types d'images product_thumbnail_image: consultez magento/theme-frontend-luma/etc/view.xmlla liste des images de produits disponibles ou créez la vôtre dans un view.xmlfichier.

thaddeusmt
la source
1
WTF? c'est juste malade: D
Lachezar Raychev
Je viens d'essayer cette solution et je n'obtiens aucune erreur, bien que l'URL renvoyée n'existe pas et que la chaîne soit vide. J'ai essayé avec 'product_base_image', 'product_small_image' et 'product_thumbnail_image', dont aucun ne fonctionne. Pouvez-vous conseiller s'il vous plaît? Ou existe-t-il un moyen efficace de le faire en utilisant le référentiel de produits? Comme je le charge déjà ailleurs dans mon bloc.
Joshua Flood
11

Si vous devez renvoyer une URL de produit, elle devrait ressembler à ceci:

//todo get product object $product 

$objectManager =\Magento\Framework\App\ObjectManager::getInstance();
$helperImport = $objectManager->get('\Magento\Catalog\Helper\Image');

$imageUrl = $helperImport->init($product, 'product_page_image_small')
                ->setImageFile($product->getSmallImage()) // image,small_image,thumbnail
                ->resize(380)
                ->getUrl();
echo $imageUrl;
Shaoqing Ma
la source
6

C'est comme ça que je l'ai fait. c'est assez efficace et propre:

1) Tout d'abord, vous devez injecter les classes suivantes:

protected $_storeManager;
protected $_appEmulation;
protected $_blockFactory;

public function __construct(
    ...
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Framework\View\Element\BlockFactory $blockFactory,
    \Magento\Store\Model\App\Emulation $appEmulation)
{
    $this->_storeManager = $storeManager;
    $this->_blockFactory = $blockFactory;
    $this->_appEmulation = $appEmulation;
}

2) Ensuite, créez une méthode getImageUrl avec le code ci-dessous:

protected function getImageUrl($product, string $imageType = '')
{
    $storeId = $this->_storeManager->getStore()->getId();

    $this->_appEmulation->startEnvironmentEmulation($storeId, \Magento\Framework\App\Area::AREA_FRONTEND, true);

    $imageBlock =  $this->_blockFactory->createBlock('Magento\Catalog\Block\Product\ListProduct');
    $productImage = $imageBlock->getImage($product, $imageType);
    $imageUrl = $productImage->getImageUrl();

    $this->_appEmulation->stopEnvironmentEmulation();

    return $imageUrl;
}

Remarque: Le code "appEmulation" n'est nécessaire que lorsque vous effectuez cet appel depuis l' administrateur ou pour une API . Sinon, vous obtiendrez l'erreur ci-dessous (ou similaire):

Unable to resolve the source file for 'webapi_rest/_view/en_AU/Magento_Catalog/images/product/placeholder/.jpg'

3) Appelez getImageUrl en passant l'objet produit et le type d'image que vous souhaitez (en fonction de votre fichier view.xml )

...
$smallImage = $this->getImageUrl($productObject, 'product_page_image_small');
...
médina
la source
1

Pour obtenir l'URL de l'image personnalisée, j'ai utilisé ce code. Donc, si l'image ne se ferme pas, elle chargera l'image du thème par défaut.

$product = $block->getProduct();

$productImageAttr = $product->getCustomAttribute('product_banner_image');

if ($productImageAttr && $productImageAttr->getValue() != 'no_selection') {

    $productImage = $this->helper('Magento\Catalog\Helper\Image')
    ->init($product, 'product_banner_image')
    ->setImageFile($productImageAttr->getValue());

    $imageUrl = $productImage->getUrl();

} else {

    $imageUrl = $this->getViewFileUrl('images/cat-img1.jpg'); // Theme/web/images

}
Amit Singh
la source