5

Im working on a module similar to the Magento2 swatch module. I have a custom collection of product and i'm trying to get an image from each product - however it always returns placeholder images.

Here is my block class :

    <?php

namespace Namespace\AlternativeColours\Block;

use Magento\Catalog\Block\Product\AbstractProduct as ProductAbstract;
use Namespace\AlternativeColours\Model\ResourceModel\AlternativeColours as AlternateResource;
use Magento\Framework\Event\ManagerInterface;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollection;
use Magento\Catalog\Helper\Image as ImageHelper;

class AlternativeColours extends \Magento\Framework\View\Element\Template
{


    /**
     * @var \Magento\Framework\Event\ManagerInterface
     */
    protected $eventManager;
    protected $productAbastract;
    protected $productCollectionFactory;
    protected $imageHelper;

    /**
     * @var \Namespace\AlternativeColours\Model\ResourceModel\AlternativeColours $alternativeColoursResource
     */

    protected $alternativeColoursResource;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        AlternateResource $alternativeColoursResource,
        ManagerInterface $eventManager,
        ProductAbstract $productAbstract,
        ProductCollection $productCollectionFactory,
        ImageHelper $imageHelper,
        array $data = []
    ) {
        $this->alternativeColoursResource = $alternativeColoursResource;
        $this->eventManager               = $eventManager;
        $this->productAbastract           = $productAbstract;
        $this->productCollection          = $productCollectionFactory;
        $this->imageHelper                = $imageHelper;
        parent::__construct($context, $data);

    }

    public function getAlternativeProducts() {

        $productId = $this->productAbastract->getProduct()->getId();

        $productIds = $this->alternativeColoursResource->getAlternativeProducts($productId);

        $collection = $this->productCollection->create();

        $collection->addStoreFilter()
            ->addAttributeToSelect('swatch_image')
            ->addAttributeToSelect('url_key')
            ->addAttributeToSelect('small_image')
            ->addAttributeToFilter('entity_id',array('in' => $productIds));


        return $collection;

    }

    public function getImageHelper() {
        return $this->imageHelper;
    }
}

I have a custom image type but for now i'm just using small_image so it's just wont problem at a time. Here is my template file :

<?php
/*
 * @var \Namespace\AlternativeColours\Block\AlternativeColours $block
 * @var $product \Magento\Catalog\Model\Product $product
 */
?>


<?php
    $_imageHelper = $block->getImageHelper();
    $_alternativeProducts = $block->getAlternativeProducts();
?>

<?php foreach($_alternativeProducts as $product) : ?>
    <?php $productImage = $_imageHelper->init($product, 'product_page_image_small')->getUrl(); ?>
    <a href="<?php echo $product->getUrlKey(); ?>" alt="<?php echo $product->getName();?>" title="<?php echo $product->getName();?>">
        <img src="<?php echo $productImage; ?>" />


    </a>
<?php endforeach; ?> 

The template file is added to the catalog_product_view page :

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="product.info.main">
            <block class="Namespace\AlternativeColours\Block\AlternativeColours" as="alternative.colours" template="Namespace_AlternativeColours::alternative_colours.phtml"/>
        </referenceContainer>
    </body>
</page>

Does anyone out there know what's going on. Baring in mind that all other images on the product page work fine!

3

I have resolved this issue myself. However i'm not entirely sure why it worked.

I added a view.xml file to Namespace/AlternativeColours/etc/view.xml

And defined a new image id with dimensions and it started working :

<?xml version="1.0"?>

<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
    <media>
        <images module="Magento_Catalog">
            <image id="alternative_swatch_image_base" type="swatch_image">
                <width>50</width>
                <height>40</height>
            </image>
        </images>
    </media>
</view>

So I therefore changed my phtml file to use this image id instead :

<?php $productImage = $_imageHelper->init($product, 'alternative_swatch_image_base')->getUrl(); ?>

It would be good to know why I couldn't use the pre-defined product_page_image_small

If anyone has any insight into that ?

Hope this helps someone though !

0

Your answer did not work for me but I found another way of showing the image.

echo $this->helper('Magento\Catalog\Helper\Image')->init($product, 'product_page_image_large')->keepAspectRatio(true)->resize($widthDesired, $heightDesired)->getUrl();
  • on the other hand, the problem, I think should be solved somehow within the view.xml, but I have to do some more digging.

Anyway, thx for your solution and I hope mine could be of some use for someone.

0

I had similar issue. A key is that you retrieve product from collection, so basically it doesn't has all data you need. Take a look at vendor/magento/module-catalog/Helper/Image.php:514:

 /**
 * Retrieve image URL
 *
 * @return string
 */
public function getUrl()
{
    try {
        $this->applyScheduledActions();
        return $this->_getModel()->getUrl();
    } catch (\Exception $e) {
        return $this->getDefaultPlaceholderUrl();
    }
}

You get placeholder, because for some reasons magento can't retrieve product's image. In my opinion in catch block should be line logging exception message, but that's only side note.

Why you are unable to get image? Because your product object from collection doesn't have image attribute. On your collection object try to call ->addAttributeToSelect('image') and all should work normally.

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.