| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617 |
- <?php
- /**
- * The model file of system 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 Jianhua Wang <wangjianhua@easycorp.ltd>
- * @package system
- * @version $Id$
- * @link https://www.zentao.net
- * @property cneModel $cne
- */
- class systemModel extends model
- {
- /**
- * 获取应用列表。
- * Get app list.
- *
- * @param int $productID
- * @param string $status
- * @param string $orderBy
- * @param object $pager
- * @access public
- * @return array
- */
- public function getList($productID, $status = 'active', $orderBy = 'id_desc', $pager = null)
- {
- if(common::isTutorialMode()) return $this->loadModel('tutorial')->getSystemList();
- return $this->dao->select('*')->from(TABLE_SYSTEM)
- ->where('deleted')->eq('0')
- ->andWhere('product')->eq($productID)
- ->beginIF($status && $status != 'all')->andWhere('status')->eq($status)->fi()
- ->orderBy($orderBy)
- ->page($pager)
- ->fetchAll('id', false);
- }
- /**
- * 获取应用键值对。
- * Get app pairs.
- *
- * @param int $productID
- * @param string $integrated
- * @param string $status
- * @access public
- * @return array
- */
- public function getPairs($productID = 0, $integrated = '', $status = '')
- {
- if(common::isTutorialMode()) return $this->loadModel('tutorial')->getSystemPairs();
- return $this->dao->select('id, name')->from(TABLE_SYSTEM)
- ->where('deleted')->eq('0')
- ->beginIF($productID)->andWhere('product')->eq($productID)->fi()
- ->beginIF($status)->andWhere('status')->eq($status)->fi()
- ->beginIF($integrated !== '')->andWhere('integrated')->eq($integrated)->fi()
- ->orderBy('id DESC')
- ->fetchPairs('id', 'name');
- }
- /**
- * 根据产品ids列表获取状态正常的非集成应用键值对。
- * @param int[] $products
- * @return array
- */
- public function getPairsByProducts($products)
- {
- $products = array_values(array_filter($products));
- return $this->dao->select('id, name')->from(TABLE_SYSTEM)
- ->where('deleted')->eq('0')
- ->beginIF(!empty($products))->andWhere('product')->in($products)->fi()
- ->andWhere('status')->eq('active')
- ->andWhere('integrated')->eq(0)
- ->orderBy('id DESC')
- ->fetchPairs('id', 'name');
- }
- /**
- * 根据ID列表获取应用。
- * Get apps by id list.
- *
- * @param array $idList
- * @access public
- * @return array
- */
- public function getByIdList($idList)
- {
- return $this->dao->select('*')->from(TABLE_SYSTEM)
- ->where('deleted')->eq('0')
- ->andWhere('id')->in($idList)
- ->fetchAll('id');
- }
- /**
- * 根据应用ID列表获取产品ID列表。
- * Get product id list by system id list.
- *
- * @param array $systemIDs
- * @return array
- */
- public function getProductListBySystemIds($systemIDs)
- {
- return $this->dao->select('t1.id,t1.name as appName,t1.product,t2.name as productName')
- ->from(TABLE_SYSTEM)->alias('t1')
- ->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id')
- ->where('t1.deleted')->eq('0')
- ->andWhere('t1.id')->in(implode(',', $systemIDs))
- ->fetchAll('id');
- }
- /**
- * 创建应用。
- * Create an app.
- *
- * @param object $formData
- * @access public
- * @return bool|int
- */
- public function create($formData)
- {
- $this->dao->insert(TABLE_SYSTEM)->data($formData)
- ->check('name', 'unique')
- ->batchCheck($this->config->system->create->requiredFields, 'notempty')
- ->autoCheck()
- ->exec();
- if(dao::isError())
- {
- if($this->app->rawModule != 'system' && !empty(dao::$errors['name']))
- {
- dao::$errors['systemName'] = dao::$errors['name'];
- unset(dao::$errors['name']);
- }
- return false;
- }
- $systemID = $this->dao->lastInsertID();
- $this->loadModel('action')->create('system', $systemID, 'created', '', '', zget($formData, 'createdBy', $this->app->user->account));
- return $systemID;
- }
- /**
- * 编辑应用。
- * Edit an app.
- *
- * @param int $id
- * @param object $formData
- * @param string $type
- * @access public
- * @return bool
- */
- public function update($id, $formData, $type = 'edit')
- {
- $oldSystem = $this->fetchByID($id);
- $change = common::createChanges($oldSystem, $formData);
- if(empty($change)) return true;
- $this->dao->update(TABLE_SYSTEM)->data($formData)
- ->check('name', 'unique', '`id` != ' . $id)
- ->autoCheck()
- ->beginIF($type == 'edit')->batchCheck($this->config->system->edit->requiredFields, 'notempty')->fi()
- ->where('id')->eq($id)
- ->exec();
- if(dao::isError()) return false;
- $actionType = $type == 'edit' ? 'edited' : $type;
- $actionID = $this->loadModel('action')->create('system', $id, $actionType);
- if($actionID) $this->action->logHistory($actionID, $change);
- return !dao::isError();
- }
- /**
- * 获取自定义的域名设置。
- * Get customized domain settings.
- *
- * @access public
- * @return object
- */
- public function getDomainSettings()
- {
- $this->loadModel('setting');
- $settings = new stdclass;
- $settings->customDomain = $this->setting->getItem('owner=system&module=common§ion=domain&key=customDomain');
- $settings->https = $this->setting->getItem('owner=system&module=common§ion=domain&key=https');
- $settings->certPem = '';
- $settings->certKey = '';
- return $settings;
- }
- /**
- * 保存自定义的域名设置。
- * Save customized domain settings.
- *
- * @param object $setting
- * @access public
- * @return void
- * @param object $settings
- */
- public function saveDomainSettings($settings)
- {
- $this->loadModel('setting');
- $this->dao->from('system')->data($settings)
- ->check('customDomain', 'notempty')
- ->checkIf($settings->https == 'true', 'certPem', 'notempty')
- ->checkIf($settings->https == 'true', 'certKey', 'notempty');
- if(dao::isError()) return;
- if(!validater::checkREG($settings->customDomain, '/^((?!-)[a-z0-9-]{1,63}(?<!-)\\.)+[a-z]{2,6}$/'))
- {
- dao::$errors[] = $this->lang->system->errors->invalidDomain;
- return;
- }
- /* Upload Certificate to CNE. */
- if($settings->https == 'true')
- {
- $cert = new stdclass;
- $cert->name = 'tls-' . str_replace('.', '-', $settings->customDomain);
- $cert->certificate_pem = $settings->certPem;
- $cert->private_key_pem = $settings->certKey;
- $certResult = $this->loadModel('cne')->uploadCert($cert);
- if($certResult->code != 200)
- {
- dao::$errors[] = $certResult->message;
- return;
- }
- }
- if(stripos($settings->customDomain, 'haogs.cn') !== false) dao::$errors[] = $this->lang->system->errors->forbiddenOriginalDomain;
- if(dao::isError()) return false;
- $expiredDomain = $this->setting->getItem('owner=system&module=common§ion=domain&key=expiredDomain');
- $expiredDomain = empty($expiredDomain ) ? array(getenv('APP_DOMAIN')) : json_decode($expiredDomain, true);
- $expiredDomain[] = zget($settings, 'customDomain', '');
- $this->setting->setItem('system.common.domain.expiredDomain', json_encode($expiredDomain));
- $this->setting->setItem('system.common.domain.customDomain', zget($settings, 'customDomain', ''));
- $this->setting->setItem('system.common.domain.https', zget($settings, 'https', 'false'));
- $this->loadModel('instance')->updateInstancesDomain();
- $this->updateMinioDomain();
- }
- /**
- * 更新域名。
- * Update minio domain.
- *
- * @access public
- * @return void
- */
- public function updateMinioDomain()
- {
- $this->loadModel('cne');
- $sysDomain = $this->cne->sysDomain();
- $minioInstance = new stdclass;
- $minioInstance->k8name = 'cne-operator';
- $minioInstance->chart = 'cne-operator';
- $minioInstance->spaceData = new stdclass;
- $minioInstance->spaceData->k8space = $this->config->k8space;
- $settings = new stdclass;
- $settings->settings_map = new stdclass;
- $settings->settings_map->minio = new stdclass;
- $settings->settings_map->minio->ingress = new stdclass;
- $settings->settings_map->minio->ingress->enabled = true;
- $settings->settings_map->minio->ingress->host = 's3.' . $sysDomain;
- $this->cne->updateConfig($minioInstance, $settings);
- }
- /**
- * 创建备份。
- * Backup the instance.
- *
- * @param object $instance
- * @param string $mode |manual|system|upgrade|downgrade
- * @return array
- */
- public function backup($instance, $mode = '')
- {
- $this->loadModel('cne');
- if(empty($instance)) $instance = $this->config->instance->zentaopaas;
- if(empty($_SESSION['fromCron'])) $this->setMaintenance('backup');
- $rawResult = $this->cne->backup($instance, $this->app->user->account, $mode);
- if(!empty($rawResult->code) && $rawResult->code == 200)
- {
- return array('result' => 'success', 'message' => $rawResult->message, 'data' => $rawResult->data);
- }
- else
- {
- $this->unsetMaintenance('backup');
- return array('result' => 'fail', 'message' => $rawResult->message);
- }
- }
- /**
- * 获取备份状态。
- * Get backup status.
- *
- * @param object $instance
- * @param string $backup
- * @return array
- * @param string $backupName
- */
- public function getBackupStatus($instance, $backupName)
- {
- $this->loadModel('cne');
- $rawResult = $this->cne->getBackupStatus($instance, $backupName);
- if(!empty($rawResult->code) && $rawResult->code == 200)
- {
- return array('result' => 'success', 'message' => $rawResult->message, 'data' => $rawResult->data);
- }
- else
- {
- return array('result' => 'fail', 'message' => $rawResult->message);
- }
- }
- /**
- * 获取备份列表。
- * Get backup list.
- *
- * @param object $instance
- * @return array
- */
- public function getBackupList($instance)
- {
- $this->loadModel('cne');
- $rawResult = $this->cne->getBackupList($instance);
- if(!empty($rawResult->code) && $rawResult->code == 200)
- {
- return array('result' => 'success', 'message' => $rawResult->message, 'data' => $rawResult->data);
- }
- else
- {
- return array('result' => 'fail', 'message' => $rawResult->message);
- }
- }
- /**
- * 恢复一个备份。
- * Restore the backup.
- *
- * @param object $instance
- * @param string $backupName
- * @param string $account
- * @return array
- */
- public function restore($instance, $backupName, $account = '')
- {
- $this->loadModel('cne');
- $rawResult = $this->cne->restore($instance, $backupName, $account);
- if(!empty($rawResult->code) && $rawResult->code == 200)
- {
- return array('result' => 'success', 'message' => $rawResult->message, 'data' => $rawResult->data);
- }
- else
- {
- return array('result' => 'fail', 'message' => $rawResult->message);
- }
- }
- /**
- * 删除一个备份。
- * Delete the backup.
- *
- * @param object $instance
- * @param string $backupName
- * @return array
- */
- public function deleteBackup($instance, $backupName)
- {
- $this->loadModel('cne');
- $rawResult = $this->cne->deleteBackup($instance, $backupName);
- if(!empty($rawResult->code) && $rawResult->code == 200)
- {
- return array('result' => 'success', 'message' => $rawResult->message, 'data' => $rawResult->data);
- }
- else
- {
- return array('result' => 'fail', 'message' => $rawResult->message);
- }
- }
- /**
- * 设置系统维护信息。
- * Set maintenance message.
- *
- * @param string $action backup|restore|upgrade
- * @return bool
- */
- public function setMaintenance($action)
- {
- if(empty($action) || !in_array($action, array_keys($this->lang->system->maintenance->reason))) return false;
- $maintenance = new stdclass();
- $maintenance->action = $action;
- $maintenance->reason = zget($this->lang->system->maintenance->reason, $action, $this->lang->unknown);
- return $this->loadModel('setting')->setItem('system.system.maintenance', json_encode($maintenance));
- }
- /**
- * 复原系统维护信息。
- * Unset Maintenance message.
- *
- * @return void
- */
- public function unsetMaintenance()
- {
- $maintenance = $this->loadModel('setting')->getItem('owner=system&module=system&key=maintenance');
- if(empty($maintenance)) return;
- $this->setting->deleteItems('owner=system&module=system&key=maintenance');
- }
- /**
- * 从云API服务器获取最新的发布版本。
- * Get the latest release from cloud API server.
- *
- * @return object
- */
- public function getLatestRelease()
- {
- $cloudApiHost = getenv('CLOUD_API_HOST');
- if(empty($cloudApiHost)) $cloudApiHost = $this->config->cloud->api->host;
- $currentRelease = array(
- 'name' => 'zentaopaas',
- 'channel' => getenv('CLOUD_DEFAULT_CHANNEL') ?: 'stable',
- 'version' => getenv('APP_VERSION')
- );
- $ztVersion = $this->loadModel('upgrade')->getOpenVersion(str_replace('.', '_', $this->config->version));
- $currentRelease['zentao_version'] = str_replace('_', '.', $ztVersion);
- $query = http_build_query($currentRelease);
- $response = common::http($cloudApiHost . '/api/market/app/version/latest?' . $query);
- if($response)
- {
- $response =json_decode($response);
- if($response && $response->code == 200) return $response->data;
- }
- return false;
- }
- /**
- * 检查当前版本是否可升级。
- * Check if the current release is upgradeable.
- *
- * @return bool
- */
- public function isUpgradeable()
- {
- $latestRelease = $this->getLatestRelease();
- if(!$latestRelease) return false;
- $latestVersion = false;
- if(isset($latestRelease->products->{$this->config->edition}))
- $latestVersion = $latestRelease->products->{$this->config->edition};
- else
- $latestVersion = $latestRelease->products->oss;
- if(version_compare($latestVersion, $this->config->version, 'lt')) return false;
- $chartVersion = getenv('CHART_VERSION');
- if(empty($chartVersion)) return false;
- if(version_compare($latestRelease->version, $chartVersion, 'gt')) return true;
- return false;
- }
- /**
- * 检查按钮是否可用。
- * Check if the button is clickable.
- *
- * @param object $system
- * @param string $action
- * @access public
- * @return bool
- */
- public function isClickable($system, $action)
- {
- if($action == 'active') return $system->status == 'inactive';
- if($action == 'inactive') return $system->status == 'active';
- return true;
- }
- /**
- * 更新应用的最新发布信息。
- * Update the latest release of the app.
- *
- * @param int $systemID
- * @param int $releaseID
- * @param string $releasedDate
- * @access public
- * @return bool
- */
- public function setSystemRelease($systemID, $releaseID, $releasedDate = '')
- {
- $system = $this->fetchByID($systemID);
- if(!$system) return false;
- if(empty($releasedDate))
- {
- if($releaseID != $system->latestRelease) return false;
- $release = $this->dao->select('id,createdDate')->from(TABLE_RELEASE)->where('deleted')->eq(0)->andWhere('system')->eq($systemID)->orderBy('id DESC')->fetch();
- $releaseID = $release ? $release->id : 0;
- $releasedDate = $release ? $release->createdDate : null;
- }
- $this->dao->update(TABLE_SYSTEM)->set('latestDate')->eq($releasedDate)->set('latestRelease')->eq($releaseID)->where('id')->eq($systemID)->exec();
- return !dao::isError();
- }
- /**
- * 根据ID获取发布信息。
- * Get release information by ID.
- *
- * @param int $systemID
- * @access public
- * @return array
- */
- public function getReleasesByID($systemID)
- {
- return $this->dao->select('*')->from(TABLE_RELEASE)
- ->where('system')->eq($systemID)
- ->andWhere('deleted')->eq(0)
- ->fetchAll('id');
- }
- /**
- * 根据ID获取构建信息。
- * Get build information by ID.
- *
- * @param int $systemID
- * @access public
- * @return array
- */
- public function getBuildsByID($systemID)
- {
- return $this->dao->select('*')->from(TABLE_BUILD)
- ->where('system')->eq($systemID)
- ->andWhere('deleted')->eq(0)
- ->fetchAll('id');
- }
- /**
- * 初始化应用。
- * Initialize application.
- *
- * @access public
- * @return bool
- */
- public function initSystem()
- {
- $productPairs = $this->dao->select('*')->from(TABLE_PRODUCT)->where('deleted')->eq('0')->fetchPairs('id', 'name');
- $releasePairs = $this->dao->select('id,product,date,createdDate')->from(TABLE_RELEASE)->where('deleted')->eq('0')->fetchAll('product');
- $systemPairs = array();
- $systemNames = array();
- $systemList = $this->dao->select('id,product,name')->from(TABLE_SYSTEM)->where('deleted')->eq('0')->fetchAll();
- foreach($systemList as $system)
- {
- $system->name = strtolower($system->name);
- $systemNames[$system->name] = $system->id;
- $systemPairs[$system->product] = $system->id;
- }
- $system = new stdclass();
- $system->createdDate = helper::now();
- $system->createdBy = 'system';
- foreach($productPairs as $productID => $productName)
- {
- $systemID = zget($systemPairs, $productID, 0);
- if(!$systemID)
- {
- if(isset($systemNames[strtolower($productName)])) $productName .= '-1';
- $system->name = $productName;
- $system->product = $productID;
- $system->latestDate = null;
- $system->latestRelease = 0;
- if(isset($releasePairs[$productID]))
- {
- $system->latestDate = $releasePairs[$productID]->createdDate ? $releasePairs[$productID]->createdDate : "{$releasePairs[$productID]->date} 00:00:00";
- $system->latestRelease = $releasePairs[$productID]->id;
- }
- $systemID = $this->create($system);
- if(dao::isError()) continue;
- }
- $this->dao->update(TABLE_BUILD)->set('system')->eq($systemID)->where('product')->eq($productID)->andWhere('system')->eq(0)->exec();
- $this->dao->update(TABLE_RELEASE)->set('system')->eq($systemID)->where('product')->eq($productID)->andWhere('system')->eq(0)->exec();
- }
- if(!dao::isError()) $this->dao->delete()->from(TABLE_CRON)->where('command')->eq('moduleName=system&methodName=initSystem')->exec();
- return dao::isError();
- }
- }
|