0

I am getting only email value in database column my custom subscriber_name column showing null please help me

db_schema.xml

<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
    <table name="newsletter_subscriber" resource="default" engine="innodb" comment="Newsletter Subscriber">
        <column xsi:type="text" name="subscriber_name"  nullable="true" comment="Subscriber Name"/>
    </table>
</schema>

di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
  <type name="Magento\Newsletter\Model\Subscriber">
    <plugin name="vendor_module_model_subscriber" type="\Vendor\Module\Plugin\Subscriber" sortOrder="1" />
  </type>
</config>

Subscriber.php

<?php
namespace Vendor\Module\Plugin;

use Magento\Framework\App\Request\Http;

class Subscriber {
    protected $request;
    public function __construct(Http $request){
        $this->request = $request;
    }

    public function aroundSubscribe($subject, \Closure $proceed, $email) {
       
        if ($this->request->isPost() && $this->request->getPost('subscriber_name')) { 
            $subscriberName = $this->request->getPost('subscriber_name');
            $subject->setSubscriberName($subscriberName);
            $result = $proceed($email);


            try {
                $subject->save();

            }catch (\Exception $e) {
                throw new \Exception($e->getMessage());
            }
        }
        return $result;
    }
}

default.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="footer">
        <block class="Magento\Newsletter\Block\Subscribe" name="form.subscribe.new" before="-" template="Vendor_Module::subscribe.phtml"/>
    </referenceContainer>
        <referenceBlock name="form.subscribe" remove="true" />
    </body>
</page>

newsletter_subscriber_block.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
  <body>
    <referenceBlock name="adminhtml.newslettrer.subscriber.grid.columnSet">
      <block class="Magento\Backend\Block\Widget\Grid\Column" as="custom_name">
        <arguments>
          <argument name="header" xsi:type="string" translate="true">Subscriber Name</argument>
          <argument name="index" xsi:type="string">subscriber name</argument>
          <argument name="header_css_class" xsi:type="string">col-name</argument>
          <argument name="column_css_class" xsi:type="string">ccol-name</argument>
        </arguments>
      </block>
    </referenceBlock>
  </body>
</page>

Subscribe.phtml

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/** @var \Magento\Newsletter\Block\Subscribe $block */
?>
<div class="block newsletter">
    <div class="title"><strong><?= $block->escapeHtml(__('Newsletter')) ?></strong></div>
    <div class="content">
        <form class="form subscribe"
            novalidate
            action="<?= $block->escapeUrl($block->getFormActionUrl()) ?>"
            method="post"
            data-mage-init='{"validation": {"errorClass": "mage-error"}}'
            id="newsletter-validate-detail">
            <div class="field newsletter">
                <div class="control">
                    <label for="newsletter">
                        <span class="label">
                            <?= $block->escapeHtml(__('Sign Up for Our Newsletter:')) ?>
                        </span>
                        <input name="email" type="email" id="newsletter"
                               placeholder="<?= $block->escapeHtmlAttr(__('Enter your email address')) ?>"
                               data-mage-init='{"mage/trim-input":{}}'
                               data-validate="{required:true, 'validate-email':true}"
                        />
                        <div class="field subscriber_name">
                            <label class="label" for="subscriber_name"><span><?php echo $block->escapeHtml(__('Subscriber Name')) ?></span></label>
                            <div class="control">
                                <input name="subscriber_name" type="text" id="subscriber_name" placeholder="<?php echo $block->escapeHtml(__('Subscriber Name')) ?>" data-validate="{required:true}"/>
                            </div>
                        </div>
                    </label>
                </div>
            </div>
            <div class="actions">
                <button class="action subscribe primary"
                        title="<?= $block->escapeHtmlAttr(__('Subscribe')) ?>"
                        type="submit"
                        aria-label="Subscribe">
                    <span><?= $block->escapeHtml(__('Subscribe')) ?></span>
                </button>
            </div>
        </form>
    </div>
</div>
<script type="text/x-magento-init">
    {
        "*": {
            "Magento_Customer/js/block-submit-on-send": {
                "formId": "newsletter-validate-detail"
            }
        }
    }
</script>

1 Answer 1

0

In module-newsletter/Controller/Subscriber/NewAction as you can see here:

class CustomSubscribe extends SubscriberController implements HttpPostActionInterface
{

    /**
     * New subscription action
     *
     * @return \Magento\Framework\Controller\Result\Redirect
     */
    public function execute()
    {
        if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')) {
            $email = (string)$this->getRequest()->getPost('email');

        try {
            $this->validateEmailFormat($email);
            $this->validateGuestSubscription();
            $this->validateEmailAvailable($email);

            $subscriber = $this->_subscriberFactory->create()->loadByEmail($email);
            if ($subscriber->getId()
                && (int) $subscriber->getSubscriberStatus() === Subscriber::STATUS_SUBSCRIBED
            ) {
                throw new LocalizedException(
                    __('This email address is already subscribed.')
                );
            }

            $status = (int) $this->_subscriberFactory->create()->subscribe($email);
            $this->messageManager->addSuccessMessage($this->getSuccessMessage($status));
        } catch (LocalizedException $e) {
            $this->messageManager->addErrorMessage($e->getMessage());
        } catch (\Exception $e) {
            $this->messageManager->addExceptionMessage($e, __('Something went wrong with the subscription.'));
        }
    }
    /** @var \Magento\Framework\Controller\Result\Redirect $redirect */
    $redirect = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT);
    $redirectUrl = $this->_redirect->getRedirectUrl();
    return $redirect->setUrl($redirectUrl);
}
}

