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 @@ -205,10 +205,6 @@ // Remove all existing column positions on the board. foreach ($positions as $position) { - if (!$position->getID()) { - // This is an ephemeral position, so don't try to destroy it. - continue; - } $position->delete(); } diff --git a/src/applications/project/query/PhabricatorProjectColumnPositionQuery.php b/src/applications/project/query/PhabricatorProjectColumnPositionQuery.php --- a/src/applications/project/query/PhabricatorProjectColumnPositionQuery.php +++ b/src/applications/project/query/PhabricatorProjectColumnPositionQuery.php @@ -178,14 +178,46 @@ $positions = $table->loadAllFromArray($data); + // Find the implied positions which don't exist yet. If there are any, + // we're going to create them. + $create = array(); foreach ($positions as $position) { if ($position->getColumnPHID() === null) { - $position->makeEphemeral(); $column_phid = idx($default_map, $position->getBoardPHID()); $position->setColumnPHID($column_phid); + + $create[] = $position; } } + if ($create) { + // If we're adding several objects to a column, insert the column + // position objects in object ID order. This means that newly added + // objects float to the top, and when a group of newly added objects + // float up at the same time, the most recently created ones end up + // highest in the list. + + $objects = id(new PhabricatorObjectQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withPHIDs(mpull($create, 'getObjectPHID')) + ->execute(); + $objects = mpull($objects, null, 'getPHID'); + $objects = msort($objects, 'getID'); + + $create = mgroup($create, 'getObjectPHID'); + $create = array_select_keys($create, array_keys($objects)) + $create; + + $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites(); + + foreach ($create as $object_phid => $create_positions) { + foreach ($create_positions as $create_position) { + $create_position->save(); + } + } + + unset($unguarded); + } + return $positions; }