Differential D7944 Diff 17986 src/applications/project/controller/PhabricatorProjectMoveController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/project/controller/PhabricatorProjectMoveController.php
<?php | <?php | ||||
final class PhabricatorProjectMoveController | final class PhabricatorProjectMoveController | ||||
extends PhabricatorProjectController { | extends PhabricatorProjectController { | ||||
private $id; | private $id; | ||||
public function willProcessRequest(array $data) { | public function willProcessRequest(array $data) { | ||||
$this->id = $data['id']; | $this->id = $data['id']; | ||||
} | } | ||||
public function processRequest() { | public function processRequest() { | ||||
$request = $this->getRequest(); | $request = $this->getRequest(); | ||||
$viewer = $request->getUser(); | $viewer = $request->getUser(); | ||||
$column_phid = $request->getStr('columnPHID'); | |||||
$object_phid = $request->getStr('objectPHID'); | |||||
$after_phid = $request->getStr('afterPHID'); | |||||
$project = id(new PhabricatorProjectQuery()) | $project = id(new PhabricatorProjectQuery()) | ||||
->setViewer($viewer) | ->setViewer($viewer) | ||||
->requireCapabilities( | ->requireCapabilities( | ||||
array( | array( | ||||
PhabricatorPolicyCapability::CAN_VIEW, | PhabricatorPolicyCapability::CAN_VIEW, | ||||
PhabricatorPolicyCapability::CAN_EDIT, | PhabricatorPolicyCapability::CAN_EDIT, | ||||
)) | )) | ||||
->withIDs(array($this->id)) | ->withIDs(array($this->id)) | ||||
->executeOne(); | ->executeOne(); | ||||
if (!$project) { | if (!$project) { | ||||
return new Aphront404Response(); | 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); | |||||
// TODO: We also need to deal with priorities, so far this only gets stuff | |||||
// in the correct column. | |||||
return id(new AphrontAjaxResponse())->setContent(array()); | 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(); | |||||
} | |||||
} | } |