Magento2 – How to Save Input Value to Database from Custom Newsletter

databasemagento2

How I can add these fields in the table, display it on the form, save values in the table.

Vendor\Module\Plugin\Newsletter\Subscriber.php

<?php
namespace Vendor\Module\Plugin\Newsletter;

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('name')) {
      $name = $this->request->getPost('name');
      // $lastname = $this->request->getPost('lastname');
      // $gender = $this->request->getPost('gender');

      $subject->setName($name);
      // $subject->setCLastname($lastname);
      // $subject->setGender($gender);
      $result = $proceed($email);
      try {
        $subject->save();

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

    }
    return $result;
  }
}

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="varchar" name="subscriber_name"  nullable="true" comment="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_newsletter_model_subscriber" type="Vendor\Module\Plugin\Newsletter\Subscriber" sortOrder="1"/>
  </type>
</config>

Best Answer

You need to add field in newsletter subscriber form

app\code\Vendor\Module\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="Vendor_Module::subscribe.phtml"/>
    </referenceContainer>
        <referenceBlock name="form.subscribe" remove="true" />
    </body>
</page>

app\code\Vendor\Module\view\frontend\templates\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>

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="vendor_module_model_subscriber" type="\Vendor\Module\Plugin\Subscriber" sortOrder="1" />
  </type>
</config>

app\code\Vendor\Module\Plugin\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;
    }
}