Page MenuHomePhabricator

D21837.id.diff
No OneTemporary

D21837.id.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -9,7 +9,7 @@
'names' => array(
'conpherence.pkg.css' => '0e3cf785',
'conpherence.pkg.js' => '020aebcf',
- 'core.pkg.css' => '00a2e7f4',
+ 'core.pkg.css' => 'b816811e',
'core.pkg.js' => 'd2de90d9',
'dark-console.pkg.js' => '187792c2',
'differential.pkg.css' => 'ffb69e3d',
@@ -147,7 +147,7 @@
'rsrc/css/phui/phui-comment-form.css' => '68a2d99a',
'rsrc/css/phui/phui-comment-panel.css' => 'ec4e31c0',
'rsrc/css/phui/phui-crumbs-view.css' => '614f43cf',
- 'rsrc/css/phui/phui-curtain-object-ref-view.css' => '5f752bdb',
+ 'rsrc/css/phui/phui-curtain-object-ref-view.css' => '51d93266',
'rsrc/css/phui/phui-curtain-view.css' => '68c5efb6',
'rsrc/css/phui/phui-document-pro.css' => 'b9613a10',
'rsrc/css/phui/phui-document-summary.css' => 'b068eed1',
@@ -838,7 +838,7 @@
'phui-comment-form-css' => '68a2d99a',
'phui-comment-panel-css' => 'ec4e31c0',
'phui-crumbs-view-css' => '614f43cf',
- 'phui-curtain-object-ref-view-css' => '5f752bdb',
+ 'phui-curtain-object-ref-view-css' => '51d93266',
'phui-curtain-view-css' => '68c5efb6',
'phui-document-summary-view-css' => 'b068eed1',
'phui-document-view-css' => '52b748a5',
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
@@ -3508,6 +3508,7 @@
'PhabricatorFileTransformController' => 'applications/files/controller/PhabricatorFileTransformController.php',
'PhabricatorFileTransformListController' => 'applications/files/controller/PhabricatorFileTransformListController.php',
'PhabricatorFileTransformTestCase' => 'applications/files/transform/__tests__/PhabricatorFileTransformTestCase.php',
+ 'PhabricatorFileUICurtainAttachController' => 'applications/files/controller/PhabricatorFileUICurtainAttachController.php',
'PhabricatorFileUICurtainListController' => 'applications/files/controller/PhabricatorFileUICurtainListController.php',
'PhabricatorFileUploadController' => 'applications/files/controller/PhabricatorFileUploadController.php',
'PhabricatorFileUploadDialogController' => 'applications/files/controller/PhabricatorFileUploadDialogController.php',
@@ -9972,6 +9973,7 @@
'PhabricatorFileTransformController' => 'PhabricatorFileController',
'PhabricatorFileTransformListController' => 'PhabricatorFileController',
'PhabricatorFileTransformTestCase' => 'PhabricatorTestCase',
+ 'PhabricatorFileUICurtainAttachController' => 'PhabricatorFileController',
'PhabricatorFileUICurtainListController' => 'PhabricatorFileController',
'PhabricatorFileUploadController' => 'PhabricatorFileController',
'PhabricatorFileUploadDialogController' => 'PhabricatorFileController',
diff --git a/src/applications/base/controller/PhabricatorController.php b/src/applications/base/controller/PhabricatorController.php
--- a/src/applications/base/controller/PhabricatorController.php
+++ b/src/applications/base/controller/PhabricatorController.php
@@ -420,6 +420,10 @@
->setSubmitURI($submit_uri);
}
+ public function newRedirect() {
+ return id(new AphrontRedirectResponse());
+ }
+
public function newPage() {
$page = id(new PhabricatorStandardPageView())
->setRequest($this->getRequest())
diff --git a/src/applications/files/application/PhabricatorFilesApplication.php b/src/applications/files/application/PhabricatorFilesApplication.php
--- a/src/applications/files/application/PhabricatorFilesApplication.php
+++ b/src/applications/files/application/PhabricatorFilesApplication.php
@@ -95,8 +95,14 @@
),
'document/(?P<engineKey>[^/]+)/(?P<phid>[^/]+)/'
=> 'PhabricatorFileDocumentController',
- 'ui/curtainlist/(?P<phid>[^/]+)/'
- => 'PhabricatorFileUICurtainListController',
+ 'ui/' => array(
+ 'curtain/' => array(
+ 'list/(?P<phid>[^/]+)/'
+ => 'PhabricatorFileUICurtainListController',
+ 'attach/(?P<objectPHID>[^/]+)/(?P<filePHID>[^/]+)/'
+ => 'PhabricatorFileUICurtainAttachController',
+ ),
+ ),
) + $this->getResourceSubroutes(),
);
}
diff --git a/src/applications/files/controller/PhabricatorFileUICurtainAttachController.php b/src/applications/files/controller/PhabricatorFileUICurtainAttachController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/files/controller/PhabricatorFileUICurtainAttachController.php
@@ -0,0 +1,136 @@
+<?php
+
+final class PhabricatorFileUICurtainAttachController
+ extends PhabricatorFileController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $request->getViewer();
+
+ $object_phid = $request->getURIData('objectPHID');
+ $file_phid = $request->getURIData('filePHID');
+
+ $object = id(new PhabricatorObjectQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($object_phid))
+ ->executeOne();
+ if (!$object) {
+ return new Aphront404Response();
+ }
+
+ $attachment = id(new PhabricatorFileAttachmentQuery())
+ ->setViewer($viewer)
+ ->withObjectPHIDs(array($object->getPHID()))
+ ->withFilePHIDs(array($file_phid))
+ ->needFiles(true)
+ ->withVisibleFiles(true)
+ ->executeOne();
+ if (!$attachment) {
+ return new Aphront404Response();
+ }
+
+ $file = $attachment->getFile();
+ $file_phid = $file->getPHID();
+
+ $handles = $viewer->loadHandles(
+ array(
+ $object_phid,
+ $file_phid,
+ ));
+
+ $object_handle = $handles[$object_phid];
+ $file_handle = $handles[$file_phid];
+ $cancel_uri = $object_handle->getURI();
+
+ $dialog = $this->newDialog()
+ ->setViewer($viewer)
+ ->setTitle(pht('Attach File'))
+ ->addCancelButton($object_handle->getURI(), pht('Close'));
+
+ $file_link = phutil_tag('strong', array(), $file_handle->renderLink());
+ $object_link = phutil_tag('strong', array(), $object_handle->renderLink());
+
+ if ($attachment->isPolicyAttachment()) {
+ $body = pht(
+ 'The file %s is already attached to the object %s.',
+ $file_link,
+ $object_link);
+
+ return $dialog->appendParagraph($body);
+ }
+
+ if (!$request->isDialogFormPost()) {
+ $dialog->appendRemarkup(
+ pht(
+ '(WARNING) This file is referenced by this object, but '.
+ 'not formally attached to it. Users who can see the object may '.
+ 'not be able to see the file.'));
+
+ $dialog->appendParagraph(
+ pht(
+ 'Do you want to attach the file %s to the object %s?',
+ $file_link,
+ $object_link));
+
+ $dialog->addSubmitButton(pht('Attach File'));
+
+ return $dialog;
+ }
+
+ if (!$request->getBool('confirm')) {
+ $dialog->setTitle(pht('Confirm File Attachment'));
+
+ $dialog->addHiddenInput('confirm', 1);
+
+ $dialog->appendRemarkup(
+ pht(
+ '(IMPORTANT) If you attach this file to this object, any user who '.
+ 'has permission to view the object will be able to view and '.
+ 'download the file!'));
+
+ $dialog->appendParagraph(
+ pht(
+ 'Really attach the file %s to the object %s, allowing any user '.
+ 'who can view the object to view and download the file?',
+ $file_link,
+ $object_link));
+
+ $dialog->addSubmitButton(pht('Grant Permission'));
+
+ return $dialog;
+ }
+
+ if (!($object instanceof PhabricatorApplicationTransactionInterface)) {
+ $dialog->appendParagraph(
+ pht(
+ 'This object (of class "%s") does not implement the required '.
+ 'interface ("%s"), so files can not be manually attached to it.',
+ get_class($object),
+ 'PhabricatorApplicationTransactionInterface'));
+
+ return $dialog;
+ }
+
+ $editor = $object->getApplicationTransactionEditor()
+ ->setActor($viewer)
+ ->setContentSourceFromRequest($request)
+ ->setContinueOnNoEffect(true)
+ ->setContinueOnMissingFields(true);
+
+ $template = $object->getApplicationTransactionTemplate();
+
+ $xactions = array();
+
+ $xactions[] = id(clone $template)
+ ->setTransactionType(PhabricatorTransactions::TYPE_FILE)
+ ->setNewValue(
+ array(
+ $file_phid => PhabricatorFileAttachment::MODE_ATTACH,
+ ));
+
+ $editor->applyTransactions($object, $xactions);
+
+ return $this->newRedirect()
+ ->setURI($cancel_uri);
+ }
+
+}
diff --git a/src/applications/files/controller/PhabricatorFileUICurtainListController.php b/src/applications/files/controller/PhabricatorFileUICurtainListController.php
--- a/src/applications/files/controller/PhabricatorFileUICurtainListController.php
+++ b/src/applications/files/controller/PhabricatorFileUICurtainListController.php
@@ -53,7 +53,7 @@
return $this->newDialog()
->setViewer($viewer)
->setWidth(AphrontDialogView::WIDTH_FORM)
- ->setTitle(pht('Attached Files'))
+ ->setTitle(pht('Referenced Files'))
->setObjectList($list)
->addCancelButton($object_handle->getURI(), pht('Close'));
}
diff --git a/src/applications/files/engineextension/PhabricatorFilesCurtainExtension.php b/src/applications/files/engineextension/PhabricatorFilesCurtainExtension.php
--- a/src/applications/files/engineextension/PhabricatorFilesCurtainExtension.php
+++ b/src/applications/files/engineextension/PhabricatorFilesCurtainExtension.php
@@ -34,15 +34,16 @@
$handles = $viewer->loadHandles($visible_phids);
- PhabricatorPolicyFilterSet::loadHandleViewCapabilities(
- $viewer,
- $handles,
- array($object));
-
$ref_list = id(new PHUICurtainObjectRefListView())
->setViewer($viewer)
->setEmptyMessage(pht('None'));
+ $view_capability = PhabricatorPolicyCapability::CAN_VIEW;
+ $object_policies = PhabricatorPolicyQuery::loadPolicies(
+ $viewer,
+ $object);
+ $object_policy = idx($object_policies, $view_capability);
+
foreach ($visible_attachments as $attachment) {
$file_phid = $attachment->getFilePHID();
$handle = $handles[$file_phid];
@@ -50,9 +51,38 @@
$ref = $ref_list->newObjectRefView()
->setHandle($handle);
- if ($handle->hasCapabilities()) {
- if (!$handle->hasViewCapability($object)) {
- $ref->setExiled(true);
+ $file = $attachment->getFile();
+ if (!$file) {
+ // ...
+ } else {
+ if (!$attachment->isPolicyAttachment()) {
+ $file_policies = PhabricatorPolicyQuery::loadPolicies(
+ $viewer,
+ $file);
+ $file_policy = idx($file_policies, $view_capability);
+
+ if ($object_policy->isStrongerThanOrEqualTo($file_policy)) {
+ // The file is not attached to the object, but the file policy
+ // allows anyone who can see the object to see the file too, so
+ // there is no material problem with the file not being attached.
+ } else {
+ $attach_uri = urisprintf(
+ '/file/ui/curtain/attach/%s/%s/',
+ $object->getPHID(),
+ $file->getPHID());
+
+ $attached_link = javelin_tag(
+ 'a',
+ array(
+ 'href' => $attach_uri,
+ 'sigil' => 'workflow',
+ ),
+ pht('File Not Attached'));
+
+ $ref->setExiled(
+ true,
+ $attached_link);
+ }
}
}
@@ -63,7 +93,7 @@
$show_all = (count($visible_attachments) < count($attachments));
if ($show_all) {
$view_all_uri = urisprintf(
- '/file/ui/curtainlist/%s/',
+ '/file/ui/curtain/list/%s/',
$object->getPHID());
$loaded_count = count($attachments);
@@ -80,7 +110,7 @@
}
return $this->newPanel()
- ->setHeaderText(pht('Attached Files'))
+ ->setHeaderText(pht('Referenced Files'))
->setOrder(15000)
->appendChild($ref_list);
}
diff --git a/src/applications/files/phid/PhabricatorFileFilePHIDType.php b/src/applications/files/phid/PhabricatorFileFilePHIDType.php
--- a/src/applications/files/phid/PhabricatorFileFilePHIDType.php
+++ b/src/applications/files/phid/PhabricatorFileFilePHIDType.php
@@ -39,6 +39,9 @@
$handle->setName("F{$id}");
$handle->setFullName("F{$id}: {$name}");
$handle->setURI($uri);
+
+ $icon = FileTypeIcon::getFileIcon($name);
+ $handle->setIcon($icon);
}
}
diff --git a/src/applications/files/query/PhabricatorFileAttachmentQuery.php b/src/applications/files/query/PhabricatorFileAttachmentQuery.php
--- a/src/applications/files/query/PhabricatorFileAttachmentQuery.php
+++ b/src/applications/files/query/PhabricatorFileAttachmentQuery.php
@@ -4,13 +4,25 @@
extends PhabricatorCursorPagedPolicyAwareQuery {
private $objectPHIDs;
+ private $filePHIDs;
private $needFiles;
+ private $visibleFiles;
public function withObjectPHIDs(array $object_phids) {
$this->objectPHIDs = $object_phids;
return $this;
}
+ public function withFilePHIDs(array $file_phids) {
+ $this->filePHIDs = $file_phids;
+ return $this;
+ }
+
+ public function withVisibleFiles($visible_files) {
+ $this->visibleFiles = $visible_files;
+ return $this;
+ }
+
public function needFiles($need) {
$this->needFiles = $need;
return $this;
@@ -34,6 +46,13 @@
$this->objectPHIDs);
}
+ if ($this->filePHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'attachments.filePHID IN (%Ls)',
+ $this->filePHIDs);
+ }
+
return $where;
}
@@ -92,6 +111,12 @@
$file_phid = $attachment->getFilePHID();
$file = idx($files, $file_phid);
+ if ($this->visibleFiles && !$file) {
+ $this->didRejectResult($attachment);
+ unset($attachments[$key]);
+ continue;
+ }
+
$attachment->attachFile($file);
}
}
diff --git a/src/applications/files/storage/PhabricatorFileAttachment.php b/src/applications/files/storage/PhabricatorFileAttachment.php
--- a/src/applications/files/storage/PhabricatorFileAttachment.php
+++ b/src/applications/files/storage/PhabricatorFileAttachment.php
@@ -46,6 +46,15 @@
);
}
+ public function isPolicyAttachment() {
+ switch ($this->getAttachmentMode()) {
+ case self::MODE_ATTACH:
+ return true;
+ default:
+ return false;
+ }
+ }
+
public function attachObject($object) {
$this->object = $object;
return $this;
diff --git a/src/applications/policy/storage/PhabricatorPolicy.php b/src/applications/policy/storage/PhabricatorPolicy.php
--- a/src/applications/policy/storage/PhabricatorPolicy.php
+++ b/src/applications/policy/storage/PhabricatorPolicy.php
@@ -417,12 +417,23 @@
PhabricatorPolicies::POLICY_NOONE => 1,
);
- $this_strength = idx($strengths, $this->getPHID(), 0);
- $other_strength = idx($strengths, $other->getPHID(), 0);
+ $this_strength = idx($strengths, $this_policy, 0);
+ $other_strength = idx($strengths, $other_policy, 0);
return ($this_strength > $other_strength);
}
+ public function isStrongerThanOrEqualTo(PhabricatorPolicy $other) {
+ $this_policy = $this->getPHID();
+ $other_policy = $other->getPHID();
+
+ if ($this_policy === $other_policy) {
+ return true;
+ }
+
+ return $this->isStrongerThan($other);
+ }
+
public function isValidPolicyForEdit() {
return $this->getType() !== PhabricatorPolicyType::TYPE_MASKED;
}
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -2321,6 +2321,7 @@
$xaction = $object->getApplicationTransactionTemplate()
->setTransactionType(PhabricatorTransactions::TYPE_FILE)
+ ->setMetadataValue('attach.implicit', true)
->setNewValue($new_map);
return $xaction;
diff --git a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
--- a/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
+++ b/src/applications/transactions/storage/PhabricatorApplicationTransaction.php
@@ -341,6 +341,9 @@
$phids[] = $old;
$phids[] = $new;
break;
+ case PhabricatorTransactions::TYPE_FILE:
+ $phids[] = array_keys($old + $new);
+ break;
case PhabricatorTransactions::TYPE_EDGE:
$record = PhabricatorEdgeChangeRecord::newFromTransaction($this);
$phids[] = $record->getChangedPHIDs();
@@ -592,7 +595,9 @@
// Always hide file attach/detach transactions.
if ($xaction_type === PhabricatorTransactions::TYPE_FILE) {
- return true;
+ if ($this->getMetadataValue('attach.implicit')) {
+ return true;
+ }
}
// Hide creation transactions if the old value is empty. These are
@@ -1041,6 +1046,124 @@
'%s updated subscribers...',
$this->renderHandleLink($author_phid));
}
+ break;
+ case PhabricatorTransactions::TYPE_FILE:
+ $add = array_diff_key($new, $old);
+ $add = array_keys($add);
+
+ $rem = array_diff_key($old, $new);
+ $rem = array_keys($rem);
+
+ $mod = array();
+ foreach ($old + $new as $key => $ignored) {
+ if (!isset($old[$key])) {
+ continue;
+ }
+
+ if (!isset($new[$key])) {
+ continue;
+ }
+
+ if ($old[$key] === $new[$key]) {
+ continue;
+ }
+
+ $mod[] = $key;
+ }
+
+ // Specialize the specific case of only modifying files and upgrading
+ // references to attachments. This is accessible via the UI and can
+ // be shown more clearly than the generic default transaction shows
+ // it.
+
+ $mode_reference = PhabricatorFileAttachment::MODE_REFERENCE;
+ $mode_attach = PhabricatorFileAttachment::MODE_ATTACH;
+
+ $is_refattach = false;
+ if ($mod && !$add && !$rem) {
+ $all_refattach = true;
+ foreach ($mod as $phid) {
+ if (idx($old, $phid) !== $mode_reference) {
+ $all_refattach = false;
+ break;
+ }
+ if (idx($new, $phid) !== $mode_attach) {
+ $all_refattach = false;
+ break;
+ }
+ }
+ $is_refattach = $all_refattach;
+ }
+
+ if ($is_refattach) {
+ return pht(
+ '%s attached %s referenced file(s): %s.',
+ $this->renderHandleLink($author_phid),
+ phutil_count($mod),
+ $this->renderHandleList($mod));
+ } else if ($add && $rem && $mod) {
+ return pht(
+ '%s updated %s attached file(s), added %s: %s; removed %s: %s; '.
+ 'modified %s: %s.',
+ $this->renderHandleLink($author_phid),
+ new PhutilNumber(count($add) + count($rem)),
+ phutil_count($add),
+ $this->renderHandleList($add),
+ phutil_count($rem),
+ $this->renderHandleList($rem),
+ phutil_count($mod),
+ $this->renderHandleList($mod));
+ } else if ($add && $rem) {
+ return pht(
+ '%s updated %s attached file(s), added %s: %s; removed %s: %s.',
+ $this->renderHandleLink($author_phid),
+ new PhutilNumber(count($add) + count($rem)),
+ phutil_count($add),
+ $this->renderHandleList($add),
+ phutil_count($rem),
+ $this->renderHandleList($rem));
+ } else if ($add && $mod) {
+ return pht(
+ '%s updated %s attached file(s), added %s: %s; modified %s: %s.',
+ $this->renderHandleLink($author_phid),
+ new PhutilNumber(count($add) + count($mod)),
+ phutil_count($add),
+ $this->renderHandleList($add),
+ phutil_count($mod),
+ $this->renderHandleList($mod));
+ } else if ($rem && $mod) {
+ return pht(
+ '%s updated %s attached file(s), removed %s: %s; modified %s: %s.',
+ $this->renderHandleLink($author_phid),
+ new PhutilNumber(count($rem) + count($mod)),
+ phutil_count($rem),
+ $this->renderHandleList($rem),
+ phutil_count($mod),
+ $this->renderHandleList($mod));
+ } else if ($add) {
+ return pht(
+ '%s attached %s file(s): %s.',
+ $this->renderHandleLink($author_phid),
+ phutil_count($add),
+ $this->renderHandleList($add));
+ } else if ($rem) {
+ return pht(
+ '%s removed %s attached file(s): %s.',
+ $this->renderHandleLink($author_phid),
+ phutil_count($rem),
+ $this->renderHandleList($rem));
+ } else if ($mod) {
+ return pht(
+ '%s modified %s attached file(s): %s.',
+ $this->renderHandleLink($author_phid),
+ phutil_count($mod),
+ $this->renderHandleList($mod));
+ } else {
+ return pht(
+ '%s attached files...',
+ $this->renderHandleLink($author_phid));
+ }
+
break;
case PhabricatorTransactions::TYPE_EDGE:
$record = PhabricatorEdgeChangeRecord::newFromTransaction($this);
@@ -1479,6 +1602,8 @@
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
+ case PhabricatorTransactions::TYPE_FILE:
+ return true;
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
$field = $this->getTransactionCustomField();
if ($field) {
@@ -1494,6 +1619,11 @@
}
public function renderChangeDetailsForMail(PhabricatorUser $viewer) {
+ switch ($this->getTransactionType()) {
+ case PhabricatorTransactions::TYPE_FILE:
+ return false;
+ }
+
$view = $this->renderChangeDetails($viewer);
if ($view instanceof PhabricatorApplicationTransactionTextDiffDetailView) {
return $view->renderForMail();
@@ -1503,6 +1633,8 @@
public function renderChangeDetails(PhabricatorUser $viewer) {
switch ($this->getTransactionType()) {
+ case PhabricatorTransactions::TYPE_FILE:
+ return $this->newFileTransactionChangeDetails($viewer);
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
$field = $this->getTransactionCustomField();
if ($field) {
@@ -1769,6 +1901,66 @@
->addInt(-$this->getActionStrength());
}
+ private function newFileTransactionChangeDetails(PhabricatorUser $viewer) {
+ $old = $this->getOldValue();
+ $new = $this->getNewValue();
+
+ $phids = array_keys($old + $new);
+ $handles = $viewer->loadHandles($phids);
+
+ $names = array(
+ PhabricatorFileAttachment::MODE_REFERENCE => pht('Referenced'),
+ PhabricatorFileAttachment::MODE_ATTACH => pht('Attached'),
+ );
+
+ $rows = array();
+ foreach ($old + $new as $phid => $ignored) {
+ $handle = $handles[$phid];
+
+ $old_mode = idx($old, $phid);
+ $new_mode = idx($new, $phid);
+
+ if ($old_mode === null) {
+ $old_name = pht('None');
+ } else if (isset($names[$old_mode])) {
+ $old_name = $names[$old_mode];
+ } else {
+ $old_name = pht('Unknown ("%s")', $old_mode);
+ }
+
+ if ($new_mode === null) {
+ $new_name = pht('Detached');
+ } else if (isset($names[$new_mode])) {
+ $new_name = $names[$new_mode];
+ } else {
+ $new_name = pht('Unknown ("%s")', $new_mode);
+ }
+
+ $rows[] = array(
+ $handle->renderLink(),
+ $old_name,
+ $new_name,
+ );
+ }
+
+ $table = id(new AphrontTableView($rows))
+ ->setHeaders(
+ array(
+ pht('File'),
+ pht('Old Mode'),
+ pht('New Mode'),
+ ))
+ ->setColumnClasses(
+ array(
+ 'pri',
+ ));
+
+ return id(new PHUIBoxView())
+ ->addMargin(PHUI::MARGIN_SMALL)
+ ->appendChild($table);
+ }
+
+
/* -( PhabricatorPolicyInterface Implementation )-------------------------- */
@@ -1836,5 +2028,4 @@
$this->saveTransaction();
}
-
}
diff --git a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
--- a/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
+++ b/src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
@@ -1789,6 +1789,20 @@
'Executed %s tasks.',
),
+ '%s modified %s attached file(s): %s.' => array(
+ array(
+ '%s modified an attached file: %3$s.',
+ '%s modified attached files: %3$s.',
+ ),
+ ),
+
+ '%s attached %s referenced file(s): %s.' => array(
+ array(
+ '%s attached a referenced file: %3$s.',
+ '%s attached referenced files: %3$s.',
+ ),
+ ),
+
);
}
diff --git a/src/view/phui/PHUICurtainObjectRefView.php b/src/view/phui/PHUICurtainObjectRefView.php
--- a/src/view/phui/PHUICurtainObjectRefView.php
+++ b/src/view/phui/PHUICurtainObjectRefView.php
@@ -7,6 +7,7 @@
private $epoch;
private $highlighted;
private $exiled;
+ private $exileNote = false;
public function setHandle(PhabricatorObjectHandle $handle) {
$this->handle = $handle;
@@ -23,8 +24,9 @@
return $this;
}
- public function setExiled($is_exiled) {
+ public function setExiled($is_exiled, $note = false) {
$this->exiled = $is_exiled;
+ $this->exileNote = $note;
return $this;
}
@@ -72,10 +74,16 @@
}
if ($this->exiled) {
+ if ($this->exileNote !== false) {
+ $exile_note = $this->exileNote;
+ } else {
+ $exile_note = pht('No View Permission');
+ }
+
$exiled_view = array(
id(new PHUIIconView())->setIcon('fa-eye-slash red'),
' ',
- pht('No View Permission'),
+ $exile_note,
);
$exiled_cells = array();
diff --git a/webroot/rsrc/css/phui/phui-curtain-object-ref-view.css b/webroot/rsrc/css/phui/phui-curtain-object-ref-view.css
--- a/webroot/rsrc/css/phui/phui-curtain-object-ref-view.css
+++ b/webroot/rsrc/css/phui/phui-curtain-object-ref-view.css
@@ -92,6 +92,7 @@
opacity: 0.75;
}
-.phui-curtain-object-ref-view-exiled-cell {
+.phui-curtain-object-ref-view-exiled-cell,
+.phui-curtain-object-ref-view-exiled-cell a {
color: {$red};
}

File Metadata

Mime Type
text/plain
Expires
Sat, Jun 1, 1:43 AM (2 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6284977
Default Alt Text
D21837.id.diff (26 KB)

Event Timeline