control.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <?php
  2. /**
  3. * The control file of testreport of ZenTaoPMS.
  4. *
  5. * @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
  6. * @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
  7. * @author Yidong Wang <yidong@cnezsoft.com>
  8. * @package testreport
  9. * @version $Id$
  10. * @link https://www.zentao.net
  11. */
  12. class testreport extends control
  13. {
  14. public $projectID = 0;
  15. /**
  16. * All products.
  17. *
  18. * @var array
  19. * @access public
  20. */
  21. public $products = array();
  22. /**
  23. * 构造函数。
  24. * Construct
  25. *
  26. * @param string $moduleName
  27. * @param string $methodName
  28. * @access public
  29. * @return void
  30. */
  31. public function __construct($moduleName = '', $methodName = '')
  32. {
  33. parent::__construct($moduleName, $methodName);
  34. $this->loadModel('project');
  35. $this->loadModel('execution');
  36. $this->loadModel('product');
  37. $this->loadModel('story');
  38. $this->loadModel('build');
  39. $this->loadModel('bug');
  40. $this->loadModel('tree');
  41. $this->loadModel('testcase');
  42. $this->loadModel('testtask');
  43. $this->loadModel('user');
  44. $this->app->loadLang('report');
  45. /* Get product data. */
  46. $products = array();
  47. $objectID = 0;
  48. $tab = $this->app->tab == 'project' || $this->app->tab == 'execution' ? $this->app->tab : 'qa';
  49. if(!isInModal())
  50. {
  51. if($tab == 'qa')
  52. {
  53. $products = $this->product->getPairs();
  54. }
  55. else
  56. {
  57. if(common::isTutorialMode())
  58. {
  59. $products = $this->loadModel('tutorial')->getProductStats();
  60. }
  61. else
  62. {
  63. $objectID = $this->session->{$tab};
  64. $products = $this->product->getProducts($objectID, 'all', '', false);
  65. }
  66. }
  67. if(empty($products) && !isInModal() && (helper::isAjaxRequest('zin') || helper::isAjaxRequest('fetch'))) $this->locate($this->createLink('product', 'showErrorNone', "moduleName={$tab}&activeMenu=testreport&objectID=$objectID"));
  68. }
  69. else
  70. {
  71. $products = $this->product->getPairs();
  72. }
  73. $this->view->products = $this->products = $products;
  74. }
  75. /**
  76. * 浏览测试报告。
  77. * Browse report.
  78. *
  79. * @param int $objectID
  80. * @param string $objectType
  81. * @param int $extra
  82. * @param string $orderBy
  83. * @param int $recTotal
  84. * @param int $recPerPage
  85. * @param int $pageID
  86. * @access public
  87. * @return void
  88. */
  89. public function browse($objectID = 0, $objectType = 'product', $extra = 0, $orderBy = 'id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
  90. {
  91. if(strpos('product|execution|project', $objectType) === false) return $this->send(array('result' => 'fail', 'message' => 'Type Error!'));
  92. $objectID = $this->testreportZen->commonAction($objectID, $objectType);
  93. $object = $this->{$objectType}->getById($objectID);
  94. if($extra) $task = $this->testtask->getByID($extra);
  95. $reports = $this->testreportZen->getReportsForBrowse($objectID, $objectType, $extra, $orderBy, $recTotal, $recPerPage, $pageID);
  96. if(empty($reports) && common::hasPriv('testreport', 'create'))
  97. {
  98. $param = '';
  99. if($objectType == 'product' && $extra) $param = "objectID={$extra}&objectType=testtask";
  100. if(in_array($objectType, array('project', 'execution')) && ($extra || !empty($_POST['taskIdList']))) $param = "objectID={$objectID}&objectType={$objectType}&extra={$extra}&begin=&end=";
  101. if($param)
  102. {
  103. $url = $this->createLink('testreport', 'create', $param);
  104. if(!empty($_POST['taskIdList'])) $url .= (strpos($url, '?') !== false ? '&' : '?') . 'taskIdList=' . implode(',', $_POST['taskIdList']);
  105. $this->locate($url);
  106. }
  107. }
  108. $this->session->set('reportList', $this->app->getURI(true), $this->app->tab);
  109. $executions = array();
  110. $tasks = array();
  111. foreach($reports as $report)
  112. {
  113. $executions[$report->execution] = $report->execution;
  114. foreach(explode(',', $report->tasks) as $taskID) $tasks[$taskID] = $taskID;
  115. }
  116. $this->view->title = ($extra ? $task->name : $object->name) . $this->lang->hyphen . $this->lang->testreport->common;
  117. $this->view->reports = $reports;
  118. $this->view->orderBy = $orderBy;
  119. $this->view->objectID = $objectID;
  120. $this->view->objectType = $objectType;
  121. $this->view->object = $object;
  122. $this->view->extra = $extra;
  123. $this->view->users = $this->user->getPairs('noletter|noclosed|nodeleted');
  124. $this->view->tasks = $tasks ? $this->loadModel('testtask')->getPairsByList($tasks) : array();
  125. $this->view->executions = $this->dao->select('id,name')->from(TABLE_PROJECT)->fetchPairs();
  126. $this->view->canBeChanged = common::canModify($objectType, $object); // Determines whether an object is editable.
  127. $this->display();
  128. }
  129. /**
  130. * 创建一个测试报告。
  131. * Create a report.
  132. *
  133. * @param int $objectID
  134. * @param string $objectType
  135. * @param string $extra
  136. * @param string $begin
  137. * @param string $end
  138. * @access public
  139. * @return void
  140. */
  141. public function create($objectID = 0, $objectType = 'testtask', $extra = '', $begin = '', $end = '')
  142. {
  143. if($_POST)
  144. {
  145. $testreport = $this->testreportZen->prepareTestreportForCreate();
  146. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  147. $reportID = $this->testreport->create($testreport);
  148. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  149. $this->loadModel('action')->create('testreport', $reportID, 'Opened');
  150. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => inlink('view', "reportID={$reportID}"), 'id' => $reportID));
  151. }
  152. if($this->get->taskIdList) $extra = $this->get->taskIdList;
  153. if($objectType == 'testtask') list($objectID, $task, $productID) = $this->testreportZen->assignTaskParisForCreate($objectID, $extra);
  154. if(!$objectID) return $this->send(array('result' => 'fail', 'load' => array('confirm' => $this->lang->testreport->noObjectID, 'confirmed' => inlink('browse', "proudctID={$productID}"), 'canceled' => inlink('browse', "proudctID={$productID}"))));
  155. if($objectType == 'testtask')
  156. {
  157. if(empty($task->joint) && $productID != $task->product) return $this->send(array('result' => 'fail', 'load' => array('confirm' => $this->lang->error->accessDenied, 'confirmed' => inlink('browse', "proudctID={$productID}"), 'canceled' => inlink('browse', "proudctID={$productID}"))));
  158. if($task->build == 'trunk') return $this->send(array('result' => 'fail', 'load' => array('confirm' => $this->lang->testreport->errorTrunk, 'confirmed' => inlink('browse', "proudctID={$productID}"), 'canceled' => inlink('browse', "proudctID={$productID}"))));
  159. $reportData = $this->testreportZen->assignTesttaskReportData($objectID, $begin, $end, $productID, $task, 'create');
  160. }
  161. elseif($objectType == 'execution' || $objectType == 'project')
  162. {
  163. $executionID = $this->testreportZen->commonAction($objectID, $objectType);
  164. if($executionID != $objectID) return $this->send(array('result' => 'fail', 'load' => array('confirm' => $this->lang->error->accessDenied, 'confirmed' => inlink('browse', "proudctID={$productID}"), 'canceled' => inlink('browse', "proudctID={$productID}"))));
  165. $reportData = $this->testreportZen->assignProjectReportDataForCreate($objectID, $objectType, $extra, $begin, $end, $executionID);
  166. if(count($reportData['productIdList']) > 1 && !in_array($this->config->edition, array('max', 'ipd'))) return $this->send(array('result' => 'fail', 'load' => array('confirm' => $this->lang->testreport->moreProduct, 'confirmed' => $this->createLink($objectType, 'testtask', "objectID={$objectID}"), 'canceled' => $this->createLink($objectType, 'testtask', "objectID={$objectID}"))));
  167. }
  168. $this->testreportZen->assignReportData($reportData, 'create');
  169. if($this->app->tab == 'project') $this->view->projectID = $this->session->project;
  170. if($this->app->tab == 'qa') $this->view->productID = $this->session->product;
  171. $this->view->objectID = $objectID;
  172. $this->view->objectType = $objectType;
  173. $this->view->extra = $extra;
  174. $this->display();
  175. }
  176. /**
  177. * Edit report
  178. *
  179. * @param int $reportID
  180. * @param string $begin
  181. * @param string $end
  182. * @access public
  183. * @return void
  184. */
  185. public function edit($reportID, $begin = '', $end ='')
  186. {
  187. $oldReport = $this->testreport->getById($reportID);
  188. if($_POST)
  189. {
  190. $report = $this->testreportZen->prepareTestreportForEdit($reportID);
  191. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  192. $changes = $this->testreport->update($report, $oldReport);
  193. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  194. $actionID = $this->loadModel('action')->create('testreport', $reportID, 'Edited');
  195. if(!empty($changes)) $this->action->logHistory($actionID, $changes);
  196. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => inlink('view', "reportID=$reportID")));
  197. }
  198. if($this->app->tab == 'qa' && !empty($oldReport->product)) $objectType = 'product';
  199. if($this->app->tab == 'execution' || $this->app->tab == 'project') $objectType = $this->app->tab;
  200. if(isset($objectType))
  201. {
  202. $objectID = $this->testreportZen->commonAction($oldReport->{$objectType}, $objectType);
  203. if($objectID != $oldReport->{$objectType}) return $this->send(array('result' => 'fail', 'message' => $this->lang->error->accessDenied, 'load' => array('alert' => $this->lang->error->accessDenied, 'locate' => array('load' => true)))); ;
  204. }
  205. if($oldReport->objectType == 'testtask')
  206. {
  207. $task = $this->testtask->getByID($oldReport->objectID);
  208. if($task->build == 'trunk') return $this->send(array('result' => 'fail', 'message' => $this->lang->error->errorTrunk, 'load' => array('alert' => $this->lang->error->errorTrunk, 'locate' => array('load' => true))));
  209. $reportData = $this->testreportZen->assignTesttaskReportData($oldReport->objectID, $begin ?: $oldReport->begin, $end ?: $oldReport->end, $oldReport->product, $task, 'edit');
  210. }
  211. elseif($oldReport->objectType == 'execution' || $oldReport->objectType == 'project')
  212. {
  213. $reportData = $this->testreportZen->assignProjectReportDataForEdit($oldReport, $begin, $end);
  214. }
  215. $reportData['cases'] = $oldReport->cases;
  216. $this->testreportZen->assignReportData($reportData, 'edit');
  217. $this->view->title = $oldReport->title . $this->lang->testreport->edit;
  218. $this->view->report = $oldReport;
  219. $this->display();
  220. }
  221. /**
  222. * 查看一个测试报告。
  223. * View a test report.
  224. *
  225. * @param int $reportID
  226. * @param string $tab
  227. * @param int $recTotal
  228. * @param int $recPerPage
  229. * @param int $pageID
  230. * @access public
  231. * @return void
  232. */
  233. public function view($reportID, $tab = 'basic', $recTotal = 0, $recPerPage = 100, $pageID = 1)
  234. {
  235. $report = $this->testreport->getById($reportID);
  236. if(!$report) return $this->send(array('result' => 'fail', 'load' => array('alert' => $this->lang->notFound)));
  237. /* Set session. */
  238. $this->session->project = $report->project;
  239. /* Check object type. */
  240. if($this->app->tab == 'qa' && !empty($report->product)) $objectType = 'product';
  241. if($this->app->tab == 'execution' || $this->app->tab == 'project') $objectType = $this->app->tab;
  242. if(isset($objectType))
  243. {
  244. $objectID = $this->testreportZen->commonAction($report->{$objectType}, $objectType);
  245. if($objectID != $report->{$objectType}) return $this->send(array('result' => 'fail', 'message' => $this->lang->error->accessDenied, 'load' => array('alert' => $this->lang->error->accessDenied, 'locate' => array('load' => true)))); ;
  246. }
  247. /* Get report data. */
  248. $reportData = $this->testreportZen->buildReportDataForView($report);
  249. if($report->objectType == 'testtask')
  250. {
  251. $this->testreportZen->setChartDatas($report->objectID);
  252. }
  253. elseif($reportData['tasks'])
  254. {
  255. foreach($reportData['tasks'] as $task) $this->testreportZen->setChartDatas($task->id);
  256. }
  257. /* Load pager. */
  258. $this->app->loadClass('pager', true);
  259. if($this->app->getViewType() == 'mhtml') $recPerPage = 10;
  260. $pager = pager::init($recTotal, $recPerPage, $pageID);
  261. /* Assign report data. */
  262. $this->testreportZen->assignReportData($reportData, 'view', $pager);
  263. $this->view->title = $report->title;
  264. $this->view->browseLink = isset($objectType) ? inlink('browse', "objectID={$objectID}&objectType={$objectType}}") : '';
  265. $this->view->tab = $tab;
  266. $this->view->actions = $this->loadModel('action')->getList('testreport', $reportID);
  267. $this->display();
  268. }
  269. /**
  270. * 删除一个测试报告。
  271. * Delete report.
  272. *
  273. * @param int $reportID
  274. * @access public
  275. * @return void
  276. */
  277. public function delete($reportID)
  278. {
  279. $testreport = $this->testreport->getByID($reportID);
  280. $locateLink = $this->session->reportList ? $this->session->reportList : inlink('browse', "productID={$testreport->product}");
  281. $this->testreport->delete(TABLE_TESTREPORT, $reportID);
  282. if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
  283. return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'load' => $locateLink));
  284. }
  285. }