Page MenuHomePhabricator

D21835.id52044.diff
No OneTemporary

D21835.id52044.diff

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

Mime Type
text/plain
Expires
Tue, May 21, 10:52 AM (3 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6284986
Default Alt Text
D21835.id52044.diff (12 KB)

Event Timeline