4

I have this module for add newsletter subscription to checkout page in a Magento 2 project. I have added a checkbox field by following code:

app/code/MyNamespace/MyModule/Plugin/Checkout/Model/Checkout/LayoutProcessor.php

namespace Muaw\Subscription\Plugin\Checkout\Model\Checkout;


class LayoutProcessor
{
    /**
     * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */
    public function afterProcess(
        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
        array  $jsLayout
    ) {
        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children']['subscribe'] = [
            'component' => 'Magento_Ui/js/form/element/abstract',
            'config' => [
                'customScope' => 'shippingAddress',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/checkbox',
                'options' => [],
                'id' => 'subscribe'
            ],
            'dataScope' => 'shippingAddress.subscribe',
            'label' => 'Opt-In to our news letter',
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' => [],
            'sortOrder' => 250,
            'id' => 'subscribe',
            'value'=>'subscription'
        ];

        return $jsLayout;
    }
}

app/code/MyNamespace/MyModule/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\Checkout\LayoutProcessor">
            <plugin name="subscription" type="Muaw\Subscription\Plugin\Checkout\Model\Checkout\LayoutProcessor" sortOrder="100"/>
        </type>
    </config>

Rendered output:

Output

My problem is when I try to get the order data it does not added into post data

Post data:

Post data

Did I do anything wrong? Is there any other way to register this field and get post data? Help is appreciated.

5

You have to add the below files.

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\Checkout\Model\ShippingInformationManagement">
        <plugin name="save-in-quote" type="Vendor\Module\Model\Checkout\ShippingInformationManagementPlugin" sortOrder="10"/>
    </type>
</config>

Vendor/Module/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="subscribe" type="string"/>
    </extension_attributes>
</config>

Vendor/Module/Model/Checkout/ShippingInformationManagementPlugin.php

<?php

namespace Vendor\Module\Model\Checkout;

class ShippingInformationManagementPlugin
{

    protected $quoteRepository;

    public function __construct(
        \Magento\Quote\Model\QuoteRepository $quoteRepository
    ) {
        $this->quoteRepository = $quoteRepository;
    }

    /**
     * @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
    ) {
        $extAttributes = $addressInformation->getExtensionAttributes();
        $subscribe = $extAttributes->getSubscribe();
        $quote = $this->quoteRepository->getActive($cartId);
        //$quote->setSubscribe($subscribe );
    }
}

Vendor/Module/view/frontend/requirejs-config.js

var config = {
    "map": {
        "*": {
            'Magento_Checkout/js/model/shipping-save-processor/default': 'Vendor_Module/js/model/shipping-save-processor/default'
        }
    }
};

Vendor/Module/view/frontend/web/js/model/shipping-save-processor/default.js

copy and paste the Magento_Checkout/js/model/shipping-save-processor/default.js file above given path and modified payload method as given below.

payload = {
                    addressInformation: {
                        shipping_address: quote.shippingAddress(),
                        billing_address: quote.billingAddress(),
                        shipping_method_code: quote.shippingMethod().method_code,
                        shipping_carrier_code: quote.shippingMethod().carrier_code,
                        extension_attributes:{
                            account_no: $('[name="account_no"]').val(),
                            subscribe: $('[name="subscribe"]').val()
                        }

                    }

                };

see my below pic it's came you can save it on quote table as given shippinginformationmanagementplufin.php file method.

enter image description here

feel free to ask if you have any queries.

  • I have added above files and it gives me an error: Uncaught Error: Call to a member function getSubscribe() on null in /blahblah/app/code/Vendor/Module/Model/Checkout/ShippingInformationManagementPlugin.php:35 This is line 35: $subscribe = $extAttributes->getSubscribe(); – Janaka Dombawela May 4 '16 at 10:08
  • @JanakaDombawela have you added Vendor/Module/etc/extension_attributes.xml xml , Vendor/Module/view/frontend/requirejs-config.js and Vendor/Module/view/frontend/web/js/model/shipping-save-processor/default.js file? – Bojjaiah May 4 '16 at 10:16
  • yes they are in the correct path. – Janaka Dombawela May 4 '16 at 10:18
  • @JanakaDombawela, then execute php bin/magento cache:clean, php bin/magento cache:flush and php bin/magento setup:upgrade commands in your CLI and try again – Bojjaiah May 4 '16 at 10:20
  • still same error. :( :( – Janaka Dombawela May 4 '16 at 10:25
1

If you check the return type hint for \Magento\Checkout\Api\Data\ShippingInformationInterface::getExtensionAttributes() it explicitly states that the return value might be null. According to other examples in the core, the "right thing to do" seems to be to inject an ShippingInformationExtensionFactory.

Then use something like

$extAttributes = $addressInformation->getExtensionAttributes() ?: $this->extensionAttributesFactory->create();
-1

I used Bojjaiah's solution but I had to change a few things to make it work with Magento 2.2.3.

default.js, change extension_attributes to:

extension_attributes: {
                        email: $('#customer-email').val(),
                        subscribe: Boolean($('[name="subscribe"]').attr('checked'))
                    }

In default.js you also need to add jQuery to the define or else you get an error on $.

If you happen to use Magento 2.2.3. delete the following line:

 payloadExtender(payload);

In the ShippingInformationManagementPlugin.php change the beforeSafeAddressInformation function to this:

    /**
 * @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
) {
    $extAttributes = $addressInformation->getExtensionAttributes();
    $email = $extAttributes->getEmail();
    $subscribe = $extAttributes->getSubscribe();

    if($subscribe === true){
        $subscriber = $this->subscriberFactory->create()->loadByEmail($email);
        if ($subscriber->getId() && $subscriber->getSubscriberStatus() == \Magento\Newsletter\Model\Subscriber::STATUS_SUBSCRIBED) {
        } else {
            $status = $this->subscriberFactory->create()->subscribe($email);
        }
    }
}

extension_attributes.xml, change this file to:

<?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="email" type="string" />
    <attribute code="subscribe" type="boolean" />
</extension_attributes>
</config>

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.