@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 AlmanacBinding
4 extends AlmanacDAO
5 implements
6 PhabricatorPolicyInterface,
7 PhabricatorApplicationTransactionInterface,
8 AlmanacPropertyInterface,
9 PhabricatorDestructibleInterface,
10 PhabricatorExtendedPolicyInterface,
11 PhabricatorConduitResultInterface {
12
13 protected $servicePHID;
14 protected $devicePHID;
15 protected $interfacePHID;
16 protected $isDisabled;
17
18 private $service = self::ATTACHABLE;
19 private $device = self::ATTACHABLE;
20 private $interface = self::ATTACHABLE;
21 private $almanacProperties = self::ATTACHABLE;
22
23 public static function initializeNewBinding(AlmanacService $service) {
24 return id(new AlmanacBinding())
25 ->setServicePHID($service->getPHID())
26 ->attachService($service)
27 ->attachAlmanacProperties(array())
28 ->setIsDisabled(0);
29 }
30
31 protected function getConfiguration() {
32 return array(
33 self::CONFIG_AUX_PHID => true,
34 self::CONFIG_COLUMN_SCHEMA => array(
35 'isDisabled' => 'bool',
36 ),
37 self::CONFIG_KEY_SCHEMA => array(
38 'key_service' => array(
39 'columns' => array('servicePHID', 'interfacePHID'),
40 'unique' => true,
41 ),
42 'key_device' => array(
43 'columns' => array('devicePHID'),
44 ),
45 'key_interface' => array(
46 'columns' => array('interfacePHID'),
47 ),
48 ),
49 ) + parent::getConfiguration();
50 }
51
52 public function getPHIDType() {
53 return AlmanacBindingPHIDType::TYPECONST;
54 }
55
56 public function getName() {
57 return pht('Binding %s', $this->getID());
58 }
59
60 public function getURI() {
61 return urisprintf(
62 '/almanac/binding/%s/',
63 $this->getID());
64 }
65
66 public function getService() {
67 return $this->assertAttached($this->service);
68 }
69
70 public function attachService(AlmanacService $service) {
71 $this->service = $service;
72 return $this;
73 }
74
75 public function getDevice() {
76 return $this->assertAttached($this->device);
77 }
78
79 public function attachDevice(AlmanacDevice $device) {
80 $this->device = $device;
81 return $this;
82 }
83
84 public function hasInterface() {
85 return ($this->interface !== self::ATTACHABLE);
86 }
87
88 public function getInterface() {
89 return $this->assertAttached($this->interface);
90 }
91
92 public function attachInterface(AlmanacInterface $interface) {
93 $this->interface = $interface;
94 return $this;
95 }
96
97
98/* -( AlmanacPropertyInterface )------------------------------------------- */
99
100
101 /**
102 * @param array<AlmanacProperty> $properties
103 */
104 public function attachAlmanacProperties(array $properties) {
105 assert_instances_of($properties, AlmanacProperty::class);
106 $this->almanacProperties = mpull($properties, null, 'getFieldName');
107 return $this;
108 }
109
110 public function getAlmanacProperties() {
111 return $this->assertAttached($this->almanacProperties);
112 }
113
114 public function hasAlmanacProperty($key) {
115 $this->assertAttached($this->almanacProperties);
116 return isset($this->almanacProperties[$key]);
117 }
118
119 public function getAlmanacProperty($key) {
120 return $this->assertAttachedKey($this->almanacProperties, $key);
121 }
122
123 public function getAlmanacPropertyValue($key, $default = null) {
124 if ($this->hasAlmanacProperty($key)) {
125 return $this->getAlmanacProperty($key)->getFieldValue();
126 } else {
127 return $default;
128 }
129 }
130
131 public function getAlmanacPropertyFieldSpecifications() {
132 return $this->getService()->getBindingFieldSpecifications($this);
133 }
134
135 public function newAlmanacPropertyEditEngine() {
136 return new AlmanacBindingPropertyEditEngine();
137 }
138
139 public function getAlmanacPropertySetTransactionType() {
140 return AlmanacBindingSetPropertyTransaction::TRANSACTIONTYPE;
141 }
142
143 public function getAlmanacPropertyDeleteTransactionType() {
144 return AlmanacBindingDeletePropertyTransaction::TRANSACTIONTYPE;
145 }
146
147
148/* -( PhabricatorPolicyInterface )----------------------------------------- */
149
150
151 public function getCapabilities() {
152 return array(
153 PhabricatorPolicyCapability::CAN_VIEW,
154 PhabricatorPolicyCapability::CAN_EDIT,
155 );
156 }
157
158 public function getPolicy($capability) {
159 return $this->getService()->getPolicy($capability);
160 }
161
162 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
163 return $this->getService()->hasAutomaticCapability($capability, $viewer);
164 }
165
166 public function describeAutomaticCapability($capability) {
167 $notes = array(
168 pht('A binding inherits the policies of its service.'),
169 pht(
170 'To view a binding, you must also be able to view its device and '.
171 'interface.'),
172 );
173
174 return $notes;
175 }
176
177
178/* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
179
180
181 public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
182 switch ($capability) {
183 case PhabricatorPolicyCapability::CAN_EDIT:
184 if ($this->getService()->isClusterService()) {
185 return array(
186 array(
187 new PhabricatorAlmanacApplication(),
188 AlmanacManageClusterServicesCapability::CAPABILITY,
189 ),
190 );
191 }
192 break;
193 }
194
195 return array();
196 }
197
198/* -( PhabricatorApplicationTransactionInterface )------------------------- */
199
200
201 public function getApplicationTransactionEditor() {
202 return new AlmanacBindingEditor();
203 }
204
205 public function getApplicationTransactionTemplate() {
206 return new AlmanacBindingTransaction();
207 }
208
209
210/* -( PhabricatorDestructibleInterface )----------------------------------- */
211
212
213 public function destroyObjectPermanently(
214 PhabricatorDestructionEngine $engine) {
215
216 $this->delete();
217 }
218
219
220/* -( PhabricatorConduitResultInterface )---------------------------------- */
221
222
223 public function getFieldSpecificationsForConduit() {
224 return array(
225 id(new PhabricatorConduitSearchFieldSpecification())
226 ->setKey('servicePHID')
227 ->setType('phid')
228 ->setDescription(pht('The bound service.')),
229 id(new PhabricatorConduitSearchFieldSpecification())
230 ->setKey('devicePHID')
231 ->setType('phid')
232 ->setDescription(pht('The device the service is bound to.')),
233 id(new PhabricatorConduitSearchFieldSpecification())
234 ->setKey('interfacePHID')
235 ->setType('phid')
236 ->setDescription(pht('The interface the service is bound to.')),
237 id(new PhabricatorConduitSearchFieldSpecification())
238 ->setKey('disabled')
239 ->setType('bool')
240 ->setDescription(pht('Interface status.')),
241 );
242 }
243
244 public function getFieldValuesForConduit() {
245 return array(
246 'servicePHID' => $this->getServicePHID(),
247 'devicePHID' => $this->getDevicePHID(),
248 'interfacePHID' => $this->getInterfacePHID(),
249 'disabled' => (bool)$this->getIsDisabled(),
250 );
251 }
252
253 public function getConduitSearchAttachments() {
254 return array(
255 id(new AlmanacPropertiesSearchEngineAttachment())
256 ->setAttachmentKey('properties'),
257 );
258 }
259
260}