| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- <?php
- /**
- * The model file of install module of ZenTaoPMS.
- *
- * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
- * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
- * @author Chunsheng Wang <chunsheng@cnezsoft.com>
- * @package install
- * @version $Id: model.php 5006 2013-07-03 08:52:21Z wyd621@gmail.com $
- * @link https://www.zentao.net
- */
- ?>
- <?php
- class installModel extends model
- {
- /**
- * 数据库版本。
- * Database version.
- *
- * @var string
- * access private
- */
- private $dbVersion = '';
- /**
- * 数据库字符集。
- * Database charset.
- *
- * @var array
- * access private
- */
- private $dbCharset = [];
- /**
- * 获取对应语言项的禅道授权信息。
- * Get license according the client lang.
- *
- * @access public
- * @return string
- */
- public function getLicense()
- {
- $clientLang = $this->app->getClientLang();
- $licenseCN = file_get_contents($this->app->getBasePath() . 'LICENSE.CN');
- $licenseEN = file_get_contents($this->app->getBasePath() . 'LICENSE.EN');
- if($clientLang == 'zh-cn' || $clientLang == 'zh-tw') return $licenseCN . $licenseEN;
- return $licenseEN . $licenseCN;
- }
- /**
- * 获取数据库版本。
- * Get database version.
- *
- * @access public
- * @return string
- */
- public function getDatabaseVersion()
- {
- if(empty($this->dbh)) $this->dbh = $this->connectDB();
- if($this->config->db->driver == 'dm') return 8;
- $sql = "SELECT VERSION() AS version";
- $result = $this->dbh->query($sql)->fetch();
- return substr($result->version, 0, 3);
- }
- /**
- * 获取php.ini里的配置信息。
- * Get the php.ini info.
- *
- * @access public
- * @return string
- */
- public function getIniInfo()
- {
- $iniInfo = '';
- ob_start();
- phpinfo(1);
- $lines = explode("\n", strip_tags(ob_get_contents()));
- ob_end_clean();
- foreach($lines as $line) if(strpos($line, 'ini') !== false) $iniInfo .= $line . "\n";
- return $iniInfo;
- }
- /**
- * 连接数据库。
- * Connect to database.
- *
- * @access public
- * @return object|string
- */
- public function connectDB()
- {
- try
- {
- return new dbh($this->config->db, false);
- }
- catch (PDOException $exception)
- {
- return $exception->getMessage();
- }
- }
- /**
- * 创建数据库表。
- * Create tables.
- *
- * @param bool $saveLog
- * @param int $isClearDB
- * @access public
- * @return bool
- */
- public function createTable($saveLog = false, $isClearDB = 0)
- {
- $this->dbh = $this->connectDB();
- /* Add exception handling to ensure that all SQL is executed successfully. */
- try
- {
- $this->dbh->useDB($this->config->db->name);
- $dbFile = $this->app->getAppRoot() . 'db' . DS . 'zentao.sql';
- $tables = explode(';', file_get_contents($dbFile));
- foreach($tables as $table)
- {
- $table = trim($table);
- if(empty($table)) continue;
- if(strpos($table, 'DROP TABLE') !== false && $isClearDB) $table = trim(str_replace('--', '', $table));
- $table = $this->replaceContantsInSQL($table);
- $table = $this->appendMySQLTableOptions($table);
- /* Skip sql that is note. */
- if(strpos($table, '--') === 0) continue;
- if($saveLog) file_put_contents($this->buildDBLogFile('progress'), $table . "\n", FILE_APPEND);
- $this->dbh->exec($table);
- }
- }
- catch (PDOException $exception)
- {
- $message = $exception->getMessage();
- if($saveLog) file_put_contents($this->buildDBLogFile('error'), $message);
- echo nl2br($message);
- helper::end();
- }
- return true;
- }
- /**
- * 替换SQL语句中的常量。
- * Replace contants in SQL.
- *
- * @param string $sql
- * @access public
- * @return string
- */
- public function replaceContantsInSQL($sql)
- {
- $prefix = in_array($this->config->db->driver, $this->config->pgsqlDriverList) ? 'public' : $this->config->db->name;
- $sql = str_replace('`zt_', $prefix . '.`zt_', $sql);
- $sql = str_replace('`ztv_', $prefix . '.`ztv_', $sql);
- $sql = str_replace('zt_', $this->config->db->prefix, $sql);
- $sql = str_replace('__DATABASE__', $this->config->db->name, $sql);
- return $sql;
- }
- /**
- * 为MySQL的建表语句追加选项。
- * Append MySQL table options.
- *
- * @param string $sql
- * @access public
- * @return string
- */
- public function appendMySQLTableOptions($sql)
- {
- if(strpos($sql, 'CREATE TABLE') !== 0) return $sql;
- $sql = substr($sql, 0, strrpos($sql, ')') + 1);
- if($this->config->db->driver != 'mysql') return $sql;
- if(empty($this->dbVersion)) $this->dbVersion = $this->getDatabaseVersion();
- if(empty($this->dbCharset)) $this->dbCharset = $this->dbh->getDatabaseCharsetAndCollation();
- $sql .= ' ENGINE=InnoDB';
- if(version_compare($this->dbVersion, '4.1', '>')) $sql .= " DEFAULT CHARSET={$this->dbCharset['charset']} COLLATE={$this->dbCharset['collation']}";
- if(version_compare($this->dbVersion, '5.6', '<') && stripos($sql, 'FULLTEXT') !== false && stripos($sql, 'InnoDB') !== false) $sql = str_ireplace('ENGINE=InnoDB', 'ENGINE=MyISAM', $sql);
- return $sql;
- }
- /**
- * 执行安装前的SQL语句。
- * Exec pre install SQL.
- *
- * @access public
- * @return bool
- */
- public function execPreInstallSQL()
- {
- $this->dbh->useDB($this->config->db->name);
- $tables = array();
- $dbPath = $this->app->getAppRoot() . 'db' . DS;
- if(in_array($this->config->db->driver, $this->config->pgsqlDriverList))
- {
- $dbFile = $dbPath . 'pgsql_function.sql';
- $tables = explode('--', file_get_contents($dbFile));
- }
- elseif($this->config->db->driver == 'dm')
- {
- $dbFile = $dbPath . 'dm_function.sql';
- $tables = explode('--', file_get_contents($dbFile));
- }
- foreach($tables as $table)
- {
- $prefix = in_array($this->config->db->driver, $this->config->pgsqlDriverList) ? 'public' : $this->config->db->name;
- $table = trim($table);
- $table = str_replace('`zt_', $prefix . '.`zt_', $table);
- $table = str_replace('`ztv_', $prefix . '.`ztv_', $table);
- if($table) $this->dbh->exec($table);
- }
- return true;
- }
- /**
- * 执行安装后的SQL语句。
- * Exec post install SQL.
- *
- * @access public
- * @return bool
- */
- public function execPostInstallSQL()
- {
- $tables = array();
- $dbPath = $this->app->getAppRoot() . 'db' . DS;
- if($this->config->db->driver == 'dm')
- {
- $dbFile = $dbPath . 'dm.sql';
- $tables = explode(';', file_get_contents($dbFile));
- }
- elseif(in_array($this->config->db->driver, $this->config->pgsqlDriverList))
- {
- $dbFile = $dbPath . 'pgsql.sql';
- $tables = explode('--', file_get_contents($dbFile));
- }
- foreach($tables as $table)
- {
- $prefix = in_array($this->config->db->driver, $this->config->pgsqlDriverList) ? 'public' : $this->config->db->name;
- $table = trim($table);
- $table = str_replace('`zt_', $prefix . '.`zt_', $table);
- $table = str_replace('`ztv_', $prefix . '.`ztv_', $table);
- if($table) $this->dbh->exec($table);
- }
- return true;
- }
- /**
- * 获取数据库日志存储路径。
- * Build DB log file.
- *
- * @param string $type config|error|success|progress
- * @access public
- * @return string
- */
- public function buildDBLogFile($type)
- {
- $cacheRoot = $this->app->getCacheRoot();
- if(!file_exists($cacheRoot)) mkdir($cacheRoot, 0777, true);
- if($type == 'config') return $cacheRoot . 'db.cnf';
- if($type == 'error') return $cacheRoot . 'dberror.log';
- if($type == 'success') return $cacheRoot . 'dbsuccess.log';
- if($type == 'progress') return $cacheRoot . 'dbprogress.log';
- }
- /**
- * 创建公司并设置管理员。
- * Create a comapny, set admin.
- *
- * @param object $data
- * @access public
- * @return bool
- */
- public function grantPriv($data)
- {
- /* Check required. */
- if(empty($data->company)) dao::$errors['company'][] = sprintf($this->lang->error->notempty, $this->lang->install->company);
- if(empty($data->account)) dao::$errors['account'][] = sprintf($this->lang->error->notempty, $this->lang->install->account);
- if(empty($data->password)) dao::$errors['password'][] = sprintf($this->lang->error->notempty, $this->lang->install->password);
- if(!validater::checkAccount($data->account)) dao::$errors['account'][] = sprintf($this->lang->error->account, $this->lang->user->account);
- if(dao::isError()) return false;
- $this->loadModel('user');
- $this->app->loadConfig('admin');
- /* Check password. */
- if(!validater::checkReg($data->password, '|(.){6,}|')) dao::$errors['password'][] = $this->lang->error->passwordrule;
- if($this->user->computePasswordStrength($data->password) < 1) dao::$errors['password'][] = $this->lang->user->placeholder->passwordStrengthCheck[1];
- if(strpos(",{$this->config->safe->weak},", ",{$data->password},") !== false) dao::$errors['password'][] = sprintf($this->lang->user->errorWeak, $this->config->safe->weak);
- if(dao::isError()) return false;
- /* Insert a company. */
- $company = new stdclass();
- $company->name = $data->company;
- $company->admins = ",{$data->account},";
- $this->dao->insert(TABLE_COMPANY)->data($company)->autoCheck()->exec();
- if(dao::isError()) return false;
- /* Set admin. */
- $visions = $this->config->edition == 'ipd' ? 'or,rnd,lite' : 'rnd,lite';
- $admin = new stdclass();
- $admin->account = $data->account;
- $admin->realname = $data->account;
- $admin->password = md5($data->password);
- $admin->gender = 'f';
- $admin->visions = $visions;
- $this->dao->insert(TABLE_USER)->data($admin)->exec();
- return !dao::isError();
- }
- /**
- * 根据当前语言更新数据库中部分数据。
- * Update language for group and cron.
- *
- * @access public
- * @return bool
- */
- public function updateLang()
- {
- /* Update group name and desc on dafault lang. */
- $groups = $this->dao->select('*')->from(TABLE_GROUP)->orderBy('id')->fetchAll();
- foreach($groups as $group)
- {
- $data = zget($this->lang->install->groupList, $group->name, '');
- if($data) $this->dao->update(TABLE_GROUP)->data($data)->where('id')->eq($group->id)->exec();
- }
- /* Update cron remark by lang. */
- foreach($this->lang->install->cronList as $command => $remark)
- {
- $this->dao->update(TABLE_CRON)->set('remark')->eq($remark)->where('command')->eq($command)->exec();
- }
- foreach($this->lang->install->langList as $langInfo)
- {
- $this->dao->update(TABLE_LANG)->set('value')->eq($langInfo['value'])->where('module')->eq($langInfo['module'])->andWhere('`key`')->eq($langInfo['key'])->exec();
- }
- /* Update lang,stage by lang. */
- $this->app->loadLang('stage');
- foreach($this->lang->stage->typeList as $key => $value)
- {
- $this->dao->update(TABLE_LANG)->set('value')->eq($value)->where('`key`')->eq($key)->exec();
- $this->dao->update(TABLE_STAGE)->set('name')->eq($value)->where('`type`')->eq($key)->exec();
- }
- if($this->config->edition != 'open') $this->updateWorkflowLang();
- if($this->config->edition == 'max' || $this->config->edition == 'ipd') $this->updatePaidVersionLang();
- return true;
- }
- /**
- * 根据当前语言更新工作流表的数据。
- * Update language for workflow.
- *
- * @access private
- * @return bool
- */
- private function updateWorkflowLang()
- {
- /* Update flowdatasource by lang. */
- foreach($this->lang->install->workflowdatasource as $id => $name)
- {
- $this->dao->update(TABLE_WORKFLOWDATASOURCE)->set('name')->eq($name)->where('id')->eq($id)->exec();
- }
- /* Update workflowrule by lang. */
- foreach($this->lang->install->workflowrule as $id => $name)
- {
- $this->dao->update(TABLE_WORKFLOWRULE)->set('name')->eq($name)->where('id')->eq($id)->exec();
- }
- return true;
- }
- /**
- * 根据当前语言更新付费版本表的数据。
- * Update language for paid table.
- *
- * @access private
- * @return true
- */
- private function updatePaidVersionLang()
- {
- /* Update process by lang. */
- foreach($this->lang->install->processList as $id => $name)
- {
- $this->dao->update(TABLE_PROCESS)->set('name')->eq($name)->where('id')->eq($id)->exec();
- }
- foreach($this->lang->install->activity as $id => $name)
- {
- $this->dao->update(TABLE_ACTIVITY)->set('name')->eq($name)->where('id')->eq($id)->exec();
- }
- foreach($this->lang->install->zoutput as $id => $name)
- {
- $this->dao->update(TABLE_ZOUTPUT)->set('name')->eq($name)->where('id')->eq($id)->exec();
- }
- /* Update basicmeas by lang. */
- foreach($this->lang->install->basicmeasList as $id => $basic)
- {
- $this->dao->update(TABLE_BASICMEAS)->set('name')->eq($basic['name'])->set('unit')->eq($basic['unit'])->set('definition')->eq($basic['definition'])->where('id')->eq($id)->exec();
- }
- return true;
- }
- /**
- * 导入测试数据。
- * Import demo data.
- *
- * @access public
- * @return bool
- */
- public function importDemoData()
- {
- $demoDataFile = $this->app->clientLang == 'en' ? 'endemo.sql' : 'demo.sql';
- $demoDataFile = $this->app->getAppRoot() . 'db' . DS . $demoDataFile;
- $insertTables = explode(";\n", file_get_contents($demoDataFile));
- foreach($insertTables as $table)
- {
- $table = trim($table);
- if(empty($table)) continue;
- $prefix = in_array($this->config->db->driver, $this->config->pgsqlDriverList) ? 'public' : $this->config->db->name;
- $table = str_replace('`zt_', $prefix . '.`zt_', $table);
- $table = str_replace('zt_', $this->config->db->prefix, $table);
- if(!$this->dbh->query($table)) return false;
- /* Make the deleted user of demo data undeleted.*/
- if($this->config->edition == 'open') $this->dao->update(TABLE_USER)->set('deleted')->eq('0')->where('deleted')->eq('1')->exec();
- }
- $config = new stdclass();
- $config->module = 'common';
- $config->owner = 'system';
- $config->section = 'global';
- $config->key = 'showDemoUsers';
- $config->value = '1';
- $config->vision = '';
- $this->dao->replace(TABLE_CONFIG)->data($config)->exec();
- return true;
- }
- /**
- * 导入BI内置数据。
- * Import BI data.
- *
- * @access public
- * @return bool
- */
- public function importBIData()
- {
- $this->loadModel('bi');
- /* Prepare built-in sqls of bi. */
- $insertTables = array();
- if(in_array($this->config->db->driver, $this->config->mysqlDriverList) || in_array($this->config->db->driver, $this->config->pgsqlDriverList))
- {
- $chartSQLs = $this->bi->prepareBuiltinChartSQL();
- $pivotSQLs = $this->bi->prepareBuiltinPivotSQL();
- $insertTables = array_merge($insertTables, $chartSQLs, $pivotSQLs);
- }
- $metricSQLs = $this->bi->prepareBuiltinMetricSQL();
- $screenSQLs = $this->bi->prepareBuiltinScreenSQL();
- $insertTables = array_merge($insertTables, $metricSQLs, $screenSQLs);
- try
- {
- foreach($insertTables as $table)
- {
- $table = trim($table);
- if(empty($table)) continue;
- $table = str_replace('zt_', $this->config->db->prefix, $table);
- if(!$this->dbh->query($table)) return false;
- }
- }
- catch(Error $e)
- {
- a($e->getMessage());
- die;
- }
- return true;
- }
- /**
- * 开启缓存。
- * Enable cache.
- *
- * @access public
- * @return bool
- */
- public function enableCache()
- {
- if(!helper::isAPCuEnabled()) return false;
- $cache = new stdclass();
- $cache->enable = true;
- $cache->driver = 'apcu';
- $cache->scope = 'shared';
- $cache->namespace = $this->config->db->name;
- $this->loadModel('setting')->setItems('system.common.cache', $cache);
- if(dao::isError()) return false;
- $this->mao->clearCache();
- return true;
- }
- /**
- * 更新数据库所有序列。
- * Update Database sequence.
- *
- * @access public
- * @return bool
- */
- public function updateDbSeq()
- {
- if(in_array($this->config->db->driver, $this->config->pgsqlDriverList))
- {
- $this->dao->exec('SELECT update_tables_seq()');
- }
- }
- }
|