Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Products block does not get rendered in the HTML output with Magento 2.4 #27

Open
andres-linares2211 opened this issue Sep 30, 2020 · 1 comment

Comments

@andres-linares2211
Copy link

Hey guys, it's me again.
After you added the compatibility with PHP 7.4 I could finally use the page builder functionality within Vue Storefront.

But now there comes a problem.
In Magento 2.3 I was using the products block to get some new products and they were successfully fetched. Now with Magento 2.4 it does not render. All I get from Magento is the external div that has a data-content-type="products" and nothing inside.

Maybe it has to do with what is inside the div? If a check the database I have this inside the div: {{widget type="Magento\CatalogWidget\Block\Product\ProductsList"...}

This is happening with an instance the Magento that has configured MSI and the default stock is 0.
I checked by changing the default stock to something != 0 and it works... Strangely.

I think this is more of a problem with Magento 2.4.0... Not sure.
Nonetheless, I report it here if anyone has the same problem 👍

@wstnbrg
Copy link

wstnbrg commented Jul 20, 2021

This is due to Magento\Catalog\Block\Product\ImageFactory not providing a string for their getLabel() method on an api call. Fixed this by replacing this class with my own with a check if $imageMiscParams['image_type'] does exists else setting it to empty string.

`<?php
declare(strict_types=1);

namespace Vendor\Module\Rewrite\Magento\Catalog\Block\Product;

use Magento\Catalog\Block\Product\Image as ImageBlock;
use Magento\Catalog\Model\View\Asset\ImageFactory as AssetImageFactory;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Image\ParamsBuilder;
use Magento\Catalog\Model\View\Asset\PlaceholderFactory;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\View\ConfigInterface;
use Magento\Catalog\Helper\Image as ImageHelper;

class ImageFactory extends \Magento\Catalog\Block\Product\ImageFactory
{
/**
* @var ConfigInterface
*/
private $presentationConfig;

/**
 * @var AssetImageFactory
 */
private $viewAssetImageFactory;

/**
 * @var ParamsBuilder
 */
private $imageParamsBuilder;

/**
 * @var ObjectManagerInterface
 */
private $objectManager;

/**
 * @var PlaceholderFactory
 */
private $viewAssetPlaceholderFactory;

/**
 * @param ObjectManagerInterface $objectManager
 * @param ConfigInterface $presentationConfig
 * @param AssetImageFactory $viewAssetImageFactory
 * @param PlaceholderFactory $viewAssetPlaceholderFactory
 * @param ParamsBuilder $imageParamsBuilder
 */
public function __construct(
    ObjectManagerInterface $objectManager,
    ConfigInterface $presentationConfig,
    AssetImageFactory $viewAssetImageFactory,
    PlaceholderFactory $viewAssetPlaceholderFactory,
    ParamsBuilder $imageParamsBuilder
) {
    $this->objectManager = $objectManager;
    $this->presentationConfig = $presentationConfig;
    $this->viewAssetPlaceholderFactory = $viewAssetPlaceholderFactory;
    $this->viewAssetImageFactory = $viewAssetImageFactory;
    $this->imageParamsBuilder = $imageParamsBuilder;
}

/**
 * Retrieve image class for HTML element
 *
 * @param array $attributes
 * @return string
 */
private function getClass(array $attributes): string
{
    return $attributes['class'] ?? 'product-image-photo';
}

/**
 * Calculate image ratio
 *
 * @param int $width
 * @param int $height
 * @return float
 */
private function getRatio(int $width, int $height): float
{
    if ($width && $height) {
        return $height / $width;
    }
    return 1.0;
}

/**
 * Get image label
 *
 * @param Product $product
 * @param string $imageType
 * @return string
 */
private function getLabel(Product $product, string $imageType): string
{
    $label = $product->getData($imageType . '_' . 'label');
    if (empty($label)) {
        $label = $product->getName();
    }
    return (string)$label;
}

/**
 * Remove class from custom attributes
 *
 * @param array $attributes
 * @return array
 */
private function filterCustomAttributes(array $attributes): array
{
    if (isset($attributes['class'])) {
        unset($attributes['class']);
    }
    return $attributes;
}

/**
 * Create image block from product
 *
 * @param Product $product
 * @param string $imageId
 * @param array|null $attributes
 * @return ImageBlock
 */
public function create(Product $product, string $imageId, array $attributes = null): ImageBlock
{
    $viewImageConfig = $this->presentationConfig->getViewConfig()->getMediaAttributes(
        'Magento_Catalog',
        ImageHelper::MEDIA_TYPE_CONFIG_NODE,
        $imageId
    );

    $imageMiscParams = $this->imageParamsBuilder->build($viewImageConfig);
    $originalFilePath = $product->getData($imageMiscParams['image_type']);

    if ($originalFilePath === null || $originalFilePath === 'no_selection') {
        $imageAsset = $this->viewAssetPlaceholderFactory->create(
            [
                'type' => $imageMiscParams['image_type']
            ]
        );
    } else {
        $imageAsset = $this->viewAssetImageFactory->create(
            [
                'miscParams' => $imageMiscParams,
                'filePath' => $originalFilePath,
            ]
        );
    }

    $attributes = $attributes === null ? [] : $attributes;

    if (!array_key_exists('image_type', $imageMiscParams)) {
        $imageMiscParams['image_type'] = '';
    }

    $data = [
        'data' => [
            'template' => 'Magento_Catalog::product/image_with_borders.phtml',
            'image_url' => $imageAsset->getUrl(),
            'width' => $imageMiscParams['image_width'],
            'height' => $imageMiscParams['image_height'],
            'label' => $this->getLabel($product, $imageMiscParams['image_type']),
            'ratio' => $this->getRatio($imageMiscParams['image_width'] ?? 0, $imageMiscParams['image_height'] ?? 0),
            'custom_attributes' => $this->filterCustomAttributes($attributes),
            'class' => $this->getClass($attributes),
            'product_id' => $product->getId()
        ],
    ];

    return $this->objectManager->create(ImageBlock::class, $data);
}

}`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants