@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class ManiphestTaskGraphController
4 extends ManiphestController {
5
6 public function shouldAllowPublic() {
7 return true;
8 }
9
10 public function handleRequest(AphrontRequest $request) {
11 $viewer = $this->getViewer();
12 $id = $request->getURIData('id');
13
14 $task = id(new ManiphestTaskQuery())
15 ->setViewer($viewer)
16 ->withIDs(array($id))
17 ->executeOne();
18 if (!$task) {
19 return new Aphront404Response();
20 }
21
22 $crumbs = $this->buildApplicationCrumbs()
23 ->addTextCrumb($task->getMonogram(), $task->getURI())
24 ->addTextCrumb(pht('Graph'))
25 ->setBorder(true);
26
27 $graph_limit = 2000;
28 $overflow_message = null;
29 $task_graph = id(new ManiphestTaskGraph())
30 ->setViewer($viewer)
31 ->setSeedPHID($task->getPHID())
32 ->setLimit($graph_limit)
33 ->setIsStandalone(true)
34 ->loadGraph();
35 if (!$task_graph->isEmpty()) {
36 $parent_type = ManiphestTaskDependedOnByTaskEdgeType::EDGECONST;
37 $subtask_type = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
38 $parent_map = $task_graph->getEdges($parent_type);
39 $subtask_map = $task_graph->getEdges($subtask_type);
40 $parent_list = idx($parent_map, $task->getPHID(), array());
41 $subtask_list = idx($subtask_map, $task->getPHID(), array());
42 $has_parents = (bool)$parent_list;
43 $has_subtasks = (bool)$subtask_list;
44
45 // First, get a count of direct parent tasks and subtasks. If there
46 // are too many of these, we just don't draw anything. You can use
47 // the search button to browse tasks with the search UI instead.
48 $direct_count = count($parent_list) + count($subtask_list);
49
50 if ($direct_count > $graph_limit) {
51 $overflow_message = pht(
52 'This task is directly connected to more than %s other tasks, '.
53 'which is too many tasks to display. Use %s to browse parents '.
54 'or subtasks.',
55 new PhutilNumber($graph_limit),
56 phutil_tag('strong', array(), pht('Search...')));
57
58 $graph_table = null;
59 } else {
60 // If there aren't too many direct tasks, but there are too many total
61 // tasks, we'll only render directly connected tasks.
62 if ($task_graph->isOverLimit()) {
63 $task_graph->setRenderOnlyAdjacentNodes(true);
64
65 $overflow_message = pht(
66 'This task is connected to more than %s other tasks. '.
67 'Only direct parents and subtasks are shown here.',
68 new PhutilNumber($graph_limit));
69 }
70
71 $graph_table = $task_graph->newGraphTable();
72 }
73
74 $graph_menu = $this->newTaskGraphDropdownMenu(
75 $task,
76 $has_parents,
77 $has_subtasks,
78 false);
79 } else {
80 $graph_menu = null;
81 $graph_table = null;
82
83 $overflow_message = pht(
84 'This task has no parent tasks and no subtasks, so there is no '.
85 'graph to draw.');
86 }
87
88 if ($overflow_message) {
89 $overflow_view = $this->newTaskGraphOverflowView(
90 $task,
91 $overflow_message,
92 false);
93
94 $graph_table = array(
95 $overflow_view,
96 $graph_table,
97 );
98 }
99
100 $header = id(new PHUIHeaderView())
101 ->setHeader(pht('Task Graph'));
102
103 if ($graph_menu) {
104 $header->addActionLink($graph_menu);
105 }
106
107 $tab_view = id(new PHUIObjectBoxView())
108 ->setHeader($header)
109 ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
110 ->appendChild($graph_table);
111
112 $view = id(new PHUITwoColumnView())
113 ->setFooter($tab_view);
114
115 return $this->newPage()
116 ->setTitle(
117 array(
118 $task->getMonogram(),
119 pht('Graph'),
120 ))
121 ->setCrumbs($crumbs)
122 ->appendChild($view);
123 }
124
125
126}