Categories


Archives


Recent Posts


Categories


Emulating Areas in Magento 2

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Updated for Magento 2! No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

One last bit on the area setting object in Magento 2. There were times in Magento 1 where it was necessary to temporarily pretend you were running code in one area, even though you were in another. One famous example of this was using Magento’s catalog/product objects to directly save product information while on the frontend. In later versions of Magento this (unexpected by the core developers) action threw some PHP errors.

While Magento 2 has tried to clean these instances up, you’re probably going to run into similar problems when converting Magento 1 extensions to Magento 2, and you’re probably going to find some instances where it’s impossible to work around. However, last time we learned it’s impossible to change the area code in Magento 2 that’s already been set.

Fortunately, a developer on Magento’s core team anticipated this need, and the MagentoFrameworkAppState object has a emulateAreaCode method.

#File: vendor/magento/framework/App/State.php
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;
}

This method allows you to pass in a PHP callback, and Magento will invoke (i.e. call) your method or function with the global area set to whatever value you pass in

$app_state->emulateAreaCode('adminhtml', function(){
    //code that does something `adminhtml` specific here
});

By providing this method, Magento gives you ability to run code in a different global area context, but also ensure that you don’t forget to rest the area when you’re done.

Magento seems to use this method itself in the sample data modules, ensure that objects are created in a specific context, likely to replicated event driven data consequences

#File: vendor/magento/module-customer-sample-data/Model/Customer.php
$this->appState->emulateAreaCode(
    'frontend',
    [$this->accountManagement, 'createAccount'],
    [$customer, $row['password']]
);

Copyright © Alan Storm 1975 – 2019 All Rights Reserved

Originally Posted: 28th April 2016