0

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?

1 Answer 1

1

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);
    }


}
3
  • I added your controller and I edited my post and added my complete code but when I save data it returns 404 error. I think it's because of routing fault! what shall I do?
    – M Taheri
    Commented Sep 20, 2017 at 7:15
  • Its action is mypoint/customer/savePost but it redirects to mypoint/customer/edit/ in the url
    – M Taheri
    Commented Sep 20, 2017 at 7:26
  • I changes $customerCandidateDataObject to $currentCustomerDataObject, now it says customer updated, but data did not save!
    – M Taheri
    Commented Sep 20, 2017 at 7:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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