mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-20 13:52:40 +01:00
Implement "Revert to Version" functionality in Phragment
Summary: This functionality allows users to revert a fragment to a previous version from the history page. Reverting a version actually creates a new version pointing at the same file as the version being "reverted" to. In this sense it acts pretty much like Git and other distributed VCS where once you have published a commit the only way to undo your changes is to create a new commit that reverts those changes. Test Plan: Reverted a fragment to a version before it was deleted, then reverted it to when it was deleted and saw the new versions have the correct file PHIDs (including null for the deletion). Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley CC: Korvin, epriestley, aran Maniphest Tasks: T4205 Differential Revision: https://secure.phabricator.com/D7738
This commit is contained in:
parent
dabc7ea28d
commit
e165787725
4 changed files with 103 additions and 0 deletions
|
@ -2188,6 +2188,7 @@ phutil_register_library_map(array(
|
||||||
'PhragmentPHIDTypeFragmentVersion' => 'applications/phragment/phid/PhragmentPHIDTypeFragmentVersion.php',
|
'PhragmentPHIDTypeFragmentVersion' => 'applications/phragment/phid/PhragmentPHIDTypeFragmentVersion.php',
|
||||||
'PhragmentPatchController' => 'applications/phragment/controller/PhragmentPatchController.php',
|
'PhragmentPatchController' => 'applications/phragment/controller/PhragmentPatchController.php',
|
||||||
'PhragmentPatchUtil' => 'applications/phragment/util/PhragmentPatchUtil.php',
|
'PhragmentPatchUtil' => 'applications/phragment/util/PhragmentPatchUtil.php',
|
||||||
|
'PhragmentRevertController' => 'applications/phragment/controller/PhragmentRevertController.php',
|
||||||
'PhragmentUpdateController' => 'applications/phragment/controller/PhragmentUpdateController.php',
|
'PhragmentUpdateController' => 'applications/phragment/controller/PhragmentUpdateController.php',
|
||||||
'PhragmentVersionController' => 'applications/phragment/controller/PhragmentVersionController.php',
|
'PhragmentVersionController' => 'applications/phragment/controller/PhragmentVersionController.php',
|
||||||
'PhragmentZIPController' => 'applications/phragment/controller/PhragmentZIPController.php',
|
'PhragmentZIPController' => 'applications/phragment/controller/PhragmentZIPController.php',
|
||||||
|
@ -4790,6 +4791,7 @@ phutil_register_library_map(array(
|
||||||
'PhragmentPHIDTypeFragmentVersion' => 'PhabricatorPHIDType',
|
'PhragmentPHIDTypeFragmentVersion' => 'PhabricatorPHIDType',
|
||||||
'PhragmentPatchController' => 'PhragmentController',
|
'PhragmentPatchController' => 'PhragmentController',
|
||||||
'PhragmentPatchUtil' => 'Phobject',
|
'PhragmentPatchUtil' => 'Phobject',
|
||||||
|
'PhragmentRevertController' => 'PhragmentController',
|
||||||
'PhragmentUpdateController' => 'PhragmentController',
|
'PhragmentUpdateController' => 'PhragmentController',
|
||||||
'PhragmentVersionController' => 'PhragmentController',
|
'PhragmentVersionController' => 'PhragmentController',
|
||||||
'PhragmentZIPController' => 'PhragmentController',
|
'PhragmentZIPController' => 'PhragmentController',
|
||||||
|
|
|
@ -41,6 +41,7 @@ final class PhabricatorApplicationPhragment extends PhabricatorApplication {
|
||||||
'zip/(?P<dblob>.*)' => 'PhragmentZIPController',
|
'zip/(?P<dblob>.*)' => 'PhragmentZIPController',
|
||||||
'version/(?P<id>[0-9]*)/' => 'PhragmentVersionController',
|
'version/(?P<id>[0-9]*)/' => 'PhragmentVersionController',
|
||||||
'patch/(?P<aid>[0-9x]*)/(?P<bid>[0-9]*)/' => 'PhragmentPatchController',
|
'patch/(?P<aid>[0-9x]*)/(?P<bid>[0-9]*)/' => 'PhragmentPatchController',
|
||||||
|
'revert/(?P<id>[0-9]*)/(?P<dblob>.*)' => 'PhragmentRevertController',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ final class PhragmentHistoryController extends PhragmentController {
|
||||||
->execute();
|
->execute();
|
||||||
$files = mpull($files, null, 'getPHID');
|
$files = mpull($files, null, 'getPHID');
|
||||||
|
|
||||||
|
$first = true;
|
||||||
foreach ($versions as $version) {
|
foreach ($versions as $version) {
|
||||||
$item = id(new PHUIObjectItemView());
|
$item = id(new PHUIObjectItemView());
|
||||||
$item->setHeader('Version '.$version->getSequence());
|
$item->setHeader('Version '.$version->getSequence());
|
||||||
|
@ -57,6 +58,16 @@ final class PhragmentHistoryController extends PhragmentController {
|
||||||
$item->addAttribute('Deletion');
|
$item->addAttribute('Deletion');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$first) {
|
||||||
|
$item->addAction(id(new PHUIListItemView())
|
||||||
|
->setIcon('undo')
|
||||||
|
->setRenderNameAsTooltip(true)
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setName(pht("Revert to Here"))
|
||||||
|
->setHref($this->getApplicationURI(
|
||||||
|
"revert/".$version->getID()."/".$current->getPath())));
|
||||||
|
}
|
||||||
|
|
||||||
$disabled = !isset($files[$version->getFilePHID()]);
|
$disabled = !isset($files[$version->getFilePHID()]);
|
||||||
$action = id(new PHUIListItemView())
|
$action = id(new PHUIListItemView())
|
||||||
->setIcon('download')
|
->setIcon('download')
|
||||||
|
@ -68,6 +79,8 @@ final class PhragmentHistoryController extends PhragmentController {
|
||||||
}
|
}
|
||||||
$item->addAction($action);
|
$item->addAction($action);
|
||||||
$list->addItem($item);
|
$list->addItem($item);
|
||||||
|
|
||||||
|
$first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
return $this->buildApplicationPage(
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhragmentRevertController extends PhragmentController {
|
||||||
|
|
||||||
|
private $dblob;
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->dblob = $data['dblob'];
|
||||||
|
$this->id = $data['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
|
$fragment = id(new PhragmentFragmentQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPaths(array($this->dblob))
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->executeOne();
|
||||||
|
if ($fragment === null) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$version = id(new PhragmentFragmentVersionQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withFragmentPHIDs(array($fragment->getPHID()))
|
||||||
|
->withIDs(array($this->id))
|
||||||
|
->executeOne();
|
||||||
|
if ($version === null) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->isDialogFormPost()) {
|
||||||
|
$file_phid = $version->getFilePHID();
|
||||||
|
|
||||||
|
$file = null;
|
||||||
|
if ($file_phid !== null) {
|
||||||
|
$file = id(new PhabricatorFileQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($file_phid))
|
||||||
|
->executeOne();
|
||||||
|
if ($file === null) {
|
||||||
|
throw new Exception(
|
||||||
|
"The file associated with this version was not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($file === null) {
|
||||||
|
$fragment->deleteFile($viewer);
|
||||||
|
} else {
|
||||||
|
$fragment->updateFromFile($viewer, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id(new AphrontRedirectResponse())
|
||||||
|
->setURI($this->getApplicationURI('/history/'.$this->dblob));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->createDialog($fragment, $version);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDialog(
|
||||||
|
PhragmentFragment $fragment,
|
||||||
|
PhragmentFragmentVersion $version) {
|
||||||
|
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
|
$dialog = id(new AphrontDialogView())
|
||||||
|
->setTitle(pht('Really revert this fragment?'))
|
||||||
|
->setUser($request->getUser())
|
||||||
|
->addSubmitButton(pht('Revert'))
|
||||||
|
->addCancelButton(pht('Cancel'))
|
||||||
|
->appendParagraph(pht(
|
||||||
|
"Reverting this fragment to version %d will create a new version of ".
|
||||||
|
"the fragment. It will not delete any version history.",
|
||||||
|
$version->getSequence(),
|
||||||
|
$version->getSequence()));
|
||||||
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue