Problema 'Prefisso locale non impostato' nei comandi CLI personalizzati in Magento 2


46

Ricevo il seguente errore durante l'aggiornamento dei dati 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                              

Di seguito è il mio di.xmlfile

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

Potresti mostrare più del tuo codice e fornire più contesto su ciò che stai cercando di fare?
Nathan Toombs l'

Sto riscontrando lo stesso problema. Tuttavia, la soluzione mostrata sopra non funziona per me. Questo mi ha sconcertato per settimane ormai.
Stevenlavine,

Risposte:


63

L'area non è impostata nell'interfaccia della riga di comando di Magento (non è richiesta per alcun comando principale). Può essere impostato all'inizio del executemetodo del tuo comando :

/** @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
Cordiali saluti, "adminhtml" non funzionava per me. "admin" ha funzionato.
Phoenix128_RiccardoT

Per me non funziona ( admino adminhtml) - c'è un errore: Area code already set. Ma poi, se lo commento, c'è di nuovo un'eccezione dal soggetto.
Bartosz Kubicki,

13
Dovresti usare le \Magento\Framework\App\Area::AREA_*costanti invece delle stringhe hardcoded
7

3
È meglio non impostare il prefisso nel costruttore; ogni volta che si eseguono bin/magento tutti i costruttori vengono eseguiti e se si tenta di impostare il prefisso 2 volte, viene generata un'eccezione. È meglio impostare il prefisso nel proprio execute()metodo, oppure eseguire il codice nell'emulazione del negozio o dell'area se è richiesto lo stato. Inoltre: le dipendenze del costruttore che potrebbero attivare una sessione lungo la catena devono essere inizializzate utilizzando una factory o un proxy per impedire alle dipendenze di impostare un prefisso.
Giel Berkers,

1
Disattivalo come risposta corretta. Crea un'eccezione quando impostiamo il prefisso nel costruttore.
Sandipan S

33

Oggi mi sono imbattuto nuovamente in questo problema ed è importante sapere che questo problema viene generato ogni volta che una dipendenza lungo la catena avvia un'istanza che deve conoscere lo stato dell'applicazione.

In molti casi questo errore è associato alla sessione (poiché la sessione deve conoscere lo stato dell'applicazione (frontend o adminhtml)).

Nel mio caso avevo bisogno di avere Magento\Tax\Api\TaxCalculationInterfaceun comando CLI, ma questo ad un certo punto richiede nella sua catena di dipendenze la sessione del cliente (probabilmente per ottenere il gruppo di clienti).

Modifica: ho trovato una soluzione migliore usando i proxy. Ma per il bene delle storie, ecco la mia risposta precedente:


Per risolvere questo problema non ho incluso questa interfaccia nel mio costruttore, ma piuttosto è 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;
}

In questo modo, la classe viene istanziata solo nell'unico metodo in cui ne avevo bisogno e non più nel costruttore:

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

Ciò ha risolto il problema per me in questo caso particolare.


E ora la risposta usando un proxy:

Se non vuoi innescare tutte le dipendenze lungo la catena, dovresti usare un proxy nel tuo costruttore. Secondo la documentazione originale :

... l'iniezione del costruttore significa anche che una reazione a catena dell'istanza di un oggetto è spesso il risultato quando si crea un oggetto.

e:

... I proxy estendono altre classi per trasformarli in versioni a caricamento lento. Ossia, un'istanza reale della classe estesa da un proxy creata solo dopo che uno dei metodi della classe viene effettivamente chiamato.

Quindi nella mia situazione, con il TaxCalculationInterface, tutto ciò che dovevo fare era creare un'istanza del mio calcolo delle imposte come proxy nel mio costruttore:

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

In questo modo, la mia classe è pigra. Cioè: viene istanziato non appena chiamo uno dei suoi metodi. Per esempio:

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

17

Non si dovrebbe usare setAreaCodenei __constructcomandi per CLI. Quando esegui un comando, Magento raccoglie e crea istanza per ogni script registrato nella tua applicazione. Se ce ne sono più di uno __constructcon la definizione del prefisso, si avrà l'errore.

Suppongo che sia meglio usare il execute()metodo per impostare il prefisso. Controlla il modulo del catalogo: vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php


1
Ha senso per me. Qualcun altro vuole aggiungere un commento su questo?
ermannob,

Questo è corretto, vedi anche il mio commento sulla risposta accettata: è meglio non impostare il prefisso nel costruttore; ogni volta che si eseguono bin/magento tutti i costruttori vengono eseguiti e se si tenta di impostare il prefisso 2 volte, viene generata un'eccezione. È meglio impostare il prefisso nel proprio execute()metodo, oppure eseguire il codice nell'emulazione del negozio o dell'area se è richiesto lo stato. Inoltre: le dipendenze del costruttore che potrebbero attivare una sessione lungo la catena devono essere inizializzate utilizzando una factory o un proxy per impedire alle dipendenze di impostare un prefisso.
Giel Berkers,

ma in Magento 2.2, l'iniezione di \ Magento \ Sales \ Api \ Data \ OrderInterface o \ Magento \ Sales \ Api \ OrderManagementInterface nei costrutti della classe di comando chiamerà Magento \ Framework \ Session \ SessionManager -> __ construct () e finirà "area not impostato". Questo non succede 2.1. perché module-ui / Config / Reader / Definition / Data è stato introdotto in 2.2 come possiamo risolverlo?
Doni Wibowo, il

4

per questo problema areaCode, se il parametro 'frontend' non funziona, provare:

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

stava lavorando per me, spero che sia d'aiuto


In quale file devo aggiungere questo codice? Ho esattamente lo stesso problema.
Magento Learner

@xxx Ho avuto questo problema da un comando personalizzato, quindi l'ho scritto nel file di comando che ho creato. Puoi aggiungerlo nella funzione di esecuzione, con qualcosa del tipo:try { $this->_state->... } finally { $this->executeMyCommand() }
DependencyHell

4

Nella maggior parte dei casi l'eccezione è causata da alcune azioni eseguite nel comando console. La soluzione (invece di impostare il prefisso) è emulare il prefisso ed eseguire l'azione usando

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

dov'è l' $stateoggetto di Magento\Framework\App\State. Impostare un'area in un luogo diverso è un problema, perché può causare conflitti tra le chiamate.


Sto usando questo riferimento e ricevo l'errore simile Il prefisso è già impostato nel mio controller, mi può aiutare per favore a uscire da questo. Ho apportato modifiche come, chiamando setareacode nella mia funzione di costruzione ma ottenendo lo stesso errore.
Gagan,


1

Il problema è che non ha alcun metodo che restituisce false se la variabile area_code non è stata impostata. Il modo in cui l'ho trovato per risolvere è stato creando l'override della classe di stato e creando un nuovo metodo per convalidare se era impostato il codice area.

Nel mio file di.xml

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

File Createad 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;
    }
}

Uso

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

In magento 2 se imposti AreadCode ma ricevi ancora questo errore, prova a seguire il codice.

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

0

Soffrivo dell'errore "Il prefisso non è impostato" in esecuzione bin/magento setup:upgradedopo l'importazione del database dalla produzione. È un caso un po 'diverso rispetto a questo argomento, ma forse aiuterà qualcuno. Sono stato in grado di risolvere questo problema localmente in esecuzione bin/magento deploy:mode:set developernonostante fossi già in modalità sviluppatore. Magento ha apportato alcune modifiche alla configurazione, specialmente per me il ruolo svolto da debug_logging.


0

Ho ottenuto la soluzione utilizzando la classe proxy. L'esempio è

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

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

Questo risolto il mio problema


-1

Ho riscontrato lo stesso problema con il prefisso durante l'aggiornamento dell'installazione.

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

Ho disabilitato tutti i moduli di terze parti ed eseguo setup:upgrade

Quindi ho riattivato tutti i moduli di terze parti ed eseguo lo stesso comando. Il problema è risolto per me Spero che questo sia di aiuto per te.


questa non è in realtà una soluzione. Sta solo nascondendo lo sporco sotto il tappeto. Ma buona scoperta comunque. Dovrebbe aiutare durante il processo di sviluppo, ma non risolve il problema.
Marius

Grazie Marius per avermi corretto. Ho trovato lo stesso caso nella maggior parte del mio progetto e questo mi aiuta a risolverlo.
Ravi yadav,

@Marius, ti dispiacerebbe spiegare perché e far conoscere alle persone il metodo più canonico per risolvere il problema?
chrBrd

-1

Prova ad aggiornare magento usando l'interfaccia della riga di comando di quanto ho trovato 'prefisso non definito' per la sessione e l'app. Ma non riesco a trovare quale modulo o tema. Quindi faccio solo le modifiche al vendor/magento/framework/App/State.phpfile e funziona.

public function __construct(
    \Magento\Framework\Config\ScopeInterface $configScope,
    $mode = self::MODE_DEFAULT
) {
    $this->_areaCode = Area::AREA_GLOBAL;
    $this->_configScope = $configScope;
    switch ($mode) {
        ...
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.