Видача "Місцевого коду не встановлено" у спеціальних командах CLI у Magento 2


46

Під час оновлення даних я отримую наступну помилку 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.xmlфайл

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

Чи можете ви, будь ласка, показати більше свого коду та дати більше контексту щодо того, що ви намагаєтесь зробити?
Nathan Toombs

Я зіткнувся з тим же питанням. Однак рішення, показане вище, не працює для мене. Це мене бентежить вже тиждень.
Стевенлавін

Відповіді:


63

Область не встановлена ​​в Magento CLI (вона не потрібна для ядерних команд). Його можна встановити на початку методу вашої команди execute:

/** @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
FYI, ти "адміністратор" не працював для мене. "адмін" працював.
Phoenix128_RiccardoT

Для мене це не працює ( adminабо adminhtml) - є помилка: Area code already set. Але тоді, якщо я це прокоментую, знову є виняток із теми.
Bartosz Kubicki

13
Ви повинні використовувати \Magento\Framework\App\Area::AREA_*константи замість жорстко закодованих рядків
7ochem

3
Краще не встановлювати код області у своєму конструкторі; щоразу, коли ви запускаєте, bin/magento всі конструктори виконуються, і якщо код області намагається встановити 2 рази, викидається виняток. Краще встановити код області у вашому execute()-методі або запустити свій код в емуляції магазину або області, якщо потрібно стан. Також: конструкторські залежності, які можуть викликати сеанс вниз по ланцюгу, повинні бути ініціалізовані за допомогою заводських або проксі-серверів, щоб запобігти встановленню коду району для залежностей.
Giel Berkers

1
Відмініть, будь ласка, правильну відповідь. Він створює виняток, коли ми встановлюємо код області в конструкторі.
Сандіпан S

33

Сьогодні я знову наткнувся на цю проблему, і важливо знати, що ця проблема викидається кожного разу, коли залежність вниз по ланцюгу ініціює екземпляр, який повинен знати стан програми.

У багатьох випадках ця помилка пов'язана з сеансом (оскільки сеанс повинен знати стан програми (frontend або adminhtml)).

У моєму випадку мені потрібно було мати Magento\Tax\Api\TaxCalculationInterfaceкоманду CLI, але це вимагає в певний момент її ланцюга залежності сеансу клієнта (можливо, щоб отримати групу клієнтів).

Редагувати: Я знайшов краще рішення за допомогою проксі. Але задля історії, ось моя попередня відповідь:


Для вирішення цього питання я не включив цей інтерфейс у свій конструктор, а скоріше це заводський:

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

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

Таким чином, клас інстанціюється лише в одному методі, де мені це було потрібно, і більше не в конструкторі:

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

Це вирішило для мене проблему в даному конкретному випадку.


А тепер відповідь за допомогою проксі:

Якщо ви не хочете запускати всі залежності по ланцюгу, вам слід використовувати проксі-сервер у своєму конструкторі. Відповідно до оригінальної документації :

... конструкторська інжекція також означає, що ланцюгова реакція при встановленні об'єкта часто є результатом при створенні об'єкта.

і:

... Проксі-сервери поширюють інші класи, щоб стати ліниво завантаженими їх версіями. Тобто реальний екземпляр класу розширюється проксі, створений лише після того, як насправді викликається один із методів класу.

Отже, в моїй ситуації, з тим TaxCalculationInterface, що мені довелося зробити, - це лише обґрунтувати свій податковий розрахунок як проксі в моєму конструкторі:

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

Таким чином мій клас ледаче завантажений. Тобто: це лише примірник, як тільки я називаю один із його методів. Наприклад:

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

17

Не слід використовувати setAreaCodeв __constructкомандах CLI. Коли ви запускаєте будь-яку команду Magento збирайте та створюйте екземпляр для кожного сценарію, зареєстрованого у вашій програмі. Якщо є декілька __constructз визначенням коду області, ви отримаєте помилку.

Я вважаю, що краще використовувати execute()метод для встановлення коду області. Перевірте модуль каталогу: vendor/magento/module-catalog/Console/Command/ImagesResizeCommand.php


1
Має сенс для мене. Хтось ще хоче додати коментар до цього?
ermannob

Це правильно, дивіться також мій коментар до прийнятої відповіді: Краще не встановлювати код області у своєму конструкторі; щоразу, коли ви запускаєте, bin/magento всі конструктори виконуються, і якщо код області намагається встановити 2 рази, викидається виняток. Краще встановити код області у вашому execute()-методі або запустити свій код в емуляції магазину або області, якщо потрібен стан. Також: конструкторські залежності, які можуть викликати сеанс вниз по ланцюгу, повинні бути ініціалізовані за допомогою заводських або проксі-серверів, щоб запобігти встановленню коду району для залежностей.
Giel Berkers

але в Magento 2.2, введення \ Magento \ Продажі \ Api \ Дані \ OrderInterface або \ Magento \ Продажі \ Api \ OrderManagementInterface в конструкти командного класу буде викликати Magento \ Framework \ Session \ SessionManager -> __ construct () і закінчиться "область не набір ". 2.1 цього не відбувається. тому що модуль-ui / Config / Reader / Definition / Data вводиться в 2.2, як ми це вирішимо?
Доні Wibowo

4

для цієї проблеми areaCode, якщо параметр 'frontend' не працює, спробуйте:

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

працював на мене, сподіваюся, що це допомагає


У який файл я повинен додати цей код? У мене точно така ж проблема.
Magento Learner

@xxx У мене була ця проблема із користувацької команди, тому я записав це у створений командний файл. Ви можете додати його у функцію Execute, наприклад:try { $this->_state->... } finally { $this->executeMyCommand() }
DependencyHell

4

У більшості випадків виняток викликається деякими діями, виконаними в консольній команді. Рішенням (замість встановлення коду області) є емуляція коду області та виконання дій з використанням

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

де $stateє об'єкт Magento\Framework\App\State. Налаштування області в іншому місці є проблемою, оскільки це може спричинити конфлікт між дзвінками.


Я використовую цю посилання і отримую аналогічну помилку Код області вже встановлений у моєму контролері, чи можете ви допомогти мені вийти з цього. Я вніс такі зміни, як, викликаючи setareacode у своїй функції конструювання, але отримую ту ж помилку.
Гаган


1

Проблема полягає в тому, що він не має жодного методу, який повертає значення false, якщо змінна area_code не була встановлена. Я вирішив, як я вирішив це, створивши переопределення класу стану та створивши новий метод перевірки, якщо встановлено код_області.

У моєму файлі di.xml

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

Створіть файл 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;
    }
}

Використовуйте

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

У програмі Magento 2, якщо ви встановили AreadCode, але все ж отримуєте цю помилку, то спробуйте наступний код.

  • Використовуйте Magento\Framework\App\Bootstrap;
  • включати app/bootstrap.php;
  • $ bootstrap = Bootstrap::create(BP, $_SERVER);
  • $ objectManager = $bootstrap->getObjectManager();
  • $ state = $objectManager->get('Magento\Framework\App\State');
  • $ state-> setAreaCode ('глобальний');

0

Я страждав від помилки "Код коду не встановлено" працює bin/magento setup:upgradeпісля імпорту бази даних з виробництва. Це трохи інший випадок, ніж ця тема теми, але, можливо, комусь допоможе. Мені вдалося вирішити цю проблему локально, bin/magento deploy:mode:set developerнезважаючи на те, що я вже був у режимі розробника. Magento зробив деякі налаштування конфігурації, спеціально для мене відіграла роль debug_logging.


0

Я отримав рішення за допомогою класу проксі. Приклад є

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

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

Це вирішило мою проблему


-1

Під час оновлення програми я знайшов проблему з кодом області.

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

Я відключив усі модулі сторонніх розробників і запускаю setup:upgrade

Тоді я знову ввімкнув усі сторонні модулі та запускаю ту саму команду. Проблема вирішена для мене. Сподіваюсь, це допомога для вас.


це насправді не є рішенням. Це просто ховати бруд під килим. Але добре знайти все одно. Це має допомогти в процесі розробки, але це не змушує проблему згасати.
Маріус

Дякую, Маріус, що мене виправили. Я знаходжу той самий випадок у більшості своїх проектів, і це допомагає мені вирішити це.
Раві ядів

@Marius, ви б хотіли пояснити, чому, і повідомте людям найбільш канонічний метод вирішення проблеми?
chrBrd

-1

Спробуйте оновити magento за допомогою CLI, ніж я знайшов "код коду не визначає" для сеансу та програми. Але я не можу знайти модуль чи тему. Тому я просто внизу зміни у 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) {
        ...
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.