The area is a logical component that organizes code for optimized request processing. While the majority of the time we don't really have to code anything specific regarding areas, understanding them is key to understanding Magento.
The Magento\Framework\App\Area class AREA_* constants hint at the following areas:
const AREA_GLOBAL = 'global';
const AREA_FRONTEND = 'frontend';
const AREA_ADMINHTML = 'adminhtml';
const AREA_DOC = 'doc';
const AREA_CRONTAB = 'crontab';
const AREA_WEBAPI_REST = 'webapi_rest';
const AREA_WEBAPI_SOAP = 'webapi_soap';
By doing a lookup for the <argument name="areas" string across all of the <MAGENTO_DIR> di.xml files, we can see that five of these areas have been explicitly added to the areas argument of the Magento\Framework\App\AreaList class:
- adminhtml via <MAGENTOI_DIR>/module-backend/etc/di.xml
- webapi_rest via <MAGENTOI_DIR>/module-webapi/etc/di.xml
- webapi_soap via <MAGENTOI_DIR>/magento/module-webapi/etc/di.xml
- frontend via <MAGENTOI_DIR>/magento/module-store/etc/di.xml
- crontab via <MAGENTOI_DIR>/magento/module-cron/etc/di.xml
The default area is frontend, as defined by the default argument under module-store/etc/di.xml. The global area is used as a fallback for files that are absent in the adminhtml and frontend areas.
Let's take a closer look at the <MAGENTO_DIR>/module-webapi/etc/di.xml file:
<type name="Magento\Framework\App\AreaList">
<arguments>
<argument name="areas" xsi:type="array">
<item name="webapi_rest" xsi:type="array">
<item name="frontName" xsi:type="string">rest</item>
</item>
<item name="webapi_soap" xsi:type="array">
<item name="frontName" xsi:type="string">soap</item>
</item>
</argument>
</arguments>
</type>
The frontName is what sometimes appears at the front of the URL, whereas the area name is used internally to refer to the area in configuration files. Different areas defined by Magento can contain different code for processing URLs and requests. This allows Magento to load only the dependent code for the specified area.
When developing modules, we define which resources are visible and accessible in a given area. This way, we get to control the specific area behavior if needed. An example of one such behavior might be the definition of the event observer under the frontend area for customer_save_after event. This observer would only trigger on customer save operations that are triggered from the storefront, which usually indicates a customer register action. The adminhtml area operations, such as Magento admin manually creating a customer, would fail to trigger this observer, as it was defined under the frontend area.
On occasion, we might need to run some code that only executes under certain areas. In such cases, emulation helps us emulate any store programmatically. The Magento\Store\Model\App\Emulation class provides the startEnvironmentEmulation and stopEnvironmentEmulation methods, which we can use for this purpose, as per the following partial example:
protected $storeRepository;
protected $emulation;
public function __construct(
\Magento\Store\Api\StoreRepositoryInterface $storeRepository,
\Magento\Store\Model\App\Emulation $emulation
) {
$this->storeRepository = $storeRepository;
$this->emulation = $emulation;
}
public function test() {
$store = $this->storeRepository->get('store-to-emulate');
$this->emulation->startEnvironmentEmulation(
$store->getId(),
\Magento\Framework\App\Area::AREA_FRONTEND
);
// Code to execute in emulated environment
$this->emulation->stopEnvironmentEmulation();
}
While it is not a common thing to do, we can further register new areas ourselves. This is easily done by using the module's di.xml.