Magento 2 Modular System
Magento 2 consists of several types of components: themes, modules, libraries, language packages. The Framework of Magento provides a set of core logic; libraries, PHP code, and base concepts inherited by all the components of the system.
Modules and themes of Magento 2 are used as customization units: modules provide business features, and themes provides look-and-feel features. Both modules and features have their own lifecycle, so they can be installed, disabled or deleted.
Modules can both depend on and relate to each other in different ways. At the same time, they should be independent enough to maximum flexibility for the site customization. In addition to the definition new business features, modules also define the user interface for those features. As a result modules interact with themes.
Everything about Magento 2 on Firebear
Every module is a logical group, which consists of blocks, helpers, controllers, models (php and xml files). This group is independent and designed not to intervene with other functionality. So with the modular approach, every module provides its own features with minimal dependencies on other modules, and the exclusion or inclusion of a module does not change the functionality of other modules.
The /app/code directory of a Magento installation is a place where modules live. The Customer Magento module can be found here: /app/code/Magento/Customer. The folder includes the code and configuration related to the module. There is even the etc/module.xml file with the information about module’s name, version and dependencies.
Name and declaration
Every module defines its name and existence (declares itself) in the module.xml file, which is located in <root>/app/code/<Vendor>/<ModuleName>/etc/. You should name the module according to the Namespace_Module schema: where “Namespace” is a module’s vendor name and “Module” is a name given to the module by the vendor.
And this is the information necessary to declare a module:
- The fully qualified name
- The dependencies
The example of minimal declaration sample:
1 2 3 4 |
<config> <module name="Namespace_Module" schema_version="2.0.0"> </module> </config> |
Module dependencies
Introduction
The concept of dependencies plays very important role in Magento: all modules are gathered into logical groups with unique separate features. In such conditions several modules can’t be responsible for the same feature. At the the same time, one module can’t be responsible for different Magento 2 features. Don’t forget that all the dependences must be declared. Both removing and disabling a module doesn’t result in removing or disabling other modules. Modules can be dependent upon such components as other modules, PHP extensions, and Libraries.
It is necessary to save all the historical information contained in a module before its deinstallation.
Module dependencies tasks
, You can manage module dependencies at a high level within 3 steps:
- First of all, you should name and declare the module
- Then, you should declare all the dependencies
- Optionally, you can also define the desired load order
Declaration of dependencies
All the dependencies are listed in the composer.json file of every module. And this is the example of usage:
1 2 3 4 5 6 7 8 9 10 11 12 |
<root>/app/code//Catalog/composer.json { "name": "magento/module-catalog", "description": "N/A", "require": { "magento/module-store": "0.1.0-alpha108", "magento/module-eav": "0.1.0-alpha108", "magento/module-cms": "0.1.0-alpha108", "magento/module-indexer": "0.1.0-alpha108", "magento/module-customer": "0.1.0-alpha108" }, |
The load order of dependencies
To declare the load order of any dependencies you should use the <sequence> element of the module.xml file.
The <sequence> is an optional element, so it is used only in the situation when the components order is necessary and modules are used. The other types of components are not used with the <sequence> section. Keep in mind, that putting a module into the <sequence> list does not mean that everything about that module will be used. Config and certain files under the /view and /etc directories are considered for the specified load order. Being in the <sequence> list, classes within a module aren’t impacted by the dedicated module .
Basic syntax:
1 2 3 |
<sequence> <module name="Vendor_Module"/> </sequence> |
The example of usage
Magento\Customer\etc\module.xml
1 2 3 4 5 6 7 8 9 |
<config> <module name="Magento_Customer" schema_version="1.11.0"> <sequence> <module name="Magento_Adminhtml"/> <module name="Magento_Customer"/> <module name="Magento_Sales"/> </sequence> </module> </config> |
The <sequence> element of the module.xml file is only used to define the dependencies load order. You should use composer.json file to make actual dependency declarations.
Dependency Injection Overview
Dependency injection means that all the dependencies are passed into the object instead of being pulled from the environment by this object .
A dependency (or coupling) implies the degree of how one component relies on some other component to perform its function. The larger amount of dependency the component has, the less transportable to new projects it is.
The object manager shows the dependency environment for constructor injection. It must be used only when composing code.
Types of module dependencies
There are two types of module dependencies in Magento: hard and soft dependencies.
- 1. A module with the hard dependency can not perform any functions without other modules upon which it depends.
- 2. A module with the soft dependency works without other modules, on which it depends.
It is necessary to remember, that in a case when one module uses code from another, it should necessarily declare the dependency explicitly.
The sequence for the installation: first of all, a module, which serves as a dependency for another module, is installed, then is the turn for the module, which is dependent on it.
Inappropriate dependencies
You should always avoid the following:
- Direct and indirect circular dependencies
- Incorrect dependencies
- Undeclared dependencies
There are different rules for building the dependencies between the modules from different layers.
With the explicit dependency, it is possible to use modules from the framework layer in the application layer via an .
Modules from the application layer can’t be used within the framework layer.
To build dependencies between classes in the application layer, you should use classes of the same module. To build dependencies between the modules of the application layer you should only use the service provider interface (SPI) or the service layer.
API- and SPI-specific interfaces
To build the correct dependencies, you should rely on API and SPI. API-specific interfaces (declared with @api annotation) can be used by other modules; SPI-specific interfaces (declared with @spi annotation) can be implemented by other modules.
API-specific interface:
1 2 3 4 5 6 7 8 9 10 11 12 |
/** * @api */ interface RouterInterface { public function match(); } final class Mage_Core_Controller_Varien_Router_Base implements RouterInterface { //... } |
For the aforementioned example, an interface with all its implementations become a part of API automatically, at the same time other elements remain module-private. All API considered classes must be declared final to prevent the hidden use of them in the SPI.
SPI-specific interface:
1 2 3 4 5 6 7 |
/** * @spi */ interface RouterInterface { public function match(); } |
For the aforementioned example, an interface becomes a part of SPI automatically, while all its implementations are a part of neither API nor SPI . Other interfaces with their implementations not marked as SPI-specific remain module-private.
Third party developers are able to implement the SPI-specific interfaces and use them in the dependency injection configurations.
API- and SPI-specific interface (declared with @api and @spi annotations):
1 2 3 4 5 6 7 8 |
/** * @api * @spi */ interface Magento_AuthorizationInterface { public function isAllowed($resource); } |
To provide correct behavior, developers should split the class into a final class (which is a part of the API) and an implementation interface (which is a part of the SPI).
Modules and areas
Overview
Modules define not only the resources, which are visible and accessible in an area, but also an area’s behavior.
Magento consists of six areas:
- adminhtml, which is Magento Admin
- frontend, which is Storefront
- webapi_rest, which is Web API REST
- webapi_soap, which is Web API SOAP
- doc
Every area with all specific resources declares itself within a certain module. It is possible to enable and disable an area in a module. With the enabled module, you inject an area’s routers into routing process of general application. With the disabled module, the routers of the area aren’t loaded, so the resources and specific functionality of the area are not available.
Keep in mind that a module should not depend on another module’s area.
Magento uses areas to make web service calls efficiently – the dependent code for that area is loaded. Frontend, backend, and webapi are the examples of the areas. Their major purpose is efficiency. Every area has its own behavior and view components, which operate apart.
Areas in modules
Modules define resources visible and accessible in the area and area’s behavior. One module can influence more than one area. RMA is represented partly in both the adminhtml and frontend areas.
By disabling an area, you do not disable the modules, which is related to it.
Module naming and location conventions
Overview
There are special Magento standards and conventions, such as modules location within the file system and naming. Use Coding Standards, to find out all the necessary information and additional Magento conventions. .
Module location conventions
This is how the standard locating for specific entities looks:
Entity | Location |
custom module сode base | <root>/app/code/<Vendor>/<Module> |
files of custom theme | <root>/app/design/<Module>/<theme> |
location of a library | <root/lib/<Vendor_Library> |
Module naming convention
Sometimes Magento modules have composite names. In such case, a name consists of two or more words with capitalized first letters. At the same time, the module alias is in lowercase, so there isn’t any simple solution designed to convert module alias to module name. To solve this issue, you should rely on setup class, which contains correspondence array of modules with composite names, and use this array in class name generation. For instance, “catalogsearch” is a module alias of “Magento_CatalogSearch” module.
Payment modules
Payments implementation
In Magento, payment methods have the following structure: abstract logic common is located in a separate module, while the implementations of particular methods are situated in corresponding modules, grouped by type or payment gateway . As a result, you can configure the set of payment methods for your store by disabling the modules of all the unnecessary solutions.
Payment module disabling and enabling
Most payment modules implement several payment methods of one provider or type. Paypal module provides all PayPal solutions.
Module | Functionality | Comments for Disabling/Enabling |
Magento_Paypal | provides all PayPal payment methods:
|
You can disabled/enabled it. To disabling Magento_Paypal, you should also disable the Magento_RecurringPayment module. |
Magento_Payment |
|
It isn’t supposed to be disabled. To disable it, you should disable all modules which depend on Magento_Payment. To find all the dependencies go to app/code/Magento/<module>/etc/module.xml and look under <depends/>. |
Magento_Ogone | Ogone payment method implementation. | You can disabled and enabled this module. |
Magento_OfflinePayments | Third-party gateways payment methods Implementation :
|
You can disabled and enabled this module. |
Magento_Authorizenet | Authorize.Net Direct Post and Authorize.Net payment methods Implementation. | You can disabled and enabled this module. |