'IIS', self::SERVER_APACHE => 'Apache', self::SERVER_OTHER => 'Другой (nginx и др.)', ]; public function options($actionID) { return [ 'help', 'domain', 'db_type', 'db_host', 'db_port', 'db_name', 'php_path', 'odinc_url', 'db_username', 'db_password', 'server_type', 'portal_name', 'odinc_url_stud', 'odinc_url_abit', 'db_silent_setup', 'odinc_login_stud', 'odinc_login_abit', 'check_environments', 'enable_1c_services', 'odinc_password_stud', 'odinc_password_abit', ]; } public function optionAliases() { return [ 'h' => 'help', 'd' => 'domain', 'dt' => 'db_type', 'dh' => 'db_host', 'dp' => 'db_port', 'dn' => 'db_name', 'pp' => 'php_path', 'ou' => 'odinc_url', 'du' => 'db_username', 'st' => 'server_type', 'pn' => 'portal_name', 'dpw' => 'db_password', 'ds' => 'db_silent_setup', 'ous' => 'odinc_url_stud', 'oua' => 'odinc_url_abit', 'ols' => 'odinc_login_stud', 'ola' => 'odinc_login_abit', 'ce' => 'check_environments', 'es' => 'enable_1c_services', 'ops' => 'odinc_password_stud', 'opa' => 'odinc_password_abit', ]; } public function beforeAction($action) { if (!parent::beforeAction($action)) { return false; } $this->check_environments = $this->convertToBoolean($this->check_environments, true); if (!isset($this->check_environments)) { return false; } $this->db_silent_setup = $this->convertToBoolean($this->db_silent_setup, false); if (!isset($this->db_silent_setup)) { return false; } if (empty($this->php_path)) { $this->php_path = 'php'; } if (empty($this->db_name)) { $this->db_name = 'lk_db'; } if (empty($this->domain)) { $this->domain = 'localhost'; } if (empty($this->db_password)) { $this->db_password = ''; } if (empty($this->db_type)) { $this->db_type = 'mysql'; } if (empty($this->db_port)) { $this->db_port = '3306'; if ($this->db_type == 'pgsql') { $this->db_port = '5432'; } } if (empty($this->db_host)) { $this->db_host = 'localhost'; } if (empty($this->db_username)) { $this->db_username = 'root'; } if (empty($this->portal_name)) { $this->portal_name = '1c portal'; } if (empty($this->odinc_password_stud)) { $this->odinc_password_stud = '1'; } if (empty($this->odinc_password_abit)) { $this->odinc_password_abit = '1'; } if (empty($this->odinc_url)) { $this->odinc_url = 'http://localhost/local'; } if (empty($this->odinc_url_stud)) { $this->odinc_url_stud = '/ws/Study.1cws?wsdl'; } if (empty($this->odinc_url_abit)) { $this->odinc_url_abit = '/ws/webabit.1cws?wsdl'; } if (empty($this->odinc_login_abit)) { $this->odinc_login_abit = 'Пользователь Web-сервис WebAbit'; } if (empty($this->odinc_login_stud)) { $this->odinc_login_stud = 'Пользователь Web-сервис WebStudy'; } if (isset($this->server_type)) { $this->server_type = (int)$this->server_type; } $this->rootPath = FileHelper::normalizePath(dirname(__FILE__) . '/../..'); return true; } public function actionIndex() { if ($this->check_environments) { if (!$this->environmentsIsCorrect()) { $this->printError('Система не удовлетворяет требованиям'); return ExitCode::UNSPECIFIED_ERROR; } if (!$this->foldersPermissionIsCorrect()) { $this->printError('Система не удовлетворяет требованиям'); return ExitCode::UNSPECIFIED_ERROR; } } if (!$this->setServerSettings()) { $this->printError('Не удалось настроить конфигурацию сервера'); return ExitCode::UNSPECIFIED_ERROR; } if (!$this->setDataBaseSettings()) { $this->printError('Не удалось настроить конфигурацию сервера СУБД'); return ExitCode::UNSPECIFIED_ERROR; } if (!$this->setEnvironment()) { $this->printError('Не удалось настроить .env сервера'); return ExitCode::UNSPECIFIED_ERROR; } if (!$this->installEnding()) { $this->printError('Не удалось завершить установку'); return ExitCode::UNSPECIFIED_ERROR; } return ExitCode::OK; } public function printNextStepNumber() { echo 'Шаг ' . $this->ansiFormat('№', Console::FG_CYAN) . $this->ansiFormat($this->stepNumber, Console::FG_YELLOW) . "\n"; $this->stepNumber++; } public function actionVerify() { echo Table::widget([ 'headers' => ['Project', 'Status'], 'rows' => [ ['Portal 1C', 'OK'], ], ]); return ExitCode::OK; } private function convertToBoolean($param = '', $default = false) { if (empty($param)) { return $default; } $param = mb_strtolower($param); if (in_array($param, self::YES_LIST)) { return true; } elseif (in_array($param, self::NO_LIST)) { return false; } else { $this->printError('Неверно указанный параметр.'); return null; } } private function printError($message = '') { $message = $this->ansiFormat( $message, Console::FG_RED ); $this->stdout( "Ошибка. {$message}", Console::BOLD ); } private function foldersPermissionIsCorrect() { $this->printNextStepNumber(); $path = FileHelper::normalizePath("{$this->rootPath}/frontend/web/install/src/steps/webserver/"); require_once("{$path}/folders_requirements.php"); $folders = getFolders(); $table = [ 'headers' => ['№', 'Директория', 'Права'], 'rows' => [], ]; $hasError = false; $i = 1; foreach ($folders as $dir => $permission) { if ($permission) { $status = '× некорректные права ×'; $hasError = true; } else { $status = '✓ права корректные ✓'; } $table['rows'][] = [ $i, $dir, $status, ]; $i++; } echo 'Проверка ' . $this->ansiFormat('прав доступа', Console::FG_YELLOW) . "\n"; echo Table::widget($table); $finalWord = $this->ansiFormat('СООТВЕТСТВУЮТ', Console::FG_GREEN); if ($hasError) { $finalWord = $this->ansiFormat('НЕ СООТВЕТСТВУЮТ', Console::FG_RED); } echo "Директории {$finalWord} правам доступа\n\n"; return !$hasError; } private function environmentsIsCorrect() { $this->printNextStepNumber(); $path = FileHelper::normalizePath("{$this->rootPath}/frontend/web/install/src/steps/system_requirements"); $frameworkPath = FileHelper::normalizePath("{$path}/requirements"); if (!is_dir($frameworkPath)) { $this->printError('Невозможно найти Yii фреймворк'); return false; } require_once("{$path}/customs_requirements.php"); $requirementsChecker = getRequirementChecker($frameworkPath, $this->php_path); if (empty($requirementsChecker->result['requirements'])) { return true; } $table = [ 'headers' => ['№', 'Результат', 'Наименование', 'Описание'], 'rows' => [], ]; $hasError = false; foreach ($requirementsChecker->result['requirements'] as $key => $requirement) { if ($requirement['error']) { $status = '× ошибка ×'; $hasError = true; } elseif ($requirement['warning']) { $status = '! внимание !'; } else { $status = '✓ успех ✓'; } $memo = $requirement['memo']; if (strlen((string)$memo) > 115) { $memo = '-'; } $table['rows'][] = [ $key, $status, $requirement['name'], $memo, ]; } echo 'Проверка корректности ' . $this->ansiFormat('окружения', Console::FG_YELLOW) . "\n"; echo Table::widget($table); $finalWord = $this->ansiFormat('СООТВЕТСТВУЕТ', Console::FG_GREEN); if ($hasError) { $finalWord = $this->ansiFormat('НЕ СООТВЕТСТВУЕТ', Console::FG_RED); } echo "Окружение {$finalWord} минимальным требованиям\n\n"; return !$hasError; } private function setServerSettings() { $this->printNextStepNumber(); if (!isset($this->server_type)) { echo "Выберите используемый веб-сервер:\n"; foreach (self::SERVERS_LIST as $number => $name) { echo " {$number}) $name\n"; } $this->server_type = (int)readline(''); } $server = ArrayHelper::getValue(self::SERVERS_LIST, $this->server_type); if (isset($server)) { $server = $this->ansiFormat($server, Console::FG_YELLOW); echo "Копирование конфигурации для сервера \"{$server}\"\n"; $confsPath = FileHelper::normalizePath("{$this->rootPath}/confs"); $copyResult = false; switch ($this->server_type) { case self::SERVER_APACHE: copy("{$confsPath}/.htaccess", "{$this->rootPath}/.htaccess"); $copyResult = file_exists("{$this->rootPath}/.htaccess"); break; case self::SERVER_IIS: copy("{$confsPath}/web.config", "{$this->rootPath}/web.config"); $copyResult = file_exists("{$this->rootPath}/web.config"); break; case self::SERVER_OTHER: $copyResult = true; break; } if ($copyResult) { echo $this->ansiFormat("Конфигурация успешно скопирована\n\n", Console::FG_GREEN); } else { echo $this->ansiFormat("Произошла ошибка копирования\n\n", Console::FG_RED); } return $copyResult; } else { $errorType = $this->ansiFormat('НЕ ВЕРНЫЙ', Console::FG_RED); echo "Выбран {$errorType} тип сервера\n\n"; } return false; } private function setDataBaseSettings() { $this->printNextStepNumber(); if (!$this->db_silent_setup) { $attrList = [ 'db_type' => 'Тип СУБД (mysql/pgsql)', 'db_host' => 'Адрес сервера', 'db_port' => 'Порт сервера', 'db_username' => 'Имя пользователя', 'db_password' => 'Пароль', 'db_name' => 'Наименование базы данных', ]; echo "Введите параметры для подключения к серверу СУБД (значение в скобках будет задано при пропуске параметра)\n"; foreach ($attrList as $attr => $alias) { $buffer = (string)readline(" {$alias} ({$this->{$attr}}): "); $buffer = trim((string)$buffer); if (!empty($buffer)) { $this->{$attr} = $buffer; } } echo "\n"; } if (preg_match('/[^a-zA-Z0-9]+^_/', $this->db_name)) { $this->printError('В названии БД используются недопустимый символ'); return false; } $serverSettings = $this->ansiFormat( "{$this->db_type}:host={$this->db_host} port={$this->db_port} username={$this->db_username} db_name={$this->db_name}", Console::FG_YELLOW ); echo "Настройка сервера СУБД: \"{$serverSettings}\".\n"; $path = FileHelper::normalizePath("{$this->rootPath}/frontend/web/install/src/controllers/DatabaseController.php"); require_once($path); $className = 'DatabaseController'; $databaseController = new $className(); $databaseController->type = $this->db_type; $databaseController->port = $this->db_port; $databaseController->server = $this->db_host; $databaseController->dbname = $this->db_name; $databaseController->username = $this->db_username; $databaseController->password = $this->db_password; $connectResult = $databaseController->connectToServer(false); if ($connectResult === true) { $useDbResult = $databaseController->useDb(false); if ($useDbResult === true) { $writeDsnToEnvResult = $databaseController->writeDsnToEnv('/..', false); if ($writeDsnToEnvResult === true) { echo $this->ansiFormat("Cервер СУБД успешно настроен\n\n", Console::FG_GREEN); return true; } else { $this->printError("{$writeDsnToEnvResult}\n"); return false; } } else { $this->printError("{$useDbResult}\n"); return false; } } else { $this->printError("{$connectResult}\n"); } return false; } private function setEnvironment() { $this->printNextStepNumber(); $attrList = [ 'domain' => 'Домен личного кабинета', 'portal_name' => 'Имя личного кабинета', ]; echo "Введите параметры для настройки сервера (значение в скобках будет задано при пропуске параметра)\n"; foreach ($attrList as $attr => $alias) { $buffer = (string)readline(" {$alias} ({$this->{$attr}}): "); $buffer = trim((string)$buffer); if (!empty($buffer)) { $this->{$attr} = $buffer; } }; echo "\n"; if (!isset($this->enable_1c_services)) { $this->enable_1c_services = $this->convertToBoolean( readline("Включить работу с SOAP-сервисами 1С? (Y / n): \n"), true ); } else { $this->enable_1c_services = $this->convertToBoolean($this->enable_1c_services, true); } if (!isset($this->enable_1c_services)) { return false; } $path = FileHelper::normalizePath("{$this->rootPath}/frontend/web/install/src/controllers/EnvironmentController.php"); require_once($path); $className = 'EnvironmentController'; $environmentController = new $className(); $environmentController->odinc_url = ''; $environmentController->mail_host = ''; $environmentController->mail_port = ''; $environmentController->admin_mail = ''; $environmentController->outer_mail = ''; $environmentController->mail_protocol = ''; $environmentController->mail_username = ''; $environmentController->mail_password = ''; $environmentController->odinc_url_stud = ''; $environmentController->odinc_url_abit = ''; $environmentController->odinc_login_stud = ''; $environmentController->odinc_login_abit = ''; $environmentController->odinc_password_stud = ''; $environmentController->odinc_password_abit = ''; $environmentController->domain = $this->domain; $environmentController->portal_name = $this->portal_name; $environmentController->enable_1c_services = $this->enable_1c_services ? 'true' : 'false'; $state = []; if ($this->enable_1c_services) { $attrList = [ 'odinc_url' => 'Адрес публика 1С', 'odinc_url_stud' => 'Префикс адреса публикации кабинета для студента', 'odinc_url_abit' => 'Префикс адреса публикации кабинета для поступающего', 'odinc_login_stud' => 'Логин для кабинета студента', 'odinc_login_abit' => 'Логин для кабинета поступающего', 'odinc_password_stud' => 'Пароль от кабинета студента', 'odinc_password_abit' => 'Пароль от кабинета поступающего', ]; echo "Введите параметры для настройки подключения к 1С серверу (значение в скобках будет задано при пропуске параметра)\n"; foreach ($attrList as $attr => $alias) { $buffer = (string)readline(" {$alias} ({$this->{$attr}}): "); $buffer = trim((string)$buffer); if (!empty($buffer)) { $this->{$attr} = $buffer; } }; echo "\n"; $environmentController->odinc_url = $this->odinc_url; $environmentController->odinc_url_stud = $this->odinc_url_stud; $environmentController->odinc_url_abit = $this->odinc_url_abit; $environmentController->odinc_login_stud = $this->odinc_login_stud; $environmentController->odinc_login_abit = $this->odinc_login_abit; $environmentController->odinc_password_stud = $this->odinc_password_stud; $environmentController->odinc_password_abit = $this->odinc_password_abit; $state = $environmentController->testAllConnection(); } $messages = $environmentController->getErrorMessage($state, $this->enable_1c_services); if (!empty($messages)) { foreach ($messages as $message) { $this->printError("{$message}\n"); } return false; } $environmentController->setEnv('/..', false); echo $this->ansiFormat(".env успешно сохранён\n\n", Console::FG_GREEN); return true; } private function installEnding() { $this->printNextStepNumber(); $path = FileHelper::normalizePath("{$this->rootPath}/frontend/web/install/src/controllers/DictionaryController.php"); require_once($path); $className = 'DictionaryController'; $dictionaryController = new $className(); echo 'Завершение установки. Копирование ' . $this->ansiFormat(".env\n", Console::FG_YELLOW); $finishResult = $dictionaryController->finish(false); if ($finishResult !== true) { $this->printError("{$finishResult}\n"); return false; } echo $this->ansiFormat("Установка успешно завершена\n\n", Console::FG_GREEN); return true; } }