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 ------------------------------------------------------------------