mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-20 12:30:56 +01:00
Implement "Download ZIP" controller for Phragment
Summary: Depends on D7727. This adds support for downloading a fragment and all it's children as a ZIP file. Fragments that have children automatically become directories in the ZIP file. Test Plan: Downloaded a fragment as a ZIP and was able to extract the contents successfully. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley CC: Korvin, epriestley, aran Maniphest Tasks: T4205 Differential Revision: https://secure.phabricator.com/D7728
This commit is contained in:
parent
f7f5a5dd34
commit
ccd4ae5638
4 changed files with 120 additions and 0 deletions
|
@ -2187,6 +2187,7 @@ phutil_register_library_map(array(
|
|||
'PhragmentPHIDTypeFragmentVersion' => 'applications/phragment/phid/PhragmentPHIDTypeFragmentVersion.php',
|
||||
'PhragmentPatchUtil' => 'applications/phragment/util/PhragmentPatchUtil.php',
|
||||
'PhragmentUpdateController' => 'applications/phragment/controller/PhragmentUpdateController.php',
|
||||
'PhragmentZIPController' => 'applications/phragment/controller/PhragmentZIPController.php',
|
||||
'PhrequentController' => 'applications/phrequent/controller/PhrequentController.php',
|
||||
'PhrequentDAO' => 'applications/phrequent/storage/PhrequentDAO.php',
|
||||
'PhrequentListController' => 'applications/phrequent/controller/PhrequentListController.php',
|
||||
|
@ -4785,6 +4786,7 @@ phutil_register_library_map(array(
|
|||
'PhragmentPHIDTypeFragmentVersion' => 'PhabricatorPHIDType',
|
||||
'PhragmentPatchUtil' => 'Phobject',
|
||||
'PhragmentUpdateController' => 'PhragmentController',
|
||||
'PhragmentZIPController' => 'PhragmentController',
|
||||
'PhrequentController' => 'PhabricatorController',
|
||||
'PhrequentDAO' => 'PhabricatorLiskDAO',
|
||||
'PhrequentListController' =>
|
||||
|
|
|
@ -38,6 +38,7 @@ final class PhabricatorApplicationPhragment extends PhabricatorApplication {
|
|||
'create/(?P<dblob>.*)' => 'PhragmentCreateController',
|
||||
'update/(?P<dblob>.*)' => 'PhragmentUpdateController',
|
||||
'history/(?P<dblob>.*)' => 'PhragmentHistoryController',
|
||||
'zip/(?P<dblob>.*)' => 'PhragmentZIPController',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -90,6 +90,12 @@ abstract class PhragmentController extends PhabricatorController {
|
|||
->setHref($file_uri)
|
||||
->setDisabled($file === null)
|
||||
->setIcon('download'));
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Download Contents as ZIP'))
|
||||
->setHref($this->getApplicationURI("zip/".$fragment->getPath()))
|
||||
->setDisabled(false) // TODO: Policy
|
||||
->setIcon('zip'));
|
||||
$actions->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Update Fragment'))
|
||||
|
|
111
src/applications/phragment/controller/PhragmentZIPController.php
Normal file
111
src/applications/phragment/controller/PhragmentZIPController.php
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?php
|
||||
|
||||
final class PhragmentZIPController extends PhragmentController {
|
||||
|
||||
private $dblob;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->dblob = idx($data, "dblob", "");
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
|
||||
$parents = $this->loadParentFragments($this->dblob);
|
||||
if ($parents === null) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
$fragment = idx($parents, count($parents) - 1, null);
|
||||
|
||||
$temp = new TempFile();
|
||||
|
||||
$zip = null;
|
||||
try {
|
||||
$zip = new ZipArchive();
|
||||
} catch (Exception $e) {
|
||||
$dialog = new AphrontDialogView();
|
||||
$dialog->setUser($viewer);
|
||||
|
||||
$inst = pht(
|
||||
'This system does not have the ZIP PHP extension installed. This '.
|
||||
'is required to download ZIPs from Phragment.');
|
||||
|
||||
$dialog->setTitle(pht('ZIP Extension Not Installed'));
|
||||
$dialog->appendParagraph($inst);
|
||||
|
||||
$dialog->addCancelButton('/phragment/browse/'.$this->dblob);
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
if (!$zip->open((string)$temp, ZipArchive::CREATE)) {
|
||||
throw new Exception("Unable to create ZIP archive!");
|
||||
}
|
||||
|
||||
$mappings = $this->getFragmentMappings($fragment, $fragment->getPath());
|
||||
|
||||
$phids = array();
|
||||
foreach ($mappings as $path => $file_phid) {
|
||||
$phids[] = $file_phid;
|
||||
}
|
||||
|
||||
$files = id(new PhabricatorFileQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($phids)
|
||||
->execute();
|
||||
$files = mpull($files, null, 'getPHID');
|
||||
foreach ($mappings as $path => $file_phid) {
|
||||
if (!isset($files[$file_phid])) {
|
||||
unset($mappings[$path]);
|
||||
}
|
||||
$mappings[$path] = $files[$file_phid];
|
||||
}
|
||||
|
||||
foreach ($mappings as $path => $file) {
|
||||
$zip->addFromString($path, $file->loadFileData());
|
||||
}
|
||||
$zip->close();
|
||||
|
||||
$zip_name = $fragment->getName();
|
||||
if (substr($zip_name, -4) !== '.zip') {
|
||||
$zip_name .= '.zip';
|
||||
}
|
||||
|
||||
$data = Filesystem::readFile((string)$temp);
|
||||
$file = PhabricatorFile::buildFromFileDataOrHash(
|
||||
$data,
|
||||
array(
|
||||
'name' => $zip_name,
|
||||
'ttl' => time() + 60 * 60 * 24,
|
||||
));
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($file->getBestURI());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of mappings like array('some/path.txt' => 'file PHID');
|
||||
*/
|
||||
private function getFragmentMappings(PhragmentFragment $current, $base_path) {
|
||||
$children = id(new PhragmentFragmentQuery())
|
||||
->setViewer($this->getRequest()->getUser())
|
||||
->needLatestVersion(true)
|
||||
->withLeadingPath($current->getPath().'/')
|
||||
->withDepths(array($current->getDepth() + 1))
|
||||
->execute();
|
||||
|
||||
if (count($children) === 0) {
|
||||
$path = substr($current->getPath(), strlen($base_path) + 1);
|
||||
return array($path => $current->getLatestVersion()->getFilePHID());
|
||||
} else {
|
||||
$mappings = array();
|
||||
foreach ($children as $child) {
|
||||
$child_mappings = $this->getFragmentMappings($child, $base_path);
|
||||
foreach ($child_mappings as $key => $value) {
|
||||
$mappings[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $mappings;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue