Magento – How to create another customer form to update custom fields in magento 2

custom-fieldcustom-optionsmagento-2.1module

I have added a link in customer dashboard links (in the left side) and also I have added 2 custom fields to customer and I'm going to create a form which can update those custom fields in the tab that I've created in dashboard in the frontend. How could I connect customer update query or method in my form submition?

Here is my code:

Magenpoint -> Mypoint -> Controller -> Customer -> Index.php

<?php

namespace Magenpoint\Mypoint\Controller\Customer;

use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;

class Index extends \Magento\Framework\App\Action\Action
{
protected $resultPageFactory;

protected $session;

public function __construct(
    \Magento\Framework\App\Action\Context $context,
    \Magento\Customer\Model\Session $customerSession,
    PageFactory $resultPageFactory
)
{
    $this->session = $customerSession;
    parent::__construct($context);
    $this->resultPageFactory = $resultPageFactory;
}
public function execute()
{
    if (!$this->session->isLoggedIn())
    {
        $resultRedirect = $this->resultRedirectFactory->create();
        $resultRedirect->setPath('customer/account/login');
        return $resultRedirect;
    }
    else
    {
        $resultPage = $this->resultPageFactory->create();
        $resultPage->getConfig()->getTitle()->set(__('My point'));
        return $resultPage;
    }
}

}

Magenpoint -> Mypoint -> Controller -> Customer -> SavePost.php

<?php
namespace Magenpoint\Mypoint\Controller\Customer;

use Magento\Customer\Model\AuthenticationInterface;
use Magento\Customer\Model\Customer\Mapper;
use Magento\Customer\Model\EmailNotificationInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Data\Form\FormKey\Validator;
use Magento\Customer\Api\AccountManagementInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\CustomerExtractor;
use Magento\Customer\Model\Session;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\InvalidEmailOrPasswordException;
use Magento\Framework\Exception\State\UserLockedException;

class savePost extends \Magento\Customer\Controller\AbstractAccount
{
/**
 * Form code for data extractor
 */
const FORM_DATA_EXTRACTOR_CODE = 'customer_account_edit';

/**
 * @var AccountManagementInterface
 */
protected $customerAccountManagement;

/**
 * @var CustomerRepositoryInterface
 */
protected $customerRepository;

/**
 * @var Validator
 */
protected $formKeyValidator;

/**
 * @var CustomerExtractor
 */
protected $customerExtractor;

/**
 * @var Session
 */
protected $session;

/** @var EmailNotificationInterface */
private $emailNotification;

/**
 * @var ScopeConfigInterface
 */
private $scopeConfig;

/**
 * @var AuthenticationInterface
 */
private $authentication;

/**
 * @var Mapper
 */
private $customerMapper;

/**
 * @param Context $context
 * @param Session $customerSession
 * @param AccountManagementInterface $customerAccountManagement
 * @param CustomerRepositoryInterface $customerRepository
 * @param Validator $formKeyValidator
 * @param CustomerExtractor $customerExtractor
 */
public function __construct(
    Context $context,
    Session $customerSession,
    AccountManagementInterface $customerAccountManagement,
    CustomerRepositoryInterface $customerRepository,
    Validator $formKeyValidator,
    CustomerExtractor $customerExtractor
) {
    parent::__construct($context);
    $this->session = $customerSession;
    $this->customerAccountManagement = $customerAccountManagement;
    $this->customerRepository = $customerRepository;
    $this->formKeyValidator = $formKeyValidator;
    $this->customerExtractor = $customerExtractor;
}



/**
 * Change customer email or password action
 *
 * @return \Magento\Framework\Controller\Result\Redirect
 */
public function execute()
{
    /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
    $resultRedirect = $this->resultRedirectFactory->create();

    if ($this->getRequest()->isPost()) {
        $currentCustomerDataObject = $this->getCustomerDataObject($this->session->getCustomerId());

        $currentCustomerDataObject->setData('national_code','11111');
        $currentCustomerDataObject->setData('mobile','22222');

        try {
            $this->customerRepository->save($customerCandidateDataObject);

            $this->messageManager->addSuccess(__('You saved the account information.'));
            return $resultRedirect->setPath('customer/account');
        }catch (UserLockedException $e) {
            $message = __(
                'The account is locked. Please wait and try again or contact %1.',
                $this->getScopeConfig()->getValue('contact/email/recipient_email')
            );
            $this->session->logout();
            $this->session->start();
            $this->messageManager->addError($message);
            return $resultRedirect->setPath('customer/account/login');
        } catch (InputException $e) {
            $this->messageManager->addError($e->getMessage());
            foreach ($e->getErrors() as $error) {
                $this->messageManager->addError($error->getMessage());
            }
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $this->messageManager->addError($e->getMessage());
        } catch (\Exception $e) {
            $this->messageManager->addException($e, __('We can\'t save the customer.'));
        }

        $this->session->setCustomerFormData($this->getRequest()->getPostValue());
    }

    return $resultRedirect->setPath('*/*/edit');
}

/**
 * Get scope config
 *
 * @return ScopeConfigInterface
 */
private function getScopeConfig()
{
    if (!($this->scopeConfig instanceof \Magento\Framework\App\Config\ScopeConfigInterface)) {
        return ObjectManager::getInstance()->get(
            \Magento\Framework\App\Config\ScopeConfigInterface::class
        );
    } else {
        return $this->scopeConfig;
    }
}


/**
 * Get customer data object
 *
 * @param int $customerId
 *
 * @return \Magento\Customer\Api\Data\CustomerInterface
 */
private function getCustomerDataObject($customerId)
{
    return $this->customerRepository->getById($customerId);
}

}

