In this post we will check how to add newsletter subscriber at checkout page in Magento2.
Create folder inside app/code/Magelearn/NewsletterSubscribeAtCheckout
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Magelearn_NewsletterSubscribeAtCheckout',
__DIR__
);Add composer.json file in it:
{
"name": "magelearn/magento2-newsletter-subscribe-at-checkout",
"description": "This module allows to enable a newsletter subscription checkbox on the checkout page. Customers can subscribe to your newsletter list in Marketing > Communications > Newsletter Subscribers during checkout.",
"type": "magento2-module",
"license": "proprietary",
"version": "1.0.0",
"authors": [
{
"name": "Vijay Rami",
"email": "vijaymrami@gmail.com"
}
],
"minimum-stability": "dev",
"require": {},
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Magelearn\\NewsletterSubscribeAtCheckout\\": ""
}
}
}Add etc/module.xml file in it:
<?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="Magelearn_NewsletterSubscribeAtCheckout" setup_version="1.0.0">
<sequence>
<module name="Magento_Checkout"/>
<module name="Magento_Newsletter"/>
</sequence>
</module>
</config>Now, we will add database setup script.
Create db_schema.xml file in etc folder.
this script will add new column `newsletter_subscribe` in `quote` table.
<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="quote" resource="checkout" engine="innodb" comment="Newsletter Subscribe At Checkout">
<column xsi:type="int" name="newsletter_subscribe" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Newsletter Subscribe"/>
</table>
</schema>To validate this db_schema.xml file we will first run below command:
php bin/magento setup:db-declaration:generate-whitelist --module-name=Magelearn_NewsletterSubscribeAtCheckout
This command will automatically generate db_schema_whitelist.json file inside etc folder.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="checkout" translate="label" type="text" sortOrder="305" showInDefault="1" showInWebsite="1" showInStore="1">
<class>separator-top</class>
<label>Checkout</label>
<tab>sales</tab>
<resource>Magento_Checkout::checkout</resource>
<group id="magelearn_newslettersubscribeatcheckout" translate="label" sortOrder="120" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Newsletter Subscribe At Checkout</label>
<field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enabled</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="checked" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Checked</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>This will pre-tick the newsletter checkbox.</comment>
<depends>
<field id="enabled">1</field>
</depends>
</field>
<field id="label" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Label</label>
<validate>validate-no-empty</validate>
<comment>E.g: Subscribe for Newsletter</comment>
<depends>
<field id="enabled">1</field>
</depends>
</field>
<field id="note_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable Note</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>Enable a note right below the newsletter subscription.</comment>
<depends>
<field id="enabled">1</field>
</depends>
</field>
<field id="note" translate="label" type="textarea" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Text for Note</label>
<comment>E.g: Subscribe now and receive great discount codes monthly. HTML is supported.</comment>
<depends>
<field id="enabled">1</field>
<field id="note_enabled">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>Now, we will provide some pre-selected configuration values in etc/config.xml file.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<checkout>
<magelearn_newslettersubscribeatcheckout>
<enabled>0</enabled>
<checked>0</checked>
<label>Subscribe for Newsletter</label>
<note_enabled>0</note_enabled>
</magelearn_newslettersubscribeatcheckout>
</checkout>
</default>
</config>We will add this newsletter subscriber field by adding UI Component (Magento\Checkout\Block\Onepage\layoutProcessors) and modifying layout file (checkout_index_index.xml).
Add app/code/Magelearn/NewsletterSubscribeAtCheckout/view/frontend/layout/checkout_index_index.xml file.
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAddress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="customer-email" xsi:type="array">
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Magelearn_NewsletterSubscribeAtCheckout/form/element/email</item>
</item>
<item name="children" xsi:type="array">
<item name="newsletter_subscribe" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/form</item>
<item name="displayArea" xsi:type="string">newsletter_subscribe</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Magelearn_NewsletterSubscribeAtCheckout/form/element/newsletter_subscribe</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
<item name="billing-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="payment" xsi:type="array">
<item name="children" xsi:type="array">
<item name="customer-email" xsi:type="array">
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Magelearn_NewsletterSubscribeAtCheckout/form/element/email</item>
</item>
<item name="children" xsi:type="array">
<item name="newsletter_subscribe" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/form</item>
<item name="displayArea" xsi:type="string">newsletter_subscribe</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">Magelearn_NewsletterSubscribeAtCheckout/form/element/newsletter_subscribe</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>As per defined in checkout_index_index.xml file, first we will modify app/code/Magelearn/NewsletterSubscribeAtCheckout/view/frontend/web/template/form/element/email.html file.
We will override vendor/magento/module-checkout/view/frontend/web/template/form/element/email.html and add `newsletter_subscribe` region in that.
Add app/code/Magelearn/NewsletterSubscribeAtCheckout/view/frontend/web/template/form/element/email.html
<!-- ko ifnot: isCustomerLoggedIn() -->
<!-- ko foreach: getRegion('before-login-form') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
<form class="form form-login" data-role="email-with-possible-login"
data-bind="submit:login"
method="post">
<fieldset id="customer-email-fieldset" class="fieldset" data-bind="blockLoader: isLoading">
<div class="field required">
<label class="label" for="customer-email"><span data-bind="i18n: 'Email Address'"></span></label>
<div class="control _with-tooltip">
<input class="input-text"
type="email"
data-bind="
textInput: email,
hasFocus: emailFocused,
afterRender: emailHasChanged,
mageInit: {'mage/trim-input':{}}"
name="username"
data-validate="{required:true, 'validate-email':true}"
id="customer-email" />
<!-- ko template: 'ui/form/element/helper/tooltip' --><!-- /ko -->
<span class="note" data-bind="fadeVisible: isPasswordVisible() == false"><!-- ko i18n: 'You can create an account after checkout.'--><!-- /ko --></span>
</div>
</div>
<!-- ko foreach: getRegion('newsletter_subscribe') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<!--Hidden fields -->
<fieldset class="fieldset hidden-fields" data-bind="fadeVisible: isPasswordVisible">
<div class="field">
<label class="label" for="customer-password"><span data-bind="i18n: 'Password'"></span></label>
<div class="control">
<input class="input-text"
data-bind="
attr: {
placeholder: $t('Password'),
}"
type="password"
name="password"
id="customer-password"
data-validate="{required:true}" autocomplete="off"/>
<span class="note" data-bind="i18n: 'You already have an account with us. Sign in or continue as guest.'"></span>
</div>
</div>
<!-- ko foreach: getRegion('additional-login-form-fields') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
<div class="actions-toolbar">
<input name="context" type="hidden" value="checkout" />
<div class="primary">
<button type="submit" class="action login primary" data-action="checkout-method-login"><span data-bind="i18n: 'Login'"></span></button>
</div>
<div class="secondary">
<a class="action remind" data-bind="attr: { href: forgotPasswordUrl }">
<span data-bind="i18n: 'Forgot Your Password?'"></span>
</a>
</div>
</div>
</fieldset>
<!--Hidden fields -->
</fieldset>
</form>
<!-- /ko -->
<!-- ko if: isCustomerLoggedIn() -->
<form class="form form-login" data-role="email-with-possible-login" data-bind="submit:login" method="post">
<fieldset id="customer-email-fieldset" class="fieldset" data-bind="blockLoader: isLoading">
<div class="field required">
<label class="label" for="customer-email">
<span data-bind="i18n: 'Email Address'"></span>
</label>
<div class="control _with-tooltip">
<input class="input-text"
type="email"
data-bind="
textInput: email,
hasFocus: emailFocused"
name="username"
data-validate="{required:true, 'validate-email':true}"
id="customer-email" />
<!-- ko template: 'ui/form/element/helper/tooltip' --><!-- /ko -->
<span class="note" data-bind="fadeVisible: isPasswordVisible() == false"><!-- ko i18n: 'You can create an account after checkout.'--><!-- /ko --></span>
</div>
</div>
<!-- ko foreach: getRegion('newsletter_subscribe') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</fieldset>
</form>
<!-- /ko --> Now we will add app/code/Magelearn/NewsletterSubscribeAtCheckout/view/frontend/web/template/form/element/newsletter_subscribe.html file.<!-- ko if: enabled -->
<div class="field">
<div class="control">
<input class="input-text"
type="checkbox"
data-bind="textInput: 1, checked: checked"
name="newsletter_subscribe"
id="newsletter_subscribe"
checked="checked" />
<label class="label" for="newsletter_subscribe">
<span data-bind="i18n: label"></span>
</label>
</div>
<!-- ko if: note_enabled -->
<span class="note" data-bind="html: note"></span>
<!-- /ko -->
</div>
<!-- /ko -->Now we will add app/code/Magelearn/NewsletterSubscribeAtCheckout/etc/frontend/di.xml file and modify Magento\Checkout\Block\Onepage\layoutProcessors to define display area for newsletter_subscribe with UI Component fields.
Add app/code/Magelearn/NewsletterSubscribeAtCheckout/etc/frontend/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\Checkout\Block\Onepage">
<arguments>
<argument name="layoutProcessors" xsi:type="array">
<item name="newsletterSubscribeConfig" xsi:type="object">Magelearn\NewsletterSubscribeAtCheckout\Model\Config\Source\NewsletterSubscribeLayoutProcessor</item>
</argument>
</arguments>
</type>
</config>Now as per defined in di.xml file add app/code/Magelearn/NewsletterSubscribeAtCheckout/Model/Config/Source/NewsletterSubscribeLayoutProcessor.php file.
<?php
namespace Magelearn\NewsletterSubscribeAtCheckout\Model\Config\Source;
use Magelearn\NewsletterSubscribeAtCheckout\Helper\Data as Helper;
/**
* Class NewsletterSubscribeLayoutProcessor
* @package Magelearn\NewsletterSubscribeAtCheckout\Model\Config\Source
*/
class NewsletterSubscribeLayoutProcessor
{
/**
* @var Helper
*/
private $helper;
/**
* NewsletterSubscribeLayoutProcessor constructor.
* @param Helper $helper
*/
public function __construct(
Helper $helper
) {
$this->helper = $helper;
}
/**
* {@inheritdoc}
*/
public function process($jsLayout)
{
$enabled = ($this->helper->getConfig('enabled')) ? 1 : 0;
$checked = ($this->helper->getConfig('checked')) ? 1 : 0;
$label = $this->helper->getConfig('label');
$note_enabled = ($this->helper->getConfig('note_enabled')) ? 1 : 0;
$note = $this->helper->getConfig('note');
$config = [
'customer-email' => [
'children' => [
'newsletter_subscribe' => [
'config' => [
'enabled' => $enabled,
'checked' => $checked,
'label' => $label,
'note_enabled' => $note_enabled,
'note' => $note
]
]
]
]
];
$updateLayout = [
'components' => [
'checkout' => [
'children' => [
'steps' => [
'children' => [
'billing-step' => [
'children' => [
'payment' => [
'children' => $config
]
]
],
'shipping-step' => [
'children' => [
'shippingAddress' => [
'children' => $config
]
]
]
]
]
]
]
]
];
// Merge updated layout with existing one
return array_merge_recursive($jsLayout, $updateLayout);
}
}Now we will add our helper file at app/code/Magelearn/NewsletterSubscribeAtCheckout/Helper/Data.php
<?php
namespace Magelearn\NewsletterSubscribeAtCheckout\Helper;
/**
* Class Data
* @package Magelearn\NewsletterSubscribeAtCheckout\Helper
*/
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
/**
* @var string
*/
private $tab = 'checkout';
/**
* Get module configuration values from core_config_data
*
* @param $setting
* @return mixed
*/
public function getConfig($setting)
{
return $this->scopeConfig->getValue(
$this->tab . '/magelearn_newslettersubscribeatcheckout/' . $setting,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
}
}Now we will pass this newsletter_subscribe checkbox value in `extension_attributes` array by overriding vendor/magento/module-checkout/view/frontend/web/js/model/shipping-save-processor/payload-extender.js
For that add app/code/Magelearn/NewsletterSubscribeAtCheckout/view/frontend/requirejs-config.js
var config = {
config: {
mixins: {
'Magento_Checkout/js/model/shipping-save-processor/payload-extender': {
'Magelearn_NewsletterSubscribeAtCheckout/js/model/shipping-save-processor/payload-extender-mixin': true
}
}
}
};Now add app/code/Magelearn/NewsletterSubscribeAtCheckout/view/frontend/web/js/model/shipping-save-processor/payload-extender-mixin.js
define([
'jquery',
'underscore',
'mage/utils/wrapper'
], function (
$,
_,
wrapper
) {
'use strict';
return function (payloadExtender) {
return wrapper.wrap(payloadExtender, function (originalPayloadExtender, payload) {
var newsletter = $('[name="newsletter_subscribe"]').prop("checked") == true ? 1 : 0;
payload = originalPayloadExtender(payload);
_.extend(payload.addressInformation,{
extension_attributes: {
'newsletter_subscribe': newsletter
}
});
return payload
});
};
});Now we will add etc/di.xml file and add plugin for Magento\Checkout\Model\ShippingInformationManagement to save newsletter_subscribe in quote object.
Before that we will add extension_attributes.xml file and define this new field.
Add app/code/Magelearn/NewsletterSubscribeAtCheckout/etc/extension_attributes.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Checkout\Api\Data\ShippingInformationInterface">
<attribute code="newsletter_subscribe" type="integer"/>
</extension_attributes>
</config>Now add app/code/Magelearn/NewsletterSubscribeAtCheckout/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\Checkout\Model\ShippingInformationManagement">
<plugin name="magelearn_newslettersubscriptionatcheckout_shippinginformationmanagement" type="Magelearn\NewsletterSubscribeAtCheckout\Model\Plugin\Checkout\ShippingInformationManagement" sortOrder="10"/>
</type>
</config>Now add our Plugin file at app/code/Magelearn/NewsletterSubscribeAtCheckout/Model/Plugin/Checkout/ShippingInformationManagement.php
<?php
namespace Magelearn\NewsletterSubscribeAtCheckout\Model\Plugin\Checkout;
use Magento\Quote\Model\QuoteRepository as QuoteRepository;
use Magento\Checkout\Api\Data\ShippingInformationInterface as ShippingInformationInterface;
use Magelearn\NewsletterSubscribeAtCheckout\Helper\Data as Helper;
/**
* Class ShippingInformationManagement
* @package Magelearn\NewsletterSubscribeAtCheckout\Model\Plugin\Checkout
*/
class ShippingInformationManagement
{
/**
* @var QuoteRepository
*/
private $quoteRepository;
/**
* @var ShippingInformationInterface
*/
private $extensionFactory;
/**
* @var Helper
*/
private $helper;
/**
* ShippingInformationManagement constructor.
* @param QuoteRepository $quoteRepository
* @param Helper $helper
* @param ShippingInformationInterface $extensionFactory
*/
public function __construct(
QuoteRepository $quoteRepository,
Helper $helper,
ShippingInformationInterface $extensionFactory
) {
$this->quoteRepository = $quoteRepository;
$this->helper = $helper;
$this->extensionFactory = $extensionFactory;
}
/**
* @param \Magento\Checkout\Model\ShippingInformationManagement $subject
* @param $cartId
* @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
*/
public function beforeSaveAddressInformation(
\Magento\Checkout\Model\ShippingInformationManagement $subject,
$cartId,
\Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
) {
// Check if feature is enabled
if ($this->helper->getConfig('enabled')) {
$extAttributes = $addressInformation->getExtensionAttributes();
$newsletterSubscribe = $extAttributes->getNewsletterSubscribe() ? 1 : 0;
$quote = $this->quoteRepository->getActive($cartId);
$quote->setNewsletterSubscribe($newsletterSubscribe);
}
}
}At last we called event `sales_model_service_quote_submit_success` to successfully add customer email address to newsletter subscriber.
Add app/code/Magelearn/NewsletterSubscribeAtCheckout/etc/events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_model_service_quote_submit_success">
<observer name="magelearn_newslettersubscribeatcheckout_sales_model_service_quote_submit_success" instance="Magelearn\NewsletterSubscribeAtCheckout\Observer\EventSalesModelServiceQuoteSubmitSuccess" />
</event>
</config>Now add our observer file at app/code/Magelearn/NewsletterSubscribeAtCheckout/Observer/EventSalesModelServiceQuoteSubmitSuccess.php
<?php
namespace Magelearn\NewsletterSubscribeAtCheckout\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Newsletter\Model\Subscriber as Subscriber;
use Magelearn\NewsletterSubscribeAtCheckout\Helper\Data as Helper;
/**
* Class EventSalesModelServiceQuoteSubmitSuccess
* @package Magelearn\NewsletterSubscribeAtCheckout\Observer
*/
class EventSalesModelServiceQuoteSubmitSuccess implements ObserverInterface
{
/**
* @var Subscriber
*/
private $subscriber;
/**
* @var Helper
*/
private $helper;
/**
* @var \Psr\Log\LoggerInterface
*/
private $logger;
/**
* EventSalesModelServiceQuoteSubmitSuccess constructor.
* @param Subscriber $subscriber
* @param Helper $helper
* @param \Psr\Log\LoggerInterface $logger
*/
public function __construct(
Subscriber $subscriber,
Helper $helper,
\Psr\Log\LoggerInterface $logger
) {
$this->subscriber = $subscriber;
$this->helper = $helper;
$this->logger = $logger;
}
/**
* Subscribe to newsletters if customer checked the checkbox
*
* @param \Magento\Framework\Event\Observer $observer
* @return boolean|$this
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
// Check if feature is disabled
if (!$this->helper->getConfig('enabled')) {
return;
}
$quote = $observer->getQuote();
// Get newsletter subscription flag from quote
if ($quote->getNewsletterSubscribe()) {
try {
$email = $quote->getCustomerEmail();
$this->subscriber->subscribe($email);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
}
return $this;
}
}

0 Comments On "Add Newsletter Subscriber at checkout page Magento2"