@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
at upstream/main 209 lines 5.2 kB view raw
1<?php 2 3/** 4 * @extends PhabricatorCursorPagedPolicyAwareQuery<PhabricatorFileAttachment> 5 */ 6final class PhabricatorFileAttachmentQuery 7 extends PhabricatorCursorPagedPolicyAwareQuery { 8 9 private $objectPHIDs; 10 private $objectPHIDPrefix; 11 private $filePHIDs; 12 private $needFiles; 13 private $visibleFiles; 14 private $attachmentModes; 15 16 /** 17 * Filter with these object PHIDs. 18 * 19 * @param array<string> $object_phids Example: array('PHID-USER-123abc') 20 * @return $this 21 */ 22 public function withObjectPHIDs(array $object_phids) { 23 $this->objectPHIDs = $object_phids; 24 return $this; 25 } 26 27 /** 28 * Filter with a PHID object type. 29 * 30 * This is just syntax sugar for the method withObjectPHIDPrefix(), 31 * so you can pass constants like PhabricatorPeopleUserPHIDType::TYPECONST. 32 * 33 * @param string $phid_type PHID type constant. Example: 'USER'. 34 * @return $this 35 */ 36 public function withObjectPHIDType(string $phid_type) { 37 return $this->withObjectPHIDPrefix("PHID-{$phid_type}-"); 38 } 39 40 /** 41 * Filter with a object PHID prefix string. 42 * 43 * @param string $phid_prefix PHID prefix. Example: 'PHID-USER-' 44 * @return $this 45 */ 46 public function withObjectPHIDPrefix(string $phid_prefix) { 47 $this->objectPHIDPrefix = $phid_prefix; 48 return $this; 49 } 50 51 /** 52 * @param array<string> $file_phids Array of file PHIDs. 53 * @return $this 54 */ 55 public function withFilePHIDs(array $file_phids) { 56 $this->filePHIDs = $file_phids; 57 return $this; 58 } 59 60 /** 61 * If the files must be visible by the current viewer. 62 * 63 * @param bool $visible_files 64 * @return $this 65 */ 66 public function withVisibleFiles($visible_files) { 67 $this->visibleFiles = $visible_files; 68 return $this; 69 } 70 71 /** 72 * Filter with some attachment modes. 73 * 74 * @param array<string> $attachment_modes Array of attachment modes defined 75 * in the in the PhabricatorFileAttachment class. 76 * Example: 'array('attach','reference')'. 77 * @return $this 78 */ 79 public function withAttachmentModes(array $attachment_modes) { 80 $this->attachmentModes = $attachment_modes; 81 return $this; 82 } 83 84 /** 85 * If you also need the file objects. 86 * 87 * @param bool $need True if you also need the file objects. 88 * @return $this 89 */ 90 public function needFiles($need) { 91 $this->needFiles = $need; 92 return $this; 93 } 94 95 public function newResultObject() { 96 return new PhabricatorFileAttachment(); 97 } 98 99 protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 100 $where = parent::buildWhereClauseParts($conn); 101 102 if ($this->objectPHIDs !== null) { 103 $where[] = qsprintf( 104 $conn, 105 'attachments.objectPHID IN (%Ls)', 106 $this->objectPHIDs); 107 } 108 109 if ($this->objectPHIDPrefix !== null) { 110 $where[] = qsprintf( 111 $conn, 112 'attachments.objectPHID LIKE %>', 113 $this->objectPHIDPrefix); 114 } 115 116 if ($this->filePHIDs !== null) { 117 $where[] = qsprintf( 118 $conn, 119 'attachments.filePHID IN (%Ls)', 120 $this->filePHIDs); 121 } 122 123 if ($this->attachmentModes !== null) { 124 $where[] = qsprintf( 125 $conn, 126 'attachments.attachmentMode IN (%Ls)', 127 $this->attachmentModes); 128 } 129 130 return $where; 131 } 132 133 protected function willFilterPage(array $attachments) { 134 $viewer = $this->getViewer(); 135 $object_phids = array(); 136 137 foreach ($attachments as $attachment) { 138 $object_phid = $attachment->getObjectPHID(); 139 $object_phids[$object_phid] = $object_phid; 140 } 141 142 if ($object_phids) { 143 $objects = id(new PhabricatorObjectQuery()) 144 ->setViewer($viewer) 145 ->setParentQuery($this) 146 ->withPHIDs($object_phids) 147 ->execute(); 148 $objects = mpull($objects, null, 'getPHID'); 149 } else { 150 $objects = array(); 151 } 152 153 foreach ($attachments as $key => $attachment) { 154 $object_phid = $attachment->getObjectPHID(); 155 $object = idx($objects, $object_phid); 156 157 if (!$object) { 158 $this->didRejectResult($attachment); 159 unset($attachments[$key]); 160 continue; 161 } 162 163 $attachment->attachObject($object); 164 } 165 166 if ($this->needFiles) { 167 $file_phids = array(); 168 foreach ($attachments as $attachment) { 169 $file_phid = $attachment->getFilePHID(); 170 $file_phids[$file_phid] = $file_phid; 171 } 172 173 if ($file_phids) { 174 $files = id(new PhabricatorFileQuery()) 175 ->setViewer($viewer) 176 ->setParentQuery($this) 177 ->withPHIDs($file_phids) 178 ->execute(); 179 $files = mpull($files, null, 'getPHID'); 180 } else { 181 $files = array(); 182 } 183 184 foreach ($attachments as $key => $attachment) { 185 $file_phid = $attachment->getFilePHID(); 186 $file = idx($files, $file_phid); 187 188 if ($this->visibleFiles && !$file) { 189 $this->didRejectResult($attachment); 190 unset($attachments[$key]); 191 continue; 192 } 193 194 $attachment->attachFile($file); 195 } 196 } 197 198 return $attachments; 199 } 200 201 protected function getPrimaryTableAlias() { 202 return 'attachments'; 203 } 204 205 public function getQueryApplicationClass() { 206 return PhabricatorFilesApplication::class; 207 } 208 209}