@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
3final class EdgeSearchConduitAPIMethod
4 extends ConduitAPIMethod {
5
6 public function getAPIMethodName() {
7 return 'edge.search';
8 }
9
10 public function getMethodDescription() {
11 return pht('Read edge relationships between objects.');
12 }
13
14 protected function newDocumentationPages(PhabricatorUser $viewer) {
15 $rows = array();
16 foreach ($this->getConduitEdgeTypeMap() as $key => $type) {
17 $inverse_constant = $type->getInverseEdgeConstant();
18 if ($inverse_constant) {
19 $inverse_type = PhabricatorEdgeType::getByConstant($inverse_constant);
20 $inverse = $inverse_type->getConduitKey();
21 } else {
22 $inverse = null;
23 }
24
25 $rows[] = array(
26 $key,
27 $type->getConduitName(),
28 $inverse,
29 new PHUIRemarkupView($viewer, $type->getConduitDescription()),
30 );
31 }
32
33 $types_table = id(new AphrontTableView($rows))
34 ->setHeaders(
35 array(
36 pht('Constant'),
37 pht('Name'),
38 pht('Inverse'),
39 pht('Description'),
40 ))
41 ->setColumnClasses(
42 array(
43 'mono',
44 'pri',
45 'mono',
46 'wide',
47 ));
48
49
50 return array(
51 $this->newDocumentationBoxPage($viewer, pht('Edge Types'), $types_table)
52 ->setAnchor('types'),
53 );
54 }
55
56 protected function defineParamTypes() {
57 return array(
58 'sourcePHIDs' => 'list<phid>',
59 'types' => 'list<const>',
60 'destinationPHIDs' => 'optional list<phid>',
61 ) + $this->getPagerParamTypes();
62 }
63
64 protected function defineReturnType() {
65 return 'list<dict>';
66 }
67
68 protected function defineErrorTypes() {
69 return array();
70 }
71
72 protected function execute(ConduitAPIRequest $request) {
73 $viewer = $request->getUser();
74 $pager = $this->newPager($request);
75
76 $source_phids = $request->getValue('sourcePHIDs', array());
77 $edge_types = $request->getValue('types', array());
78 $destination_phids = $request->getValue('destinationPHIDs', array());
79
80 $object_query = id(new PhabricatorObjectQuery())
81 ->setViewer($viewer)
82 ->withNames($source_phids);
83
84 $object_query->execute();
85 $objects = $object_query->getNamedResults();
86 foreach ($source_phids as $phid) {
87 if (empty($objects[$phid])) {
88 throw new Exception(
89 pht(
90 'Source PHID "%s" does not identify a valid object, or you do '.
91 'not have permission to view it.',
92 $phid));
93 }
94 }
95 $source_phids = mpull($objects, 'getPHID');
96
97 if (!$edge_types) {
98 throw new Exception(
99 pht(
100 'Edge search must specify a nonempty list of edge types.'));
101 }
102
103 $edge_map = $this->getConduitEdgeTypeMap();
104
105 $constant_map = array();
106 $edge_constants = array();
107 foreach ($edge_types as $edge_type) {
108 if (!isset($edge_map[$edge_type])) {
109 throw new Exception(
110 pht(
111 'Edge type "%s" is not a recognized edge type.',
112 $edge_type));
113 }
114
115 $constant = $edge_map[$edge_type]->getEdgeConstant();
116
117 $edge_constants[] = $constant;
118 $constant_map[$constant] = $edge_type;
119 }
120
121 $edge_query = id(new PhabricatorEdgeObjectQuery())
122 ->setViewer($viewer)
123 ->withSourcePHIDs($source_phids)
124 ->withEdgeTypes($edge_constants);
125
126 if ($destination_phids) {
127 $edge_query->withDestinationPHIDs($destination_phids);
128 }
129
130 $edge_objects = $edge_query->executeWithCursorPager($pager);
131
132 $edges = array();
133 foreach ($edge_objects as $edge_object) {
134 $edges[] = array(
135 'sourcePHID' => $edge_object->getSourcePHID(),
136 'edgeType' => $constant_map[$edge_object->getEdgeType()],
137 'destinationPHID' => $edge_object->getDestinationPHID(),
138 );
139 }
140
141 $results = array(
142 'data' => $edges,
143 );
144
145 return $this->addPagerResults($results, $pager);
146 }
147
148 private function getConduitEdgeTypeMap() {
149 $types = PhabricatorEdgeType::getAllTypes();
150
151 $map = array();
152 foreach ($types as $type) {
153 $key = $type->getConduitKey();
154 if ($key === null) {
155 continue;
156 }
157
158 $map[$key] = $type;
159 }
160
161 ksort($map);
162
163 return $map;
164 }
165}