Masalah 'Kode area tidak disetel' dalam perintah CLI khusus di Magento 2

46

Saya menerima galat berikut saat memperbarui data melalui CustomerRepositoryInterface

[Magento\Framework\Exception\SessionException]  
Area code not set: Area code must be set before starting a session.

[Magento\Framework\Exception\LocalizedException]  
Area code is not set                              

Berikut ini adalah di.xmlfile saya

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandList">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="test1_command" xsi:type="object">Test\Module\Console\Command\Test1Command</item>
                <item name="test2_command" xsi:type="object">Test\Module\Console\Command\Test2Command</item>
            </argument>
        </arguments>
    </type>
</config>
SK.
sumber
Bisakah Anda menunjukkan lebih banyak kode Anda dan memberikan lebih banyak konteks tentang apa yang Anda coba lakukan?
Nathan Toombs
Saya mengalami masalah yang sama. Namun solusi yang ditunjukkan di atas tidak bekerja untuk saya. Ini telah membingungkan saya selama berminggu-minggu sekarang.
Stevenlavine

Jawaban:

63

Area tidak diatur dalam Magento CLI (tidak diperlukan untuk perintah inti apa pun). Itu dapat diatur di awal executemetode perintah Anda :

/** @var \Magento\Framework\App\State **/
private $state;

public function __construct(\Magento\Framework\App\State $state) {
    $this->state = $state;
    parent::__construct();
}

public function execute() {
    $this->state->setAreaCode(\Magento\Framework\App\Area::AREA_FRONTEND); // or \Magento\Framework\App\Area::AREA_ADMINHTML, depending on your needs
}
Alex Paliarush
sumber
6
FYI, Anda "adminhtml" tidak berfungsi untuk saya. "admin" berhasil.
Phoenix128_RiccardoT
Bagi saya itu tidak bekerja ( adminatau adminhtml) - ada kesalahan: Area code already set. Tetapi kemudian, jika saya berkomentar, ada pengecualian dari subjek lagi.
Bartosz Kubicki
13
Anda harus menggunakan \Magento\Framework\App\Area::AREA_*konstanta alih-alih string hardcoded
7ochem
3
Yang terbaik adalah tidak mengatur kode area di konstruktor Anda; setiap kali Anda menjalankan bin/magento semua konstruktor dieksekusi, dan jika kode area dicoba untuk ditetapkan 2 kali pengecualian dilemparkan. Lebih baik mengatur kode area di execute()-metode Anda , atau menjalankan kode Anda di emulasi store- atau area jika diperlukan. Juga: dependensi konstruktor yang dapat memicu sesi ke bawah rantai harus diinisialisasi menggunakan pabrik atau proxy untuk mencegah dependensi dari pengaturan kode area.
Giel Berkers
1
Batalkan setel sebagai jawaban yang benar. Itu menciptakan pengecualian ketika kita menetapkan kode area di konstruktor.
Sandipan S
33

Saya telah menemukan masalah ini lagi hari ini dan penting untuk mengetahui bahwa masalah ini dilemparkan setiap kali ketergantungan pada rantai memulai sebuah contoh yang perlu mengetahui keadaan aplikasi.

Dalam banyak kasus kesalahan ini terikat pada sesi (karena sesi perlu mengetahui keadaan aplikasi (frontend atau adminhtml)).

Dalam kasus saya, saya perlu memiliki Magento\Tax\Api\TaxCalculationInterfaceperintah CLI, tetapi ini memerlukan pada beberapa titik dalam rantai ketergantungan sesi pelanggan (mungkin untuk mendapatkan kelompok pelanggan).

Sunting: Saya menemukan solusi yang lebih baik menggunakan proxy. Tapi demi sejarah, inilah jawaban saya sebelumnya:


Untuk mengatasi ini saya tidak menyertakan antarmuka ini dalam konstruktor saya, tetapi ini adalah pabrik:

/**
 * @var \Magento\Tax\Api\TaxCalculationInterfaceFactory
 */
protected $taxCalculationFactory;

/**
 * @param \Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
 */
public function __construct(
    \Magento\Tax\Api\TaxCalculationInterfaceFactory $taxCalculationFactory
) {
    $this->taxCalculationFactory = $taxCalculationFactory;
}

Dengan cara ini, kelas hanya dipakai di satu metode di mana saya membutuhkannya, dan tidak lagi di konstruktor:

$taxCalculation = $this->taxCalculationFactory->create();

Ini memecahkan masalah bagi saya dalam kasus khusus ini.


