POINTS TO REMEMBER
• There are five areas: adminhtml, frontend, base, webapi_rest, webapi_soap and cron. Not all areas are always available. For instance, the cron area is only used when running cron jobs.
• The three necessary files to bootstrap a module are registration.php, etc/module.xml and composer.json.
Overview
Magento 2’s module-based architecture keeps that module’s files in one folder. This makes discovery of the functionality pertaining to that module easier. Modules live in one of two places:
• app/code/CompanyName/ModuleName
• vendor/vendor-name/module-name
POINTS TO REMEMBER
• There are five areas: adminhtml, frontend, base, webapi_rest, webapi_soap and cron. Not all areas are always available. For instance, the cron area is only used when running cron jobs.
• The three necessary files to bootstrap a module are registration.php, etc/module.xml and composer.json.
With Magento 2, modules can be installed with Composer, making for easier upgrades and version management. These modules are placed in /vendor. Any file in /vendor is considered “untouchable” (not directly editable) as those files will be removed when new versions are released. Installing modules via Composer into the /vendor folder reduces technical debt as you no longer have to directly manage the versions of these modules: Composer does it for you. In most cases, the modules that you develop go into app/code/CompanyName. This is the namespace used for development. Modules are placed in the folder directly below. With Magento’s dependency on Composer, you can theoretically import modules from almost any location in a project.
Example:
The only required files to initiate a module is:
• registration.php
• etc/module.xml
registration.php – This file is included by the Composer autoloader (app/etc/NonComposerComponentRegistration.php). This adds the module (component) to the static list of components in \Magento\Framework\Component\ComponentRegistrar. Once it is there, Magento will look for etc/module.xml.
Example:
etc/module.xm – This file specifies the setup version and loading sequence for the module. The setup version is available in the module’s Setup classes to determine what upgrade activities should occur. The sequence tells Magento (vendor/magento/framework/Module/ModuleList/Loader.php) in which order to load modules. This adjustment Magento Architecture and Customization Techniques happens only when the module is installed. The list of modules is stored in app/etc/config.php.
The sequence is useful for events, plugins and preferences, (although events’ listeners should never be dependent on the order in which they are called) and layouts. If you modify the layout of another module and your module is initialized first, the other module will overwrite your adjustments.
Example:
Describe module limitations Magento 2 modules are to be completely contained within the module’s directory (ie. app/code/AcmeWidgets/ProductPromoter). All customizations and extensions are made within that folder. If it is disabled, the module is not functional. Keep in mind that disabling a module does not automatically remove its tables or entries in the database.
If you are having trouble with modules not being enabled, check:
• The required files are present (see above).
• The module is enabled (bin/magento module:enable AcmeWidgets_ProductPromotor).
How do different modules interact with each other?
Magento 2 provides a much-improved system for inter-module interaction. At its core, Magento 2 is PSR-4 compliant. This standard declares that the namespace path will match the file path to the class. While the PSR-0 standard has been deprecated, Composer still uses this idea to assist in autoloading classes. In /composer.json (in the root folder), there should be a “psr-0” node. Inside it, will be an “app/code” value. This has the same effect of adding and include directory for PHP to search. Magento 2 does not include the Mage “god” class like its earlier counterpart. Magento 2 relies on service contracts and dependency injection to determine what classes to use. This will be discussed more in the Dependency Injection section. These service contracts are stored in the app/code/AcmeWidgets/ProductPromoter/Api/ directory. Data representations are in the app/code/AcmeWidgets/ProductPromoter/Api/Data folder. When building modules that are dependent on other modules, whenever possible, use interfaces as defined by the service contracts. That way, your module works with a blueprint and it does not matter what class or module fulfills that blueprint.
HELPFUL LINKS:
• http://devdocs.magento.com/guides/v2.0/architecture/archi_perspectives/components/modules/mod_and_areas.html
• Service contracts introduction: https://alankent.me/2014/10/31/magento-2-service-contract-patterns/
What side effects can come from this interaction? Any time you are working with a system where any installed module can extend core functionality, fallout can happen.
When implementing according to Magento 2’s guidelines, the fallout is limited.
When breaking recommendations, problems happen. It is good to assume that other modules will change things in the system. For example, let’s say you install a module that introduces a massive change for a product. This change is so significant that the developer wrote an entirely new class to represent the product model. This class was written against the service contracts that
Magento specifies for a product:
namespace \SwiftOtter\NewProduct\Model
use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\Pricing\SaleableInterface;
use Magento\Catalog\Api\Data\ProductInterface;
class Product implements IdentityInterface,
SaleableInterface, ProductInterface
{
// …
}
But what if your custom product code uses a method that is only defined in \Magento\Catalog\Model\Product? You (or your customer or a website visitor) might get a PHP Fatal Error when it attempts to call a method that does not exist in the other class. This flexibility is incredible but also must be used responsibly. When working with Magento-defined classes that have service contracts (Api/ and Api/Data folders), use those interfaces instead of the concrete classes that implement the service contracts. If you must explicitly use a Magento-defined class (such as \Magento\Catalog\Model\Product), make the implicit dependency explicit by depending on the concrete implementation instead of the service contract interface.