Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15391507
D21835.id52040.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
D21835.id52040.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
@@ -3453,6 +3453,7 @@
'PhabricatorFileAES256StorageFormat' => 'applications/files/format/PhabricatorFileAES256StorageFormat.php',
'PhabricatorFileAltTextTransaction' => 'applications/files/xaction/PhabricatorFileAltTextTransaction.php',
'PhabricatorFileAttachment' => 'applications/files/storage/PhabricatorFileAttachment.php',
+ 'PhabricatorFileAttachmentQuery' => 'applications/files/query/PhabricatorFileAttachmentQuery.php',
'PhabricatorFileBundleLoader' => 'applications/files/query/PhabricatorFileBundleLoader.php',
'PhabricatorFileChunk' => 'applications/files/storage/PhabricatorFileChunk.php',
'PhabricatorFileChunkIterator' => 'applications/files/engine/PhabricatorFileChunkIterator.php',
@@ -9892,7 +9893,12 @@
),
'PhabricatorFileAES256StorageFormat' => 'PhabricatorFileStorageFormat',
'PhabricatorFileAltTextTransaction' => 'PhabricatorFileTransactionType',
- 'PhabricatorFileAttachment' => 'PhabricatorFileDAO',
+ 'PhabricatorFileAttachment' => array(
+ 'PhabricatorFileDAO',
+ 'PhabricatorPolicyInterface',
+ 'PhabricatorExtendedPolicyInterface',
+ ),
+ 'PhabricatorFileAttachmentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorFileBundleLoader' => 'Phobject',
'PhabricatorFileChunk' => array(
'PhabricatorFileDAO',
diff --git a/src/applications/files/query/PhabricatorFileAttachmentQuery.php b/src/applications/files/query/PhabricatorFileAttachmentQuery.php
new file mode 100644
--- /dev/null
+++ b/src/applications/files/query/PhabricatorFileAttachmentQuery.php
@@ -0,0 +1,110 @@
+<?php
+
+final class PhabricatorFileAttachmentQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $objectPHIDs;
+ private $needFiles;
+
+ public function withObjectPHIDs(array $object_phids) {
+ $this->objectPHIDs = $object_phids;
+ return $this;
+ }
+
+ public function needFiles($need) {
+ $this->needFiles = $need;
+ return $this;
+ }
+
+ public function newResultObject() {
+ return new PhabricatorFileAttachment();
+ }
+
+ protected function loadPage() {
+ return $this->loadStandardPage($this->newResultObject());
+ }
+
+ protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) {
+ $where = parent::buildWhereClauseParts($conn);
+
+ if ($this->objectPHIDs !== null) {
+ $where[] = qsprintf(
+ $conn,
+ 'attachments.objectPHID IN (%Ls)',
+ $this->objectPHIDs);
+ }
+
+ return $where;
+ }
+
+ protected function willFilterPage(array $attachments) {
+ $viewer = $this->getViewer();
+ $object_phids = array();
+
+ foreach ($attachments as $attachment) {
+ $object_phid = $attachment->getObjectPHID();
+ $object_phids[$object_phid] = $object_phid;
+ }
+
+ if ($object_phids) {
+ $objects = id(new PhabricatorObjectQuery())
+ ->setViewer($viewer)
+ ->setParentQuery($this)
+ ->withPHIDs($object_phids)
+ ->execute();
+ $objects = mpull($objects, null, 'getPHID');
+ } else {
+ $objects = array();
+ }
+
+ foreach ($attachments as $key => $attachment) {
+ $object_phid = $attachment->getObjectPHID();
+ $object = idx($objects, $object_phid);
+
+ if (!$object) {
+ $this->didRejectResult($attachment);
+ unset($attachments[$key]);
+ continue;
+ }
+
+ $attachment->attachObject($object);
+ }
+
+ if ($this->needFiles) {
+ $file_phids = array();
+ foreach ($attachments as $attachment) {
+ $file_phid = $attachment->getFilePHID();
+ $file_phids[$file_phid] = $file_phid;
+ }
+
+ if ($file_phids) {
+ $files = id(new PhabricatorFileQuery())
+ ->setViewer($viewer)
+ ->setParentQuery($this)
+ ->withPHIDs($file_phids)
+ ->execute();
+ $files = mpull($files, null, 'getPHID');
+ } else {
+ $files = array();
+ }
+
+ foreach ($attachments as $key => $attachment) {
+ $file_phid = $attachment->getFilePHID();
+ $file = idx($files, $file_phid);
+
+ $attachment->attachFile($file);
+ }
+ }
+
+ return $attachments;
+ }
+
+ protected function getPrimaryTableAlias() {
+ return 'attachments';
+ }
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorFilesApplication';
+ }
+
+}
diff --git a/src/applications/files/query/PhabricatorFileQuery.php b/src/applications/files/query/PhabricatorFileQuery.php
--- a/src/applications/files/query/PhabricatorFileQuery.php
+++ b/src/applications/files/query/PhabricatorFileQuery.php
@@ -309,9 +309,13 @@
$attachments = queryfx_all(
$attachments_conn,
- 'SELECT filePHID, objectPHID FROM %R WHERE filePHID IN (%Ls)',
+ 'SELECT filePHID, objectPHID FROM %R WHERE filePHID IN (%Ls)
+ AND attachmentMode IN (%Ls)',
$attachments_table,
- $file_phids);
+ $file_phids,
+ array(
+ PhabricatorFileAttachment::MODE_ATTACH,
+ ));
$attachments_map = array_fill_keys($file_phids, array());
foreach ($attachments as $row) {
@@ -374,8 +378,12 @@
if ($this->shouldJoinAttachmentsTable()) {
$joins[] = qsprintf(
$conn,
- 'JOIN %R attachments ON attachments.filePHID = f.phid',
- new PhabricatorFileAttachment());
+ 'JOIN %R attachments ON attachments.filePHID = f.phid
+ AND attachmentMode IN (%Ls)',
+ new PhabricatorFileAttachment(),
+ array(
+ PhabricatorFileAttachment::MODE_ATTACH,
+ ));
}
return $joins;
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
@@ -1,13 +1,19 @@
<?php
final class PhabricatorFileAttachment
- extends PhabricatorFileDAO {
+ extends PhabricatorFileDAO
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorExtendedPolicyInterface {
protected $objectPHID;
protected $filePHID;
protected $attacherPHID;
protected $attachmentMode;
+ private $object = self::ATTACHABLE;
+ private $file = self::ATTACHABLE;
+
const MODE_ATTACH = 'attach';
const MODE_REFERENCE = 'reference';
const MODE_DETACH = 'detach';
@@ -40,4 +46,53 @@
);
}
+ public function attachObject($object) {
+ $this->object = $object;
+ return $this;
+ }
+
+ public function getObject() {
+ return $this->assertAttached($this->object);
+ }
+
+ public function attachFile(PhabricatorFile $file = null) {
+ $this->file = $file;
+ return $this;
+ }
+
+ public function getFile() {
+ return $this->assertAttached($this->file);
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ );
+ }
+
+ public function getPolicy($capability) {
+ switch ($capability) {
+ case PhabricatorPolicyCapability::CAN_VIEW:
+ return PhabricatorPolicies::getMostOpenPolicy();
+ }
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return false;
+ }
+
+
+/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
+
+
+ public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
+ return array(
+ array($this->getObject(), $capability),
+ );
+ }
+
}
diff --git a/src/applications/files/storage/__tests__/PhabricatorFileTestCase.php b/src/applications/files/storage/__tests__/PhabricatorFileTestCase.php
--- a/src/applications/files/storage/__tests__/PhabricatorFileTestCase.php
+++ b/src/applications/files/storage/__tests__/PhabricatorFileTestCase.php
@@ -100,7 +100,14 @@
$xactions[] = id(new ManiphestTransaction())
->setTransactionType(
ManiphestTaskDescriptionTransaction::TRANSACTIONTYPE)
- ->setNewValue('{'.$file->getMonogram().'}');
+ ->setNewValue('{'.$file->getMonogram().'}')
+ ->setMetadataValue(
+ 'remarkup.control',
+ array(
+ 'attachedFilePHIDs' => array(
+ $file->getPHID(),
+ ),
+ ));
id(new ManiphestTransactionEditor())
->setActor($author)
@@ -167,9 +174,10 @@
// Create an object and test object policies.
- $object = ManiphestTask::initializeNewTask($author);
- $object->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy());
- $object->save();
+ $object = ManiphestTask::initializeNewTask($author)
+ ->setTitle(pht('File Visibility Test Task'))
+ ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
+ ->save();
$this->assertTrue(
$filter->hasCapability(
@@ -185,10 +193,53 @@
PhabricatorPolicyCapability::CAN_VIEW),
pht('Object Visible to Others'));
+ // Reference the file in a comment. This should not affect the file
+ // policy.
+
+ $file_ref = '{F'.$file->getID().'}';
+
+ $xactions = array();
+ $xactions[] = id(new ManiphestTransaction())
+ ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
+ ->attachComment(
+ id(new ManiphestTransactionComment())
+ ->setContent($file_ref));
+
+ id(new ManiphestTransactionEditor())
+ ->setActor($author)
+ ->setContentSource($this->newContentSource())
+ ->applyTransactions($object, $xactions);
+
+ // Test the referenced file's visibility.
+ $this->assertEqual(
+ array(
+ true,
+ false,
+ ),
+ $this->canViewFile($users, $file),
+ pht('Referenced File Visibility'));
+
// Attach the file to the object and test that the association opens a
// policy exception for the non-author viewer.
- $file->attachToObject($object->getPHID());
+ $xactions = array();
+ $xactions[] = id(new ManiphestTransaction())
+ ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
+ ->setMetadataValue(
+ 'remarkup.control',
+ array(
+ 'attachedFilePHIDs' => array(
+ $file->getPHID(),
+ ),
+ ))
+ ->attachComment(
+ id(new ManiphestTransactionComment())
+ ->setContent($file_ref));
+
+ id(new ManiphestTransactionEditor())
+ ->setActor($author)
+ ->setContentSource($this->newContentSource())
+ ->applyTransactions($object, $xactions);
// Test the attached file's visibility.
$this->assertEqual(
diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php
--- a/src/applications/transactions/editengine/PhabricatorEditEngine.php
+++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php
@@ -2080,26 +2080,6 @@
}
}
- public static function newTransactionsFromRemarkupMetadata(
- PhabricatorApplicationTransaction $template,
- array $metadata) {
-
- $xactions = array();
-
- $attached_phids = idx($metadata, 'attachedFilePHIDs');
- if (is_array($attached_phids) && $attached_phids) {
- $attachment_map = array_fill_keys(
- $attached_phids,
- PhabricatorFileAttachment::MODE_ATTACH);
-
- $xactions[] = id(clone $template)
- ->setTransactionType(PhabricatorTransactions::TYPE_FILE)
- ->setNewValue($attachment_map);
- }
-
- return $xactions;
- }
-
protected function newDraftEngine($object) {
$viewer = $this->getViewer();
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
@@ -2266,7 +2266,14 @@
$viewer = $this->getActor();
$old_blocks = mpull($remarkup_changes, 'getOldValue');
+ foreach ($old_blocks as $key => $old_block) {
+ $old_blocks[$key] = phutil_string_cast($old_block);
+ }
+
$new_blocks = mpull($remarkup_changes, 'getNewValue');
+ foreach ($new_blocks as $key => $new_block) {
+ $new_blocks[$key] = phutil_string_cast($new_block);
+ }
$old_refs = PhabricatorMarkupEngine::extractFilePHIDsFromEmbeddedFiles(
$viewer,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 16, 10:17 AM (5 d, 2 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7528474
Default Alt Text
D21835.id52040.diff (12 KB)
Attached To
Mode
D21835: Give "FileAttachment" policy support and a query object
Attached
Detach File
Event Timeline
Log In to Comment