1

I have created a pop up html form for sending mail to admin panel, it can pop up and keys in data but somehow it showed error while submitting.

app/code/Myvendor/Mymodule/Block/Popup.php

<?php

namespace Myvendor\Mymodule\Block;

use Magento\Framework\View\Element\Template;

class Popup extends \Magento\Framework\View\Element\Template
{
protected $_registry;

public function __construct(Template\Context $context, array $data = [], \Magento\Framework\Registry $registry)
{
    $this->_registry = $registry;
    parent::__construct($context, $data);
}

public function _prepareLayout()
{
    return parent::_prepareLayout(); // TODO: Change the autogenerated stub
}

public function getCurrentCategory() {
    return $this->_registry->registry('current_category');
}

public function getCurrentProduct() {
    return $this->_registry->registry('current_product');
}


/**
 * @return string
 */
  public function getFormAction()
  {

    return $this->getUrl('productenquiry/index/send', ['_secure' => true]);
  }
}

app/code/Myvendor/Mymodule/Controller/Index/Send.php

<?php
namespace Myvendor\Mymodule\Controller\Index;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Mail\Template\TransportBuilder;
use Zend_Mail_Transport_Sendmail;

class Send extends \Magento\Framework\App\Action\Action{

/**
 * Recipient email config path
 */
const XML_PATH_EMAIL_RECIPIENT = 'email_section/sendmail/email_section_sendmail_email_template';
/**
 * @var \Magento\Framework\Mail\Template\TransportBuilder
 */
protected $_transportBuilder;

/**
 * @var \Magento\Framework\Translate\Inline\StateInterface
 */
protected $inlineTranslation;

/**
 * @var \Magento\Framework\App\Config\ScopeConfigInterface
 */
protected $scopeConfig;

/**
 * @var \Magento\Store\Model\StoreManagerInterface
 */
protected $storeManager;
/**
 * @var \Magento\Framework\Escaper
 */
protected $_escaper;
/**
 * @param \Magento\Framework\App\Action\Context $context
 * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
 * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
 * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 */
public function __construct(
    \Magento\Framework\App\Action\Context $context,
    \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
    \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
    \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Framework\Escaper $escaper
) {
    parent::__construct($context);
    $this->_transportBuilder = $transportBuilder;
    $this->inlineTranslation = $inlineTranslation;
    $this->scopeConfig = $scopeConfig;
    $this->storeManager = $storeManager;
    $this->_escaper = $escaper;
}

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

    $this->inlineTranslation->suspend();

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

        $error = false;

        $sender = [
            'name' => $this->_escaper->escapeHtml($post['name']),
            'email' => $this->_escaper->escapeHtml($post['email']),
        ];

        $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;

        $transport = $this->_transportBuilder
            ->setTemplateIdentifier('email_section_sendmail_email_template') // this code we have mentioned in the email_templates.xml
            ->setTemplateOptions(
                [
                    'area' => \Magento\Framework\App\Area::AREA_FRONTEND, // this is using frontend area to get the template file
                    'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
                ]
            )
            ->setTemplateVars(['data' => $postObject])
            ->setFrom($sender)
            ->addTo($this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope))
            ->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.')
        );

    } catch (\Exception $e) {
        $this->inlineTranslation->resume();
        $this->messageManager->addError(
            __('We can\'t process your request right now. Sorry, that\'s all we know.'.$e->getMessage())
        );

    }

    return $this->_redirect($this->_redirect->getRefererUrl());
}

}

app/code/Myvendor/Mymodule/view/frontend/email/email_file.html

{{template config_path="design/email/header_template"}}

 <table class="message-details">
<tr>
    <td><b>{{trans "Name"}}</b></td>
    <td>{{var data.name}}</td>
</tr>
<tr>
    <td><b>{{trans "Email"}}</b></td>
    <td>{{var data.email}}</td>
</tr>
<tr>
    <td><b>{{trans "Product Name"}}</b></td>
    <td>{{var data.product_name}}</td>
</tr>
</table>
<p><b>{{trans "Message"}}</b></p>
<p>{{var data.message}}</p>

{{template config_path="design/email/footer_template"}}

app/code/Myvendor/Mymodule/view/frontend/templates/popup.phtml

