0

I am trying to extend Magento\Catalog\Model\Product\Image\ParamsBuilder class in the custom extension and I have passed all the parameters of parent constructor but I'm getting this error,

  Type Error occurred when creating object: Vendor\Management\Model\Product\Image\ParamsBuilder, Argument 1 passed to Magento\Catalog\Model\Product\Image\
  ParamsBuilder::__construct() must implement interface Magento\Framework\App\Config\ScopeConfigInterface, instance of Magento\Framework\Model\Context give
  n, called in /var/www/html/magento/app/code/Vendor\Management/Model/Product/Image/ParamsBuilder.php on line 33

In di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Model\Product\Image\ParamsBuilder" type="Vendor\Management\Model\Product\Image\ParamsBuilder"/>
</config>

In Vendor\Management\Model\Product\Image\ParamsBuilder.php

<?php
namespace Vendor\Management\Model\Product\Image;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\View\ConfigInterface;
use Magento\Catalog\Model\Product\Image\ParamsBuilder as MainModel;

class ParamsBuilder extends MainModel
{
    /**
     * @var ScopeConfigInterface
     */
    private $scopeConfig;

    /**
     * @var ConfigInterface
     */
    private $viewConfig;
    
    /**
     * @param ScopeConfigInterface $scopeConfig
     * @param ConfigInterface $viewConfig
     */
    public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        ScopeConfigInterface $scopeConfig,
        ConfigInterface $viewConfig
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->viewConfig = $viewConfig;
        parent::__construct(
            $context,
            $registry,
            $scopeConfig,
            $viewConfig
        );
    }
    /**
     * Get watermark
     *
     * @param string $type
     * @param int $scopeId
     * @return array
     */
    private function getWatermark(string $type, int $scopeId = null): array
    {
        $writer = new \Laminas\Log\Writer\Stream(BP . '/var/log/test.log');
        $logger = new \Laminas\Log\Logger();
        $logger->addWriter($writer);
        $logger->info(print_r("In getWatermark",true));

        $file = $this->scopeConfig->getValue(
            "design/watermark/{$type}_image",
            ScopeInterface::SCOPE_STORE,
            $scopeId
        );

        if ($file) {
            $size = explode(
                'x',
                (string) $this->scopeConfig->getValue(
                    "design/watermark/{$type}_size",
                    ScopeInterface::SCOPE_STORE,
                    $scopeId
                )
            );
            $opacity = $this->scopeConfig->getValue(
                "design/watermark/{$type}_imageOpacity",
                ScopeInterface::SCOPE_STORE,
                $scopeId
            );
            $position = $this->scopeConfig->getValue(
                "design/watermark/{$type}_position",
                ScopeInterface::SCOPE_STORE,
                $scopeId
            );
            $width = !empty($size['0']) ? $size['0'] : null;
            $height = !empty($size['1']) ? $size['1'] : null;

            return [
                'watermark_file' => $file,
                'watermark_image_opacity' => $opacity,
                'watermark_position' => $position,
                'watermark_width' => $width,
                'watermark_height' => $height
            ];
        }

        return [];
    }
}

The actual params builder class which i am extending is

Magento\Catalog\Model\Product\Image\ParamsBuilder.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Magento\Catalog\Model\Product\Image;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\View\ConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Catalog\Model\Product\Image;

/**
 * Builds parameters array used to build Image Asset
 */
class ParamsBuilder
{
    /**
     * @var array
     */
    private $defaultBackground = [255, 255, 255];

    /**
     * @var int|null
     */
    private $defaultAngle = null;

    /**
     * @var bool
     */
    private $defaultKeepAspectRatio = true;

    /**
     * @var bool
     */
    private $defaultKeepTransparency = true;

    /**
     * @var bool
     */
    private $defaultConstrainOnly = true;

    /**
     * @var ScopeConfigInterface
     */
    private $scopeConfig;

    /**
     * @var ConfigInterface
     */
    private $viewConfig;

