1

We're in the process of upgrading our store from Magento 2.4.2 to 2.4.4 and encountered the error shown in the image below. Please help us fix this issue.

enter image description here

Script in the project folder:

<?php

namespace StripeIntegration\Payments\Block\Customer;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Filesystem;
use Magento\Framework\View\Element;
use StripeIntegration\Payments\Helper\Logger;

class Cards extends \Magento\Framework\View\Element\Template
{
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        array $data = [],
        \StripeIntegration\Payments\Helper\Generic $helper,
        \Magento\Payment\Block\Form\Cc $ccBlock,
        \StripeIntegration\Payments\Model\Config $config
    ) {
        $this->stripeCustomer = $helper->getCustomerModel();
        $this->helper = $helper;

        $this->ccBlock = $ccBlock;
        $this->config = $config;

        parent::__construct($context, $data);
    }

    public function getCards()
    {
        try
        {
            return $this->stripeCustomer->getCustomerCards();
        }
        catch (\Exception $e)
        {
            $this->helper->addError($e->getMessage());
            $this->helper->logError($e->getMessage());
            $this->helper->logError($e->getTraceAsString());
        }
    }

    public function verifyBillingAddress()
    {
        $address = $this->helper->getCustomerDefaultBillingAddress();

        if (!$address || empty($address->getStreet()))
            return false;

        return true;
    }

    public function getCcMonths()
    {
        return $this->ccBlock->getCcMonths();
    }

    public function getCcYears()
    {
        return $this->ccBlock->getCcYears();
    }

    public function cardType($code)
    {
        return $this->helper->cardType($code);
    }
}

3 Answers 3

6

This is means that in your block you define optional argument before another required, like:

public function __construt($data = [], SomeClass $required)
{
    //...
}

You need to change order of variables to first required and only after optional (predefined)

public function __construt(SomeClass $required, $data = [])
{
    //...
}

[Update]

In your case it should be

// ...
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \StripeIntegration\Payments\Helper\Generic $helper,
        \Magento\Payment\Block\Form\Cc $ccBlock,
        \StripeIntegration\Payments\Model\Config $config,
        array $data = []
    ) {
        $this->stripeCustomer = $helper->getCustomerModel();
        $this->helper         = $helper;
        $this->ccBlock        = $ccBlock;
        $this->config         = $config;

        parent::__construct($context, $data);
    }
// ...
4
  • Thanks, Victor. I copy pasted the script contents for you to have a look. Commented Aug 25, 2022 at 17:48
  • See update in answer, I hope you understand the idea of changes. Commented Aug 25, 2022 at 17:52
  • Yes, it is clear, thanks Commented Aug 25, 2022 at 17:59
  • @VictorTihonchuk what is quick solution ? if number of 1000 construct() method and function method optional param before required params? Will we change all thousand of methd change or any other quick solution? can we ignore this exception because In my case 150+ module installed and thousand of error face.
    – HaFiz Umer
    Commented Oct 18, 2022 at 12:21
1

I know it's an old post but I recently stumbled upon the same error with an extended class.

Usually you don't need the constructor in the child class unless you have some custom DI to add to the parent class. This was my case. So I had a constructor with the same DI of the parent class plus my own DI.

I was used to put my DI at the end of the required parameters in the constructor, just before the optional parameters. Just as an example, let's say that this is the parent constructor:

public function __construct(
    Class $class,
    array $data = []
) {
    $this->class = $class;
}

My class constructor would be:

public function __construct(
        Class $class,
        Newclass $newclass,
        array $data = []
    ) {
        parent::__construct($class, $data);
        $this->newclass = $newclass;
    }

This has always worked fine.

Recently I switched to magento 2.4.4 with php 8.1 and this class would throw a fatal error cannot instantiate abstract class type. This error happens because the child constructor presents the DI in a different order than the parent class. In this case, original $data was after additional $newclass.

If you just put $data before $newclass, php 8.1 launch your error deprecated function because an optional parameter ($data) is presented before a required one ($newclass).

The solution I found to avoid both error is to put my custom DI at the beginning of the constructor:

public function __construct(
            Newclass $newclass,
            Class $class,
            array $data = []
        ) {
            parent::__construct($class, $data);
            $this->newclass = $newclass;
        }

This way the original order is preserved and the optional parameters are still at the end of the di list.

0

you can use ?type instead in your case : ?array $data, read more here: https://php.watch/versions/8.0/deprecate-required-param-after-optional

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.