5

I'm using magento 2.2 and I want to add name field for newsletter module, so there has to be input box in front-end, and also it needs to show in backend, how to achieve this? There is a lot of posts about this, but they all are on older magento versions. So can someone explain how to achieve this?

1
10

I have created module for your requirement and firstname & lastname

Create registeration file.

app\code\Hm\Newsletters - registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Hm_Newsletters',
    __DIR__
);

app\code\Hm\Newsletters\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="Hm_Newsletters" setup_version="1.0.0">
            <sequence>
                <module name="Magento_Newsletter" />
            </sequence>
        </module>
    </config>

Override a newsletter subscriber action using a plungin

app\code\Hm\Newsletters\etc - 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="hm_newsletter_model_subscriber" type="\Hm\Newsletters\Plugin\Subscriber" sortOrder="1" />
  </type>
</config>

Replace a custom newsletter form with default form with layout

app\code\Hm\Newsletters\view\frontend\layout -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="Hm_Newsletters::subscribe.phtml"/>
    </referenceContainer>
        <referenceBlock name="form.subscribe" remove="true" />
    </body>
</page>

Add two fields in newsletter form

app\code\Hm\Newsletters\view\frontend\templates - subscribe.phtml

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

// @codingStandardsIgnoreFile

/** @var \Magento\Newsletter\Block\Subscribe $block */

?>
<div class="block newsletter">
    <div class="title"><strong><?php /* @escapeNotVerified */ echo __('Newsletter') ?></strong></div>
    <div class="content">
        <form class="form subscribe" novalidate
              action="<?php echo $block->escapeUrl($block->getFormActionUrl()) ?>"
              method="post"
              data-mage-init='{"validation": {"errorClass": "mage-error"}}'
              id="newsletter-validate-detail">
            <div class="field firstname">
                <label class="label" for="firstname"><span><?php echo $block->escapeHtml(__('Vorname')) ?></span></label>
                <div class="control">
                    <input name="firstname" type="text" id="firstname" placeholder="<?php echo $block->escapeHtml(__('Vorname')) ?>" data-validate="{required:true}"/>
                </div>
            </div>
            <div class="field lastname">
                <label class="label" for="lastname"><span><?php echo $block->escapeHtml(__('Nachname')) ?></span></label>
                <div class="control">
                    <input name="lastname" type="text" id="lastname" placeholder="<?php echo $block->escapeHtml(__('Nachname')) ?>" data-validate="{required:true}"/>
                </div>
            </div>
            <div class="field newsletter">
                <label class="label" for="newsletter"><span><?php echo $block->escapeHtml(__('Mailadresse:')) ?></span></label>
                <div class="control">
                    <input name="email" type="email" id="newsletter" placeholder="<?php echo $block->escapeHtml(__('Mailadresse')) ?>" data-validate="{required:true, 'validate-email':true}"/>
                </div>
            </div>
            <div class="actions">
                <button class="action subscribe primary" title="<?php echo $block->escapeHtml(__('Absenden')) ?>" type="submit">
                    <span><?php echo $block->escapeHtml(__('Absenden')) ?></span>
                </button>
            </div>
        </form>
    </div>
</div>

Create a plugin for newsletter subscriber action

app\code\Hm\Newsletters\Plugin - Subscriber.php

<?php
namespace Hm\Newsletters\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('firstname')) { 

            $firstname = $this->request->getPost('firstname');
            $lastname = $this->request->getPost('lastname');

            $subject->setCFirstname($firstname);
            $subject->setCLastname($lastname);
            $result = $proceed($email);

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

Create database table fields using installSchema

app\code\Hm\Newsletters\Setup - InstallSchema.php

<?php

namespace Hm\Newsletters\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\DB\Ddl\Table;

class InstallSchema implements InstallSchemaInterface
{
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) {
        $setup->startSetup();

        $table = $setup->getTable('newsletter_subscriber');

        $setup->getConnection()->addColumn(
            $table,
            'c_firstname',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'First Name'
            ]
        );
        $setup->getConnection()->addColumn(
            $table,
            'c_lastname',
            [
                'type' => Table::TYPE_TEXT,
                'nullable' => true,
                'comment' => 'Last Name'
            ]
        );
        $setup->endSetup();
    }
}

Create Admin grid columns using newsletter_subscriber_block

