<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Framework\Module;
use Magento\Framework\App\DeploymentConfig\Writer;
use Magento\Framework\Config\File\ConfigFilePool;
/**
* A service for controlling module status
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Status
{
/**
* Module list loader
*
* @var ModuleList\Loader
*/
private $loader;
/**
* Module list
*
* @var ModuleList
*/
private $list;
/**
* Deployment config writer
*
* @var Writer
*/
private $writer;
/**
* Dependency Checker
*
* @var DependencyChecker
*/
private $dependencyChecker;
/**
* Conflict checker
*
* @var ConflictChecker
*/
private $conflictChecker;
/**
* Constructor
*
* @param ModuleList\Loader $loader
* @param ModuleList $list
* @param Writer $writer
* @param ConflictChecker $conflictChecker
* @param DependencyChecker $dependencyChecker
*/
public function __construct(
ModuleList\Loader $loader,
ModuleList $list,
Writer $writer,
ConflictChecker $conflictChecker,
DependencyChecker $dependencyChecker
) {
$this->loader = $loader;
$this->list = $list;
$this->writer = $writer;
$this->conflictChecker = $conflictChecker;
$this->dependencyChecker = $dependencyChecker;
}
/**
* Whether it is allowed to enable or disable specified modules
*
* @param bool $isEnabled
* @param string[] $modulesToBeChanged
* @param string[] $currentlyEnabledModules
* @param bool $prettyMessage
*
* @return string[]
*/
public function checkConstraints(
$isEnabled,
$modulesToBeChanged,
$currentlyEnabledModules = null,
$prettyMessage = false
) {
$errorMessages = [];
if ($isEnabled) {
$errorModulesDependency = $this->dependencyChecker->checkDependenciesWhenEnableModules(
$modulesToBeChanged,
$currentlyEnabledModules
);
$errorModulesConflict = $this->conflictChecker->checkConflictsWhenEnableModules(
$modulesToBeChanged,
$currentlyEnabledModules
);
} else {
$errorModulesDependency = $this->dependencyChecker->checkDependenciesWhenDisableModules(
$modulesToBeChanged,
$currentlyEnabledModules
);
$errorModulesConflict = [];
}
foreach ($errorModulesDependency as $moduleName => $missingDependencies) {
if (!empty($missingDependencies)) {
if ($prettyMessage) {
$errorMessages[] = $this->createShortErrorMessage($isEnabled, $moduleName);
} else {
$errorMessages = array_merge(
$errorMessages,
$this->createVerboseErrorMessage($isEnabled, $moduleName, $missingDependencies)
);
}
}
}
foreach ($errorModulesConflict as $moduleName => $conflictingModules) {
if (!empty($conflictingModules)) {
$errorMessages[] = "Cannot enable $moduleName because it conflicts with other modules:";
$errorMessages[] = implode("\n", $conflictingModules);
}
}
return $errorMessages;
}
/**
* Sets specified modules to enabled or disabled state
*
* Performs other necessary routines, such as cache cleanup
*
* @param bool $isEnabled
* @param string[] $modules
* @return void
*/
public function setIsEnabled($isEnabled, $modules)
{
$result = [];
foreach ($this->getAllModules($modules) as $name) {
$currentStatus = $this->list->has($name);
if (in_array($name, $modules)) {
$result[$name] = (int)$isEnabled;
} else {
$result[$name] = (int)$currentStatus;
}
}
$this->writer->saveConfig([ConfigFilePool::APP_CONFIG => ['modules' => $result]], true);
}
/**
* Get a list of modules that will be changed
*
* @param bool $isEnabled
* @param string[] $modules
* @return string[]
*/
public function getModulesToChange($isEnabled, $modules)
{
$changed = [];
foreach ($this->getAllModules($modules) as $name) {
$currentStatus = $this->list->has($name);
if (in_array($name, $modules)) {
if ($isEnabled != $currentStatus) {
$changed[] = $name;
}
}
}
return $changed;
}
/**
* Gets all modules and filters against the specified list
*
* @param string[] $modules
* @return string[]
* @throws \LogicException
*/
private function getAllModules($modules)
{
$all = $this->loader->load();
$unknown = [];
foreach ($modules as $name) {
if (!isset($all[$name])) {
$unknown[] = $name;
}
}
if ($unknown) {
throw new \LogicException("Unknown module(s): '" . implode("', '", $unknown) . "'");
}
return array_keys($all);
}
/**
* Creates a one-line error message that a module cannot be enabled/disabled.
*
* @param bool $isEnabled
* @param string $moduleName
* @return string
*/
private function createShortErrorMessage($isEnabled, $moduleName)
{
if ($isEnabled) {
return "Cannot enable $moduleName";
} else {
return "Cannot disable $moduleName";
}
}
/**
* Creates a verbose error message that a module cannot be enabled/disabled.
*
* Each line in the error message will be an array element.
*
* @param bool $isEnabled
* @param string $moduleName
* @param array $missingDependencies
* @return string[]
*/
private function createVerboseErrorMessage($isEnabled, $moduleName, $missingDependencies)
{
if ($isEnabled) {
$errorMessages[] = "Cannot enable $moduleName because it depends on disabled modules:";
} else {
$errorMessages[] = "Cannot disable $moduleName because modules depend on it:";
}
foreach ($missingDependencies as $errorModule => $path) {
$errorMessages[] = "$errorModule: " . implode('->', $path);
}
return $errorMessages;
}
}
|