diff --git a/src/applications/maniphest/editor/ManiphestTransactionEditor.php b/src/applications/maniphest/editor/ManiphestTransactionEditor.php --- a/src/applications/maniphest/editor/ManiphestTransactionEditor.php +++ b/src/applications/maniphest/editor/ManiphestTransactionEditor.php @@ -632,7 +632,8 @@ */ public static function getAdjacentSubpriority( ManiphestTask $dst, - $is_after) { + $is_after, + $allow_recursion = true) { $query = id(new ManiphestTaskQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) @@ -654,20 +655,25 @@ // If we find an adjacent task, we average the two subpriorities and // return the result. if ($adjacent) { + $epsilon = 0.01; + // 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 // tasks with the same subpriority a little farther down the subpriority // scale. - if (abs($adjacent->getSubpriority() - $base) < 0.01) { + if ($allow_recursion && + (abs($adjacent->getSubpriority() - $base) < $epsilon)) { $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. - $shift_base = $adjacent->getSubpriority(); $query = id(new ManiphestTaskQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withPriorities(array($adjacent->getPriority())) - ->withSubpriorities(array($shift_base)); + ->withSubpriorityBetween($min, $max); if (!$is_after) { $query->setOrderVector(array('-priority', '-subpriority', '-id')); @@ -678,11 +684,16 @@ $shift_all = $query->execute(); $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 // block. list($shift_pri, $shift_sub) = self::getAdjacentSubpriority( $shift_last, - $is_after); + $is_after, + $allow_recursion = false); $delta = ($shift_sub - $shift_base); $count = count($shift_all); diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php --- a/src/applications/maniphest/query/ManiphestTaskQuery.php +++ b/src/applications/maniphest/query/ManiphestTaskQuery.php @@ -21,6 +21,8 @@ private $dateCreatedBefore; private $dateModifiedAfter; private $dateModifiedBefore; + private $subpriorityMin; + private $subpriorityMax; private $fullTextSearch = ''; @@ -140,6 +142,12 @@ return $this; } + public function withSubpriorityBetween($min, $max) { + $this->subpriorityMin = $min; + $this->subpriorityMax = $max; + return $this; + } + public function withSubscribers(array $subscribers) { $this->subscriberPHIDs = $subscribers; return $this; @@ -381,6 +389,20 @@ $this->subpriorities); } + if ($this->subpriorityMin) { + $where[] = qsprintf( + $conn, + 'task.subpriority >= %f', + $this->subpriorityMin); + } + + if ($this->subpriorityMax) { + $where[] = qsprintf( + $conn, + 'task.subpriority <= %f', + $this->subpriorityMax); + } + $where[] = $this->buildPagingClause($conn); $where = $this->formatWhereClause($where);