@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<PhabricatorObjectHandle>
5 */
6final class PhabricatorHandleQuery
7 extends PhabricatorCursorPagedPolicyAwareQuery {
8
9 private $objectCapabilities;
10 private $phids = array();
11
12 public function withPHIDs(array $phids) {
13 $this->phids = $phids;
14 return $this;
15 }
16
17 public function requireObjectCapabilities(array $capabilities) {
18 $this->objectCapabilities = $capabilities;
19 return $this;
20 }
21
22 protected function getRequiredObjectCapabilities() {
23 if ($this->objectCapabilities) {
24 return $this->objectCapabilities;
25 }
26 return $this->getRequiredCapabilities();
27 }
28
29 protected function loadPage() {
30 $types = PhabricatorPHIDType::getAllTypes();
31
32 $phids = array_unique($this->phids);
33 if (!$phids) {
34 return array();
35 }
36
37 $object_query = id(new PhabricatorObjectQuery())
38 ->withPHIDs($phids)
39 ->setParentQuery($this)
40 ->requireCapabilities($this->getRequiredObjectCapabilities())
41 ->setViewer($this->getViewer());
42
43 // We never want the subquery to raise policy exceptions, even if this
44 // query is being executed via executeOne(). Policy exceptions are not
45 // meaningful or relevant for handles, which load in an "Unknown" or
46 // "Restricted" state after encountering a policy violation.
47 $object_query->setRaisePolicyExceptions(false);
48
49 $objects = $object_query->execute();
50 $filtered = $object_query->getPolicyFilteredPHIDs();
51
52 $groups = array();
53 foreach ($phids as $phid) {
54 $type = phid_get_type($phid);
55 $groups[$type][] = $phid;
56 }
57
58 $results = array();
59 foreach ($groups as $type => $phid_group) {
60 $handles = array();
61 foreach ($phid_group as $key => $phid) {
62 if (isset($handles[$phid])) {
63 unset($phid_group[$key]);
64 // The input had a duplicate PHID; just skip it.
65 continue;
66 }
67 $handles[$phid] = id(new PhabricatorObjectHandle())
68 ->setType($type)
69 ->setPHID($phid);
70 if (isset($objects[$phid])) {
71 $handles[$phid]->setComplete(true);
72 } else if (isset($filtered[$phid])) {
73 $handles[$phid]->setPolicyFiltered(true);
74 }
75 }
76
77 if (isset($types[$type])) {
78 $type_objects = array_select_keys($objects, $phid_group);
79 if ($type_objects) {
80 $have_object_phids = array_keys($type_objects);
81 $types[$type]->loadHandles(
82 $this,
83 array_select_keys($handles, $have_object_phids),
84 $type_objects);
85 }
86 }
87
88 $results += $handles;
89 }
90
91 return $results;
92 }
93
94 public function getQueryApplicationClass() {
95 return null;
96 }
97
98}