Christopher Johnson (WMDE) has submitted this change and it was merged.
Change subject: Refactor BurndownDataView
......................................................................
Refactor BurndownDataView
Change-Id: I9f1b6b5c0fa46e58ff362aa0009ce2b8da6b4438
---
A scruntizer.yml
M src/__phutil_library_map__.php
M src/util/BurndownDataDate.php
M src/view/BurndownDataView.php
A src/view/EventTableView.php
A src/view/SprintTableView.php
A src/view/TasksTableView.php
7 files changed, 429 insertions(+), 343 deletions(-)
Approvals:
Christopher Johnson (WMDE): Verified; Looks good to me, approved
diff --git a/scruntizer.yml b/scruntizer.yml
new file mode 100644
index 0000000..d7450ca
--- /dev/null
+++ b/scruntizer.yml
@@ -0,0 +1,3 @@
+# .scrutinizer.yml
+tools:
+ external_code_coverage: true
\ No newline at end of file
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index b9da3d2..d7728ef 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -20,6 +20,7 @@
'BurndownListController' => 'controller/BurndownListController.php',
'BurndownTestDataGenerator' => '__tests__/BurndownTestDataGenerator.php',
'CeleritySprintResources' => 'celerity/CeleritySprintResources.php',
+ 'EventTableView' => 'view/EventTableView.php',
'OpenTasksView' => 'view/OpenTasksView.php',
'ProjectOpenTasksView' => 'view/ProjectOpenTasksView.php',
'SprintBeginDateField' => 'customfield/SprintBeginDateField.php',
@@ -32,10 +33,12 @@
'SprintReportBurndownView' => 'view/SprintReportBurndownView.php',
'SprintReportController' => 'controller/SprintReportController.php',
'SprintReportOpenTasksView' => 'view/SprintReportOpenTasksView.php',
+ 'SprintTableView' => 'view/SprintTableView.php',
'SprintTaskStoryPointsField' =>
'customfield/SprintTaskStoryPointsField.php',
'SprintTestCase' => '__tests__/SprintTestCase.php',
'SprintTransaction' => 'storage/SprintTransaction.php',
'SprintView' => 'view/SprintView.php',
+ 'TasksTableView' => 'view/TasksTableView.php',
'UserOpenTasksView' => 'view/UserOpenTasksView.php',
'ViewController' => 'controller/ViewController.php',
),
diff --git a/src/util/BurndownDataDate.php b/src/util/BurndownDataDate.php
index ef227ea..9cfa89d 100644
--- a/src/util/BurndownDataDate.php
+++ b/src/util/BurndownDataDate.php
@@ -90,8 +90,8 @@
return $this->tasks_total;
}
- public function setTasksRemaining($tasks_added_today) {
- $this->tasks_remaining = $tasks_added_today;
+ public function setTasksRemaining($tasks_remaining) {
+ $this->tasks_remaining = $tasks_remaining;
return $this->tasks_remaining;
}
diff --git a/src/view/BurndownDataView.php b/src/view/BurndownDataView.php
index 452339c..d39e5da 100644
--- a/src/view/BurndownDataView.php
+++ b/src/view/BurndownDataView.php
@@ -4,7 +4,8 @@
* @license GPL version 3
*/
-final class BurndownDataView extends SprintView {
+final class BurndownDataView extends SprintView
+{
private $request;
private $timeseries;
@@ -13,37 +14,41 @@
private $viewer;
private $tasks;
private $xactions;
- private $task_open_status_sum;
- private $task_closed_status_sum;
- public function setProject ($project) {
+ public function setProject($project) {
$this->project = $project;
return $this;
}
- public function setViewer ($viewer) {
+ public function setViewer($viewer) {
$this->viewer = $viewer;
return $this;
}
- public function setRequest ($request) {
- $this->request = $request;
+ public function setRequest($request) {
+ $this->request = $request;
return $this;
}
public function render() {
$chart = $this->buildC3Chart();
- $tasks_table = $this->buildTasksTable();
+ $tasks_table = id(new TasksTableView())
+ ->setProject($this->project)
+ ->setViewer($this->viewer)
+ ->setRequest($this->request);
+ $tasks_table = $tasks_table->buildTasksTable();
$pie = $this->buildC3Pie();
- $burndown_table = $this->buildBurnDownTable();
- $event_table = $this->buildEventTable();
- return array ($chart, $tasks_table, $pie, $burndown_table, $event_table);
+ $sprint_table = new SprintTableView();
+ $burndown_table = $sprint_table->buildBurnDownTable($this->sprint_data);
+ $event_table = new EventTableView();
+ $event_table = $event_table->buildEventTable($this->project,
$this->viewer);
+ return array($chart, $tasks_table, $pie, $burndown_table, $event_table);
}
private function buildChartDataSet() {
$query = id(new SprintQuery())
- ->setProject($this->project)
- ->setViewer($this->viewer);
+ ->setProject($this->project)
+ ->setViewer($this->viewer);
$aux_fields = $query->getAuxFields();
$start = $query->getStartDate($aux_fields);
$end = $query->getEndDate($aux_fields);
@@ -76,7 +81,7 @@
$dates = $stats->sumSprintStats($dates);
$sprint_data = $stats->computeIdealPoints($dates);
return $sprint_data;
-}
+ }
private function transposeArray($array) {
$transposed_array = array();
@@ -92,7 +97,7 @@
}
}
return $transposed_array;
- }
+ }
private function buildC3Chart() {
$data = $this->buildChartDataSet();
@@ -102,9 +107,9 @@
$pointstoday = $data[3];
$timeseries = $this->timeseries;
- require_celerity_resource('d3','sprint');
- require_celerity_resource('c3-css','sprint');
- require_celerity_resource('c3','sprint');
+ require_celerity_resource('d3', 'sprint');
+ require_celerity_resource('c3-css', 'sprint');
+ require_celerity_resource('c3', 'sprint');
$id = 'chart';
Javelin::initBehavior('c3-chart', array(
@@ -112,13 +117,13 @@
'timeseries' => $timeseries,
'totalpoints' => $totalpoints,
'remainingpoints' => $remainingpoints,
- 'idealpoints' => $idealpoints,
- 'pointstoday' => $pointstoday
+ 'idealpoints' => $idealpoints,
+ 'pointstoday' => $pointstoday
), 'sprint');
- $chart= id(new PHUIObjectBoxView())
+ $chart = id(new PHUIObjectBoxView())
->setHeaderText(pht('Burndown for ' . $this->project->getName()))
- ->appendChild(phutil_tag('div',
+ ->appendChild(phutil_tag('div',
array(
'id' => 'chart',
'style' => 'width: 100%; height:400px'
@@ -128,12 +133,17 @@
}
private function buildC3Pie() {
- $task_open_status_sum = $this->task_open_status_sum;
- $task_closed_status_sum = $this->task_closed_status_sum;
+ $tasks_table = id(new TasksTableView())
+ ->setProject($this->project)
+ ->setViewer($this->viewer)
+ ->setRequest($this->request);
+ $tasks_table->setStatusPoints();
+ $task_open_status_sum = $tasks_table->getOpenStatusSum();
+ $task_closed_status_sum = $tasks_table->getClosedStatusSum();
- require_celerity_resource('d3','sprint');
- require_celerity_resource('c3-css','sprint');
- require_celerity_resource('c3','sprint');
+ require_celerity_resource('d3', 'sprint');
+ require_celerity_resource('c3-css', 'sprint');
+ require_celerity_resource('c3', 'sprint');
$id = 'pie';
Javelin::initBehavior('c3-pie', array(
@@ -142,7 +152,7 @@
'resolved' => $task_closed_status_sum,
), 'sprint');
- $pie= id(new PHUIObjectBoxView())
+ $pie = id(new PHUIObjectBoxView())
->setHeaderText(pht('Task Status Report for ' .
$this->project->getName()))
->appendChild(phutil_tag('div',
array(
@@ -152,316 +162,4 @@
return $pie;
}
-
- /**
- * Format the Burndown data for display on the page.
- *
- * @returns PHUIObjectBoxView
- */
- private function buildBurnDownTable() {
- $data = array();
-
- foreach ($this->sprint_data as $date) {
- $data[] = array(
- $date->getDate(),
- $date->getTasksTotal(),
- $date->getTasksRemaining(),
- $date->getPointsTotal(),
- $date->getPointsRemaining(),
- $date->getPointsIdealRemaining(),
- $date->getPointsClosedToday(),
- );
- }
-
- $table = id(new AphrontTableView($data))
- ->setHeaders(
- array(
- pht('Date'),
- pht('Total Tasks'),
- pht('Remaining Tasks'),
- pht('Total Points'),
- pht('Remaining Points'),
- pht('Ideal Remaining Points'),
- pht('Points Completed Today'),
- ));
-
- $box = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('DATA'))
- ->appendChild($table);
-
- return $box;
- }
-
- /**
- * Format the tasks data for display on the page.
- *
- * @returns PHUIObjectBoxView
- */
- private function buildTasksTable() {
- $order = $this->request->getStr('order', 'name');
- list($order, $reverse) = AphrontTableView::parseSort($order);
- $rows = $this->buildTasksTree($order, $reverse);
- $table = id(new AphrontTableView($rows))
- ->setHeaders(
- array(
- pht('Task'),
- pht('Assigned to'),
- pht('Priority'),
- pht('Points'),
- pht('Status'),
- ));
- $table->makeSortable(
- $this->request->getRequestURI(),
- 'order',
- $order,
- $reverse,
- array(
- 'Task',
- 'Assigned to',
- 'Priority',
- 'Points',
- 'Status'
- )
- );
-
- $box = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Tasks in this Sprint'))
- ->appendChild($table);
-
- return $box;
- }
-
- private function setSortOrder ($row, $order, $task, $assigned_to, $priority,
- $points, $status) {
- switch ($order) {
- case 'Task':
- $row['sort'] = $task;
- break;
- case 'Assigned to':
- $row['sort'] = $assigned_to;
- break;
- case 'Priority':
- $row['sort'] = $priority;
- break;
- case 'Points':
- $row['sort'] = $points;
- break;
- case 'Status':
- default:
- $row['sort'] = $status;
- break;
- }
- return $row['sort'];
- }
-
-
- private function buildTaskMap ($edges) {
- $map = array();
- foreach ($this->tasks as $task) {
- if ($parents =
-
$edges[$task->getPHID()][PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK])
{
- foreach ($parents as $parent) {
- // Make sure this task is in this sprint.
- if (isset($this->tasks[$parent['dst']]))
- $map[$task->getPHID()]['parents'][] = $parent['dst'];
- }
- }
-
- if ($children =
-
$edges[$task->getPHID()][PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK]) {
- foreach ($children as $child) {
- // Make sure this task is in this sprint.
- if (isset($this->tasks[$child['dst']])) {
- $map[$task->getPHID()]['children'][] = $child['dst'];
- }
- }
- }
- }
- return $map;
- }
-
- /**
- * This builds a tree of the tasks in this project. Due to the acyclic nature
- * of tasks, we ntake some steps to reduce and call out duplication.
- *
- * We ignore any tasks not in this sprint.
- *
- * @return array
- */
- private function buildTasksTree($order, $reverse) {
- $query = id(new SprintQuery());
- $edges = $query->getEdges($this->tasks);
- $map = $this->buildTaskMap($edges);
-
- // We also collect the phids we need to fetch owner information
- $handle_phids = array();
- foreach ($this->tasks as $task) {
- // Get the owner (assigned to) phid
- $handle_phids[$task->getOwnerPHID()] = $task->getOwnerPHID();
- }
- $handles = $query->getViewerHandles($this->request, $handle_phids);
-
- // Now we loop through the tasks, and add them to the output
- $output = array();
- $rows = array();
- foreach ($this->tasks as $task) {
- // If parents is set, it means this task has a parent in this sprint so
- // skip it, the parent will handle adding this task to the output
- if (isset($map[$task->getPHID()]['parents'])) {
- continue;
- }
-
- $row = $this->addTaskToTree($output, $task, $map, $handles);
- list ($task, $assigned_to, $priority,$points, $status) = $row[0];
- $row['sort'] = $this->setSortOrder($row, $order, $task, $assigned_to,
$priority,$points, $status);
- $rows[] = $row;
- }
- $rows = isort($rows, 'sort');
-
- foreach ($rows as $k => $row) {
- unset($rows[$k]['sort']);
- }
-
- if ($reverse) {
- $rows = array_reverse($rows);
- }
- $rows = array_map( function( $a ) { return $a['0']; }, $rows );
- return $rows;
- }
-
- private function addTaskToTree($output, $task, $map, $handles, $depth = 0) {
- static $included = array();
- $query = id(new SprintQuery())
- ->setProject($this->project)
- ->setViewer($this->viewer);
-
- // Get the owner object so we can render the owner username/link
- $owner = $handles[$task->getOwnerPHID()];
-
- // If this task is already is this tree, this is a repeat.
- $repeat = isset($included[$task->getPHID()]);
-
- $data = $query->getXactionData(SprintConstants::CUSTOMFIELD_TYPE_STATUS);
- $points = $this->getTaskStoryPoints($task->getPHID(),$data);
- $points = trim($points, '"');
-
- $priority_name = new ManiphestTaskPriority();
- $status = $this->setTaskStatus($task);
- $this->sumPointsbyStatus($status, $points);
- $depth_indent = '';
- for ($i = 0; $i < $depth; $i++) {
- $depth_indent .= ' ';
- }
-
- // Build the row
- $output[] = array(
- phutil_safe_html($depth_indent . phutil_tag(
- 'a',
- array(
- 'href' => '/' . $task->getMonogram(),
- 'class' => $task->getStatus() !== 'open'
- ? 'phui-tag-core-closed'
- : '',
- ),
- $task->getMonogram() . ': ' . $task->getTitle()
- ) . ($repeat ? ' <em title="This task is a child of
more than one task in this list. Children are only shown on ' .
- 'the first occurance">[Repeat]</em>' : '')),
- $task->getOwnerPHID() ? $owner->renderLink() : 'none assigned',
- $priority_name->getTaskPriorityName($task->getPriority()),
- $points,
- $status,
- );
- $included[$task->getPHID()] = $task->getPHID();
-
- if (isset($map[$task->getPHID()]['children'])) {
- foreach ($map[$task->getPHID()]['children'] as $child) {
- $child = $this->tasks[$child];
- $this->addTaskToTree($output, $child, $map, $handles, $depth + 1);
- }
- }
- return $output;
- }
-
- /**
- * Format the Event data for display on the page.
- *
- * @returns PHUIObjectBoxView
- */
- private function buildEventTable() {
- $query = id(new SprintQuery())
- ->setProject($this->project)
- ->setViewer($this->viewer);
- $aux_fields = $query->getAuxFields();
- $start = $query->getStartDate($aux_fields);
- $end = $query->getEndDate($aux_fields);
-
- $tasks = $query->getTasks();
-
- $query->checkNull($start, $end, $tasks);
-
- $xactions = $query->getXactions($tasks);
-
- $events = $query->getEvents($xactions, $tasks);
- $rows = array();
- foreach ($events as $event) {
- $task_phid = $this->xactions[$event['transactionPHID']]->getObjectPHID();
- $task = $this->tasks[$task_phid];
-
- $rows[] = array(
- phabricator_datetime($event['epoch'], $this->viewer),
- phutil_tag(
- 'a',
- array(
- 'href' => '/' . $task->getMonogram(),
- ),
- $task->getMonogram() . ': ' . $task->getTitle()),
- $event['title'],
- );
- }
-
- $table = id(new AphrontTableView($rows))
- ->setHeaders(
- array(
- pht('When'),
- pht('Task'),
- pht('Action'),
- ))
- ->setColumnClasses(
- array(
- '',
- '',
- 'wide',
- ));
-
- $box = id(new PHUIObjectBoxView())
- ->setHeaderText(pht('Events related to this sprint'))
- ->appendChild($table);
-
- return $box;
- }
-
- private function getTaskStoryPoints($task,$points_data) {
- $storypoints = array();
- foreach ($points_data as $k=>$subarray) {
- if (isset ($subarray['objectPHID']) && $subarray['objectPHID'] ==
$task) {
- $points_data[$k] = $subarray;
- $storypoints = $subarray['newValue'];
- }
- }
- return $storypoints;
- }
-
- private function setTaskStatus($task) {
- $status = $task->getStatus();
- return $status;
- }
-
- private function sumPointsbyStatus ($status, $points) {
- $stats = id(new SprintBuildStats());
- if ($status == 'open') {
- $this->task_open_status_sum =
$stats->setTaskOpenStatusSum($this->task_open_status_sum, $points);
- } elseif ($status == 'resolved') {
- $this->task_closed_status_sum =
$stats->setTaskClosedStatusSum($this->task_closed_status_sum, $points);
- }
- }
-}
\ No newline at end of file
+}
diff --git a/src/view/EventTableView.php b/src/view/EventTableView.php
new file mode 100644
index 0000000..a122142
--- /dev/null
+++ b/src/view/EventTableView.php
@@ -0,0 +1,61 @@
+<?php
+
+final class EventTableView {
+ /**
+ * Format the Event data for display on the page.
+ *
+ * @returns PHUIObjectBoxView
+ */
+ public function buildEventTable($project, $viewer) {
+ $query = id(new SprintQuery())
+ ->setProject($project)
+ ->setViewer($viewer);
+ $aux_fields = $query->getAuxFields();
+ $start = $query->getStartDate($aux_fields);
+ $end = $query->getEndDate($aux_fields);
+
+ $tasks = $query->getTasks();
+ $query->checkNull($start, $end, $tasks);
+ $xactions = $query->getXactions($tasks);
+ $xactions = mpull($xactions, null, 'getPHID');
+ $tasks = mpull($tasks, null, 'getPHID');
+ $events = $query->getEvents($xactions, $tasks);
+ $rows = array();
+ foreach ($events as $event) {
+ $task_phid = $xactions[$event['transactionPHID']]->getObjectPHID();
+ $task = $tasks[$task_phid];
+
+ $rows[] = array(
+ phabricator_datetime($event['epoch'], $viewer),
+ phutil_tag(
+ 'a',
+ array(
+ 'href' => '/' . $task->getMonogram(),
+ ),
+ $task->getMonogram() . ': ' . $task->getTitle()),
+ $event['title'],
+ );
+ }
+
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ pht('When'),
+ pht('Task'),
+ pht('Action'),
+ ))
+ ->setColumnClasses(
+ array(
+ '',
+ '',
+ 'wide',
+ ));
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Events related to this sprint'))
+ ->appendChild($table);
+
+ return $box;
+ }
+
+}
\ No newline at end of file
diff --git a/src/view/SprintTableView.php b/src/view/SprintTableView.php
new file mode 100644
index 0000000..6423ccd
--- /dev/null
+++ b/src/view/SprintTableView.php
@@ -0,0 +1,45 @@
+<?php
+
+final class SprintTableView
+{
+
+ /**
+ * Format the Burndown data for display on the page.
+ *
+ * @returns PHUIObjectBoxView
+ */
+ public function buildBurnDownTable($sprint_data)
+ {
+ $data = array();
+
+ foreach ($sprint_data as $date) {
+ $data[] = array(
+ $date->getDate(),
+ $date->getTasksTotal(),
+ $date->getTasksRemaining(),
+ $date->getPointsTotal(),
+ $date->getPointsRemaining(),
+ $date->getPointsIdealRemaining(),
+ $date->getPointsClosedToday(),
+ );
+ }
+
+ $table = id(new AphrontTableView($data))
+ ->setHeaders(
+ array(
+ pht('Date'),
+ pht('Total Tasks'),
+ pht('Remaining Tasks'),
+ pht('Total Points'),
+ pht('Remaining Points'),
+ pht('Ideal Remaining Points'),
+ pht('Points Completed Today'),
+ ));
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('DATA'))
+ ->appendChild($table);
+
+ return $box;
+ }
+}
diff --git a/src/view/TasksTableView.php b/src/view/TasksTableView.php
new file mode 100644
index 0000000..2829a71
--- /dev/null
+++ b/src/view/TasksTableView.php
@@ -0,0 +1,276 @@
+<?php
+
+final class TasksTableView {
+
+ private $project;
+ private $viewer;
+ private $request;
+ private $task_open_status_sum;
+ private $task_closed_status_sum;
+
+ public function setProject ($project) {
+ $this->project = $project;
+ return $this;
+ }
+
+ public function setViewer ($viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ public function setRequest ($request) {
+ $this->request = $request;
+ return $this;
+ }
+
+ public function getTaskOpenStatusSum () {
+ return $this->task_open_status_sum;
+ }
+
+ public function getTaskClosedStatusSum () {
+ return $this->task_closed_status_sum;
+ }
+ /**
+ * Format the tasks data for display on the page.
+ *
+ * @returns PHUIObjectBoxView
+ */
+ public function buildTasksTable() {
+ $order = $this->request->getStr('order', 'name');
+ list($order, $reverse) = AphrontTableView::parseSort($order);
+ $rows = $this->buildTasksTree($order, $reverse);
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ pht('Task'),
+ pht('Assigned to'),
+ pht('Priority'),
+ pht('Points'),
+ pht('Status'),
+ ));
+ $table->makeSortable(
+ $this->request->getRequestURI(),
+ 'order',
+ $order,
+ $reverse,
+ array(
+ 'Task',
+ 'Assigned to',
+ 'Priority',
+ 'Points',
+ 'Status'
+ )
+ );
+
+ $box = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Tasks in this Sprint'))
+ ->appendChild($table);
+
+ return $box;
+ }
+
+ /**
+ * This builds a tree of the tasks in this project. Due to the acyclic nature
+ * of tasks, we ntake some steps to reduce and call out duplication.
+ *
+ * We ignore any tasks not in this sprint.
+ *
+ * @return array
+ */
+ private function buildTasksTree($order, $reverse) {
+ $query = id(new SprintQuery())
+ ->setProject($this->project)
+ ->setViewer($this->viewer);
+ $tasks = $query->getTasks();
+ $tasks = mpull($tasks, null, 'getPHID');
+ $edges = $query->getEdges($tasks);
+ $map = $this->buildTaskMap($edges, $tasks);
+
+ // We also collect the phids we need to fetch owner information
+ $handle_phids = array();
+ foreach ($tasks as $task) {
+ // Get the owner (assigned to) phid
+ $handle_phids[$task->getOwnerPHID()] = $task->getOwnerPHID();
+ }
+ $handles = $query->getViewerHandles($this->request, $handle_phids);
+
+ // Now we loop through the tasks, and add them to the output
+ $output = array();
+ $rows = array();
+ foreach ($tasks as $task) {
+ // If parents is set, it means this task has a parent in this sprint so
+ // skip it, the parent will handle adding this task to the output
+ if (isset($map[$task->getPHID()]['parents'])) {
+ continue;
+ }
+
+ $row = $this->addTaskToTree($output, $task, $tasks, $map, $handles);
+ list ($task, $assigned_to, $priority,$points, $status) = $row[0];
+ $row['sort'] = $this->setSortOrder($row, $order, $task, $assigned_to,
$priority,$points, $status);
+ $rows[] = $row;
+ }
+ $rows = isort($rows, 'sort');
+
+ foreach ($rows as $k => $row) {
+ unset($rows[$k]['sort']);
+ }
+
+ if ($reverse) {
+ $rows = array_reverse($rows);
+ }
+ $rows = array_map( function( $a ) { return $a['0']; }, $rows );
+ return $rows;
+ }
+
+ private function setSortOrder ($row, $order, $task, $assigned_to, $priority,
+ $points, $status) {
+ switch ($order) {
+ case 'Task':
+ $row['sort'] = $task;
+ break;
+ case 'Assigned to':
+ $row['sort'] = $assigned_to;
+ break;
+ case 'Priority':
+ $row['sort'] = $priority;
+ break;
+ case 'Points':
+ $row['sort'] = $points;
+ break;
+ case 'Status':
+ default:
+ $row['sort'] = $status;
+ break;
+ }
+ return $row['sort'];
+ }
+
+ private function buildTaskMap ($edges, $tasks) {
+ $map = array();
+ foreach ($tasks as $task) {
+ if ($parents =
+
$edges[$task->getPHID()][PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK])
{
+ foreach ($parents as $parent) {
+ // Make sure this task is in this sprint.
+ if (isset($tasks[$parent['dst']]))
+ $map[$task->getPHID()]['parents'][] = $parent['dst'];
+ }
+ }
+
+ if ($children =
+
$edges[$task->getPHID()][PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK]) {
+ foreach ($children as $child) {
+ // Make sure this task is in this sprint.
+ if (isset($tasks[$child['dst']])) {
+ $map[$task->getPHID()]['children'][] = $child['dst'];
+ }
+ }
+ }
+ }
+ return $map;
+ }
+
+ private function getTaskPoints($task) {
+ $query = id(new SprintQuery())
+ ->setProject($this->project)
+ ->setViewer($this->viewer);
+ $data = $query->getXactionData(SprintConstants::CUSTOMFIELD_TYPE_STATUS);
+ $points = $this->getTaskStoryPoints($task->getPHID(),$data);
+ $points = trim($points, '"');
+ return $points;
+ }
+
+ private function addTaskToTree($output, $task, $tasks, $map, $handles,
$depth = 0) {
+ static $included = array();
+
+ // Get the owner object so we can render the owner username/link
+ $owner = $handles[$task->getOwnerPHID()];
+
+ // If this task is already in this tree, this is a repeat.
+ $repeat = isset($included[$task->getPHID()]);
+
+ $points = $this->getTaskPoints($task);
+ $priority_name = new ManiphestTaskPriority();
+ $status = $this->setTaskStatus($task);
+ $depth_indent = '';
+ for ($i = 0; $i < $depth; $i++) {
+ $depth_indent .= ' ';
+ }
+
+ // Build the row
+ $output[] = array(
+ phutil_safe_html($depth_indent . phutil_tag(
+ 'a',
+ array(
+ 'href' => '/' . $task->getMonogram(),
+ 'class' => $task->getStatus() !== 'open'
+ ? 'phui-tag-core-closed'
+ : '',
+ ),
+ $task->getMonogram() . ': ' . $task->getTitle()
+ ) . ($repeat ? ' <em title="This task is a child of
more than one task in this list. Children are only shown on ' .
+ 'the first occurance">[Repeat]</em>' : '')),
+ $task->getOwnerPHID() ? $owner->renderLink() : 'none assigned',
+ $priority_name->getTaskPriorityName($task->getPriority()),
+ $points,
+ $status,
+ );
+ $included[$task->getPHID()] = $task->getPHID();
+
+ if (isset($map[$task->getPHID()]['children'])) {
+ foreach ($map[$task->getPHID()]['children'] as $child) {
+ $child = $tasks[$child];
+ $this->addTaskToTree($output, $child, $map, $handles, $depth + 1);
+ }
+ }
+ return $output;
+ }
+
+ private function getTaskStoryPoints($task,$points_data) {
+ $storypoints = array();
+ foreach ($points_data as $k=>$subarray) {
+ if (isset ($subarray['objectPHID']) && $subarray['objectPHID'] == $task)
{
+ $points_data[$k] = $subarray;
+ $storypoints = $subarray['newValue'];
+ }
+ }
+ return $storypoints;
+ }
+
+ private function setTaskStatus($task) {
+ $status = $task->getStatus();
+ return $status;
+ }
+
+ private function sumPointsbyStatus ($task) {
+ $stats = id(new SprintBuildStats());
+ $status = $this->setTaskStatus($task);
+ $points = $this->getTaskPoints($task);
+ if ($status == 'open') {
+ $this->task_open_status_sum =
$stats->setTaskOpenStatusSum($this->task_open_status_sum, $points);
+ } elseif ($status == 'resolved') {
+ $this->task_closed_status_sum =
$stats->setTaskClosedStatusSum($this->task_closed_status_sum, $points);
+ }
+ return;
+ }
+
+ public function setStatusPoints () {
+ $query = id(new SprintQuery())
+ ->setProject($this->project)
+ ->setViewer($this->viewer);
+ $tasks = $query->getTasks();
+ $tasks = mpull($tasks, null, 'getPHID');
+ foreach ($tasks as $task) {
+ $this->sumPointsbyStatus($task);
+ }
+ return;
+ }
+
+ public function getOpenStatusSum() {
+ return $this->task_open_status_sum;
+ }
+
+ public function getClosedStatusSum() {
+ return $this->task_closed_status_sum;
+ }
+}
\ No newline at end of file
--
To view, visit https://gerrit.wikimedia.org/r/172664
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I9f1b6b5c0fa46e58ff362aa0009ce2b8da6b4438
Gerrit-PatchSet: 3
Gerrit-Project: phabricator/extensions/Sprint
Gerrit-Branch: master
Gerrit-Owner: Christopher Johnson (WMDE) <[email protected]>
Gerrit-Reviewer: Christopher Johnson (WMDE) <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits