diff --git a/config/filter.php b/config/filter.php index e173dd69be..a5db047a7f 100644 --- a/config/filter.php +++ b/config/filter.php @@ -13,7 +13,7 @@ $filter->rules->word = '/^\w+$/'; $filter->rules->paramName = '/^[a-zA-Z0-9_\.]+$/'; $filter->rules->paramValue = '/^[a-zA-Z0-9=_,`#+\^\/\.%\|\x7f-\xff]+$/'; -$filter->default = new stdclass(); +$filter->default = new stdclass(); $filter->default->moduleName = 'code'; $filter->default->methodName = 'code'; $filter->default->paramName = 'reg::paramName'; @@ -194,6 +194,7 @@ $filter->sso->login->get['md5'] = 'reg::md5'; $filter->sso->login->get['referer'] = 'reg::base64'; $filter->sso->login->get['status'] = 'code'; $filter->sso->login->get['token'] = 'reg::md5'; +$filter->sso->login->get['sessionid'] = 'reg::base64'; $filter->sso->logout->get['status'] = 'code'; $filter->sso->logout->get['token'] = 'reg::md5'; diff --git a/module/block/control.php b/module/block/control.php index 9671aba027..d77fef5557 100644 --- a/module/block/control.php +++ b/module/block/control.php @@ -904,7 +904,7 @@ class block extends control /* Get tasks. */ $yesterday = date('Y-m-d', strtotime('-1 day')); - $tasks = $this->dao->select("project, count(id) as totalTasks, count(status not in ('wait,doing,pause') or null) as undoneTasks, count(finishedDate like '{$yesterday}%' or null) as yesterdayFinished, sum(if(status != 'cancel', estimate, 0)) as totalEstimate, sum(if(status != 'cancel', consumed, 0)) as totalConsumed, sum(if(status != 'cancel', `left`, 0)) as totalLeft")->from(TABLE_TASK) + $tasks = $this->dao->select("project, count(id) as totalTasks, count(status not in ('wait,doing,pause') or null) as undoneTasks, count(finishedDate like '{$yesterday}%' or null) as yesterdayFinished, sum(if(status != 'cancel', estimate, 0)) as totalEstimate, sum(consumed) as totalConsumed, sum(if(status != 'cancel', `left`, 0)) as totalLeft")->from(TABLE_TASK) ->where('project')->in($projectIDList) ->andWhere('deleted')->eq(0) ->andWhere('parent')->eq(0) diff --git a/module/block/view/todoblock.html.php b/module/block/view/todoblock.html.php index 452e832df3..77ad50d0f5 100644 --- a/module/block/view/todoblock.html.php +++ b/module/block/view/todoblock.html.php @@ -22,7 +22,7 @@ .block-todoes .todoes > li:hover {background-color: #e9f2fb;} .block-todoes .todo-title {padding: 5px;} .block-todoes .todo-pri {margin: 0 5px;} -.block-todoes .todo-time {display: inline-block; padding: 0 5px; font-size: 12px; color: #8e939a; width: 90px;} +.block-todoes .todo-time {display: inline-block; padding: 0 5px; font-size: 12px; color: #8e939a; width: 100px;} .block-todoes .todo-check {position: absolute; top: 5px; left: 10px; display: block; width: 20px; height: 20px; font-size: 20px; color: transparent; cursor: pointer; background: #fff; border: 2px solid #eee; border-radius: 50%;} .block-todoes .todo-check:hover {border-color: #8e939a;} .block-todoes .active > .todo-check {color: #00da88; background: transparent;border: none;} diff --git a/module/bug/model.php b/module/bug/model.php index 99f2b8b319..27c0f4b58d 100644 --- a/module/bug/model.php +++ b/module/bug/model.php @@ -927,8 +927,8 @@ class bugModel extends model if(dao::isError()) return false; $buildData = new stdclass(); - $buildData->product = $oldBug->product; - $buildData->branch = $oldBug->branch; + $buildData->product = (int)$oldBug->product; + $buildData->branch = (int)$oldBug->branch; $buildData->project = $bug->buildProject; $buildData->name = $bug->buildName; $buildData->date = date('Y-m-d'); diff --git a/module/build/model.php b/module/build/model.php index f40a24ddf4..cfcbd7796b 100644 --- a/module/build/model.php +++ b/module/build/model.php @@ -199,6 +199,7 @@ class buildModel extends model $build = fixer::input('post') ->setDefault('product', 0) ->setDefault('branch', 0) + ->cleanInt('product,branch') ->add('project', (int)$projectID) ->stripTags($this->config->build->editor->create['id'], $this->config->allowedTags) ->remove('resolvedBy,allchecker,files,labels,uid') @@ -230,8 +231,10 @@ class buildModel extends model */ public function update($buildID) { - $oldBuild = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->eq((int)$buildID)->fetch(); + $buildID = (int)$buildID; + $oldBuild = $this->dao->select('*')->from(TABLE_BUILD)->where('id')->eq($buildID)->fetch(); $build = fixer::input('post')->stripTags($this->config->build->editor->edit['id'], $this->config->allowedTags) + ->cleanInt('product,branch') ->remove('allchecker,resolvedBy,files,labels,uid') ->get(); if(!isset($build->branch)) $build->branch = $oldBuild->branch; @@ -240,7 +243,7 @@ class buildModel extends model $this->dao->update(TABLE_BUILD)->data($build) ->autoCheck() ->batchCheck($this->config->build->edit->requiredFields, 'notempty') - ->where('id')->eq((int)$buildID) + ->where('id')->eq($buildID) ->check('name', 'unique', "id != $buildID AND product = {$build->product} AND branch = {$build->branch} AND deleted = '0'") ->exec(); if(isset($build->branch) and $oldBuild->branch != $build->branch) $this->dao->update(TABLE_RELEASE)->set('branch')->eq($build->branch)->where('build')->eq($buildID)->exec(); diff --git a/module/common/view/datatable.html.php b/module/common/view/datatable.html.php index 1725d9a274..75d78c9b2f 100644 --- a/module/common/view/datatable.html.php +++ b/module/common/view/datatable.html.php @@ -36,32 +36,7 @@ moduleName . ucfirst($this->methodName);?> $(document).ready(function() { - 'use strict'; - - var $datatable = $('table.datatable').first(); - var datatableId = $datatable.attr('id'); - var dtSetting = $.cookie('datatable.' + '.cols') || {}; - if(dtSetting === 'null') dtSetting = {}; - if(typeof dtSetting === 'string') dtSetting = $.parseJSON(dtSetting); - var $modal = $('#customDatatable'); - var $checkList = $modal.find('.modal-body > .table > tbody'); - - $datatable.find('thead>tr>th').each(function(idx) - { - var $th = $(this); - idx = $th.data('index') || idx; - var colSetting = dtSetting[idx]; - $th.toggleClass('ignore', !!(colSetting && colSetting.ignore)); - }); - - $checkList.on('click', 'tr', function() - { - var $tr = $(this); - if($tr.hasClass('disabled')) return; - $tr.toggleClass('checked'); - }); - - $datatable.datatable( + var datatableOptions = { customizable : false, sortable : false, @@ -73,19 +48,46 @@ $(document).ready(function() fixedHeader: true, ready: function() { - $datatable.addClass('datatable-origin'); - if ($datatable.hasClass('has-sort-head')) + this.$table.addClass('datatable-origin'); + if (this.$table.hasClass('has-sort-head')) { this.$datatable.find('.table').addClass('has-sort-head'); } this.$datatable.find('.sparkline').sparkline(); } - }); + }; - $(window).on('fixFooter', function(e, isFixed) + window.initDatatable = function($datatable) { - $('body').toggleClass('has-fixed-footer', isFixed); - }); + $datatable = $datatable || $('table.datatable').first(); + if(!$datatable.length) return null; + var $datatable = $('table.datatable').first(); + var datatableId = $datatable.attr('id'); + var dtSetting = $.cookie('datatable.' + '.cols') || {}; + if(dtSetting === 'null') dtSetting = {}; + if(typeof dtSetting === 'string') dtSetting = $.parseJSON(dtSetting); + + $datatable.datatable(datatableOptions); + + + $datatable.find('thead>tr>th').each(function(idx) + { + var $th = $(this); + idx = $th.data('index') || idx; + var colSetting = dtSetting[idx]; + $th.toggleClass('ignore', !!(colSetting && colSetting.ignore)); + }); + return $datatable; + }; + + var $datatable = initDatatable(); + if($datatable && $datatable.length) + { + $('#main').on('beforeTableReload', '[data-ride="table"]', function() + { + initDatatable($datatable); + }); + } window.saveDatatableConfig = function(name, value, reload, global) { @@ -102,6 +104,20 @@ $(document).ready(function() url: 'createLink('datatable', 'ajaxSave')?>' }); }; + + var $modal = $('#customDatatable'); + var $checkList = $modal.find('.modal-body > .table > tbody'); + $checkList.on('click', 'tr', function() + { + var $tr = $(this); + if($tr.hasClass('disabled')) return; + $tr.toggleClass('checked'); + }); + + $(window).on('fixFooter', function(e, isFixed) + { + $('body').toggleClass('has-fixed-footer', isFixed); + }); }); diff --git a/module/custom/model.php b/module/custom/model.php index 4d1f576faa..9663ae6ea5 100644 --- a/module/custom/model.php +++ b/module/custom/model.php @@ -484,6 +484,8 @@ class customModel extends model } } - $this->loadModel('setting')->setItems("system.{$moduleName}", $requiredFields); + $this->loadModel('setting'); + $this->setting->deleteItems("owner=system&module={$moduleName}"); + $this->setting->setItems("system.{$moduleName}", $requiredFields); } } diff --git a/module/doc/css/createlib.css b/module/doc/css/createlib.css index d5f518687f..a71c64e34e 100644 --- a/module/doc/css/createlib.css +++ b/module/doc/css/createlib.css @@ -1,3 +1,3 @@ -form {margin-right: 30px;} +form {margin-right: 30px; margin-bottom:130px;} #whiteListBox div.input-group {margin-bottom: 2px;} diff --git a/module/doc/model.php b/module/doc/model.php index d81b91560f..7b15723fff 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -606,7 +606,7 @@ class docModel extends model ->add('version', 1) ->setDefault('product,project,module', 0) ->stripTags($this->config->doc->editor->create['id'], $this->config->allowedTags) - ->cleanInt('product,project,module') + ->cleanInt('product,project,module,lib') ->join('groups', ',') ->join('users', ',') ->remove('files,labels,uid') diff --git a/module/product/model.php b/module/product/model.php index 28a9fb539e..e170f85ba9 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -433,6 +433,7 @@ class productModel extends model $oldProducts = $this->getByIdList($this->post->productIDList); foreach($data->productIDList as $productID) { + $productID = (int)$productID; $products[$productID] = new stdClass(); $products[$productID]->name = $data->names[$productID]; $products[$productID]->code = $data->codes[$productID]; diff --git a/module/project/model.php b/module/project/model.php index 14101e7eaa..ecd4abb46b 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -378,7 +378,8 @@ class projectModel extends model */ public function update($projectID) { - $oldProject = $this->dao->findById((int)$projectID)->from(TABLE_PROJECT)->fetch(); + $projectID = (int)$projectID; + $oldProject = $this->dao->findById($projectID)->from(TABLE_PROJECT)->fetch(); $team = $this->getTeamMemberPairs($projectID); $this->lang->project->team = $this->lang->project->teamname; $projectID = (int)$projectID; @@ -443,6 +444,7 @@ class projectModel extends model $oldProjects = $this->getByIdList($this->post->projectIDList); foreach($data->projectIDList as $projectID) { + $projectID = (int)$projectID; $projects[$projectID] = new stdClass(); $projects[$projectID]->name = $data->names[$projectID]; $projects[$projectID]->code = $data->codes[$projectID]; diff --git a/module/release/model.php b/module/release/model.php index 9373150af5..be6d099162 100644 --- a/module/release/model.php +++ b/module/release/model.php @@ -103,7 +103,9 @@ class releaseModel extends model */ public function create($productID, $branch = 0) { - $buildID = 0; + $productID = (int)$productID; + $branch = (int)$branch; + $buildID = 0; if($this->post->build == false && $this->post->name) { $build = $this->dao->select('*')->from(TABLE_BUILD) @@ -186,11 +188,13 @@ class releaseModel extends model */ public function update($releaseID) { - $oldRelease = $this->dao->select('*')->from(TABLE_RELEASE)->where('id')->eq((int)$releaseID)->fetch(); - $branch = $this->dao->select('branch')->from(TABLE_BUILD)->where('id')->eq($this->post->build)->fetch('branch'); + $releaseID = (int)$releaseID; + $oldRelease = $this->dao->select('*')->from(TABLE_RELEASE)->where('id')->eq($releaseID)->fetch(); + $branch = $this->dao->select('branch')->from(TABLE_BUILD)->where('id')->eq((int)$this->post->build)->fetch('branch'); $release = fixer::input('post')->stripTags($this->config->release->editor->edit['id'], $this->config->allowedTags) ->add('branch', (int)$branch) + ->cleanInt('product') ->remove('files,labels,allchecker,uid') ->get(); $release = $this->loadModel('file')->processImgURL($release, $this->config->release->editor->edit['id'], $this->post->uid); diff --git a/module/report/model.php b/module/report/model.php index 8c6436b731..0c58fe8ed6 100644 --- a/module/report/model.php +++ b/module/report/model.php @@ -95,7 +95,7 @@ class reportModel extends model ->andWhere('t1.deleted')->eq(0) ->andWhere('t2.deleted')->eq(0) ->andWhere('t1.parent')->eq(0) - ->andWhere('t2.status')->eq('done') + ->andWhere('t2.status')->eq('closed') ->beginIF($begin)->andWhere('t2.begin')->ge($begin)->fi() ->beginIF($end)->andWhere('t2.end')->le($end)->fi() ->orderBy('t2.end_desc') @@ -288,32 +288,45 @@ class reportModel extends model ->andWhere('t1.status')->notin('cancel, closed, done, pause') ->andWhere('t2.deleted')->eq(0) ->andWhere('t2.status')->notin('cancel, closed, done, suspended') + ->andWhere('assignedTo')->ne('') ->beginIF($dept)->andWhere('t3.dept')->in($depts)->fi() - ->fetchGroup('assignedTo', 'id'); + ->fetchAll('id'); if(empty($tasks)) return array(); /* Fix bug for children. */ - $parents = array(); - foreach($tasks as $user => $userTasks) + $parents = array(); + $taskIdList = array(); + $taskGroups = array(); + foreach($tasks as $task) { - if($user) + if(!empty($task->parent)) $parents[$task->parent] = $task->parent; + $taskGroups[$task->assignedTo][$task->id] = $task; + } + + $multiTaskTeams = $this->dao->select('*')->from(TABLE_TEAM)->where('type')->eq('task') + ->andWhere('root')->in(array_keys($tasks)) + ->fetchGroup('account', 'root'); + foreach($multiTaskTeams as $assignedTo => $multiTasks) + { + foreach($multiTasks as $task) { - foreach($userTasks as $task) - { - if(!empty($task->parent)) $parents[$task->parent] = $task->parent; - } + $userTask = $tasks[$task->root]; + $userTask->estimate = $task->estimate; + $userTask->consumed = $task->consumed; + $userTask->left = $task->left; + $taskGroups[$assignedTo][$task->root] = $userTask; } } $workload = array(); - foreach($tasks as $user => $userTasks) + foreach($taskGroups as $user => $userTasks) { if($user) { foreach($userTasks as $task) { - if(!empty($parents) && in_array($task->id, $parents)) continue; + if(isset($parents[$task->id])) continue; $workload[$user]['task'][$task->projectName]['count'] = isset($workload[$user]['task'][$task->projectName]['count']) ? $workload[$user]['task'][$task->projectName]['count'] + 1 : 1; $workload[$user]['task'][$task->projectName]['manhour'] = isset($workload[$user]['task'][$task->projectName]['manhour']) ? $workload[$user]['task'][$task->projectName]['manhour'] + $task->left : $task->left; $workload[$user]['task'][$task->projectName]['projectID'] = $task->project; diff --git a/module/sso/control.php b/module/sso/control.php index e2eee29823..bf89541177 100644 --- a/module/sso/control.php +++ b/module/sso/control.php @@ -13,8 +13,8 @@ class sso extends control { /** * SSO login. - * - * @param string $type + * + * @param string $type * @access public * @return void */ @@ -44,6 +44,11 @@ class sso extends control { $location = rtrim($location, '?') . "?token=$token&auth=$auth&userIP=$userIP&callback=$callback&referer=$referer"; } + if(!empty($_GET['sessionid'])) + { + $sessionConfig = json_decode(base64_decode($this->get->sessionid), false); + $location .= '&' . $sessionConfig->session_name . '=' . $sessionConfig->session_id; + } $this->locate($location); } @@ -95,8 +100,8 @@ class sso extends control /** * SSO logout. - * - * @param string $type + * + * @param string $type * @access public * @return void */ @@ -115,9 +120,9 @@ class sso extends control if(strpos($location, '&') !== false) { $location = rtrim($location, '&') . "&token=$token&auth=$auth&userIP=$userIP&callback=$callback"; - } + } else - { + { $location = rtrim($location, '?') . "?token=$token&auth=$auth&userIP=$userIP&callback=$callback"; } $this->locate($location); @@ -135,7 +140,7 @@ class sso extends control /** * Ajax set config. - * + * * @access public * @return void */ @@ -158,9 +163,9 @@ class sso extends control } /** - * Bind user. - * - * @param string $referer + * Bind user. + * + * @param string $referer * @access public * @return void */ @@ -199,7 +204,7 @@ class sso extends control /** * Get pairs of user. - * + * * @access public * @return void */ @@ -212,7 +217,7 @@ class sso extends control /** * Get bind users with ranzhi. - * + * * @access public * @return void */ @@ -225,7 +230,7 @@ class sso extends control /** * Bind user from ranzhi. - * + * * @access public * @return void */ @@ -242,7 +247,7 @@ class sso extends control /** * Create user from ranzhi. - * + * * @access public * @return void */ @@ -258,8 +263,8 @@ class sso extends control /** * Get todo list for ranzhi. - * - * @param string $account + * + * @param string $account * @access public * @return void */ diff --git a/module/story/model.php b/module/story/model.php index d299d0baa8..ac96fb8eee 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -168,7 +168,7 @@ class storyModel extends model if($result['stop']) return array('status' => 'exists', 'id' => $result['duplicate']); if($this->checkForceReview()) $story->status = 'draft'; - if($story->status == 'draft') $story->stage = $this->post->plan > 0 ? 'planned' : 'wait'; + if($story->status == 'draft') $story->stage = $this->post->plan > 0 ? 'planned' : 'wait'; $story = $this->loadModel('file')->processImgURL($story, $this->config->story->editor->create['id'], $this->post->uid); $this->dao->insert(TABLE_STORY)->data($story, 'spec,verify')->autoCheck()->batchCheck($this->config->story->create->requiredFields, 'notempty')->exec(); if(!dao::isError()) @@ -476,7 +476,8 @@ class storyModel extends model } $story = fixer::input('post') - ->cleanInt('product,module,pri,duplicateStory,estimate') + ->cleanInt('product,module,pri,duplicateStory') + ->cleanFloat('estimate') ->add('assignedDate', $oldStory->assignedDate) ->add('lastEditedBy', $this->app->user->account) ->add('lastEditedDate', $now) diff --git a/module/task/control.php b/module/task/control.php index ba8539f1cf..3a0da100d7 100644 --- a/module/task/control.php +++ b/module/task/control.php @@ -1382,7 +1382,7 @@ class task extends control $task->files = ''; foreach($relatedFiles[$task->id] as $file) { - $fileURL = common::getSysURL() . $this->file->webPath . $this->file->getRealPathName($file->pathname); + $fileURL = common::getSysURL() . $this->createLink('file', 'download', "fileID={$file->id}"); $task->files .= html::a($fileURL, $file->title, '_blank') . '
'; } } diff --git a/module/testcase/view/import.html.php b/module/testcase/view/import.html.php index c02e265e9c..52b164d3e0 100644 --- a/module/testcase/view/import.html.php +++ b/module/testcase/view/import.html.php @@ -1,5 +1,5 @@ -
+
diff --git a/module/testreport/control.php b/module/testreport/control.php index f42f97fc9a..a374571706 100644 --- a/module/testreport/control.php +++ b/module/testreport/control.php @@ -158,6 +158,8 @@ class testreport extends control $tasks = array($task->id => $task); $owner = $task->owner; + $this->setChartDatas($objectID); + $this->view->title = $task->name . $this->lang->testreport->create; $this->view->position[] = html::a(inlink('browse', "objectID=$productID&objectType=product&extra={$task->id}"), $task->name); $this->view->position[] = $this->lang->testreport->create; @@ -306,6 +308,8 @@ class testreport extends control $bugs = $this->testreport->getBugs4Test($builds, $report->product, $report->begin, $report->end); } $tasks = array($task->id => $task); + + $this->setChartDatas($report->objectID); } else { @@ -390,6 +394,8 @@ class testreport extends control $cases = $this->testreport->getTaskCases($tasks, $report->cases); $bugInfo = $this->testreport->getBugInfo($tasks, $report->product, $report->begin, $report->end, $builds); + if($report->objectType == 'testtask') $this->setChartDatas($report->objectID); + $this->view->title = $report->title; $this->view->browseLink = $browseLink; $this->view->position[] = $report->title; @@ -461,4 +467,29 @@ class testreport extends control return $projectID; } } + + /** + * Set chart datas of cases. + * + * @param int $taskID + * @access public + * @return void + */ + public function setChartDatas($taskID) + { + $this->loadModel('report'); + $task = $this->loadModel('testtask')->getById($taskID); + foreach($this->lang->testtask->report->charts as $chart => $title) + { + if(strpos($chart, 'testTask') === false) continue; + + $chartFunc = 'getDataOf' . $chart; + $chartData = $this->testtask->$chartFunc($taskID); + $chartOption = $this->testtask->mergeChartOption($chart); + if(!empty($chartType)) $chartOption->type = $chartType; + + $this->view->charts[$chart] = $chartOption; + $this->view->datas[$chart] = $this->report->computePercent($chartData); + } + } } diff --git a/module/testreport/view/blockbugreport.html.php b/module/testreport/view/blockbugreport.html.php index c5acb1ac11..232a061728 100644 --- a/module/testreport/view/blockbugreport.html.php +++ b/module/testreport/view/blockbugreport.html.php @@ -1,4 +1,50 @@ + $chartOption):?> + + + + $infoValue):?>
+ + + + + + + + + + + +
+
testtask->report->charts[$chartType];?>
+ testreport->none;?> +
+
+
testtask->report->charts[$chartType];?>
+
+
+
+
+ + + + + + + + + $data):?> + + + + + + + +
report->item;?>report->value;?>report->percent;?>
name;?>value;?>percent * 100) . '%';?>
+
+
+
diff --git a/module/testsuite/view/showimport.html.php b/module/testsuite/view/showimport.html.php index 3dd4406c07..703ae36083 100644 --- a/module/testsuite/view/showimport.html.php +++ b/module/testsuite/view/showimport.html.php @@ -6,8 +6,11 @@
+
+

