2

I see there isn't a lot of information about using app states and if there is it doesn't work properly. So bellow is my answer based on my own investigation.

6

There is this blog post by our friend Alan Storm, which most people seems to be using. The problem is this really doesn't work properly here's why.

DON'T

  1. Use setAreaCode or getAreaCode in the __constructor. This is bad! When you run a command, magento builds the list of all commands available in the system and then does a check to see if the requested is in the list. It doesn't only do that but also initialises the command class, so if there is a setAreaCode in the __constructor of the first command picked all other commands with their own area code will fail (if they don't have an exception handler) or will not be using the right area code (if they have an exception handler), this is because there is no way of unsetting the area code.

  2. Use setAreaCode or getAreaCode in the configure function, similar results to the above mostly when you do bin/magento. Magento initialises the command class and then the configure function.

My personal opinion is to really NOT USE setAreaCode or getAreaCode instead use emulateAreaCode, this function accepts a callback, this is useful because if you have a look at the function it unsets the area code after execution of the callback to its initial app state. See below:

\Magento\Framework\App\State

**
 * 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;
}`

Here's an example of how to use the function.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.