Problem „Nie ustawiono kodu obszaru” w niestandardowych komendach CLI w Magento 2


46

Podczas aktualizacji danych pojawia się błąd 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                              

Oto mój di.xmlplik

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

Czy mógłbyś pokazać więcej swojego kodu i dać więcej kontekstu, co próbujesz zrobić?
Nathan Toombs

Mam ten sam problem. Jednak pokazane powyżej rozwiązanie nie działa dla mnie. To mnie denerwuje od tygodni.
Stevenlavine

Odpowiedzi:


63

Obszar nie jest ustawiony w Magento CLI (nie jest wymagany dla żadnych podstawowych poleceń). Można go ustawić na początku executemetody polecenia :

/** @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
}

6
Do Twojej wiadomości „adminhtml” nie działał dla mnie. „admin” działał.
Phoenix128_RiccardoT

Dla mnie to nie działa ( adminlub adminhtml) - wystąpił błąd: Area code already set. Ale jeśli to skomentuję, będzie wyjątek od tematu.
Bartosz Kubicki

13
Powinieneś używać \Magento\Framework\App\Area::AREA_*stałych zamiast ciągów zakodowanych na stałe
7ochem

3
Najlepiej nie ustawiać kodu obszaru w swoim konstruktorze; przy każdym uruchomieniu bin/magento wszystkie konstruktory są wykonywane i jeśli próbujesz ustawić kod obszaru 2 razy, zgłaszany jest wyjątek. Lepiej ustawić kod obszaru w execute()metodzie lub uruchomić kod w emulacji sklepu lub obszaru, jeśli wymagany jest stan. Ponadto: zależności konstruktora, które mogą wyzwalać sesję w dół łańcucha, należy zainicjować za pomocą fabryki lub serwera proxy, aby zapobiec ustawianiu kodu obszaru przez zależności.
Giel Berkers

1
Proszę odznaczyć to jako poprawną odpowiedź. Tworzy wyjątek, gdy ustawiamy kod obszaru w konstruktorze.
Sandipan S

33

Znowu natknąłem się na ten problem dzisiaj i ważne jest, aby wiedzieć, że ten problem jest zgłaszany, ilekroć zależność w dół łańcucha inicjuje instancję, która musi znać stan aplikacji.

W wielu przypadkach błąd ten jest związany z sesją (ponieważ sesja musi znać stan aplikacji (frontend lub adminhtml)).

W moim przypadku musiałem mieć Magento\Tax\Api\TaxCalculationInterfacekomendę CLI, ale wymaga to w pewnym momencie łańcucha zależności sesji klienta (prawdopodobnie w celu uzyskania grupy klientów).

Edycja: Znalazłem lepsze rozwiązanie przy użyciu serwerów proxy. Ale ze względu na historię, oto moja poprzednia odpowiedź:


Aby rozwiązać ten problem, nie dodałem tego interfejsu do mojego konstruktora, ale raczej jest on fabryczny:

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

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

W ten sposób klasa jest tworzona tylko w jednej metodzie, w której jej potrzebowałem, a nie w konstruktorze:

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

To rozwiązało problem w tym konkretnym przypadku.


A teraz odpowiedź za pomocą proxy:

Jeśli nie chcesz wyzwalać wszystkich zależności w dół łańcucha, powinieneś użyć proxy w swoim konstruktorze. Według oryginalnej dokumentacji :

... wstrzyknięcie konstruktora oznacza również, że reakcja łańcuchowa tworzenia instancji obiektu jest często wynikiem tworzenia obiektu.

i:

... Proxy rozszerzają inne klasy, by stały się ich leniwymi wersjami. Oznacza to, że rzeczywista instancja klasy, którą rozszerza serwer proxy, tworzona tylko po wywołaniu jednej z metod klasy.

Więc w mojej sytuacji, jedyne TaxCalculationInterface, co musiałem zrobić, to utworzyć kalkulację podatkową jako przybliżenie w moim konstruktorze:

/**
 * @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;
}

W ten sposób moja klasa jest leniwie załadowana. To znaczy: jest on tworzony tylko wtedy, gdy wywołam jedną z jego metod. Na przykład:

$rate = $this->taxCalculation->getCalculatedRate($productRateId);

17

Nie należy używać setAreaCodew poleceniach __constructfor CLI. Po uruchomieniu dowolnego polecenia Magento zbiera i tworzy instancję dla każdego skryptu zarejestrowanego w aplikacji. Jeśli jest więcej niż jeden __constructz definicją numeru kierunkowego, wystąpi błąd.

Przypuszczam, że lepiej użyć tej execute()metody do ustawienia kodu kierunkowego. Sprawdź moduł katalogu: vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php


1
Dla mnie to ma sens. Czy ktoś jeszcze chce dodać komentarz na ten temat?
ermannob

Jest to poprawne, patrz także mój komentarz do zaakceptowanej odpowiedzi: Najlepiej nie ustawiać kodu obszaru w swoim konstruktorze; przy każdym uruchomieniu bin/magento wszystkie konstruktory są wykonywane i jeśli próbujesz ustawić kod obszaru 2 razy, zgłaszany jest wyjątek. Lepiej ustawić kod obszaru w execute()metodzie lub uruchomić kod w emulacji sklepu lub obszaru, jeśli wymagany jest stan. Ponadto: zależności konstruktora, które mogą wyzwalać sesję w dół łańcucha, należy zainicjować za pomocą fabryki lub serwera proxy, aby zapobiec ustawianiu kodu obszaru przez zależności.
Giel Berkers

ale w Magento 2.2 wstrzyknięcie \ Magento \ Sales \ Api \ Data \ OrderInterface lub \ Magento \ Sales \ Api \ OrderManagementInterface w konstrukcjach klas poleceń wywoła Magento \ Framework \ Session \ SessionManager -> __ construct () i zakończy się "obszarem nie zestaw". Tak się nie dzieje 2.1. ponieważ moduł-ui / Config / Reader / Definition / Data jest wprowadzony w 2.2, jak to rozwiązać?
Doni Wibowo

4

w przypadku tego kodu areaCode, jeśli parametr „frontend” nie działa, spróbuj:

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

pracował dla mnie, mam nadzieję, że to pomaga


W jakim pliku powinienem dodać ten kod? Mam dokładnie ten sam problem.
Magento Learner,

@xxx Miałem ten problem z polecenia niestandardowego, więc napisałem to w utworzonym pliku poleceń. Możesz dodać go do funkcji wykonywania za pomocą czegoś takiego:try { $this->_state->... } finally { $this->executeMyCommand() }
DependencyHell

4

W większości przypadków wyjątek jest spowodowany niektórymi czynnościami wykonywanymi w poleceniu konsoli. Rozwiązaniem (zamiast ustawiania numeru kierunkowego) jest emulacja numeru kierunkowego i wykonywanie akcji za pomocą

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

gdzie $statejest przedmiotem Magento\Framework\App\State. Ustawienie obszaru w innym miejscu jest problemem, ponieważ może powodować konflikt między połączeniami.


Korzystam z tego odniesienia i otrzymuję podobny błąd Kod obszaru jest już ustawiony w moim kontrolerze, czy możesz mi pomóc wydostać się z tego. Wprowadziłem zmiany, takie jak wywołanie setareacode w mojej funkcji konstrukcyjnej, ale otrzymałem ten sam błąd.
Gagan


1

Problem polega na tym, że nie ma żadnej metody, która zwraca false, jeśli zmienna kod_pola nie została ustawiona. Sposób, w jaki znalazłem to rozwiązanie, polegał na utworzeniu zastąpienia klasy stanu i utworzeniu nowej metody sprawdzania poprawności, jeśli został ustawiony kod_pola.

W moim pliku di.xml

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

Utwórz plik 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;
    }
}

Posługiwać się

/**
* @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);
}
}

1

W Magento 2, jeśli ustawisz AreadCode, ale nadal pojawia się ten błąd, spróbuj wykonać następujący kod.

  • Posługiwać się Magento\Framework\App\Bootstrap;
  • zawierać app/bootstrap.php;
  • $ bootstrap = Bootstrap::create(BP, $_SERVER);
  • $ objectManager = $bootstrap->getObjectManager();
  • Stan $ = $objectManager->get('Magento\Framework\App\State');
  • $ state-> setAreaCode ('global');

0

Wystąpił błąd „Kod obszaru nie jest ustawiony” uruchomiony bin/magento setup:upgradepo importowaniu bazy danych z produkcji. To trochę inna sprawa niż ten temat, ale może komuś pomoże. Byłem w stanie rozwiązać ten problem działający lokalnie, bin/magento deploy:mode:set developermimo że byłem już w trybie programisty. Magento dokonało pewnych modyfikacji konfiguracji, specjalnie dla mnie odegrała rolę debug_logging.


0

Mam rozwiązanie za pomocą klasy proxy. Przykładem jest

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

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

To naprawiło mój problem


-1

Znalazłem ten sam problem z numerem kierunkowym podczas aktualizacji instalacji.

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

Wyłączyłem wszystkie moduły stron trzecich i uruchomiłem setup:upgrade

Następnie ponownie włączyłem wszystkie moduły innych firm i uruchomiłem to samo polecenie. Problem został dla mnie rozwiązany. Mam nadzieję, że to jest pomoc dla ciebie.


to nie jest rozwiązanie. Po prostu chowa brud pod dywanikiem. Ale i tak dobre znalezisko. Powinno to pomóc w procesie rozwoju, ale nie rozwiązuje problemu.
Marius

Dziękuję Marius za poprawienie mnie. Znalazłem ten sam przypadek w większości moich projektów i to pomaga mi rozwiązać ten problem.
Ravi yadav

@Marius, czy zechciałbyś wyjaśnić, dlaczego i dać ludziom znać najbardziej kanoniczną metodę rozwiązania problemu?
chrBrd

-1

Spróbuj zaktualizować Magento przy użyciu interfejsu CLI, niż znalazłem „numer kierunkowy nie definiuje” dla sesji i aplikacji, ale nie mogę znaleźć modułu lub motywu, więc po prostu wykonuję poniższe zmiany w vendor/magento/framework/App/State.phppliku i działa.

public function __construct(
    \Magento\Framework\Config\ScopeInterface $configScope,
    $mode = self::MODE_DEFAULT
) {
    $this->_areaCode = Area::AREA_GLOBAL;
    $this->_configScope = $configScope;
    switch ($mode) {
        ...
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.