diff --git a/src/applications/files/controller/PhabricatorFileInfoController.php b/src/applications/files/controller/PhabricatorFileInfoController.php
index cea2272bd..9b1f1c061 100644
--- a/src/applications/files/controller/PhabricatorFileInfoController.php
+++ b/src/applications/files/controller/PhabricatorFileInfoController.php
@@ -1,164 +1,165 @@
phid = $data['phid'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$file = id(new PhabricatorFileQuery())
->setViewer($user)
->withPHIDs(array($this->phid))
->executeOne();
if (!$file) {
return new Aphront404Response();
}
$this->loadHandles(array($file->getAuthorPHID()));
$phid = $file->getPHID();
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName('F'.$file->getID())
->setHref($this->getApplicationURI("/info/{$phid}/")));
$header = id(new PhabricatorHeaderView())
->setObjectName('F'.$file->getID())
->setHeader($file->getName());
$actions = $this->buildActionView($file);
$properties = $this->buildPropertyView($file);
return $this->buildApplicationPage(
array(
$crumbs,
$header,
$actions,
$properties,
),
array(
'title' => $file->getName(),
'device' => true,
));
}
private function buildActionView(PhabricatorFile $file) {
$request = $this->getRequest();
$user = $request->getUser();
$id = $file->getID();
$view = id(new PhabricatorActionListView())
->setUser($user)
->setObject($file);
if ($file->isViewableInBrowser()) {
$view->addAction(
id(new PhabricatorActionView())
->setName(pht('View File'))
->setIcon('preview')
->setHref($file->getViewURI()));
} else {
$view->addAction(
id(new PhabricatorActionView())
->setUser($user)
->setRenderAsForm(true)
+ ->setDownload(true)
->setName(pht('Download File'))
->setIcon('download')
->setHref($file->getViewURI()));
}
$view->addAction(
id(new PhabricatorActionView())
->setName(pht('Delete File'))
->setIcon('delete')
->setHref($this->getApplicationURI("/delete/{$id}/"))
->setWorkflow(true));
return $view;
}
private function buildPropertyView(PhabricatorFile $file) {
$request = $this->getRequest();
$user = $request->getUser();
$view = id(new PhabricatorPropertyListView());
if ($file->getAuthorPHID()) {
$view->addProperty(
pht('Author'),
$this->getHandle($file->getAuthorPHID())->renderLink());
}
$view->addProperty(
pht('Created'),
phabricator_datetime($file->getDateCreated(), $user));
$view->addProperty(
pht('Size'),
phabricator_format_bytes($file->getByteSize()));
$view->addSectionHeader(pht('Technical Details'));
$view->addProperty(
pht('Mime Type'),
phutil_escape_html($file->getMimeType()));
$view->addProperty(
pht('Engine'),
phutil_escape_html($file->getStorageEngine()));
$view->addProperty(
pht('Format'),
phutil_escape_html($file->getStorageFormat()));
$view->addProperty(
pht('Handle'),
phutil_escape_html($file->getStorageHandle()));
$metadata = $file->getMetadata();
if (!empty($metadata)) {
$view->addSectionHeader(pht('Metadata'));
foreach ($metadata as $key => $value) {
$view->addProperty(
PhabricatorFile::getMetadataName($key),
phutil_escape_html($value));
}
}
if ($file->isViewableImage()) {
// TODO: Clean this up after Pholio (dark backgrounds, standardization,
// etc.)
$image = phutil_tag(
'img',
array(
'src' => $file->getViewURI(),
'class' => 'phabricator-property-list-image',
));
$linked_image = phutil_tag(
'a',
array(
'href' => $file->getViewURI(),
),
$image);
$view->addTextContent($linked_image);
}
return $view;
}
}
diff --git a/src/view/AphrontTagView.php b/src/view/AphrontTagView.php
index 5b276e11f..0b3f17a09 100644
--- a/src/view/AphrontTagView.php
+++ b/src/view/AphrontTagView.php
@@ -1,158 +1,158 @@
workflow = $workflow;
return $this;
}
public function getWorkflow() {
return $this->workflow;
}
public function setMustCapture($must_capture) {
$this->mustCapture = $must_capture;
return $this;
}
public function getMustCapture() {
return $this->mustCapture;
}
final public function setMetadata(array $metadata) {
$this->metadata = $metadata;
return $this;
}
final public function getMetadata() {
return $this->metadata;
}
final public function setStyle($style) {
$this->style = $style;
return $this;
}
final public function getStyle() {
return $this->style;
}
final public function addSigil($sigil) {
$this->sigils[] = $sigil;
return $this;
}
- final public function getSigil() {
- return $this->sigil;
+ final public function getSigils() {
+ return $this->sigils;
}
public function addClass($class) {
$this->classes[] = $class;
return $this;
}
public function getClass() {
return $this->class;
}
public function setID($id) {
$this->id = $id;
return $this;
}
public function getID() {
return $this->id;
}
protected function getTagName() {
return 'div';
}
protected function getTagAttributes() {
return array();
}
protected function getTagContent() {
return $this->renderChildren();
}
protected function willRender() {
return;
}
final public function render() {
$this->willRender();
$attributes = $this->getTagAttributes();
$implode = array('class', 'sigil');
foreach ($implode as $attr) {
if (isset($attributes[$attr])) {
if (is_array($attributes[$attr])) {
$attributes[$attr] = implode(' ', $attributes[$attr]);
}
}
}
if (!is_array($attributes)) {
$class = get_class($this);
throw new Exception(
"View '{$class}' did not return an array from getTagAttributes()!");
}
$sigils = $this->sigils;
if ($this->workflow) {
$sigils[] = 'workflow';
}
$tag_view_attributes = array(
'id' => $this->id,
'class' => $this->classes ? implode(' ', $this->classes) : null,
'style' => $this->style,
'meta' => $this->metadata,
'sigil' => $sigils ? implode(' ', $sigils) : null,
'mustcapture' => $this->mustCapture,
);
foreach ($tag_view_attributes as $key => $value) {
if ($value === null) {
continue;
}
if (!isset($attributes[$key])) {
$attributes[$key] = $value;
continue;
}
switch ($key) {
case 'class':
case 'sigil':
$attributes[$key] = $attributes[$key].' '.$value;
break;
default:
// Use the explicitly set value rather than the tag default value.
$attributes[$key] = $value;
break;
}
}
return javelin_render_tag(
$this->getTagName(),
$attributes,
$this->getTagContent());
}
}
diff --git a/src/view/form/AphrontFormView.php b/src/view/form/AphrontFormView.php
index 1dca03e2c..8b0041f00 100644
--- a/src/view/form/AphrontFormView.php
+++ b/src/view/form/AphrontFormView.php
@@ -1,114 +1,112 @@
flexible = $flexible;
return $this;
}
public function setID($id) {
$this->id = $id;
return $this;
}
public function setAction($action) {
$this->action = $action;
return $this;
}
public function setMethod($method) {
$this->method = $method;
return $this;
}
public function setEncType($enc_type) {
$this->encType = $enc_type;
return $this;
}
public function addHiddenInput($key, $value) {
$this->data[$key] = $value;
return $this;
}
public function setWorkflow($workflow) {
$this->workflow = $workflow;
return $this;
}
public function addSigil($sigil) {
$this->sigils[] = $sigil;
return $this;
}
public function render() {
if ($this->flexible) {
require_celerity_resource('phabricator-form-view-css');
}
require_celerity_resource('aphront-form-view-css');
- Javelin::initBehavior('aphront-form-disable-on-submit');
-
$layout = new AphrontFormLayoutView();
if (!$this->flexible) {
$layout
->setBackgroundShading(true)
->setPadded(true);
}
$layout
->appendChild($this->renderDataInputs())
->appendChild($this->renderChildren());
if (!$this->user) {
throw new Exception('You must pass the user to AphrontFormView.');
}
$sigils = $this->sigils;
if ($this->workflow) {
$sigils[] = 'workflow';
}
return phabricator_render_form(
$this->user,
array(
'class' => $this->flexible ? 'phabricator-form-view' : null,
'action' => $this->action,
'method' => $this->method,
'enctype' => $this->encType,
'sigil' => $sigils ? implode(' ', $sigils) : null,
'id' => $this->id,
),
$layout->render());
}
private function renderDataInputs() {
$inputs = array();
foreach ($this->data as $key => $value) {
if ($value === null) {
continue;
}
$inputs[] = phutil_tag(
'input',
array(
'type' => 'hidden',
'name' => $key,
'value' => $value,
));
}
return implode("\n", $inputs);
}
}
diff --git a/src/view/layout/PhabricatorActionView.php b/src/view/layout/PhabricatorActionView.php
index 53c2c1e94..bb030b60c 100644
--- a/src/view/layout/PhabricatorActionView.php
+++ b/src/view/layout/PhabricatorActionView.php
@@ -1,138 +1,156 @@
download = $download;
+ return $this;
+ }
+
+ public function getDownload() {
+ return $this->download;
+ }
public function setHref($href) {
$this->href = $href;
return $this;
}
public function setIcon($icon) {
$this->icon = $icon;
return $this;
}
public function setName($name) {
$this->name = $name;
return $this;
}
public function setDisabled($disabled) {
$this->disabled = $disabled;
return $this;
}
public function setWorkflow($workflow) {
$this->workflow = $workflow;
return $this;
}
public function setRenderAsForm($form) {
$this->renderAsForm = $form;
return $this;
}
public function render() {
$icon = null;
if ($this->icon) {
$suffix = '';
if ($this->disabled) {
$suffix = '-grey';
}
require_celerity_resource('sprite-icon-css');
$icon = phutil_tag(
'span',
array(
'class' => 'phabricator-action-view-icon sprite-icon '.
'action-'.$this->icon.$suffix,
),
'');
}
if ($this->href) {
if ($this->renderAsForm) {
if (!$this->user) {
throw new Exception(
'Call setUser() when rendering an action as a form.');
}
$item = javelin_tag(
'button',
array(
'class' => 'phabricator-action-view-item',
),
$this->name);
+ $sigils = array();
+ if ($this->workflow) {
+ $sigils[] = 'workflow';
+ }
+ if ($this->download) {
+ $sigils[] = 'download';
+ }
+
$item = phabricator_render_form(
$this->user,
array(
'action' => $this->href,
'method' => 'POST',
- 'sigil' => $this->workflow ? 'workflow' : null,
+ 'sigil' => implode(' ', $sigils),
),
$item);
} else {
$item = javelin_tag(
'a',
array(
'href' => $this->href,
'class' => 'phabricator-action-view-item',
'sigil' => $this->workflow ? 'workflow' : null,
),
$this->name);
}
} else {
$item = phutil_tag(
'span',
array(
'class' => 'phabricator-action-view-item',
),
$this->name);
}
$classes = array();
$classes[] = 'phabricator-action-view';
if ($this->disabled) {
$classes[] = 'phabricator-action-view-disabled';
}
return phutil_tag(
'li',
array(
'class' => implode(' ', $classes),
),
array($icon, $item));
}
public static function getAvailableIcons() {
$root = dirname(phutil_get_library_root('phabricator'));
$path = $root.'/resources/sprite/manifest/icon.json';
$data = Filesystem::readFile($path);
$manifest = json_decode($data, true);
$results = array();
$prefix = 'action-';
foreach ($manifest['sprites'] as $sprite) {
$name = $sprite['name'];
if (preg_match('/-(white|grey)$/', $name)) {
continue;
}
if (!strncmp($name, $prefix, strlen($prefix))) {
$results[] = substr($name, strlen($prefix));
}
}
return $results;
}
}
diff --git a/src/view/page/PhabricatorStandardPageView.php b/src/view/page/PhabricatorStandardPageView.php
index b1ce431b1..26ae9f3c0 100644
--- a/src/view/page/PhabricatorStandardPageView.php
+++ b/src/view/page/PhabricatorStandardPageView.php
@@ -1,362 +1,381 @@
applicationMenu = $application_menu;
return $this;
}
public function getApplicationMenu() {
return $this->applicationMenu;
}
public function setApplicationName($application_name) {
$this->applicationName = $application_name;
return $this;
}
public function setDisableConsole($disable) {
$this->disableConsole = $disable;
return $this;
}
public function getApplicationName() {
return $this->applicationName;
}
public function setBaseURI($base_uri) {
$this->baseURI = $base_uri;
return $this;
}
public function getBaseURI() {
return $this->baseURI;
}
public function setShowChrome($show_chrome) {
$this->showChrome = $show_chrome;
return $this;
}
public function getShowChrome() {
return $this->showChrome;
}
public function setSearchDefaultScope($search_default_scope) {
$this->searchDefaultScope = $search_default_scope;
return $this;
}
public function getSearchDefaultScope() {
return $this->searchDefaultScope;
}
public function appendPageObjects(array $objs) {
foreach ($objs as $obj) {
$this->pageObjects[] = $obj;
}
}
public function getTitle() {
$use_glyph = true;
$request = $this->getRequest();
if ($request) {
$user = $request->getUser();
if ($user && $user->loadPreferences()->getPreference(
PhabricatorUserPreferences::PREFERENCE_TITLES) !== 'glyph') {
$use_glyph = false;
}
}
return ($use_glyph ?
$this->getGlyph() : '['.$this->getApplicationName().']').
' '.parent::getTitle();
}
protected function willRenderPage() {
parent::willRenderPage();
if (!$this->getRequest()) {
throw new Exception(
"You must set the Request to render a PhabricatorStandardPageView.");
}
$console = $this->getConsole();
require_celerity_resource('phabricator-core-css');
require_celerity_resource('phabricator-zindex-css');
require_celerity_resource('phabricator-core-buttons-css');
require_celerity_resource('sprite-gradient-css');
require_celerity_resource('phabricator-standard-page-view');
Javelin::initBehavior('workflow', array());
- $current_token = null;
$request = $this->getRequest();
+ $user = null;
if ($request) {
$user = $request->getUser();
- if ($user) {
- $current_token = $user->getCSRFToken();
- $download_form = phabricator_render_form_magic($user);
- $default_img_uri =
- PhabricatorEnv::getCDNURI(
- '/rsrc/image/icon/fatcow/document_black.png'
- );
-
- Javelin::initBehavior(
- 'lightbox-attachments',
- array(
- 'defaultImageUri' => $default_img_uri,
- 'downloadForm' => $download_form,
- ));
- }
}
+ if ($user) {
+ $default_img_uri =
+ PhabricatorEnv::getCDNURI(
+ '/rsrc/image/icon/fatcow/document_black.png'
+ );
+ $download_form = phabricator_render_form(
+ $user,
+ array(
+ 'action' => '#',
+ 'method' => 'POST',
+ 'class' => 'lightbox-download-form',
+ 'sigil' => 'download',
+ ),
+ phutil_tag(
+ 'button',
+ array(),
+ pht('Download')));
+
+ Javelin::initBehavior(
+ 'lightbox-attachments',
+ array(
+ 'defaultImageUri' => $default_img_uri,
+ 'downloadForm' => $download_form,
+ ));
+ }
+
+ Javelin::initBehavior('aphront-form-disable-on-submit');
Javelin::initBehavior('toggle-class', array());
Javelin::initBehavior('konami', array());
+
+ $current_token = null;
+ if ($user) {
+ $current_token = $user->getCSRFToken();
+ }
+
Javelin::initBehavior(
'refresh-csrf',
array(
'tokenName' => AphrontRequest::getCSRFTokenName(),
'header' => AphrontRequest::getCSRFHeaderName(),
'current' => $current_token,
));
+
Javelin::initBehavior('device');
if ($console) {
require_celerity_resource('aphront-dark-console-css');
Javelin::initBehavior(
'dark-console',
array(
'uri' => '/~/',
'request_uri' => $request ? (string) $request->getRequestURI() : '/',
));
// Change this to initBehavior when there is some behavior to initialize
require_celerity_resource('javelin-behavior-error-log');
}
$menu = id(new PhabricatorMainMenuView())
->setUser($request->getUser())
->setDefaultSearchScope($this->getSearchDefaultScope());
if ($this->getController()) {
$menu->setController($this->getController());
}
if ($this->getApplicationMenu()) {
$menu->setApplicationMenu($this->getApplicationMenu());
}
$this->menuContent = $menu->render();
}
protected function getHead() {
$monospaced = PhabricatorEnv::getEnvConfig('style.monospace');
$request = $this->getRequest();
if ($request) {
$user = $request->getUser();
if ($user) {
$monospaced = nonempty(
$user->loadPreferences()->getPreference(
PhabricatorUserPreferences::PREFERENCE_MONOSPACED),
$monospaced);
}
}
$response = CelerityAPI::getStaticResourceResponse();
$head = array(
parent::getHead(),
'',
$response->renderSingleResource('javelin-magical-init'),
);
return implode("\n", $head);
}
public function setGlyph($glyph) {
$this->glyph = $glyph;
return $this;
}
public function getGlyph() {
return $this->glyph;
}
protected function willSendResponse($response) {
$response = parent::willSendResponse($response);
$console = $this->getRequest()->getApplicationConfiguration()->getConsole();
if ($console) {
$response = str_replace(
'