1

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.

  • can you say why you are building the custom mail form? – Ahdee Sep 25 '17 at 0:35
  • I'm creating a feedback form on the checkout success page allowing customers that have made an order to send feedback through this email form. – Solide Sep 25 '17 at 16:52
1

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;
        }
    }
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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