app\code\Hm\Newsletters\view\adminhtml\layout - 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.newsletter.subscriber.container">
            <block class="Magento\Newsletter\Block\Adminhtml\Subscriber\Grid" name="adminhtml.newslettrer.subscriber.grid" as="grid">
                <arguments>
                    <argument name="id" xsi:type="string">subscriberGrid</argument>
                    <argument name="dataSource" xsi:type="object">Magento\Newsletter\Model\ResourceModel\Subscriber\Grid\Collection</argument>
                    <argument name="default_sort" xsi:type="string">subscriber_id</argument>
                    <argument name="default_dir" xsi:type="string">desc</argument>
                    <argument name="use_ajax" xsi:type="string">1</argument>
                </arguments>
                <block class="Magento\Backend\Block\Widget\Grid\Massaction" name="adminhtml.newslettrer.subscriber.grid.massaction" as="grid.massaction">
                    <arguments>
                        <argument name="massaction_id_field" xsi:type="string">subscriber_id</argument>
                        <argument name="form_field_name" xsi:type="string">subscriber</argument>
                        <argument name="use_select_all" xsi:type="string">1</argument>
                        <argument name="options" xsi:type="array">
                            <item name="unsubscribe" xsi:type="array">
                                <item name="label" xsi:type="string" translate="true">Unsubscribe</item>
                                <item name="url" xsi:type="string">*/*/massUnsubscribe</item>
                            </item>
                            <item name="delete" xsi:type="array">
                                <item name="label" xsi:type="string" translate="true">Delete</item>
                                <item name="url" xsi:type="string">*/*/massDelete</item>
                            </item>
                        </argument>
                    </arguments>
                </block>
                <block class="Magento\Backend\Block\Widget\Grid\Export" name="adminhtml.newslettrer.subscriber.grid.export" as="grid.export">
                    <arguments>
                        <argument name="exportTypes" xsi:type="array">
                            <item name="csv" xsi:type="array">
                                <item name="urlPath" xsi:type="string">*/*/exportCsv</item>
                                <item name="label" xsi:type="string" translate="true">CSV</item>
                            </item>
                            <item name="excel" xsi:type="array">
                                <item name="urlPath" xsi:type="string">*/*/exportXml</item>
                                <item name="label" xsi:type="string" translate="true">Excel XML</item>
                            </item>
                        </argument>
                    </arguments>
                </block>
                <block class="Magento\Backend\Block\Widget\Grid\ColumnSet" name="adminhtml.newslettrer.subscriber.grid.columnSet" as="grid.columnSet">
                    <arguments>
                        <argument name="id" xsi:type="string">problemGrid</argument>
                    </arguments>
                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="subscriber_id">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">ID</argument>
                            <argument name="index" xsi:type="string">subscriber_id</argument>
                            <argument name="header_css_class" xsi:type="string">col-id</argument>
                            <argument name="column_css_class" xsi:type="string">col-id</argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="email">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Email</argument>
                            <argument name="index" xsi:type="string">subscriber_email</argument>
                            <argument name="header_css_class" xsi:type="string">col-email</argument>
                            <argument name="column_css_class" xsi:type="string">ccol-email</argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="type">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Type</argument>
                            <argument name="index" xsi:type="string">type</argument>
                            <argument name="type" xsi:type="string">options</argument>
                            <argument name="options" xsi:type="array">
                                <item name="guest" xsi:type="array">
                                    <item name="value" xsi:type="string">1</item>
                                    <item name="label" xsi:type="string" translate="true">Guest</item>
                                </item>
                                <item name="customer" xsi:type="array">
                                    <item name="value" xsi:type="string">2</item>
                                    <item name="label" xsi:type="string" translate="true">Customer</item>
                                </item>
                            </argument>
                            <argument name="header_css_class" xsi:type="string">col-type</argument>
                            <argument name="column_css_class" xsi:type="string">col-type</argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="firstname">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Customer First Name</argument>
                            <argument name="index" xsi:type="string">firstname</argument>
                            <argument name="renderer" xsi:type="string">Hm\Newsletters\Block\Newsletter\Adminhtml\Template\Grid\Renderer\Customerfirstname</argument>
                            <argument name="default" xsi:type="string">----</argument>
                            <argument name="header_css_class" xsi:type="string">col-first-name</argument>
                            <argument name="column_css_class" xsi:type="string">col-first-name</argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="lastname">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Customer Last Name</argument>
                            <argument name="index" xsi:type="string">lastname</argument>
                            <argument name="renderer" xsi:type="string">Hm\Newsletters\Block\Newsletter\Adminhtml\Template\Grid\Renderer\Customerlastname</argument>
                            <argument name="default" xsi:type="string">----</argument>
                            <argument name="header_css_class" xsi:type="string">col-last-name</argument>
                            <argument name="column_css_class" xsi:type="string">col-last-name</argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column" as="status">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Status</argument>
                            <argument name="index" xsi:type="string">subscriber_status</argument>
                            <argument name="type" xsi:type="string">options</argument>
                            <argument name="options" xsi:type="array">
                                <item name="status_not_active" xsi:type="array">
                                    <item name="value" xsi:type="string">2</item>
                                    <item name="label" xsi:type="string" translate="true">Not Activated</item>
                                </item>
                                <item name="status_subscribed" xsi:type="array">
                                    <item name="value" xsi:type="string">1</item>
                                    <item name="label" xsi:type="string" translate="true">Subscribed</item>
                                </item>
                                <item name="status_unsubscribed" xsi:type="array">
                                    <item name="value" xsi:type="string">3</item>
                                    <item name="label" xsi:type="string" translate="true">Unsubscribed</item>
                                </item>
                                <item name="status_unconfirmed" xsi:type="array">
                                    <item name="value" xsi:type="string">4</item>
                                    <item name="label" xsi:type="string" translate="true">Unconfirmed</item>
                                </item>
                            </argument>
                            <argument name="header_css_class" xsi:type="string">col-status</argument>
                            <argument name="column_css_class" xsi:type="string">col-status</argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column\Multistore" as="website">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Web Site</argument>
                            <argument name="index" xsi:type="string">website_id</argument>
                            <argument name="type" xsi:type="string">options</argument>
                            <argument name="options" xsi:type="options" model="Magento\Config\Model\Config\Source\Website\OptionHash"/>
                            <argument name="header_css_class" xsi:type="string">col-website</argument>
                            <argument name="column_css_class" xsi:type="string">col-website</argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column\Multistore" as="group">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Store</argument>
                            <argument name="index" xsi:type="string">group_id</argument>
                            <argument name="type" xsi:type="string">options</argument>
                            <argument name="options" xsi:type="options" model="Magento\Newsletter\Block\Subscribe\Grid\Options\GroupOptionHash"/>
                            <argument name="header_css_class" xsi:type="string">col-store</argument>
                            <argument name="column_css_class" xsi:type="string">col-store</argument>
                        </arguments>
                    </block>
                    <block class="Magento\Backend\Block\Widget\Grid\Column\Multistore" as="store">
                        <arguments>
                            <argument name="header" xsi:type="string" translate="true">Store View</argument>
                            <argument name="index" xsi:type="string">store_id</argument>
                            <argument name="type" xsi:type="string">options</argument>
                            <argument name="options" xsi:type="options" model="Magento\Newsletter\Block\Subscribe\Grid\Options\StoreOptionHash"/>
                            <argument name="header_css_class" xsi:type="string">col-store-view</argument>
                            <argument name="column_css_class" xsi:type="string">col-store-view</argument>
                        </arguments>
                    </block>
                </block>
            </block>
        </referenceBlock>
    </body>
