Page MenuHomePhabricator

D7728.diff
No OneTemporary

D7728.diff

Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -2187,6 +2187,7 @@
'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 @@
'PhragmentPHIDTypeFragmentVersion' => 'PhabricatorPHIDType',
'PhragmentPatchUtil' => 'Phobject',
'PhragmentUpdateController' => 'PhragmentController',
+ 'PhragmentZIPController' => 'PhragmentController',
'PhrequentController' => 'PhabricatorController',
'PhrequentDAO' => 'PhabricatorLiskDAO',
'PhrequentListController' =>
Index: src/applications/phragment/application/PhabricatorApplicationPhragment.php
===================================================================
--- src/applications/phragment/application/PhabricatorApplicationPhragment.php
+++ src/applications/phragment/application/PhabricatorApplicationPhragment.php
@@ -38,6 +38,7 @@
'create/(?P<dblob>.*)' => 'PhragmentCreateController',
'update/(?P<dblob>.*)' => 'PhragmentUpdateController',
'history/(?P<dblob>.*)' => 'PhragmentHistoryController',
+ 'zip/(?P<dblob>.*)' => 'PhragmentZIPController',
),
);
}
Index: src/applications/phragment/controller/PhragmentController.php
===================================================================
--- src/applications/phragment/controller/PhragmentController.php
+++ src/applications/phragment/controller/PhragmentController.php
@@ -92,6 +92,12 @@
->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'))
->setHref($this->getApplicationURI("update/".$fragment->getPath()))
->setDisabled(false) // TODO: Policy
Index: src/applications/phragment/controller/PhragmentZIPController.php
===================================================================
--- /dev/null
+++ src/applications/phragment/controller/PhragmentZIPController.php
@@ -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;
+ }
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 21, 3:58 PM (1 w, 10 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7332669
Default Alt Text
D7728.diff (6 KB)

Event Timeline