* @package install * @link https://www.zentao.net */ class installZen extends install { /** * 获取当前PHP版本。 * get php version. * * @access protected * @return string */ protected function getPHPVersion(): string { return PHP_VERSION; } /** * 获取tmp的目录信息。 * Get tempRoot info. * * @access protected * @return array */ protected function getTmpRoot(): array { $result['path'] = $this->app->getTmpRoot(); $result['exists'] = is_dir($result['path']); $result['writable'] = is_writable($result['path']); return $result; } /** * 获取session的存储目录信息。 * Get session save path. * * @access protected * @return array */ protected function getSessionSavePath(): array { $result['path'] = preg_replace("/\d;/", '', session_save_path()); $result['exists'] = is_dir($result['path']); $result['writable'] = is_writable($result['path']); return $result; } /** * 获取附件存储的目录信息。 * Get data root. * * @access protected * @return array */ protected function getDataRoot(): array { $result['path'] = $this->app->getAppRoot() . 'www' . DS . 'data'; $result['exists'] = is_dir($result['path']); $result['writable']= is_writable($result['path']); return $result; } /** * 检查PHP版本是否大于5.2.0。 * Check php version. * * @access protected * @return string ok|fail */ protected function checkPHPVersion(): string { return version_compare(PHP_VERSION, '5.2.0') >= 0 ? 'ok' : 'fail'; } /** * 检查是否安装pdo扩展。 * Check PDO. * * @access protected * @return string ok|fail */ protected function checkPDO(): string { return extension_loaded('pdo') ? 'ok' : 'fail'; } /** * 检查是否安装pdo_mysql扩展。 * Check PDO::MySQL * * @access protected * @return string ok|fail */ protected function checkPDOMySQL(): string { return extension_loaded('pdo_mysql') ? 'ok' : 'fail'; } /** * 检查是否安装了json扩展。 * Check json extension. * * @access protected * @return string ok|fail */ protected function checkJSON(): string { return extension_loaded('json') ? 'ok' : 'fail'; } /** * 检查是否安装了openssl扩展。 * Check openssl extension. * * @access protected * @return string ok|fail */ protected function checkOpenssl(): string { return extension_loaded('openssl') ? 'ok' : 'fail'; } /** * 检查是否安装了mbstring扩展。 * Check mbstring extension. * * @access protected * @return string ok|fail */ protected function checkMBstring(): string { return extension_loaded('mbstring') ? 'ok' : 'fail'; } /** * 检查是否安装了zlib扩展。 * Check zlib extension. * * @access protected * @return string ok|fail */ protected function checkZlib(): string { return extension_loaded('zlib') ? 'ok' : 'fail'; } /** * 检查是否安装了curl扩展。 * Check curl extension. * * @access protected * @return string ok|fail */ protected function checkCURL(): string { return extension_loaded('curl') ? 'ok' : 'fail'; } /** * 检查是否安装了filter扩展。 * Check filter extension. * * @access protected * @return string ok|fail */ protected function checkFilter(): string { return extension_loaded('filter') ? 'ok' : 'fail'; } /** * 检查是否安装了iconv扩展。 * Check iconv extension. * * @access protected * @return string ok|fail */ protected function checkIconv(): string { return extension_loaded('iconv') ? 'ok' : 'fail'; } /** * 检查tmp目录的完整性和可写性。 * Check tmpRoot. * * @access protected * @return string ok|fail */ protected function checkTmpRoot(): string { $tmpRoot = $this->app->getTmpRoot(); return is_dir($tmpRoot) && is_writable($tmpRoot) ? 'ok' : 'fail'; } /** * 检查session存储目录的完整性和可写性质。 * Check session save path. * * @access protected * @return string ok|fail */ protected function checkSessionSavePath(): string { $sessionSavePath = preg_replace("/\d;/", '', session_save_path()); if(!is_dir($sessionSavePath) || !is_writable($sessionSavePath)) return 'fail'; /* Test session path again. */ file_put_contents($sessionSavePath . '/zentaotest', 'zentao'); $sessionContent = file_get_contents($sessionSavePath . '/zentaotest'); if($sessionContent == 'zentao') { unlink($sessionSavePath . '/zentaotest'); return 'ok'; } return 'fail'; } /** * 检查附件存储目录的完整性和可写性质。 * Check the data root. * * @access protected * @return string ok|fail */ protected function checkDataRoot(): string { $dataRoot = $this->app->getAppRoot() . 'www' . DS . 'data'; return is_dir($dataRoot) && is_writable($dataRoot) ? 'ok' : 'fail'; } /** * 检查数据库配置信息的正确性。 * Check config ok or not. * * @param object $data * @access protected * @return object */ protected function checkConfig(object $data): object { $return = new stdclass(); $return->result = 'ok'; /* Connect to database. */ $this->setDBParam($data); $this->install->dbh = $this->install->connectDB(); if(strpos($data->dbName, '.') !== false) { /* 如果数据库名字带有.字符的话,则提示错误信息。 */ $return->result = 'fail'; $return->error = $this->lang->install->errorDBName; return $return; } if(!is_object($this->install->dbh)) { /* 没有成功连接数据库的话,则提示错误信息。 */ $return->result = 'fail'; $return->error = $this->lang->install->errorConnectDB . $this->install->dbh; return $return; } /* 检查数据库用户是否缺少权限。 */ $missingPrivs = $this->install->dbh->checkUserPriv(); if($missingPrivs) { $missingPrivs = $this->lang->install->errorDBUserPriv . '' . $missingPrivs . ''; return $this->send(array('result' => 'fail', 'callback' => "zui.Modal.alert({icon: 'icon-exclamation-sign', size: '600', iconClass: 'text-4xl text-warning', message: {html:'" . str_replace("'", '"', $missingPrivs) . "'}})")); } /* Get database version. */ $version = $this->install->getDatabaseVersion(); /* If database no exits, try create it. */ if(!$this->install->dbh->dbExists()) { if(!$this->install->dbh->createDB($version)) { /* 如果创建数据库失败的话,则提示错误信息。 */ $return->result = 'fail'; $return->error = $this->lang->install->errorCreateDB; return $return; } } elseif($this->install->dbh->tableExist(TABLE_ACL) && empty($data->clearDB)) { /* 如果已经存在config表,并且用户没有勾选清空旧数据库选项的话,则提示错误信息。 */ $return->result = 'fail'; $return->error = $this->lang->install->errorTableExists; return $return; } return $return; } /** * DevOps平台版将配置信息写入my.php。 * Save config file when inQuickon is true. * * @access protected * @return bool */ protected function saveConfigFile(): bool { $configRoot = $this->app->getConfigRoot(); $myConfigFile = $configRoot . 'my.php'; if(file_exists($myConfigFile) && trim(file_get_contents($myConfigFile))) return false; /* Set the session save path when the session save path is null. */ $customSession = $this->setSessionPath(); $configContent = <<installed = getEnvData('ZT_INSTALLED', true, 'bool'); \$config->debug = getEnvData('ZT_DEBUG', 0, 'int'); \$config->requestType = getEnvData('ZT_REQUEST_TYPE'); \$config->timezone = getEnvData('ZT_TIMEZONE', 'Asia/Shanghai'); \$config->db->driver = getEnvData('ZT_DB_DRIVER', 'mysql'); \$config->db->host = getEnvData('ZT_DB_HOST'); \$config->db->port = getEnvData('ZT_DB_PORT'); \$config->db->name = getEnvData('ZT_DB_NAME'); \$config->db->user = getEnvData('ZT_DB_USER'); \$config->db->encoding = getEnvData('ZT_DB_ENCODING', 'UTF8'); \$config->db->password = getEnvData('ZT_DB_PASSWORD'); \$config->db->prefix = getEnvData('ZT_DB_PREFIX'); \$config->webRoot = getWebRoot(); \$config->default->lang = getEnvData('ZT_DEFAULT_LANG', 'zh-cn'); \$hasSlaveDB = (string)getEnvData('ENABLE_DB_SLAVE'); if(\$hasSlaveDB && \$hasSlaveDB != 'false') { \$slaveDB = new stdclass(); \$slaveDB->host = getEnvData('ZT_SLAVE_DB_HOST'); \$slaveDB->port = getEnvData('ZT_SLAVE_DB_PORT'); \$slaveDB->name = getEnvData('ZT_SLAVE_DB_NAME'); \$slaveDB->user = getEnvData('ZT_SLAVE_DB_USER'); \$slaveDB->password = getEnvData('ZT_SLAVE_DB_PASSWORD'); \$slaveDB->driver = getEnvData('ZT_DB_DRIVER'); \$slaveDB->encoding = getEnvData('ZT_DB_ENCODING'); \$slaveDB->prefix = getEnvData('ZT_DB_PREFIX'); \$config->slaveDBList = array(\$slaveDB); } EOT; if($customSession) $configContent .= "\n\$config->customSession = true;"; if(is_writable($configRoot)) @file_put_contents($myConfigFile, $configContent); $this->config->installed = true; return true; } /** * 写入数据库配置信息。 * Set database params. * * @param object $data * @access private * @return bool */ private function setDBParam(object $data): bool { $this->config->db->driver = $data->dbDriver; if($this->config->inQuickon) { $this->config->db->host = getenv('ZT_MYSQL_HOST'); $this->config->db->user = getenv('ZT_MYSQL_USER'); $this->config->db->encoding = 'UTF8'; $this->config->db->password = getenv('ZT_MYSQL_PASSWORD'); $this->config->db->port = getenv('ZT_MYSQL_PORT'); } else { $this->config->db->host = $data->dbHost; $this->config->db->user = $data->dbUser; $this->config->db->encoding = $data->dbEncoding; $this->config->db->password = $data->dbPassword; $this->config->db->port = $data->dbPort; } $this->config->db->name = $data->dbName; $this->config->db->prefix = $data->dbPrefix; file_put_contents($this->install->buildDBLogFile('config'), json_encode(array('db' => $this->config->db, 'post' => $data))); return true; } /** * DevOps平台版设置session path。 * Set session save path. * * @access private * @return bool */ private function setSessionPath(): bool { $customSession = false; $checkSession = ini_get('session.save_handler') == 'files'; if($checkSession) { if(!session_save_path()) { /* Restart the session because the session save path is null when start the session last time. */ session_write_close(); $tmpRootInfo = $this->getTmpRoot(); $sessionSavePath = $tmpRootInfo['path'] . 'session'; if(!is_dir($sessionSavePath)) mkdir($sessionSavePath, 0777, true); session_save_path($sessionSavePath); $customSession = true; $sessionResult = $this->checkSessionSavePath(); if($sessionResult == 'fail') chmod($sessionSavePath, 0777); session_start(); $this->session->set('installing', true); } } $_SESSION['installing'] = true; return $customSession; } /** * 处理安装应用下拉选择的数据。 * Process application options. * * @param object $components * @param object $cloudSolution * @access protected * @return object */ protected function processComponents(object $components, object $cloudSolution): object { foreach($components->category as $key => &$item) { if($item->name === 'pms') { unset($components->category[$key]); continue; } if(in_array($item->name, array('analysis', 'artifact'))) array_unshift($item->choices, (object)array('name' => $this->lang->install->solution->skipInstall, 'version' => '')); $item->schemaChoices = array(); foreach($item->choices as $cloudApp) { $appInfo = zget($cloudSolution->apps, $cloudApp->name, array()); $item->schemaChoices[$cloudApp->name] = zget($appInfo, 'alias', $cloudApp->name); } } return $components; } }