Changeset View
Changeset View
Standalone View
Standalone View
src/applications/project/engine/PhabricatorBoardLayoutEngine.php
Show First 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | if ($position) { | ||||
} | } | ||||
} | } | ||||
unset($this->boardLayout[$board_phid][$column_phid][$object_phid]); | unset($this->boardLayout[$board_phid][$column_phid][$object_phid]); | ||||
return $this; | return $this; | ||||
} | } | ||||
public function queueAddPositionBefore( | |||||
$board_phid, | |||||
$column_phid, | |||||
$object_phid, | |||||
$before_phid) { | |||||
return $this->queueAddPositionRelative( | |||||
$board_phid, | |||||
$column_phid, | |||||
$object_phid, | |||||
$before_phid, | |||||
true); | |||||
} | |||||
public function queueAddPositionAfter( | |||||
$board_phid, | |||||
$column_phid, | |||||
$object_phid, | |||||
$after_phid) { | |||||
return $this->queueAddPositionRelative( | |||||
$board_phid, | |||||
$column_phid, | |||||
$object_phid, | |||||
$after_phid, | |||||
false); | |||||
} | |||||
public function queueAddPosition( | public function queueAddPosition( | ||||
$board_phid, | $board_phid, | ||||
$column_phid, | $column_phid, | ||||
$object_phid) { | |||||
return $this->queueAddPositionRelative( | |||||
$board_phid, | |||||
$column_phid, | |||||
$object_phid, | |||||
null, | |||||
true); | |||||
} | |||||
private function queueAddPositionRelative( | |||||
$board_phid, | |||||
$column_phid, | |||||
$object_phid, | $object_phid, | ||||
$relative_phid, | array $after_phids, | ||||
$is_before) { | array $before_phids) { | ||||
$board_layout = idx($this->boardLayout, $board_phid, array()); | $board_layout = idx($this->boardLayout, $board_phid, array()); | ||||
$positions = idx($board_layout, $column_phid, array()); | $positions = idx($board_layout, $column_phid, array()); | ||||
// Check if the object is already in the column, and remove it if it is. | // Check if the object is already in the column, and remove it if it is. | ||||
$object_position = idx($positions, $object_phid); | $object_position = idx($positions, $object_phid); | ||||
unset($positions[$object_phid]); | unset($positions[$object_phid]); | ||||
if (!$object_position) { | if (!$object_position) { | ||||
$object_position = id(new PhabricatorProjectColumnPosition()) | $object_position = id(new PhabricatorProjectColumnPosition()) | ||||
->setBoardPHID($board_phid) | ->setBoardPHID($board_phid) | ||||
->setColumnPHID($column_phid) | ->setColumnPHID($column_phid) | ||||
->setObjectPHID($object_phid); | ->setObjectPHID($object_phid); | ||||
} | } | ||||
$found = false; | |||||
if (!$positions) { | if (!$positions) { | ||||
$object_position->setSequence(0); | $object_position->setSequence(0); | ||||
} else { | } else { | ||||
// The user's view of the board may fall out of date, so they might | |||||
// try to drop a card under a different card which is no longer where | |||||
// they thought it was. | |||||
// When this happens, we perform the move anyway, since this is almost | |||||
// certainly what users want when interacting with the UI. We'l try to | |||||
// fall back to another nearby card if the client provided us one. If | |||||
// we don't find any of the cards the client specified in the column, | |||||
// we'll just move the card to the default position. | |||||
$search_phids = array(); | |||||
foreach ($after_phids as $after_phid) { | |||||
$search_phids[] = array($after_phid, false); | |||||
} | |||||
foreach ($before_phids as $before_phid) { | |||||
$search_phids[] = array($before_phid, true); | |||||
} | |||||
// This makes us fall back to the default position if we fail every | |||||
// candidate position. The default position counts as a "before" position | |||||
// because we want to put the new card at the top of the column. | |||||
$search_phids[] = array(null, true); | |||||
$found = false; | |||||
foreach ($search_phids as $search_position) { | |||||
list($relative_phid, $is_before) = $search_position; | |||||
foreach ($positions as $position) { | foreach ($positions as $position) { | ||||
if (!$found) { | if (!$found) { | ||||
if ($relative_phid === null) { | if ($relative_phid === null) { | ||||
$is_match = true; | $is_match = true; | ||||
} else { | } else { | ||||
$position_phid = $position->getObjectPHID(); | $position_phid = $position->getObjectPHID(); | ||||
$is_match = ($relative_phid == $position_phid); | $is_match = ($relative_phid === $position_phid); | ||||
} | } | ||||
if ($is_match) { | if ($is_match) { | ||||
$found = true; | $found = true; | ||||
$sequence = $position->getSequence(); | $sequence = $position->getSequence(); | ||||
if (!$is_before) { | if (!$is_before) { | ||||
$sequence++; | $sequence++; | ||||
} | } | ||||
$object_position->setSequence($sequence++); | $object_position->setSequence($sequence++); | ||||
if (!$is_before) { | if (!$is_before) { | ||||
// If we're inserting after this position, continue the loop so | // If we're inserting after this position, continue the loop so | ||||
// we don't update it. | // we don't update it. | ||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if ($found) { | if ($found) { | ||||
$position->setSequence($sequence++); | $position->setSequence($sequence++); | ||||
$this->addQueue[] = $position; | $this->addQueue[] = $position; | ||||
} | } | ||||
} | } | ||||
} | |||||
if ($relative_phid && !$found) { | if ($found) { | ||||
throw new Exception( | break; | ||||
pht( | } | ||||
'Unable to find object "%s" in column "%s" on board "%s".', | } | ||||
$relative_phid, | |||||
$column_phid, | |||||
$board_phid)); | |||||
} | } | ||||
$this->addQueue[] = $object_position; | $this->addQueue[] = $object_position; | ||||
$positions[$object_phid] = $object_position; | $positions[$object_phid] = $object_position; | ||||
$positions = msort($positions, 'getOrderingKey'); | $positions = msort($positions, 'getOrderingKey'); | ||||
$this->boardLayout[$board_phid][$column_phid] = $positions; | $this->boardLayout[$board_phid][$column_phid] = $positions; | ||||
▲ Show 20 Lines • Show All 361 Lines • Show Last 20 Lines |