0

I have installed a custom module related newsletter, I want my module to be compatible in 2.3 and 2.4. I'm overriding the class Magento\Newsletter\Controller\Subscriber\NewAction

MyVendor/MyModule/etc/di.xml

<preference for="Magento\Newsletter\Controller\Subscriber\NewAction" type="MyVendor\MyModule\Controller\Subscriber\NewAction" />

MyVendor/MyModule/Controller/Subscriber/NewAction.php

<?php
namespace MyVendor\MyModule\Controller\Subscriber;

use Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement;
use Magento\Customer\Model\Session;
use Magento\Customer\Model\Url as CustomerUrl;
use Magento\Framework\App\Action\Context;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Newsletter\Model\SubscriberFactory;
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Framework\App\ObjectManager;

class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{
    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     */
    protected $resultJsonFactory;

    /**
     * @var ProductMetadataInterface $productMetadata
     */
    protected $productMetadata;
    
    /**
     * Initialize dependencies.
     *
     * @param Context $context
     * @param SubscriberFactory $subscriberFactory
     * @param Session $customerSession
     * @param StoreManagerInterface $storeManager
     * @param CustomerUrl $customerUrl
     * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     * @param \Magento\Newsletter\Model\Subscriber $subscriber
     * @param CustomerAccountManagement $customerAccountManagement
     * @param ProductMetadataInterface $productMetadata
     */
    public function __construct(
        Context $context,
        SubscriberFactory $subscriberFactory,
        Session $customerSession,
        StoreManagerInterface $storeManager,
        CustomerUrl $customerUrl,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        \Magento\Newsletter\Model\Subscriber $subscriber,
        CustomerAccountManagement $customerAccountManagement,
        ProductMetadataInterface $productMetadata
    )
    {
        $this->resultJsonFactory = $resultJsonFactory;
        $this->_subscriber= $subscriber;
        $this->productMetadata = $productMetadata;
        if ($this->productMetadata->getVersion() >= "2.4.0") {
            $subscriptionManager = ObjectManager::getInstance()->get(\Magento\Newsletter\Model\SubscriptionManagerInterface::class);
            parent::__construct(
                $context,
                $subscriberFactory,
                $customerSession,
                $storeManager,
                $customerUrl,
                $customerAccountManagement,
                $subscriptionManager
            );    
        }else{
            parent::__construct(
                $context,
                $subscriberFactory,
                $customerSession,
                $storeManager,
                $customerUrl,
                $customerAccountManagement
            );
        }
    }
    
    /**
     * New subscription action
     *
     * @throws \Magento\Framework\Exception\LocalizedException
     * @return void
     */
    public function execute()
    {
        $ajax=$this->getRequest()->getPost('isajax');
        if(isset($ajax) && $ajax == 1){
            $result = $this->resultJsonFactory->create();
            if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')){
                $email = (string)$this->getRequest()->getPost('email');
                try {
                    $this->validateEmailFormat($email);
                    $this->validateGuestSubscription();
                    $this->validateEmailAvailable($email);
                    $emailExist = $this->_subscriber->loadByEmail($email);
                    if ($emailExist->isSubscribed()) {
                        return $result->setData(['message' => 'This email address is already exist.']);    
                    }
                    
                    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();   
                    $session = $objectManager->create('\Magento\Newsletter\Model\Session');
                    $session->setisNewsAjax($this->getRequest()->getPost('isajax'));
                    $session->setNewsPromocode($this->getRequest()->getPost('promo'));
                    $session->setCodeDesc($this->getRequest()->getPost('codedesc'));
                    $status = $this->_subscriberFactory->create()->subscribe($email);

                    if ($status == \Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE) {
                        return $result->setData(['message' => '2']);
                    } else {
                        return $result->setData(['message' => '1']);
                    }
                } catch (\Magento\Framework\Exception\LocalizedException $e) {
                   return $result->setData(['message' => 'There was a problem with the subscription']);
                } catch (\Exception $e) {
                   return $result->setData(['message' => 'Sorry !!! due to some problems you are not able subscribe right now.']);
                }
            }
        }
        else{
            parent::execute();
        }
        
    }
}

