سؤال

I try to override the method sendConfirmationRequestEmail from the module-newsletter Module in vendor\magento\module-newsletter\Model\Subscriber.php.

Attempt:

app\code\Company\Newsletter2Go\etc\di.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <preference for="Magento\Subscriber\Model\Subscriber"
                type="Company\Newsletter2Go\Model\Subscriber" />
</config>

app\code\Company\Newsletter2Go\Model\Subscriber.php:

<?php
namespace Company\Newsletter2Go\Model;

use Magento\Customer\Api\AccountManagementInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Api\Data\CustomerInterfaceFactory;
use Magento\Framework\Api\DataObjectHelper;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Registry;
use Magento\Framework\Stdlib\DateTime\DateTime;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Newsletter\Helper\Data;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Customer\Model\Session;
use Magento\Newsletter\Model\SubscriptionManagerInterface;

class Subscriber extends \Magento\Newsletter\Model\Subscriber
{       
    public function __construct(
        Context $context,
        Registry $registry,
        Data $newsletterData,
        ScopeConfigInterface $scopeConfig,
        TransportBuilder $transportBuilder,
        StoreManagerInterface $storeManager,
        Session $customerSession,
        CustomerRepositoryInterface $customerRepository,
        AccountManagementInterface $customerAccountManagement,
        StateInterface $inlineTranslation,
        AbstractResource $resource = null,
        AbstractDb $resourceCollection = null,
        array $data = [],
        DateTime $dateTime = null,
        CustomerInterfaceFactory $customerFactory = null,
        DataObjectHelper $dataObjectHelper = null,
        SubscriptionManagerInterface $subscriptionManager = null
    ) {
        parent::__construct(
               $context, 
               $registry, 
               $newsletterData, 
               $scopeConfig, 
               $transportBuilder,
               $storeManager,
               $customerSession,
               $customerRepository,
               $customerAccountManagement,
               $inlineTranslation,
               $resource,
               $resourceCollection,
               $data,
               $dateTime,
               $customerFactory,
               $dataObjectHelper,
               $subscriptionManager
           );
    }

    /**
     * Sends out confirmation email
     *
     * @return $this
     */
    public function sendConfirmationRequestEmail()
    {
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/zend_debug.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        
        $logger->info("sendConfirmationRequestEmail override");


        return $this;
    }




}

I also added a log entry to the original method:

vendor\magento\module-newsletter\Model\Subscriber.php

...

public function sendConfirmationRequestEmail()
{
    $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/zend_debug.log');
    $logger = new \Zend\Log\Logger();
    $logger->addWriter($writer);
    $logger->info("sendConfirmationRequestEmail original");
    ...
}

Then I executed php bin/magento setup:di:compile and flushed the cache with php bin/magento cache:flush

Now If I open a customer in the backend, set the newsletter checkbox and press on save customer button

enter image description here

then I get this logged into the logfile:

sendConfirmationRequestEmail original

Why does it still load the original Method instead of my override?


Additional Information:

I've set the module sequence to this:

app\code\Company\Newsletter2Go\etc\module.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Company_Newsletter2Go" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Newsletter"/>
        </sequence>
    </module>
</config>
  • I am using Magento 2.4.2
  • I disabled any third party module but mine, and it is still not working.
  • I removed any other code from the module which is not related to the preference override
  • I executed grunt clean to clear any generated content and cache before executing setup:di:compile.
  • Also tested on a fresh up-to-date magento 2.4.2 with sample data, without any third party modules.
هل كانت مفيدة؟

المحلول 2

It was my fault. I accidentially used Magento\Subscriber\Model\Subscriber instead of Magento\Newsletter\Model\Subscriber.

app\code\Company\Newsletter2Go\etc\di.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <preference for="Magento\Subscriber\Model\Subscriber"  <--- wrong, should be Magento\Newsletter\Model\Subscriber
                type="Company\Newsletter2Go\Model\Subscriber" />
</config>

نصائح أخرى

Is is possible Magento is not reading your di.xml file - permissions perhaps?

Because I tested your code and receive a parse error on compilation due to the extra comma in last line of construct: SubscriptionManagerInterface $subscriptionManager = null, after removing that, and running compilation successfully your code works fine for me in frontend and admin. I get the log file written and parent isn't called.

If that isn't the problem, then I would check to see if no other custom module is already overriding the Subscriber model.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى magento.stackexchange
scroll top