Implement snapshots in Phragment

Summary:
Ref T4212.  This implements snapshots in Phragment, which allows you to take a snapshot of a fragment at a given point in time, and download a ZIP of the snapshot as it was in this state.

There's also functionality for deleting and promoting snapshots.  You can promote a snapshot to either the latest version or any other snapshot of the fragment.

Test Plan: Clicked around, took some snapshots, promoted them to different points and deleted snapshots.  Also downloaded ZIPs of the snapshots and saw the right versions coming through for all the files downloaded.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4205, T4212

Differential Revision: https://secure.phabricator.com/D7741
This commit is contained in:
James Rhodes
2013-12-09 08:24:50 +11:00
parent e165787725
commit 8bb6e807f0
20 changed files with 1151 additions and 9 deletions

View File

@@ -0,0 +1,146 @@
<?php
final class PhragmentSnapshotViewController extends PhragmentController {
private $id;
public function willProcessRequest(array $data) {
$this->id = idx($data, "id", "");
}
public function processRequest() {
$request = $this->getRequest();
$viewer = $request->getUser();
$snapshot = id(new PhragmentSnapshotQuery())
->setViewer($viewer)
->withIDs(array($this->id))
->executeOne();
if ($snapshot === null) {
return new Aphront404Response();
}
$box = $this->createSnapshotView($snapshot);
$fragment = id(new PhragmentFragmentQuery())
->setViewer($viewer)
->withPHIDs(array($snapshot->getPrimaryFragmentPHID()))
->executeOne();
if ($fragment === null) {
return new Aphront404Response();
}
$parents = $this->loadParentFragments($fragment->getPath());
if ($parents === null) {
return new Aphront404Response();
}
$crumbs = $this->buildApplicationCrumbsWithPath($parents);
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName(pht('"%s" Snapshot', $snapshot->getName())));
$children = id(new PhragmentSnapshotChildQuery())
->setViewer($viewer)
->needFragments(true)
->needFragmentVersions(true)
->withSnapshotPHIDs(array($snapshot->getPHID()))
->execute();
$list = id(new PHUIObjectItemListView())
->setUser($viewer);
foreach ($children as $child) {
$item = id(new PHUIObjectItemView())
->setHeader($child->getFragment()->getPath());
if ($child->getFragmentVersion() !== null) {
$item
->setHref($child->getFragmentVersion()->getURI())
->addAttribute(pht(
'Version %s',
$child->getFragmentVersion()->getSequence()));
} else {
$item
->setHref($child->getFragment()->getURI())
->addAttribute(pht('Directory'));
}
$list->addItem($item);
}
return $this->buildApplicationPage(
array(
$crumbs,
$box,
$list),
array(
'title' => pht('View Snapshot'),
'device' => true));
}
protected function createSnapshotView($snapshot) {
if ($snapshot === null) {
return null;
}
$viewer = $this->getRequest()->getUser();
$phids = array();
$phids[] = $snapshot->getPrimaryFragmentPHID();
$this->loadHandles($phids);
$header = id(new PHUIHeaderView())
->setHeader(pht('"%s" Snapshot', $snapshot->getName()))
->setPolicyObject($snapshot)
->setUser($viewer);
$zip_uri = $this->getApplicationURI(
"zip@".$snapshot->getName().
"/".$snapshot->getPrimaryFragment()->getPath());
$actions = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($snapshot)
->setObjectURI($snapshot->getURI());
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Download Snapshot as ZIP'))
->setHref($zip_uri)
->setDisabled(false) // TODO: Policy
->setIcon('zip'));
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Delete Snapshot'))
->setHref($this->getApplicationURI(
"snapshot/delete/".$snapshot->getID()."/"))
->setWorkflow(true)
->setDisabled(false) // TODO: Policy
->setIcon('delete'));
$actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Promote Another Snapshot to Here'))
->setHref($this->getApplicationURI(
"snapshot/promote/".$snapshot->getID()."/"))
->setWorkflow(true)
->setDisabled(false) // TODO: Policy
->setIcon('promote'));
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($snapshot)
->setActionList($actions);
$properties->addProperty(
pht('Name'),
$snapshot->getName());
$properties->addProperty(
pht('Fragment'),
$this->renderHandlesForPHIDs(array($snapshot->getPrimaryFragmentPHID())));
return id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($properties);
}
}