<?php
 $myBlock = \Magento\Framework\App\ObjectManager::getInstance()->get('Myvendor\Mymodule\Block\Popup');


?>



<div class="content" style="display:none" id="popup_content">
<form
    class="form enquire"
    id="enquire-form"
    action="<?= $myBlock->escapeUrl($myBlock->getFormAction()) ?>"
    method="post">
    <div class="form-group">
        <Label for="#name">Name</Label>
        <input name="name" id="name" title="Name" class="form-control input-text" type="text"/>
    </div>
    <div class="form-group">
        <Label for="#email">Email</Label>
        <input id="email" name="email" title="Email" class="form-control input-text" type="email">
    </div>
    <div class="form-group">
        <Label for="#message">Message</Label>
        <input id="message" name="message" title="Message" type="text" class="form-control input-text">
    </div>
    <div class="form-group">
        <Label for="#product_name">Product Name</Label>
        <input id="product_name" name="product_name" title="Product Name" type="text" value="<?php if ($currentProduct = $myBlock->getCurrentProduct()) { echo $currentProduct->getName();}; ?>" class="form-control input-text" readonly><br>
    </div>
    <button type="submit">Submit</button>
</form>
</div>


<div id="click-section" class="click-section">
<br>
<button type="button" class="action primary" id="click_section2">
    <span data-bind="i18n: 'Click Me'"></span>
</button>
 </div>

  <script type="text/javascript">
  require(
    [
        'jquery',
        'Magento_Ui/js/modal/modal'
    ],
    function($,modal) {
        var options = {
            type: 'popup',
            responsive: true,
            innerScroll: true,
            title: 'Popup',
            buttons: []
        };

        $( "#click_section2" ).click(function() {
            modal(options, $('#popup_content'));
            $('#popup_content').modal('openModal');
        });
    }
);

When I click submit button:

TypeError: Argument 1 passed to Magento\Framework\Mail\AddressConverter::convertMany() must be of the type array, null given,
1

1 Answer 1

1

In this $this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope) you should get either string or array value, I think you are getting this as null value.

Complete Explanation as shown below

You have call the addTo method as given in example which accepts @param array|string $address

Explanation :-

/**
     * Add to address
     *
     * @param array|string $address
     * @param string $name
     *
     * @return $this
     * @throws InvalidArgumentException
     */
    public function addTo($address, $name = '')
    {
        $this->addAddressByType('to', $address, $name);

        return $this;
    }

addTo method calls addAddressByType method that accepts again array or string by passing your data as argument on second position as $email (@param string|array $email).

Example :-

/**
     * Handles possible incoming types of email (string or array)
     *
     * @param string $addressType
     * @param string|array $email
     * @param string|null $name
     *
     * @return void
     * @throws InvalidArgumentException
     */
    private function addAddressByType(string $addressType, $email, ?string $name = null): void
    {
        if (is_string($email)) {
            $this->messageData[$addressType][] = $this->addressConverter->convert($email, $name);
            return;
        }
        $convertedAddressArray = $this->addressConverter->convertMany($email);
        if (isset($this->messageData[$addressType])) {
            $this->messageData[$addressType] = array_merge(
                $this->messageData[$addressType],
                $convertedAddressArray
            );
        } else {
            $this->messageData[$addressType] = $convertedAddressArray;
        }
    }

And as you value passes is null and not a string it does not go to below code section of method

if (is_string($email)) {
     $this->messageData[$addressType][] = $this->addressConverter->convert($email, $name);
     return;
}

and goes for further execution which requires array to be passed in convertMany function.

Or your config path might be wrong Please refer below image instruction to correct your path if it is wrong

enter image description here

If this answer works as your expected, please mark it as accepted. That indicates your issue is solved and makes it easier for others with the same issue to find a verified answer. And that would be great if you click the upvote button for the answer in case you feel it is useful.

3
  • Hi. thank you for your answer, sorry that I am new and may I know which part should be changed in my code? Thanks!
    – hill2011
    Commented Nov 14, 2022 at 5:18
  • Can you please check what value you are getting when you print this $this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope) Have you set the default configuration value for this setting? Or have you set any value from admin? Commented Nov 14, 2022 at 6:07
  • @hill2011 May be your path can be incorrect, I have updated my answer with instruction about how to define correct config path. Commented Nov 14, 2022 at 6:45

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.