-
-
Notifications
You must be signed in to change notification settings - Fork 2
Module structure
A module must have, at the very least:
module.xml
registration.php
A module may also have an optional composer.json
file.
Upon running bin/magento module:enable Vendor_Module
:
#11 registration.php:5, require_once()
#10 NonComposerComponentRegistration.php:29, Magento\NonComposerComponentRegistration\{closure:/var/www/html/m2/research/m23-example-modules/html/app/etc/NonComposerComponentRegistration.php:29-29}()
#9 NonComposerComponentRegistration.php:29, array_map()
#8 NonComposerComponentRegistration.php:29, Magento\NonComposerComponentRegistration\{closure:/var/www/html/m2/research/m23-example-modules/html/app/etc/NonComposerComponentRegistration.php:18-31}()
#7 NonComposerComponentRegistration.php:33, require()
#6 autoload_real.php:73, composerRequirefe24ed7cfcf7e56742d967c8a9b0a516()
#5 autoload_real.php:63, ComposerAutoloaderInitfe24ed7cfcf7e56742d967c8a9b0a516::getLoader()
#4 autoload.php:7, include()
#3 autoload.php:30, require_once()
#2 bootstrap.php:33, require()
#1 magento:14, {main}()
Starting at the bottom with stack frame:
-
#1
,bin/magento
is the entry point. -
#2
initialises the Magento 2 environment. -
#3
registers an autoloader and validates thatcomposer install
has been run. - These next three lines all call logic inside composer (and outside of Magento). They are all about loading autoloaders.
- This line includes a composer autoloader.
- This line includes a composer autoloader.
- Back in the Magento core,
NonComposerComponentRegistration
is a special file which contains a single function (it's not a method because it's not in a class). - This method, called
main
, globs a list of components which cannot be autoloaded. These components are listed in the file itrequires
(html/app/etc/registration_globlist.php
). - The list of glob()bed files is iterated over with
array_map
. - For each file in the glob()bed list, Magento 2 includes it with
require_once
. - This is how the
registration.php
file is read by Magento 2.
Each registration.php file calls \Magento\Framework\Component\ComponentRegistrar::register
:
/**
* Sets the location of a component.
*
* @param string $type component type
* @param string $componentName Fully-qualified component name
* @param string $path Absolute file path to the component
* @throws \LogicException
* @return void
*/
public static function register($type, $componentName, $path)
{
self::validateType($type);
if (isset(self::$paths[$type][$componentName])) {
throw new \LogicException(
ucfirst($type) . ' \'' . $componentName . '\' from \'' . $path . '\' '
. 'has been already defined in \'' . self::$paths[$type][$componentName] . '\'.'
);
} else {
self::$paths[$type][$componentName] = str_replace('\\', '/', $path);
}
}
The purpose of this method is to check that the component is one of several pre-determined types defined at the top of the class:
/**#@- */
private static $paths = [
self::MODULE => [],
self::LIBRARY => [],
self::LANGUAGE => [],
self::THEME => [],
self::SETUP => []
];
That property eventually contains a list of all the components (modules, themes, etc) registered by Magento 2.
This is used whenever a module wants to find the paths to installed component types.
The command is defined here: \Magento\Setup\Console\Command\ModuleEnableCommand
, but all the logic is in the parent abstract class: \Magento\Setup\Console\Command\AbstractModuleManageCommand
.
On running the command, the execute
method is executed and checks to see if there are any modules registered whose 'Status' has changed.
protected function execute(InputInterface $input, OutputInterface $output)
{
// Flag set in \Magento\Setup\Console\Command\ModuleEnableCommand or \Magento\Setup\Console\Command\ModuleDisableCommand
$isEnable = $this->isEnable();
// Check if we are enabling/disabling one module or all of them
if ($input->getOption(self::INPUT_KEY_ALL)) {
/** @var \Magento\Framework\Module\FullModuleList $fullModulesList */
$fullModulesList = $this->objectManager->get(\Magento\Framework\Module\FullModuleList::class);
$modules = $fullModulesList->getNames();
} else {
$modules = $input->getArgument(self::INPUT_KEY_MODULES);
}
$messages = $this->validate($modules);
if (!empty($messages)) {
$output->writeln(implode(PHP_EOL, $messages));
return Cli::RETURN_FAILURE;
}
try {
// Check which modules have changed status
$modulesToChange = $this->getStatus()->getModulesToChange($isEnable, $modules);
} catch (\LogicException $e) {
$output->writeln('<error>' . $e->getMessage() . '</error>');
return Cli::RETURN_FAILURE;
}
if (!empty($modulesToChange)) {
$force = $input->getOption(self::INPUT_KEY_FORCE);
if (!$force) {
// Check to see if this module(s) have any dependencies on other modules
$constraints = $this->getStatus()->checkConstraints($isEnable, $modulesToChange);
if ($constraints) {
$output->writeln(
"<error>Unable to change status of modules because of the following constraints:</error>"
);
$output->writeln('<error>' . implode("</error>\n<error>", $constraints) . '</error>');
// we must have an exit code higher than zero to indicate something was wrong
return Cli::RETURN_FAILURE;
}
}
// Enable the modules
$this->setIsEnabled($isEnable, $modulesToChange, $output);
// Clean cache and generated files and folders
$this->cleanup($input, $output);
// Regenerate generated files and folders
$this->getGeneratedFiles()->requestRegeneration();
if ($force) {
$output->writeln(
'<error>Alert: You used the --force option.'
. ' As a result, modules might not function properly.</error>'
);
}
} else {
$output->writeln('<info>No modules were changed.</info>');
}
return Cli::RETURN_SUCCESS;
}
\Magento\Framework\Module\Status::checkConstraints
checks to see if the module depends on any other modules.
\Magento\Framework\Module\Status::setIsEnabled
enables the changed modules.
\Magento\Framework\App\Cache
is cleaned.
\Magento\Framework\App\Filesystem\DirectoryList::GENERATED_CODE
and \Magento\Framework\App\Filesystem\DirectoryList::GENERATED_METADATA
folders are cleared.
Regeneration of generated files is requested by creating the flag .regenerate
in var/