diff --git a/gui/templates/requirements/inc_btn_reqSpecView.tpl b/gui/templates/requirements/inc_btn_reqSpecView.tpl
index 33bf3c7a6b..19d48b9cba 100644
--- a/gui/templates/requirements/inc_btn_reqSpecView.tpl
+++ b/gui/templates/requirements/inc_btn_reqSpecView.tpl
@@ -9,7 +9,7 @@ TestLink Open Source Project - http://testlink.sourceforge.net/
req_select_create_tc,btn_import_req_spec,btn_import_reqs,
btn_export_reqs,btn_edit_spec,btn_delete_spec,btn_print_view,
btn_show_direct_link,btn_copy_requirements,btn_copy_req_spec,
- req_spec_operations, req_operations, btn_freeze_req_spec,btn_new_revision,btn_view_history'}
+ req_spec_operations, req_operations, btn_freeze_req_spec,btn_new_revision,btn_view_history,btn_bulk_mon'}
{$cfg_section=$smarty.template|basename|replace:".tpl":"" }
{config_load file="input_dimensions.conf" section=$cfg_section}
@@ -91,11 +91,15 @@ TestLink Open Source Project - http://testlink.sourceforge.net/
onclick="location='{$req_create_from_issue_xml_url}'" />
{if $gui->requirements_count > 0}
-
+
-
+
+
+
+
{/if}
{/if}
diff --git a/gui/templates/requirements/reqSpecView.tpl b/gui/templates/requirements/reqSpecView.tpl
index e75f4499f3..7756f662e5 100644
--- a/gui/templates/requirements/reqSpecView.tpl
+++ b/gui/templates/requirements/reqSpecView.tpl
@@ -55,6 +55,9 @@ Purpose: view a requirement specification
{$url_args="reqCreateFromIssueMantisXML.php?scope=branch&req_spec_id="}
{$req_create_from_issue_xml_url="$basehref$req_module$url_args$reqSpecID"}
+{$url_args="reqSpecEdit.php?doAction=bulkReqMon&req_spec_id="}
+{$req_spec_bulk_req_mon_url="$basehref$req_module$url_args$reqSpecID"}
+
{* used on inc_btn_reqSpecView.tpl *}
{lang_get s='warning_delete_req_spec' var="warning_msg" }
diff --git a/lib/functions/requirement_mgr.class.php b/lib/functions/requirement_mgr.class.php
index 804cbe3648..03c957c072 100644
--- a/lib/functions/requirement_mgr.class.php
+++ b/lib/functions/requirement_mgr.class.php
@@ -156,7 +156,8 @@ function get_by_id($id,$version_id=self::ALL_VERSIONS,$version_number=1,$options
$my['options'] = array('order_by' => " ORDER BY REQV.version DESC ",
- 'output_format' => 'array', 'renderImageInline' => false);
+ 'output_format' => 'array', 'renderImageInline' => false,
+ 'decodeUsers' => true, 'outputLevel' => 'std');
$my['options'] = array_merge($my['options'], (array)$options);
@@ -210,7 +211,8 @@ function get_by_id($id,$version_id=self::ALL_VERSIONS,$version_number=1,$options
}
// added -1 AS revision_id to make some process easier
- $sql = " /* $debugMsg */ SELECT REQ.id,REQ.srs_id,REQ.req_doc_id," .
+ /*
+ $sql = " SELECT REQ.id,REQ.srs_id,REQ.req_doc_id," .
" REQV.scope,REQV.status,REQV.type,REQV.active," .
" REQV.is_open,REQV.author_id,REQV.version,REQV.id AS version_id," .
" REQV.expected_coverage,REQV.creation_ts,REQV.modifier_id," .
@@ -224,9 +226,36 @@ function get_by_id($id,$version_id=self::ALL_VERSIONS,$version_number=1,$options
" JOIN {$this->tables['req_specs']} REQ_SPEC ON REQ_SPEC.id = REQ.srs_id " .
" JOIN {$this->tables['nodes_hierarchy']} NH_RSPEC ON NH_RSPEC.id = REQ_SPEC.id " .
$where_clause . $filter_clause . $my['options']['order_by'];
+ */
+ switch($my['options']['outputLevel'])
+ {
+ case 'minimal':
+ $outf = " /* $debugMsg */ SELECT REQ.id,REQ.req_doc_id,NH_REQ.name AS title ";
+ break;
+
+ case 'std':
+ default:
+ $outf = " /* $debugMsg */ SELECT REQ.id,REQ.srs_id,REQ.req_doc_id," .
+ " REQV.scope,REQV.status,REQV.type,REQV.active," .
+ " REQV.is_open,REQV.author_id,REQV.version,REQV.id AS version_id," .
+ " REQV.expected_coverage,REQV.creation_ts,REQV.modifier_id," .
+ " REQV.modification_ts,REQV.revision, -1 AS revision_id, " .
+ " NH_REQ.name AS title, REQ_SPEC.testproject_id, " .
+ " NH_RSPEC.name AS req_spec_title, REQ_SPEC.doc_id AS req_spec_doc_id, NH_REQ.node_order ";
+ break;
+ }
+
+ // added -1 AS revision_id to make some process easier
+ $sql = $outf .
+ " FROM {$this->object_table} REQ " .
+ " JOIN {$this->tables['nodes_hierarchy']} NH_REQ ON NH_REQ.id = REQ.id " .
+ " JOIN {$this->tables['nodes_hierarchy']} NH_REQV ON NH_REQV.parent_id = NH_REQ.id ".
+ " JOIN {$this->tables['req_versions']} REQV ON REQV.id = NH_REQV.id " .
+ " JOIN {$this->tables['req_specs']} REQ_SPEC ON REQ_SPEC.id = REQ.srs_id " .
+ " JOIN {$this->tables['nodes_hierarchy']} NH_RSPEC ON NH_RSPEC.id = REQ_SPEC.id " .
+ $where_clause . $filter_clause . $my['options']['order_by'];
- // echo $sql;
$decodeUserMode = 'simple';
if ($version_id != self::LATEST_VERSION)
{
@@ -265,11 +294,6 @@ function get_by_id($id,$version_id=self::ALL_VERSIONS,$version_number=1,$options
}
$rs = null;
- // echo 'IN::' . __FUNCTION__ . '
';
- // new dBug($recordset);
-
-
- // 20141130 - inline images
if(!is_null($recordset) && $my['options']['renderImageInline'])
{
$k2l = array_keys($recordset);
@@ -280,12 +304,9 @@ function get_by_id($id,$version_id=self::ALL_VERSIONS,$version_number=1,$options
reset($recordset);
}
-
- if(!is_null($recordset))
+ $rs = $recordset;
+ if(!is_null($recordset) && $my['options']['decodeUsers'])
{
- // Decode users
- $rs = $recordset;
-
switch ($decodeUserMode)
{
case 'complex':
@@ -4172,10 +4193,16 @@ function monitorOff($req_id,$user_id=null,$tproject_id=null)
/**
*
*/
- function getMonitoredByUser($user_id,$tproject_id)
+ function getMonitoredByUser($user_id,$tproject_id,$opt=null,$filters=null)
{
$debugMsg = 'Class:' . __CLASS__ . ' - Method: ' . __FUNCTION__;
+ $my['opt'] = array('reqSpecID' => null);
+ $my['filters'] = array();
+
+ $my['opt'] = array_merge($my['opt'],(array)$opt);
+ $my['filters'] = array_merge($my['opt'],(array)$filters);
+
// simple checks
$safe = array();
$safe['user_id'] = intval($user_id);
@@ -4190,18 +4217,36 @@ function getMonitoredByUser($user_id,$tproject_id)
}
$rs = null;
- try
+
+ if( is_null($my['opt']['reqSpecID']) )
{
$sql = "/* $debugMsg */ " .
- " SELECT * FROM {$this->tables['req_monitor']} " .
- " WHERE user_id = {$safe['user_id']} " .
- " AND testproject_id = {$safe['tproject_id']}";
+ " SELECT RQM.* FROM {$this->tables['req_monitor']} RQM " .
+ " WHERE RQM.user_id = {$safe['user_id']} " .
+ " AND RQM.testproject_id = {$safe['tproject_id']}";
+ }
+ else
+ {
+ $sql = "/* $debugMsg */ " .
+ " SELECT RQM.* FROM {$this->tables['req_monitor']} RQM " .
+ " JOIN {$this->tables['nodes_hierarchy']} NH_REQ " .
+ " ON NH_REQ.id = RQM.req_id " .
+ " WHERE RQM.user_id = {$safe['user_id']} " .
+ " AND RQM.testproject_id = {$safe['tproject_id']} " .
+ " AND NH_REQ.parent_id = " . intval($my['opt']['reqSpecID']);
+ }
+
+ try
+ {
$rs = $this->db->fetchRowsIntoMap($sql,'req_id');
}
catch (Exception $e)
{
echo $e->getMessage();
}
+
+
+
return $rs;
}
@@ -4217,8 +4262,6 @@ function getReqMonitors($req_id,$opt=null)
$options = array('tproject_id' => 0, 'output' => 'map');
$options = array_merge($options,(array)$opt);
- //\Kint::dump($options);
-
// simple checks
$safe = array();
$safe['req_id'] = intval($req_id);
@@ -4265,8 +4308,6 @@ function notifyMonitors($req_id,$action,$user_id,$log_msg=null)
// who is monitoring?
$iuSet = $this->getReqMonitors($safe['req_id']);
- // \Kint::dump($iuSet);
-
if( is_null($iuSet) )
{
return;
@@ -4277,8 +4318,6 @@ function notifyMonitors($req_id,$action,$user_id,$log_msg=null)
$user = new tlUser($this->db);
}
- //\Kint::dump($iuSet);
- //die();
$author = $user->getNames($this->db,$user_id);
$author = $author[$user_id];
$idCard = $author['login'] .
@@ -4315,8 +4354,6 @@ function notifyMonitors($req_id,$action,$user_id,$log_msg=null)
$subj['target'] = array_keys($trf);
$subj['values'] = array_values($trf);
-
- // \Kint::dump($iuSet);
foreach($iuSet as $ue)
{
if( !isset($mailBodyCache[$ue['locale']]) )
diff --git a/lib/functions/requirement_spec_mgr.class.php b/lib/functions/requirement_spec_mgr.class.php
index 0c3b34861f..78697261c4 100644
--- a/lib/functions/requirement_spec_mgr.class.php
+++ b/lib/functions/requirement_spec_mgr.class.php
@@ -597,7 +597,8 @@ function get_requirements($id, $range = 'all', $testcase_id = null, $options=nul
{
$debugMsg = 'Class:' . __CLASS__ . ' - Method: ' . __FUNCTION__;
$my['options'] = array( 'order_by' => " ORDER BY NH_REQ.node_order,NH_REQ.name,REQ.req_doc_id",
- 'output' => 'standard');
+ 'output' => 'standard', 'outputLevel' => 'std', 'decodeUsers' => true);
+
$my['options'] = array_merge($my['options'], (array)$options);
// null => do not filter
@@ -655,11 +656,18 @@ function get_requirements($id, $range = 'all', $testcase_id = null, $options=nul
$latestVersionSet = $this->db->fetchRowsIntoMap($sql,'version_id');
$reqVersionSet = array_keys($latestVersionSet);
+ /*
$getOptions = null;
if( !is_null($my['options']['order_by']) )
{
$getOptions = array('order_by' => $my['options']['order_by']);
}
+ */
+
+ $getOptions['order_by'] = $my['options']['order_by'];
+ $getOptions['outputLevel'] = $my['options']['outputLevel'];
+ $getOptions['decodeUsers'] = $my['options']['decodeUsers'];
+
$rs = $this->req_mgr->get_by_id($reqSet,$reqVersionSet,null,$getOptions,$my['filters']);
switch($my['options']['output'])
diff --git a/lib/requirements/reqSpecCommands.class.php b/lib/requirements/reqSpecCommands.class.php
index 8d31742051..0cac439f74 100644
--- a/lib/requirements/reqSpecCommands.class.php
+++ b/lib/requirements/reqSpecCommands.class.php
@@ -6,8 +6,9 @@
* @filesource reqSpecCommands.class.php
* @author Francisco Mancardi
*
- * @internal revisions
- * @since 1.9.10
+ * @internal revisions
+ * @since 1.9.15
+ *
*/
class reqSpecCommands
{
@@ -171,7 +172,7 @@ function edit(&$argsObj,$request,$overwriteArgs=true)
$argsObj->scope = $guiObj->req_spec['scope'];
}
- return $guiObj;
+ return $guiObj;
}
/*
@@ -245,15 +246,15 @@ function: doUpdate
*/
function doUpdate(&$argsObj,$request)
{
- $descr_prefix = lang_get('req_spec_short') . TITLE_SEP;
+ $descr_prefix = lang_get('req_spec_short') . TITLE_SEP;
- $guiObj = $this->initGuiBean();
- $guiObj->submit_button_label=$this->submit_button_label;
- $guiObj->template = null;
+ $guiObj = $this->initGuiBean();
+ $guiObj->submit_button_label=$this->submit_button_label;
+ $guiObj->template = null;
$guiObj->req_spec_id = $argsObj->req_spec_id;
- $guiObj = $this->edit($argsObj,null,!self::OVERWRITESCOPE);
- $guiObj->user_feedback = '';
+ $guiObj = $this->edit($argsObj,null,!self::OVERWRITESCOPE);
+ $guiObj->user_feedback = '';
$guiObj->template = null;
$guiObj->askForRevision = false;
@@ -304,7 +305,7 @@ function: doDelete
*/
function doDelete(&$argsObj)
{
- $guiObj = $this->initGuiBean();
+ $guiObj = $this->initGuiBean();
$req_spec = $this->reqSpecMgr->get_by_id($argsObj->req_spec_id);
$this->reqSpecMgr->delete_deep($argsObj->req_spec_id);
@@ -334,16 +335,16 @@ function: reorder
*/
function reorder(&$argsObj)
{
- $guiObj = $this->initGuiBean();
- $guiObj->template = 'reqSpecReorder.tpl';
+ $guiObj = $this->initGuiBean();
+ $guiObj->template = 'reqSpecReorder.tpl';
$guiObj->main_descr = lang_get('testproject') . TITLE_SEP . $argsObj->tproject_name;
$guiObj->action_descr = lang_get('title_change_req_spec_order');
$order_by = ' ORDER BY NH.node_order,REQ_SPEC.id ';
$guiObj->all_req_spec = $this->reqSpecMgr->get_all_in_testproject($argsObj->tproject_id,$order_by);
- $guiObj->tproject_name=$argsObj->tproject_name;
- $guiObj->tproject_id=$argsObj->tproject_id;
- return $guiObj;
+ $guiObj->tproject_name=$argsObj->tproject_name;
+ $guiObj->tproject_id=$argsObj->tproject_id;
+ return $guiObj;
}
@@ -358,19 +359,19 @@ function: doReorder
*/
function doReorder(&$argsObj)
{
- $guiObj = $this->initGuiBean();
- $guiObj->tproject_name=$argsObj->tproject_name;
- $guiObj->tproject_id=$argsObj->tproject_id;
- $guiObj->template = 'project_req_spec_mgmt.tpl';
- $guiObj->main_descr = lang_get('testproject') . TITLE_SEP . $argsObj->tproject_name;
+ $guiObj = $this->initGuiBean();
+ $guiObj->tproject_name=$argsObj->tproject_name;
+ $guiObj->tproject_id=$argsObj->tproject_id;
+ $guiObj->template = 'project_req_spec_mgmt.tpl';
+ $guiObj->main_descr = lang_get('testproject') . TITLE_SEP . $argsObj->tproject_name;
$nodes_in_order = transform_nodes_order($argsObj->nodes_order);
// need to remove first element, is testproject
array_shift($nodes_in_order);
$this->reqSpecMgr->set_order($nodes_in_order);
- $guiObj->refreshTree=1;
- return $guiObj;
+ $guiObj->refreshTree=1;
+ return $guiObj;
}
@@ -418,8 +419,8 @@ function copyRequirements(&$argsObj,$options=null)
$my['options'] = array_merge($my['options'], (array)$options);
if( $my['options']['get_items'] )
{
- $obj->items = $this->reqSpecMgr->get_requirements($argsObj->req_spec_id,'all',null,
- $this->getRequirementsOptions);
+ $opt = $this->getRequirementsOptions + array('output' => 'minimal');
+ $obj->items = $this->reqSpecMgr->get_requirements($argsObj->req_spec_id,'all',null,$opt);
}
$obj->main_descr = lang_get('req_spec') . TITLE_SEP . $req_spec['title'];
$obj->action_descr = lang_get('copy_several_reqs');
@@ -842,4 +843,101 @@ private function initGuiObjForAttachmentOperations($argsObj)
return $guiObj;
}
+ /*
+ function: copyRequirements
+
+ args:
+
+ returns:
+
+ */
+ function bulkReqMon(&$argsObj,$options=null)
+ {
+ $obj = $this->initGuiBean();
+ $req_spec = $this->reqSpecMgr->get_by_id($argsObj->req_spec_id);
+
+ $my['options'] = array( 'get_items' => true);
+ $my['options'] = array_merge($my['options'], (array)$options);
+
+
+ if( $my['options']['get_items'] )
+ {
+ $opt = $this->getRequirementsOptions +
+ array('outputLevel' => 'minimal', 'decodeUsers' => false);
+ $obj->items = $this->reqSpecMgr->get_requirements($argsObj->req_spec_id,'all',null,$opt);
+ }
+
+ $opx = array('reqSpecID' => $argsObj->req_spec_id);
+ $monSet = $this->reqMgr->getMonitoredByUser($argsObj->user_id,$argsObj->tproject_id,$opx);
+
+ $obj->enable_start_btn = false;
+ $obj->enable_stop_btn = false;
+ foreach($obj->items as $xdx => &$itx)
+ {
+ $onOff = isset($monSet[$itx['id']]) ? true : false;
+ $itx['monitor'] = $onOff ? 'On' : 'Off';
+ $obj->enable_start_btn |= !$onOff;
+ $obj->enable_stop_btn |= $onOff;
+ }
+
+ $obj->main_descr = lang_get('req_spec') . TITLE_SEP . $req_spec['title'];
+ $obj->action_descr = lang_get('bulk_monitoring');
+ $obj->template = 'reqBulkMon.tpl';
+ $obj->containers = null;
+ $obj->page2call = 'lib/requirements/reqSpecEdit.php';
+ $obj->array_of_msg = '';
+ $obj->doActionButton = 'do' . ucfirst(__FUNCTION__);
+ $obj->req_spec_id = $argsObj->req_spec_id;
+ $obj->refreshTree = 0;
+
+ return $obj;
+ }
+
+ /**
+ *
+ *
+ */
+ function doBulkReqMon(&$argsObj)
+ {
+ $obj = $this->initGuiBean();
+ $obj->req = null;
+ $obj->req_spec_id = $argsObj->req_spec_id;
+ $obj->array_of_msg = '';
+
+ $m2r = null;
+ switch($argsObj->op)
+ {
+ case 'toogleMon':
+ $opx = array('reqSpecID' => $argsObj->req_spec_id);
+ $monSet = $this->reqMgr->getMonitoredByUser($argsObj->user_id,$argsObj->tproject_id,$opx);
+
+ foreach($argsObj->itemSet as $req_id)
+ {
+ $f2r = isset($monSet[$req_id]) ? 'monitorOff' : 'monitorOn';
+ $this->reqMgr->$f2r($req_id,$argsObj->user_id,$argsObj->tproject_id);
+ }
+ break;
+
+ case 'startMon':
+ $m2r = 'monitorOn';
+ break;
+
+ case 'stopMon':
+ $m2r = 'monitorOff';
+ break;
+ }
+
+ if( !is_null($m2r) )
+ {
+ foreach($argsObj->itemSet as $req_id)
+ {
+ $this->reqMgr->$m2r($req_id,$argsObj->user_id,$argsObj->tproject_id);
+ }
+ }
+
+ return $this->bulkReqMon($argsObj);
+ }
+
+
+
}
diff --git a/lib/requirements/reqSpecEdit.php b/lib/requirements/reqSpecEdit.php
index 7482442a74..8ef26a7680 100644
--- a/lib/requirements/reqSpecEdit.php
+++ b/lib/requirements/reqSpecEdit.php
@@ -8,7 +8,7 @@
* View existing and create a new req. specification.
*
* @internal revisions
- * @since 1.9.10
+ * @since 1.9.15
*
*/
require_once("../../config.inc.php");
@@ -37,6 +37,7 @@
{
$op = $commandMgr->$pFn($args,$_REQUEST);
}
+
renderGui($args,$gui,$op,$templateCfg,$editorCfg);
@@ -85,6 +86,19 @@ function init_args()
? $_SESSION['setting_refresh_tree_on_action'] : 0;
$args->countReq = is_null($args->countReq) ? 0 : intval($args->countReq);
+
+ // Process buttons
+ $args->op = null;
+ $btnSet = array('toogleMon','startMon','stopMon');
+ foreach( $btnSet as $btn )
+ {
+ if( isset($_REQUEST[$btn]) )
+ {
+ $args->op = $btn;
+ break;
+ }
+ }
+
return $args;
}
@@ -108,7 +122,9 @@ function renderGui(&$argsObj,$guiObj,$opObj,$templateCfg,$editorCfg)
'copyRequirements' => 'doCopyRequirements',
'doCopyRequirements' => 'doCopyRequirements',
'doCreateRevision' => 'doCreateRevision',
- 'fileUpload' => '', 'deleteFile' => '');
+ 'fileUpload' => '', 'deleteFile' => '',
+ 'bulkReqMon' => 'doBulkReqMon',
+ 'doBulkReqMon' => 'doBulkReqMon');
// ------------------------------------------------------------------------------------------------
// Web Editor Processing
$owebEditor = web_editor('scope',$argsObj->basehref,$editorCfg) ;
@@ -146,6 +162,7 @@ function renderGui(&$argsObj,$guiObj,$opObj,$templateCfg,$editorCfg)
case "doCopy":
case "doFreeze":
case "doDelete":
+ case "doBulkReqMon":
$guiObj->refreshTree = $argsObj->refreshTree;
break;
}
@@ -169,10 +186,12 @@ function renderGui(&$argsObj,$guiObj,$opObj,$templateCfg,$editorCfg)
case "doCreateRevision":
case "fileUpload":
case "deleteFile":
+ case "bulkReqMon":
+ case "doBulkReqMon":
$renderType = 'template';
$key2loop = get_object_vars($opObj);
- if($opObj->action_status_ok == false) // TICKET 4661
+ if($opObj->action_status_ok == false)
{
// Remember that scope normally is a WebRichEditor, and that
// we have already processed WebRichEditor
diff --git a/locale/en_GB/strings.txt b/locale/en_GB/strings.txt
index f7f6b6c8cc..d3088608aa 100644
--- a/locale/en_GB/strings.txt
+++ b/locale/en_GB/strings.txt
@@ -4003,4 +4003,11 @@ $TLS_copy_done = "Copy done";
$TLS_copy_tester_assignments_title = "Copy Tester Assignment";
$TLS_assignments = "Assignments:";
$TLS_no_builds_available_for_tester_copy = "There are no ACTIVE and OPEN builds to use";
+
+$TLS_btn_bulk_mon = 'Bulk Monitoring';
+$TLS_bulk_monitoring = $TLS_btn_bulk_mon;
+$TLS_monitoring = 'Monitoring';
+$TLS_btn_toogle_mon = 'Toogle Monitoring';
+$TLS_btn_start_mon = 'Start Monitoring';
+$TLS_btn_stop_mon = 'Stop Monitoring';
// ----- END ------------------------------------------------------------------