    /**
     * @param ScopeConfigInterface $scopeConfig
     * @param ConfigInterface $viewConfig
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig,
        ConfigInterface $viewConfig
    ) {
        $this->scopeConfig = $scopeConfig;
        $this->viewConfig = $viewConfig;
    }

    /**
     * Build image params
     *
     * @param array $imageArguments
     * @param int $scopeId
     * @return array
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     */
    public function build(array $imageArguments, int $scopeId = null): array
    {
        $miscParams = [
            'image_type' => $imageArguments['type'] ?? null,
            'image_height' => $imageArguments['height'] ?? null,
            'image_width' => $imageArguments['width'] ?? null,
        ];

        $overwritten = $this->overwriteDefaultValues($imageArguments);
        $watermark = isset($miscParams['image_type']) ? $this->getWatermark($miscParams['image_type'], $scopeId) : [];

        return array_merge($miscParams, $overwritten, $watermark);
    }

    /**
     * Overwrite default values
     *
     * @param array $imageArguments
     * @return array
     */
    private function overwriteDefaultValues(array $imageArguments): array
    {
        $frame = $imageArguments['frame'] ?? $this->hasDefaultFrame();
        $constrain = $imageArguments['constrain'] ?? $this->defaultConstrainOnly;
        $aspectRatio = $imageArguments['aspect_ratio'] ?? $this->defaultKeepAspectRatio;
        $transparency = $imageArguments['transparency'] ?? $this->defaultKeepTransparency;
        $background = $imageArguments['background'] ?? $this->defaultBackground;
        $angle = $imageArguments['angle'] ?? $this->defaultAngle;
        $quality = (int) $this->scopeConfig->getValue(Image::XML_PATH_JPEG_QUALITY);

        return [
            'background' => (array) $background,
            'angle' => $angle,
            'quality' => $quality,
            'keep_aspect_ratio' => (bool) $aspectRatio,
            'keep_frame' => (bool) $frame,
            'keep_transparency' => (bool) $transparency,
            'constrain_only' => (bool) $constrain,
        ];
    }

    /**
     * Get watermark
     *
     * @param string $type
     * @param int $scopeId
     * @return array
     */
    private function getWatermark(string $type, int $scopeId = null): array
    {
        $file = $this->scopeConfig->getValue(
            "design/watermark/{$type}_image",
            ScopeInterface::SCOPE_STORE,
            $scopeId
        );

        if ($file) {
            $size = explode(
                'x',
                (string) $this->scopeConfig->getValue(
                    "design/watermark/{$type}_size",
                    ScopeInterface::SCOPE_STORE,
                    $scopeId
                )
            );
            $opacity = $this->scopeConfig->getValue(
                "design/watermark/{$type}_imageOpacity",
                ScopeInterface::SCOPE_STORE,
                $scopeId
            );
            $position = $this->scopeConfig->getValue(
                "design/watermark/{$type}_position",
                ScopeInterface::SCOPE_STORE,
                $scopeId
            );
            $width = !empty($size['0']) ? $size['0'] : null;
            $height = !empty($size['1']) ? $size['1'] : null;

            return [
                'watermark_file' => $file,
                'watermark_image_opacity' => $opacity,
                'watermark_position' => $position,
                'watermark_width' => $width,
                'watermark_height' => $height
            ];
        }

        return [];
    }

    /**
     * Get frame from product_image_white_borders
     *
     * @return bool
     */
    private function hasDefaultFrame(): bool
    {
        return (bool) $this->viewConfig->getViewConfig(['area' => \Magento\Framework\App\Area::AREA_FRONTEND])
            ->getVarValue('Magento_Catalog', 'product_image_white_borders');
    }
}

1 Answer 1

1

remove $cntext and $registry in your construct:

public function __construct(
    ScopeConfigInterface $scopeConfig,
    ConfigInterface $viewConfig
) {
    parent::__construct(
        $scopeConfig,
        $viewConfig
    );
}
8
  • I tried but then there is nothing logged in getwatermark() method.
    – Bushra
    Sep 24, 2021 at 7:43
  • getwatermark is the private method, how I can override it?
    – Bushra
    Sep 24, 2021 at 7:49
  • You cannot do it. The only way is to rewrite the whole class, not extend it.
    – krybbio
    Sep 24, 2021 at 8:00
  • Can you refer to some example links?
    – Bushra
    Sep 24, 2021 at 8:09
  • Copy the whole class in Vendor\Management\Model\Product\Image\ParamsBuilder.php then add your customizations.
    – krybbio
    Sep 24, 2021 at 8:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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