diff --git a/framework/base/control.class.php b/framework/base/control.class.php index 0c887bfd3d..8a5211adb2 100644 --- a/framework/base/control.class.php +++ b/framework/base/control.class.php @@ -445,44 +445,114 @@ class baseControl */ public function getCSS($moduleName, $methodName) { - $moduleName = strtolower(trim($moduleName)); - $methodName = strtolower(trim($methodName)); + $moduleName = strtolower(trim($moduleName)); + $methodName = strtolower(trim($methodName)); - $modulePath = $this->app->getModulePath($this->appName, $moduleName); - $cssExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'css') ; + $modulePath = $this->app->getModulePath($this->appName, $moduleName); + $cssExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'css') ; - $css = ''; - $mainCssFile = $modulePath . 'css' . DS . $this->devicePrefix . 'common.css'; - $methodCssFile = $modulePath . 'css' . DS . $this->devicePrefix . $methodName . '.css'; - if(file_exists($mainCssFile)) $css .= file_get_contents($mainCssFile); - if(is_file($methodCssFile)) $css .= file_get_contents($methodCssFile); + $clientLang = $this->app->getClientLang(); + $notCNLang = strpos('|zh-cn|zh-tw|', "|{$clientLang}|") === false; + + $css = ''; + $devicePrefix = $this->devicePrefix; + $mainCssPath = $modulePath . 'css' . DS; + + /* Common css file. like module/story/css/common.css. */ + $mainCssFile = $mainCssPath . $devicePrefix . 'common.css'; + if(is_file($mainCssFile)) $css .= file_get_contents($mainCssFile); + + /* Common css file with lang. like module/story/css/common.en.css. */ + $mainCssLangFile = $mainCssPath . $devicePrefix . "common.{$clientLang}.css"; + if(!file_exists($mainCssLangFile) and $notCNLang) $mainCssLangFile = $mainCssPath . $devicePrefix . "common.en.css"; + if(is_file($mainCssLangFile)) $css .= file_get_contents($mainCssLangFile); + + /* Method css file. like module/story/css/create.css. */ + $methodCssFile = $mainCssPath . $devicePrefix . $methodName . '.css'; + if(is_file($methodCssFile)) $css .= file_get_contents($methodCssFile); + + /* Method css file with lang. like module/story/css/create.en.css. */ + $methodCssLangFile = $mainCssPath . $devicePrefix . "{$methodName}.{$clientLang}.css"; + if(!file_exists($methodCssLangFile) and $notCNLang) $methodCssLangFile = $mainCssPath . $devicePrefix . "{$methodName}.en.css"; + if(is_file($methodCssLangFile)) $css .= file_get_contents($methodCssLangFile); if(!empty($cssExtPath)) { $cssMethodExt = $cssExtPath['common'] . $methodName . DS; $cssCommonExt = $cssExtPath['common'] . 'common' . DS; - $cssExtFiles = glob($cssCommonExt . $this->devicePrefix . '*.css'); - if(!empty($cssExtFiles) and is_array($cssExtFiles)) foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile); + $cssExtFiles = glob($cssCommonExt . $devicePrefix . '*.css'); + if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); - $cssExtFiles = glob($cssMethodExt . $this->devicePrefix . '*.css'); - if(!empty($cssExtFiles) and is_array($cssExtFiles)) foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile); + $cssExtFiles = glob($cssMethodExt . $devicePrefix . '*.css'); + if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); if(!empty($cssExtPath['site'])) { $cssMethodExt = $cssExtPath['site'] . $methodName . DS; $cssCommonExt = $cssExtPath['site'] . 'common' . DS; - $cssExtFiles = glob($cssCommonExt . $this->devicePrefix . '*.css'); - if(!empty($cssExtFiles) and is_array($cssExtFiles)) foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile); + $cssExtFiles = glob($cssCommonExt . $devicePrefix . '*.css'); + if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); - $cssExtFiles = glob($cssMethodExt . $this->devicePrefix . '*.css'); - if(!empty($cssExtFiles) and is_array($cssExtFiles)) foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile); + $cssExtFiles = glob($cssMethodExt . $devicePrefix . '*.css'); + if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); } } return $css; } + /** + * Get extension css and extension css with lang. + * + * @param array $files + * @access public + * @return string + */ + public function getExtCSS($files) + { + $clientLang = $this->app->getClientLang(); + $notCNLang = strpos('|zh-cn|zh-tw|', "|{$clientLang}|") === false; + + $filePairs = array(); + foreach($files as $cssFile) + { + $fileName = basename($cssFile); + $filePairs[$fileName] = $cssFile; + } + + $css = ''; + $usedCodes = array(); + foreach($filePairs as $fileName => $cssFile) + { + if(preg_match('/^\w+\.css$/', $fileName)) + { + /* Method extension css file. like module/story/ext/css/create/effort.css. */ + $css .= file_get_contents($cssFile); + list($code) = explode('.', $fileName); + } + else + { + list($code) = explode('.', $fileName); + if(isset($usedCodes[$code])) continue; + } + + + /* Method extension css file. like module/story/ext/css/create/effort.zh-cn.css. */ + if(isset($filePairs["{$code}.{$clientLang}.css"])) + { + $css .= file_get_contents($filePairs["{$code}.{$clientLang}.css"]); + } + elseif($notCNLang and isset($filePairs["{$code}.en.css"])) + { + $css .= file_get_contents($filePairs["{$code}.en.css"]); + } + $usedCodes[$code] = $code; + } + + return $css; + } + /** * 获取适用于当前方法的js:该模块公用的js + 当前方法的js + 扩展的js。 * Get js codes applied to current method: module common js + method js + extension js. @@ -739,8 +809,11 @@ class baseControl * Load the control file. */ if(!is_file($file2Included)) $this->app->triggerError("The control file $file2Included not found", __FILE__, __LINE__, $exit = true); - chdir(dirname($file2Included)); - if(!class_exists($moduleName)) helper::import($file2Included); + if(!class_exists($moduleName)) + { + chdir(dirname($file2Included)); + helper::import($file2Included); + } /** * 设置调用的类名。 diff --git a/framework/control.class.php b/framework/control.class.php index 385fdee3b1..b98973b91f 100644 --- a/framework/control.class.php +++ b/framework/control.class.php @@ -21,10 +21,10 @@ include dirname(__FILE__) . '/base/control.class.php'; class control extends baseControl { /** - * 加载指定模块的model文件。 - * Load the model file of one module. - * - * Extension: set appName as empty. + * 企业版部分功能是从然之合并过来的。然之代码中调用loadModel方法时传递了一个非空的appName,在禅道中会导致错误。 + * 调用父类的loadModel方法来避免这个错误。 + * Some codes merged from ranzhi called the function loadModel with a non-empty appName which causes an error in zentao. + * Call the parent function with empty appName to avoid this error. * * @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name. * @param string $appName The app name, if empty, use current app's name. @@ -33,52 +33,7 @@ class control extends baseControl */ public function loadModel($moduleName = '', $appName = '') { - $appName = ''; - - if(empty($moduleName)) $moduleName = $this->moduleName; - if(empty($appName)) $appName = $this->appName; - - global $loadedModels; - if(isset($loadedModels[$appName][$moduleName])) - { - $this->$moduleName = $loadedModels[$appName][$moduleName]; - $this->dao = $this->$moduleName->dao; - return $this->$moduleName; - } - - $modelFile = $this->app->setModelFile($moduleName, $appName); - - /** - * 如果没有model文件,尝试加载config配置信息。 - * If no model file, try load config. - */ - if(!helper::import($modelFile)) - { - $this->app->loadModuleConfig($moduleName, $appName); - $this->app->loadLang($moduleName, $appName); - $this->dao = new dao(); - return false; - } - - /** - * 如果没有扩展文件,model类名是$moduleName + 'model',如果有扩展,还需要增加ext前缀。 - * If no extension file, model class name is $moduleName + 'model', else with 'ext' as the prefix. - */ - $modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model'; - if(!class_exists($modelClass)) - { - $modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model'; - if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true); - } - - /** - * 初始化model对象,在control对象中可以通过$this->$moduleName来引用。同时将dao对象赋为control对象的成员变量,方便引用。 - * Init the model object thus you can try $this->$moduleName to access it. Also assign the $dao object as a member of control object. - */ - $loadedModels[$appName][$moduleName] = new $modelClass($appName); - $this->$moduleName = $loadedModels[$appName][$moduleName]; - $this->dao = $this->$moduleName->dao; - return $this->$moduleName; + return parent::loadModel($moduleName); } /** @@ -198,7 +153,7 @@ class control extends baseControl /** * Execute hooks of a method. * - * @param int $objectID + * @param int $objectID The id of an object. The object maybe a bug | build | feedback | product | productplan | project | release | story | task | testcase | testsuite | testtask. * @access public * @return void */ @@ -214,7 +169,7 @@ class control extends baseControl /** * Build operate menu of a method. * - * @param object $object product|project|productplan|release|build|story|task|bug|testtask|testcase|testsuite + * @param object $object product|project|productplan|release|build|story|task|bug|testtask|testcase|testsuite * @param string $displayOn view|browse * @access public * @return void @@ -230,9 +185,9 @@ class control extends baseControl /** * Print extend fields. * - * @param object $object - * @param string $type - * @param string $extras + * @param object $object bug | build | feedback | product | productplan | project | release | story | task | testcase | testsuite | testtask + * @param string $type table | div + * @param string $extras columns=1,mode=value,position=right|right|all * @access public * @return void */ diff --git a/framework/model.class.php b/framework/model.class.php index caa3db33d1..5132163f4c 100644 --- a/framework/model.class.php +++ b/framework/model.class.php @@ -21,12 +21,10 @@ include dirname(__FILE__) . '/base/model.class.php'; class model extends baseModel { /** - * 加载一个模块的model。加载完成后,使用$this->$moduleName来访问这个model对象。 - * 比如:loadModel('user')引入user模块的model实例对象,可以通过$this->user来访问它。 - * - * Load the model of one module. After loaded, can use $this->$moduleName to visit the model object. - * - * Extension: set appName as empty. + * 企业版部分功能是从然之合并过来的。然之代码中调用loadModel方法时传递了一个非空的appName,在禅道中会导致错误。 + * 调用父类的loadModel方法来避免这个错误。 + * Some codes merged from ranzhi called the function loadModel with a non-empty appName which causes an error in zentao. + * Call the parent function with empty appName to avoid this error. * * @param string $moduleName * @access public @@ -34,31 +32,7 @@ class model extends baseModel */ public function loadModel($moduleName, $appName = '') { - $appName = ''; - - if(empty($moduleName)) return false; - if(empty($appName)) $appName = $this->appName; - - global $loadedModels; - if(isset($loadedModels[$appName][$moduleName])) - { - $this->$moduleName = $loadedModels[$appName][$moduleName]; - return $this->$moduleName; - } - - $modelFile = $this->app->setModelFile($moduleName, $appName); - - if(!helper::import($modelFile)) return false; - $modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model'; - if(!class_exists($modelClass)) - { - $modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model'; - if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true); - } - - $loadedModels[$appName][$moduleName] = new $modelClass($appName); - $this->$moduleName = $loadedModels[$appName][$moduleName]; - return $this->$moduleName; + return parent::loadModel($moduleName); } /** diff --git a/framework/router.class.php b/framework/router.class.php index 02c9a94cd3..fd1cbd4bdc 100755 --- a/framework/router.class.php +++ b/framework/router.class.php @@ -39,9 +39,18 @@ class router extends baseRouter public $rawMethod; /** - * Add custom langs when set client lang. + * 标记是否是工作流 + * Whether the tag is a workflow * - * @param string $lang zh-cn|zh-tw|zh-hk|en + * @var bool + * @access public + */ + public $isFlow = false; + + /** + * Merge system and translated langs. + * + * @param string $lang zh-cn|zh-tw|en * @access public * @return void */ @@ -57,8 +66,10 @@ class router extends baseRouter } /** - * 加载语言文件,返回全局$lang对象。 - * Load lang and return it as the global lang object. + * 企业版部分功能是从然之合并过来的。然之代码中调用loadLang方法时传递了一个非空的appName,在禅道中会导致错误。 + * 把appName设置为空来避免这个错误。 + * Some codes merged from ranzhi called the function loadLang with a non-empty appName which causes an error in zentao. + * Set the value of appName to empty to avoid this error. * * @param string $moduleName the module name * @param string $appName the app name @@ -112,8 +123,10 @@ class router extends baseRouter $productProject = $productProject->value; list($productCommon, $projectCommon) = explode('_', $productProject); } - $lang->productCommon = isset($this->config->productCommonList[$this->clientLang][(int)$productCommon]) ? $this->config->productCommonList[$this->clientLang][(int)$productCommon] : $this->config->productCommonList['en'][0]; - $lang->projectCommon = isset($this->config->projectCommonList[$this->clientLang][(int)$projectCommon]) ? $this->config->projectCommonList[$this->clientLang][(int)$projectCommon] : $this->config->projectCommonList['en'][0]; + + /* Set productCommon and projectCommon. Default english lang. */ + $lang->productCommon = isset($this->config->productCommonList[$this->clientLang][(int)$productCommon]) ? $this->config->productCommonList[$this->clientLang][(int)$productCommon] : $this->config->productCommonList['en'][(int)$productCommon]; + $lang->projectCommon = isset($this->config->projectCommonList[$this->clientLang][(int)$projectCommon]) ? $this->config->projectCommonList[$this->clientLang][(int)$projectCommon] : $this->config->projectCommonList['en'][(int)$projectCommon]; } parent::loadLang($moduleName, $appName); @@ -165,13 +178,10 @@ class router extends baseRouter } /** - * 加载模块的config文件,返回全局$config对象。 - * 如果该模块是common,加载$configRoot的配置文件,其他模块则加载其模块的配置文件。 - * - * Load config and return it as the global config object. - * If the module is common, search in $configRoot, else in $modulePath. - * - * Extension: set appName as empty. + * 企业版部分功能是从然之合并过来的。然之代码中调用loadModuleConfig方法时传递了一个非空的appName,在禅道中会导致错误。 + * 把appName设置为空来避免这个错误。 + * Some codes merged from ranzhi called the function loadModuleConfig with a non-empty appName which causes an error in zentao. + * Set the value of appName to empty to avoid this error. * * @param string $moduleName module name * @param string $appName app name @@ -222,8 +232,7 @@ class router extends baseRouter } /** - * 调用父类方法时不传递$appName参数,保证父类方法中$appName值为空。 - * The $appName parameter is not passed when calling the parent class method, ensuring that the $appName value in the parent class method is null. + * The alias for loadModuleConfig. * * @param string $moduleName * @param string $appName @@ -286,6 +295,10 @@ class router extends baseRouter */ public function setControlFile($exitIfNone = true) { + /* Set raw module and method name for fetch control. */ + if(empty($this->rawModule)) $this->rawModule = $this->moduleName; + if(empty($this->rawMethod)) $this->rawMethod = $this->methodName; + /* If is not a biz version or is in install mode or in in upgrade mode, call parent method. */ if(!isset($this->config->bizVersion) or defined('IN_INSTALL') or defined('IN_UPGRADE')) return parent::setControlFile($exitIfNone); @@ -305,6 +318,7 @@ class router extends baseRouter { $this->rawModule = $this->moduleName; $this->rawMethod = 'browse'; + $this->isFlow = true; $moduleName = 'flow'; $methodName = 'browse'; @@ -318,6 +332,7 @@ class router extends baseRouter { $this->rawModule = $this->moduleName; $this->rawMethod = $this->methodName; + $this->isFlow = true; $this->loadModuleConfig('workflowaction'); @@ -434,8 +449,8 @@ class router extends baseRouter } /** - * 如果$this->rawModule和$this->rawMethod的值不为空,说明这个请求需要工作流引擎来处理,则要根据工作流引擎的需要重新设置参数。 - * If the values of $this->rawModule and $this->rawMethod are not empty, indicating that the request needs to be processed + * 如果$this->isFlow的值为true,说明这个请求需要工作流引擎来处理,则要根据工作流引擎的需要重新设置参数。 + * If the values of $this->isFlow is true, indicating that the request needs to be processed * by the workflow engine, the parameters are reset according to the needs of the workflow engine. * * @param array $defaultParams the default params defined by the method. @@ -445,14 +460,14 @@ class router extends baseRouter */ public function mergeParams($defaultParams, $passedParams) { - /* If the rawModule and rawMethod is not empty, reset the passed params. */ - if($this->rawModule && $this->rawMethod) + /* If the isFlow is true, reset the passed params. */ + if($this->isFlow) { $passedParams = array_reverse($passedParams); /* 如果请求的方法名不是browse、create、edit、view、delete、export中的任何一个,则需要添加action参数来传递请求的方法名。 */ /* If the requested method name is not any of browse, create, edit, view, delete, or export, you need to add an action parameter to pass the requested method name. */ - if(!in_array($this->rawMethod, $this->config->workflowaction->default->actions)) $passedParams['action'] = $this->rawMethod; + if(isset($this->config->workflowaction->default->actions) and !in_array($this->rawMethod, $this->config->workflowaction->default->actions)) $passedParams['action'] = $this->rawMethod; /* 添加module参数来传递请求的模块名。 */ /* Add the module parameter to pass the requested module name. */ $passedParams['module'] = $this->rawModule; diff --git a/lib/base/front/front.class.php b/lib/base/front/front.class.php index 6fbe58ac12..4281932177 100644 --- a/lib/base/front/front.class.php +++ b/lib/base/front/front.class.php @@ -1075,6 +1075,7 @@ EOT; $jsLang = new stdclass(); $jsLang->submitting = isset($lang->loading) ? $lang->loading : ''; $jsLang->save = $jsConfig->save; + $jsLang->expand = isset($lang->expand) ? $lang->expand : ''; $jsLang->timeout = isset($lang->timeout) ? $lang->timeout : ''; $js = self::start(false); diff --git a/lib/filter/filter.class.php b/lib/filter/filter.class.php index 03c47426ac..a6e1ae9d42 100644 --- a/lib/filter/filter.class.php +++ b/lib/filter/filter.class.php @@ -34,6 +34,7 @@ class fixer extends baseFixer { $fields = str_replace(' ', '', trim($fields)); + /* Get extend field by flow. */ global $config; $flowFields = array(); if(isset($config->bizVersion)) @@ -45,14 +46,27 @@ class fixer extends baseFixer } foreach($this->data as $field => $value) { - if(isset($flowFields[$field]) and is_array($value)) $this->data->$field = implode(',', $value); + /* Implode array when form has array. */ + if(isset($flowFields[$field]) and is_array($value)) + { + $canImplode = true; + foreach($value as $k => $v) + { + if(is_object($v) or is_array($v)) + { + $canImplode = false; + break; + } + } + if($canImplode) $this->data->$field = implode(',', $value); + } $this->specialChars($field); } - if(empty($fields)) return $this->data; if(strpos($fields, ',') === false) return $this->data->$fields; + /* Process fields for check by key. */ $fields = array_flip(explode(',', $fields)); foreach($this->data as $field => $value) { diff --git a/lib/phpmailer/class.smtp.php b/lib/phpmailer/class.smtp.php index ed372e3e2e..1d2aa89c82 100644 --- a/lib/phpmailer/class.smtp.php +++ b/lib/phpmailer/class.smtp.php @@ -126,11 +126,12 @@ class SMTP { } // connect to the smtp server - $this->smtp_conn = fsockopen($host, // the host of the server - $port, // the port to use - $errno, // error number if any - $errstr, // error message if any - $tval); // give up after ? secs + // Replace fsockopen for don't validate remote hosts + $contextOptions['ssl']['verify_host'] = false; + $contextOptions['ssl']['verify_peer'] = false; + $contextOptions['ssl']['verify_peer_name'] = false; + $context = stream_context_create($contextOptions); + $this->smtp_conn = stream_socket_client($host . ':' . $port, $errno, $errstr, $tval, STREAM_CLIENT_CONNECT, $context); // verify we connected properly if(empty($this->smtp_conn)) { $this->error = array("error" => "Failed to connect to server", @@ -616,7 +617,7 @@ class SMTP { protected function parseHelloFields($type) { - $this->server_caps = []; + $this->server_caps = array(); $lines = explode("\n", $this->helo_rply); foreach ($lines as $n => $s) { @@ -638,7 +639,7 @@ class SMTP { break; case 'AUTH': if (!is_array($fields)) { - $fields = []; + $fields = array(); } break; default: diff --git a/module/action/lang/en.php b/module/action/lang/en.php index 3f94f775a7..b971bdd570 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -19,6 +19,7 @@ $lang->action->actor = 'User'; $lang->action->action = 'Action'; $lang->action->actionID = 'Action ID'; $lang->action->date = 'Date'; +$lang->action->extra = 'Extra'; $lang->action->trash = 'Recycle'; $lang->action->undelete = 'Restore'; @@ -87,7 +88,7 @@ $lang->action->objectTypes['testreport'] = 'Report'; $lang->action->objectTypes['entry'] = 'Entry'; $lang->action->objectTypes['webhook'] = 'Webhook'; -/* 用来描述操作历史记录。*/ +/* Used to describe operation history. */ $lang->action->desc = new stdclass(); $lang->action->desc->common = '$date, $action by $actor.' . "\n"; $lang->action->desc->extra = '$date, $action as $extra by $actor.' . "\n"; @@ -129,7 +130,7 @@ $lang->action->desc->diff2 = '%s is changed. Th $lang->action->desc->diff3 = 'File Name %s was changed to %s .' . "\n"; $lang->action->desc->linked2bug = '$date, linked to $extra by $actor'; -/* 子任务修改父任务的历史操作记录 */ +/* Used to describe the history of operations related to parent-child tasks. */ $lang->action->desc->createchildren = '$date, $actor created a child task $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, $actor linked a child task $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, $actor linked a child task $extra。' . "\n"; @@ -137,11 +138,11 @@ $lang->action->desc->unlinkchildrentask = '$date, $actor unlink $lang->action->desc->linkparenttask = '$date, $actor linked to a parent task $extra。' . "\n"; $lang->action->desc->unlinkparenttask = '$date, $actor unlinked a parent task $extra。' . "\n"; -/* 关联用例和移除用例时的历史操作记录。*/ +/* Historical record of actions when associating and removing cases. */ $lang->action->desc->linkrelatedcase = '$date, $actor linked a case $extra.' . "\n"; $lang->action->desc->unlinkrelatedcase = '$date, $actor unlinked a case $extra.' . "\n"; -/* 用来显示动态信息。*/ +/* Used to display dynamic information. */ $lang->action->label = new stdclass(); $lang->action->label->created = 'created '; $lang->action->label->opened = 'opened '; @@ -209,7 +210,7 @@ $lang->action->label->batchcreate = "batch created tasks"; $lang->action->label->createchildren = "create child tasks"; $lang->action->label->managed = "managed"; -/* 动态信息按照对象分组 */ +/* Dynamic information is grouped by object. */ $lang->action->dynamicAction = new stdclass; $lang->action->dynamicAction->todo['opened'] = 'Create Todo'; $lang->action->dynamicAction->todo['edited'] = 'Edit Todo'; @@ -357,7 +358,7 @@ $lang->action->dynamicAction->user['loginxuanxuan'] = 'Login Desktop'; $lang->action->dynamicAction->entry['created'] = 'Add Application'; $lang->action->dynamicAction->entry['edited'] = 'Edit Application'; -/* 用来生成相应对象的链接。*/ +/* Generate the corresponding object link. */ $lang->action->label->product = $lang->productCommon . '|product|view|productID=%s'; $lang->action->label->productplan = 'Plan|productplan|view|productID=%s'; $lang->action->label->release = 'Release|release|view|productID=%s'; @@ -402,7 +403,7 @@ $lang->action->search->objectTypeList['testsuite'] = 'Suite'; $lang->action->search->objectTypeList['caselib'] = 'Library'; $lang->action->search->objectTypeList['testreport'] = 'Report'; -/* 用来在动态显示中显示动作 */ +/* Used to display actions in dynamic method. */ $lang->action->search->label[''] = ''; $lang->action->search->label['created'] = $lang->action->label->created; $lang->action->search->label['opened'] = $lang->action->label->opened; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 665d1098c3..e6d26c50d3 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -19,6 +19,7 @@ $lang->action->actor = '操作者'; $lang->action->action = '动作'; $lang->action->actionID = '记录ID'; $lang->action->date = '日期'; +$lang->action->extra = '附加值'; $lang->action->trash = '回收站'; $lang->action->undelete = '还原'; @@ -129,7 +130,7 @@ $lang->action->desc->diff2 = '修改了 %s, $lang->action->desc->diff3 = '将文件名 %s 改为 %s 。' . "\n"; $lang->action->desc->linked2bug = '$date 由 $actor 关联到版本 $extra'; -/* 子任务修改父任务的历史操作记录 */ +/* 用来描述和父子任务相关的操作历史记录。*/ $lang->action->desc->createchildren = '$date, 由 $actor 创建子任务 $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, 由 $actor 关联子任务 $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, 由 $actor 关联子任务 $extra。' . "\n"; diff --git a/module/action/lang/zh-tw.php b/module/action/lang/zh-tw.php index 51a07b3f3a..8c22824465 100755 --- a/module/action/lang/zh-tw.php +++ b/module/action/lang/zh-tw.php @@ -19,6 +19,7 @@ $lang->action->actor = '操作者'; $lang->action->action = '動作'; $lang->action->actionID = '記錄ID'; $lang->action->date = '日期'; +$lang->action->extra = '附加值'; $lang->action->trash = '資源回收筒'; $lang->action->undelete = '還原'; @@ -129,7 +130,7 @@ $lang->action->desc->diff2 = '修改了 %s, $lang->action->desc->diff3 = '將檔案名 %s 改為 %s 。' . "\n"; $lang->action->desc->linked2bug = '$date 由 $actor 關聯到版本 $extra'; -/* 子任務修改父任務的歷史操作記錄 */ +/* 用來描述和父子任務相關的操作歷史記錄。*/ $lang->action->desc->createchildren = '$date, 由 $actor 創建子任務 $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, 由 $actor 關聯子任務 $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, 由 $actor 關聯子任務 $extra。' . "\n"; diff --git a/module/action/model.php b/module/action/model.php index 27394bd8dd..da708c9ea9 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -45,9 +45,11 @@ class actionModel extends model $action->actor = $actor; $action->action = $actionType; $action->date = helper::now(); - $action->comment = trim(strip_tags($comment, $this->config->allowedTags)); $action->extra = $extra; + $_POST['comment'] = $comment; + $action->comment = fixer::input('post')->stripTags('comment')->get('comment'); + /* Process action. */ $action = $this->loadModel('file')->processImgURL($action, 'comment', $this->post->uid); if($autoDelete) $this->file->autoDelete($this->post->uid); @@ -978,6 +980,12 @@ class actionModel extends model { $this->dao->update(TABLE_DOCLIB)->set('deleted')->eq(0)->where($action->objectType)->eq($action->objectID)->exec(); } + /* Revert productplan project status */ + if($action->objectType == 'productplan') + { + $plan = $this->loadModel('productplan')->getById($action->objectID); + $this->loadModel('productplan')->updatePlanParentStatus($plan->parent); + } /* Update action record in action table. */ $this->dao->update(TABLE_ACTION)->set('extra')->eq(ACTIONMODEL::BE_UNDELETED)->where('id')->eq($actionID)->exec(); @@ -1059,7 +1067,7 @@ class actionModel extends model if($dateGroup) { - $lastDateActions = $this->dao->select('*')->from(TABLE_ACTION)->where($this->session->actionQueryCondition)->andWhere('`date`')->like(substr($action->originalDate, 0, 10) . '%')->orderBy($this->session->actionOrderBy)->fetchAll('id'); + $lastDateActions = $this->dao->select('*')->from(TABLE_ACTION)->where($this->session->actionQueryCondition)->andWhere("(LEFT(`date`, 10) = '" . substr($action->originalDate, 0, 10) . "')")->orderBy($this->session->actionOrderBy)->fetchAll('id'); if(count($dateGroup[$date]) < count($lastDateActions)) { unset($dateGroup[$date]); diff --git a/module/action/view/trash.html.php b/module/action/view/trash.html.php index ef7c090b5e..6e56576a07 100755 --- a/module/action/view/trash.html.php +++ b/module/action/view/trash.html.php @@ -53,7 +53,7 @@ $flow = $config->action->customFlows[$action->objectType]; $module = $flow->module; } - if(strpos(',doclib,module,webhook,workflowdatasource,workflowfield,workflowlabel,workflowlayout,workflowrule,', ",{$module},") !== false) + if(strpos(',doclib,module,webhook,', ",{$module},") !== false) { echo $action->objectName; } @@ -63,7 +63,7 @@ } ?> -
[Steps]
[Results]
[Expectations]