I have tried with the below code in construct but with that default Magento newsletter is not working in 2.4 and 2.3 and showing blank page on newsletter submit as shown in this screenshot https://nimb.ws/hFuldp

 if ($this->productMetadata->getVersion() >= "2.4.0") {
            $subscriptionManager = ObjectManager::getInstance()->get(\Magento\Newsletter\Model\SubscriptionManagerInterface::class);
            parent::__construct(
                $context,
                $subscriberFactory,
                $customerSession,
                $storeManager,
                $customerUrl,
                $customerAccountManagement,
                $subscriptionManager
            );    
        }else{
            parent::__construct(
                $context,
                $subscriberFactory,
                $customerSession,
                $storeManager,
                $customerUrl,
                $customerAccountManagement
            );
        }

Please let me know if anyone has a solution.

0

You should better add a plugin for the class instead of overwriting it.

  1. app/code/Vendor/Module/etc/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">
        <type name="Magento\Newsletter\Controller\Subscriber\NewAction">
            <plugin name="newsletter-subscribe-plugin" type="Vendor\Module\Plugin\Controller\Subscriber\NewActionPlugin" />
        </type>
    </config>
    
  2. app/code/Vendor/Module/Plugin/Controller/Subscriber/NewActionPlugin.php

    <?php
    
    namespace Vendor\Module\Plugin\Controller\Subscriber;
    
    use Magento\Framework\App\ObjectManager;
    use Magento\Framework\App\Request\Http;
    use Magento\Framework\Controller\Result\JsonFactory;
    use Magento\Framework\Exception\LocalizedException;
    use Magento\Framework\Validator\EmailAddress as EmailValidator;
    use Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement;
    use Magento\Customer\Model\Url as CustomerUrl;
    use Magento\Customer\Model\Session;
    use Magento\Newsletter\Controller\Subscriber\NewAction;
    use Magento\Newsletter\Model\Subscriber;
    use Magento\Newsletter\Model\SubscriberFactory;
    use Magento\Store\Model\ScopeInterface;
    use Magento\Store\Model\StoreManagerInterface;
    
    class NewActionPlugin
    {
        /**
         * @var JsonFactory $resultJsonFactory
         */
        private $resultJsonFactory;
    
        /**
         * @var Http
         */
        private $request;
    
        /**
         * @var SubscriberFactory
         */
        private $subscriberFactory;
    
        /**
         * @var \Magento\Newsletter\Model\Session
         */
        private $newsletterSession;
    
        /**
         * @var Session
         */
        private $customerSession;
    
        /**
         * @var StoreManagerInterface
         */
        private $storeManager;
    
        /**
         * @var CustomerUrl
         */
        private $customerUrl;
    
        /**
         * @var CustomerAccountManagement
         */
        private $customerAccountManagement;
    
        /**
         * @var ObjectManager
         */
        private $objectManager;
    
        /**
         * NewActionPlugin constructor.
         * @param JsonFactory $resultJsonFactory
         * @param Http $request
         * @param SubscriberFactory $subscriberFactory
         * @param \Magento\Newsletter\Model\Session $newsletterSession
         * @param Session $customerSession
         * @param StoreManagerInterface $storeManager
         * @param CustomerUrl $customerUrl
         * @param CustomerAccountManagement $customerAccountManagement
         * @param ObjectManager $objectManager
         */
        public function __construct(
            JsonFactory $resultJsonFactory,
            Http $request,
            SubscriberFactory $subscriberFactory,
            \Magento\Newsletter\Model\Session $newsletterSession,
            Session $customerSession,
            StoreManagerInterface $storeManager,
            CustomerUrl $customerUrl,
            CustomerAccountManagement $customerAccountManagement,
            ObjectManager $objectManager
        )
        {
            $this->resultJsonFactory = $resultJsonFactory;
            $this->request = $request;
            $this->subscriberFactory = $subscriberFactory;
            $this->newsletterSession = $newsletterSession;
            $this->customerSession = $customerSession;
            $this->storeManager = $storeManager;
            $this->customerUrl = $customerUrl;
            $this->customerAccountManagement = $customerAccountManagement;
            $this->objectManager = $objectManager;
        }
    
        /**
         * @param NewAction $subject
         * @param callable $proceed
         * @return \Magento\Framework\Controller\Result\Json
         */
        public function aroundExecute(NewAction $subject, callable $proceed)
        {
            $ajax = $this->request->getPost('isajax');
    
            if (isset($ajax) && $ajax == 1) {
                $result = $this->resultJsonFactory->create();
    
                if ($this->request->isPost() && $this->request->getPost('email')) {
                    $email = (string) $this->request->getPost('email');
    
                    try {
                        /** @var Subscriber $subscriber */
                        $subscriber = $this->subscriberFactory->create();
    
                        $this->validateEmailFormat($email);
                        $this->validateGuestSubscription();
                        $this->validateEmailAvailable($email);
    
                        $emailExist = $subscriber->loadByEmail($email);
                        if ($emailExist->isSubscribed()) {
                            return $result->setData(['message' => 'This email address is already exist.']);
                        }
    
                        $this->newsletterSession->setisNewsAjax($this->request->getPost('isajax'));
                        $this->newsletterSession->setNewsPromocode($this->request->getPost('promo'));
                        $this->newsletterSession->setCodeDesc($this->request->getPost('codedesc'));
                        $status = $subscriber->subscribe($email);
    
                        if ($status == \Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE) {
                            return $result->setData(['message' => '2']);
                        } else {
                            return $result->setData(['message' => '1']);
                        }
                    } catch (\Magento\Framework\Exception\LocalizedException $e) {
                        return $result->setData(['message' => 'There was a problem with the subscription']);
                    } catch (\Exception $e) {
                        return $result->setData(['message' => 'Sorry !!! due to some problems you are not able subscribe right now.']);
                    }
                } {
                    return $result;
                }
            } else {
                return $proceed();
            }
        }
    
        /**
         * Validates that the email address isn't being used by a different account.
         *
         * @param string $email
         * @throws LocalizedException
         * @return void
         */
        protected function validateEmailAvailable($email)
        {
            $websiteId = $this->storeManager->getStore()->getWebsiteId();
            if ($this->customerSession->isLoggedIn()
                && ($this->customerSession->getCustomerDataObject()->getEmail() !== $email
                    && !$this->customerAccountManagement->isEmailAvailable($email, $websiteId))
            ) {
                throw new LocalizedException(
                    __('This email address is already assigned to another user.')
                );
            }
        }
    
        /**
         * Validates that if the current user is a guest, that they can subscribe to a newsletter.
         *
         * @throws LocalizedException
         * @return void
         */
        protected function validateGuestSubscription()
        {
            if ($this->objectManager->get(ScopeConfigInterface::class)
                    ->getValue(
                        Subscriber::XML_PATH_ALLOW_GUEST_SUBSCRIBE_FLAG,
                        ScopeInterface::SCOPE_STORE
                    ) != 1
                && !$this->customerSession->isLoggedIn()
            ) {
                throw new LocalizedException(
                    __(
                        'Sorry, but the administrator denied subscription for guests. Please <a href="%1">register</a>.',
                        $this->customerUrl->getRegisterUrl()
                    )
                );
            }
        }
    
        /**
         * Validates the format of the email address
         *
         * @param string $email
         * @throws LocalizedException
         * @return void
         */
        protected function validateEmailFormat($email)
        {
            $emailValidator = $this->objectManager->get(EmailValidator::class);
            if (!$emailValidator->isValid($email)) {
                throw new LocalizedException(__('Please enter a valid email address.'));
            }
        }
    }
    
