Changeset View
Changeset View
Standalone View
Standalone View
src/applications/maniphest/editor/ManiphestTransactionEditor.php
Show First 20 Lines • Show All 626 Lines • ▼ Show 20 Lines | final class ManiphestTransactionEditor | ||||
} | } | ||||
/** | /** | ||||
* Get priorities for moving a task before or after another task. | * Get priorities for moving a task before or after another task. | ||||
*/ | */ | ||||
public static function getAdjacentSubpriority( | public static function getAdjacentSubpriority( | ||||
ManiphestTask $dst, | ManiphestTask $dst, | ||||
$is_after) { | $is_after, | ||||
$allow_recursion = true) { | |||||
$query = id(new ManiphestTaskQuery()) | $query = id(new ManiphestTaskQuery()) | ||||
->setViewer(PhabricatorUser::getOmnipotentUser()) | ->setViewer(PhabricatorUser::getOmnipotentUser()) | ||||
->setOrderBy(ManiphestTaskQuery::ORDER_PRIORITY) | ->setOrderBy(ManiphestTaskQuery::ORDER_PRIORITY) | ||||
->withPriorities(array($dst->getPriority())) | ->withPriorities(array($dst->getPriority())) | ||||
->setLimit(1); | ->setLimit(1); | ||||
if ($is_after) { | if ($is_after) { | ||||
$query->setAfterID($dst->getID()); | $query->setAfterID($dst->getID()); | ||||
} else { | } else { | ||||
$query->setBeforeID($dst->getID()); | $query->setBeforeID($dst->getID()); | ||||
} | } | ||||
$adjacent = $query->executeOne(); | $adjacent = $query->executeOne(); | ||||
$base = $dst->getSubpriority(); | $base = $dst->getSubpriority(); | ||||
$step = (double)(2 << 32); | $step = (double)(2 << 32); | ||||
// If we find an adjacent task, we average the two subpriorities and | // If we find an adjacent task, we average the two subpriorities and | ||||
// return the result. | // return the result. | ||||
if ($adjacent) { | if ($adjacent) { | ||||
$epsilon = 0.01; | |||||
// If the adjacent task has a subpriority that is identical or very | // If the adjacent task has a subpriority that is identical or very | ||||
// close to the task we're looking at, we're going to move it and all | // close to the task we're looking at, we're going to move it and all | ||||
// tasks with the same subpriority a little farther down the subpriority | // tasks with the same subpriority a little farther down the subpriority | ||||
// scale. | // scale. | ||||
if (abs($adjacent->getSubpriority() - $base) < 0.01) { | if ($allow_recursion && | ||||
(abs($adjacent->getSubpriority() - $base) < $epsilon)) { | |||||
$conn_w = $adjacent->establishConnection('w'); | $conn_w = $adjacent->establishConnection('w'); | ||||
// Get all of the tasks with the same subpriority as the adjacent | $min = ($adjacent->getSubpriority() - ($epsilon)); | ||||
$max = ($adjacent->getSubpriority() + ($epsilon)); | |||||
// Get all of the tasks with the similar subpriorities to the adjacent | |||||
// task, including the adjacent task itself. | // task, including the adjacent task itself. | ||||
$shift_base = $adjacent->getSubpriority(); | |||||
$query = id(new ManiphestTaskQuery()) | $query = id(new ManiphestTaskQuery()) | ||||
->setViewer(PhabricatorUser::getOmnipotentUser()) | ->setViewer(PhabricatorUser::getOmnipotentUser()) | ||||
->withPriorities(array($adjacent->getPriority())) | ->withPriorities(array($adjacent->getPriority())) | ||||
->withSubpriorities(array($shift_base)); | ->withSubpriorityBetween($min, $max); | ||||
if (!$is_after) { | if (!$is_after) { | ||||
$query->setOrderVector(array('-priority', '-subpriority', '-id')); | $query->setOrderVector(array('-priority', '-subpriority', '-id')); | ||||
} else { | } else { | ||||
$query->setOrderVector(array('priority', 'subpriority', 'id')); | $query->setOrderVector(array('priority', 'subpriority', 'id')); | ||||
} | } | ||||
$shift_all = $query->execute(); | $shift_all = $query->execute(); | ||||
$shift_last = last($shift_all); | $shift_last = last($shift_all); | ||||
// Select the most extreme subpriority in the result set as the | |||||
// base value. | |||||
$shift_base = head($shift_all)->getSubpriority(); | |||||
// Find the subpriority before or after the task at the end of the | // Find the subpriority before or after the task at the end of the | ||||
// block. | // block. | ||||
list($shift_pri, $shift_sub) = self::getAdjacentSubpriority( | list($shift_pri, $shift_sub) = self::getAdjacentSubpriority( | ||||
$shift_last, | $shift_last, | ||||
$is_after); | $is_after, | ||||
$allow_recursion = false); | |||||
$delta = ($shift_sub - $shift_base); | $delta = ($shift_sub - $shift_base); | ||||
$count = count($shift_all); | $count = count($shift_all); | ||||
$shift = array(); | $shift = array(); | ||||
$cursor = 1; | $cursor = 1; | ||||
foreach ($shift_all as $shift_task) { | foreach ($shift_all as $shift_task) { | ||||
$shift_target = $shift_base + (($cursor / $count) * $delta); | $shift_target = $shift_base + (($cursor / $count) * $delta); | ||||
Show All 38 Lines |