15

This is my observer:

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

How can I get the product image and product URL from the item?

22

This way may not the best way to get a product image.

Inject \Magento\Catalog\Api\ProductRepositoryInterfaceFactory in our constructor.

protected $_productRepositoryFactory;

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

    $this->_productRepositoryFactory = $productRepositoryFactory;
}

We can get the image:

$product = $this->_productRepositoryFactory->create()->getById($item->getProductId());
$product->getData('image');
$product->getData('thumbnail');
$product->getData('small_image');
  • your answer is right but what shoild i do if i have more than one product in cart how can i show more than one product image – Ramkishan Suthar Sep 20 '16 at 4:17
  • ok i got it @khoa. if i have more than one produc image. thanks alot – Ramkishan Suthar Sep 20 '16 at 4:22
  • This is not working. Value returned is some kind of string like this "/w/s/wsh10-orange_main.jpg" – Hoang Trinh Oct 17 '16 at 1:37
  • 2
    @piavgh it's the path to image: pub/media/catalog/product – Khoa TruongDinh Oct 17 '16 at 2:17
  • 1
    so how do i use /w/s/wsh10-orange_main.jpg in <img src="" /> attribute so i can load the actual image – Lachezar Raychev Nov 8 '17 at 11:06
15

If you want the published/cache frontend URL of an image for a specific store view (like I did) this is working for me:

/**
 * @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;
}

Then, wherever you need to get the image frontend URL:

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

You can select other images types besides product_thumbnail_image: see magento/theme-frontend-luma/etc/view.xml for a list of available product images, or create your own in a view.xml file.

  • 1
    WTF? that is just sick :D – Lachezar Raychev Nov 2 '17 at 9:13
  • Just tried this solution and I'm not getting any errors, though the returned URL doesn't exist and the string is empty. I've tried with 'product_base_image', 'product_small_image' and 'product_thumbnail_image', none of which work. Can you advise please? Or is there an efficient way to do this using the product repository? As I am already loading that elsewhere in my block. – Joshua Flood Apr 24 '18 at 15:57
10

If you need to return a product URL it should look like this:

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

That's the way I did. it's quite efficient and clean:

1) First, you need to inject the following classes:

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) Then, create a getImageUrl method with the code below:

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

Note: The "appEmulation" code is only necessary when you making this call from the admin or for an API. Otherwise, you will get the error below (or similar):

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

3) Call the getImageUrl passing the product object and the type of image you want (based on your view.xml file)

...
$smallImage = $this->getImageUrl($productObject, 'product_page_image_small');
...
1

For gettting custom image url I used this code. So if the image does not exits it will load the default theme image.

$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

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.