cancel
Showing results for 
Search instead for 
Did you mean: 

Send a contact from from product page

SOLVED

Send a contact from from product page

I would like to add a tab with a contact form with additional fields.

Would you tell me the best way without installing an extension?

 

I have tried like this:

 

 

1. Add contact form to the tab

<block class="Magento\Catalog\Block\Product\View\Description" name="product.info.details" template="Magento_Catalog::product/view/details.phtml" after="product.info.media">...
...
<block class="Magento\Contact\Block\ContactForm" name="contactForm" template="Vendor_Theme::productform.phtml"> <container name="form.additional.info" label="Form Additional Info"/> </block>
</block>...</block>

However doing this it submits an contact form and it redirects to the contact us page. I would like to submit a form with additional fields and after submitting, staying on the same page.

1 ACCEPTED SOLUTION

Accepted Solutions

Re: Send a contact from from product page

@tvgarden

 

You need to override Contact Post Controller because by default it redirects to contact/index 
$this->_redirect('contact/index'); needs to be changed to $this->_redirect->getRefererUrl(); in file vendor/magento/module-contact/Controller/Index/Post.php 

Code for controller override is as follows :

app/code/Custom/Contact/registration.php

 

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

app/code/Custom/Contact/etc/module.xml 

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Custom_Contact" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Contact"/>
        </sequence>
    </module>
</config>

app/code/Custom/Contact/etc/di.xml

<?xml version="1.0" encoding="UTF-8"?>
<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="Custom\Contact\Controller\Index\Post" />
</config>

app/code/Custom/Contact/Controller/Index/Post.php

<?phpnamespace Custom\Contact\Controller\Index;

use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class Post extends \Magento\Contact\Controller\Index\Post{
    /**
     * @var DataPersistorInterface
     */
    private $dataPersistor;

    /**
     * Post user question
     *
     * @return void
     * @throws \Exception
     */
    public function execute()
    {        $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->getRefererUrl();
            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->getRefererUrl();
            return;
        }
    }

    /**
     * Get Data Persistor
     *
     * @return DataPersistorInterface
     */
    private function getDataPersistor()
    {
        if ($this->dataPersistor === null) {            $this->dataPersistor = ObjectManager::getInstance()
                ->get(DataPersistorInterface::class);
        }

        return $this->dataPersistor;
    }

}

 

Manish Mittal
https://www.manishmittal.com/

View solution in original post

7 REPLIES 7

Re: Send a contact from from product page

@tvgarden

 

You need to override Contact Post Controller because by default it redirects to contact/index 
$this->_redirect('contact/index'); needs to be changed to $this->_redirect->getRefererUrl(); in file vendor/magento/module-contact/Controller/Index/Post.php 

Code for controller override is as follows :

app/code/Custom/Contact/registration.php

 

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

app/code/Custom/Contact/etc/module.xml 

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Custom_Contact" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Contact"/>
        </sequence>
    </module>
</config>

app/code/Custom/Contact/etc/di.xml

<?xml version="1.0" encoding="UTF-8"?>
<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="Custom\Contact\Controller\Index\Post" />
</config>

app/code/Custom/Contact/Controller/Index/Post.php

<?phpnamespace Custom\Contact\Controller\Index;

use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class Post extends \Magento\Contact\Controller\Index\Post{
    /**
     * @var DataPersistorInterface
     */
    private $dataPersistor;

    /**
     * Post user question
     *
     * @return void
     * @throws \Exception
     */
    public function execute()
    {        $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->getRefererUrl();
            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->getRefererUrl();
            return;
        }
    }

    /**
     * Get Data Persistor
     *
     * @return DataPersistorInterface
     */
    private function getDataPersistor()
    {
        if ($this->dataPersistor === null) {            $this->dataPersistor = ObjectManager::getInstance()
                ->get(DataPersistorInterface::class);
        }

        return $this->dataPersistor;
    }

}

 

Manish Mittal
https://www.manishmittal.com/

Re: Send a contact from from product page

Hi @Manish Mittal

 

Thank you for your reply. 

I am not able to test it from my PC as I haven't installed Linux onto my PC.

I will test it tomorrow.

 

So how can I call this module from xml file?

I have created a module Custom_Module, and in the Theme I changed block class to:

<block class="Custom\Contact\Block\ContactForm" >

 

So the xml file would be:

<block class="Magento\Catalog\Block\Product\View\Description" name="product.info.details" template="Magento_Catalog::product/view/details.phtml" after="product.info.media">...
...
 <block class="Custom\Contact\Block\ContactForm" name="contactForm" template="Vendor_Theme::productform.phtml"> <container name="form.additional.info" label="Form Additional Info"/> </block>

</block>...</block>


Is this right?

 

 

Re: Send a contact from from product page

@tvgarden

 

I have shared all the steps to create a custom module and files with code, please follow as it is and change according to your requirements.

Manish Mittal
https://www.manishmittal.com/

Re: Send a contact from from product page

@Manish Mittal

 

Receiving an error:

Notice: Undefined property: Custom\Contact\Controller\Index\Post\Interceptor::$inlineTranslation 