2
  • I have made changes as you suggested, on default magento newsletter it's showing this error:- nimb.ws/yY3T8h
    – Mohit Rane
    Nov 17 at 13:51
  • Also in my module newsletter popup, which is subscribing in the popup also not working.
    – Mohit Rane
    Nov 17 at 13:56
0

Finally, I figured it out myself. Below is the working code.

<?php

namespace MyVendor\MyModule\Controller\Subscriber;

use Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement;
use Magento\Customer\Model\Session;
use Magento\Customer\Model\Url as CustomerUrl;
use Magento\Framework\App\Action\Context;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Newsletter\Model\SubscriberFactory;
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Framework\Controller\ResultFactory;

class NewAction extends \Magento\Newsletter\Controller\Subscriber\NewAction
{
    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     */
    protected $resultJsonFactory;
    
    /**
     * Initialize dependencies.
     *
     * @param Context $context
     * @param SubscriberFactory $subscriberFactory
     * @param Session $customerSession
     * @param StoreManagerInterface $storeManager
     * @param CustomerUrl $customerUrl
     * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     * @param \Magento\Newsletter\Model\Subscriber $subscriber
     * @param CustomerAccountManagement $customerAccountManagement
     * @param ProductMetadataInterface $productMetadata
     */
    public function __construct(
        Context $context,
        SubscriberFactory $subscriberFactory,
        Session $customerSession,
        StoreManagerInterface $storeManager,
        CustomerUrl $customerUrl,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        \Magento\Newsletter\Model\Subscriber $subscriber,
        CustomerAccountManagement $customerAccountManagement,
        ProductMetadataInterface $productMetadata
    )
    {
        $this->resultJsonFactory = $resultJsonFactory;
        $this->_subscriber= $subscriber;
        $this->productMetadata = $productMetadata;
        if (version_compare($this->productMetadata->getVersion(), '2.4.0', '>=')) {
            $subscriptionManager = \Magento\Framework\App\ObjectManager::getInstance()->get(\Magento\Newsletter\Model\SubscriptionManagerInterface::class);
            parent::__construct(
                $context,
                $subscriberFactory,
                $customerSession,
                $storeManager,
                $customerUrl,
                $customerAccountManagement,
                $subscriptionManager
            );    
        }else{
            parent::__construct(
                $context,
                $subscriberFactory,
                $customerSession,
                $storeManager,
                $customerUrl,
                $customerAccountManagement
            );
        }
    }
    
