phorge/src/applications/phragment/controller/PhragmentController.php36e2d02d6ec5master
phorge/src/applications/phragment/controller/PhragmentController.php
36e2d02d6ec5master
PhragmentController.php
PhragmentController.php
4c143ad3b2c4 | <?php | ||
---|---|---|---|
abstract class PhragmentController extends PhabricatorController { | |||
protected function loadParentFragments($path) { | |||
$components = explode('/', $path); | |||
$combinations = array(); | |||
$current = ''; | |||
foreach ($components as $component) { | |||
$current .= '/'.$component; | |||
$current = trim($current, '/'); | |||
if (trim($current) === '') { | |||
continue; | |||
} | |||
$combinations[] = $current; | |||
} | |||
$fragments = array(); | |||
$results = id(new PhragmentFragmentQuery()) | |||
->setViewer($this->getRequest()->getUser()) | |||
f7f5a5dd34de | ->needLatestVersion(true) | ||
4c143ad3b2c4 | ->withPaths($combinations) | ||
->execute(); | |||
foreach ($combinations as $combination) { | |||
$found = false; | |||
foreach ($results as $fragment) { | |||
if ($fragment->getPath() === $combination) { | |||
$fragments[] = $fragment; | |||
$found = true; | |||
break; | |||
} | |||
} | |||
if (!$found) { | |||
return null; | |||
} | |||
} | |||
return $fragments; | |||
} | |||
protected function buildApplicationCrumbsWithPath(array $fragments) { | |||
$crumbs = $this->buildApplicationCrumbs(); | |||
a5dc9067af0c | $crumbs->addTextCrumb('/', '/phragment/'); | ||
4c143ad3b2c4 | foreach ($fragments as $parent) { | ||
a5dc9067af0c | $crumbs->addTextCrumb( | ||
$parent->getName(), | |||
'/phragment/browse/'.$parent->getPath()); | |||
4c143ad3b2c4 | } | ||
return $crumbs; | |||
} | |||
f7f5a5dd34de | protected function createCurrentFragmentView($fragment, $is_history_view) { | ||
if ($fragment === null) { | |||
return null; | |||
} | |||
$viewer = $this->getRequest()->getUser(); | |||
8bb6e807f097 | $snapshot_phids = array(); | ||
$snapshots = id(new PhragmentSnapshotQuery()) | |||
->setViewer($viewer) | |||
->withPrimaryFragmentPHIDs(array($fragment->getPHID())) | |||
->execute(); | |||
foreach ($snapshots as $snapshot) { | |||
$snapshot_phids[] = $snapshot->getPHID(); | |||
} | |||
25e7b7d53cd5 | $file = null; | ||
f7f5a5dd34de | $file_uri = null; | ||
25e7b7d53cd5 | if (!$fragment->isDirectory()) { | ||
$file = id(new PhabricatorFileQuery()) | |||
->setViewer($viewer) | |||
->withPHIDs(array($fragment->getLatestVersion()->getFilePHID())) | |||
->executeOne(); | |||
if ($file !== null) { | |||
86ec4d602137 | $file_uri = $file->getDownloadURI(); | ||
25e7b7d53cd5 | } | ||
f7f5a5dd34de | } | ||
$header = id(new PHUIHeaderView()) | |||
->setHeader($fragment->getName()) | |||
->setPolicyObject($fragment) | |||
->setUser($viewer); | |||
86ec4d602137 | $can_edit = PhabricatorPolicyFilter::hasCapability( | ||
$viewer, | |||
$fragment, | |||
PhabricatorPolicyCapability::CAN_EDIT); | |||
0a62f13464b8 | $zip_uri = $this->getApplicationURI('zip/'.$fragment->getPath()); | ||
86ec4d602137 | |||
f7f5a5dd34de | $actions = id(new PhabricatorActionListView()) | ||
->setUser($viewer) | |||
->setObject($fragment) | |||
->setObjectURI($fragment->getURI()); | |||
$actions->addAction( | |||
id(new PhabricatorActionView()) | |||
->setName(pht('Download Fragment')) | |||
86ec4d602137 | ->setHref($this->isCorrectlyConfigured() ? $file_uri : null) | ||
->setDisabled($file === null || !$this->isCorrectlyConfigured()) | |||
b2f3001ec4be | ->setIcon('fa-download')); | ||
ccd4ae563827 | $actions->addAction( | ||
id(new PhabricatorActionView()) | |||
->setName(pht('Download Contents as ZIP')) | |||
86ec4d602137 | ->setHref($this->isCorrectlyConfigured() ? $zip_uri : null) | ||
->setDisabled(!$this->isCorrectlyConfigured()) | |||
b2f3001ec4be | ->setIcon('fa-floppy-o')); | ||
25e7b7d53cd5 | if (!$fragment->isDirectory()) { | ||
$actions->addAction( | |||
id(new PhabricatorActionView()) | |||
->setName(pht('Update Fragment')) | |||
0a62f13464b8 | ->setHref($this->getApplicationURI('update/'.$fragment->getPath())) | ||
86ec4d602137 | ->setDisabled(!$can_edit) | ||
->setWorkflow(!$can_edit) | |||
b2f3001ec4be | ->setIcon('fa-refresh')); | ||
25e7b7d53cd5 | } else { | ||
$actions->addAction( | |||
id(new PhabricatorActionView()) | |||
->setName(pht('Convert to File')) | |||
0a62f13464b8 | ->setHref($this->getApplicationURI('update/'.$fragment->getPath())) | ||
86ec4d602137 | ->setDisabled(!$can_edit) | ||
->setWorkflow(!$can_edit) | |||
b2f3001ec4be | ->setIcon('fa-file-o')); | ||
25e7b7d53cd5 | } | ||
86ec4d602137 | $actions->addAction( | ||
id(new PhabricatorActionView()) | |||
->setName(pht('Set Fragment Policies')) | |||
0a62f13464b8 | ->setHref($this->getApplicationURI('policy/'.$fragment->getPath())) | ||
86ec4d602137 | ->setDisabled(!$can_edit) | ||
->setWorkflow(!$can_edit) | |||
b2f3001ec4be | ->setIcon('fa-asterisk')); | ||
f7f5a5dd34de | if ($is_history_view) { | ||
$actions->addAction( | |||
id(new PhabricatorActionView()) | |||
->setName(pht('View Child Fragments')) | |||
0a62f13464b8 | ->setHref($this->getApplicationURI('browse/'.$fragment->getPath())) | ||
b2f3001ec4be | ->setIcon('fa-search-plus')); | ||
f7f5a5dd34de | } else { | ||
$actions->addAction( | |||
id(new PhabricatorActionView()) | |||
->setName(pht('View History')) | |||
0a62f13464b8 | ->setHref($this->getApplicationURI('history/'.$fragment->getPath())) | ||
b2f3001ec4be | ->setIcon('fa-list')); | ||
f7f5a5dd34de | } | ||
8bb6e807f097 | $actions->addAction( | ||
id(new PhabricatorActionView()) | |||
->setName(pht('Create Snapshot')) | |||
->setHref($this->getApplicationURI( | |||
0a62f13464b8 | 'snapshot/create/'.$fragment->getPath())) | ||
86ec4d602137 | ->setDisabled(!$can_edit) | ||
->setWorkflow(!$can_edit) | |||
b2f3001ec4be | ->setIcon('fa-files-o')); | ||
8bb6e807f097 | $actions->addAction( | ||
id(new PhabricatorActionView()) | |||
->setName(pht('Promote Snapshot to Here')) | |||
->setHref($this->getApplicationURI( | |||
0a62f13464b8 | 'snapshot/promote/latest/'.$fragment->getPath())) | ||
8bb6e807f097 | ->setWorkflow(true) | ||
86ec4d602137 | ->setDisabled(!$can_edit) | ||
b2f3001ec4be | ->setIcon('fa-arrow-circle-up')); | ||
f7f5a5dd34de | |||
$properties = id(new PHUIPropertyListView()) | |||
->setUser($viewer) | |||
->setObject($fragment) | |||
->setActionList($actions); | |||
25e7b7d53cd5 | if (!$fragment->isDirectory()) { | ||
dabc7ea28dec | if ($fragment->isDeleted()) { | ||
$properties->addProperty( | |||
pht('Type'), | |||
pht('File (Deleted)')); | |||
} else { | |||
$properties->addProperty( | |||
pht('Type'), | |||
pht('File')); | |||
} | |||
25e7b7d53cd5 | $properties->addProperty( | ||
pht('Latest Version'), | |||
a8271ecd4010 | $viewer->renderHandle($fragment->getLatestVersionPHID())); | ||
25e7b7d53cd5 | } else { | ||
$properties->addProperty( | |||
pht('Type'), | |||
pht('Directory')); | |||
} | |||
f7f5a5dd34de | |||
8bb6e807f097 | if (count($snapshot_phids) > 0) { | ||
$properties->addProperty( | |||
pht('Snapshots'), | |||
a8271ecd4010 | $viewer->renderHandleList($snapshot_phids)); | ||
8bb6e807f097 | } | ||
f7f5a5dd34de | return id(new PHUIObjectBoxView()) | ||
->setHeader($header) | |||
->addPropertyList($properties); | |||
} | |||
698b7f9ea39c | public function renderConfigurationWarningIfRequired() { | ||
0a62f13464b8 | $alt = PhabricatorEnv::getEnvConfig('security.alternate-file-domain'); | ||
86ec4d602137 | if ($alt === null) { | ||
c038c643f498 | return id(new PHUIInfoView()) | ||
86ec4d602137 | ->setTitle(pht('security.alternate-file-domain must be configured!')) | ||
c038c643f498 | ->setSeverity(PHUIInfoView::SEVERITY_ERROR) | ||
36e2d02d6ec5 | ->appendChild( | ||
phutil_tag( | |||
'p', | |||
array(), | |||
pht( | |||
"Because Phragment generates files (such as ZIP archives and ". | |||
"patches) as they are requested, it requires that you configure ". | |||
"the `%s` option. This option on it's own will also provide ". | |||
"additional security when serving files across Phabricator.", | |||
'security.alternate-file-domain'))); | |||
86ec4d602137 | } | ||
return null; | |||
} | |||
/** | |||
* We use this to disable the download links if the alternate domain is | |||
8756d82cf6c1 | * not configured correctly. Although the download links will mostly work | ||
86ec4d602137 | * for logged in users without an alternate domain, the behaviour is | ||
* reasonably non-consistent and will deny public users, even if policies | |||
* are configured otherwise (because the Files app does not support showing | |||
* the info page to viewers who are not logged in). | |||
*/ | |||
698b7f9ea39c | public function isCorrectlyConfigured() { | ||
0a62f13464b8 | $alt = PhabricatorEnv::getEnvConfig('security.alternate-file-domain'); | ||
86ec4d602137 | return $alt !== null; | ||
} | |||
4c143ad3b2c4 | } |
Owner Packages
Owner Packages
- No Owners