Dan sekarang jawabannya menggunakan proxy:

Jika Anda tidak ingin memicu semua dependensi ke rantai, Anda harus menggunakan proxy di konstruktor Anda. Menurut dokumentasi asli :

... injeksi konstruktor juga berarti bahwa reaksi berantai instantiasi objek sering terjadi ketika Anda membuat objek.

dan:

... Proxy memperluas kelas lain untuk menjadi versi yang malas dari mereka. Yaitu, contoh nyata dari kelas yang diperluas oleh proxy yang dibuat hanya setelah salah satu metode kelas benar-benar dipanggil.

Jadi dalam situasi saya, dengan TaxCalculationInterface, yang harus saya lakukan adalah membuat perhitungan pajak saya sebagai proksi dalam konstruktor saya:

/**
 * @var \Magento\Tax\Api\TaxCalculationInterface\Proxy
 */
protected $taxCalculation;

/**
 * @param \Magento\Tax\Api\TaxCalculationInterface\Proxy $taxCalculation
 */
public function __construct(
    \Magento\Tax\Api\TaxCalculationInterface\Proxy $taxCalculation
) {
    $this->taxCalculation = $taxCalculation;
}

Dengan cara ini, kelas saya dimuat dengan malas. Yaitu: itu hanya dipakai segera setelah saya memanggil salah satu metode itu. Sebagai contoh:

$rate = $this->taxCalculation->getCalculatedRate($productRateId);
Giel Berkers
sumber
17

Anda tidak harus menggunakan setAreaCodedalam __constructuntuk perintah CLI. Saat Anda menjalankan perintah apa pun, Magento mengumpulkan dan membuat instance untuk setiap skrip yang terdaftar dalam aplikasi Anda. Jika ada lebih dari satu __constructdengan definisi kode area Anda akan memiliki kesalahan.

Saya kira lebih baik menggunakan execute()metode untuk mengatur kode area. Periksa modul katalog: vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php

Eugene Kovalyov
sumber
1
Masuk akal bagi saya. Adakah yang ingin menambahkan komentar tentang ini?
ermannob
Ini benar, lihat juga komentar saya pada jawaban yang diterima: Sebaiknya jangan mengatur kode area di konstruktor Anda; setiap kali Anda menjalankan bin/magento semua konstruktor dieksekusi, dan jika kode area dicoba untuk ditetapkan 2 kali pengecualian dilemparkan. Lebih baik mengatur kode area di execute()-metode Anda , atau menjalankan kode Anda di emulasi store- atau area jika diperlukan. Juga: dependensi konstruktor yang dapat memicu sesi ke bawah rantai harus diinisialisasi menggunakan pabrik atau proxy untuk mencegah dependensi dari pengaturan kode area.
Giel Berkers
tetapi di Magento 2.2, menyuntikkan \ Magento \ Sales \ Api \ Data \ OrderInterface atau \ Magento \ Sales \ Api \ OrderManagementInterface dalam konstruk kelas perintah akan memanggil Magento \ Framework \ Session \ SessionManager -> __ construct () dan akan berakhir "area tidak set". Ini tidak terjadi 2.1. karena module-ui / Config / Reader / Definition / Data diperkenalkan pada 2.2 bagaimana kita menyelesaikan ini?
Doni Wibowo
4

untuk masalah areaCode ini, jika parameter 'frontend' tidak berfungsi, coba:

$this->_state->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);

bekerja untuk saya, semoga membantu

Ketergantungan
sumber
Di file mana saya harus menambahkan kode ini? Saya memiliki masalah yang persis sama.
Magento Learner
@xxx Saya mendapatkan masalah ini dari perintah khusus, jadi saya menulis ini di file perintah yang saya buat. Anda dapat menambahkannya di fungsi eksekusi, dengan sesuatu seperti:try { $this->_state->... } finally { $this->executeMyCommand() }
DependencyHell
4

Dalam kebanyakan kasus pengecualian disebabkan oleh beberapa tindakan yang dilakukan dalam perintah konsol. Solusi (alih-alih mengatur kode area) adalah meniru kode area dan melakukan tindakan menggunakan

$this->state->emulateAreaCode(Area::AREA_ADMINHTML, [$this, 'someAction'], []);

dimana $stateobjek Magento\Framework\App\State. Pengaturan area di tempat yang berbeda adalah masalah, karena dapat menyebabkan konflik antar panggilan.