    /**
     * New subscription action
     *
     * @throws \Magento\Framework\Exception\LocalizedException
     * @return void
     */
    public function execute()
    {
        $ajax=$this->getRequest()->getPost('isajax');
        if(isset($ajax) && $ajax == 1){
            $result = $this->resultJsonFactory->create();
            if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')){
                $email = (string)$this->getRequest()->getPost('email');
                try {
                    $this->validateEmailFormat($email);
                    $this->validateGuestSubscription();
                    $this->validateEmailAvailable($email);
                    $emailExist = $this->_subscriber->loadByEmail($email);
                    if ($emailExist->isSubscribed()) {
                        return $result->setData(['message' => 'This email address is already exist.']);    
                    }
                    
                    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();   
                    $session = $objectManager->create('\Magento\Newsletter\Model\Session');
                    $session->setisNewsAjax($this->getRequest()->getPost('isajax'));
                    $session->setNewsPromocode($this->getRequest()->getPost('promo'));
                    $session->setCodeDesc($this->getRequest()->getPost('codedesc'));
                    $status = $this->_subscriberFactory->create()->subscribe($email);

                    if ($status == \Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE) {
                        return $result->setData(['message' => '2']);
                    } else {
                        return $result->setData(['message' => '1']);
                    }
                } catch (\Magento\Framework\Exception\LocalizedException $e) {
                   return $result->setData(['message' => 'There was a problem with the subscription']);
                } catch (\Exception $e) {
                   return $result->setData(['message' => 'Sorry !!! due to some problems you are not able subscribe right now.']);
                }
            }
        }
        else{
            parent::execute();
            /** @var Redirect $redirect */
            $redirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
            $redirectUrl = $this->_redirect->getRedirectUrl();
            return $redirect->setUrl($redirectUrl);
        }
        
    }
}

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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