Magento 2: Как правильно установить состояние приложения "Код города"? (setareacode, getAreaCode) (Установить код, получить код)


Я вижу, что информации об использовании состояний приложений не так много, а если и есть, то она работает неправильно. Итак, ниже приведен мой ответ, основанный на моем собственном расследовании.

Author: André Ferraz, 2018-04-17

1 answers

Есть это сообщение в блоге нашего друга Алана Шторма, которым, похоже, пользуется большинство людей. Проблема в том, что это действительно не работает должным образом, вот почему.

НЕ ДЕЛАЙ ЭТОГО

  1. Используйте setAreaCode или getAreaCode в __constructor. Это плохо! Когда вы запускаете команду, magento создает список всех команд, доступных в системе, а затем проверяет, есть ли запрошенная команда в списке. Это не только делает это, но и инициализирует класс команд, поэтому, если в __конструкторе __ первой команды есть setAreaCode. все остальные команды с собственным кодом области завершатся ошибкой (если у них нет обработчика исключений) или не будут использовать правильный код области (если у них есть обработчик исключений), это связано с тем, что нет способа отменить код области.

  2. Используйте setAreaCode или getAreaCode в функции configure, результаты, аналогичные приведенным выше, в основном, когда вы делаете bin/magento. Magento инициализирует класс команд, а затем configure функция.

Мое личное мнение состоит в том, чтобы действительно НЕ ИСПОЛЬЗОВАТЬ setAreaCode или getAreaCode вместо этого используйте emulateAreaCode, эта функция принимает обратный вызов, это полезно, потому что, если вы посмотрите на функцию, она сбрасывает код области после выполнения обратного вызова в исходное состояние приложения. См. ниже:

\Magento\Фреймворк\Приложение\Состояние

**
 * Emulate callback inside some area code
 *
 * @param string $areaCode
 * @param callable $callback
 * @param array $params
 * @return mixed
 * @throws \Exception
 */
public function emulateAreaCode($areaCode, $callback, $params = [])
{
    $currentArea = $this->_areaCode;
    $this->_areaCode = $areaCode;
    $this->_isAreaCodeEmulated = true;
    try {
        $result = call_user_func_array($callback, $params);
    } catch (\Exception $e) {
        $this->_areaCode = $currentArea;
        $this->_isAreaCodeEmulated = false;
        throw $e;
    }
    $this->_areaCode = $currentArea;
    $this->_isAreaCodeEmulated = false;
    return $result;
}`

Вот пример того, как использовать эту функцию.

/**
 * Emulates Area code for callback function.
 *
 * @param   InputInterface $input
 * @param   OutputInterface $output
 * @throws  \Exception
 */
protected function execute(InputInterface $input, OutputInterface $output)
{
    $this->appState->emulateAreaCode(
        "catalog",
        [$this, "executeCallBack"],
        [$input, $output]
    );
}

/**
 * Execute the command
 *
 * @param InputInterface $input
 * @param OutputInterface $output
 * @throws \Exception
 * @return void
 */
public function executeCallBack(InputInterface $input, OutputInterface $output)
{
      $output->writeln("Hello World!");     
}
 7
Author: André Ferraz, 2018-04-19 08:29:50