Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F87945
D7728.diff
All Users
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
D7728.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/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' =>
diff --git a/src/applications/phragment/application/PhabricatorApplicationPhragment.php b/src/applications/phragment/application/PhabricatorApplicationPhragment.php
--- a/src/applications/phragment/application/PhabricatorApplicationPhragment.php
+++ b/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',
),
);
}
diff --git a/src/applications/phragment/controller/PhragmentController.php b/src/applications/phragment/controller/PhragmentController.php
--- a/src/applications/phragment/controller/PhragmentController.php
+++ b/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
diff --git a/src/applications/phragment/controller/PhragmentZIPController.php b/src/applications/phragment/controller/PhragmentZIPController.php
new file mode 100644
--- /dev/null
+++ b/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
Details
Attached
Mime Type
text/x-diff
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/se/ov/k5fsmpy5lqtjlbya
Default Alt Text
D7728.diff (6 KB)
Attached To
Mode
D7728: Implement "Download ZIP" controller for Phragment
Attached
Detach File
Event Timeline
Log In to Comment