Magento2 - Dòng lệnh - Gửi email bằng cách sử dụng Mẫu khối - Lỗi: Thiếu đối số bắt buộc $ debugHintsPath


11

Khi cố gắng gửi email trong Magento 2 từ dòng lệnh, tôi đã gặp ngoại lệ bên dưới. Trong khi sử dụng cùng một lớp để gửi email từ bộ điều khiển frontend hoặc backend đã hoạt động hoàn hảo. Vấn đề đã xảy ra nghiêm trọng bằng cách sử dụng giao diện dòng lệnh.

Ngoại lệ:

main.CRITICS: ngoại lệ 'BadMethodCallException' với thông báo 'Thiếu đối số bắt buộc $ debugHintsPath của Magento \ Developer \ Model \ TemplateEngine \ Plugin \ DebugHints.' trong /.../.../magento/vendor/magento/framework/ObjectManager/Factory/Docate/Developer.php:45

Vấn đề cũng chỉ xảy ra khi cố gắng gọi một khối thông qua bố cục từ bên trong mẫu. Ngay khi cuộc gọi chặn được gỡ bỏ, ngoại lệ đã dừng hiển thị.

Tệp mẫu:

ứng dụng / mã / 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"}}

Email vẫn được gửi với dòng tiêu đề nguyên vẹn nhưng toàn bộ nội dung không được hiển thị và chỉ có lỗi bên dưới được hiển thị trong phần nội dung sau khi nhận được email.

Lỗi in bên trong email:

Lỗi lọc mẫu: Thiếu đối số bắt buộc $ debugHintsPath của Magento \ Developer \ Model \ TemplateEngine \ Plugin \ DebugH gợi ý.

Câu trả lời:


16

Cuối cùng tôi đã tìm thấy giải pháp cho vấn đề này trong Diễn đàn cộng đồng Magento, được cung cấp bởi @ dunagan5887 . Tôi quyết định chia sẻ nó ở đây trên magento.stackexchange.com vì nhiều người có thể được hưởng lợi từ một giải pháp được giới thiệu tốt cho ngoại lệ này.

Có một liên kết đến bài đăng Diễn đàn cộng đồng gốc: Mẫu email có khối

Có vẻ như giải pháp này, như được trích dẫn bởi @ dunagan5887 ;dictates that the di.xml directive set in vendor/magento/module-developer/etc/adminhtml/di.xml is loaded.

Giải pháp bao gồm dòng mã đơn giản này:

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


Vui lòng tìm một lớp dòng lệnh phiên bản làm việc dưới đây:

ứng dụng / mã / 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();
    }

    ...

}

Chỉ cần thay đổi khu vực từ frontendđến adminhoặc globaltheo yêu cầu của ứng dụng của bạn.


[CẬP NHẬT]

Khu vực adminhtmlgây ra lỗi triển khai nội dung tĩnh

Dường như vì một số lý do, việc đặt khu vực adminhtmlnày gây ra một số lỗi trong khi triển khai nội dung tĩnh.

Chúng tôi đã thấy các lỗi như sau:

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

Ban đầu tôi nghĩ rằng lỗi này sẽ do max_allowed_packetMYSQL cài đặt thấp nhưng vì giới hạn đã đủ cao và việc nâng cao nó không giải quyết được vấn đề, tôi quyết định đào sâu hơn. Sau khi trải qua quá trình loại bỏ, cuối cùng tôi phát hiện ra rằng đây là điểm khác biệt chính giữa hai mô-đun sử dụng các chức năng lệnh tương tự, từ đó một trong các mô-đun đã gây ra sự cố này ngay khi được bật.

Mặc dù tôi không đào sâu để tìm ra nguồn gốc của vấn đề hoặc xung đột này, tôi nghĩ rằng sẽ là một ý tưởng tốt để chia sẻ những phát hiện của tôi ở đây vì những người khác có thể thấy nó hữu ích.


[CẬP NHẬT - 2]

Phương pháp đúng:

Sau khi nâng cấp Magento lên 2.2.X, chúng tôi nhận ra rằng đây là phương pháp phù hợp để thiết lập khu vực:

ứng dụng / mã / 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

        ...

    }

    ...

}

Lưu ý rằng chúng tôi không sử dụng Trình quản lý đối tượng và khu vực đó phải được đặt trong hàm yêu cầu và KHÔNG trong hàm tạo. Đây là cách chính thức để thiết lập khu vực và nó sẽ hoạt động hoàn hảo với tất cả các phiên bản Magento 2.


Một danh sách các khu vực có sẵn trong lớp sau:

Magento \ Framework \ Ứng dụng \ Khu vực

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';

    ...

Cảm ơn rất nhiều @ElGatito. Bạn tiết kiệm trong ngày của tôi. :) Cảm ơn một bản ghi một lần nữa
Ankit Shah

Tôi đã đặt phạm vi là toàn cầu và nó hoạt động tốt với tôi.
Rakesh Jesadiya

1
CẢNH BÁO: KHÔNG sử dụng mã đó ( $objectManager->configure($configLoader->load('frontend'));) trong hàm tạo của lớp! Nếu bạn làm và tải cấu hình từ một khu vực khác với khu vực hiện tại của bạn, điều này có thể phá vỡ nghiêm trọng Magento 2!
Wesley Vestjens

@Wesley Vestjens +1 Cảm ơn bạn đã bình luận. Phương pháp đúng thực sự rất khác biệt và tôi đã cập nhật câu trả lời của mình để phản ánh nó. Vui lòng tham khảo [CẬP NHẬT - 2] .
ElGatito

Trên thực tế, chỉ đơn thuần là thiết lập khu vực không hoạt động nếu bạn sử dụng bất kỳ phần nào của lớp xem của Magento 2 (cần thiết để tạo tệp PDF trong Magento 2). Bạn sẽ gặp lỗi liên quan đến đối tượng sau: Magento\Developer\Model\TemplateEngine\Plugin\DebugHintsdebugHintsPathbiến không được đặt. Sử dụng mã gốc của bạn để tải cấu hình DI khu vực ADMINHTML hoạt động hoặc cài đặt thủ công debugHintsPathbiến số, nhưng có thể có các phần bị hỏng khác. Đây thực sự là một "lỗi" trong Magento, vì không thể sử dụng các thành phần lớp xem trong CLI.
Wesley Vestjens

6

Vì CLI ở Magento không có khu vực thích hợp, tôi đã tìm ra cách giải quyết sau:

ứng dụng / mã / 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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.