Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / almanac / storage / AlmanacService.php
blob58a3f681df9083086d9cfede88313004dc2b42a9
1 <?php
3 final class AlmanacService
4 extends AlmanacDAO
5 implements
6 PhabricatorPolicyInterface,
7 PhabricatorApplicationTransactionInterface,
8 PhabricatorProjectInterface,
9 AlmanacPropertyInterface,
10 PhabricatorDestructibleInterface,
11 PhabricatorNgramsInterface,
12 PhabricatorConduitResultInterface,
13 PhabricatorExtendedPolicyInterface {
15 protected $name;
16 protected $nameIndex;
17 protected $viewPolicy;
18 protected $editPolicy;
19 protected $serviceType;
21 private $almanacProperties = self::ATTACHABLE;
22 private $bindings = self::ATTACHABLE;
23 private $activeBindings = self::ATTACHABLE;
24 private $serviceImplementation = self::ATTACHABLE;
26 public static function initializeNewService($type) {
27 $type_map = AlmanacServiceType::getAllServiceTypes();
29 $implementation = idx($type_map, $type);
30 if (!$implementation) {
31 throw new Exception(
32 pht(
33 'No Almanac service type "%s" exists!',
34 $type));
37 return id(new AlmanacService())
38 ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
39 ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN)
40 ->attachAlmanacProperties(array())
41 ->setServiceType($type)
42 ->attachServiceImplementation($implementation);
45 protected function getConfiguration() {
46 return array(
47 self::CONFIG_AUX_PHID => true,
48 self::CONFIG_COLUMN_SCHEMA => array(
49 'name' => 'text128',
50 'nameIndex' => 'bytes12',
51 'serviceType' => 'text64',
53 self::CONFIG_KEY_SCHEMA => array(
54 'key_name' => array(
55 'columns' => array('nameIndex'),
56 'unique' => true,
58 'key_nametext' => array(
59 'columns' => array('name'),
61 'key_servicetype' => array(
62 'columns' => array('serviceType'),
65 ) + parent::getConfiguration();
68 public function getPHIDType() {
69 return AlmanacServicePHIDType::TYPECONST;
72 public function save() {
73 AlmanacNames::validateName($this->getName());
75 $this->nameIndex = PhabricatorHash::digestForIndex($this->getName());
77 return parent::save();
80 public function getURI() {
81 return '/almanac/service/view/'.$this->getName().'/';
84 public function getBindings() {
85 return $this->assertAttached($this->bindings);
88 public function getActiveBindings() {
89 return $this->assertAttached($this->activeBindings);
92 public function attachBindings(array $bindings) {
93 $active_bindings = array();
94 foreach ($bindings as $key => $binding) {
95 // Filter out disabled bindings.
96 if ($binding->getIsDisabled()) {
97 continue;
100 // Filter out bindings to disabled devices.
101 if ($binding->getDevice()->isDisabled()) {
102 continue;
105 $active_bindings[$key] = $binding;
108 $this->attachActiveBindings($active_bindings);
110 $this->bindings = $bindings;
111 return $this;
114 public function attachActiveBindings(array $bindings) {
115 $this->activeBindings = $bindings;
116 return $this;
119 public function getServiceImplementation() {
120 return $this->assertAttached($this->serviceImplementation);
123 public function attachServiceImplementation(AlmanacServiceType $type) {
124 $this->serviceImplementation = $type;
125 return $this;
128 public function isClusterService() {
129 return $this->getServiceImplementation()->isClusterServiceType();
133 /* -( AlmanacPropertyInterface )------------------------------------------- */
136 public function attachAlmanacProperties(array $properties) {
137 assert_instances_of($properties, 'AlmanacProperty');
138 $this->almanacProperties = mpull($properties, null, 'getFieldName');
139 return $this;
142 public function getAlmanacProperties() {
143 return $this->assertAttached($this->almanacProperties);
146 public function hasAlmanacProperty($key) {
147 $this->assertAttached($this->almanacProperties);
148 return isset($this->almanacProperties[$key]);
151 public function getAlmanacProperty($key) {
152 return $this->assertAttachedKey($this->almanacProperties, $key);
155 public function getAlmanacPropertyValue($key, $default = null) {
156 if ($this->hasAlmanacProperty($key)) {
157 return $this->getAlmanacProperty($key)->getFieldValue();
158 } else {
159 return $default;
163 public function getAlmanacPropertyFieldSpecifications() {
164 return $this->getServiceImplementation()->getFieldSpecifications();
167 public function getBindingFieldSpecifications(AlmanacBinding $binding) {
168 $impl = $this->getServiceImplementation();
169 return $impl->getBindingFieldSpecifications($binding);
172 public function newAlmanacPropertyEditEngine() {
173 return new AlmanacServicePropertyEditEngine();
176 public function getAlmanacPropertySetTransactionType() {
177 return AlmanacServiceSetPropertyTransaction::TRANSACTIONTYPE;
180 public function getAlmanacPropertyDeleteTransactionType() {
181 return AlmanacServiceDeletePropertyTransaction::TRANSACTIONTYPE;
185 /* -( PhabricatorPolicyInterface )----------------------------------------- */
188 public function getCapabilities() {
189 return array(
190 PhabricatorPolicyCapability::CAN_VIEW,
191 PhabricatorPolicyCapability::CAN_EDIT,
195 public function getPolicy($capability) {
196 switch ($capability) {
197 case PhabricatorPolicyCapability::CAN_VIEW:
198 return $this->getViewPolicy();
199 case PhabricatorPolicyCapability::CAN_EDIT:
200 return $this->getEditPolicy();
204 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
205 return false;
209 /* -( PhabricatorExtendedPolicyInterface )--------------------------------- */
212 public function getExtendedPolicy($capability, PhabricatorUser $viewer) {
213 switch ($capability) {
214 case PhabricatorPolicyCapability::CAN_EDIT:
215 if ($this->isClusterService()) {
216 return array(
217 array(
218 new PhabricatorAlmanacApplication(),
219 AlmanacManageClusterServicesCapability::CAPABILITY,
223 break;
226 return array();
230 /* -( PhabricatorApplicationTransactionInterface )------------------------- */
233 public function getApplicationTransactionEditor() {
234 return new AlmanacServiceEditor();
237 public function getApplicationTransactionTemplate() {
238 return new AlmanacServiceTransaction();
242 /* -( PhabricatorDestructibleInterface )----------------------------------- */
245 public function destroyObjectPermanently(
246 PhabricatorDestructionEngine $engine) {
248 $bindings = id(new AlmanacBindingQuery())
249 ->setViewer($engine->getViewer())
250 ->withServicePHIDs(array($this->getPHID()))
251 ->execute();
252 foreach ($bindings as $binding) {
253 $engine->destroyObject($binding);
256 $this->delete();
260 /* -( PhabricatorNgramsInterface )----------------------------------------- */
263 public function newNgrams() {
264 return array(
265 id(new AlmanacServiceNameNgrams())
266 ->setValue($this->getName()),
271 /* -( PhabricatorConduitResultInterface )---------------------------------- */
274 public function getFieldSpecificationsForConduit() {
275 return array(
276 id(new PhabricatorConduitSearchFieldSpecification())
277 ->setKey('name')
278 ->setType('string')
279 ->setDescription(pht('The name of the service.')),
280 id(new PhabricatorConduitSearchFieldSpecification())
281 ->setKey('serviceType')
282 ->setType('string')
283 ->setDescription(pht('The service type constant.')),
287 public function getFieldValuesForConduit() {
288 return array(
289 'name' => $this->getName(),
290 'serviceType' => $this->getServiceType(),
294 public function getConduitSearchAttachments() {
295 return array(
296 id(new AlmanacPropertiesSearchEngineAttachment())
297 ->setAttachmentKey('properties'),
298 id(new AlmanacBindingsSearchEngineAttachment())
299 ->setAttachmentKey('bindings'),
300 id(new AlmanacBindingsSearchEngineAttachment())
301 ->setIsActive(true)
302 ->setAttachmentKey('activeBindings'),