Magento2-命令行-使用阻止模板发送电子邮件-错误:缺少必需的参数$ debugHintsPath


11

尝试从命令行在Magento 2中发送电子邮件时,遇到以下异常。使用相同的类从前端或后端控制器发送电子邮件时,效果很好。使用命令行界面确实发生了此问题。

例外:

main.CRITICAL:异常“ BadMethodCallException”,消息为“ Magento \ Developer \ Model \ TemplateEngine \ Plugin \ DebugHints缺少必需的参数$ debugHintsPath”。在/.../.../magento/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:45中

该问题仅在尝试从模板内部通过布局调用块时才发生。删除块调用后,该异常立即停止显示。

模板文件:

app / code / NameSpace / Module / view / frontend / email / email_notification.html

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

...

<!-- THIS LINE CAUSED THE EXCEPTION TO SHOW UP -->
{{layout handle="sales_email_order_items" order=$order area="frontend"}}

...

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

电子邮件仍以完整的主题行发送,但未呈现全部内容,并且在收到电子邮件后,内容部分仅显示以下错误。

在电子邮件中打印错误:

错误筛选模板:缺少Magento \ Developer \ Model \ TemplateEngine \ Plugin \ DebugHints的必需参数$ debugHintsPath。

Answers:


16

我终于在@ dunagan5887提供的Magento社区论坛中找到了解决此问题的方法。我决定在magento.stackexchange.com上共享它,因为许多人可能会从对此异常引用得当的解决方案中受益。

有一个指向原始社区论坛帖子的链接:带模板的电子邮件模板

似乎这个解决方案,如@ dunagan5887所引用;dictates that the di.xml directive set in vendor/magento/module-developer/etc/adminhtml/di.xml is loaded.

解决方案包括以下简单的代码行:

$ this-> _ objectManager-> configure($ this-> _ configLoader-> load('adminhtml'));


请在下面找到工作版本的命令行类:

应用程序/代码/名称空间/模块/控制台/Command.php

<?php
namespace NameSpace\Module\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CustomCommandClass extends Command
{
    public function __construct(
        \Magento\Framework\App\State $state,
        \Magento\Framework\ObjectManagerInterface $objectManager,
        \Magento\Framework\ObjectManager\ConfigLoaderInterface $configLoader
    ) {
        $state->setAreaCode('frontend'); //SET CURRENT AREA
        $objectManager->configure($configLoader->load('frontend')); //SOLUTION
        parent::__construct();
    }

    ...

}

只需将区域从更改为frontendadminglobal根据应用程序的要求进行更改。


[更新]

adminhtml造成静态内容部署错误

似乎出于某些原因,将区域设置为adminhtml会在部署静态内容时引起一些错误。

我们看到了如下错误:

Fatal error: Uncaught Exception: Warning: Error while sending QUERY packet. PID=22912 in ../magento/vendor/magento/zendframework1/library/Zend/Db/Statement/Pdo.php on line 228 in ../magento/vendor/magento/framework/App/ErrorHandler.php:61

最初,我认为该错误是由max_allowed_packetMYSQL 的较低设置引起的,但由于限制已经足够高,并且提高该限制仍无法解决问题,因此我决定进一步研究。经过消除过程后,我最终发现这是使用相似命令功能的两个模块之间的主要区别,其中一个模块在启用后立即导致了此问题。

尽管我还没有找到问题或冲突的根源,但我认为在这里分享我的发现是一个好主意,因为其他人可能会觉得有用。


[更新-2]

正确的方法:

将Magento升级到2.2.X之后,我们意识到这是设置区域的正确方法:

应用程序/代码/名称空间/模块/控制台/Command.php

<?php
namespace NameSpace\Module\Console\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Magento\Framework\Exception\LocalizedException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CustomCommandClass extends Command
{
    public function __construct(
        \Magento\Framework\App\State $state,
    ) {
        $this->_appState = $appState;
        parent::__construct();
    }

    ...

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $this->_appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL); //SET CURRENT AREA

        ...

    }

    ...

}

注意,我们没有使用对象管理器,必须在需要它的函数中设置区域,而不是在构造函数中设置区域。这是设置区域的官方方法,并且可以在所有Magento 2版本中正常使用。


可用的列表在以下类别中可用:

Magento \ Framework \ App \ Area

class Area implements \Magento\Framework\App\AreaInterface
{
    const AREA_GLOBAL = 'global';
    const AREA_FRONTEND = 'frontend';
    const AREA_ADMIN    = 'admin';
    const AREA_ADMINHTML = 'adminhtml';
    const AREA_DOC = 'doc';
    const AREA_CRONTAB = 'crontab';
    const AREA_WEBAPI_REST = 'webapi_rest';
    const AREA_WEBAPI_SOAP = 'webapi_soap';

    ...

非常感谢@ElGatito。你救我的日子。:)再次感谢您的日志
Ankit Shah

我已将范围设置为全局范围,并且对我来说很好。
Rakesh Jesadiya

1
警告:请勿$objectManager->configure($configLoader->load('frontend'));在类的构造函数中使用该代码()!如果您从当前区域以外的区域进行配置并加载配置,则可能会严重破坏Magento 2!
Wesley Vestjens

@Wesley Vestjens +1感谢您的评论。正确的方法实际上有很大的不同,我已经更新了答案以反映出来。请参考[UPDATE-2]
ElGatito

实际上,如果您使用Magento 2的视图层的任何部分(在Magento 2中生成PDF文件是必需的),则仅设置区域是行不通的。您将收到有关以下对象的错误:Magento\Developer\Model\TemplateEngine\Plugin\DebugHints因为debugHintsPath未设置变量。使用原始代码加载ADMINHTML区域,DI配置有效,或手动设置debugHintsPath变量有效,但是可能还有其他损坏的部分。实际上这是Magento中的“错误”,因为在CLI中无法使用视图层元素。
Wesley Vestjens

6

由于Magento中的CLI没有适当的区域,因此我想出了以下解决方法:

应用程序/代码/名称空间/模块/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!-- Add this for sending email via cli -->
    <type name="Magento\Developer\Model\TemplateEngine\Plugin\DebugHints">
        <arguments>
            <argument name="debugHintsPath" xsi:type="string">dev/debug/template_hints_storefront</argument>
        </arguments>
    </type>
</config>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.