@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
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}