In Magento 2 wurde in benutzerdefinierten CLI-Befehlen das Problem "Vorwahl nicht festgelegt" festgestellt


46

Beim Aktualisieren der Daten erhalte ich folgende Fehlermeldung 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                              

Es folgt meine di.xmlAkte

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

Könnten Sie bitte mehr von Ihrem Code zeigen und mehr Kontext zu dem geben, was Sie versuchen zu tun?
Nathan Toombs

Ich stoße auf dasselbe Problem. Die oben gezeigte Lösung funktioniert jedoch nicht für mich. Das verwirrt mich schon seit Wochen.
Stevenlavine

Antworten:


63

Der Bereich ist in Magento CLI nicht festgelegt (für Kernbefehle nicht erforderlich). Sie kann zu Beginn der executeMethode Ihres Befehls festgelegt werden:

/** @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
Zu Ihrer Information, Sie "adminhtml" hat bei mir nicht funktioniert. "admin" hat funktioniert.
Phoenix128_RiccardoT

Für mich ist es nicht (funktioniert adminoder adminhtml) - gibt es einen Fehler: Area code already set. Aber dann, wenn ich es auskommentiere, gibt es wieder eine Ausnahme vom Thema.
Bartosz Kubicki

13
Sie sollten \Magento\Framework\App\Area::AREA_*Konstanten anstelle von fest codierten Zeichenfolgen verwenden
7ochem

3
Es ist am besten, die Ortsvorwahl nicht in Ihrem Konstruktor festzulegen. Jedes Mal, wenn Sie ausführen, werden bin/magento alle Konstruktoren ausgeführt, und wenn versucht wird, die Ortsvorwahl zweimal festzulegen, wird eine Ausnahme ausgelöst. Es ist besser, die Ortsvorwahl in Ihrer execute()-Methode festzulegen oder sie in der Speicher- oder Gebietsemulation auszuführen, wenn der Status erforderlich ist. Außerdem: Konstruktorabhängigkeiten, die eine Sitzung in der Kette auslösen könnten, sollten mithilfe einer Factory oder eines Proxys initialisiert werden, um zu verhindern, dass Abhängigkeiten eine Vorwahl festlegen.
Giel Berkers

1
Bitte deaktivieren Sie es als richtige Antwort. Es erzeugt eine Ausnahme, wenn wir die Vorwahl im Konstruktor setzen.
Sandipan S

33

Ich bin heute wieder auf dieses Problem gestoßen, und es ist wichtig zu wissen, dass dieses Problem immer dann auftritt, wenn eine Abhängigkeit in der Kette eine Instanz initiiert, die den Status der Anwendung kennen muss.

In vielen Fällen ist dieser Fehler sitzungsgebunden (da die Sitzung den Status der Anwendung (Frontend oder Adminhtml) kennen muss).

In meinem Fall musste ich Magento\Tax\Api\TaxCalculationInterfacein einem CLI-Befehl, aber dies erfordert irgendwann in seiner Abhängigkeitskette die Kundensitzung (wahrscheinlich, um die Kundengruppe zu erhalten).

Edit: Ich habe eine bessere Lösung mit Proxies gefunden. Aber um der Geschichte willen, hier ist meine vorherige Antwort:


Um dies zu lösen, habe ich dieses Interface nicht in meinen Konstruktor aufgenommen, sondern es ist Factory:

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

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

Auf diese Weise wird die Klasse nur in der einen Methode instanziiert, in der ich sie benötigte, und nicht mehr im Konstruktor:

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

Dies löste das Problem für mich in diesem speziellen Fall.


Und jetzt die Antwort per Proxy:

Wenn Sie nicht alle Abhängigkeiten in der Kette auslösen möchten, sollten Sie einen Proxy in Ihrem Konstruktor verwenden. Nach Angaben der Original - Dokumentation :

... Konstruktorinjektion bedeutet auch, dass eine Kettenreaktion der Objektinstanziierung häufig die Folge ist, wenn Sie ein Objekt erstellen.

und:

... Proxies erweitern andere Klassen, um faul geladene Versionen von ihnen zu werden. Dies bedeutet, dass eine reale Instanz der Klasse, die ein Proxy erweitert, erst erstellt wird, nachdem eine der Methoden der Klasse tatsächlich aufgerufen wurde.

Also musste ich in meiner Situation mit dem nur TaxCalculationInterfacemeine Steuerberechnung als Proxy in meinem Konstruktor instanziieren:

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

Auf diese Weise ist meine Klasse faul geladen. Das heißt: Es wird nur instanziiert, sobald ich eine seiner Methoden aufrufe. Zum Beispiel:

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

17

Sie sollten setAreaCodein den __constructBefehlen für CLI nicht verwenden . Wenn Sie einen Befehl ausführen, sammelt und erstellt Magento eine Instanz für jedes in Ihrer Anwendung registrierte Skript. Wenn es mehr als eine __constructmit Vorwahldefinition gibt, tritt der Fehler auf.

Ich nehme an, es ist besser, die execute()Methode zum Festlegen der Ortsvorwahl zu verwenden. Überprüfen Sie das Katalogmodul: vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php


1
Für mich ergibt das Sinn. Möchte noch jemand einen Kommentar dazu abgeben?
Ermannob

Dies ist richtig, siehe auch meinen Kommentar zur akzeptierten Antwort: Es ist am besten, die Vorwahl nicht in Ihrem Konstruktor festzulegen; Jedes Mal, wenn Sie ausführen, werden bin/magento alle Konstruktoren ausgeführt, und wenn versucht wird, die Ortsvorwahl zweimal festzulegen, wird eine Ausnahme ausgelöst. Es ist besser, die Ortsvorwahl in Ihrer execute()-Methode festzulegen oder sie in der Speicher- oder Gebietsemulation auszuführen, wenn der Status erforderlich ist. Außerdem: Konstruktorabhängigkeiten, die eine Sitzung in der Kette auslösen könnten, sollten mithilfe einer Factory oder eines Proxys initialisiert werden, um zu verhindern, dass Abhängigkeiten eine Vorwahl festlegen.
Giel Berkers

In Magento 2.2 wird beim Injizieren von "\ Magento \ Sales \ Api \ Data \ OrderInterface" oder "\ Magento \ Sales \ Api \ OrderManagementInterface" in Befehlsklassenkonstrukten "Magento \ Framework \ Session \ SessionManager -> __ construct ()" aufgerufen einstellen". Das passiert nicht 2.1. weil Modul-UI / Config / Reader / Definition / Daten in 2.2 eingeführt wird, wie lösen wir das?
Doni Wibowo

4

Wenn der Parameter 'frontend' bei diesem areaCode-Problem nicht funktioniert, versuchen Sie Folgendes:

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

arbeitete für mich, hoffe es hilft


In welcher Datei soll ich diesen Code einfügen? Ich habe genau das gleiche Problem.
Magento Learner

@xxx Ich hatte dieses Problem aufgrund eines benutzerdefinierten Befehls. Deshalb habe ich dies in die von mir erstellte Befehlsdatei geschrieben. Sie können es in der Execute-Funktion hinzufügen, mit so etwas wie:try { $this->_state->... } finally { $this->executeMyCommand() }
DependencyHell

4

In den meisten Fällen wird die Ausnahme durch einige Aktionen verursacht, die im Konsolenbefehl ausgeführt werden. Die Lösung (anstatt die Vorwahl einzustellen) besteht darin, die Vorwahl zu emulieren und die Aktion mit auszuführen

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

wo $stateist Gegenstand von Magento\Framework\App\State. Das Festlegen eines Bereichs an einem anderen Ort ist ein Problem, da es zu Konflikten zwischen Anrufen kommen kann.


Ich verwende diese Referenz und erhalte den ähnlichen Fehler. Die Vorwahl ist bereits in meinem Controller eingestellt. Können Sie mir bitte helfen, diesen Fehler zu beheben? Ich habe Änderungen vorgenommen wie: setareacode in meiner Konstruktfunktion aufrufen, aber den gleichen Fehler erhalten.
Gagan


1

Das Problem ist, dass es keine Methode gibt, die false zurückgibt, wenn die Variable area_code nicht festgelegt wurde. Ich fand es zu lösen, indem ich eine Überschreibung der Zustandsklasse erstellte und eine neue Methode erstellte, um zu überprüfen, ob die area_code gesetzt war.

In meiner Datei di.xml

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

Erstellen Sie die Datei 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;
    }
}

Verwenden

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

Wenn Sie in Magento 2 AreadCode einstellen, aber dennoch diese Fehlermeldung erhalten, versuchen Sie bitte den folgenden Code.

  • Verwenden Magento\Framework\App\Bootstrap;
  • umfassen app/bootstrap.php;
  • $ bootstrap = Bootstrap::create(BP, $_SERVER);
  • $ objectManager = $bootstrap->getObjectManager();
  • $ state = $objectManager->get('Magento\Framework\App\State');
  • $ state-> setAreaCode ('global');

0

Ich hatte den Fehler "Vorwahl ist nicht eingestellt", bin/magento setup:upgradenachdem die Datenbank aus der Produktion importiert wurde. Es ist ein bisschen anders als in diesem Thema, aber vielleicht hilft es jemandem. Ich konnte dieses Problem lokal beheben, bin/magento deploy:mode:set developerobwohl ich mich bereits im Entwicklermodus befand. Magento hat einige Konfigurationsanpassungen vorgenommen, speziell für mich spielte debug_logging eine Rolle.


0

Ich habe die Lösung mithilfe der Proxy-Klasse erhalten. Beispiel ist

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

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

Dies hat mein Problem behoben


-1

Ich habe das gleiche Problem mit der Vorwahl beim Setup-Upgrade festgestellt.

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

Ich habe alle Module von Drittanbietern deaktiviert und lauffähig gemacht setup:upgrade

Dann habe ich alle Module von Drittanbietern wieder aktiviert und den gleichen Befehl ausgeführt. Problem ist für mich gelöst Hoffe das ist Hilfe für dich.


das ist eigentlich keine lösung. Es versteckt nur den Schmutz unter dem Teppich. Aber trotzdem gut zu finden. Es sollte während des Entwicklungsprozesses helfen, aber es lässt das Problem nicht verschwinden.
Marius

Danke Marius, dass du mich korrigiert hast. Ich habe den gleichen Fall in den meisten meiner Projekte gefunden und dies hilft mir, dies zu beheben.
Ravi Yadav

@Marius, würden Sie gerne erklären, warum und die kanonischste Methode zur Behebung des Problems kennenlernen?
17.

-1

Versuchen Sie, Magento mit der CLI zu aktualisieren, als ich "Vorwahl nicht definiert" für Sitzung & App gefunden habe. Aber ich kann nicht finden, welches Modul oder Thema 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) {
        ...
    }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.