Magento2 - Wiersz poleceń - Wysyłanie wiadomości e-mail za pomocą szablonów bloków - Błąd: Brak wymaganego argumentu $ debugHintsPath

11

Podczas próby wysłania wiadomości e-mail w Magento 2 z wiersza polecenia napotkałem wyjątek poniżej. Podczas korzystania z tej samej klasy do wysyłania wiadomości e-mail z interfejsu lub kontrolera zaplecza działało idealnie. Problem występował ściśle przy użyciu interfejsu wiersza poleceń.

Wyjątek:

main.CRITICAL: wyjątek „BadMethodCallException” z komunikatem „Brak wymaganego argumentu $ debugHintsPath of Magento \ Developer \ Model \ TemplateEngine \ Plugin \ DebugHints.” w /.../.../magento/vendor/magento/framework/ObjectManager/Factory/Dynamic/Developer.php:45

Problem występował także tylko podczas próby wywołania bloku za pomocą układu z poziomu szablonu. Po usunięciu wywołania blokowego wyjątek przestał być wyświetlany.

Plik szablonu:

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"}}

Wiadomość e-mail nadal była wysyłana z nienaruszonym wierszem tematu, ale cała treść nie została renderowana, a tylko poniższy błąd pojawiał się w sekcji treści po otrzymaniu wiadomości e-mail.

Błąd wydrukowany w wiadomościach e-mail:

Błąd filtrowania szablonu: brak wymaganego argumentu $ debugHintsPath of Magento \ Developer \ Model \ TemplateEngine \ Plugin \ DebugHints.

ElGatito
źródło

Odpowiedzi:

16

W końcu znalazłem rozwiązanie tego problemu na forach społeczności Magento, które dostarczył @ dunagan5887 . Postanowiłem udostępnić go tutaj na magento.stackexchange.com, ponieważ wiele osób może skorzystać z dobrze opracowanego rozwiązania tego wyjątku.

Link do oryginalnego postu na forum społeczności: Szablon wiadomości e-mail z blokiem

Wygląda na to, że takie rozwiązanie cytowane przez @ dunagan5887 ;dictates that the di.xml directive set in vendor/magento/module-developer/etc/adminhtml/di.xml is loaded.

Rozwiązanie składa się z tej prostej linii kodu:

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


Poniżej znajduje się klasa wiersza poleceń działającej wersji:

app / code / NameSpace / Module / 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();
    }

    ...

}

Wystarczy zmienić obszar z frontendna adminlub globalzgodnie z wymaganiami aplikacji.


[AKTUALIZACJA]

Obszar adminhtmlpowodujący błędy wdrażania zawartości statycznej

Wydaje się, że z pewnych powodów ustawienie tego obszaru adminhtmlpowoduje błędy podczas wdrażania zawartości statycznej.

Widzieliśmy następujące błędy:

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

Początkowo myślałem, że ten błąd będzie spowodowany niskim max_allowed_packetustawieniem MYSQL, ale ponieważ limit był już wystarczająco wysoki i podniesienie go nie rozwiązało problemu, postanowiłem kopać dalej. Po przejściu przez proces eliminacji w końcu odkryłem, że to była główna różnica między dwoma modułami używającymi podobnych funkcji poleceń, z których jeden z modułów powodował ten problem, gdy tylko został włączony.

Chociaż nie kopałem, aby znaleźć źródło tego problemu lub konfliktu, pomyślałem, że dobrym pomysłem byłoby podzielenie się swoimi odkryciami tutaj, ponieważ inni mogą uznać to za przydatne.


[AKTUALIZACJA - 2]

Właściwa metoda:

Po aktualizacji Magento do wersji 2.2.X zdaliśmy sobie sprawę, że jest to właściwa metoda ustawienia obszaru:

app / code / NameSpace / Module / 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

        ...

    }

    ...

}

Zauważ, że nie korzystamy z Object Managera i że obszar musi być ustawiony w funkcji, która go wymaga, a NIE w konstruktorze. Jest to oficjalny sposób ustawiania obszaru i powinien działać bezbłędnie ze wszystkimi wersjami Magento 2.


Lista dostępnych obszarów jest dostępna w następującej klasie:

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
źródło
Wielkie dzięki @ElGatito. Uratuj mi dzień. :)
Jeszcze
Ustawiłem zakres jako globalny i działa dobrze dla mnie.
Rakesh Jesadiya
1
OSTRZEŻENIE: NIE używaj tego kodu ( $objectManager->configure($configLoader->load('frontend'));) w konstruktorze klasy! Jeśli to zrobisz i załadujesz konfigurację z innego obszaru niż bieżący, może to poważnie uszkodzić Magento 2!
Wesley Vestjens
@Wesley Vestjens +1 Dziękujemy za komentarz. Właściwa metoda jest bardzo różna i zaktualizowałem swoją odpowiedź, aby ją odzwierciedlić. Proszę odnieść się do [AKTUALIZACJA - 2] .
ElGatito
Właściwie samo ustawienie obszaru nie działa, jeśli używasz dowolnej części warstwy widoku Magento 2 (która jest wymagana do generowania plików PDF w Magento 2). Pojawi się błąd dotyczący następującego obiektu: Magento\Developer\Model\TemplateEngine\Plugin\DebugHintsponieważ debugHintsPathzmienna nie jest ustawiona. Użycie oryginalnego kodu do załadowania obszaru DI obszaru ADMINHTML działa lub ręczne ustawienie debugHintsPathzmiennej działa, ale mogą istnieć inne uszkodzone części. W rzeczywistości jest to „błąd” w Magento, ponieważ nie można używać elementów warstwy widoku w CLI.
Wesley Vestjens
6

Ponieważ CLI w Magento nie ma odpowiedniego obszaru, wymyśliłem następujące obejście:

app / code / NameSpace / Module / 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>
rut4
źródło