Question

I'm trying to create a custom mail form on Magento 2.2.x. I have looked at several instructions for Magento 2.0.x and/or Magento 2.1.x but they dont seem to work anymore for Magento 2.2.x. Perhaps someone can shed some light on this. The code of my controller in /app/code/Vendor/Module/controller/index/post.php looks like this:

namespace Vendor\Module\Controller\Index;

use Magento\Framework\App\Action\Context;
use Magento\Framework\Mail\Template\TransportBuilder;

class Post extends \Magento\Framework\App\Action\Action
{
    /**
     * @var TransportBuilder
     */
    private $transportBuilder;

    /**
     * @param Context $context
     * @param TransportBuilder $transportBuilder
     */
    public function __construct(
        Context $context,
        TransportBuilder $transportBuilder
    ) {
        parent::__construct($context);
        $this->transportBuilder = $transportBuilder;
    }

    /**
     * Post user question.
     *
     * @return void
     */
    public function execute()
    {
        $post = $this->getRequest()->getPostValue();
        if (!$post) {
            $this->_redirect('*/*/');
            return;
        }

        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->messageManager->addSuccessMessage(
                __('Thanks for contacting us with your feedback or questions. We\'ll respond to you very soon.')
            );
            $this->_redirect($post['redirect']);
            return;
        } catch (\Exception $e) {
            $this->messageManager->addErrorMessage(
                __('We can\'t process your request right now. Sorry, that\'s all we know.')
            );
            $this->messageManager->addErrorMessage($e->getMessage());
            $this->_redirect($post['redirect']);
            return;
        }
    }

}

This generates the error:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function Vendor\Module\Controller\Index\Feedback::__construct(), 1 passed in \generated\code\Vendor\Module\Controller\Index\Feedback\Interceptor.php on line 14 and exactly 2 expected in \app\code\Vendor\Module\Controller\Index\Post.php:29 Stack trace: #0 \generated\code\Vendor\Module\Controller\Index\Feedback\Interceptor.php(14): Vendor\Module\Controller\Index\Feedback->__construct(Object(Magento\Framework\App\Action\Context)) #1 \lib\internal\Magento\Framework\ObjectManager\Factory\AbstractFactory.php(111): Vendor\Module\Controller\Index\Feedback\Interceptor->__construct(Object(Magento\Framework\App\Action\Context)) #2 \lib\internal\Magento\Framework\ObjectMa in \app\code\Vendor\Module\Controller\Index\Post.php on line 29

Leaving TransportBuilder out of the constructor gives the following error:

Notice: Undefined property: Vendor\Module\Controller\Index\Post\Interceptor::$transportBuilder in E:\Localhost\www\magento2\versie22\app\code\Vendor\Module\Controller\Index\Post.php on line 68

Any help to get a custom email form on Magento 2.2.x working is appreciated.

Was it helpful?

Solution

Probably not the most elegant solution but this is how I got it working on Magento v2.2.x

namespace Vendor\Module\Controller\Index;

use Magento\Framework\App\Action\Context;
use Magento\Contact\Model\ConfigInterface;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\ObjectManager;

class Post extends \Magento\Contact\Controller\Index
{

    const XML_PATH_EMAIL_RECIPIENT = 'contact/email/recipient_email';
    const XML_PATH_EMAIL_SENDER = 'contact/email/sender_email_identity';
    const XML_PATH_EMAIL_TEMPLATE = 'contact/email/email_template';

    private $context;
    private $transportBuilder;
    private $inlineTranslation;
    protected $scopeConfig;
    private $storeManager;

    public function __construct(
        Context $context,
        ConfigInterface $contactsConfig,
        TransportBuilder $transportBuilder,
        StateInterface $inlineTranslation,
        ScopeConfigInterface $scopeConfig,
        StoreManagerInterface $storeManager = null
    ) {
        parent::__construct($context, $contactsConfig);
        $this->context = $context;
        $this->transportBuilder = $transportBuilder;
        $this->inlineTranslation = $inlineTranslation;
        $this->scopeConfig = $scopeConfig;
        $this->storeManager = $storeManager ?:
            ObjectManager::getInstance()->get(StoreManagerInterface::class);
    }

    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' => 'frontend',
                        'store' => $this->storeManager->getStore()->getId()
                    ]
                )
                ->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'], $post['name'])
                ->getTransport();

            $transport->sendMessage();
            $this->inlineTranslation->resume();
            $this->messageManager->addSuccessMessage(
                __('Thanks for contacting us with your feedback or questions. We\'ll respond to you very soon.')
            );
            $this->_redirect($post['redirect']);
            return;
        } catch (\Exception $e) {
            $this->messageManager->addErrorMessage(
                __('We can\'t process your request right now. Sorry, that\'s all we know.')
            );
            $this->_redirect($post['redirect']);
            return;
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top