Magenpoint -> Mypoint -> etc -> frontend -> routes.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
    <route id="mypoint" frontName="mypoint">
        <module name="Magenpoint_Mypoint" />
    </route>
</router>

Magenpoint -> Mypoint -> 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="Magenpoint_Mypoint" setup_version="0.0.9">
    <sequence>
        <module name="Magento_Customer"/>
    </sequence>
</module>

Magenpoint -> Mypoint -> view -> frontend -> layout -> customer_account.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="customer_account_navigation">
        <block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-mypoint">
            <arguments>
                <argument name="path" xsi:type="string">mypoint/customer/index</argument>
                <argument name="label" xsi:type="string">My Points</argument>
            </arguments>
        </block>
    </referenceBlock>
</body>

Magenpoint -> Mypoint -> view -> frontend -> layout -> mypoint_customer_index.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<update handle="customer_account"/>
<body>
    <referenceBlock name="page.main.title">
        <action method="setPageTitle">
            <argument translate="true" name="title" xsi:type="string">My Points</argument>
        </action>
    </referenceBlock>
    <referenceContainer name="content">
        <block class="Magento\Framework\View\Element\Template" name="my_point" template="Magenpoint_Mypoint::mypoint.phtml">
        </block>
    </referenceContainer>
</body>

Magenpoint -> Mypoint -> view -> frontend -> templates -> mypoint.phtml

<?php
echo "My Points:<br>";

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
$customerData = $customerSession->getCustomer()->getData();
echo "<br/>";

if ($customerSession->isLoggedIn()) {
$customerSession->getCustomerId();  // get Customer Id
$customerSession->getCustomerGroupId();
$customerSession->getCustomer();
$customerSession->getCustomerData();
?>
<form class="form form-edit-account" action="<?php echo $block->getUrl('mypoint/customer/savePost') ?>" method="post" id="form-validate" enctype="multipart/form-data" data-hasrequired="<?php echo __('* Required Fields') ?>" autocomplete="off">
<fieldset class="fieldset info" data-hasrequired="<?php echo __('* Required Fields') ?>">
    <legend class="legend"><span><?php echo __('More Info.') ?></span></legend><br>
    <?php
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $customerSession = $objectManager->create('Magento\Customer\Model\Session');
    $customerData = $customerSession->getCustomer()->getData();
    $url = 'http://'.$_SERVER['SERVER_NAME'].'/magento-v1';
    $national_code = isset($customerData["national_code"])? $customerData["national_code"]:'';
    ?>
    <div class="field national_code required">
        <label for="national_code" class="label"><span><?php /* @escapeNotVerified */ echo __('national code') ?></span></label>
        <div class="control">
            <input type="text" name="national_code" value="<?php echo $national_code; ?>" id="national_code" title="<?php /* @escapeNotVerified */ echo __('national code') ?>" class="input-text" data-validate="{required:true}" autocomplete="off">
        </div>
    </div>

    <?php
    $mobile = isset($customerData["mobile"])? $customerData["mobile"]:'';
    ?>

    <div class="field mobile required">
        <label for="mobile" class="label"><span><?php /* @escapeNotVerified */ echo __('mobile') ?></span></label>
        <div class="control">
            <input type="text" name="mobile" value="<?php echo $mobile; ?>" id="mobile" title="<?php /* @escapeNotVerified */ echo __('mobile') ?>" class="input-text" data-validate="{required:true}" autocomplete="off">
        </div>
    </div>

</fieldset>

<div class="actions-toolbar">
    <div class="primary">
        <button type="submit" class="action save primary" title="<?php /* @escapeNotVerified */ echo __('Save') ?>"><span><?php /* @escapeNotVerified */ echo __('Save') ?></span></button>
    </div>
    <div class="secondary">
        <a class="action back" href="<?php echo $block->escapeUrl($block->getBackUrl()) ?>"><span><?php /* @escapeNotVerified */ echo __('Go back') ?></span></a>
    </div>
</div>
</form>

<?php
}
?>