testsuite->import;?>

+
- +
@@ -18,7 +21,7 @@ -
testcase->id?>testcase->stage?> testcase->keywords?> testcase->precondition?> + @@ -29,7 +32,10 @@ - + $case):?> title)) continue;?> id) and !isset($cases[$case->id])) $case->id = 0;?> @@ -43,7 +49,7 @@ } else { - echo $key . " {$lang->testcase->new}"; + echo $key . " {$lang->testcase->new}"; } echo html::hidden("lib[$key]", $libID); ?> @@ -51,15 +57,18 @@ - + -
testcase->stepDesc?>
title, "class='form-control' style='margin-top:2px' autocomplete='off'")?> module) ? $case->module : (!empty($case->id) ? $cases[$case->id]->module : ''), "class='form-control chosen'")?> testcase->priList, isset($case->pri) ? $case->pri : (!empty($case->id) ? $cases[$case->id]->pri : ''), "class='form-control chosen'")?>testcase->typeList, isset($case->type) ? $case->type : (!empty($case->id) ? $cases[$case->id]->type : ''), "class='form-control chosen'")?>testcase->typeList, isset($case->type) ? $case->type : (!empty($case->id) ? $cases[$case->id]->type : ''), "class='form-control chosen'")?> testcase->stageList, !empty($case->stage) ? $case->stage : (!empty($case->id) ? $cases[$case->id]->stage : ''), "multiple='multiple' class='form-control chosen'")?> keywords) ? $case->keywords : "", "class='form-control' autocomplete='off'")?> precondition) ? htmlspecialchars($case->precondition) : "", "class='form-control'")?> + $desc):?> - + @@ -94,6 +103,9 @@ + + +