Magento2 - Командная строка - Отправка электронной почты с использованием блочных шаблонов - Ошибка: отсутствует обязательный аргумент $ debugHintsPath

11

При попытке отправить электронную почту в Magento 2 из командной строки, я столкнулся с исключением ниже. Хотя использование одного и того же класса для отправки писем с внешнего или внутреннего контроллера работало отлично. Проблема строго происходила с использованием интерфейса командной строки.

Исключение:

main.CRITICAL: исключение «BadMethodCallException» с сообщением «Отсутствует обязательный аргумент $ debugHintsPath из Magento \ Developer \ Model \ TemplateEngine \ Plugin \ DebugHints. ' в /.../.../magento/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:45

Эта проблема также возникала только при попытке вызвать блок через макет из шаблона. Как только вызов блока был удален, исключение перестало отображаться.

Файл шаблона:

Приложение / код / ​​NameSpace / модуль / вид / интерфейс / электронная почта / 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"}}

Электронное письмо все еще было отправлено с неповрежденной строкой темы, но весь контент не был обработан, и только одна ошибка ниже отображалась в разделе контента после получения электронного письма.

Ошибка напечатана внутри писем:

Ошибка фильтрации шаблона: отсутствует обязательный аргумент $ debugHintsPath из Magento \ Developer \ Model \ TemplateEngine \ Plugin \ DebugHints.

ElGatito
источник

Ответы:

16

Наконец-то я нашел решение этой проблемы на форумах сообщества Magento, предоставленных @ dunagan5887 . Я решил поделиться этим здесь, на magento.stackexchange.com, так как многие могут извлечь пользу из хорошо отрекомендованного решения этого исключения.

Существует ссылка на оригинальное сообщение форума сообщества: Шаблон электронной почты с блоком

Похоже, это решение, цитируемое @ dunagan5887 ;dictates that the di.xml directive set in vendor/magento/module-developer/etc/adminhtml/di.xml is loaded.

Решение состоит из этой простой строки кода:

$ Это -> _ objectManager-> Configure ($ это -> _ configLoader-> нагрузки ( 'adminhtml'));


Пожалуйста, найдите рабочую версию класса командной строки ниже:

Приложение / код / ​​NameSpace / модуль / Console / 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();
    }

    ...

}

Просто измените область с frontendна adminили globalв соответствии с требованиями вашего приложения.


[ОБНОВИТЬ]

Область, 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_packetзначением для MYSQL, но так как лимит был уже достаточно высок и его повышение не решило проблему, я решил продолжить. Пройдя процесс исключения, я, наконец, обнаружил, что это было основным различием между двумя модулями, использующими аналогичные командные функции, из-за которых один из модулей вызывал эту проблему при включении.

Хотя я не стал искать источник этой проблемы или конфликта, я подумал, что было бы неплохо поделиться своими выводами здесь, так как другие могут найти это полезным.


[ОБНОВЛЕНИЕ - 2]

Правильный метод:

После обновления Magento до 2.2.X мы поняли, что это правильный метод для установки области:

Приложение / код / ​​NameSpace / модуль / Console / 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
источник
Большое спасибо @ElGatito. Ты сохранишь мой день. :)
Еще
Я установил область действия как глобальную, и она отлично работает для меня.
Ракеш Джесадия
1
ВНИМАНИЕ: НЕ используйте этот код ( $objectManager->configure($configLoader->load('frontend'));) в конструкторе класса! Если вы загрузите конфигурацию из другой области, отличной от текущей, это может серьезно сломать Magento 2!
Уэсли Вестьенс
@Wesley Vestjens +1 Спасибо за ваш комментарий. Правильный метод на самом деле очень отличается, и я обновил свой ответ, чтобы отразить его. Пожалуйста, обратитесь к [ОБНОВЛЕНИЕ - 2] .
ElGatito
На самом деле, простая установка области не работает, если вы используете какую-либо часть слоя представления Magento 2 (что требуется для создания PDF-файлов в Magento 2). Вы получите ошибку относительно следующего объекта: Magento\Developer\Model\TemplateEngine\Plugin\DebugHintsпотому что debugHintsPathпеременная не установлена. Использование исходного кода для загрузки конфигурации DI области ADMINHTML работает или ручная настройка debugHintsPathпеременной работает, но могут быть и другие сломанные части. На самом деле это «ошибка» в Magento, потому что невозможно использовать элементы слоя представления в CLI.
Уэсли Вестженс
6

Поскольку CLI в Magento не имеет соответствующей области, я нашел следующий обходной путь:

Приложение / код / ​​NameSpace / модуль / и т.д. / 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>
rut4
источник