Exception #0 (Exception): Notice: Undefined property: Custom\Contact\Controller\Index\Post\Interceptor::$inlineTranslation in /var/www/vhosts/appliancespares-direct.co.uk/htdocs/app/code/Custom/Contact/Controller/Index/Post.php on line 28
#0 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/app/code/Custom/Contact/Controller/Index/Post.php(28): Magento\Framework\App\ErrorHandler->handler(8, 'Undefined prope...', '/var/www/vhosts...', 28, Array)
#1 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/generated/code/Custom/Contact/Controller/Index/Post/Interceptor.php(24): CUstom\Contact\Controller\Index\Post->execute()
#2 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/App/Action/Action.php(107): CUstom\Contact\Controller\Index\Post\Interceptor->execute()
#3 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/module-contact/Controller/Index.php(67): Magento\Framework\App\Action\Action->dispatch(Object(Magento\Framework\App\Request\Http))
#4 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Contact\Controller\Index->dispatch(Object(Magento\Framework\App\Request\Http))
#5 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/Interception/Interceptor.php(138): Custom\Contact\Controller\Index\Post\Interceptor->___callParent('dispatch', Array)
#6 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/Interception/Interceptor.php(153): Custom\Contact\Controller\Index\Post\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#7 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/generated/code/custom/Contact/Controller/Index/Post/Interceptor.php(39): Custom\Contact\Controller\Index\Post\Interceptor->___callPlugins('dispatch', Array, Array)
#8 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/App/FrontController.php(55): Custom\Contact\Controller\Index\Post\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#9 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/Interception/Interceptor.php(58): Magento\Framework\App\FrontController->dispatch(Object(Magento\Framework\App\Request\Http))
#10 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/Interception/Interceptor.php(138): Magento\Framework\App\FrontController\Interceptor->___callParent('dispatch', Array)
#11 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/module-store/App/FrontController/Plugin/RequestPreprocessor.php(94): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#12 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/Interception/Interceptor.php(135): Magento\Store\App\FrontController\Plugin\RequestPreprocessor->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#13 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/module-page-cache/Model/App/FrontController/BuiltinPlugin.php(73): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#14 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/Interception/Interceptor.php(135): Magento\PageCache\Model\App\FrontController\BuiltinPlugin->aroundDispatch(Object(Magento\Framework\App\FrontController\Interceptor), Object(Closure), Object(Magento\Framework\App\Request\Http))
#15 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/Interception/Interceptor.php(153): Magento\Framework\App\FrontController\Interceptor->Magento\Framework\Interception\{closure}(Object(Magento\Framework\App\Request\Http))
#16 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/generated/code/Magento/Framework/App/FrontController/Interceptor.php(26): Magento\Framework\App\FrontController\Interceptor->___callPlugins('dispatch', Array, NULL)
#17 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/App/Http.php(135): Magento\Framework\App\FrontController\Interceptor->dispatch(Object(Magento\Framework\App\Request\Http))
#18 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/generated/code/Magento/Framework/App/Http/Interceptor.php(24): Magento\Framework\App\Http->launch()
#19 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/vendor/magento/framework/App/Bootstrap.php(257): Magento\Framework\App\Http\Interceptor->launch()
#20 /var/www/vhosts/appliancespares-direct.co.uk/htdocs/pub/index.php(37): Magento\Framework\App\Bootstrap->run(Object(Magento\Framework\App\Http\Interceptor))
#21 {main}


Re: Send a contact from from product page

@tvgarden

 

Please follow below link for your reference:

 

https://magento.stackexchange.com/questions/228434/magento-2-notice-undefined-property-interceptorin...

Manish Mittal
https://www.manishmittal.com/

Re: Send a contact from from product page

@Manish Mittal 

Thank you very much for your reply.

The solution works!

 

I am sorry for the delay.

 

There is only one problem.

 

After submitting the form, it directs to contact/index rather than the product page,

 

The code is obviously directing to the referer.

 

$this->_redirect->getRefererUrl();

 

I would like to make it go back to the product page to display the message.

 

Re: Send a contact from from product page

I've just worked out by replacing the code on the bottom of execute() function:

 

from:

return $this->resultRedirectFactory->create()->setPath('contact/index');

 

to:

return $this->resultRedirectFactory->create()->setPath($this->_redirect->getRefererUrl());

 

 

public function execute()
    {
        if (!$this->getRequest()->isPost()) {
            return $this->resultRedirectFactory->create()->setPath('*/*/');
        }
        try {
            $this->sendEmail($this->validatedParams());
            $this->messageManager->addSuccessMessage(
                __('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.')
            );
            $this->dataPersistor->clear('contact_us');
        } catch (LocalizedException $e) {
            $this->messageManager->addErrorMessage($e->getMessage());
            $this->dataPersistor->set('contact_us', $this->getRequest()->getParams());
        } catch (\Exception $e) {
            $this->logger->critical($e);
            $this->messageManager->addErrorMessage(
                __('An error occurred while processing your form. Please try again later.')
            );
            $this->dataPersistor->set('contact_us', $this->getRequest()->getParams());
        }
             return $this->resultRedirectFactory->create()->setPath($this->_redirect->getRefererUrl());
    }

So now it's redirecting to the product page after sending an email.