Smile-SA/magento2-module-product-label

View on GitHub
Block/Product/ImageFactory.php

Summary

Maintainability
A
2 hrs
Test Coverage
<?php

declare(strict_types=1);

namespace Smile\ProductLabel\Block\Product;

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

/**
 * Custom Image Factory.
 * It's a copy paste of the legacy image factory. Override is only in create() method and is highlighted.
 */
class ImageFactory extends \Magento\Catalog\Block\Product\ImageFactory
{
    private ConfigInterface $presentationConfig;
    private AssetImageFactory $viewAssetImageFactory;
    private ParamsBuilder $imageParamsBuilder;
    private ObjectManagerInterface $objectManager;
    private PlaceholderFactory $viewAssetPlaceholderFactory;

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

    /**
     * Create image block from product
     *
     * @throws LocalizedException
     */
    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]
            );
        }

        $data = [
            'data' => [
                'template'          => 'Smile_ProductLabel::product/image_with_pictos.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'],
                    $imageMiscParams['image_height']
                ),
                'custom_attributes' => $this->getStringCustomAttributes($attributes),
                'product_id'        => $product->getId(),
            ],
        ];

        // Override starts here.
        /** @var ProductLabel $labelsRenderer */
        $labelsRenderer = $this->objectManager->create(ProductLabel::class);
        $labelsRenderer->setProduct($product);

        $data['data']['product_labels'] = $labelsRenderer->getProductLabels();
        $data['data']['product_labels_wrapper_class'] = $labelsRenderer->getWrapperClass();

        /** @var ImageBlock $block */
        $block = $this->objectManager->create(ImageBlock::class, $data);

        return $block;
    }

    /**
     * Retrieve image custom attributes for HTML element
     */
    private function getStringCustomAttributes(array $attributes): string
    {
        $result = [];
        foreach ($attributes as $name => $value) {
            $result[] = $name . '="' . $value . '"';
        }

        return !empty($result) ? implode(' ', $result) : '';
    }

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

    /**
     * Get label
     */
    private function getLabel(Product $product, string $imageType): string
    {
        return (string) ($product->getData($imageType . '_label') ?: $product->getName());
    }
}