31 use Magento\Framework\Setup\PatchApplierInterface;
44 use Magento\Setup\Validator\DbValidator;
73 const SCHEMA_INSTALL = \Magento\Framework\Setup\InstallSchemaInterface::class;
74 const SCHEMA_UPGRADE = \Magento\Framework\Setup\UpgradeSchemaInterface::class;
75 const DATA_INSTALL = \Magento\Framework\Setup\InstallDataInterface::class;
76 const DATA_UPGRADE = \Magento\Framework\Setup\UpgradeDataInterface::class;
91 private $filePermissions;
98 private $deploymentConfigWriter;
105 private $deploymentConfigReader;
119 private $moduleLoader;
126 private $adminAccountFactory;
140 private $connectionFactory;
154 private $maintenanceMode;
168 private $installInfo = [];
173 private $deploymentConfig;
178 private $objectManagerProvider;
188 private $setupConfigModel;
193 private $cleanupFiles;
198 private $dbValidator;
205 private $setupFactory;
212 private $dataSetupFactory;
224 private $componentRegistrar;
229 private $phpReadinessCheck;
234 private $declarationInstaller;
239 private $schemaPersistor;
244 private $patchApplierFactory;
275 Writer $deploymentConfigWriter,
276 Reader $deploymentConfigReader,
279 ModuleLoader $moduleLoader,
287 SetupConfigModel $setupConfigModel,
289 DbValidator $dbValidator,
296 $this->filePermissions = $filePermissions;
297 $this->deploymentConfigWriter = $deploymentConfigWriter;
298 $this->deploymentConfigReader = $deploymentConfigReader;
299 $this->moduleList = $moduleList;
300 $this->moduleLoader = $moduleLoader;
301 $this->adminAccountFactory = $adminAccountFactory;
303 $this->connectionFactory = $connectionFactory;
304 $this->maintenanceMode = $maintenanceMode;
308 $this->objectManagerProvider = $objectManagerProvider;
309 $this->context = $context;
310 $this->setupConfigModel = $setupConfigModel;
311 $this->cleanupFiles = $cleanupFiles;
312 $this->dbValidator = $dbValidator;
313 $this->setupFactory = $setupFactory;
314 $this->dataSetupFactory = $dataSetupFactory;
317 $this->phpReadinessCheck = $phpReadinessCheck;
318 $this->schemaPersistor = $this->objectManagerProvider->get()->get(SchemaPersistor::class);
330 $script[] = [
'File permissions check...',
'checkInstallationFilePermissions', []];
331 $script[] = [
'Required extensions check...',
'checkExtensions', []];
332 $script[] = [
'Enabling Maintenance Mode...',
'setMaintenanceMode', [1]];
333 $script[] = [
'Installing deployment configuration...',
'installDeploymentConfig', [
$request]];
335 $script[] = [
'Cleaning up database...',
'cleanupDb', []];
337 $script[] = [
'Installing database schema:',
'installSchema', [
$request]];
338 $script[] = [
'Installing user configuration...',
'installUserConfig', [
$request]];
339 $script[] = [
'Enabling caches:',
'enableCaches', []];
340 $script[] = [
'Installing data...',
'installDataFixtures', [
$request]];
343 'Creating sales order increment prefix...',
344 'installOrderIncrementPrefix',
348 if ($this->isAdminDataSet(
$request)) {
349 $script[] = [
'Installing admin user...',
'installAdminUser', [
$request]];
353 $script[] = [
'Caches clearing:',
'cleanCaches', [
$request]];
355 $script[] = [
'Disabling Maintenance Mode:',
'setMaintenanceMode', [0]];
356 $script[] = [
'Post installation file permissions check...',
'checkApplicationFilePermissions', []];
357 $script[] = [
'Write installation date...',
'writeInstallationDate', []];
358 $estimatedModules = $this->createModulesConfig(
$request,
true);
359 $total = count($script) + 4 * count(array_filter($estimatedModules));
360 $this->progress =
new Installer\Progress($total, 0);
362 $this->log->log(
'Starting Magento installation:');
364 foreach ($script as
$item) {
368 $this->logProgress();
370 $this->log->logSuccess(
'Magento installation complete.');
371 $this->log->logSuccess(
372 'Magento Admin URI: /' 373 . $this->deploymentConfig->get(BackendConfigOptionsList::CONFIG_PATH_BACKEND_FRONTNAME)
376 if ($this->progress->getCurrent() != $this->progress->getTotal()) {
377 throw new \LogicException(
'Installation progress did not finish properly.');
379 if ($this->sampleDataState->hasError()) {
380 $this->log->log(
'Sample Data is installed with errors. See log file for details');
389 private function getDeclarationInstaller()
391 if (!$this->declarationInstaller) {
392 $this->declarationInstaller = $this->objectManagerProvider->get()->get(
393 DeclarationInstaller::class
396 return $this->declarationInstaller;
405 private function writeInstallationDate()
409 $configData = [$dateData->getFileKey() => $dateData->getData()];
410 $this->deploymentConfigWriter->saveConfig(
$configData);
421 private function createModulesConfig(
$request, $dryRun =
false)
423 $all = array_keys($this->moduleLoader->load());
424 $deploymentConfig = $this->deploymentConfigReader->load();
430 foreach ($all as $module) {
431 if ((isset($currentModules[$module]) && !$currentModules[$module])) {
436 if (in_array($module, $disable)) {
439 if (in_array($module, $enable)) {
458 private function readListOfModules($all,
$request, $key)
467 if (!in_array($module, $all)) {
468 throw new \LogicException(
"Unknown module in the requested list: '{$module}'");
481 private function logProgress()
483 if (!$this->progress) {
486 $this->progress->setNext();
488 sprintf(self::PROGRESS_LOG_RENDER, $this->progress->getCurrent(), $this->progress->getTotal())
500 $this->throwExceptionForNotWritablePaths(
501 $this->filePermissions->getMissingWritablePathsForInstallation()
513 $phpExtensionsCheckResult = $this->phpReadinessCheck->checkPhpExtensions();
515 && isset($phpExtensionsCheckResult[
'data'][
'missing'])
517 $errorMsg =
"Missing following extensions: '" 518 . implode(
"' '", $phpExtensionsCheckResult[
'data'][
'missing']) .
"'";
519 throw new \Exception($errorMsg);
530 $results = $this->filePermissions->getUnnecessaryWritableDirectoriesForApplication();
532 $errorMsg =
"For security, remove write permissions from these directories: '" 534 $this->log->log($errorMsg);
548 $this->createModulesConfig(
$data);
550 $this->setupConfigModel->process($userData);
552 if (isset($deploymentConfigData)) {
556 $this->objectManagerProvider->reset();
576 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
578 [
'nullable' =>
false,
'primary' =>
true],
582 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
588 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
592 )->setComment(
'Module versions registry');
603 private function setupCoreTables(SchemaSetupInterface
$setup)
624 private function setupSessionTable(
625 SchemaSetupInterface
$setup,
630 $setup->getTable(
'session')
633 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
635 [
'nullable' =>
false,
'primary' =>
true],
639 \
Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
641 [
'unsigned' =>
true,
'nullable' =>
false,
'default' =>
'0'],
642 'Date of Session Expiration' 645 \
Magento\Framework\DB\Ddl\Table::TYPE_BLOB,
647 [
'nullable' =>
false],
650 'Database Sessions Storage' 663 private function setupCacheTable(
664 SchemaSetupInterface
$setup,
672 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
674 [
'nullable' =>
false,
'primary' =>
true],
678 \
Magento\Framework\DB\Ddl\Table::TYPE_BLOB,
684 \
Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
687 'Cache Creation Time' 690 \
Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
693 'Time of Cache Updating' 696 \
Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
699 'Cache Expiration Time' 701 $setup->getIdxName(
'cache', [
'expire_time']),
717 private function setupCacheTagTable(
718 SchemaSetupInterface
$setup,
723 $setup->getTable(
'cache_tag')
726 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
728 [
'nullable' =>
false,
'primary' =>
true],
732 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
734 [
'nullable' =>
false,
'primary' =>
true],
737 $setup->getIdxName(
'cache_tag', [
'cache_id']),
753 private function setupFlagTable(
754 SchemaSetupInterface
$setup,
762 \
Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
764 [
'identity' =>
true,
'unsigned' =>
true,
'nullable' =>
false,
'primary' =>
true],
768 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
770 [
'nullable' =>
false],
774 \
Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
776 [
'unsigned' =>
true,
'nullable' =>
false,
'default' =>
'0'],
780 \
Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
786 \
Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
788 [
'nullable' =>
false,
'default' => \
Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE],
789 'Date of Last Flag Update' 791 $setup->getIdxName(
'flag', [
'last_update']),
808 $this->getDeclarationInstaller()->installSchema(
$request);
817 public function installSchema(array
$request)
820 $registry = $this->objectManagerProvider->get()->get(\
Magento\Framework\Registry::class);
822 $registry->register(
'setup-mode-enabled',
true);
824 $this->assertDbConfigExists();
825 $this->assertDbAccessible();
826 $setup = $this->setupFactory->create($this->context->getResources());
827 $this->setupModuleRegistry(
$setup);
828 $this->setupCoreTables(
$setup);
829 $this->log->log(
'Schema creation/updates:');
834 $schemaListener =
$adapter->getSchemaListener();
836 if ($this->convertationOfOldScriptsIsAllowed(
$request)) {
837 $schemaListener->setResource(
'default');
838 $this->schemaPersistor->persist($schemaListener);
841 $registry->unregister(
'setup-mode-enabled');
850 private function convertationOfOldScriptsIsAllowed(array
$request)
862 public function installDataFixtures(array
$request = [])
865 $registry = $this->objectManagerProvider->get()->get(\
Magento\Framework\Registry::class);
867 $registry->register(
'setup-mode-enabled',
true);
869 $this->assertDbConfigExists();
870 $this->assertDbAccessible();
871 $setup = $this->dataSetupFactory->create();
873 $this->log->log(
'Data install/update:');
876 $registry->unregister(
'setup-mode-enabled');
887 $this->throwExceptionForNotWritablePaths(
888 $this->filePermissions->getMissingWritableDirectoriesForDbUpgrade()
899 private function throwExceptionForNotWritablePaths(array
$paths)
902 $errorMsg =
"Missing write permissions to the following paths:" . PHP_EOL . implode(PHP_EOL,
$paths);
903 throw new \Exception($errorMsg);
922 if (!((
$type ===
'schema') || (
$type ===
'data'))) {
923 throw new \Magento\Setup\Exception(
"Unsupported operation type $type is requested");
925 $resource = new \Magento\Framework\Module\ModuleResource($this->context);
926 $verType =
$type .
'-version';
927 $installType =
$type .
'-install';
928 $upgradeType =
$type .
'-upgrade';
929 $moduleNames = $this->moduleList->getNames();
930 $moduleContextList = $this->generateListOfModuleContext(
$resource, $verType);
933 $schemaListener =
$adapter->getSchemaListener();
934 $this->patchApplierFactory = $this->objectManagerProvider->get()->create(
935 PatchApplierFactory::class,
937 'objectManager' => $this->objectManagerProvider->get()
941 if (
$type ===
'schema') {
942 $patchApplier = $this->patchApplierFactory->create([
'schemaSetup' =>
$setup]);
944 $patchApplier = $this->patchApplierFactory->create([
945 'moduleDataSetup' =>
$setup,
946 'objectManager' => $this->objectManagerProvider->get()
950 foreach ($moduleNames as $moduleName) {
952 $this->log->log(
"Module '{$moduleName}':");
953 $this->logProgress();
956 $schemaListener->setModuleName($moduleName);
957 $this->log->log(
"Module '{$moduleName}':");
958 $configVer = $this->moduleList->getOne($moduleName)[
'setup_version'];
959 $currentVersion = $moduleContextList[$moduleName]->getVersion();
961 if ($currentVersion !==
'') {
962 $status = version_compare($configVer, $currentVersion);
964 $upgrader = $this->getSchemaDataHandler($moduleName, $upgradeType);
966 $this->log->logInline(
"Upgrading $type.. ");
967 $upgrader->upgrade(
$setup, $moduleContextList[$moduleName]);
968 if (
$type ===
'schema') {
969 $resource->setDbVersion($moduleName, $configVer);
971 $resource->setDataVersion($moduleName, $configVer);
976 $installer = $this->getSchemaDataHandler($moduleName, $installType);
978 $this->log->logInline(
"Installing $type... ");
981 $upgrader = $this->getSchemaDataHandler($moduleName, $upgradeType);
983 $this->log->logInline(
"Upgrading $type... ");
984 $upgrader->upgrade(
$setup, $moduleContextList[$moduleName]);
989 if (
$type ===
'schema') {
990 $resource->setDbVersion($moduleName, $configVer);
992 $resource->setDataVersion($moduleName, $configVer);
999 if (
$type ===
'schema') {
1000 $patchApplier->applySchemaPatch($moduleName);
1002 $patchApplier->applyDataPatch($moduleName);
1005 $this->logProgress();
1008 if (
$type ===
'schema') {
1009 $this->log->log(
'Schema post-updates:');
1010 $handlerType =
'schema-recurring';
1012 $this->log->log(
'Data post-updates:');
1013 $handlerType =
'data-recurring';
1015 foreach ($moduleNames as $moduleName) {
1017 $this->log->log(
"Module '{$moduleName}':");
1018 $this->logProgress();
1021 $this->log->log(
"Module '{$moduleName}':");
1022 $modulePostUpdater = $this->getSchemaDataHandler($moduleName, $handlerType);
1023 if ($modulePostUpdater) {
1024 $this->log->logInline(
'Running ' . str_replace(
'-',
' ', $handlerType) .
'...');
1025 $modulePostUpdater->install(
$setup, $moduleContextList[$moduleName]);
1027 $this->logProgress();
1037 private function assertDbConfigExists()
1041 throw new \Magento\Setup\Exception(
1042 "Can't run this operation: configuration for DB connection is absent." 1053 private function isDryRun(array
$request)
1065 public function installUserConfig(
$data)
1067 if ($this->isDryRun(
$data)) {
1070 $userConfig =
new StoreConfigurationDataMapper();
1072 $appState = $this->objectManagerProvider->get()->get(\
Magento\Framework\
App\State::class);
1073 $appState->setAreaCode(\
Magento\Framework\
App\Area::AREA_GLOBAL);
1080 $configFactory = $this->objectManagerProvider->get()->create(\
Magento\Config\Model\Config\Factory::class);
1083 $configModel->setDataByPath($key, $val);
1084 $configModel->save();
1100 throw new \Magento\Setup\Exception(
$className .
' must implement \\' . $interfaceName);
1102 return $this->objectManagerProvider->get()->create(
$className);
1116 private function installOrderIncrementPrefix($orderIncrementPrefix)
1118 $setup = $this->setupFactory->create($this->context->getResources());
1119 $dbConnection =
$setup->getConnection();
1122 $select = $dbConnection->select()
1123 ->from(
$setup->getTable(
'eav_entity_type'),
'entity_type_id')
1124 ->where(
'entity_type_code = \'order\'');
1128 $incrementRow = $dbConnection->fetchRow(
1129 'SELECT * FROM ' .
$setup->getTable(
'eav_entity_store') .
' WHERE entity_type_id = ? AND store_id = ?',
1133 if (!empty($incrementRow)) {
1135 $entityStoreId = $incrementRow[
'entity_store_id'];
1136 $dbConnection->update(
1137 $setup->getTable(
'eav_entity_store'),
1138 [
'increment_prefix' => $orderIncrementPrefix],
1139 [
'entity_store_id' => $entityStoreId]
1146 'increment_prefix' => $orderIncrementPrefix,
1148 $dbConnection->insert(
$setup->getTable(
'eav_entity_store'), $rowData);
1160 if ($this->isDryRun(
$data)) {
1164 $adminUserModuleIsInstalled = (bool)$this->deploymentConfig->get(
'modules/Magento_User');
1166 if ($adminUserModuleIsInstalled) {
1167 $this->assertDbConfigExists();
1169 $setup = $this->setupFactory->create($this->context->getResources());
1170 $adminAccount = $this->adminAccountFactory->create(
$setup->getConnection(), (array)
$data);
1171 $adminAccount->save();
1186 throw new \Magento\Setup\Exception(
1187 "Can't run this operation: deployment configuration is absent." 1188 .
" Run 'magento setup:config:set --help' for options." 1191 $this->cleanCaches();
1192 if (!$keepGeneratedFiles) {
1193 $this->cleanupGeneratedFiles();
1195 $this->log->log(
'Updating modules:');
1196 $this->createModulesConfig([]);
1206 $this->log->log(
'Starting Magento uninstallation:');
1209 $this->cleanCaches();
1212 'Can\'t clear cache due to the following error: ' 1213 . $e->getMessage() . PHP_EOL
1214 .
'To fully clean up your uninstallation, you must manually clear your cache.' 1220 $this->log->log(
'File system cleanup:');
1221 $messages = $this->cleanupFiles->clearAllFiles();
1226 $this->deleteDeploymentConfig();
1228 $this->log->logSuccess(
'Magento uninstallation complete.');
1238 private function enableCaches()
1241 $cacheManager = $this->objectManagerProvider->get()->create(\
Magento\Framework\
App\Cache\Manager::class);
1242 $types = $cacheManager->getAvailableTypes();
1243 $enabledTypes = $cacheManager->setEnabled($types,
true);
1244 $cacheManager->clean($enabledTypes);
1246 $this->log->log(
'Current status:');
1247 $this->log->log(print_r($cacheManager->getStatus(),
true));
1257 private function cleanCaches()
1260 $cacheManager = $this->objectManagerProvider->get()->get(\
Magento\Framework\
App\Cache\Manager::class);
1261 $types = $cacheManager->getAvailableTypes();
1262 $cacheManager->clean($types);
1263 $this->log->log(
'Cache cleared successfully');
1274 private function setMaintenanceMode(
$value)
1276 $this->maintenanceMode->set(
$value);
1286 return $this->installInfo;
1296 $cleanedUpDatabases = [];
1299 foreach ($connections as
$config) {
1303 $this->log->log(
"Can't create connection to database - skipping database cleanup");
1306 $this->log->log($e->getMessage() .
' - skipping database cleanup');
1312 if (!in_array($dbName, $cleanedUpDatabases)) {
1313 $this->log->log(
"Cleaning up database {$dbName}");
1314 $connection->query(
"DROP DATABASE IF EXISTS {$dbName}");
1315 $connection->query(
"CREATE DATABASE IF NOT EXISTS {$dbName}");
1316 $cleanedUpDatabases[] = $dbName;
1321 $this->log->log(
'No database connection defined - skipping database cleanup');
1330 private function deleteDeploymentConfig()
1333 $configFiles = $this->deploymentConfigReader->getFiles();
1334 foreach ($configFiles as $configFile) {
1335 $absolutePath = $configDir->getAbsolutePath($configFile);
1336 if (!$configDir->isFile($configFile)) {
1337 $this->log->log(
"The file '{$absolutePath}' doesn't exist - skipping cleanup");
1341 $this->log->log($absolutePath);
1342 $configDir->delete($configFile);
1343 }
catch (FileSystemException $e) {
1344 $this->log->log($e->getMessage());
1354 private function assertDbAccessible()
1356 $this->dbValidator->checkDatabaseConnection(
1357 $this->deploymentConfig->get(
1361 $this->deploymentConfig->get(
1365 $this->deploymentConfig->get(
1369 $this->deploymentConfig->get(
1374 $prefix = $this->deploymentConfig->get(
1379 $this->dbValidator->checkDatabaseTablePrefix(
$prefix);
1391 private function getSchemaDataHandler($moduleName,
$type)
1393 $className = str_replace(
'_',
'\\', $moduleName) .
'\Setup';
1395 case 'schema-install':
1399 case 'schema-upgrade':
1403 case 'schema-recurring':
1407 case 'data-install':
1411 case 'data-upgrade':
1415 case 'data-recurring':
1420 throw new \Magento\Setup\Exception(
"$className does not exist");
1436 $moduleContextList = [];
1437 foreach ($this->moduleList->getNames() as $moduleName) {
1438 if (
$type ===
'schema-version') {
1439 $dbVer =
$resource->getDbVersion($moduleName);
1441 $dbVer =
$resource->getDataVersion($moduleName);
1443 throw new \Magento\Setup\Exception(
"Unsupported version type $type is requested");
1445 if ($dbVer !==
false) {
1446 $moduleContextList[$moduleName] =
new ModuleContext($dbVer);
1448 $moduleContextList[$moduleName] =
new ModuleContext(
'');
1451 return $moduleContextList;
1459 private function cleanupGeneratedFiles()
1461 $this->log->log(
'File system cleanup:');
1462 $messages = $this->cleanupFiles->clearCodeGeneratedFiles();
1466 if (is_array($autoloader) && $autoloader[0] instanceof \
Magento\Framework\Code\Generator\Autoloader) {
1467 spl_autoload_unregister([$autoloader[0], $autoloader[1]]);
1473 $this->objectManagerProvider->reset();
1486 private function isAdminDataSet(
$request)
1499 }, ARRAY_FILTER_USE_BOTH);
1501 return !empty($adminData);
const CONFIG_PATH_INSTALL_DATE
const CONFIG_PATH_DB_CONNECTION_DEFAULT
const CONFIG_PATH_CRYPT_KEY
is_subclass_of($obj, $className)
elseif(isset( $params[ 'redirect_parent']))
const VERSION_COMPARE_GREATER
const CONFIG_PATH_DB_PREFIX
__construct(FilePermissions $filePermissions, Writer $deploymentConfigWriter, Reader $deploymentConfigReader, \Magento\Framework\App\DeploymentConfig $deploymentConfig, ModuleListInterface $moduleList, ModuleLoader $moduleLoader, AdminAccountFactory $adminAccountFactory, LoggerInterface $log, ConnectionFactory $connectionFactory, MaintenanceMode $maintenanceMode, Filesystem $filesystem, ObjectManagerProvider $objectManagerProvider, Context $context, SetupConfigModel $setupConfigModel, CleanupFiles $cleanupFiles, DbValidator $dbValidator, SetupFactory $setupFactory, DataSetupFactory $dataSetupFactory, \Magento\Framework\Setup\SampleData\State $sampleDataState, ComponentRegistrar $componentRegistrar, PhpReadinessCheck $phpReadinessCheck)
const INPUT_KEY_DISABLE_MODULES
checkApplicationFilePermissions()
const INPUT_KEY_CLEANUP_DB
installDeploymentConfig($data)
updateModulesSequence($keepGeneratedFiles=false)
const PROGRESS_LOG_RENDER
checkFilePermissionsForDbUpgrade()
declarativeInstallSchema(array $request)
const CONFIG_PATH_DB_CONNECTIONS
const INPUT_KEY_SALES_ORDER_INCREMENT_PREFIX
const RESPONSE_TYPE_ERROR
const INPUT_KEY_DRY_RUN_MODE
const INPUT_KEY_ENABLE_MODULES
const MYSQL_VERSION_REQUIRED
checkInstallationFilePermissions()
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE]
const CONVERT_OLD_SCRIPTS_KEY
createSchemaDataHandler($className, $interfaceName)