</page>

Add renderer to display firstname and lastname if user not logged in

app\code\Hm\Newsletters\Block\Newsletter\Adminhtml\Template\Grid\Renderer - Customerfirstname.php

<?php
namespace Hm\Newsletters\Block\Newsletter\Adminhtml\Template\Grid\Renderer;
use Magento\Framework\DataObject;
class Customerfirstname extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
{
    public function render(\Magento\Framework\DataObject $row)
    {
        if($row->getData('type')==1){
            return ($row->getData('c_firstname')!=''?$row->getData('c_firstname'):'----');
        }else{
            return ($row->getData('firstname')!=''?$row->getData('firstname'):'----');
        }
    }
}

app\code\Hm\Newsletters\Block\Newsletter\Adminhtml\Template\Grid\Renderer - Customerlastname.php

<?php
namespace Hm\Newsletters\Block\Newsletter\Adminhtml\Template\Grid\Renderer;
use Magento\Framework\DataObject;
class Customerlastname extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
{
    public function render(\Magento\Framework\DataObject $row)
    {
        if($row->getData('type')==1){
            return ($row->getData('c_lastname')!=''?$row->getData('c_lastname'):'----');
        }else{
            return ($row->getData('lastname')!=''?$row->getData('lastname'):'----');
        }
    }
}

Hope this will work for you......

2
  • why we need to create Firstname and Lastname in database field? is it suppose to add record directly to the newsletter subscriber table from magento iteself?
    – Paul Fan
    Mar 4 '20 at 23:20
  • I am sorry, I found out subscriber table has no field for firstname and lastname, firstname and lastname is base on the customer_id, if customer_id is 0, then they are the guest.
    – Paul Fan
    Mar 5 '20 at 0:01

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