* @package transfer * @link https://www.zentao.net */ class transferTao extends transferModel { /** * 根据config:dataSource中配置的方法获取字段数据源。 * Get source by module method. * * @param string $module * @param string $callModule * @param string $method * @param string|array|int $params * @param string|array $pairs * @access protected * @return array */ protected function getSourceByModuleMethod($module, $callModule, $method, $params = '', $pairs = '') { /* 获取模块传递的参数。 */ /* Get params. */ $getParams = $this->session->{$module . 'TransferParams'}; /* 解析dataSource params中配置的参数。 */ /* Parse params. */ if(is_string($params)) $params = explode('&', $params); foreach($params as $param => $value) { /* 如果参数是$开头的变量,则从SESSION中获取该变量。 */ /* If the param is $var, get it from SESSION. */ if(!is_string($value)) continue; if(strpos($value, '$') === false) continue; $params[$param] = isset($getParams[ltrim($value, '$')]) ? $getParams[ltrim($value, '$')] : ''; if(isset($this->config->transfer->convertInt[$callModule][$method][ltrim($value, '$')])) $params[$param] = (int)$params[$param]; if(isset($this->config->transfer->convertInt[$callModule][$method][$param])) $params[$param] = (int)$params[$param]; } /* 调用模块的方法。 */ /* If this method has multiple parameters use call_user_func_array. */ if(is_array($params) and $params) { $values = call_user_func_array(array($this->loadModel($callModule), $method), $params); } else { $values = $this->loadModel($callModule)->$method($params); } /* 解析dataSource pairs中配置的参数(是否需要返回array(key => value)形式的关联数组。 */ /* Parse pairs. */ if(!empty($pairs)) { $valuePairs = array(); foreach($values as $key => $value) { if(is_object($value)) $value = get_object_vars($value); $valuePairs[$key] = $value[$pairs[1]]; if(!empty($pairs[0])) $valuePairs[$value[$pairs[0]]] = $value[$pairs[1]]; } $values = $valuePairs; } return $values; } /** * 根据id获取附件分组。 * Get file group by id. * * @param string $module * @param array $idList * @access protected * @return array */ protected function getFileGroups($module, $idList) { if(in_array($module, array('epic', 'requirement'))) $module = "{$module},story"; return $this->dao->select('id, objectID, pathname, title')->from(TABLE_FILE) ->where('objectType')->in($module) ->beginIf($idList)->andWhere('objectID')->in($idList)->fi() ->andWhere('extra')->ne('editor') ->fetchGroup('objectID'); } /** * 获取级联数据列表。 * Get cascade list for export excel. * * @param string $module * @param array $lists * @access protected * @return array */ protected function getCascadeList($module, $lists) { /* 如果没有配置config->cascade,则不需要进行级联操作。*/ /* If has not cascade config, do not need to do cascade operation. */ $this->commonActions($module); if(!isset($this->moduleConfig->cascade)) return $lists; $cascadeArray = $this->moduleConfig->cascade; foreach($cascadeArray as $field => $linkField) { $fieldName = $field . 'List'; $linkFieldName = $linkField . 'List'; $tmpFieldName = array(); if(isset($_POST['cascade'][$field])) { if(is_array($_POST['cascade'][$field])) $lists[$fieldName] = $_POST['cascade'][$field]; continue; } if(empty($lists[$fieldName]) || empty($lists[$linkFieldName])) continue; /* 根据字段名获取表名。*/ /* Get table name by field name. */ $table = zget($this->config->objectTables, $field, ''); if(empty($table)) continue; /* 根据字段名获取关联数据。*/ /* Get ID list by field name. */ $fieldIDList = array_keys($lists[$fieldName]); $fieldDatas = $this->dao->select("id, $linkField")->from($table)->where('id')->in($fieldIDList)->fetchPairs(); if(empty($fieldDatas)) continue; /* 将获取到的数据替换到lists中。*/ /* Replace data to lists. */ foreach($fieldDatas as $id => $linkFieldID) { $tmpFieldName[0][$id] = $tmpFieldName[$linkFieldID][$id] = $lists[$fieldName][$id]; } $lists[$fieldName] = $tmpFieldName; } return $lists; } /** * 解析Excel中下拉框单元格的值。 * Parse value of multiple dropdown cells. * * @param string $cellValue * @param string $field * @param array $values * @access protected * @return array */ protected function extractElements($cellValue, $field, $values) { if(empty($values)) return $cellValue; /* 多行下拉框和单行下拉框都按照多行处理。*/ /* Multiple dropdowns and single dropdowns are processed in multiple rows. */ $cellValue = explode("\n", $cellValue); foreach($cellValue as &$value) { /* 解析下拉框的值value(#rawValue),提取rawValue。*/ /* Parse dropdown values value(#rawValue) and extract rawValue. */ if(strrpos($value, '(#') !== false) { $value = trim(substr($value, strrpos($value,'(#') + 2), ')'); } else { /* 如果value在values中存在则在values中查找(一般为语言项)。*/ /* If value exists in values, find it in values (usually as a language item). */ $valueKey = array_search($value, $values); $value = $valueKey !== false ? $valueKey : $value; } } /* 过滤掉数组中的空值(null、空字符串、0等)以及值为字符串 '0' 的元素,只保留其他非空元素。*/ /* Filter out empty values (null, empty string, 0, etc.) in the array and only keep other non-empty elements. */ $cellValue = array_filter($cellValue, function($v) {return (empty($v) && $v == '0') || !empty($v);}); return implode(',', $cellValue); } /** * 配置导入字段。 * Config import fields. * * @param string $module * @access protected * @return array */ protected function getImportFields($module = '') { $this->commonActions($module); $moduleLang = $this->moduleLang; $fields = explode(',', $this->moduleConfig->templateFields); // 获取导入模板字段 array_unshift($fields, 'id'); foreach($fields as $key => $fieldName) { /* 匹配语言项。 */ /* Match language item. */ $fieldName = trim($fieldName); $fields[$fieldName] = isset($moduleLang->$fieldName) ? $moduleLang->$fieldName : $fieldName; unset($fields[$key]); } /* 获取工作流扩展字段。*/ /* Get workflow extend fields. */ if($this->config->edition != 'open') { $appendFields = $this->loadModel('flow')->getExtendFields($module, 'showimport'); foreach($appendFields as $appendField) { /* 不是内置字段并且在导入确认页面展示。 */ /* Is not builtin field and show in import confirm page. */ if(!$appendField->buildin and $appendField->show) $fields[$appendField->field] = $appendField->name; } } return $fields; } /** * 更新子数据。 * Update children datas. * * @param array $datas * @access protected * @return array */ protected function updateChildDatas($datas) { foreach($datas as $id => $data) { if(!empty($data->mode)) $datas[$id]->name = '[' . $this->lang->task->multipleAB . '] ' . $data->name; //任务类型(多人任务/单人任务) } /* 如果存在子数据,则将子数据插入到父数据之后。*/ /* Move child data after parent data. */ $children = array(); $orphans = array(); foreach($datas as $data) { $parentId = isset($data->parentId) ? $data->parentId : (isset($data->parent) ? $data->parent : 0); if($parentId != 0 && !isset($datas[$parentId])) { $orphans[] = $data; } else { if(!isset($children[$parentId])) $children[$parentId] = array(); $children[$parentId][] = $data; } } if(empty($children)) return $datas; $buildTree = function($parentId) use (&$buildTree, &$children) { $result = array(); if(isset($children[$parentId])) { foreach($children[$parentId] as $child) { $result[] = $child; $result = array_merge($result, $buildTree($child->id)); } } return $result; }; $tree = array_merge((array)$buildTree(0), $orphans); if(count($tree) != count($datas)) return $datas; return $tree; } }