Magento 2 error occurs when using <preference> to override a block class
-
10-10-2020 - |
سؤال
I want to override the block class Book.php
of customer module,But i got Following error.
Recoverable Error: Argument 2 passed to Magento\Customer\Block\Address\Book::__construct() must implement interface Magento\Customer\Api\CustomerRepositoryInterface, array given, called in
E:\xampp\htdocs\magento217\app\code\MyCompany\MyModule\Block\Rewrite\Address\Book.php on line 67 and defined in
E:\xampp\htdocs\magento217\vendor\magento\module-customer\Block\Address\Book.php on line 55
My 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\Customer\Block\Address\Book" type="MyCompany\MyModule\Block\Rewrite\Address\Book" />
</config>
Book.php
<?php
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace MyCompany\MyModule\Block\Rewrite\Address;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\Address\Mapper;
/**
* Customer address book block
*
* @author Magento Core Team <core@magentocommerce.com>
*/
class Book extends \Magento\Customer\Block\Address\Book
{
/**
* @var \Magento\Customer\Helper\Session\CurrentCustomer
*/
protected $currentCustomer;
/**
* @var CustomerRepositoryInterface
*/
protected $customerRepository;
/**
* @var AddressRepositoryInterface
*/
protected $addressRepository;
/**
* @var \Magento\Customer\Model\Address\Config
*/
protected $_addressConfig;
/**
* @var Mapper
*/
protected $addressMapper;
/**
* @param \Magento\Framework\View\Element\Template\Context $context
* @param CustomerRepositoryInterface $customerRepository
* @param AddressRepositoryInterface $addressRepository
* @param \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer
* @param \Magento\Customer\Model\Address\Config $addressConfig
* @param Mapper $addressMapper
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
CustomerRepositoryInterface $customerRepository,
AddressRepositoryInterface $addressRepository,
\Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer,
\Magento\Customer\Model\Address\Config $addressConfig,
Mapper $addressMapper
array $data = []
) {
$this->customerRepository = $customerRepository;
$this->currentCustomer = $currentCustomer;
$this->addressRepository = $addressRepository;
$this->_addressConfig = $addressConfig;
$this->addressMapper = $addressMapper;
parent::__construct($context, $data);
}
/**
* @return $this
*/
protected function _prepareLayout()
{
$this->pageConfig->getTitle()->set(__('Address Book'));
return parent::_prepareLayout();
}
/**
* @return string
*/
public function getAddAddressUrl()
{
return $this->getUrl('customer/address/new', ['_secure' => true]);
}
/**
* @return string
*/
public function getBackUrl()
{
if ($this->getRefererUrl()) {
return $this->getRefererUrl();
}
return $this->getUrl('customer/account/', ['_secure' => true]);
}
/**
* @return string
*/
public function getDeleteUrl()
{
return $this->getUrl('customer/address/delete');
}
/**
* @param int $addressId
* @return string
*/
public function getAddressEditUrl($addressId)
{
return $this->getUrl('customer/address/edit', ['_secure' => true, 'id' => $addressId]);
}
/**
* @return bool
*/
public function hasPrimaryAddress()
{
return $this->getDefaultBilling() || $this->getDefaultShipping();
}
/**
* @return \Magento\Customer\Api\Data\AddressInterface[]|bool
*/
public function getAdditionalAddresses()
{
try {
$addresses = $this->customerRepository->getById($this->currentCustomer->getCustomerId())->getAddresses();
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
return false;
}
$primaryAddressIds = [$this->getDefaultBilling(), $this->getDefaultShipping()];
foreach ($addresses as $address) {
if (!in_array($address->getId(), $primaryAddressIds)) {
$additional[] = $address;
}
}
return empty($additional) ? false : $additional;
}
/**
* Render an address as HTML and return the result
*
* @param \Magento\Customer\Api\Data\AddressInterface $address
* @return string
*/
public function getAddressHtml(\Magento\Customer\Api\Data\AddressInterface $address = null)
{
if ($address !== null) {
/** @var \Magento\Customer\Block\Address\Renderer\RendererInterface $renderer */
$renderer = $this->_addressConfig->getFormatByCode('html')->getRenderer();
return $renderer->renderArray($this->addressMapper->toFlatArray($address));
}
return '';
}
/**
* @return \Magento\Customer\Api\Data\CustomerInterface|null
*/
public function getCustomer()
{
$customer = $this->getData('customer');
if ($customer === null) {
try {
$customer = $this->customerRepository->getById($this->currentCustomer->getCustomerId());
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
return null;
}
$this->setData('customer', $customer);
}
return $customer;
}
/**
* @return int|null
*/
public function getDefaultBilling()
{
$customer = $this->getCustomer();
if ($customer === null) {
return null;
} else {
return $customer->getDefaultBilling();
}
}
/**
* @param int $addressId
* @return \Magento\Customer\Api\Data\AddressInterface|null
*/
public function getAddressById($addressId)
{
try {
return $this->addressRepository->getById($addressId);
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
return null;
}
}
/**
* @return int|null
*/
public function getDefaultShipping()
{
$customer = $this->getCustomer();
if ($customer === null) {
return null;
} else {
return $customer->getDefaultShipping();
}
}
}
Can any one help me on this problem ? Any references or suggestions are highly appreciated.
المحلول
Replace your __construct by following code
/**
* @param \Magento\Framework\View\Element\Template\Context $context
* @param CustomerRepositoryInterface $customerRepository
* @param AddressRepositoryInterface $addressRepository
* @param \Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer
* @param \Magento\Customer\Model\Address\Config $addressConfig
* @param Mapper $addressMapper
* @param array $data
*/
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
CustomerRepositoryInterface $customerRepository,
AddressRepositoryInterface $addressRepository,
\Magento\Customer\Helper\Session\CurrentCustomer $currentCustomer,
\Magento\Customer\Model\Address\Config $addressConfig,
Mapper $addressMapper,
array $data = []
) {
$this->customerRepository = $customerRepository;
$this->currentCustomer = $currentCustomer;
$this->addressRepository = $addressRepository;
$this->_addressConfig = $addressConfig;
$this->addressMapper = $addressMapper;
parent::__construct($context, $customerRepository, $addressRepository, $currentCustomer, $addressConfig, $addressMapper, $data);
}
Delete var/generation/*
[Update]
Inside layout config customer_address_index.xml, template attribute should be Magento_Customer::address/book.phtml
<block class="Magento\Customer\Block\Address\Book" name="address_book" template="Magento_Customer::address/book.phtml" cacheable="false"/>