Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Installer.php
Go to the documentation of this file.
1 <?php
7 namespace Magento\Setup\Model;
8 
9 use Magento\Backend\Setup\ConfigOptionsList as BackendConfigOptionsList;
31 use Magento\Framework\Setup\PatchApplierInterface;
38 use Magento\Setup\Model\ConfigModel as SetupConfigModel;
44 use Magento\Setup\Validator\DbValidator;
46 
54 class Installer
55 {
59  const ENABLE_MODULES = 'enable-modules';
60  const DISABLE_MODULES = 'disable-modules';
66  const PROGRESS_LOG_RENDER = '[Progress: %d / %d]';
67  const PROGRESS_LOG_REGEX = '/\[Progress: (\d+) \/ (\d+)\]/s';
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;
79  const INFO_MESSAGE = 'message';
80 
84  const MYSQL_VERSION_REQUIRED = '5.6.0';
85 
91  private $filePermissions;
92 
98  private $deploymentConfigWriter;
99 
105  private $deploymentConfigReader;
106 
112  private $moduleList;
113 
119  private $moduleLoader;
120 
126  private $adminAccountFactory;
127 
133  private $log;
134 
140  private $connectionFactory;
141 
147  private $progress;
148 
154  private $maintenanceMode;
155 
161  private $filesystem;
162 
168  private $installInfo = [];
169 
173  private $deploymentConfig;
174 
178  private $objectManagerProvider;
179 
183  private $context;
184 
188  private $setupConfigModel;
189 
193  private $cleanupFiles;
194 
198  private $dbValidator;
199 
205  private $setupFactory;
206 
212  private $dataSetupFactory;
213 
217  protected $sampleDataState;
218 
224  private $componentRegistrar;
225 
229  private $phpReadinessCheck;
230 
234  private $declarationInstaller;
235 
239  private $schemaPersistor;
240 
244  private $patchApplierFactory;
245 
273  public function __construct(
274  FilePermissions $filePermissions,
275  Writer $deploymentConfigWriter,
276  Reader $deploymentConfigReader,
277  \Magento\Framework\App\DeploymentConfig $deploymentConfig,
278  ModuleListInterface $moduleList,
279  ModuleLoader $moduleLoader,
280  AdminAccountFactory $adminAccountFactory,
281  LoggerInterface $log,
282  ConnectionFactory $connectionFactory,
283  MaintenanceMode $maintenanceMode,
284  Filesystem $filesystem,
285  ObjectManagerProvider $objectManagerProvider,
286  Context $context,
287  SetupConfigModel $setupConfigModel,
288  CleanupFiles $cleanupFiles,
289  DbValidator $dbValidator,
290  SetupFactory $setupFactory,
291  DataSetupFactory $dataSetupFactory,
292  \Magento\Framework\Setup\SampleData\State $sampleDataState,
293  ComponentRegistrar $componentRegistrar,
294  PhpReadinessCheck $phpReadinessCheck
295  ) {
296  $this->filePermissions = $filePermissions;
297  $this->deploymentConfigWriter = $deploymentConfigWriter;
298  $this->deploymentConfigReader = $deploymentConfigReader;
299  $this->moduleList = $moduleList;
300  $this->moduleLoader = $moduleLoader;
301  $this->adminAccountFactory = $adminAccountFactory;
302  $this->log = $log;
303  $this->connectionFactory = $connectionFactory;
304  $this->maintenanceMode = $maintenanceMode;
305  $this->filesystem = $filesystem;
306  $this->installInfo[self::INFO_MESSAGE] = [];
307  $this->deploymentConfig = $deploymentConfig;
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;
315  $this->sampleDataState = $sampleDataState;
316  $this->componentRegistrar = $componentRegistrar;
317  $this->phpReadinessCheck = $phpReadinessCheck;
318  $this->schemaPersistor = $this->objectManagerProvider->get()->get(SchemaPersistor::class);
319  }
320 
328  public function install($request)
329  {
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', []];
336  }
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]];
342  $script[] = [
343  'Creating sales order increment prefix...',
344  'installOrderIncrementPrefix',
346  ];
347  }
348  if ($this->isAdminDataSet($request)) {
349  $script[] = ['Installing admin user...', 'installAdminUser', [$request]];
350  }
351 
352  if (!$this->isDryRun($request)) {
353  $script[] = ['Caches clearing:', 'cleanCaches', [$request]];
354  }
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);
361 
362  $this->log->log('Starting Magento installation:');
363 
364  foreach ($script as $item) {
365  list($message, $method, $params) = $item;
366  $this->log->log($message);
367  call_user_func_array([$this, $method], $params);
368  $this->logProgress();
369  }
370  $this->log->logSuccess('Magento installation complete.');
371  $this->log->logSuccess(
372  'Magento Admin URI: /'
373  . $this->deploymentConfig->get(BackendConfigOptionsList::CONFIG_PATH_BACKEND_FRONTNAME)
374  );
375 
376  if ($this->progress->getCurrent() != $this->progress->getTotal()) {
377  throw new \LogicException('Installation progress did not finish properly.');
378  }
379  if ($this->sampleDataState->hasError()) {
380  $this->log->log('Sample Data is installed with errors. See log file for details');
381  }
382  }
383 
389  private function getDeclarationInstaller()
390  {
391  if (!$this->declarationInstaller) {
392  $this->declarationInstaller = $this->objectManagerProvider->get()->get(
393  DeclarationInstaller::class
394  );
395  }
396  return $this->declarationInstaller;
397  }
398 
405  private function writeInstallationDate()
406  {
407  $dateData = new ConfigData(ConfigFilePool::APP_ENV);
408  $dateData->set(ConfigOptionsListConstants::CONFIG_PATH_INSTALL_DATE, date('r'));
409  $configData = [$dateData->getFileKey() => $dateData->getData()];
410  $this->deploymentConfigWriter->saveConfig($configData);
411  }
412 
421  private function createModulesConfig($request, $dryRun = false)
422  {
423  $all = array_keys($this->moduleLoader->load());
424  $deploymentConfig = $this->deploymentConfigReader->load();
425  $currentModules = isset($deploymentConfig[ConfigOptionsListConstants::KEY_MODULES])
427  $enable = $this->readListOfModules($all, $request, InstallCommand::INPUT_KEY_ENABLE_MODULES);
428  $disable = $this->readListOfModules($all, $request, InstallCommand::INPUT_KEY_DISABLE_MODULES);
429  $result = [];
430  foreach ($all as $module) {
431  if ((isset($currentModules[$module]) && !$currentModules[$module])) {
432  $result[$module] = 0;
433  } else {
434  $result[$module] = 1;
435  }
436  if (in_array($module, $disable)) {
437  $result[$module] = 0;
438  }
439  if (in_array($module, $enable)) {
440  $result[$module] = 1;
441  }
442  }
443  if (!$dryRun) {
444  $this->deploymentConfigWriter->saveConfig([ConfigFilePool::APP_CONFIG => ['modules' => $result]], true);
445  }
446  return $result;
447  }
448 
458  private function readListOfModules($all, $request, $key)
459  {
460  $result = [];
461  if (!empty($request[$key])) {
462  if ($request[$key] == 'all') {
463  $result = $all;
464  } else {
465  $result = explode(',', $request[$key]);
466  foreach ($result as $module) {
467  if (!in_array($module, $all)) {
468  throw new \LogicException("Unknown module in the requested list: '{$module}'");
469  }
470  }
471  }
472  }
473  return $result;
474  }
475 
481  private function logProgress()
482  {
483  if (!$this->progress) {
484  return;
485  }
486  $this->progress->setNext();
487  $this->log->logMeta(
488  sprintf(self::PROGRESS_LOG_RENDER, $this->progress->getCurrent(), $this->progress->getTotal())
489  );
490  }
491 
499  {
500  $this->throwExceptionForNotWritablePaths(
501  $this->filePermissions->getMissingWritablePathsForInstallation()
502  );
503  }
504 
511  public function checkExtensions()
512  {
513  $phpExtensionsCheckResult = $this->phpReadinessCheck->checkPhpExtensions();
514  if ($phpExtensionsCheckResult['responseType'] === ResponseTypeInterface::RESPONSE_TYPE_ERROR
515  && isset($phpExtensionsCheckResult['data']['missing'])
516  ) {
517  $errorMsg = "Missing following extensions: '"
518  . implode("' '", $phpExtensionsCheckResult['data']['missing']) . "'";
519  throw new \Exception($errorMsg);
520  }
521  }
522 
529  {
530  $results = $this->filePermissions->getUnnecessaryWritableDirectoriesForApplication();
531  if ($results) {
532  $errorMsg = "For security, remove write permissions from these directories: '"
533  . implode("' '", $results) . "'";
534  $this->log->log($errorMsg);
535  $this->installInfo[self::INFO_MESSAGE][] = $errorMsg;
536  }
537  }
538 
546  {
548  $this->createModulesConfig($data);
549  $userData = is_array($data) ? $data : $data->getArrayCopy();
550  $this->setupConfigModel->process($userData);
551  $deploymentConfigData = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_CRYPT_KEY);
552  if (isset($deploymentConfigData)) {
553  $this->installInfo[ConfigOptionsListConstants::KEY_ENCRYPTION_KEY] = $deploymentConfigData;
554  }
555  // reset object manager now that there is a deployment config
556  $this->objectManagerProvider->reset();
557  }
558 
565  private function setupModuleRegistry(SchemaSetupInterface $setup)
566  {
567  $connection = $setup->getConnection();
568 
569  if (!$connection->isTableExists($setup->getTable('setup_module'))) {
573  $table = $connection->newTable($setup->getTable('setup_module'))
574  ->addColumn(
575  'module',
576  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
577  50,
578  ['nullable' => false, 'primary' => true],
579  'Module'
580  )->addColumn(
581  'schema_version',
582  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
583  50,
584  [],
585  'Schema Version'
586  )->addColumn(
587  'data_version',
588  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
589  50,
590  [],
591  'Data Version'
592  )->setComment('Module versions registry');
593  $connection->createTable($table);
594  }
595  }
596 
603  private function setupCoreTables(SchemaSetupInterface $setup)
604  {
605  /* @var $connection \Magento\Framework\DB\Adapter\AdapterInterface */
606  $connection = $setup->getConnection();
607  $setup->startSetup();
608 
609  $this->setupSessionTable($setup, $connection);
610  $this->setupCacheTable($setup, $connection);
611  $this->setupCacheTagTable($setup, $connection);
612  $this->setupFlagTable($setup, $connection);
613 
614  $setup->endSetup();
615  }
616 
624  private function setupSessionTable(
625  SchemaSetupInterface $setup,
626  \Magento\Framework\DB\Adapter\AdapterInterface $connection
627  ) {
628  if (!$connection->isTableExists($setup->getTable('session'))) {
629  $table = $connection->newTable(
630  $setup->getTable('session')
631  )->addColumn(
632  'session_id',
633  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
634  255,
635  ['nullable' => false, 'primary' => true],
636  'Session Id'
637  )->addColumn(
638  'session_expires',
639  \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
640  null,
641  ['unsigned' => true, 'nullable' => false, 'default' => '0'],
642  'Date of Session Expiration'
643  )->addColumn(
644  'session_data',
645  \Magento\Framework\DB\Ddl\Table::TYPE_BLOB,
646  '2M',
647  ['nullable' => false],
648  'Session Data'
649  )->setComment(
650  'Database Sessions Storage'
651  );
652  $connection->createTable($table);
653  }
654  }
655 
663  private function setupCacheTable(
664  SchemaSetupInterface $setup,
665  \Magento\Framework\DB\Adapter\AdapterInterface $connection
666  ) {
667  if (!$connection->isTableExists($setup->getTable('cache'))) {
668  $table = $connection->newTable(
669  $setup->getTable('cache')
670  )->addColumn(
671  'id',
672  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
673  200,
674  ['nullable' => false, 'primary' => true],
675  'Cache Id'
676  )->addColumn(
677  'data',
678  \Magento\Framework\DB\Ddl\Table::TYPE_BLOB,
679  '2M',
680  [],
681  'Cache Data'
682  )->addColumn(
683  'create_time',
684  \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
685  null,
686  [],
687  'Cache Creation Time'
688  )->addColumn(
689  'update_time',
690  \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
691  null,
692  [],
693  'Time of Cache Updating'
694  )->addColumn(
695  'expire_time',
696  \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
697  null,
698  [],
699  'Cache Expiration Time'
700  )->addIndex(
701  $setup->getIdxName('cache', ['expire_time']),
702  ['expire_time']
703  )->setComment(
704  'Caches'
705  );
706  $connection->createTable($table);
707  }
708  }
709 
717  private function setupCacheTagTable(
718  SchemaSetupInterface $setup,
719  \Magento\Framework\DB\Adapter\AdapterInterface $connection
720  ) {
721  if (!$connection->isTableExists($setup->getTable('cache_tag'))) {
722  $table = $connection->newTable(
723  $setup->getTable('cache_tag')
724  )->addColumn(
725  'tag',
726  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
727  100,
728  ['nullable' => false, 'primary' => true],
729  'Tag'
730  )->addColumn(
731  'cache_id',
732  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
733  200,
734  ['nullable' => false, 'primary' => true],
735  'Cache Id'
736  )->addIndex(
737  $setup->getIdxName('cache_tag', ['cache_id']),
738  ['cache_id']
739  )->setComment(
740  'Tag Caches'
741  );
742  $connection->createTable($table);
743  }
744  }
745 
753  private function setupFlagTable(
754  SchemaSetupInterface $setup,
755  \Magento\Framework\DB\Adapter\AdapterInterface $connection
756  ) {
757  if (!$connection->isTableExists($setup->getTable('flag'))) {
758  $table = $connection->newTable(
759  $setup->getTable('flag')
760  )->addColumn(
761  'flag_id',
762  \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
763  null,
764  ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
765  'Flag Id'
766  )->addColumn(
767  'flag_code',
768  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
769  255,
770  ['nullable' => false],
771  'Flag Code'
772  )->addColumn(
773  'state',
774  \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
775  null,
776  ['unsigned' => true, 'nullable' => false, 'default' => '0'],
777  'Flag State'
778  )->addColumn(
779  'flag_data',
780  \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
781  '64k',
782  [],
783  'Flag Data'
784  )->addColumn(
785  'last_update',
786  \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP,
787  null,
788  ['nullable' => false, 'default' => \Magento\Framework\DB\Ddl\Table::TIMESTAMP_INIT_UPDATE],
789  'Date of Last Flag Update'
790  )->addIndex(
791  $setup->getIdxName('flag', ['last_update']),
792  ['last_update']
793  )->setComment(
794  'Flag'
795  );
796  $connection->createTable($table);
797  }
798  }
799 
806  public function declarativeInstallSchema(array $request)
807  {
808  $this->getDeclarationInstaller()->installSchema($request);
809  }
810 
817  public function installSchema(array $request)
818  {
820  $registry = $this->objectManagerProvider->get()->get(\Magento\Framework\Registry::class);
821  //For backward compatibility in install and upgrade scripts with enabled parallelization.
822  $registry->register('setup-mode-enabled', true);
823 
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:');
830  $this->declarativeInstallSchema($request);
831  $this->handleDBSchemaData($setup, 'schema', $request);
833  $adapter = $setup->getConnection();
834  $schemaListener = $adapter->getSchemaListener();
835 
836  if ($this->convertationOfOldScriptsIsAllowed($request)) {
837  $schemaListener->setResource('default');
838  $this->schemaPersistor->persist($schemaListener);
839  }
840 
841  $registry->unregister('setup-mode-enabled');
842  }
843 
850  private function convertationOfOldScriptsIsAllowed(array $request)
851  {
854  }
855 
862  public function installDataFixtures(array $request = [])
863  {
865  $registry = $this->objectManagerProvider->get()->get(\Magento\Framework\Registry::class);
866  //For backward compatibility in install and upgrade scripts with enabled parallelization.
867  $registry->register('setup-mode-enabled', true);
868 
869  $this->assertDbConfigExists();
870  $this->assertDbAccessible();
871  $setup = $this->dataSetupFactory->create();
873  $this->log->log('Data install/update:');
874  $this->handleDBSchemaData($setup, 'data', $request);
875 
876  $registry->unregister('setup-mode-enabled');
877  }
878 
886  {
887  $this->throwExceptionForNotWritablePaths(
888  $this->filePermissions->getMissingWritableDirectoriesForDbUpgrade()
889  );
890  }
891 
899  private function throwExceptionForNotWritablePaths(array $paths)
900  {
901  if ($paths) {
902  $errorMsg = "Missing write permissions to the following paths:" . PHP_EOL . implode(PHP_EOL, $paths);
903  throw new \Exception($errorMsg);
904  }
905  }
906 
920  private function handleDBSchemaData($setup, $type, array $request)
921  {
922  if (!(($type === 'schema') || ($type === 'data'))) {
923  throw new \Magento\Setup\Exception("Unsupported operation type $type is requested");
924  }
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);
932  $adapter = $setup->getConnection();
933  $schemaListener = $adapter->getSchemaListener();
934  $this->patchApplierFactory = $this->objectManagerProvider->get()->create(
935  PatchApplierFactory::class,
936  [
937  'objectManager' => $this->objectManagerProvider->get()
938  ]
939  );
941  if ($type === 'schema') {
942  $patchApplier = $this->patchApplierFactory->create(['schemaSetup' => $setup]);
943  } elseif ($type === 'data') {
944  $patchApplier = $this->patchApplierFactory->create([
945  'moduleDataSetup' => $setup,
946  'objectManager' => $this->objectManagerProvider->get()
947  ]);
948  }
949 
950  foreach ($moduleNames as $moduleName) {
951  if ($this->isDryRun($request)) {
952  $this->log->log("Module '{$moduleName}':");
953  $this->logProgress();
954  continue;
955  }
956  $schemaListener->setModuleName($moduleName);
957  $this->log->log("Module '{$moduleName}':");
958  $configVer = $this->moduleList->getOne($moduleName)['setup_version'];
959  $currentVersion = $moduleContextList[$moduleName]->getVersion();
960  // Schema/Data is installed
961  if ($currentVersion !== '') {
962  $status = version_compare($configVer, $currentVersion);
964  $upgrader = $this->getSchemaDataHandler($moduleName, $upgradeType);
965  if ($upgrader) {
966  $this->log->logInline("Upgrading $type.. ");
967  $upgrader->upgrade($setup, $moduleContextList[$moduleName]);
968  if ($type === 'schema') {
969  $resource->setDbVersion($moduleName, $configVer);
970  } elseif ($type === 'data') {
971  $resource->setDataVersion($moduleName, $configVer);
972  }
973  }
974  }
975  } elseif ($configVer) {
976  $installer = $this->getSchemaDataHandler($moduleName, $installType);
977  if ($installer) {
978  $this->log->logInline("Installing $type... ");
979  $installer->install($setup, $moduleContextList[$moduleName]);
980  }
981  $upgrader = $this->getSchemaDataHandler($moduleName, $upgradeType);
982  if ($upgrader) {
983  $this->log->logInline("Upgrading $type... ");
984  $upgrader->upgrade($setup, $moduleContextList[$moduleName]);
985  }
986  }
987 
988  if ($configVer) {
989  if ($type === 'schema') {
990  $resource->setDbVersion($moduleName, $configVer);
991  } elseif ($type === 'data') {
992  $resource->setDataVersion($moduleName, $configVer);
993  }
994  }
995 
999  if ($type === 'schema') {
1000  $patchApplier->applySchemaPatch($moduleName);
1001  } elseif ($type === 'data') {
1002  $patchApplier->applyDataPatch($moduleName);
1003  }
1004 
1005  $this->logProgress();
1006  }
1007 
1008  if ($type === 'schema') {
1009  $this->log->log('Schema post-updates:');
1010  $handlerType = 'schema-recurring';
1011  } elseif ($type === 'data') {
1012  $this->log->log('Data post-updates:');
1013  $handlerType = 'data-recurring';
1014  }
1015  foreach ($moduleNames as $moduleName) {
1016  if ($this->isDryRun($request)) {
1017  $this->log->log("Module '{$moduleName}':");
1018  $this->logProgress();
1019  continue;
1020  }
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]);
1026  }
1027  $this->logProgress();
1028  }
1029  }
1030 
1037  private function assertDbConfigExists()
1038  {
1040  if (!$config) {
1041  throw new \Magento\Setup\Exception(
1042  "Can't run this operation: configuration for DB connection is absent."
1043  );
1044  }
1045  }
1046 
1053  private function isDryRun(array $request)
1054  {
1057  }
1058 
1065  public function installUserConfig($data)
1066  {
1067  if ($this->isDryRun($data)) {
1068  return;
1069  }
1070  $userConfig = new StoreConfigurationDataMapper();
1072  $appState = $this->objectManagerProvider->get()->get(\Magento\Framework\App\State::class);
1073  $appState->setAreaCode(\Magento\Framework\App\Area::AREA_GLOBAL);
1074  $configData = $userConfig->getConfigData($data);
1075  if (count($configData) === 0) {
1076  return;
1077  }
1078 
1080  $configFactory = $this->objectManagerProvider->get()->create(\Magento\Config\Model\Config\Factory::class);
1081  foreach ($configData as $key => $val) {
1082  $configModel = $configFactory->create();
1083  $configModel->setDataByPath($key, $val);
1084  $configModel->save();
1085  }
1086  }
1087 
1096  protected function createSchemaDataHandler($className, $interfaceName)
1097  {
1098  if (class_exists($className)) {
1099  if (!is_subclass_of($className, $interfaceName) && $className !== $interfaceName) {
1100  throw new \Magento\Setup\Exception($className . ' must implement \\' . $interfaceName);
1101  } else {
1102  return $this->objectManagerProvider->get()->create($className);
1103  }
1104  }
1105  return null;
1106  }
1107 
1116  private function installOrderIncrementPrefix($orderIncrementPrefix)
1117  {
1118  $setup = $this->setupFactory->create($this->context->getResources());
1119  $dbConnection = $setup->getConnection();
1120 
1121  // get entity_type_id for order
1122  $select = $dbConnection->select()
1123  ->from($setup->getTable('eav_entity_type'), 'entity_type_id')
1124  ->where('entity_type_code = \'order\'');
1125  $entityTypeId = $dbConnection->fetchOne($select);
1126 
1127  // See if row already exists
1128  $incrementRow = $dbConnection->fetchRow(
1129  'SELECT * FROM ' . $setup->getTable('eav_entity_store') . ' WHERE entity_type_id = ? AND store_id = ?',
1131  );
1132 
1133  if (!empty($incrementRow)) {
1134  // row exists, update it
1135  $entityStoreId = $incrementRow['entity_store_id'];
1136  $dbConnection->update(
1137  $setup->getTable('eav_entity_store'),
1138  ['increment_prefix' => $orderIncrementPrefix],
1139  ['entity_store_id' => $entityStoreId]
1140  );
1141  } else {
1142  // add a row to the store's eav table, setting the increment_prefix
1143  $rowData = [
1144  'entity_type_id' => $entityTypeId,
1145  'store_id' => Store::DISTRO_STORE_ID,
1146  'increment_prefix' => $orderIncrementPrefix,
1147  ];
1148  $dbConnection->insert($setup->getTable('eav_entity_store'), $rowData);
1149  }
1150  }
1151 
1158  public function installAdminUser($data)
1159  {
1160  if ($this->isDryRun($data)) {
1161  return;
1162  }
1163 
1164  $adminUserModuleIsInstalled = (bool)$this->deploymentConfig->get('modules/Magento_User');
1165  //Admin user data is not system data, so we need to install it only if schema for admin user was installed
1166  if ($adminUserModuleIsInstalled) {
1167  $this->assertDbConfigExists();
1168  $data += ['db-prefix' => $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DB_PREFIX)];
1169  $setup = $this->setupFactory->create($this->context->getResources());
1170  $adminAccount = $this->adminAccountFactory->create($setup->getConnection(), (array)$data);
1171  $adminAccount->save();
1172  }
1173  }
1174 
1182  public function updateModulesSequence($keepGeneratedFiles = false)
1183  {
1184  $config = $this->deploymentConfig->get(ConfigOptionsListConstants::KEY_MODULES);
1185  if (!$config) {
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."
1189  );
1190  }
1191  $this->cleanCaches();
1192  if (!$keepGeneratedFiles) {
1193  $this->cleanupGeneratedFiles();
1194  }
1195  $this->log->log('Updating modules:');
1196  $this->createModulesConfig([]);
1197  }
1198 
1204  public function uninstall()
1205  {
1206  $this->log->log('Starting Magento uninstallation:');
1207 
1208  try {
1209  $this->cleanCaches();
1210  } catch (\Exception $e) {
1211  $this->log->log(
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.'
1215  );
1216  }
1217 
1218  $this->cleanupDb();
1219 
1220  $this->log->log('File system cleanup:');
1221  $messages = $this->cleanupFiles->clearAllFiles();
1222  foreach ($messages as $message) {
1223  $this->log->log($message);
1224  }
1225 
1226  $this->deleteDeploymentConfig();
1227 
1228  $this->log->logSuccess('Magento uninstallation complete.');
1229  }
1230 
1238  private function enableCaches()
1239  {
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);
1245 
1246  $this->log->log('Current status:');
1247  $this->log->log(print_r($cacheManager->getStatus(), true));
1248  }
1249 
1257  private function cleanCaches()
1258  {
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');
1264  }
1265 
1274  private function setMaintenanceMode($value)
1275  {
1276  $this->maintenanceMode->set($value);
1277  }
1278 
1284  public function getInstallInfo()
1285  {
1286  return $this->installInfo;
1287  }
1288 
1294  public function cleanupDb()
1295  {
1296  $cleanedUpDatabases = [];
1297  $connections = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTIONS, []);
1298  //Do database cleanup for all shards
1299  foreach ($connections as $config) {
1300  try {
1301  $connection = $this->connectionFactory->create($config);
1302  if (!$connection) {
1303  $this->log->log("Can't create connection to database - skipping database cleanup");
1304  }
1305  } catch (\Exception $e) {
1306  $this->log->log($e->getMessage() . ' - skipping database cleanup');
1307  return;
1308  }
1309 
1310  $dbName = $connection->quoteIdentifier($config[ConfigOptionsListConstants::KEY_NAME]);
1311  //If for different shards one database was specified - no need to clean it few times
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;
1317  }
1318  }
1319 
1320  if (empty($config)) {
1321  $this->log->log('No database connection defined - skipping database cleanup');
1322  }
1323  }
1324 
1330  private function deleteDeploymentConfig()
1331  {
1332  $configDir = $this->filesystem->getDirectoryWrite(DirectoryList::CONFIG);
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");
1338  continue;
1339  }
1340  try {
1341  $this->log->log($absolutePath);
1342  $configDir->delete($configFile);
1343  } catch (FileSystemException $e) {
1344  $this->log->log($e->getMessage());
1345  }
1346  }
1347  }
1348 
1354  private function assertDbAccessible()
1355  {
1356  $this->dbValidator->checkDatabaseConnection(
1357  $this->deploymentConfig->get(
1360  ),
1361  $this->deploymentConfig->get(
1364  ),
1365  $this->deploymentConfig->get(
1368  ),
1369  $this->deploymentConfig->get(
1372  )
1373  );
1374  $prefix = $this->deploymentConfig->get(
1377  );
1378  if (null !== $prefix) {
1379  $this->dbValidator->checkDatabaseTablePrefix($prefix);
1380  }
1381  }
1382 
1391  private function getSchemaDataHandler($moduleName, $type)
1392  {
1393  $className = str_replace('_', '\\', $moduleName) . '\Setup';
1394  switch ($type) {
1395  case 'schema-install':
1396  $className .= '\InstallSchema';
1397  $interface = self::SCHEMA_INSTALL;
1398  break;
1399  case 'schema-upgrade':
1400  $className .= '\UpgradeSchema';
1401  $interface = self::SCHEMA_UPGRADE;
1402  break;
1403  case 'schema-recurring':
1404  $className .= '\Recurring';
1405  $interface = self::SCHEMA_INSTALL;
1406  break;
1407  case 'data-install':
1408  $className .= '\InstallData';
1409  $interface = self::DATA_INSTALL;
1410  break;
1411  case 'data-upgrade':
1412  $className .= '\UpgradeData';
1413  $interface = self::DATA_UPGRADE;
1414  break;
1415  case 'data-recurring':
1416  $className .= '\RecurringData';
1417  $interface = self::DATA_INSTALL;
1418  break;
1419  default:
1420  throw new \Magento\Setup\Exception("$className does not exist");
1421  }
1422 
1423  return $this->createSchemaDataHandler($className, $interface);
1424  }
1425 
1434  private function generateListOfModuleContext($resource, $type)
1435  {
1436  $moduleContextList = [];
1437  foreach ($this->moduleList->getNames() as $moduleName) {
1438  if ($type === 'schema-version') {
1439  $dbVer = $resource->getDbVersion($moduleName);
1440  } elseif ($type === 'data-version') {
1441  $dbVer = $resource->getDataVersion($moduleName);
1442  } else {
1443  throw new \Magento\Setup\Exception("Unsupported version type $type is requested");
1444  }
1445  if ($dbVer !== false) {
1446  $moduleContextList[$moduleName] = new ModuleContext($dbVer);
1447  } else {
1448  $moduleContextList[$moduleName] = new ModuleContext('');
1449  }
1450  }
1451  return $moduleContextList;
1452  }
1453 
1459  private function cleanupGeneratedFiles()
1460  {
1461  $this->log->log('File system cleanup:');
1462  $messages = $this->cleanupFiles->clearCodeGeneratedFiles();
1463 
1464  // unload Magento autoloader because it may be using compiled definition
1465  foreach (spl_autoload_functions() as $autoloader) {
1466  if (is_array($autoloader) && $autoloader[0] instanceof \Magento\Framework\Code\Generator\Autoloader) {
1467  spl_autoload_unregister([$autoloader[0], $autoloader[1]]);
1468  break;
1469  }
1470  }
1471 
1472  // Corrected Magento autoloader will be loaded upon next get() call on $this->objectManagerProvider
1473  $this->objectManagerProvider->reset();
1474 
1475  foreach ($messages as $message) {
1476  $this->log->log($message);
1477  }
1478  }
1479 
1486  private function isAdminDataSet($request)
1487  {
1488  $adminData = array_filter($request, function ($value, $key) {
1489  return in_array(
1490  $key,
1491  [
1497  ]
1498  ) && $value !== null;
1499  }, ARRAY_FILTER_USE_BOTH);
1500 
1501  return !empty($adminData);
1502  }
1503 }
$results
Definition: popup.phtml:13
$componentRegistrar
Definition: bootstrap.php:23
is_subclass_of($obj, $className)
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$config
Definition: fraud_order.php:17
$resource
Definition: bulk.php:12
$message
__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)
Definition: Installer.php:273
$deploymentConfig
$adapter
Definition: webapi_user.php:16
$type
Definition: item.phtml:13
updateModulesSequence($keepGeneratedFiles=false)
Definition: Installer.php:1182
$prefix
Definition: name.phtml:25
$value
Definition: gender.phtml:16
declarativeInstallSchema(array $request)
Definition: Installer.php:806
$status
Definition: order_status.php:8
$method
Definition: info.phtml:13
$configFactory
Definition: config_data.php:43
$setup
Definition: trigger.php:12
$paths
Definition: _bootstrap.php:83
$connection
Definition: bulk.php:13
$table
Definition: trigger.php:14
$params[\Magento\Store\Model\StoreManager::PARAM_RUN_CODE]
Definition: website.php:18
$filesystem
if($currentSelectedMethod==$_code) $className
Definition: form.phtml:31
createSchemaDataHandler($className, $interfaceName)
Definition: Installer.php:1096