* Finish task#9005.
This commit is contained in:
@@ -284,3 +284,6 @@ $filter->repo->ajaxsynccommit->cookie['syncBranch'] = 'reg::any';
|
||||
|
||||
$filter->webhook->bind->get['selectedDepts'] = 'reg::checked';
|
||||
$filter->webhook->bind->cookie['selectedDepts'] = 'reg::checked';
|
||||
|
||||
$filter->search->index->get['words'] = 'reg::any';
|
||||
$filter->search->index->get['type'] = 'code';
|
||||
|
||||
@@ -174,6 +174,9 @@ if(!defined('TABLE_BUDGET')) define('TABLE_BUDGET', '`' . $config->d
|
||||
if(!defined('TABLE_HOLIDAY')) define('TABLE_HOLIDAY', '`' . $config->db->prefix . 'holiday`');
|
||||
if(!defined('TABLE_WEEKLYREPORT')) define('TABLE_WEEKLYREPORT', '`' . $config->db->prefix . 'weeklyreport`');
|
||||
|
||||
if(!defined('TABLE_SEARCHINDEX')) define('TABLE_SEARCHINDEX', $config->db->prefix . 'searchindex');
|
||||
if(!defined('TABLE_SEARCHDICT')) define('TABLE_SEARCHDICT', $config->db->prefix . 'searchdict');
|
||||
|
||||
$config->objectTables['product'] = TABLE_PRODUCT;
|
||||
$config->objectTables['story'] = TABLE_STORY;
|
||||
$config->objectTables['productplan'] = TABLE_PRODUCTPLAN;
|
||||
|
||||
@@ -18,3 +18,39 @@ ALTER TABLE `zt_project` DROP `storyConcept`;
|
||||
ALTER TABLE `zt_product` DROP `storyConcept`;
|
||||
|
||||
ALTER TABLE `zt_user` CHANGE `avatar` `avatar` text NOT NULL AFTER `commiter`;
|
||||
|
||||
-- DROP TABLE IF EXISTS `zt_searchindex`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_searchindex` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`objectType` char(20) NOT NULL,
|
||||
`objectID` mediumint(9) NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`content` text NOT NULL,
|
||||
`addedDate` datetime NOT NULL,
|
||||
`editedDate` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `object` (`objectType`,`objectID`),
|
||||
KEY `addedDate` (`addedDate`),
|
||||
FULLTEXT KEY `content` (`content`),
|
||||
FULLTEXT KEY `title` (`title`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- DROP TABLE IF EXISTS `zt_searchdict`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_searchdict` (
|
||||
`key` smallint(5) unsigned NOT NULL,
|
||||
`value` char(3) NOT NULL,
|
||||
PRIMARY KEY (`key`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(1, 'search', 'index'),
|
||||
(2, 'search', 'index'),
|
||||
(3, 'search', 'index'),
|
||||
(4, 'search', 'index'),
|
||||
(5, 'search', 'index'),
|
||||
(6, 'search', 'index'),
|
||||
(7, 'search', 'index'),
|
||||
(8, 'search', 'index'),
|
||||
(9, 'search', 'index'),
|
||||
(10, 'search', 'index'),
|
||||
(1, 'search', 'buildIndex');
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
-- DROP TABLE IF EXISTS `zt_searchindex`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_searchindex` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`objectType` char(20) NOT NULL,
|
||||
`objectID` mediumint(9) NOT NULL,
|
||||
`title` text NOT NULL,
|
||||
`content` text NOT NULL,
|
||||
`addedDate` datetime NOT NULL,
|
||||
`editedDate` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `object` (`objectType`,`objectID`),
|
||||
KEY `addedDate` (`addedDate`),
|
||||
FULLTEXT KEY `content` (`content`),
|
||||
FULLTEXT KEY `title` (`title`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- DROP TABLE IF EXISTS `zt_searchdict`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_searchdict` (
|
||||
`key` smallint(5) unsigned NOT NULL,
|
||||
`value` char(3) NOT NULL,
|
||||
PRIMARY KEY (`key`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- DROP TABLE IF EXISTS `zt_acl`;
|
||||
CREATE TABLE IF NOT EXISTS `zt_acl` (
|
||||
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
@@ -1481,6 +1504,19 @@ INSERT INTO `zt_group` (`id`, `name`, `role`, `desc`) VALUES
|
||||
(12, 'LIMITED', 'limited', 'For limited user'),
|
||||
(13, '项目管理员', 'PRJAdmin', '项目管理员可以维护项目的权限');
|
||||
|
||||
INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(1, 'search', 'index'),
|
||||
(2, 'search', 'index'),
|
||||
(3, 'search', 'index'),
|
||||
(4, 'search', 'index'),
|
||||
(5, 'search', 'index'),
|
||||
(6, 'search', 'index'),
|
||||
(7, 'search', 'index'),
|
||||
(8, 'search', 'index'),
|
||||
(9, 'search', 'index'),
|
||||
(10, 'search', 'index'),
|
||||
(1, 'search', 'buildIndex');
|
||||
|
||||
INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(1, 'action', 'editComment'),
|
||||
(1, 'action', 'hideAll'),
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* The spliter class file of chanzhiEPS.
|
||||
*
|
||||
* @copyright Copyright 2013-2014 青岛息壤网络信息有限公司 (QingDao XiRang Network Infomation Co,LTD www.xirangit.com)
|
||||
* @license LGPL
|
||||
* @author Xiying Guan <guanxiying@xirangit.com>
|
||||
* @package spliter
|
||||
* @version $Id$
|
||||
* @link http://www.chanzhi.org
|
||||
* @see http://www.cnblogs.com/chenwenbiao/archive/2011/08/11/2134503.html
|
||||
* @see http://stackoverflow.com/questions/9361303/can-i-get-the-unicode-value-of-a-character-or-vise-versa-with-php
|
||||
*/
|
||||
class spliter
|
||||
{
|
||||
/**
|
||||
* Split a utf-8 string into words, computing unicode for every word.
|
||||
*
|
||||
* @param string $string
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function utf8Split($string)
|
||||
{
|
||||
$string = strtolower($string);
|
||||
$i = 0;
|
||||
$length = strlen($string);
|
||||
$dict = array();
|
||||
$words = '';
|
||||
$offset = 0;
|
||||
|
||||
while($i <= $length)
|
||||
{
|
||||
$letter = substr($string, $i, 1);
|
||||
$ord = ord($letter);
|
||||
|
||||
/* The first letter is ascii, try to get a word. */
|
||||
if($ord >= 0 && $ord <= 191)
|
||||
{
|
||||
$i ++;
|
||||
|
||||
if($this->isLetter($letter))
|
||||
{
|
||||
$word = $letter;
|
||||
while($i <= $length)
|
||||
{
|
||||
$letter = substr($string, $i, 1);
|
||||
if(!$this->isLetter($letter)) break;
|
||||
|
||||
$word .= $letter;
|
||||
$i++;
|
||||
}
|
||||
|
||||
/* Process intigers. */
|
||||
if(is_numeric($word) and (strpos($word, '.') === false)) $word = "|" . $word . "|";
|
||||
$word = str_pad(strtolower($word), 5, '_');
|
||||
$words .= ' ' . $word;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if($ord >= 192 && $ord <= 223) $offset = 2;
|
||||
if($ord >= 224 && $ord <= 239) $offset = 3;
|
||||
if($ord >= 240 && $ord <= 247) $offset = 4;
|
||||
if($ord >= 248 && $ord <= 251) $offset = 5;
|
||||
if($ord >= 252 && $ord <= 253) $offset = 6;
|
||||
|
||||
if($offset >= 2)
|
||||
{
|
||||
$letter = substr($string, $i, $offset);
|
||||
$unicode = $this->unicode($letter);
|
||||
if(strlen($unicode) == 5)
|
||||
{
|
||||
$dict[$unicode] = $letter;
|
||||
$words .= ' ' . $unicode;
|
||||
}
|
||||
else
|
||||
{
|
||||
$words .= ' ' . $letter;
|
||||
}
|
||||
$i += $offset;
|
||||
}
|
||||
}
|
||||
|
||||
return array('dict' => $dict, 'words' => $words);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return unicode value for a char.
|
||||
*
|
||||
* @param string $c
|
||||
* @access public
|
||||
* @return int
|
||||
*/
|
||||
public function unicode($c)
|
||||
{
|
||||
if(ord($c{0}) >= 0 && ord($c{0}) <= 127) return ord($c{0});
|
||||
if(ord($c{0}) >= 192 && ord($c{0}) <= 223) return (ord($c{0}) - 192) * 64 + (ord($c{1}) - 128);
|
||||
if(ord($c{0}) >= 224 && ord($c{0}) <= 239) return (ord($c{0}) - 224) * 4096 + (ord($c{1}) - 128) * 64 + (ord($c{2}) - 128);
|
||||
if(ord($c{0}) >= 240 && ord($c{0}) <= 247) return (ord($c{0}) - 240) * 262144 + (ord($c{1}) - 128) * 4096 + (ord($c{2}) - 128) * 64 + (ord($c{3}) - 128);
|
||||
if(ord($c{0}) >= 248 && ord($c{0}) <= 251) return (ord($c{0}) - 248) * 16777216 + (ord($c{1}) - 128) * 262144 + (ord($c{2}) - 128) * 4096 + (ord($c{3}) - 128) * 64 + (ord($c{4}) - 128);
|
||||
if(ord($c{0}) >= 252 && ord($c{0}) <= 253) return (ord($c{0}) - 252) * 1073741824 + (ord($c{1}) - 128) * 16777216 + (ord($c{2}) - 128) * 262144 + (ord($c{3}) - 128) * 4096 + (ord($c{4}) - 128) * 64 + (ord($c{5}) - 128);
|
||||
|
||||
if(ord($c{0}) >= 254 && ord($c{0}) <= 255) return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge a char is Letter or not.
|
||||
*
|
||||
* @param string $letter
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function isLetter($letter)
|
||||
{
|
||||
$ord = ord($letter);
|
||||
if($ord >= ord('a') and $ord <= ord('z')) return true;
|
||||
if($ord >= ord('A') and $ord <= ord('Z')) return true;
|
||||
if($ord >= ord(0) and $ord <= ord(9)) return true;
|
||||
if($letter and strpos('._/->:<?&', $letter) !== false) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -69,6 +69,8 @@ class actionModel extends model
|
||||
|
||||
$this->loadModel('message')->send($objectType, $objectID, $actionType, $actionID, $actor);
|
||||
|
||||
$this->saveIndex($objectType, $objectID, $actionType);
|
||||
|
||||
return $actionID;
|
||||
}
|
||||
|
||||
@@ -1185,4 +1187,55 @@ class actionModel extends model
|
||||
->fetch('count');
|
||||
return $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save global search object index information.
|
||||
*
|
||||
* @param string $objectType
|
||||
* @param int $objectID
|
||||
* @param string $actionType
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function saveIndex($objectType, $objectID, $actionType)
|
||||
{
|
||||
$this->loadModel('search');
|
||||
$actionType = strtolower($actionType);
|
||||
if(!isset($this->config->search->fields->$objectType)) return true;
|
||||
if(strpos($this->config->search->buildAction, ",{$actionType},") === false and empty($_POST['comment'])) return true;
|
||||
if($actionType == 'deleted' or $actionType == 'erased') return $this->search->deleteIndex($objectType, $objectID);
|
||||
|
||||
$field = $this->config->search->fields->$objectType;
|
||||
$query = $this->search->buildIndexQuery($objectType, $testDeleted = false);
|
||||
$data = $query->andWhere('t1.' . $field->id)->eq($objectID)->fetch();
|
||||
if(empty($data)) return true;
|
||||
|
||||
$data->comment = '';
|
||||
if($objectType == 'effort' and $data->objectType == 'task') return true;
|
||||
if($objectType == 'case')
|
||||
{
|
||||
$caseStep = $this->dao->select('*')->from(TABLE_CASESTEP)->where('`case`')->eq($objectID)->andWhere('version')->eq($data->version)->fetchAll();
|
||||
$data->desc = '';
|
||||
$data->expect = '';
|
||||
foreach($caseStep as $step)
|
||||
{
|
||||
$data->desc .= $step->desc . "\n";
|
||||
$data->expect .= $step->expect . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$actions = $this->dao->select('*')->from(TABLE_ACTION)
|
||||
->where('objectType')->eq($objectType)
|
||||
->andWhere('objectID')->eq($objectID)
|
||||
->orderBy('id asc')
|
||||
->fetchAll();
|
||||
foreach($actions as $action)
|
||||
{
|
||||
if($action->action == 'opened') $data->{$field->addedDate} = $action->date;
|
||||
$data->{$field->editedDate} = $action->date;
|
||||
if(!empty($action->comment)) $data->comment .= $action->comment . "\n";
|
||||
}
|
||||
|
||||
$this->search->saveIndex($objectType, $data);
|
||||
}
|
||||
}
|
||||
|
||||
+27
-13
@@ -131,6 +131,11 @@ $lang->typeAB = 'Typ';
|
||||
$lang->common = new stdclass();
|
||||
$lang->common->common = 'Standard Module';
|
||||
|
||||
global $config;
|
||||
list($programModule, $programMethod) = explode('-', $config->programLink);
|
||||
list($productModule, $productMethod) = explode('-', $config->productLink);
|
||||
list($projectModule, $projectMethod) = explode('-', $config->projectLink);
|
||||
|
||||
/* Main menu. */
|
||||
$lang->mainNav = new stdclass();
|
||||
$lang->mainNav->my = '<i class="icon icon-menu-my"></i> My|my|index|';
|
||||
@@ -220,7 +225,11 @@ $lang->holiday->menu = $lang->subject->menu;
|
||||
$lang->measurement = new stdclass();
|
||||
$lang->measurement->menu = new stdclass();
|
||||
|
||||
$lang->searchTips = '';
|
||||
$lang->searchAB = 'Search';
|
||||
|
||||
/* Object list in search form. */
|
||||
$lang->searchObjects['all'] = 'All';
|
||||
$lang->searchObjects['bug'] = 'Bug';
|
||||
$lang->searchObjects['story'] = 'Story';
|
||||
$lang->searchObjects['task'] = 'Aufgaben';
|
||||
@@ -236,6 +245,7 @@ $lang->searchObjects['testreport'] = 'Test-Bericht';
|
||||
$lang->searchObjects['program'] = 'Program';
|
||||
$lang->searchObjects['project'] = 'Project';
|
||||
$lang->searchObjects['execution'] = $lang->sprintCommon;
|
||||
$lang->searchObjects['user'] = 'User';
|
||||
$lang->searchTips = 'ID (strg+g)';
|
||||
|
||||
/* Code formats for import. */
|
||||
@@ -338,18 +348,18 @@ $lang->story->menu = $lang->product->menu;
|
||||
$lang->project = new stdclass();
|
||||
$lang->project->menu = new stdclass();
|
||||
|
||||
$lang->project->menu->task = array('link' => 'Aufgabenliste|project|task|projectID=%s', 'subModule' => 'task,grouptask,tree', 'alias' => 'grouptask,importtask,importbug,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->kanban = array('link' => 'Kanban|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => 'Burn|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => 'View|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => 'Story|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => 'Test Aufgabe|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => 'Dok|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => 'Team|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => 'More|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->task = array('link' => 'Aufgabenliste|project|task|projectID=%s', 'subModule' => 'task,grouptask,tree', 'alias' => 'grouptask,importtask,importbug,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->kanban = array('link' => 'Kanban|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => 'Burn|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => 'View|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => 'Story|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => 'Test Aufgabe|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => 'Dok|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => 'Team|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => 'More|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
|
||||
$lang->project->subMenu = new stdclass();
|
||||
$lang->project->subMenu->view = new stdclass();
|
||||
@@ -560,6 +570,9 @@ $lang->admin->subMenu->system = new stdclass();
|
||||
$lang->admin->subMenu->system->cron = array('link' => 'Cron|cron|index', 'subModule' => 'cron');
|
||||
$lang->admin->subMenu->system->timezone = array('link' => 'Timezone|custom|timezone', 'subModule' => 'custom');
|
||||
|
||||
$lang->admin->subMenu->system->buildIndex = array('link' => 'Full Text Search|search|buildindex|');
|
||||
$lang->admin->subMenuOrder->system[15] = 'buildIndex';
|
||||
|
||||
$lang->convert = new stdclass();
|
||||
$lang->upgrade = new stdclass();
|
||||
$lang->action = new stdclass();
|
||||
@@ -619,6 +632,7 @@ $lang->navGroup = new stdclass();
|
||||
$lang->navGroup->my = 'my';
|
||||
$lang->navGroup->todo = 'my';
|
||||
$lang->navGroup->effort = 'my';
|
||||
$lang->navGroup->score = 'my';
|
||||
|
||||
$lang->navGroup->personnel = 'program';
|
||||
|
||||
@@ -999,6 +1013,6 @@ $lang->projectstory->menu->story = array('link' => "{$lang->SRCommon}|projectsto
|
||||
$lang->projectstory->menu->track = array('link' => 'Track|projectstory|track', 'subModule' => '');
|
||||
|
||||
$lang->nc->menu = $lang->auditplan->menu;
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'product', 'productplan', 'projectbuild', 'projectrelease', 'story', 'job', 'jenkins', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search', 'stage');
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'product', 'productplan', 'projectbuild', 'projectrelease', 'story', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search', 'score', 'stage');
|
||||
|
||||
include (dirname(__FILE__) . '/menuOrder.php');
|
||||
|
||||
+27
-13
@@ -131,6 +131,11 @@ $lang->typeAB = 'Type';
|
||||
$lang->common = new stdclass();
|
||||
$lang->common->common = 'Common Module';
|
||||
|
||||
global $config;
|
||||
list($programModule, $programMethod) = explode('-', $config->programLink);
|
||||
list($productModule, $productMethod) = explode('-', $config->productLink);
|
||||
list($projectModule, $projectMethod) = explode('-', $config->projectLink);
|
||||
|
||||
/* Main menu. */
|
||||
$lang->mainNav = new stdclass();
|
||||
$lang->mainNav->my = '<i class="icon icon-menu-my"></i> My|my|index|';
|
||||
@@ -220,7 +225,11 @@ $lang->holiday->menu = $lang->subject->menu;
|
||||
$lang->measurement = new stdclass();
|
||||
$lang->measurement->menu = new stdclass();
|
||||
|
||||
$lang->searchTips = '';
|
||||
$lang->searchAB = 'Search';
|
||||
|
||||
/* Object list in search form. */
|
||||
$lang->searchObjects['all'] = 'All';
|
||||
$lang->searchObjects['bug'] = 'Bug';
|
||||
$lang->searchObjects['story'] = 'Story';
|
||||
$lang->searchObjects['task'] = 'Task';
|
||||
@@ -236,6 +245,7 @@ $lang->searchObjects['testreport'] = 'Test Report';
|
||||
$lang->searchObjects['program'] = 'Program';
|
||||
$lang->searchObjects['project'] = 'Project';
|
||||
$lang->searchObjects['execution'] = $lang->sprintCommon;
|
||||
$lang->searchObjects['user'] = 'User';
|
||||
$lang->searchTips = 'ID (ctrl+g)';
|
||||
|
||||
/* Code formats for import. */
|
||||
@@ -338,18 +348,18 @@ $lang->story->menu = $lang->product->menu;
|
||||
$lang->project = new stdclass();
|
||||
$lang->project->menu = new stdclass();
|
||||
|
||||
$lang->project->menu->task = array('link' => 'Task|project|task|projectID=%s', 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
|
||||
$lang->project->menu->kanban = array('link' => 'Kanban|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => 'Burndown|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => 'View|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => 'Story|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => 'Request|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => 'Doc|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => 'Team|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => 'More|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->task = array('link' => 'Task|project|task|projectID=%s', 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
|
||||
$lang->project->menu->kanban = array('link' => 'Kanban|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => 'Burndown|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => 'View|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => 'Story|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => 'Request|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => 'Doc|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => 'Team|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => 'More|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
|
||||
$lang->project->subMenu = new stdclass();
|
||||
$lang->project->subMenu->view = new stdclass();
|
||||
@@ -560,6 +570,9 @@ $lang->admin->subMenu->system = new stdclass();
|
||||
$lang->admin->subMenu->system->cron = array('link' => 'Cron|cron|index', 'subModule' => 'cron');
|
||||
$lang->admin->subMenu->system->timezone = array('link' => 'Timezone|custom|timezone', 'subModule' => 'custom');
|
||||
|
||||
$lang->admin->subMenu->system->buildIndex = array('link' => 'Full Text Search|search|buildindex|');
|
||||
$lang->admin->subMenuOrder->system[15] = 'buildIndex';
|
||||
|
||||
$lang->convert = new stdclass();
|
||||
$lang->upgrade = new stdclass();
|
||||
$lang->action = new stdclass();
|
||||
@@ -619,6 +632,7 @@ $lang->navGroup = new stdclass();
|
||||
$lang->navGroup->my = 'my';
|
||||
$lang->navGroup->todo = 'my';
|
||||
$lang->navGroup->effort = 'my';
|
||||
$lang->navGroup->score = 'my';
|
||||
|
||||
$lang->navGroup->personnel = 'program';
|
||||
|
||||
@@ -999,6 +1013,6 @@ $lang->projectstory->menu->story = array('link' => "{$lang->SRCommon}|projectsto
|
||||
$lang->projectstory->menu->track = array('link' => 'Track|projectstory|track', 'subModule' => '');
|
||||
|
||||
$lang->nc->menu = $lang->auditplan->menu;
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'product', 'productplan', 'projectbuild', 'projectrelease', 'story', 'job', 'jenkins', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search', 'stage');
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'product', 'productplan', 'projectbuild', 'projectrelease', 'story', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search', 'score', 'stage');
|
||||
|
||||
include (dirname(__FILE__) . '/menuOrder.php');
|
||||
|
||||
+27
-16
@@ -131,6 +131,11 @@ $lang->typeAB = 'Type';
|
||||
$lang->common = new stdclass();
|
||||
$lang->common->common = 'Module Commun';
|
||||
|
||||
global $config;
|
||||
list($programModule, $programMethod) = explode('-', $config->programLink);
|
||||
list($productModule, $productMethod) = explode('-', $config->productLink);
|
||||
list($projectModule, $projectMethod) = explode('-', $config->projectLink);
|
||||
|
||||
/* Main menu. */
|
||||
$lang->mainNav = new stdclass();
|
||||
$lang->mainNav->my = '<i class="icon icon-menu-my"></i> My|my|index|';
|
||||
@@ -220,7 +225,11 @@ $lang->holiday->menu = $lang->subject->menu;
|
||||
$lang->measurement = new stdclass();
|
||||
$lang->measurement->menu = new stdclass();
|
||||
|
||||
$lang->searchTips = '';
|
||||
$lang->searchAB = 'Search';
|
||||
|
||||
/* Object list in search form. */
|
||||
$lang->searchObjects['all'] = 'All';
|
||||
$lang->searchObjects['bug'] = 'Bug';
|
||||
$lang->searchObjects['story'] = 'Story';
|
||||
$lang->searchObjects['task'] = 'Tâche';
|
||||
@@ -236,6 +245,7 @@ $lang->searchObjects['testreport'] = 'CR de Test';
|
||||
$lang->searchObjects['program'] = 'Program';
|
||||
$lang->searchObjects['project'] = 'Project';
|
||||
$lang->searchObjects['execution'] = $lang->sprintCommon;
|
||||
$lang->searchObjects['user'] = 'User';
|
||||
$lang->searchTips = 'ID (ctrl+g)';
|
||||
|
||||
/* Code formats for import. */
|
||||
@@ -338,21 +348,18 @@ $lang->story->menu = $lang->product->menu;
|
||||
$lang->project = new stdclass();
|
||||
$lang->project->menu = new stdclass();
|
||||
|
||||
$lang->project->menu->task = array('link' => 'Tâche|project|task|projectID=%s', 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
|
||||
$lang->project->menu->kanban = array('link' => 'Kanban|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => 'Atterrissage|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => 'View|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => 'Story|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => 'Recette|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => 'Doc|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => 'Equipe|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => 'More|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->action = array('link' => 'Historique|project|dynamic|projectID=%s', 'subModule' => 'dynamic', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->view = array('link' => "Vue d'ensemble|project|view|projectID=%s", 'alias' => 'edit,start,suspend,putoff,close');
|
||||
$lang->project->menu->whitelist = array('link' => 'Whitelist|project|whitelist|projectID=%s', 'alias' => 'addwhitelist', 'subModule' => 'personnel');
|
||||
$lang->project->menu->task = array('link' => 'Tâche|project|task|projectID=%s', 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
|
||||
$lang->project->menu->kanban = array('link' => 'Kanban|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => 'Atterrissage|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => 'View|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => "Story|project|story|projectID=%s", 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => 'Build|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => 'Recette|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => 'Doc|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => 'Equipe|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => 'More|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
|
||||
$lang->project->subMenu = new stdclass();
|
||||
$lang->project->subMenu->view = new stdclass();
|
||||
@@ -563,6 +570,9 @@ $lang->admin->subMenu->system = new stdclass();
|
||||
$lang->admin->subMenu->system->cron = array('link' => 'Cron|cron|index', 'subModule' => 'cron');
|
||||
$lang->admin->subMenu->system->timezone = array('link' => 'Timezone|custom|timezone', 'subModule' => 'custom');
|
||||
|
||||
$lang->admin->subMenu->system->buildIndex = array('link' => 'Full Text Search|search|buildindex|');
|
||||
$lang->admin->subMenuOrder->system[15] = 'buildIndex';
|
||||
|
||||
$lang->convert = new stdclass();
|
||||
$lang->upgrade = new stdclass();
|
||||
$lang->action = new stdclass();
|
||||
@@ -622,6 +632,7 @@ $lang->navGroup = new stdclass();
|
||||
$lang->navGroup->my = 'my';
|
||||
$lang->navGroup->todo = 'my';
|
||||
$lang->navGroup->effort = 'my';
|
||||
$lang->navGroup->score = 'my';
|
||||
|
||||
$lang->navGroup->personnel = 'program';
|
||||
|
||||
@@ -1002,6 +1013,6 @@ $lang->projectstory->menu->story = array('link' => "{$lang->SRCommon}|projectsto
|
||||
$lang->projectstory->menu->track = array('link' => 'Track|projectstory|track', 'subModule' => '');
|
||||
|
||||
$lang->nc->menu = $lang->auditplan->menu;
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'product', 'productplan', 'projectbuild', 'projectrelease', 'story', 'job', 'jenkins', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search', 'stage');
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'product', 'productplan', 'projectbuild', 'projectrelease', 'story', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search', 'score', 'stage');
|
||||
|
||||
include (dirname(__FILE__) . '/menuOrder.php');
|
||||
|
||||
+27
-16
@@ -131,6 +131,11 @@ $lang->typeAB = 'Loại';
|
||||
$lang->common = new stdclass();
|
||||
$lang->common->common = 'Module chung';
|
||||
|
||||
global $config;
|
||||
list($programModule, $programMethod) = explode('-', $config->programLink);
|
||||
list($productModule, $productMethod) = explode('-', $config->productLink);
|
||||
list($projectModule, $projectMethod) = explode('-', $config->projectLink);
|
||||
|
||||
/* Main menu. */
|
||||
$lang->mainNav = new stdclass();
|
||||
$lang->mainNav->my = '<i class="icon icon-menu-my"></i> My|my|index|';
|
||||
@@ -220,7 +225,11 @@ $lang->holiday->menu = $lang->subject->menu;
|
||||
$lang->measurement = new stdclass();
|
||||
$lang->measurement->menu = new stdclass();
|
||||
|
||||
$lang->searchTips = '';
|
||||
$lang->searchAB = 'Tìm ki?m';
|
||||
|
||||
/* Object list in search form. */
|
||||
$lang->searchObjects['all'] = 'T?t c?';
|
||||
$lang->searchObjects['bug'] = 'Bug';
|
||||
$lang->searchObjects['story'] = 'Câu chuyện';
|
||||
$lang->searchObjects['task'] = 'Nhiệm vụ';
|
||||
@@ -236,6 +245,7 @@ $lang->searchObjects['testreport'] = 'Test báo cáo';
|
||||
$lang->searchObjects['program'] = 'Program';
|
||||
$lang->searchObjects['project'] = 'Project';
|
||||
$lang->searchObjects['execution'] = $lang->sprintCommon;
|
||||
$lang->searchObjects['user'] = 'User';
|
||||
$lang->searchTips = 'ID (ctrl+g)';
|
||||
|
||||
/* Code formats for import. */
|
||||
@@ -338,21 +348,18 @@ $lang->story->menu = $lang->product->menu;
|
||||
$lang->project = new stdclass();
|
||||
$lang->project->menu = new stdclass();
|
||||
|
||||
$lang->project->menu->task = array('link' => 'Nhiệm vụ|project|task|projectID=%s', 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
|
||||
$lang->project->menu->kanban = array('link' => 'Kanban|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => 'Burndown|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => 'View|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => 'Câu chuyện|project|story|projectID=%s', 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => 'Bản dựng|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => 'Yêu cầu|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => 'Tài liệu|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => 'Đội nhóm|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => 'More|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->action = array('link' => 'Lịch sử|project|dynamic|projectID=%s', 'subModule' => 'dynamic', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->view = array('link' => 'Tổng quan|project|view|projectID=%s', 'alias' => 'edit,start,suspend,putoff,close');
|
||||
$lang->project->menu->whitelist = array('link' => 'Whitelist|project|whitelist|projectID=%s', 'alias' => 'addwhitelist', 'subModule' => 'personnel');
|
||||
$lang->project->menu->task = array('link' => 'Nhiệm vụ|project|task|projectID=%s', 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
|
||||
$lang->project->menu->kanban = array('link' => 'Kanban|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => 'Burndown|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => 'View|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => "Câu chuyện|project|story|projectID=%s", 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => 'Bản dựng|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => 'Yêu cầu|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => 'Tài liệu|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => 'Đội nhóm|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => 'More|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
|
||||
$lang->project->subMenu = new stdclass();
|
||||
$lang->project->subMenu->view = new stdclass();
|
||||
@@ -563,6 +570,9 @@ $lang->admin->subMenu->system = new stdclass();
|
||||
$lang->admin->subMenu->system->cron = array('link' => 'Cron|cron|index', 'subModule' => 'cron');
|
||||
$lang->admin->subMenu->system->timezone = array('link' => 'Timezone|custom|timezone', 'subModule' => 'custom');
|
||||
|
||||
$lang->admin->subMenu->system->buildIndex = array('link' => 'Full Text Search|search|buildindex|');
|
||||
$lang->admin->subMenuOrder->system[15] = 'buildIndex';
|
||||
|
||||
$lang->convert = new stdclass();
|
||||
$lang->upgrade = new stdclass();
|
||||
$lang->action = new stdclass();
|
||||
@@ -622,6 +632,7 @@ $lang->navGroup = new stdclass();
|
||||
$lang->navGroup->my = 'my';
|
||||
$lang->navGroup->todo = 'my';
|
||||
$lang->navGroup->effort = 'my';
|
||||
$lang->navGroup->score = 'my';
|
||||
|
||||
$lang->navGroup->personnel = 'program';
|
||||
|
||||
@@ -1002,6 +1013,6 @@ $lang->projectstory->menu->story = array('link' => "{$lang->SRCommon}|projectsto
|
||||
$lang->projectstory->menu->track = array('link' => 'Track|projectstory|track', 'subModule' => '');
|
||||
|
||||
$lang->nc->menu = $lang->auditplan->menu;
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'product', 'productplan', 'projectbuild', 'projectrelease', 'story', 'job', 'jenkins', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search', 'stage');
|
||||
$lang->noMenuModule = array('my', 'todo', 'effort', 'program', 'product', 'productplan', 'projectbuild', 'projectrelease', 'story', 'branch', 'release', 'attend', 'leave', 'makeup', 'overtime', 'lieu', 'custom', 'admin', 'mail', 'extension', 'dev', 'backup', 'action', 'cron', 'issue', 'risk', 'pssp', 'sms', 'message', 'webhook', 'search', 'score', 'stage');
|
||||
|
||||
include (dirname(__FILE__) . '/menuOrder.php');
|
||||
|
||||
@@ -225,7 +225,11 @@ $lang->holiday->menu = $lang->subject->menu;
|
||||
$lang->measurement = new stdclass();
|
||||
$lang->measurement->menu = new stdclass();
|
||||
|
||||
/* 查询条中可以选择的对象列表。*/
|
||||
$lang->searchTips = '';
|
||||
$lang->searchAB = '搜索';
|
||||
|
||||
/* 查询中可以选择的对象列表。*/
|
||||
$lang->searchObjects['all'] = '全部';
|
||||
$lang->searchObjects['bug'] = 'Bug';
|
||||
$lang->searchObjects['story'] = "{$lang->SRCommon}";
|
||||
$lang->searchObjects['task'] = '任务';
|
||||
@@ -241,6 +245,7 @@ $lang->searchObjects['testreport'] = '测试报告';
|
||||
$lang->searchObjects['program'] = '项目集';
|
||||
$lang->searchObjects['project'] = '项目';
|
||||
$lang->searchObjects['execution'] = $lang->sprintCommon;
|
||||
$lang->searchObjects['user'] = '用户';
|
||||
$lang->searchTips = '编号(ctrl+g)';
|
||||
|
||||
/* 导入支持的编码格式。*/
|
||||
@@ -343,18 +348,18 @@ $lang->story->menu = $lang->product->menu;
|
||||
$lang->project = new stdclass();
|
||||
$lang->project->menu = new stdclass();
|
||||
|
||||
$lang->project->menu->task = array('link' => '任务|project|task|projectID=%s', 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
|
||||
$lang->project->menu->kanban = array('link' => '看板|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => '燃尽图|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => '视图|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => "{$lang->SRCommon}|project|story|projectID=%s", 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => '版本|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => '测试单|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => '文档|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => '团队|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => '更多|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->task = array('link' => '任务|project|task|projectID=%s', 'subModule' => 'task,tree', 'alias' => 'importtask,importbug');
|
||||
$lang->project->menu->kanban = array('link' => '看板|project|kanban|projectID=%s');
|
||||
$lang->project->menu->burn = array('link' => '燃尽图|project|burn|projectID=%s');
|
||||
$lang->project->menu->view = array('link' => '视图|project|grouptask|projectID=%s', 'alias' => 'grouptask,tree', 'class' => 'dropdown dropdown-hover');
|
||||
$lang->project->menu->story = array('link' => "{$lang->SRCommon}|project|story|projectID=%s", 'subModule' => 'story', 'alias' => 'linkstory,storykanban');
|
||||
$lang->project->menu->bug = array('link' => 'Bug|project|bug|projectID=%s');
|
||||
$lang->project->menu->build = array('link' => '版本|project|build|projectID=%s', 'subModule' => 'build');
|
||||
$lang->project->menu->testtask = array('link' => '测试单|project|testtask|projectID=%s', 'subModule' => 'testreport,testtask');
|
||||
$lang->project->menu->doc = array('link' => '文档|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
|
||||
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
|
||||
$lang->project->menu->team = array('link' => '团队|project|team|projectID=%s', 'alias' => 'managemembers');
|
||||
$lang->project->menu->more = array('link' => '更多|project|whitelist|projectID=%s', 'subModule' => 'personnel', 'alias' => 'edit', 'class' => 'dropdown dropdown-hover');
|
||||
|
||||
$lang->project->subMenu = new stdclass();
|
||||
$lang->project->subMenu->view = new stdclass();
|
||||
@@ -565,6 +570,9 @@ $lang->admin->subMenu->system = new stdclass();
|
||||
$lang->admin->subMenu->system->cron = array('link' => '定时|cron|index', 'subModule' => 'cron');
|
||||
$lang->admin->subMenu->system->timezone = array('link' => '时区|custom|timezone', 'subModule' => 'custom');
|
||||
|
||||
$lang->admin->subMenu->system->buildIndex = array('link' => '重建索引|search|buildindex|');
|
||||
$lang->admin->subMenuOrder->system[15] = 'buildIndex';
|
||||
|
||||
$lang->convert = new stdclass();
|
||||
$lang->upgrade = new stdclass();
|
||||
$lang->action = new stdclass();
|
||||
|
||||
+5
-29
@@ -748,45 +748,21 @@ class commonModel extends model
|
||||
*/
|
||||
public static function printSearchBox()
|
||||
{
|
||||
global $app, $config, $lang;
|
||||
$moduleName = $app->getModuleName();
|
||||
$methodName = $app->getMethodName();
|
||||
$searchObject = $moduleName;
|
||||
|
||||
if($moduleName == 'product')
|
||||
{
|
||||
if($methodName == 'browse') $searchObject = 'story';
|
||||
}
|
||||
elseif($moduleName == 'project')
|
||||
{
|
||||
if(strpos('task|story|bug|build', $methodName) !== false) $searchObject = $methodName;
|
||||
}
|
||||
elseif($moduleName == 'my' or $moduleName == 'user')
|
||||
{
|
||||
$searchObject = $methodName;
|
||||
if($methodName == 'execution') $searchObject = 'project';
|
||||
}
|
||||
if(empty($lang->searchObjects[$searchObject])) $searchObject = 'bug';
|
||||
|
||||
echo "<div id='searchbox'>";
|
||||
echo "<div class='input-group'>";
|
||||
global $lang;
|
||||
$searchObject = 'bug';
|
||||
echo "<div class='input-group-btn'>";
|
||||
echo "<a data-toggle='dropdown' class='btn btn-link'><span id='searchTypeName'>" . $lang->searchObjects[$searchObject] . "</span> <span class='caret'></span></a>";
|
||||
echo html::hidden('searchType', $searchObject);
|
||||
echo "<ul id='searchTypeMenu' class='dropdown-menu'>";
|
||||
foreach ($lang->searchObjects as $key => $value)
|
||||
{
|
||||
$class = $key == $searchObject ? "class='selected'" : '';
|
||||
if($key == 'program') $key = 'program-pgmproduct';
|
||||
if($key == 'project') $key = 'program-index';
|
||||
if($key == 'program') $key = 'program-pgmproduct';
|
||||
if($key == 'project') $key = 'program-index';
|
||||
if($key == 'execution') $key = 'project-view';
|
||||
|
||||
echo "<li $class><a href='javascript:$.setSearchType(\"$key\");' data-value='{$key}'>{$value}</a></li>";
|
||||
}
|
||||
echo '</ul></div>';
|
||||
echo "<input id='searchInput' class='form-control search-input' type='search' onclick='this.value=\"\"' onkeydown='if(event.keyCode==13) $.gotoObject();' placeholder='" . $lang->searchTips . "'/>";
|
||||
echo '</div>';
|
||||
echo "<a href='javascript:$.gotoObject();' class='btn btn-link' id='searchGo'>GO!</a>";
|
||||
echo "</div>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -83,6 +83,8 @@ $config->dev->group['repo'] = 'repo';
|
||||
$config->dev->group['repofiles'] = 'repo';
|
||||
$config->dev->group['repohistory'] = 'repo';
|
||||
$config->dev->group['repobranch'] = 'repo';
|
||||
$config->dev->group['searchindex'] = 'search';
|
||||
$config->dev->group['searchdict'] = 'search';
|
||||
|
||||
$config->dev->tableMap['storyspec'] = 'story';
|
||||
$config->dev->tableMap['storystage'] = 'story';
|
||||
@@ -110,6 +112,7 @@ $config->dev->tableMap['suitecase'] = 'testcase';
|
||||
$config->dev->tableMap['repofiles'] = 'repo';
|
||||
$config->dev->tableMap['repohistory'] = 'repo';
|
||||
$config->dev->tableMap['repobranch'] = 'repo';
|
||||
$config->dev->tableMap['searchindex'] = 'search';
|
||||
|
||||
$config->dev->postParams['story']['create']['product'] = 'int';
|
||||
$config->dev->postParams['story']['create']['title'] = 'string';
|
||||
|
||||
@@ -114,6 +114,8 @@ $lang->dev->tableList['ci'] = 'CI';
|
||||
$lang->dev->tableList['compile'] = 'Compile';
|
||||
$lang->dev->tableList['jenkins'] = 'Jenkins';
|
||||
$lang->dev->tableList['job'] = 'Job';
|
||||
$lang->dev->tableList['searchdict'] = 'Search dict';
|
||||
$lang->dev->tableList['searchindex'] = 'Search index';
|
||||
|
||||
$lang->dev->groupList['my'] = 'Dashboard';
|
||||
$lang->dev->groupList['product'] = $lang->productCommon;
|
||||
@@ -125,6 +127,7 @@ $lang->dev->groupList['company'] = 'Unternehmen';
|
||||
$lang->dev->groupList['repo'] = 'CI';
|
||||
$lang->dev->groupList['api'] = 'API';
|
||||
$lang->dev->groupList['message'] = 'Message';
|
||||
$lang->dev->groupList['search'] = 'Search';
|
||||
|
||||
$lang->dev->endGroupList['admin'] = 'Admin';
|
||||
$lang->dev->endGroupList['system'] = 'System';
|
||||
|
||||
@@ -114,6 +114,8 @@ $lang->dev->tableList['ci'] = 'CI';
|
||||
$lang->dev->tableList['compile'] = 'Compile';
|
||||
$lang->dev->tableList['jenkins'] = 'Jenkins';
|
||||
$lang->dev->tableList['job'] = 'Job';
|
||||
$lang->dev->tableList['searchdict'] = 'Search dict';
|
||||
$lang->dev->tableList['searchindex'] = 'Search index';
|
||||
|
||||
$lang->dev->groupList['my'] = 'Dashboard';
|
||||
$lang->dev->groupList['product'] = $lang->productCommon;
|
||||
@@ -125,6 +127,7 @@ $lang->dev->groupList['company'] = 'Company';
|
||||
$lang->dev->groupList['repo'] = 'CI';
|
||||
$lang->dev->groupList['api'] = 'API';
|
||||
$lang->dev->groupList['message'] = 'Message';
|
||||
$lang->dev->groupList['search'] = 'Search';
|
||||
|
||||
$lang->dev->endGroupList['admin'] = 'Admin';
|
||||
$lang->dev->endGroupList['system'] = 'System';
|
||||
|
||||
@@ -114,6 +114,8 @@ $lang->dev->tableList['ci'] = 'CI';
|
||||
$lang->dev->tableList['compile'] = 'Compile';
|
||||
$lang->dev->tableList['jenkins'] = 'Jenkins';
|
||||
$lang->dev->tableList['job'] = 'Job';
|
||||
$lang->dev->tableList['searchdict'] = 'Search dict';
|
||||
$lang->dev->tableList['searchindex'] = 'Search index';
|
||||
|
||||
$lang->dev->groupList['my'] = 'Dashboard';
|
||||
$lang->dev->groupList['product'] = $lang->productCommon;
|
||||
@@ -125,6 +127,7 @@ $lang->dev->groupList['company'] = 'Entreprise';
|
||||
$lang->dev->groupList['repo'] = 'CI';
|
||||
$lang->dev->groupList['api'] = 'API';
|
||||
$lang->dev->groupList['message'] = 'Message';
|
||||
$lang->dev->groupList['search'] = 'Search';
|
||||
|
||||
$lang->dev->endGroupList['admin'] = 'Admin';
|
||||
$lang->dev->endGroupList['system'] = 'Système';
|
||||
|
||||
@@ -114,6 +114,8 @@ $lang->dev->tableList['ci'] = 'CI';
|
||||
$lang->dev->tableList['compile'] = 'Compile';
|
||||
$lang->dev->tableList['jenkins'] = 'Jenkins';
|
||||
$lang->dev->tableList['job'] = 'Job';
|
||||
$lang->dev->tableList['searchdict'] = 'Search dict';
|
||||
$lang->dev->tableList['searchindex'] = 'Search index';
|
||||
|
||||
$lang->dev->groupList['my'] = 'Dashboard';
|
||||
$lang->dev->groupList['product'] = $lang->productCommon;
|
||||
@@ -125,6 +127,7 @@ $lang->dev->groupList['company'] = 'Doanh nghiệp';
|
||||
$lang->dev->groupList['repo'] = 'CI';
|
||||
$lang->dev->groupList['api'] = 'API';
|
||||
$lang->dev->groupList['message'] = 'Tin nhắn';
|
||||
$lang->dev->groupList['search'] = 'Tìm kiếm';
|
||||
|
||||
$lang->dev->endGroupList['admin'] = 'Quản trị';
|
||||
$lang->dev->endGroupList['system'] = 'Hệ thống';
|
||||
|
||||
@@ -114,6 +114,8 @@ $lang->dev->tableList['ci'] = '持续集成';
|
||||
$lang->dev->tableList['compile'] = '构建';
|
||||
$lang->dev->tableList['jenkins'] = 'Jenkins';
|
||||
$lang->dev->tableList['job'] = '构建任务';
|
||||
$lang->dev->tableList['searchdict'] = '搜索字典';
|
||||
$lang->dev->tableList['searchindex'] = '搜索索引';
|
||||
|
||||
$lang->dev->groupList['my'] = '我的地盘';
|
||||
$lang->dev->groupList['product'] = $lang->productCommon;
|
||||
@@ -125,6 +127,7 @@ $lang->dev->groupList['company'] = '组织';
|
||||
$lang->dev->groupList['repo'] = '持续集成';
|
||||
$lang->dev->groupList['api'] = 'API';
|
||||
$lang->dev->groupList['message'] = '消息';
|
||||
$lang->dev->groupList['search'] = '搜索';
|
||||
|
||||
$lang->dev->endGroupList['admin'] = '后台';
|
||||
$lang->dev->endGroupList['system'] = '系统';
|
||||
|
||||
@@ -1370,17 +1370,21 @@ $lang->report->methodOrder[20] = 'workload';
|
||||
|
||||
/* Search. */
|
||||
$lang->resource->search = new stdclass();
|
||||
$lang->resource->search->buildForm = 'buildForm';
|
||||
$lang->resource->search->buildQuery = 'buildQuery';
|
||||
$lang->resource->search->saveQuery = 'saveQuery';
|
||||
$lang->resource->search->deleteQuery = 'deleteQuery';
|
||||
$lang->resource->search->select = 'select';
|
||||
$lang->resource->search->buildForm = 'buildForm';
|
||||
$lang->resource->search->buildQuery = 'buildQuery';
|
||||
$lang->resource->search->saveQuery = 'saveQuery';
|
||||
$lang->resource->search->deleteQuery = 'deleteQuery';
|
||||
$lang->resource->search->select = 'select';
|
||||
$lang->resource->search->index = 'index';
|
||||
$lang->resource->search->buildIndex = 'buildIndex';
|
||||
|
||||
$lang->search->methodOrder[5] = 'buildForm';
|
||||
$lang->search->methodOrder[10] = 'buildQuery';
|
||||
$lang->search->methodOrder[15] = 'saveQuery';
|
||||
$lang->search->methodOrder[20] = 'deleteQuery';
|
||||
$lang->search->methodOrder[25] = 'select';
|
||||
$lang->search->methodOrder[30] = 'index';
|
||||
$lang->search->methodOrder[35] = 'buildIndex';
|
||||
|
||||
/* Admin. */
|
||||
$lang->resource->admin = new stdclass();
|
||||
|
||||
@@ -62,6 +62,10 @@ body.menu-hide {padding-left: 0;}
|
||||
#poweredBy{width: 55%; position: absolute; top: 4px; right: 0; padding: 0;}
|
||||
|
||||
#globalSearchDiv{width:50%; float: right; margin-right: 4px;}
|
||||
@media screen and (max-height: 768px)
|
||||
{
|
||||
#globalSearchDiv{width:60%;}
|
||||
}
|
||||
#globalSearchDiv .input-group{width: 70%; float: right; margin-top: 2px;}
|
||||
#globalSearchInput{height: 28px; padding-left: 10px;}
|
||||
#globalSearchButton{height: 28px;}
|
||||
@@ -70,3 +74,17 @@ body.menu-hide {padding-left: 0;}
|
||||
#globalBarLogo a:first-child{margin-right: 10px;}
|
||||
#globalBarLogo a{float: right; margin: 0px 2px;}
|
||||
#globalBarLogo a .icon{font-size: 24px; color: #16a8f8;}
|
||||
|
||||
#searchbox a {float: left; width: 100%;}
|
||||
#searchbox a:hover {color:white}
|
||||
#searchbox {width: 100%;}
|
||||
#searchbox .dropdown-menu {margin-top: 0px; left: 1px; position: absolute; top: -50px;}
|
||||
#searchbox .dropdown-menu > li > a {padding: 5px 8px}
|
||||
#searchbox .dropdown-menu > li {display: none}
|
||||
#searchbox .dropdown-menu > li.search-type-all {width: 100%; display: block;}
|
||||
#searchbox .dropdown-menu > li:hover {position: relative;}
|
||||
#searchbox .dropdown-menu.show-quick-go.with-active {position: absolute; top: -358px; max-height: 355px; padding-top: 30px;}
|
||||
#searchbox .dropdown-menu.show-quick-go > li {display: block;}
|
||||
#searchbox .dropdown-menu.show-quick-go > li.active {width: 100%; position: absolute; top: 0; left: 0; right: 0;}
|
||||
#searchbox .dropdown-menu>li.active>a, #searchbox .dropdown-menu>li.selected>a { position: relative; color: #fff; background-color: #16a8f8;}
|
||||
#searchbox .dropdown-menu>li.selected>a:after {position: absolute; top: 2px; right: 4px; display: block; font-family: ZentaoIcon; font-size: 18px; font-size: 14px; font-style: normal; font-weight: 400; font-variant: normal; line-height: 1; line-height: 20px; text-transform: none; content: "\e5ca"; speak: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;}
|
||||
|
||||
@@ -499,3 +499,134 @@ function getExecutions()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$.extend({
|
||||
gotoObject:function()
|
||||
{
|
||||
objectType = $('#searchType').attr('value');
|
||||
objectValue = $('input#globalSearchInput').attr('value');
|
||||
|
||||
if(objectType && objectValue)
|
||||
{
|
||||
var reg = /[^0-9]/;
|
||||
if(reg.test(objectValue) || objectType == 'all')
|
||||
{
|
||||
location.href = createLink('search', 'index') + (config.requestType == 'PATH_INFO' ? '?' : '&') + 'words=' + objectValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var types = objectType.split('-');
|
||||
var searchModule = types[0];
|
||||
var searchMethod = typeof(types[1]) == 'undefined' ? 'view' : types[1];
|
||||
|
||||
location.href = createLink(searchModule, searchMethod, "id=" + objectValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* Initialize global search. */
|
||||
$(function()
|
||||
{
|
||||
var reg = /[^0-9]/;
|
||||
var $searchbox = $('#searchbox');
|
||||
var $typeSelector = $searchbox.find('.input-group-btn');
|
||||
var $dropmenu = $typeSelector.children('.dropdown-menu');
|
||||
var $searchQuery = $('#globalSearchInput');
|
||||
var searchType = $('#searchType').val();
|
||||
|
||||
var toggleMenu = function(show)
|
||||
{
|
||||
$searchbox.toggleClass('open', show);
|
||||
$dropmenu.toggleClass('show', show).toggleClass('in', show);
|
||||
if(show) $dropmenu.show();
|
||||
else $dropmenu.hide();
|
||||
};
|
||||
|
||||
var hideMenu = function(){toggleMenu(false);};
|
||||
|
||||
var refreshMenu = function()
|
||||
{
|
||||
var val = $searchQuery.val();
|
||||
var searchType = changeSearchObject();
|
||||
if(val !== null && val !== "")
|
||||
{
|
||||
var isQuickGo = !reg.test(val);
|
||||
$dropmenu.toggleClass('show-quick-go', isQuickGo);
|
||||
var $typeAll = $dropmenu.find('li.search-type-all > a');
|
||||
$typeAll.html(searchAB + ' <span>"' + val + '"</span>');
|
||||
if(isQuickGo)
|
||||
{
|
||||
$typeAll.closest('li').removeClass('active');
|
||||
$dropmenu.removeClass('with-active').find('li:not(.search-type-all) > a').each(function()
|
||||
{
|
||||
var $this = $(this);
|
||||
var isActiveType = $this.data('value') === searchType && searchType !== 'all';
|
||||
$this.closest('li').toggleClass('selected active', isActiveType);
|
||||
$this.html($this.data('name') + ' <span>#' + (val.length > 4 ? (val.substr(0, 4) + '...') : val) + "</span>");
|
||||
if(isActiveType) $dropmenu.addClass('with-active');
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
$dropmenu.find('li.active').removeClass('active');
|
||||
$typeAll.closest('li').addClass('active');
|
||||
}
|
||||
toggleMenu(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
hideMenu();
|
||||
}
|
||||
};
|
||||
|
||||
$dropmenu = $dropmenu.appendTo($searchbox);
|
||||
$dropmenu.on('click', 'a', function(e)
|
||||
{
|
||||
$('#searchType').val($(this).data('value'));
|
||||
$.gotoObject();
|
||||
e.stopPropagation();
|
||||
}).find('li > a').each(function()
|
||||
{
|
||||
var $this = $(this);
|
||||
$this.attr('data-name', $this.text());
|
||||
});
|
||||
|
||||
var $allItem = $dropmenu.find('li > a[data-value="all"]');
|
||||
if($allItem.length)
|
||||
{
|
||||
$allItem.closest('li').addClass('search-type-all').prependTo($dropmenu);
|
||||
}
|
||||
|
||||
$searchQuery.on('change keyup paste input propertychange', refreshMenu).on('focus', function()
|
||||
{
|
||||
setTimeout(refreshMenu, 300);
|
||||
});
|
||||
|
||||
$(document).on('click', hideMenu);
|
||||
});
|
||||
|
||||
/* Change the search object according to the module and method. */
|
||||
function changeSearchObject()
|
||||
{
|
||||
var tabInfo = $.tabs.getLastTab();
|
||||
var tabPageModuleName = tabInfo.$iframe[0].contentWindow.config.currentModule;
|
||||
var tabPageMethodName = tabInfo.$iframe[0].contentWindow.config.currentMethod;
|
||||
|
||||
var searchType = tabPageModuleName;
|
||||
if(tabPageModuleName == 'product' && tabPageMethodName == 'browse') var searchType = 'story';
|
||||
|
||||
var projectMethod = 'task|story|bug|build';
|
||||
if(tabPageModuleName == 'project' && projectMethod.indexOf(tabPageMethodName) != -1) var searchType = tabPageMethodName;
|
||||
|
||||
if(tabPageModuleName == 'my' || tabPageModuleName == 'user') var searchType = tabPageMethodName;
|
||||
|
||||
if(searchObjectList.indexOf(searchType) == -1) var searchType = 'bug';
|
||||
|
||||
if(searchType == 'program') var searchType = 'program-pgmproduct';
|
||||
if(searchType == 'project') var searchType = 'program-index';
|
||||
if(searchType == 'execution') var searchType = 'project-view';
|
||||
|
||||
$("#searchType").val(searchType);
|
||||
return searchType;
|
||||
}
|
||||
|
||||
@@ -56,10 +56,13 @@ js::set('defaultOpen', $open);
|
||||
<!--<a href='javascript:void(0)' class="btn btn-sm btn-link" type="button"><i class="icon icon-message"></i></a>-->
|
||||
<div id="globalSearchDiv">
|
||||
<div class="input-group">
|
||||
<div class="input-control search-box search-box-circle has-icon-left has-icon-right search-example" id="searchboxExample">
|
||||
<input id="globalSearchInput" type="search" class="form-control search-input" placeholder="<?php echo $lang->index->search;?>">
|
||||
<div id='searchbox'>
|
||||
<?php echo common::printSearchBox();?>
|
||||
</div>
|
||||
<span class="input-group-btn">
|
||||
<div class="input-control search-box search-box-circle has-icon-left has-icon-right search-example" id="searchboxExample">
|
||||
<input id="globalSearchInput" type="search" onclick="this.value=''" onkeydown="if(event.keyCode==13) $.gotoObject();" class="form-control search-input" placeholder="<?php echo $lang->index->search;?>" autocomplete="off">
|
||||
</div>
|
||||
<span class="input-group-btn" onclick="javascript:$.gotoObject();">
|
||||
<button id="globalSearchButton" class="btn btn-secondary" type="button"><i class="icon icon-search"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
@@ -67,4 +70,6 @@ js::set('defaultOpen', $open);
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php js::set('searchAB', $lang->searchAB);?>
|
||||
<?php js::set('searchObjectList', implode(',', array_keys($lang->searchObjects)));?>
|
||||
<?php include '../../common/view/footer.lite.html.php';?>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/sortable.html.php';?>
|
||||
<div id="mainMenu" class="clearfix">
|
||||
<?php if(!isonlybody()):?>
|
||||
<div class="btn-toolbar pull-left">
|
||||
<?php foreach($lang->product->featureBar['all'] as $key => $label):?>
|
||||
<?php $active = $key == $browseType ? 'btn-active-text' : '';?>
|
||||
@@ -22,6 +23,7 @@
|
||||
<div class="btn-toolbar pull-right">
|
||||
<?php common::printLink('product', 'create', "programID=$program->id", '<i class="icon icon-plus"></i>' . $lang->product->create, '', 'class="btn btn-primary"');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<div id="mainContent" class="main-row fade">
|
||||
<?php if(empty($products)):?>
|
||||
@@ -33,7 +35,7 @@
|
||||
<form class="main-table table-product" data-ride="table" id="productListForm" method="post" action='<?php echo $this->createLink('product', 'batchEdit', "programID=$program->id");?>'>
|
||||
<?php $canOrder = common::hasPriv('product', 'updateOrder');?>
|
||||
<?php $canBatchEdit = common::hasPriv('product', 'batchEdit');?>
|
||||
<table id="productList" class="table has-sort-head table-fixed">
|
||||
<table id="productList" class="table has-sort-head table-bordered table-fixed">
|
||||
<?php $vars = "programID=$program->id&browseType=$browseType&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
|
||||
<thead>
|
||||
<tr class="text-center">
|
||||
|
||||
@@ -8,3 +8,138 @@ $config->search->dynamic['$lastWeek'] = '$lastWeek';
|
||||
$config->search->dynamic['$thisWeek'] = '$thisWeek';
|
||||
$config->search->dynamic['$yesterday'] = '$yesterday';
|
||||
$config->search->dynamic['$today'] = '$today';
|
||||
|
||||
$config->search->buildAction = ',created,opened,changed,edited,deleted,undeleted,erased,';
|
||||
|
||||
$config->search->fields = new stdclass();
|
||||
$config->search->fields->bug = new stdclass();
|
||||
$config->search->fields->bug->id = 'id';
|
||||
$config->search->fields->bug->title = 'title';
|
||||
$config->search->fields->bug->content = 'steps,keywords,resolvedBuild';
|
||||
$config->search->fields->bug->addedDate = 'openedDate';
|
||||
$config->search->fields->bug->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->build = new stdclass();
|
||||
$config->search->fields->build->id = 'id';
|
||||
$config->search->fields->build->title = 'name';
|
||||
$config->search->fields->build->content = 'desc,filePath,scmPath';
|
||||
$config->search->fields->build->addedDate = 'date';
|
||||
$config->search->fields->build->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->case = new stdclass();
|
||||
$config->search->fields->case->id = 'id';
|
||||
$config->search->fields->case->title = 'title';
|
||||
$config->search->fields->case->content = 'precondition,desc,expect';
|
||||
$config->search->fields->case->addedDate = 'openedDate';
|
||||
$config->search->fields->case->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->doc = new stdclass();
|
||||
$config->search->fields->doc->id = 'id';
|
||||
$config->search->fields->doc->title = 'title';
|
||||
$config->search->fields->doc->content = 'digest,keywords,content';
|
||||
$config->search->fields->doc->addedDate = 'addedDate';
|
||||
$config->search->fields->doc->editedDate = 'editedDate';
|
||||
|
||||
$config->search->fields->product = new stdclass();
|
||||
$config->search->fields->product->id = 'id';
|
||||
$config->search->fields->product->title = 'name';
|
||||
$config->search->fields->product->content = 'code,desc';
|
||||
$config->search->fields->product->addedDate = 'createdDate';
|
||||
$config->search->fields->product->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->productplan = new stdclass();
|
||||
$config->search->fields->productplan->id = 'id';
|
||||
$config->search->fields->productplan->title = 'title';
|
||||
$config->search->fields->productplan->content = 'desc';
|
||||
$config->search->fields->productplan->addedDate = 'addedDate';
|
||||
$config->search->fields->productplan->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->project = new stdclass();
|
||||
$config->search->fields->project->id = 'id';
|
||||
$config->search->fields->project->title = 'name';
|
||||
$config->search->fields->project->content = 'code,desc';
|
||||
$config->search->fields->project->addedDate = 'openedDate';
|
||||
$config->search->fields->project->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->release = new stdclass();
|
||||
$config->search->fields->release->id = 'id';
|
||||
$config->search->fields->release->title = 'name';
|
||||
$config->search->fields->release->content = 'desc';
|
||||
$config->search->fields->release->addedDate = 'addedDate';
|
||||
$config->search->fields->release->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->story = new stdclass();
|
||||
$config->search->fields->story->id = 'id';
|
||||
$config->search->fields->story->title = 'title';
|
||||
$config->search->fields->story->content = 'keywords,spec,verify';
|
||||
$config->search->fields->story->addedDate = 'openedDate';
|
||||
$config->search->fields->story->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->task = new stdclass();
|
||||
$config->search->fields->task->id = 'id';
|
||||
$config->search->fields->task->title = 'name';
|
||||
$config->search->fields->task->content = 'desc';
|
||||
$config->search->fields->task->addedDate = 'openedDate';
|
||||
$config->search->fields->task->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->testtask = new stdclass();
|
||||
$config->search->fields->testtask->id = 'id';
|
||||
$config->search->fields->testtask->title = 'name';
|
||||
$config->search->fields->testtask->content = 'desc,report';
|
||||
$config->search->fields->testtask->addedDate = 'addedDate';
|
||||
$config->search->fields->testtask->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->todo = new stdclass();
|
||||
$config->search->fields->todo->id = 'id';
|
||||
$config->search->fields->todo->title = 'name';
|
||||
$config->search->fields->todo->content = 'desc';
|
||||
$config->search->fields->todo->addedDate = 'date';
|
||||
$config->search->fields->todo->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->effort = new stdclass();
|
||||
$config->search->fields->effort->id = 'id';
|
||||
$config->search->fields->effort->title = 'work';
|
||||
$config->search->fields->effort->content = '';
|
||||
$config->search->fields->effort->addedDate = 'date';
|
||||
$config->search->fields->effort->editedDate = 'date';
|
||||
|
||||
$config->search->fields->testsuite = new stdclass();
|
||||
$config->search->fields->testsuite->id = 'id';
|
||||
$config->search->fields->testsuite->title = 'name';
|
||||
$config->search->fields->testsuite->content = 'desc';
|
||||
$config->search->fields->testsuite->addedDate = 'addedDate';
|
||||
$config->search->fields->testsuite->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->caselib = new stdclass();
|
||||
$config->search->fields->caselib->id = 'id';
|
||||
$config->search->fields->caselib->title = 'name';
|
||||
$config->search->fields->caselib->content = 'desc';
|
||||
$config->search->fields->caselib->addedDate = 'addedDate';
|
||||
$config->search->fields->caselib->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->testreport = new stdclass();
|
||||
$config->search->fields->testreport->id = 'id';
|
||||
$config->search->fields->testreport->title = 'title';
|
||||
$config->search->fields->testreport->content = 'report';
|
||||
$config->search->fields->testreport->addedDate = 'createdDate';
|
||||
$config->search->fields->testreport->editedDate = 'createdDate';
|
||||
|
||||
$config->search->fields->program = new stdclass();
|
||||
$config->search->fields->program->id = 'id';
|
||||
$config->search->fields->program->title = 'name';
|
||||
$config->search->fields->program->content = 'code,desc';
|
||||
$config->search->fields->program->addedDate = 'openedDate';
|
||||
$config->search->fields->program->editedDate = 'lastEditedDate';
|
||||
|
||||
$config->search->fields->execution = new stdclass();
|
||||
$config->search->fields->execution->id = 'id';
|
||||
$config->search->fields->execution->title = 'name';
|
||||
$config->search->fields->execution->content = 'code,desc';
|
||||
$config->search->fields->execution->addedDate = 'openedDate';
|
||||
$config->search->fields->execution->editedDate = 'lastEditedDate';
|
||||
|
||||
/* Set the recPerPage of search. */
|
||||
$config->search->recPerPage = 10;
|
||||
|
||||
/* Set the length of summary of search results. */
|
||||
$config->search->summaryLength = 120;
|
||||
|
||||
@@ -130,4 +130,99 @@ class search extends control
|
||||
{
|
||||
$this->dao->update(TABLE_USERQUERY)->set('shortcut')->eq(0)->where('id')->eq($queryID)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build All index.
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function buildIndex($type = '', $lastID = 0)
|
||||
{
|
||||
if(helper::isAjaxRequest())
|
||||
{
|
||||
$result = $this->search->buildAllIndex($type, $lastID);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
if(isset($result['finished']) and $result['finished'])
|
||||
{
|
||||
$this->send(array('result' => 'finished', 'message' => $this->lang->search->buildSuccessfully));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->send(array('result' => 'unfinished', 'message' => sprintf($this->lang->search->buildResult, zget($this->lang->searchObjects, ($result['type'] == 'case' ? 'testcase' : $result['type']), $result['type']), $result['count']),'next' => inlink('buildIndex', "type={$result['type']}&lastID={$result['lastID']}") ));
|
||||
}
|
||||
}
|
||||
|
||||
$this->lang->search->menu = $this->lang->admin->menu;
|
||||
$this->lang->menugroup->search = 'admin';
|
||||
|
||||
$this->view->title = $this->lang->search->buildIndex;
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* index
|
||||
*
|
||||
* @param int $recTotal
|
||||
* @param int $pageID
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function index($recTotal = 0, $pageID = 1)
|
||||
{
|
||||
$this->lang->admin->menu->search = "{$this->lang->search->common}|search|index";
|
||||
|
||||
if(empty($words)) $words = $this->get->words;
|
||||
if(empty($words)) $words = $this->post->words;
|
||||
if(empty($words) and ($recTotal != 0 or $pageID != 1)) $words = $this->session->searchIngWord;
|
||||
$words = strip_tags(strtolower($words));
|
||||
|
||||
if(empty($type)) $type = $this->get->type;
|
||||
if(empty($type)) $type = $this->post->type;
|
||||
if(empty($type) and ($recTotal != 0 or $pageID != 1)) $type = $this->session->searchIngType;
|
||||
$type = (empty($type) or $type[0] == 'all') ? 'all' : $type;
|
||||
|
||||
$this->app->loadClass('pager', $static = true);
|
||||
$pager = new pager($recTotal, $this->config->search->recPerPage, $pageID);
|
||||
|
||||
/* Set session. */
|
||||
$uri = inlink('index', "recTotal=$recTotal&pageID=$pageID");
|
||||
$uri .= strpos($uri, '?') === false ? '?' : '&';
|
||||
$uri .= 'words=' . $words;
|
||||
$this->session->set('bugList', $uri);
|
||||
$this->session->set('buildList', $uri);
|
||||
$this->session->set('caseList', $uri);
|
||||
$this->session->set('docList', $uri);
|
||||
$this->session->set('productList', $uri);
|
||||
$this->session->set('productPlanList', $uri);
|
||||
$this->session->set('projectList', $uri);
|
||||
$this->session->set('releaseList', $uri);
|
||||
$this->session->set('storyList', $uri);
|
||||
$this->session->set('taskList', $uri);
|
||||
$this->session->set('testtaskList', $uri);
|
||||
$this->session->set('todoList', $uri);
|
||||
$this->session->set('effortList', $uri);
|
||||
$this->session->set('reportList', $uri);
|
||||
$this->session->set('testsuiteList', $uri);
|
||||
$this->session->set('searchIngWord', $words);
|
||||
$this->session->set('searchIngType', $type);
|
||||
|
||||
$begin = time();
|
||||
$this->view->results = $this->search->getList($words, $pager, $type);
|
||||
|
||||
if(strpos($this->server->http_referer, 'search') === false)
|
||||
{
|
||||
$this->session->set('referer', $this->server->http_referer);
|
||||
}
|
||||
|
||||
$this->view->consumed = time() - $begin;
|
||||
$this->view->title = $this->lang->search->index;
|
||||
$this->view->type = $type;
|
||||
$this->view->pager = $pager;
|
||||
$this->view->words = $words;
|
||||
$this->view->referer = $this->session->referer;
|
||||
|
||||
$this->display();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
.execute-info{position:relative; top:5px;}
|
||||
#type_chosen .chosen-drop{width:150px;}
|
||||
.table-footer .pager{margin:0px; height:30px; padding-top:10px;}
|
||||
.table-footer .pager .icon-play.icon-flip-horizontal:before{content:"\e314";}
|
||||
.table-footer .pager .icon-play:before{content:"\e315";}
|
||||
.modal.with-titlebar .modal-header{margin-bottom:10px;}
|
||||
.modal.with-titlebar .modal-header .modal-title{display:block;}
|
||||
|
||||
.list {color: #333; background-color: #fff; border: solid #DDD 1px; border-radius: 3px;}
|
||||
.list > header
|
||||
{
|
||||
padding: 8px 15px;
|
||||
border-bottom: solid #DDD 1px;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
background-color: #F5F5F5;
|
||||
color: #333;
|
||||
background-image: -moz-linear-gradient(top,#fbfbfb 0%,#f2f2f2 100%);
|
||||
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#fbfbfb),color-stop(100%,#f2f2f2));
|
||||
background-image: -webkit-linear-gradient(top,#fbfbfb 0%,#f2f2f2 100%);
|
||||
background-image: -o-linear-gradient(top,#fbfbfb 0%,#f2f2f2 100%);
|
||||
background-image: linear-gradient(top,#fbfbfb 0%,#f2f2f2 100%);
|
||||
}
|
||||
.list > header h2 {font-size: 14px; font-weight: bold; margin: 0; padding: 0; line-height: 20px;}
|
||||
.list-condensed > .items > .item {padding: 10px 15px; border-bottom: 1px solid #e5e5e5; transition: all .5s cubic-bezier(.175,.885,.32,1);}
|
||||
.items .item .text-muted{color: #757575;}
|
||||
.items .item-heading h4{margin-top: 5px; font-size:14px; line-height:1.5; font-weight:normal}
|
||||
.item:hover{background-color:#f5f5f5}
|
||||
|
||||
.modal-iframe .modal-content .modal-header{margin:0px;}
|
||||
.modal-iframe .modal-content .modal-header .modal-title{position:absolute; right:45px; background:#F8FAFE; height:45px; padding:8px 0px; width:200px; text-align:right;}
|
||||
.modal-iframe .modal-content .modal-header .modal-title .icon-eye-open{display:none}
|
||||
.modal-iframe .modal-content .modal-header .modal-title a.btn{border-color: transparent; background:none; padding: 0px; border-radius: 2px; color: #036; padding:4px 7px;;}
|
||||
.modal-iframe .modal-content .modal-header .modal-title a.btn .icon-eye-open{display:inline;}
|
||||
.input-group-btn.goback{padding-left:10px;}
|
||||
.input-group-btn.select{min-width:60px;margin-left:-2px;}
|
||||
.input-group .chosen-container {min-width: 250px; }
|
||||
#words {border-right-width: 0px}
|
||||
#submit {border: 0px;}
|
||||
@@ -0,0 +1,23 @@
|
||||
$(document).ready(function()
|
||||
{
|
||||
$('#execButton').click(function()
|
||||
{
|
||||
$('#execButton').hide();
|
||||
|
||||
$.getJSON($(this).attr('href'), function(response)
|
||||
{
|
||||
if(response.result == 'finished')
|
||||
{
|
||||
$('#resultBox').append("<li class='text-success'>" + response.message + "</li>");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#execButton').attr('href', response.next);
|
||||
$('#resultBox').append("<li class='text-success'>" + response.message + "</li>");
|
||||
return $('#execButton').click();
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
})
|
||||
@@ -51,3 +51,41 @@ $lang->search->null = 'Null';
|
||||
|
||||
$lang->userquery = new stdclass();
|
||||
$lang->userquery->title = 'Title';
|
||||
|
||||
$lang->searchObjects['todo'] = 'Todo';
|
||||
$lang->searchObjects['effort'] = 'Effort';
|
||||
$lang->searchObjects['testsuite'] = 'Test Suite';
|
||||
|
||||
$lang->search->objectType = 'Object Type';
|
||||
$lang->search->objectID = 'Object ID';
|
||||
$lang->search->content = 'Content';
|
||||
$lang->search->addedDate = 'Added';
|
||||
|
||||
$lang->search->index = 'Full Text Search';
|
||||
$lang->search->buildIndex = 'Rebuild Index';
|
||||
$lang->search->preview = 'Preview';
|
||||
|
||||
$lang->search->result = 'Search Results';
|
||||
$lang->search->buildSuccessfully = 'Search index initialized.';
|
||||
$lang->search->executeInfo = '%s search results for you in %s seconds.';
|
||||
$lang->search->buildResult = 'Created index %s and added %s records.';
|
||||
|
||||
$lang->search->modules['all'] = 'All';
|
||||
$lang->search->modules['task'] = 'Task';
|
||||
$lang->search->modules['bug'] = 'Bug';
|
||||
$lang->search->modules['case'] = 'Case';
|
||||
$lang->search->modules['doc'] = 'Doc';
|
||||
$lang->search->modules['todo'] = 'Todo';
|
||||
$lang->search->modules['build'] = 'Build';
|
||||
$lang->search->modules['effort'] = 'Effort';
|
||||
$lang->search->modules['caselib'] = 'CaseLib';
|
||||
$lang->search->modules['product'] = $lang->productCommon;
|
||||
$lang->search->modules['release'] = 'Release';
|
||||
$lang->search->modules['testtask'] = 'Test Request';
|
||||
$lang->search->modules['testsuite'] = 'Test Suite';
|
||||
$lang->search->modules['testreport'] = 'Testing Report';
|
||||
$lang->search->modules['productplan'] = 'Plan';
|
||||
$lang->search->modules['program'] = 'Program';
|
||||
$lang->search->modules['project'] = 'Project';
|
||||
$lang->search->modules['execution'] = 'Iteration/Phase';
|
||||
$lang->search->modules['story'] = 'US/SR';
|
||||
|
||||
@@ -51,3 +51,41 @@ $lang->search->null = 'Null';
|
||||
|
||||
$lang->userquery = new stdclass();
|
||||
$lang->userquery->title = 'Title';
|
||||
|
||||
$lang->searchObjects['todo'] = 'Todo';
|
||||
$lang->searchObjects['effort'] = 'Effort';
|
||||
$lang->searchObjects['testsuite'] = 'Test Suite';
|
||||
|
||||
$lang->search->objectType = 'Object Type';
|
||||
$lang->search->objectID = 'Object ID';
|
||||
$lang->search->content = 'Content';
|
||||
$lang->search->addedDate = 'Added';
|
||||
|
||||
$lang->search->index = 'Full Text Search';
|
||||
$lang->search->buildIndex = 'Rebuild Index';
|
||||
$lang->search->preview = 'Preview';
|
||||
|
||||
$lang->search->result = 'Search Results';
|
||||
$lang->search->buildSuccessfully = 'Search index initialized.';
|
||||
$lang->search->executeInfo = '%s search results for you in %s seconds.';
|
||||
$lang->search->buildResult = 'Created index %s and added %s records.';
|
||||
|
||||
$lang->search->modules['all'] = 'All';
|
||||
$lang->search->modules['task'] = 'Task';
|
||||
$lang->search->modules['bug'] = 'Bug';
|
||||
$lang->search->modules['case'] = 'Case';
|
||||
$lang->search->modules['doc'] = 'Doc';
|
||||
$lang->search->modules['todo'] = 'Todo';
|
||||
$lang->search->modules['build'] = 'Build';
|
||||
$lang->search->modules['effort'] = 'Effort';
|
||||
$lang->search->modules['caselib'] = 'CaseLib';
|
||||
$lang->search->modules['product'] = $lang->productCommon;
|
||||
$lang->search->modules['release'] = 'Release';
|
||||
$lang->search->modules['testtask'] = 'Test Request';
|
||||
$lang->search->modules['testsuite'] = 'Test Suite';
|
||||
$lang->search->modules['testreport'] = 'Testing Report';
|
||||
$lang->search->modules['productplan'] = 'Plan';
|
||||
$lang->search->modules['program'] = 'Program';
|
||||
$lang->search->modules['project'] = 'Project';
|
||||
$lang->search->modules['execution'] = 'Iteration/Phase';
|
||||
$lang->search->modules['story'] = 'US/SR';
|
||||
|
||||
@@ -51,3 +51,41 @@ $lang->search->null = 'Null';
|
||||
|
||||
$lang->userquery = new stdclass();
|
||||
$lang->userquery->title = 'Title';
|
||||
|
||||
$lang->searchObjects['todo'] = 'Todo';
|
||||
$lang->searchObjects['effort'] = 'Effort';
|
||||
$lang->searchObjects['testsuite'] = 'Test Suite';
|
||||
|
||||
$lang->search->objectType = 'Object Type';
|
||||
$lang->search->objectID = 'Object ID';
|
||||
$lang->search->content = 'Content';
|
||||
$lang->search->addedDate = 'Added';
|
||||
|
||||
$lang->search->index = 'Full Text Search';
|
||||
$lang->search->buildIndex = 'Rebuild Index';
|
||||
$lang->search->preview = 'Preview';
|
||||
|
||||
$lang->search->result = 'Search Results';
|
||||
$lang->search->buildSuccessfully = 'Search index initialized.';
|
||||
$lang->search->executeInfo = '%s search results for you in %s seconds.';
|
||||
$lang->search->buildResult = 'Created index %s and added %s records.';
|
||||
|
||||
$lang->search->modules['all'] = 'All';
|
||||
$lang->search->modules['task'] = 'Task';
|
||||
$lang->search->modules['bug'] = 'Bug';
|
||||
$lang->search->modules['case'] = 'Case';
|
||||
$lang->search->modules['doc'] = 'Doc';
|
||||
$lang->search->modules['todo'] = 'Todo';
|
||||
$lang->search->modules['build'] = 'Build';
|
||||
$lang->search->modules['effort'] = 'Effort';
|
||||
$lang->search->modules['caselib'] = 'CaseLib';
|
||||
$lang->search->modules['product'] = $lang->productCommon;
|
||||
$lang->search->modules['release'] = 'Release';
|
||||
$lang->search->modules['testtask'] = 'Test Request';
|
||||
$lang->search->modules['testsuite'] = 'Test Suite';
|
||||
$lang->search->modules['testreport'] = 'Testing Report';
|
||||
$lang->search->modules['productplan'] = 'Plan';
|
||||
$lang->search->modules['program'] = 'Program';
|
||||
$lang->search->modules['project'] = 'Project';
|
||||
$lang->search->modules['execution'] = 'Iteration/Phase';
|
||||
$lang->search->modules['story'] = 'US/SR';
|
||||
|
||||
@@ -51,3 +51,41 @@ $lang->search->null = 'Null';
|
||||
|
||||
$lang->userquery = new stdclass();
|
||||
$lang->userquery->title = 'Title';
|
||||
|
||||
$lang->searchObjects['todo'] = 'Việc làm';
|
||||
$lang->searchObjects['effort'] = 'Chấm công';
|
||||
$lang->searchObjects['testsuite'] = 'Test Suite';
|
||||
|
||||
$lang->search->objectType = 'Loại đối tượng';
|
||||
$lang->search->objectID = 'ID đối tượng';
|
||||
$lang->search->content = 'Nội dung';
|
||||
$lang->search->addedDate = 'Ngày thêm';
|
||||
|
||||
$lang->search->index = 'Full Text Search';
|
||||
$lang->search->buildIndex = 'Rebuild Index';
|
||||
$lang->search->preview = 'Preview';
|
||||
|
||||
$lang->search->result = 'Kết quả tìm kiếm';
|
||||
$lang->search->buildSuccessfully = 'Tìm kiếm khởi tạo chỉ mục.';
|
||||
$lang->search->executeInfo = '%s kết quả tìm kiếm trong %s giây';
|
||||
$lang->search->buildResult = 'Chỉ mục được tao %s và được thêm %s mục';
|
||||
|
||||
$lang->search->modules['all'] = 'Tất cả';
|
||||
$lang->search->modules['task'] = 'Nhiệm vụ';
|
||||
$lang->search->modules['bug'] = 'Bug';
|
||||
$lang->search->modules['case'] = 'Tình huống';
|
||||
$lang->search->modules['doc'] = 'Tài liệu';
|
||||
$lang->search->modules['todo'] = 'Việc làm';
|
||||
$lang->search->modules['build'] = 'Bản dựng';
|
||||
$lang->search->modules['effort'] = 'Chấm công';
|
||||
$lang->search->modules['caselib'] = 'CaseLib';
|
||||
$lang->search->modules['product'] = $lang->productCommon;
|
||||
$lang->search->modules['release'] = 'Phát hành';
|
||||
$lang->search->modules['testtask'] = 'Yêu cầu Test';
|
||||
$lang->search->modules['testsuite'] = 'Test Suite';
|
||||
$lang->search->modules['testreport'] = 'Báo cáo Test';
|
||||
$lang->search->modules['productplan'] = 'Kế hoạch';
|
||||
$lang->search->modules['program'] = 'Program';
|
||||
$lang->search->modules['project'] = 'Project';
|
||||
$lang->search->modules['execution'] = 'Iteration/Phase';
|
||||
$lang->search->modules['story'] = 'US/SR';
|
||||
|
||||
@@ -51,3 +51,41 @@ $lang->search->null = '空';
|
||||
|
||||
$lang->userquery = new stdclass();
|
||||
$lang->userquery->title = '标题';
|
||||
|
||||
$lang->searchObjects['todo'] = '待办';
|
||||
$lang->searchObjects['effort'] = '日志';
|
||||
$lang->searchObjects['testsuite'] = '套件';
|
||||
|
||||
$lang->search->objectType = '对象类型';
|
||||
$lang->search->objectID = '对象编号';
|
||||
$lang->search->content = '内容';
|
||||
$lang->search->addedDate = '添加时间';
|
||||
|
||||
$lang->search->index = '全文检索';
|
||||
$lang->search->buildIndex = '重建索引';
|
||||
$lang->search->preview = '预览';
|
||||
|
||||
$lang->search->result = '搜索结果';
|
||||
$lang->search->buildSuccessfully = '初始化搜索索引成功';
|
||||
$lang->search->executeInfo = '为您找到相关结果%s个,耗时%s秒';
|
||||
$lang->search->buildResult = '创建 %s 索引, 新增 %s 条记录;';
|
||||
|
||||
$lang->search->modules['all'] = '全部';
|
||||
$lang->search->modules['task'] = '任务';
|
||||
$lang->search->modules['bug'] = 'Bug';
|
||||
$lang->search->modules['case'] = '用例';
|
||||
$lang->search->modules['doc'] = '文档';
|
||||
$lang->search->modules['todo'] = '待办';
|
||||
$lang->search->modules['build'] = 'Build';
|
||||
$lang->search->modules['effort'] = '日志';
|
||||
$lang->search->modules['caselib'] = '测试库';
|
||||
$lang->search->modules['product'] = $lang->productCommon;
|
||||
$lang->search->modules['release'] = '发布';
|
||||
$lang->search->modules['testtask'] = '测试单';
|
||||
$lang->search->modules['testsuite'] = '测试套件';
|
||||
$lang->search->modules['testreport'] = '报告';
|
||||
$lang->search->modules['productplan'] = '计划';
|
||||
$lang->search->modules['program'] = '项目集';
|
||||
$lang->search->modules['project'] = '项目';
|
||||
$lang->search->modules['execution'] = '迭代/阶段';
|
||||
$lang->search->modules['story'] = '用需/软需';
|
||||
|
||||
@@ -491,4 +491,546 @@ class searchModel extends model
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* get search results of keywords.
|
||||
*
|
||||
* @param string $keywords
|
||||
* @param object $pager
|
||||
* @param string $type
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function getList($keywords, $pager, $type)
|
||||
{
|
||||
$spliter = $this->app->loadClass('spliter');
|
||||
$words = explode(' ', self::unify($keywords, ' '));
|
||||
|
||||
$against = '';
|
||||
$againstCond = '';
|
||||
$likeCondition = '';
|
||||
foreach($words as $word)
|
||||
{
|
||||
$splitedWords = $spliter->utf8Split($word);
|
||||
|
||||
$trimedWord = trim($splitedWords['words']);
|
||||
$against .= '"' . $trimedWord . '" ';
|
||||
$againstCond .= '+"' . $trimedWord . '" ';
|
||||
if(is_numeric($word) and strlen($word) == 5) $againstCond .= "-\" $word \" ";
|
||||
|
||||
$likeWord = is_numeric($word) ? $word : $trimedWord;
|
||||
if(is_numeric($word) and strlen($word) < 5) $likeWord = str_pad("|$likeWord|", 5, '_');
|
||||
$condition = "OR title like '%{$likeWord}%' OR content like '%{$likeWord}%'";
|
||||
if(is_numeric($word) and strlen($word) == 5) $condition = "OR title REGEXP '[^ ]{$likeWord}[^ ]' OR content REGEXP '[^ ]{$likeWord}[^ ]'";
|
||||
$likeCondition .= $condition;
|
||||
}
|
||||
|
||||
$words = str_replace('"', '', $against);
|
||||
$words = str_pad($words, 5, '_');
|
||||
|
||||
$allowedObject = array();
|
||||
if($type != 'all')
|
||||
{
|
||||
foreach($type as $module) $allowedObject[] = $module;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($this->config->search->fields as $objectType => $fields)
|
||||
{
|
||||
$module = $objectType;
|
||||
if($module == 'case') $module = 'testcase';
|
||||
if(common::hasPriv($module, 'view')) $allowedObject[] = $objectType;
|
||||
if($module == 'caselib' and common::hasPriv('caselib', 'view')) $allowedObject[] = $objectType;
|
||||
}
|
||||
}
|
||||
|
||||
$scoreColumn = "((1 * (MATCH(title) AGAINST('{$against}' IN BOOLEAN MODE))) + (0.6 * (MATCH(content) AGAINST('{$against}' IN BOOLEAN MODE))) )";
|
||||
$results = $this->dao->select("*, {$scoreColumn} as score")
|
||||
->from(TABLE_SEARCHINDEX)
|
||||
->where("(MATCH(title) AGAINST('{$againstCond}' IN BOOLEAN MODE) >= 1 or MATCH(content) AGAINST('{$againstCond}' IN BOOLEAN MODE) >= 1 $likeCondition)")
|
||||
->andWhere('objectType')->in($allowedObject)
|
||||
->andWhere('addedDate')->le(helper::now())
|
||||
->orderBy('score_desc, editedDate_desc')
|
||||
->page($pager)
|
||||
->fetchAll('id');
|
||||
|
||||
foreach($results as $record)
|
||||
{
|
||||
$record->title = str_replace('</span> ', '</span>', $this->decode($this->markKeywords($record->title, $words)));
|
||||
$record->title = str_replace('_', '', $record->title);
|
||||
$record->summary = str_replace('</span> ', '</span>', $this->getSummary($record->content, $words));
|
||||
$record->summary = str_replace('_', '', $record->summary);
|
||||
|
||||
$module = $record->objectType == 'case' ? 'testcase' : $record->objectType;
|
||||
$method = 'view';
|
||||
if($module == 'deploystep')
|
||||
{
|
||||
$module = 'deploy';
|
||||
$method = 'viewstep';
|
||||
}
|
||||
$record->url = helper::createLink($module, $method, "id={$record->objectID}");
|
||||
}
|
||||
|
||||
foreach($results as $object)
|
||||
{
|
||||
if($object->objectType == 'program') $object->url = str_replace('m=program&f=view&', 'm=program&f=view&', $object->url);
|
||||
if($object->objectType == 'project') $object->url = str_replace('m=project&f=view&', 'm=program&f=index&', $object->url);
|
||||
if($object->objectType == 'execution') $object->url = str_replace('m=execution&f=view&', 'm=project&f=view&', $object->url);
|
||||
}
|
||||
|
||||
return $this->checkPriv($results, $pager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an index item.
|
||||
*
|
||||
* @param string $objectType article|blog|page|product|thread|reply|
|
||||
* @param int $objectID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function saveIndex($objectType, $object)
|
||||
{
|
||||
$fields = $this->config->search->fields->{$objectType};
|
||||
if(empty($fields)) return true;
|
||||
|
||||
$index = new stdclass();
|
||||
$index->objectID = $object->{$fields->id};
|
||||
$index->objectType = $objectType;
|
||||
$index->title = $object->{$fields->title};
|
||||
$index->addedDate = isset($object->{$fields->addedDate}) ? $object->{$fields->addedDate} : '0000-00-00 00:00:00';
|
||||
$index->editedDate = isset($object->{$fields->editedDate}) ? $object->{$fields->editedDate} : '0000-00-00 00:00:00';
|
||||
|
||||
$index->content = '';
|
||||
$contentFields = explode(',', $fields->content . ',comment');
|
||||
foreach($contentFields as $field)
|
||||
{
|
||||
if(empty($field)) continue;
|
||||
$index->content .= $object->$field;
|
||||
}
|
||||
|
||||
$spliter = $this->app->loadClass('spliter');
|
||||
|
||||
$titleSplited = $spliter->utf8Split($index->title);
|
||||
$index->title = $titleSplited['words'];
|
||||
$contentSplited = $spliter->utf8Split(strip_tags($index->content));
|
||||
$index->content = $contentSplited['words'];
|
||||
|
||||
$this->saveDict($titleSplited['dict'] + $contentSplited['dict']);
|
||||
$this->dao->replace(TABLE_SEARCHINDEX)->data($index)->exec();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save dict info.
|
||||
*
|
||||
* @param array $words
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function saveDict($dict)
|
||||
{
|
||||
foreach($dict as $key => $value)
|
||||
{
|
||||
if(!is_numeric($key) or empty($value) or strlen($key) != 5) continue;
|
||||
$this->dao->replace(TABLE_SEARCHDICT)->data(array('key' => $key, 'value' => $value))->exec();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer unicode to words.
|
||||
*
|
||||
* @param string $string
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function decode($string)
|
||||
{
|
||||
static $dict;
|
||||
if(empty($dict))
|
||||
{
|
||||
$dict = $this->dao->select("concat(`key`, ' ') as `key`, value")->from(TABLE_SEARCHDICT)->fetchPairs();
|
||||
$dict['|'] = '';
|
||||
}
|
||||
if(strpos($string, ' ') === false) return zget($dict, $string . ' ');
|
||||
return trim(str_replace(array_keys($dict), array_values($dict), $string . ' '));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summary of results.
|
||||
*
|
||||
* @param string $content
|
||||
* @param string $words
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
public function getSummary($content, $words)
|
||||
{
|
||||
$length = $this->config->search->summaryLength;
|
||||
if(strlen($content) <= $length) return $this->decode($this->markKeywords($content, $words));
|
||||
|
||||
$content = $this->markKeywords($content, $words);
|
||||
preg_match_all("/\<span class='text-danger'\>.*\<\/span\>/U", $content, $matches);
|
||||
|
||||
if(empty($matches[0])) return $this->decode($this->markKeywords(substr($content, 0, $length), $words));
|
||||
|
||||
$matches = $matches[0];
|
||||
$score = 0;
|
||||
$needle = '';
|
||||
foreach($matches as $matched)
|
||||
{
|
||||
if(strlen($matched) > $score)
|
||||
{
|
||||
$content = str_replace($needle, strip_tags($needle), $content);
|
||||
$needle = $matched;
|
||||
$score = strlen($matched);
|
||||
}
|
||||
}
|
||||
|
||||
$content = str_replace('<span class', ' <spanclass', $content);
|
||||
$content = explode(' ', $content);
|
||||
|
||||
$pos = array_search(str_replace('<span class', '<spanclass', $needle), $content);
|
||||
|
||||
$start = max(0, $pos - ($length / 2));
|
||||
$summary = join(' ', array_slice($content, $start, $length));
|
||||
$summary = str_replace(' <spanclass', '<span class', $summary);
|
||||
|
||||
return $this->decode($summary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check product and project priv.
|
||||
*
|
||||
* @param array $results
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function checkPriv($results, $pager = null)
|
||||
{
|
||||
$this->loadModel('doc');
|
||||
$products = $this->app->user->view->products;
|
||||
$projects = $this->app->user->view->projects;
|
||||
|
||||
$objectPairs = array();
|
||||
$noPrivNum = 0;
|
||||
foreach($results as $record) $objectPairs[$record->objectType][$record->objectID] = $record->id;
|
||||
|
||||
foreach($objectPairs as $objectType => $objectIdList)
|
||||
{
|
||||
$objectProducts = array();
|
||||
$objectProjects = array();
|
||||
if(!isset($this->config->objectTables[$objectType])) continue;
|
||||
$table = $this->config->objectTables[$objectType];
|
||||
if(strpos(',bug,case,productplan,release,story,testtask,', ",$objectType,") !== false)
|
||||
{
|
||||
$objectProducts = $this->dao->select('id,product')->from($table)->where('id')->in(array_keys($objectIdList))->fetchGroup('product', 'id');
|
||||
}
|
||||
elseif(strpos(',build,task,testreport,', ",$objectType,") !== false)
|
||||
{
|
||||
$objectProjects = $this->dao->select('id,project')->from($table)->where('id')->in(array_keys($objectIdList))->fetchGroup('project', 'id');
|
||||
}
|
||||
elseif($objectType == 'effort')
|
||||
{
|
||||
$efforts = $this->dao->select('id,product,project')->from($table)->where('id')->in(array_keys($objectIdList))->fetchAll();
|
||||
foreach($efforts as $effort)
|
||||
{
|
||||
$objectProjects[$effort->project][$effort->id] = $effort;
|
||||
$effortProducts = explode(',', trim($effort->product, ','));
|
||||
foreach($effortProducts as $effortProduct) $objectProducts[$effortProduct][$effort->id] = $effort;
|
||||
}
|
||||
}
|
||||
elseif($objectType == 'product')
|
||||
{
|
||||
foreach($objectIdList as $productID => $recordID)
|
||||
{
|
||||
if(strpos(",$products,", ",$productID,") === false)
|
||||
{
|
||||
unset($results[$recordID]);
|
||||
$noPrivNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif($objectType == 'project')
|
||||
{
|
||||
foreach($objectIdList as $projectID => $recordID)
|
||||
{
|
||||
if(strpos(",$projects,", ",$projectID,") === false)
|
||||
{
|
||||
unset($results[$recordID]);
|
||||
$noPrivNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif($objectType == 'doc')
|
||||
{
|
||||
$objectDocs = $this->dao->select('*')->from($table)->where('id')->in(array_keys($objectIdList))
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchAll('id');
|
||||
$privLibs = array();
|
||||
foreach($objectIdList as $docID => $recordID)
|
||||
{
|
||||
if(!isset($objectDocs[$docID]) or !$this->doc->checkPrivDoc($objectDocs[$docID]))
|
||||
{
|
||||
unset($results[$recordID]);
|
||||
$noPrivNum++;
|
||||
continue;
|
||||
}
|
||||
$objectDoc = $objectDocs[$docID];
|
||||
$privLibs[$objectDoc->lib] = $objectDoc->lib;
|
||||
}
|
||||
|
||||
$libs = $this->doc->getLibs('all');
|
||||
$objectDocLibs = $this->dao->select('id')->from(TABLE_DOCLIB)->where('id')->in($privLibs)
|
||||
->andWhere('id')->in(array_keys($libs))
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchPairs('id', 'id');
|
||||
foreach($objectDocs as $docID => $doc)
|
||||
{
|
||||
$libID = $doc->lib;
|
||||
if(!isset($objectDocLibs[$libID]))
|
||||
{
|
||||
$recordID = $objectIdList[$docID];
|
||||
unset($results[$recordID]);
|
||||
$noPrivNum++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
elseif($objectType == 'todo')
|
||||
{
|
||||
$objectTodos = $this->dao->select('id')->from($table)->where('id')->in(array_keys($objectIdList))->andWhere("private")->eq(1)->fetchPairs('id', 'id');
|
||||
foreach($objectTodos as $todoID)
|
||||
{
|
||||
if(isset($objectIdList[$todoID]))
|
||||
{
|
||||
$recordID = $objectIdList[$todoID];
|
||||
unset($results[$recordID]);
|
||||
$noPrivNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif($objectType == 'testsuite')
|
||||
{
|
||||
$objectSuites = $this->dao->select('id')->from($table)->where('id')->in(array_keys($objectIdList))
|
||||
->andWhere("type")->eq('private')
|
||||
->andWhere('deleted')->eq(0)
|
||||
->fetchPairs('id', 'id');
|
||||
foreach($objectSuites as $suiteID)
|
||||
{
|
||||
if(isset($objectIdList[$suiteID]))
|
||||
{
|
||||
$recordID = $objectIdList[$suiteID];
|
||||
unset($results[$recordID]);
|
||||
$noPrivNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($objectProducts as $productID => $idList)
|
||||
{
|
||||
if(empty($productID)) continue;
|
||||
if(strpos(",$products,", ",$productID,") === false)
|
||||
{
|
||||
foreach($idList as $object)
|
||||
{
|
||||
$recordID = $objectIdList[$object->id];
|
||||
unset($results[$recordID]);
|
||||
$noPrivNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach($objectProjects as $projectID => $idList)
|
||||
{
|
||||
if(empty($projectID)) continue;
|
||||
if(strpos(",$projects,", ",$projectID,") === false)
|
||||
{
|
||||
foreach($idList as $object)
|
||||
{
|
||||
$recordID = $objectIdList[$object->id];
|
||||
unset($results[$recordID]);
|
||||
$noPrivNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($noPrivNum > 0) $pager->recTotal = $pager->recTotal - $noPrivNum;
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark keywords in content.
|
||||
*
|
||||
* @param string $content
|
||||
* @param string $keywords
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function markKeywords($content, $keywords)
|
||||
{
|
||||
$words = explode(' ', trim($keywords, ' '));
|
||||
$markedWords = array();
|
||||
|
||||
foreach($words as $key => $word)
|
||||
{
|
||||
if(preg_match('/^\|[0-9]+\|$/', $word))
|
||||
{
|
||||
$words[$key] = trim($word, '|');
|
||||
}
|
||||
elseif(is_numeric($word))
|
||||
{
|
||||
$words[$key] = $word . ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$words[$key] = strlen($word) == 5 ? str_replace('_', '', $word) : $word;
|
||||
}
|
||||
$markedWords[] = "<span class='text-danger'>" . $this->decode($word) . "</span > ";
|
||||
}
|
||||
|
||||
$content = str_replace($words, $markedWords, $content . ' ');
|
||||
$content = str_replace("</span > <span class='text-danger'>", '', $content);
|
||||
$content = str_replace("</span >", '</span>', $content);
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function buildIndexQuery($type, $testDeleted = true)
|
||||
{
|
||||
$table = $this->config->objectTables[$type];
|
||||
if($type == 'story')
|
||||
{
|
||||
$query = $this->dao->select('DISTINCT t1.*,t2.spec,t2.verify')->from($table)->alias('t1')->leftJoin(TABLE_STORYSPEC)->alias('t2')->on('t1.id=t2.story')->where('t1.deleted')->eq(0)->andWhere('t1.version=t2.version');
|
||||
}
|
||||
elseif($type == 'doc')
|
||||
{
|
||||
$query = $this->dao->select('DISTINCT t1.*,t2.content,t2.digest')->from($table)->alias('t1')->leftJoin(TABLE_DOCCONTENT)->alias('t2')->on('t1.id=t2.doc')->where('t1.deleted')->eq(0)->andWhere('t1.version=t2.version');
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = '';
|
||||
if($testDeleted) $data = $this->dao->select('*')->from($table)->limit(1)->fetch();
|
||||
|
||||
$query = $this->dao->select('t1.*')->from($table)->alias('t1')
|
||||
->where('1')
|
||||
->beginIF(isset($data->deleted))->andWhere('t1.deleted')->eq(0)->fi();
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build all search index.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function buildAllIndex($type = '', $lastID = 0)
|
||||
{
|
||||
$limit = 100;
|
||||
$nextObject = false;
|
||||
if(empty($type))
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_SEARCHINDEX)->exec();
|
||||
$this->dao->delete()->from(TABLE_SEARCHDICT)->exec();
|
||||
try
|
||||
{
|
||||
$this->dbh->exec('ALTER TABLE ' . TABLE_SEARCHINDEX . ' auto_increment=1');
|
||||
}
|
||||
catch(Exception $e){}
|
||||
$type = key($this->config->search->fields);
|
||||
}
|
||||
|
||||
foreach($this->config->search->fields as $module => $field)
|
||||
{
|
||||
if($module != $type and !$nextObject) continue;
|
||||
if($module == $type) $nextObject = true;
|
||||
if(!isset($this->config->objectTables[$module])) continue;
|
||||
|
||||
while(true)
|
||||
{
|
||||
$query = $this->buildIndexQuery($module);
|
||||
$dataList = $query->beginIF($lastID)->andWhere('t1.id')->gt($lastID)->fi()->limit($limit)->fetchAll('id');
|
||||
if(empty($dataList))
|
||||
{
|
||||
$lastID = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if($module == 'case') $caseStep = $this->dao->select('*')->from(TABLE_CASESTEP)->where('`case`')->in(array_keys($dataList))->fetchGroup('case', 'id');
|
||||
$actions = $this->dao->select('*')->from(TABLE_ACTION)
|
||||
->where('objectType')->eq($module)
|
||||
->andWhere('objectID')->in(array_keys($dataList))
|
||||
->orderBy('date asc')
|
||||
->fetchGroup('objectID', 'id');
|
||||
|
||||
$files = $this->dao->select('id,objectID,title,extension')->from(TABLE_FILE)
|
||||
->where('objectType')->eq($module)
|
||||
->andWhere('objectID')->in(array_keys($dataList))
|
||||
->orderBy('id asc')
|
||||
->fetchGroup('objectID', 'id');
|
||||
|
||||
foreach($dataList as $id => $data)
|
||||
{
|
||||
$data->comment = '';
|
||||
if(isset($actions[$id]))
|
||||
{
|
||||
foreach($actions[$id] as $action)
|
||||
{
|
||||
if($action->action == 'opened')$data->{$field->addedDate} = $action->date;
|
||||
$data->{$field->editedDate} = $action->date;
|
||||
if(!empty($action->comment)) $data->comment .= $action->comment . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($files[$id]))
|
||||
{
|
||||
foreach($files[$id] as $file)
|
||||
{
|
||||
if(!empty($file->title)) $data->comment .= $file->title . '.' . $file->extension . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if($module == 'case')
|
||||
{
|
||||
$data->desc = '';
|
||||
$data->expect = '';
|
||||
if(isset($caseStep[$id]))
|
||||
{
|
||||
foreach($caseStep[$id] as $step)
|
||||
{
|
||||
if($step->version != $data->version) continue;
|
||||
$data->desc .= $step->desc . "\n";
|
||||
$data->expect .= $step->expect . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($dataList as $data) $this->saveIndex($module, $data);
|
||||
return array('type' => $module, 'count' => count($dataList), 'lastID' => max(array_keys($dataList)));
|
||||
}
|
||||
}
|
||||
return array('finished' => true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete index of an object.
|
||||
*
|
||||
* @param string $objectType
|
||||
* @param int $objectID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function deleteIndex($objectType, $objectID)
|
||||
{
|
||||
$this->dao->delete()->from(TABLE_SEARCHINDEX)->where('objectType')->eq($objectType)->andWhere('objectID')->eq($objectID)->exec();
|
||||
return !dao::isError();
|
||||
}
|
||||
|
||||
public static function unify($string, $to = ',')
|
||||
{
|
||||
$labels = array('_', '、', ' ', '-', '\n', '?', '@', '&', '%', '~', '`', '+', '*', '/', '\\', '。', ',');
|
||||
$string = str_replace($labels, $to, $string);
|
||||
return preg_replace("/[{$to}]+/", $to, trim($string, $to));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/**
|
||||
* The create view file of article module of chanzhiEPS.
|
||||
*
|
||||
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
|
||||
* @license ZPL (http://zpl.pub/page/zplv11.html)
|
||||
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
|
||||
* @package article
|
||||
* @version $Id$
|
||||
* @link http://www.chanzhi.org
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div id='mainMenu' class='clearfix'>
|
||||
<div class='btn-toolbar pull-left'><?php common::printAdminSubMenu('system');?></div>
|
||||
</div>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='main-header'>
|
||||
<h2><i class='icon-refresh'></i> <?php echo $lang->search->index;?></h2>
|
||||
</div>
|
||||
<div>
|
||||
<div class='form-group'>
|
||||
<ul id='resultBox'></ul>
|
||||
</div>
|
||||
<div class='from-group'><?php echo html::a(inlink('buildIndex'), $lang->search->buildIndex, '', "class='btn btn-primary' id='execButton'");?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('#subNavbar li[data-id=system]').addClass('active');
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<div class='row'>
|
||||
<div class='col-md-12'>
|
||||
<form method='post' action='<?php echo inlink('index')?>' style='margin-bottom:10px;'>
|
||||
<div class='input-group col-md-8 col-md-offset-2'>
|
||||
<span class='input-group-btn w-auto'><?php echo html::input('words', $words, "class='form-control'")?></span>
|
||||
<span class='input-group-btn select'><?php echo html::select('type[]', $lang->search->modules, $type, "class='form-control chosen' multiple")?></span>
|
||||
<span class='input-group-btn'><?php echo html::submitButton($lang->search->common, '', 'btn btn-primary')?></span>
|
||||
</div>
|
||||
</form>
|
||||
<div class='list list-condensed'>
|
||||
<header>
|
||||
<h2><?php echo $lang->search->result;?></h2>
|
||||
</header>
|
||||
<section class='items items-hover'>
|
||||
<?php foreach($results as $object):?>
|
||||
<div class='item'>
|
||||
<div class='item-heading'>
|
||||
<div class="pull-right">
|
||||
<span><?php echo html::a($object->url . (strpos($object->url, '?') !== false ? '&onlybody=yes' : '?onlybody=yes'), "<i class='icon-eye-open'></i>" . $lang->search->preview, '', "class='iframe' data-width='90%' data-title=\"<a href='$object->url' target='_blank' class='btn'><i class='icon-eye-open'></i>$lang->preview</a>\"")?></span>
|
||||
</div>
|
||||
<h4>
|
||||
<?php
|
||||
$objectType = $object->objectType == 'case' ? 'testcase' : $object->objectType;
|
||||
echo html::a($object->url, $object->title, '', 'title="' . strip_tags($object->title) . '"');
|
||||
echo "<small class=''>[{$lang->searchObjects[$objectType]} #{$object->objectID}]</small> ";
|
||||
?>
|
||||
</h4>
|
||||
</div>
|
||||
<div class='item-content'>
|
||||
<div class='text text-muted'><?php echo $object->summary;?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
</section>
|
||||
<footer class='table-footer'>
|
||||
<?php echo str_replace($words, urlencode($words), $pager->get('right', 'short'));?>
|
||||
<span class='execute-info text-muted'><?php printf($lang->search->executeInfo, $pager->recTotal, $consumed);?></span>
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(function()
|
||||
{
|
||||
$('#searchbox #searchInput').val(<?php echo json_encode($words)?>);
|
||||
})
|
||||
</script>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
+12
-12
@@ -643,9 +643,9 @@ class task extends control
|
||||
else
|
||||
{
|
||||
$story = $this->story->getById($task->story, $task->storyVersion);
|
||||
$task->storySpec = empty($story) ? '' : $this->loadModel('file')->setImgSize($story->spec);
|
||||
$task->storyVerify = empty($story) ? '' : $this->loadModel('file')->setImgSize($story->verify);
|
||||
$task->storyFiles = $this->loadModel('file')->getByObject('story', $task->story);
|
||||
$task->storySpec = empty($story) ? '' : $this->loadModel('file')->setImgSize($story->spec);
|
||||
$task->storyVerify = empty($story) ? '' : $this->loadModel('file')->setImgSize($story->verify);
|
||||
$task->storyFiles = $this->loadModel('file')->getByObject('story', $task->story);
|
||||
}
|
||||
|
||||
if($task->team) $this->lang->task->assign = $this->lang->task->transfer;
|
||||
@@ -664,15 +664,15 @@ class task extends control
|
||||
$position[] = $this->lang->task->common;
|
||||
$position[] = $this->lang->task->view;
|
||||
|
||||
$this->view->title = $title;
|
||||
$this->view->position = $position;
|
||||
$this->view->project = $project;
|
||||
$this->view->task = $task;
|
||||
$this->view->actions = $this->loadModel('action')->getList('task', $taskID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('task', $taskID);
|
||||
$this->view->product = $this->tree->getProduct($task->module);
|
||||
$this->view->modulePath = $this->tree->getParents($task->module);
|
||||
$this->view->title = $title;
|
||||
$this->view->position = $position;
|
||||
$this->view->project = $project;
|
||||
$this->view->task = $task;
|
||||
$this->view->actions = $this->loadModel('action')->getList('task', $taskID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('noletter');
|
||||
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('task', $taskID);
|
||||
$this->view->product = $this->tree->getProduct($task->module);
|
||||
$this->view->modulePath = $this->tree->getParents($task->module);
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user