Magento – Magento 2 : Overriding Default Contact Controller POST Action

contact-formcontrollersmagento2overrides

I'm trying to rewrite default post action of contact controller in my custom module.
di.xml is

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Contact\Controller\Index\Post" type="Company\Helloworld\Controller\Contact\Index" />
</config>

And Controller file is

<?php
namespace Company\Helloworld\Controller\Contact;
class Index extends \Magento\Contact\Controller\Index\Post {

    public function execute( $coreRoute = null )
    {
        $post = $this->getRequest()->getPostValue();
        if (!$post) {
            $this->_redirect('*/*/');
            return;
        }

        $this->inlineTranslation->suspend();
        try {
            $postObject = new \Magento\Framework\DataObject();
            $postObject->setData($post);

            $error = false;

            if (!\Zend_Validate::is(trim($post['name']), 'NotEmpty')) {
                $error = true;
            }
            if (!\Zend_Validate::is(trim($post['comment']), 'NotEmpty')) {
                $error = true;
            }
            if (!\Zend_Validate::is(trim($post['email']), 'EmailAddress')) {
                $error = true;
            }
            if (\Zend_Validate::is(trim($post['hideit']), 'NotEmpty')) {
                $error = true;
            }
            if ($error) {
                throw new \Exception();
            }

            $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
            $transport = $this->_transportBuilder
                ->setTemplateIdentifier($this->scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE, $storeScope))
                ->setTemplateOptions(
                    [
                        'area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE,
                        'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
                    ]
                )
                ->setTemplateVars(['data' => $postObject])
                ->setFrom($this->scopeConfig->getValue(self::XML_PATH_EMAIL_SENDER, $storeScope))
                ->addTo($this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope))
                ->setReplyTo($post['email'])
                ->getTransport();

            $transport->sendMessage();
            $this->inlineTranslation->resume();
            $this->messageManager->addSuccess(
                __('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.')
            );
            $this->getDataPersistor()->clear('contact_us');
            $this->_redirect('contact/index');
            return;
        } catch (\Exception $e) {
            $this->inlineTranslation->resume();
            $this->messageManager->addError(
                __('We can\'t process your request right now. Sorry, that\'s all we know.')
            );
            $this->getDataPersistor()->set('contact_us', $post);
            $this->_redirect('contact/index');
            return;
        }

    }


}

But, after submitting contact form, I'm getting following error

Fatal error: Call to private method Magento\Contact\Controller\Index\Post::getDataPersistor() from context 'Company\Helloworld\Controller\Contact\Index' in .../app/code/Company/Helloworld/Controller/Contact/Index.php

It's because of calling private function in default controller. I tried to copy same function here. But because of $this object calls in parent class, I'm getting error continuously. How to avoid this error and rewrite this controller action?

Best Answer

You cannot call a parent private method from the child class: $this->getDataPersistor().

In this case, if you use the <preference> way to override this class, you need to re-declare getDataPersistor() method.
However, I strongly recommend we to use the Plugin way for execute method as we can.