Magenpoint -> Mypoint -> registration.php

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

Any suggestion?

Best Answer

As you have form then you should have a form post Action.

On your post Action Url, you should you load current customer model by its id.

So, you Action file name like

app/code/[Vendorname]/[ModuleName]/Controller/Index/savePost.php

controller

<?php
namespace[Vendorname]\[ModuleName]\Controller\Index;

use Magento\Customer\Model\AuthenticationInterface;
use Magento\Customer\Model\Customer\Mapper;
use Magento\Customer\Model\EmailNotificationInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Data\Form\FormKey\Validator;
use Magento\Customer\Api\AccountManagementInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\CustomerExtractor;
use Magento\Customer\Model\Session;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\InvalidEmailOrPasswordException;
use Magento\Framework\Exception\State\UserLockedException;

/**
 * Class EditPost
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class savePost extends \Magento\Customer\Controller\AbstractAccount
{
    /**
     * Form code for data extractor
     */
    const FORM_DATA_EXTRACTOR_CODE = 'customer_account_edit';

    /**
     * @var AccountManagementInterface
     */
    protected $customerAccountManagement;

    /**
     * @var CustomerRepositoryInterface
     */
    protected $customerRepository;

    /**
     * @var Validator
     */
    protected $formKeyValidator;

    /**
     * @var CustomerExtractor
     */
    protected $customerExtractor;

    /**
     * @var Session
     */
    protected $session;

    /** @var EmailNotificationInterface */
    private $emailNotification;

    /**
     * @var ScopeConfigInterface
     */
    private $scopeConfig;

    /**
     * @var AuthenticationInterface
     */
    private $authentication;

    /**
     * @var Mapper
     */
    private $customerMapper;

    /**
     * @param Context $context
     * @param Session $customerSession
     * @param AccountManagementInterface $customerAccountManagement
     * @param CustomerRepositoryInterface $customerRepository
     * @param Validator $formKeyValidator
     * @param CustomerExtractor $customerExtractor
     */
    public function __construct(
        Context $context,
        Session $customerSession,
        AccountManagementInterface $customerAccountManagement,
        CustomerRepositoryInterface $customerRepository,
        Validator $formKeyValidator,
        CustomerExtractor $customerExtractor
    ) {
        parent::__construct($context);
        $this->session = $customerSession;
        $this->customerAccountManagement = $customerAccountManagement;
        $this->customerRepository = $customerRepository;
        $this->formKeyValidator = $formKeyValidator;
        $this->customerExtractor = $customerExtractor;
    }



    /**
     * Change customer email or password action
     *
     * @return \Magento\Framework\Controller\Result\Redirect
     */
    public function execute()
    {
        /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
        $resultRedirect = $this->resultRedirectFactory->create();

        if ($this->getRequest()->isPost()) {
            $currentCustomerDataObject = $this->getCustomerDataObject($this->session->getCustomerId());

            $currentCustomerDataObject->setData('Your_AtrributeCode1','Val1');
            $currentCustomerDataObject->setData('Your_AtrributeCode2','Val2');

            try {
                $this->customerRepository->save($customerCandidateDataObject);

                $this->messageManager->addSuccess(__('You saved the account information.'));
                return $resultRedirect->setPath('customer/account');
            }catch (UserLockedException $e) {
                $message = __(
                    'The account is locked. Please wait and try again or contact %1.',
                    $this->getScopeConfig()->getValue('contact/email/recipient_email')
                );
                $this->session->logout();
                $this->session->start();
                $this->messageManager->addError($message);
                return $resultRedirect->setPath('customer/account/login');
            } catch (InputException $e) {
                $this->messageManager->addError($e->getMessage());
                foreach ($e->getErrors() as $error) {
                    $this->messageManager->addError($error->getMessage());
                }
            } catch (\Magento\Framework\Exception\LocalizedException $e) {
                $this->messageManager->addError($e->getMessage());
            } catch (\Exception $e) {
                $this->messageManager->addException($e, __('We can\'t save the customer.'));
            }

            $this->session->setCustomerFormData($this->getRequest()->getPostValue());
        }

        return $resultRedirect->setPath('*/*/edit');
    }

    /**
     * Get scope config
     *
     * @return ScopeConfigInterface
     */
    private function getScopeConfig()
    {
        if (!($this->scopeConfig instanceof \Magento\Framework\App\Config\ScopeConfigInterface)) {
            return ObjectManager::getInstance()->get(
                \Magento\Framework\App\Config\ScopeConfigInterface::class
            );
        } else {
            return $this->scopeConfig;
        }
    }


    /**
     * Get customer data object
     *
     * @param int $customerId
     *
     * @return \Magento\Customer\Api\Data\CustomerInterface
     */
    private function getCustomerDataObject($customerId)
    {
        return $this->customerRepository->getById($customerId);
    }


}
Related Topic