Differential D20265 Diff 48400 src/applications/project/controller/PhabricatorProjectMoveController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/project/controller/PhabricatorProjectMoveController.php
| Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | public function handleRequest(AphrontRequest $request) { | ||||
| } | } | ||||
| $engine = id(new PhabricatorBoardLayoutEngine()) | $engine = id(new PhabricatorBoardLayoutEngine()) | ||||
| ->setViewer($viewer) | ->setViewer($viewer) | ||||
| ->setBoardPHIDs(array($board_phid)) | ->setBoardPHIDs(array($board_phid)) | ||||
| ->setObjectPHIDs(array($object_phid)) | ->setObjectPHIDs(array($object_phid)) | ||||
| ->executeLayout(); | ->executeLayout(); | ||||
| $columns = $engine->getObjectColumns($board_phid, $object_phid); | |||||
| $old_column_phids = mpull($columns, 'getPHID'); | |||||
| $xactions = array(); | |||||
| $order_params = array(); | $order_params = array(); | ||||
| if ($order == PhabricatorProjectColumn::ORDER_NATURAL) { | |||||
| if ($after_phid) { | if ($after_phid) { | ||||
| $order_params['afterPHID'] = $after_phid; | $order_params['afterPHID'] = $after_phid; | ||||
| } else if ($before_phid) { | } else if ($before_phid) { | ||||
| $order_params['beforePHID'] = $before_phid; | $order_params['beforePHID'] = $before_phid; | ||||
| } | } | ||||
| } | |||||
| $xactions = array(); | |||||
| $xactions[] = id(new ManiphestTransaction()) | $xactions[] = id(new ManiphestTransaction()) | ||||
| ->setTransactionType(PhabricatorTransactions::TYPE_COLUMNS) | ->setTransactionType(PhabricatorTransactions::TYPE_COLUMNS) | ||||
| ->setNewValue( | ->setNewValue( | ||||
| array( | array( | ||||
| array( | array( | ||||
| 'columnPHID' => $column->getPHID(), | 'columnPHID' => $column->getPHID(), | ||||
| ) + $order_params, | ) + $order_params, | ||||
| )); | )); | ||||
| if ($order == PhabricatorProjectColumn::ORDER_PRIORITY) { | $header_xactions = $this->newHeaderTransactions( | ||||
| $header_priority = idx( | |||||
| $edit_header, | |||||
| PhabricatorProjectColumn::ORDER_PRIORITY); | |||||
| $priority_xactions = $this->getPriorityTransactions( | |||||
| $object, | $object, | ||||
| $after_phid, | $order, | ||||
| $before_phid, | $edit_header); | ||||
| $header_priority); | foreach ($header_xactions as $header_xaction) { | ||||
| foreach ($priority_xactions as $xaction) { | $xactions[] = $header_xaction; | ||||
| $xactions[] = $xaction; | |||||
| } | |||||
| } | } | ||||
| $editor = id(new ManiphestTransactionEditor()) | $editor = id(new ManiphestTransactionEditor()) | ||||
| ->setActor($viewer) | ->setActor($viewer) | ||||
| ->setContinueOnMissingFields(true) | ->setContinueOnMissingFields(true) | ||||
| ->setContinueOnNoEffect(true) | ->setContinueOnNoEffect(true) | ||||
| ->setContentSourceFromRequest($request); | ->setContentSourceFromRequest($request); | ||||
| $editor->applyTransactions($object, $xactions); | $editor->applyTransactions($object, $xactions); | ||||
| return $this->newCardResponse($board_phid, $object_phid); | return $this->newCardResponse($board_phid, $object_phid); | ||||
| } | } | ||||
| private function getPriorityTransactions( | private function newHeaderTransactions( | ||||
| ManiphestTask $task, | ManiphestTask $task, | ||||
| $after_phid, | $order, | ||||
| $before_phid, | array $header) { | ||||
| $header_priority) { | |||||
| $xactions = array(); | $xactions = array(); | ||||
| $must_move = false; | |||||
| if ($header_priority !== null) { | switch ($order) { | ||||
| if ($task->getPriority() !== $header_priority) { | case PhabricatorProjectColumn::ORDER_PRIORITY: | ||||
| $task = id(clone $task) | $new_priority = idx($header, $order); | ||||
| ->setPriority($header_priority); | |||||
| if ($task->getPriority() !== $new_priority) { | |||||
| $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap(); | $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap(); | ||||
| $keyword = head(idx($keyword_map, $header_priority)); | $keyword = head(idx($keyword_map, $new_priority)); | ||||
| $xactions[] = id(new ManiphestTransaction()) | $xactions[] = id(new ManiphestTransaction()) | ||||
| ->setTransactionType( | ->setTransactionType( | ||||
| ManiphestTaskPriorityTransaction::TRANSACTIONTYPE) | ManiphestTaskPriorityTransaction::TRANSACTIONTYPE) | ||||
| ->setNewValue($keyword); | ->setNewValue($keyword); | ||||
| $must_move = true; | |||||
| } | |||||
| } | } | ||||
| list($after_task, $before_task) = $this->loadPriorityTasks( | |||||
| $after_phid, | |||||
| $before_phid); | |||||
| if ($after_task && !$task->isLowerPriorityThan($after_task)) { | |||||
| $must_move = true; | |||||
| } | |||||
| if ($before_task && !$task->isHigherPriorityThan($before_task)) { | |||||
| $must_move = true; | |||||
| } | |||||
| // The move doesn't require a subpriority change to be valid, so don't | |||||
| // change the subpriority since we are not being forced to. | |||||
| if (!$must_move) { | |||||
| return $xactions; | |||||
| } | |||||
| $try = array( | |||||
| array($after_task, true), | |||||
| array($before_task, false), | |||||
| ); | |||||
| $pri = null; | |||||
| $sub = null; | |||||
| foreach ($try as $spec) { | |||||
| list($nearby_task, $is_after) = $spec; | |||||
| if (!$nearby_task) { | |||||
| continue; | |||||
| } | |||||
| list($pri, $sub) = ManiphestTransactionEditor::getAdjacentSubpriority( | |||||
| $nearby_task, | |||||
| $is_after); | |||||
| // If we drag under a "Low" header between a "Normal" task and a "Low" | |||||
| // task, we don't want to accept a subpriority assignment which changes | |||||
| // our priority to "Normal". Only accept a subpriority that keeps us in | |||||
| // the right primary priority. | |||||
| if ($header_priority !== null) { | |||||
| if ($pri !== $header_priority) { | |||||
| continue; | |||||
| } | |||||
| } | |||||
| // If we find a priority on the first try, don't keep going. | |||||
| break; | break; | ||||
| } | } | ||||
| if ($pri !== null) { | |||||
| if ($header_priority === null) { | |||||
| $keyword_map = ManiphestTaskPriority::getTaskPriorityKeywordsMap(); | |||||
| $keyword = head(idx($keyword_map, $pri)); | |||||
| $xactions[] = id(new ManiphestTransaction()) | |||||
| ->setTransactionType( | |||||
| ManiphestTaskPriorityTransaction::TRANSACTIONTYPE) | |||||
| ->setNewValue($keyword); | |||||
| } | |||||
| $xactions[] = id(new ManiphestTransaction()) | |||||
| ->setTransactionType( | |||||
| ManiphestTaskSubpriorityTransaction::TRANSACTIONTYPE) | |||||
| ->setNewValue($sub); | |||||
| } | |||||
| return $xactions; | return $xactions; | ||||
| } | } | ||||
| private function loadPriorityTasks($after_phid, $before_phid) { | |||||
| $viewer = $this->getViewer(); | |||||
| $task_phids = array(); | |||||
| if ($after_phid) { | |||||
| $task_phids[] = $after_phid; | |||||
| } | |||||
| if ($before_phid) { | |||||
| $task_phids[] = $before_phid; | |||||
| } | |||||
| if (!$task_phids) { | |||||
| return array(null, null); | |||||
| } | |||||
| $tasks = id(new ManiphestTaskQuery()) | |||||
| ->setViewer($viewer) | |||||
| ->withPHIDs($task_phids) | |||||
| ->execute(); | |||||
| $tasks = mpull($tasks, null, 'getPHID'); | |||||
| if ($after_phid) { | |||||
| $after_task = idx($tasks, $after_phid); | |||||
| } else { | |||||
| $after_task = null; | |||||
| } | |||||
| if ($before_phid) { | |||||
| $before_task = idx($tasks, $before_phid); | |||||
| } else { | |||||
| $before_task = null; | |||||
| } | |||||
| return array($after_task, $before_task); | |||||
| } | |||||
| } | } | ||||