1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-11 17:32:41 +01:00
phorge-phorge/src/applications/project/controller/PhabricatorProjectMoveController.php
Bob Trahan 37b1b31638 Maniphest - move subpriority edits to be transaction powered
Summary:
...this was nice to do for boards, since this diff also starts calling this code in the board move case. The big trick is to use the new expandTransactions hook to expand the subpriority transaction into a priority transaction if pertinent. The other stuff is just about hiding these new subpriority extractions.

...also removes the "edit" UI from the default board since we can't actually edit anything and it thus is buggy.

Ref T4422. Next step is to move board edits into the editor with their own little transaction.

Test Plan: re-orded tasks on a maniphest query, reloaded, and noted re-order stuck.

Reviewers: epriestley

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4422

Differential Revision: https://secure.phabricator.com/D8358
2014-02-27 09:39:59 -08:00

143 lines
3.9 KiB
PHP

<?php
final class PhabricatorProjectMoveController
extends PhabricatorProjectController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$column_phid = $request->getStr('columnPHID');
$object_phid = $request->getStr('objectPHID');
$after_phid = $request->getStr('afterPHID');
$project = id(new PhabricatorProjectQuery())
->setViewer($viewer)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->withIDs(array($this->id))
->executeOne();
if (!$project) {
return new Aphront404Response();
}
// NOTE: I'm not requiring EDIT on the object for now, since we require
// EDIT on the project anyway and this relationship is more owned by the
// project than the object. Maybe this is worth revisiting eventually.
$object = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->withPHIDs(array($object_phid))
->executeOne();
if (!$object) {
return new Aphront404Response();
}
$columns = id(new PhabricatorProjectColumnQuery())
->setViewer($viewer)
->withProjectPHIDs(array($project->getPHID()))
->execute();
$columns = mpull($columns, null, 'getPHID');
if (empty($columns[$column_phid])) {
// User is trying to drop this object into a nonexistent column, just kick
// them out.
return new Aphront404Response();
}
$edge_type = PhabricatorEdgeConfig::TYPE_OBJECT_HAS_COLUMN;
$query = id(new PhabricatorEdgeQuery())
->withSourcePHIDs(array($object->getPHID()))
->withEdgeTypes(array($edge_type))
->withDestinationPHIDs(array_keys($columns));
$query->execute();
$edge_phids = $query->getDestinationPHIDs();
$this->rewriteEdges(
$object->getPHID(),
$edge_type,
$column_phid,
$edge_phids);
if ($after_phid) {
$after_task = id(new ManiphestTaskQuery())
->setViewer($viewer)
->withPHIDs(array($after_phid))
->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT))
->executeOne();
if (!$after_task) {
return new Aphront404Response();
}
$after_pri = $after_task->getPriority();
$after_sub = $after_task->getSubpriority();
$xactions = array(id(new ManiphestTransaction())
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
->setNewValue(array(
'newPriority' => $after_pri,
'newSubpriorityBase' => $after_sub)));
$editor = id(new ManiphestTransactionEditor())
->setActor($viewer)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request);
$editor->applyTransactions($object, $xactions);
}
return id(new AphrontAjaxResponse())->setContent(array());
}
private function rewriteEdges($src, $edge_type, $dst, array $edges) {
$viewer = $this->getRequest()->getUser();
// NOTE: Normally, we expect only one edge to exist, but this works in a
// general way so it will repair any stray edges.
$remove = array();
$edge_missing = true;
foreach ($edges as $phid) {
if ($phid == $dst) {
$edge_missing = false;
} else {
$remove[] = $phid;
}
}
$add = array();
if ($edge_missing) {
$add[] = $dst;
}
if (!$add && !$remove) {
return;
}
$editor = id(new PhabricatorEdgeEditor())
->setActor($viewer)
->setSuppressEvents(true);
foreach ($add as $phid) {
$editor->addEdge($src, $edge_type, $phid);
}
foreach ($remove as $phid) {
$editor->removeEdge($src, $edge_type, $phid);
}
$editor->save();
}
}