Bartosz Kubicki
sumber
Saya menggunakan referensi ini dan mendapatkan kode Area kesalahan serupa sudah diatur di controller saya, bisa tolong bantu saya untuk keluar dari ini. Saya telah membuat perubahan seperti, memanggil setareacode di fungsi konstruk saya tetapi mendapatkan kesalahan yang sama.
Gagan
1

Masalahnya adalah ia tidak memiliki metode apa pun yang mengembalikan false jika variabel area_code belum disetel. Cara saya menemukannya untuk dipecahkan adalah dengan membuat override dari kelas negara dan membuat metode baru untuk memvalidasi jika area_code disetel.

Di file saya di.xml

    <preference for="Magento\Framework\App\State" type="Webjump\Abacos\App\State" />

Buat file Webjump \ Abacos \ App \ State

namespace Webjump\Abacos\App;

class State extends \Magento\Framework\App\State
{
    public function validateAreaCode()
    {
        if (!isset($this->_areaCode)) {
            return false;
        }
        return true;
    }
}

Menggunakan

/**
* @var \Magento\Framework\App\State
*/
protected $state;

public function __construct(
            \Magento\Framework\App\State $state
)
{
$this->state = $state;
if (!$this->state->validateAreaCode()) {
 $this->state->setAreaCode(\Magento\Framework\App\Area::AREA_ADMINHTML);
}
}
Luan Alves
sumber
1

Di magento 2 jika Anda mengatur AreadCode tetapi masih mendapatkan kesalahan ini, silakan coba kode berikut.

  • Menggunakan Magento\Framework\App\Bootstrap;
  • termasuk app/bootstrap.php;
  • $ bootstrap = Bootstrap::create(BP, $_SERVER);
  • $ objectManager = $bootstrap->getObjectManager();
  • $ state = $objectManager->get('Magento\Framework\App\State');
  • $ state-> setAreaCode ('global');
rakesh prajapati
sumber
0

Saya menderita kesalahan 'Kode area tidak disetel' berjalan bin/magento setup:upgradesetelah mengimpor basis data dari produksi. Ini kasus yang sedikit berbeda dari subjek topik ini, tetapi mungkin akan membantu seseorang. Saya dapat menyelesaikan masalah ini secara lokal bin/magento deploy:mode:set developermeskipun saya sudah dalam mode pengembang. Magento melakukan beberapa penyesuaian konfigurasi, khusus untuk saya peran debug_logging.

Artem Klimoff
sumber
0

Saya mendapatkan solusinya dengan menggunakan kelas proxy. Contohnya adalah

use Klevu\Search\Model\Product\MagentoProductActionsInterface\Proxy as MagentoProductActionsInterface;

public function __construct(
        MagentoProductActionsInterface $magentoProductActionsInterface
    )
    {
        $this->_magentoProductActionsInterface = $magentoProductActionsInterface;
        parent::__construct();
    }

Ini memperbaiki masalah saya

Tejas Vyas
sumber
-1

Saya telah menemukan masalah yang sama dengan kode Area saat menyiapkan peningkatan.

Module 'Magento_WebsiteRestriction':Installing data... Area code not set: Area code must be set before starting a session

Saya telah menonaktifkan semua modul pihak ketiga dan menjalankan setup:upgrade

Kemudian saya telah mengaktifkan kembali semua modul pihak ketiga dan menjalankan perintah yang sama. Masalah terpecahkan untuk saya. Semoga ini bisa membantu Anda.

Ravi yadav
sumber
ini sebenarnya bukan solusi. Itu hanya menyembunyikan kotoran di bawah permadani. Tapi tetap bagus. Seharusnya membantu selama proses pengembangan, tetapi tidak membuat masalah hilang.
Marius
Terima kasih, Marius, telah mengoreksi saya. Saya telah menemukan kasus yang sama di sebagian besar proyek saya dan ini membantu saya untuk menyelesaikannya.
Ravi yadav
@Marius, maukah Anda menjelaskan alasannya, dan biarkan orang tahu metode paling kanonik untuk menyelesaikan masalah?
chrBrd
-1

Cobalah untuk meningkatkan magento menggunakan CLI daripada yang saya temukan 'kode area tidak mendefinisikan' untuk sesi & aplikasi vendor/magento/framework/App/State.php.

public function __construct(
    \Magento\Framework\Config\ScopeInterface $configScope,
    $mode = self::MODE_DEFAULT
) {
    $this->_areaCode = Area::AREA_GLOBAL;
    $this->_configScope = $configScope;
    switch ($mode) {
        ...
    }
}
himansu
sumber