PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/plan/buildEdit.php

https://bitbucket.org/pfernandez/testlink1.9.6
PHP | 574 lines | 369 code | 73 blank | 132 comment | 45 complexity | d0f0fdf62be7ed7e754e95f1bd076bfa MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, GPL-3.0
  1. <?php
  2. /**
  3. * TestLink Open Source Project - http://testlink.sourceforge.net/
  4. * This script is distributed under the GNU General Public License 2 or later.
  5. *
  6. * Filename $RCSfile: buildEdit.php,v $
  7. *
  8. * @version $Revision: 1.27 $
  9. * @modified $Date: 2010/08/20 13:42:43 $ $Author: franciscom $
  10. *
  11. * @internal revision
  12. * 20100820 - franciscom - init_source_build_selector() - refactoring
  13. * refactoring to use only one variable ($gui) in interface to smarty
  14. * 20100726 - asimon - added number of existing assignments to source build selection
  15. * 20100707 - asimon - BUGID 3406: copy user assignments from other builds
  16. * on creation of new builds
  17. * 20100706 - franciscom - BUGID 3581 added better check on release date
  18. * 20091121 - franciscom - BUGID - contribution
  19. * 20090509 - franciscom - BUGID - release_date
  20. * 20080827 - franciscom - BUGID 1692
  21. */
  22. require('../../config.inc.php');
  23. require_once("common.php");
  24. require_once("web_editor.php");
  25. $editorCfg = getWebEditorCfg('build');
  26. require_once(require_web_editor($editorCfg['type']));
  27. testlinkInitPage($db,false,false,"checkRights");
  28. $templateCfg = templateConfiguration();
  29. $op = new stdClass();
  30. $op->user_feedback = '';
  31. $op->buttonCfg = new stdClass();
  32. $op->buttonCfg->name = "";
  33. $op->buttonCfg->value = "";
  34. $smarty = new TLSmarty();
  35. $tplan_mgr = new testplan($db);
  36. $build_mgr = new build_mgr($db);
  37. $args = init_args($_REQUEST,$_SESSION);
  38. $gui = new stdClass();
  39. $gui->main_descr = lang_get('title_build_2') . config_get('gui_title_separator_2') .
  40. lang_get('test_plan') . config_get('gui_title_separator_1') . $args->tplan_name;
  41. $of = web_editor('notes',$_SESSION['basehref'],$editorCfg);
  42. $of->Value = getItemTemplateContents('build_template', $of->InstanceName, $args->notes);
  43. switch($args->do_action)
  44. {
  45. case 'edit':
  46. $op = edit($args,$build_mgr);
  47. $gui->closed_on_date = $args->closed_on_date;
  48. $of->Value = $op->notes;
  49. break;
  50. case 'create':
  51. $op = create($args);
  52. $gui->closed_on_date = $args->closed_on_date;
  53. break;
  54. case 'do_delete':
  55. $op = doDelete($args,$build_mgr);
  56. break;
  57. case 'do_update':
  58. $op = doUpdate($args,$build_mgr,$tplan_mgr);
  59. $of->Value = $op->notes;
  60. $templateCfg->template = $op->template;
  61. break;
  62. case 'do_create':
  63. $op = doCreate($args,$build_mgr,$tplan_mgr);
  64. $of->Value = $op->notes;
  65. $templateCfg->template = $op->template;
  66. break;
  67. }
  68. $gui->release_date = $args->release_date;
  69. $gui->operation_descr = $op->operation_descr;
  70. $gui->user_feedback = $op->user_feedback;
  71. $gui->buttonCfg = $op->buttonCfg;
  72. $gui->mgt_view_events = $_SESSION['currentUser']->hasRight($db,"mgt_view_events");
  73. $gui->editorType = $editorCfg['type'];
  74. if(trim($gui->release_date) == '')
  75. {
  76. $gui->release_date = '0000-00-00';
  77. }
  78. renderGui($smarty,$args,$tplan_mgr,$templateCfg,$of,$gui);
  79. /*
  80. * INITialize page ARGuments, using the $_REQUEST and $_SESSION
  81. * super-global hashes.
  82. * Important: changes in HTML input elements on the Smarty template
  83. * must be reflected here.
  84. *
  85. *
  86. * @parameter hash request_hash the $_REQUEST
  87. * @parameter hash session_hash the $_SESSION
  88. * @return object with html values tranformed and other
  89. * generated variables.
  90. * @internal revisions:
  91. * 20100707 - asimon - BUGID 3406 - added source_build_id and copy_tester_assignments
  92. */
  93. function init_args($request_hash, $session_hash)
  94. {
  95. $args = new stdClass();
  96. $request_hash = strings_stripSlashes($request_hash);
  97. $nullable_keys = array('notes','do_action','build_name');
  98. foreach($nullable_keys as $value)
  99. {
  100. $args->$value = isset($request_hash[$value]) ? $request_hash[$value] : null;
  101. }
  102. // BUGID 3406 - added source_build_id
  103. $intval_keys = array('build_id' => 0, 'source_build_id' => 0);
  104. foreach($intval_keys as $key => $value)
  105. {
  106. $args->$key = isset($request_hash[$key]) ? intval($request_hash[$key]) : $value;
  107. }
  108. // BUGID 3406 - added copy_tester_assignments
  109. $bool_keys = array('is_active' => 0, 'is_open' => 0, 'copy_to_all_tplans' => 0,
  110. 'copy_tester_assignments' => 0);
  111. foreach($bool_keys as $key => $value)
  112. {
  113. $args->$key = isset($request_hash[$key]) ? 1 : $value;
  114. }
  115. $args->release_date = '';
  116. $args->closed_on_date = isset($request_hash['closed_on_date']) ? $request_hash['closed_on_date'] : null;
  117. // Important!!!
  118. // name of these variables is generated by smarty (See html_select_date in Smarty Manual)
  119. $date_vars = array('release_date_Year','release_date_Month','release_date_Day');
  120. $create_date = true;
  121. foreach($date_vars as $my)
  122. {
  123. $$my = isset($_REQUEST[$my]) ? $_REQUEST[$my] : null;
  124. $create_date = $create_date && !is_null($$my) && trim($$my) != '';
  125. }
  126. if($create_date)
  127. {
  128. $args->release_date = $release_date_Year . "-" . $release_date_Month . "-" . $release_date_Day;
  129. }
  130. $args->tplan_id = isset($session_hash['testplanID']) ? $session_hash['testplanID']: 0;
  131. $args->tplan_name = isset($session_hash['testplanName']) ? $session_hash['testplanName']: '';
  132. $args->testprojectID = $session_hash['testprojectID'];
  133. $args->testprojectName = $session_hash['testprojectName'];
  134. $args->userID = $session_hash['userID'];
  135. return $args;
  136. }
  137. /*
  138. function: edit
  139. edit action
  140. args :
  141. returns:
  142. */
  143. function edit(&$argsObj,&$buildMgr)
  144. {
  145. $binfo = $buildMgr->get_by_id($argsObj->build_id);
  146. $op = new stdClass();
  147. $op->buttonCfg = new stdClass();
  148. $op->buttonCfg->name = "do_update";
  149. $op->buttonCfg->value = lang_get('btn_save');
  150. $op->notes = $binfo['notes'];
  151. $op->user_feedback = '';
  152. $argsObj->build_name = $binfo['name'];
  153. $argsObj->is_active = $binfo['active'];
  154. $argsObj->is_open = $binfo['is_open'];
  155. $argsObj->release_date = $binfo['release_date'];
  156. if( $binfo['closed_on_date'] == '')
  157. {
  158. $argsObj->closed_on_date = mktime(0, 0, 0, date("m") , date("d"), date("Y"));
  159. }
  160. else
  161. {
  162. $datePieces = explode("-",$binfo['closed_on_date']);
  163. $argsObj->closed_on_date = mktime(0,0,0,$datePieces[1],$datePieces[2],$datePieces[0]);
  164. }
  165. $op->operation_descr=lang_get('title_build_edit') . TITLE_SEP_TYPE3 . $argsObj->build_name;
  166. return $op;
  167. }
  168. /*
  169. function: create
  170. prepares environment to manage user interaction on a create operations
  171. args: $argsObj: reference to input values received by page.
  172. returns: object with part of gui configuration
  173. */
  174. function create(&$argsObj)
  175. {
  176. $op = new stdClass();
  177. $op->operation_descr = lang_get('title_build_create');
  178. $op->buttonCfg = new stdClass();
  179. $op->buttonCfg->name = "do_create";
  180. $op->buttonCfg->value = lang_get('btn_create');
  181. $op->user_feedback = '';
  182. $argsObj->is_active = 1;
  183. $argsObj->is_open = 1;
  184. $argsObj->closed_on_date = mktime(0, 0, 0, date("m") , date("d"), date("Y"));
  185. return $op;
  186. }
  187. /*
  188. function: doDelete
  189. args :
  190. returns:
  191. */
  192. function doDelete(&$argsObj,&$buildMgr)
  193. {
  194. $op = new stdClass();
  195. $op->user_feedback = '';
  196. $op->operation_descr = '';
  197. $op->buttonCfg = null;
  198. $build = $buildMgr->get_by_id($argsObj->build_id);
  199. if (!$buildMgr->delete($argsObj->build_id))
  200. {
  201. $op->user_feedback = lang_get("cannot_delete_build");
  202. }
  203. else
  204. {
  205. logAuditEvent(TLS("audit_build_deleted",$argsObj->testprojectName,$argsObj->tplan_name,$build['name']),
  206. "DELETE",$argsObj->build_id,"builds");
  207. }
  208. return $op;
  209. }
  210. /*
  211. function:
  212. args :
  213. returns:
  214. */
  215. function renderGui(&$smartyObj,&$argsObj,&$tplanMgr,$templateCfg,$owebeditor,&$guiObj)
  216. {
  217. $doRender = false;
  218. switch($argsObj->do_action)
  219. {
  220. case "do_create":
  221. case "do_delete":
  222. case "do_update":
  223. $doRender = true;
  224. $tpl = is_null($templateCfg->template) ? 'buildView.tpl' : $templateCfg->template;
  225. break;
  226. case "edit":
  227. case "create":
  228. $doRender = true;
  229. $tpl = is_null($templateCfg->template) ? $templateCfg->default_template : $templateCfg->template;
  230. break;
  231. }
  232. if($doRender)
  233. {
  234. $enable_copy = ($argsObj->do_action == 'create' || $argsObj->do_action == 'do_create') ? 1 : 0;
  235. // Attention this is affected by changes in templates
  236. $guiObj->buildSet=$tplanMgr->get_builds($argsObj->tplan_id);
  237. $guiObj->tplan_name=$argsObj->tplan_name;
  238. $guiObj->build_id = $argsObj->build_id;
  239. $guiObj->build_name = $argsObj->build_name;
  240. $guiObj->is_active = $argsObj->is_active;
  241. $guiObj->is_open = $argsObj->is_open;
  242. $guiObj->notes = $owebeditor->CreateHTML();
  243. $guiObj->enable_copy = $enable_copy;
  244. // BUGID 3406
  245. $html_menu = init_source_build_selector($tplanMgr, $argsObj);
  246. $guiObj->source_build = $html_menu;
  247. $guiObj->copy_tester_assignments = $argsObj->copy_tester_assignments;
  248. $smartyObj->assign('gui',$guiObj);
  249. $smartyObj->display($templateCfg->template_dir . $tpl);
  250. }
  251. }
  252. /*
  253. function: doCreate
  254. args :
  255. returns:
  256. @internal revisions:
  257. 20100722 - asimon - BUGID 3406 - using assignment_mgr of tplan_mgr instead of new one
  258. 20100707 - asimon - BUGID 3406 - added assignment_mgr to copy assignments
  259. */
  260. function doCreate(&$argsObj,&$buildMgr,&$tplanMgr) //,&$smartyObj)
  261. {
  262. $op = new stdClass();
  263. $op->operation_descr = '';
  264. $op->user_feedback = '';
  265. $op->template = "buildEdit.tpl";
  266. $op->notes = $argsObj->notes;
  267. $op->status_ok = false;
  268. $op->buttonCfg = null;
  269. $check = crossChecks($argsObj,$tplanMgr);
  270. $targetDate=null;
  271. if($check->status_ok)
  272. {
  273. $user_feedback = lang_get("cannot_add_build");
  274. $buildID = $buildMgr->create($argsObj->tplan_id,$argsObj->build_name,$argsObj->notes,
  275. $argsObj->is_active,$argsObj->is_open,$argsObj->release_date);
  276. if ($buildID)
  277. {
  278. if($argsObj->is_open == 1)
  279. {
  280. $targetDate=null;
  281. }
  282. else
  283. {
  284. $targetDate=date("Y-m-d",$argsObj->closed_on_date);
  285. }
  286. $buildMgr->setClosedOnDate($buildID,$targetDate);
  287. // BUGID 3406 - copy tester assignments from chosen source build
  288. if ($argsObj->copy_tester_assignments && $argsObj->source_build_id) {
  289. $tplanMgr->assignment_mgr->copy_assignments($argsObj->source_build_id, $buildID, $argsObj->userID);
  290. }
  291. $op->user_feedback = '';
  292. $op->notes = '';
  293. $op->template = null;
  294. $op->status_ok = true;
  295. logAuditEvent(TLS("audit_build_created",$argsObj->testprojectName,$argsObj->tplan_name,$argsObj->build_name),
  296. "CREATE",$buildID,"builds");
  297. }
  298. }
  299. if(!$op->status_ok)
  300. {
  301. $op->buttonCfg = new stdClass();
  302. $op->buttonCfg->name = "do_create";
  303. $op->buttonCfg->value = lang_get('btn_create');
  304. $op->user_feedback = $check->user_feedback;
  305. }
  306. elseif($argsObj->copy_to_all_tplans)
  307. {
  308. doCopyToTestPlans($argsObj,$buildMgr,$tplanMgr);
  309. }
  310. return $op;
  311. }
  312. /*
  313. function: doUpdate
  314. args :
  315. returns:
  316. */
  317. function doUpdate(&$argsObj,&$buildMgr,&$tplanMgr)
  318. {
  319. $op = new stdClass();
  320. $op->operation_descr = '';
  321. $op->user_feedback = '';
  322. $op->template = "buildEdit.tpl";
  323. $op->notes = $argsObj->notes;
  324. $op->status_ok = false;
  325. $op->buttonCfg = null;
  326. $oldObjData = $buildMgr->get_by_id($argsObj->build_id);
  327. $oldname = $oldObjData['name'];
  328. $check = crossChecks($argsObj,$tplanMgr);
  329. if($check->status_ok)
  330. {
  331. $user_feedback = lang_get("cannot_update_build");
  332. if ($buildMgr->update($argsObj->build_id,$argsObj->build_name,$argsObj->notes,
  333. $argsObj->is_active,$argsObj->is_open,$argsObj->release_date))
  334. {
  335. if( $argsObj->closed_on_date == '')
  336. {
  337. $argsObj->closed_on_date = mktime(0, 0, 0, date("m") , date("d"), date("Y"));
  338. }
  339. if($argsObj->is_open == 1)
  340. {
  341. $targetDate=null;
  342. }
  343. else
  344. {
  345. $targetDate=date("Y-m-d",$argsObj->closed_on_date);
  346. }
  347. $buildMgr->setClosedOnDate($argsObj->build_id,$targetDate);
  348. $op->user_feedback = '';
  349. $op->notes = '';
  350. $op->template = null;
  351. $op->status_ok = true;
  352. logAuditEvent(TLS("audit_build_saved",$argsObj->testprojectName,$argsObj->tplan_name,$argsObj->build_name),
  353. "SAVE",$argsObj->build_id,"builds");
  354. }
  355. }
  356. if(!$op->status_ok)
  357. {
  358. $op->operation_descr = lang_get('title_build_edit') . TITLE_SEP_TYPE3 . $oldname;
  359. $op->buttonCfg = new stdClass();
  360. $op->buttonCfg->name = "do_update";
  361. $op->buttonCfg->value = lang_get('btn_save');
  362. $op->user_feedback = $check->user_feedback;
  363. }
  364. return $op;
  365. }
  366. /*
  367. function: crossChecks
  368. do checks that are common to create and update operations
  369. - name already exists in this testplan?
  370. args:
  371. returns: -
  372. @internal revision
  373. 20100706 - franciscom - BUGID 3581
  374. */
  375. function crossChecks($argsObj,&$tplanMgr)
  376. {
  377. $op = new stdClass();
  378. $op->user_feedback = '';
  379. $op->status_ok = 1;
  380. $buildID = ($argsObj->do_action == 'do_update') ? $argsObj->build_id : null;
  381. if( $tplanMgr->check_build_name_existence($argsObj->tplan_id,$argsObj->build_name,$buildID) )
  382. {
  383. $op->user_feedback = lang_get("warning_duplicate_build") . TITLE_SEP_TYPE3 . $argsObj->build_name;
  384. $op->status_ok = 0;
  385. }
  386. // check is date is valid
  387. if( $op->status_ok )
  388. {
  389. $datestring = 'YYYY-MM-DD';
  390. $ok_len = strlen($datestring);
  391. $ok_pieces_qty = 3;
  392. $rdate = trim($argsObj->release_date);
  393. $rdate_len = strlen($rdate) ;
  394. if( $rdate_len != 0 && $rdate_len != $ok_len )
  395. {
  396. $op->status_ok = 0;
  397. }
  398. else if ($rdate_len == $ok_len )
  399. {
  400. // cut in pieces
  401. $idx_year = 0;
  402. $idx_month = 1;
  403. $idx_day = 2;
  404. $date_pieces = explode('-',$rdate);
  405. if( count($date_pieces) == $ok_pieces_qty )
  406. {
  407. $status_ok = checkdate($date_pieces[$idx_month],$date_pieces[$idx_day],$date_pieces[$idx_year]);
  408. $op->status_ok = $status_ok ? 1 : 0;
  409. }
  410. }
  411. if( $op->status_ok == 0 )
  412. {
  413. $op->user_feedback = lang_get("invalid_release_date");
  414. }
  415. }
  416. return $op;
  417. }
  418. /*
  419. function: doCopyToTestPlans
  420. copy do checks that are common to create and update operations
  421. - name already exists in this testplan?
  422. args:
  423. returns: -
  424. */
  425. function doCopyToTestPlans(&$argsObj,&$buildMgr,&$tplanMgr)
  426. {
  427. $tprojectMgr = new testproject($tplanMgr->db);
  428. // exclude this testplan
  429. $filters = array('tplan2exclude' => $argsObj->tplan_id);
  430. $tplanset = $tprojectMgr->get_all_testplans($argsObj->testprojectID,$filters);
  431. if(!is_null($tplanset))
  432. {
  433. foreach($tplanset as $id => $info)
  434. {
  435. if(!$tplanMgr->check_build_name_existence($id,$argsObj->build_name))
  436. {
  437. $buildMgr->create($id,$argsObj->build_name,$argsObj->notes,
  438. $argsObj->is_active,$argsObj->is_open);
  439. }
  440. }
  441. }
  442. }
  443. function checkRights(&$db,&$user)
  444. {
  445. return $user->hasRight($db,'testplan_create_build');
  446. }
  447. /**
  448. * Initialize the HTML select box for selection of a source build when
  449. * user wants to copy the user assignments on creation of a new build.
  450. *
  451. * @author Andreas Simon
  452. * @param testplan $testplan_mgr reference to testplan manager object
  453. * @param object $argsObj reference to user input object
  454. * @return array $htmlMenu array structure with all information needed for the menu
  455. *
  456. * @internal revision
  457. * 20100820 - franciscom - refactoring to remove unneeded support/temp variables and
  458. * event viewer complain due to foreach() over a null variable.
  459. */
  460. function init_source_build_selector(&$testplan_mgr, &$argsObj) {
  461. $htmlMenu = array('items' => null, 'selected' => null, 'build_count' => 0);
  462. $htmlMenu['items'] = $testplan_mgr->get_builds_for_html_options($argsObj->tplan_id);
  463. // get the number of existing execution assignments with each build
  464. if( !is_null($htmlMenu['items']) )
  465. {
  466. $htmlMenu['build_count'] = count($htmlMenu['items']);
  467. foreach ($htmlMenu['items'] as $key => $name) {
  468. $count = $testplan_mgr->assignment_mgr->get_count_of_assignments_for_build_id($key);
  469. $htmlMenu['items'][$key] = $name . " (" . $count . ")";
  470. }
  471. // if no build has been chosen yet, select the newest build by default
  472. if( !$argsObj->source_build_id )
  473. {
  474. $htmlMenu['selected'] = key($htmlMenu['items']);
  475. }
  476. }
  477. return $htmlMenu;
  478. } // end of method
  479. ?>