The Subscribe method takes only the Email parameter from the post action, so your plugin probably tries to save something that is null.

I suggest you in your case to create your own subscribe controller under your module extending the Magento base model to implement your customSubscribe:

Vendor/Module/Controller/Subscriber/CustomSubscriber:

public function execute()
{
    if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email') && $this->getRequest()->getPost('custom_name')) {
        $email = (string)$this->getRequest()->getPost('email');
        $customName = (string)$this->getRequest()->getPost('custom_name');

        try {
            $this->validateEmailFormat($email);
            $this->validateGuestSubscription();
            $this->validateEmailAvailable($email);

            $subscriber = $this->_subscriberFactory->create()->loadByEmail($email);
            if ($subscriber->getId()
                && (int) $subscriber->getSubscriberStatus() === Subscriber::STATUS_SUBSCRIBED
            ) {
                throw new LocalizedException(
                    __('This email address is already subscribed.')
                );
            }

            $status = (int) $this->_subscriberFactory->create()->customSubscribe($email);
            $this->messageManager->addSuccessMessage($this->getSuccessMessage($status));
        } catch (LocalizedException $e) {
            $this->messageManager->addErrorMessage($e->getMessage());
        } catch (\Exception $e) {
            $this->messageManager->addExceptionMessage($e, __('Something went wrong with the subscription.'));
        }
    }

    /** @var \Magento\Framework\Controller\Result\Redirect $redirect */
    $redirect = $this->resultFactory->create(\Magento\Framework\Controller\ResultFactory::TYPE_REDIRECT);
    $redirectUrl = $this->_redirect->getRedirectUrl();
    return $redirect->setUrl($redirectUrl);
}

And create a new method extending Magento/Newsletter/Model/Subscriber:

in your di.xml:

<preference for="Magento\Newsletter\Model\Subscriber" type="Vendor\Module\Model\Subscriber" />

and then inside your new Vendor\Module\Model\Subscriber:

public function customSubscribe($email, $customName)
{
    $this->loadByEmail($email);

    if ($this->getId() && $this->getStatus() == self::STATUS_SUBSCRIBED) {
        return $this->getStatus();
    }

    if (!$this->getId()) {
        $this->setSubscriberConfirmCode($this->randomSequence());
    }

    $isConfirmNeed = $this->_scopeConfig->getValue(
        self::XML_PATH_CONFIRMATION_FLAG,
        \Magento\Store\Model\ScopeInterface::SCOPE_STORE
    ) == 1 ? true : false;

    $isSubscribeOwnEmail = $this->_customerSession->isLoggedIn()
        && $this->_customerSession->getCustomerDataObject()->getEmail() == $email;

    if (!$this->getId() || $this->getStatus() == self::STATUS_UNSUBSCRIBED
        || $this->getStatus() == self::STATUS_NOT_ACTIVE
    ) {
        if ($isConfirmNeed === true) {
            $this->setStatus(self::STATUS_NOT_ACTIVE);
        } else {
            $this->setStatus(self::STATUS_SUBSCRIBED);
        }
        $this->setSubscriberEmail($email);
        $this->setCustomName($customName);
    }

    if ($isSubscribeOwnEmail) {
        try {
            $customer = $this->customerRepository->getById($this->_customerSession->getCustomerId());
            $this->setStoreId($customer->getStoreId());
            $this->setCustomerId($customer->getId());
        } catch (NoSuchEntityException $e) {
            $this->setStoreId($this->_storeManager->getStore()->getId());
            $this->setCustomerId(0);
        }
    } else {
        $this->setStoreId($this->_storeManager->getStore()->getId());
        $this->setCustomerId(0);
    }

    $this->setStatusChanged(true);

    try {
        /* Save model before sending out email */
        $this->save();
        if ($isConfirmNeed === true) {
            $this->sendConfirmationRequestEmail();
        } else {
            $this->sendConfirmationSuccessEmail();
        }
        return $this->getStatus();
    } catch (\Exception $e) {
        // phpcs:ignore Magento2.Exceptions.DirectThrow
        throw new \Exception($e->getMessage());
    }
}

Then you have to edit your custom subscriber.phtml changing the form action:

<form action="<?php echo $block->getBaseUrl().'vendor/module/customSubscribe/' ?>"> .... </form>

And create a Vendor/Module/etc/frontend/route.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="module" frontName="module">
            <module name="Vendor_Module" />
        </route>
    </router>
</config>
5
  • 5.7.8 Username and Password not accepted. Learn more at 5.7.8 support.google.com/mail/?p=BadCredentials c12sm13612062pfl.56 - gsmtp getting this type error
    – Mark
    Commented Aug 23, 2021 at 6:03
  • And the smtp is working fine for all the other transaction emails? Commented Aug 23, 2021 at 7:30
  • yes i also solved that error
    – Mark
    Commented Aug 23, 2021 at 7:31
  • i am not getting any error now but i getting null value in my database custom table
    – Mark
    Commented Aug 23, 2021 at 7:31
  • /vendor/magento/module-newsletter/Model/Plugin/CustomerPlugin.php, it seems that the subscribe event triggers a plugin to save data's inside the table, so now that you've got the data from the post, you might want to use extensionAttributes and then save on the newsletter table Commented Aug 23, 2021 at 7:43

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.