ipd.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. /**
  3. * Build operate menu.
  4. *
  5. * @param object $story
  6. * @param string $type
  7. * @param object $execution
  8. * @param string $storyType story|requirement
  9. * @access public
  10. * @return array
  11. */
  12. public function buildOperateMenu($story, $type = 'view', $execution = null, $storyType = 'story')
  13. {
  14. $this->lang->story->changeTip = $storyType == 'story' ? $this->lang->story->changeTip : $this->lang->story->URChangeTip;
  15. if($story->type != 'requirement' and !empty($story->confirmeObject))
  16. {
  17. $mothed = $story->confirmeObject['type'] == 'confirmedretract' ? 'confirmDemandRetract' : 'confirmDemandUnlink';
  18. return $this->buildMenu('story', $mothed, "objectID=$story->id&object=story&extra={$story->confirmeObject['id']}", $story, 'view', 'search', '', 'iframe', true);
  19. }
  20. return parent::buildOperateMenu($story, $type, $execution, $storyType);
  21. }
  22. /**
  23. * Get affect objects.
  24. *
  25. * @param mixed $objects
  26. * @param string $objectType
  27. * @param string $object
  28. * @access public
  29. * @return void
  30. */
  31. public function getAffectObject($objects = '', $objectType = '', $objectInfo = '')
  32. {
  33. if(empty($objects) and empty($objectInfo)) return $objects;
  34. if(empty($objects) and $objectInfo) $objects = array($objectInfo->id => $objectInfo);
  35. $objectIDList = array();
  36. $storyIDList = array();
  37. foreach($objects as $object)
  38. {
  39. $objectID = $object->id;
  40. if($this->app->rawModule == 'testtask') $objectID = $object->case;
  41. if(!empty($object->children)) $this->getAffectObject($object->children, $objectType);
  42. $objectIDList[] = $objectID;
  43. $storyIDList[] = $objectType == 'story' ? $object->id : $object->story;
  44. $object->confirmeObject = array();
  45. $object->URs = '';
  46. }
  47. /* 根据需求ID查找父需求。*/
  48. $parentStories = $this->dao->select('id,parent')->from(TABLE_STORY)
  49. ->where('deleted')->eq(0)
  50. ->andWhere('id')->in($storyIDList)
  51. ->andWhere('parent')->gt(0)
  52. ->fetchPairs('id', 'parent');
  53. /* 获取需要确认的用户需求id。 */
  54. $URs = $this->getStoryRelationByIds($storyIDList, 'story');
  55. $URIds = implode(',', $URs);
  56. if($parentStories)
  57. {
  58. $parentURs = $this->getStoryRelationByIds($parentStories, 'story');
  59. $URIds .= ',' . implode(',', $parentURs);
  60. foreach($parentStories as $storyID => $parentStoryID)
  61. {
  62. $URs[$storyID] = isset($URs[$storyID]) ? $URs[$storyID] : '';
  63. $URs[$storyID] .= isset($parentURs[$parentStoryID]) ? ',' . $parentURs[$parentStoryID] : '';
  64. }
  65. }
  66. if(!$URIds) return $objectInfo ? $objectInfo : $objects;
  67. /* 查询最近一次撤回/移除操作。 */
  68. $lastActions = $this->dao->select('*')->from(TABLE_ACTION)
  69. ->where('objectType')->eq('story')
  70. ->andWhere('objectID')->in($URIds)
  71. ->andWhere('action')->in('retractclosed,unlinkedfromroadmap')
  72. ->orderBy('id_asc')
  73. ->fetchAll('objectID');
  74. /* 获取已经确认过的对象。*/
  75. $confirmedActions = $this->dao->select('*')->from(TABLE_ACTION)
  76. ->where('objectType')->eq($objectType)
  77. ->andWhere('objectID')->in($objectIDList)
  78. ->andWhere('action')->in('confirmedretract,confirmedunlink')
  79. ->orderBy('id_asc')
  80. ->fetchAll('objectID');
  81. /* 将确认信息插入到objects中并且过滤掉已经确认的用户需求。*/
  82. foreach($objects as $objectID => $object)
  83. {
  84. $objectID = $object->id;
  85. if($this->app->rawModule == 'testtask') $objectID = $object->case;
  86. $storyID = $objectType == 'story' ? $object->id : $object->story;
  87. $object->URs = isset($URs[$storyID]) ? $URs[$storyID] : '';
  88. if(!$object->URs) continue;
  89. $objectURs = explode(',', $object->URs);
  90. $URAction = $objectAction = array();
  91. foreach($objectURs as $URID)
  92. {
  93. if(!isset($lastActions[$URID])) continue;
  94. if($object->openedDate > $lastActions[$URID]->date) continue;
  95. if(empty($URAction)) $URAction = $lastActions[$URID];
  96. if($URAction->date < $lastActions[$URID]->date) $URAction = $lastActions[$URID];
  97. if(!isset($confirmedActions[$objectID])) continue;
  98. $objectAction = $confirmedActions[$objectID];
  99. if($objectAction and $objectAction->date > $URAction->date) $URAction = array();
  100. }
  101. if($URAction)
  102. {
  103. $actionType = $URAction->action == 'retractclosed' ? 'confirmedretract' : 'confirmedunlink';
  104. $object->confirmeObjectID = $URAction->objectID;
  105. $object->confirmeActionType = $actionType;
  106. }
  107. }
  108. if($objectInfo) return $objects[$objectInfo->id];
  109. return $objects;
  110. }
  111. /**
  112. * Get story relation by Ids.
  113. *
  114. * @param array $storyIdList
  115. * @param string $storyType
  116. * @access public
  117. * @return array
  118. */
  119. public function getStoryRelationByIds($storyIdList, $storyType = 'story')
  120. {
  121. $conditionField = $storyType == 'story' ? 'BID' : 'AID';
  122. $anotherField = $storyType == 'story' ? 'AID' : 'BID';
  123. $relations = $this->dao->select('BID,AID')->from(TABLE_RELATION)
  124. ->where('AType')->eq('requirement')
  125. ->andWhere('BType')->eq('story')
  126. ->andWhere('relation')->eq('subdivideinto')
  127. ->andWhere($conditionField)->in($storyIdList)
  128. ->fetchGroup($conditionField, $anotherField);
  129. foreach($relations as $storyId => $relation)
  130. {
  131. if($relation) $relations[$storyId] = implode(',', array_keys($relation));
  132. }
  133. return $relations;
  134. }