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

Configure Feed

Select the types of activity you want to include in your feed.

Store Almanac "service types" instead of "service classes"

Summary:
Ref T10449. Currently, we store classes (like "AlmanacClusterRepositoryServiceType") in the database.

Instead, store types (like "cluster.repository").

This is a small change, but types are a little more flexible (they let us freely reanme classes), a little cleaner (fewer magic strings in the codebase), and a little better for API usage (they're more human readable).

Make this minor usability change now, before we unprototype.

Also make services searchable by type.

Also remove old Almanac API endpoints.

Test Plan:
- Ran migration, verified all data migrated properly.
- Created, edited, rebound, and changed properties of services.
- Searched for services by service type.
- Reviewed available Conduit methods.

Reviewers: chad

Reviewed By: chad

Subscribers: yelirekim

Maniphest Tasks: T10449

Differential Revision: https://secure.phabricator.com/D15346

+226 -282
+2
resources/sql/autopatches/20160225.almanac.2.stype.sql
··· 1 + ALTER TABLE {$NAMESPACE}_almanac.almanac_service 2 + CHANGE serviceClass serviceType VARCHAR(64) NOT NULL COLLATE {$COLLATE_TEXT};
+30
resources/sql/autopatches/20160225.almanac.3.stype.php
··· 1 + <?php 2 + 3 + // Previously, Almanac services stored a "serviceClass". Migrate these to 4 + // new "serviceType" values. 5 + 6 + $table = new AlmanacService(); 7 + $conn_w = $table->establishConnection('w'); 8 + 9 + foreach (new LiskMigrationIterator($table) as $service) { 10 + 11 + $new_type = null; 12 + try { 13 + $old_type = $service->getServiceType(); 14 + $object = newv($old_type, array()); 15 + $new_type = $object->getServiceTypeConstant(); 16 + } catch (Exception $ex) { 17 + continue; 18 + } 19 + 20 + if (!$new_type) { 21 + continue; 22 + } 23 + 24 + queryfx( 25 + $conn_w, 26 + 'UPDATE %T SET serviceType = %s WHERE id = %d', 27 + $table->getTableName(), 28 + $new_type, 29 + $service->getID()); 30 + }
+2 -6
src/__phutil_library_map__.php
··· 25 25 'AlmanacClusterDatabaseServiceType' => 'applications/almanac/servicetype/AlmanacClusterDatabaseServiceType.php', 26 26 'AlmanacClusterRepositoryServiceType' => 'applications/almanac/servicetype/AlmanacClusterRepositoryServiceType.php', 27 27 'AlmanacClusterServiceType' => 'applications/almanac/servicetype/AlmanacClusterServiceType.php', 28 - 'AlmanacConduitAPIMethod' => 'applications/almanac/conduit/AlmanacConduitAPIMethod.php', 29 28 'AlmanacConsoleController' => 'applications/almanac/controller/AlmanacConsoleController.php', 30 29 'AlmanacController' => 'applications/almanac/controller/AlmanacController.php', 31 30 'AlmanacCreateDevicesCapability' => 'applications/almanac/capability/AlmanacCreateDevicesCapability.php', ··· 101 100 'AlmanacPropertyInterface' => 'applications/almanac/property/AlmanacPropertyInterface.php', 102 101 'AlmanacPropertyQuery' => 'applications/almanac/query/AlmanacPropertyQuery.php', 103 102 'AlmanacQuery' => 'applications/almanac/query/AlmanacQuery.php', 104 - 'AlmanacQueryDevicesConduitAPIMethod' => 'applications/almanac/conduit/AlmanacQueryDevicesConduitAPIMethod.php', 105 - 'AlmanacQueryServicesConduitAPIMethod' => 'applications/almanac/conduit/AlmanacQueryServicesConduitAPIMethod.php', 106 103 'AlmanacSchemaSpec' => 'applications/almanac/storage/AlmanacSchemaSpec.php', 107 104 'AlmanacSearchEngineAttachment' => 'applications/almanac/engineextension/AlmanacSearchEngineAttachment.php', 108 105 'AlmanacService' => 'applications/almanac/storage/AlmanacService.php', ··· 120 117 'AlmanacServiceTransaction' => 'applications/almanac/storage/AlmanacServiceTransaction.php', 121 118 'AlmanacServiceTransactionQuery' => 'applications/almanac/query/AlmanacServiceTransactionQuery.php', 122 119 'AlmanacServiceType' => 'applications/almanac/servicetype/AlmanacServiceType.php', 120 + 'AlmanacServiceTypeDatasource' => 'applications/almanac/typeahead/AlmanacServiceTypeDatasource.php', 123 121 'AlmanacServiceTypeTestCase' => 'applications/almanac/servicetype/__tests__/AlmanacServiceTypeTestCase.php', 124 122 'AlmanacServiceViewController' => 'applications/almanac/controller/AlmanacServiceViewController.php', 125 123 'AlmanacTransaction' => 'applications/almanac/storage/AlmanacTransaction.php', ··· 4012 4010 'AlmanacClusterDatabaseServiceType' => 'AlmanacClusterServiceType', 4013 4011 'AlmanacClusterRepositoryServiceType' => 'AlmanacClusterServiceType', 4014 4012 'AlmanacClusterServiceType' => 'AlmanacServiceType', 4015 - 'AlmanacConduitAPIMethod' => 'ConduitAPIMethod', 4016 4013 'AlmanacConsoleController' => 'AlmanacController', 4017 4014 'AlmanacController' => 'PhabricatorController', 4018 4015 'AlmanacCreateDevicesCapability' => 'PhabricatorPolicyCapability', ··· 4120 4117 'AlmanacPropertyEditEngine' => 'PhabricatorEditEngine', 4121 4118 'AlmanacPropertyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4122 4119 'AlmanacQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4123 - 'AlmanacQueryDevicesConduitAPIMethod' => 'AlmanacConduitAPIMethod', 4124 - 'AlmanacQueryServicesConduitAPIMethod' => 'AlmanacConduitAPIMethod', 4125 4120 'AlmanacSchemaSpec' => 'PhabricatorConfigSchemaSpec', 4126 4121 'AlmanacSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment', 4127 4122 'AlmanacService' => array( ··· 4149 4144 'AlmanacServiceTransaction' => 'AlmanacTransaction', 4150 4145 'AlmanacServiceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 4151 4146 'AlmanacServiceType' => 'Phobject', 4147 + 'AlmanacServiceTypeDatasource' => 'PhabricatorTypeaheadDatasource', 4152 4148 'AlmanacServiceTypeTestCase' => 'PhabricatorTestCase', 4153 4149 'AlmanacServiceViewController' => 'AlmanacServiceController', 4154 4150 'AlmanacTransaction' => 'PhabricatorApplicationTransaction',
-73
src/applications/almanac/conduit/AlmanacConduitAPIMethod.php
··· 1 - <?php 2 - 3 - abstract class AlmanacConduitAPIMethod extends ConduitAPIMethod { 4 - 5 - final public function getApplication() { 6 - return PhabricatorApplication::getByClass( 7 - 'PhabricatorAlmanacApplication'); 8 - } 9 - 10 - public function getMethodStatus() { 11 - return self::METHOD_STATUS_DEPRECATED; 12 - } 13 - 14 - public function getMethodStatusDescription() { 15 - return pht( 16 - 'Almanac is a prototype application and its APIs are '. 17 - 'subject to change.'); 18 - } 19 - 20 - protected function getServiceDictionary(AlmanacService $service) { 21 - return array( 22 - 'id' => (int)$service->getID(), 23 - 'phid' => $service->getPHID(), 24 - 'name' => $service->getName(), 25 - 'uri' => PhabricatorEnv::getProductionURI($service->getURI()), 26 - 'serviceClass' => $service->getServiceClass(), 27 - 'properties' => $this->getPropertiesDictionary($service), 28 - ); 29 - } 30 - 31 - protected function getBindingDictionary(AlmanacBinding $binding) { 32 - return array( 33 - 'id' => (int)$binding->getID(), 34 - 'phid' => $binding->getPHID(), 35 - 'properties' => $this->getPropertiesDictionary($binding), 36 - 'interface' => $this->getInterfaceDictionary($binding->getInterface()), 37 - ); 38 - } 39 - 40 - protected function getPropertiesDictionary(AlmanacPropertyInterface $obj) { 41 - $properties = $obj->getAlmanacProperties(); 42 - return (object)mpull($properties, 'getFieldValue', 'getFieldName'); 43 - } 44 - 45 - protected function getInterfaceDictionary(AlmanacInterface $interface) { 46 - return array( 47 - 'id' => (int)$interface->getID(), 48 - 'phid' => $interface->getPHID(), 49 - 'address' => $interface->getAddress(), 50 - 'port' => (int)$interface->getPort(), 51 - 'device' => $this->getDeviceDictionary($interface->getDevice()), 52 - 'network' => $this->getNetworkDictionary($interface->getNetwork()), 53 - ); 54 - } 55 - 56 - protected function getDeviceDictionary(AlmanacDevice $device) { 57 - return array( 58 - 'id' => (int)$device->getID(), 59 - 'phid' => $device->getPHID(), 60 - 'name' => $device->getName(), 61 - 'properties' => $this->getPropertiesDictionary($device), 62 - ); 63 - } 64 - 65 - protected function getNetworkDictionary(AlmanacNetwork $network) { 66 - return array( 67 - 'id' => (int)$network->getID(), 68 - 'phid' => $network->getPHID(), 69 - 'name' => $network->getName(), 70 - ); 71 - } 72 - 73 - }
-63
src/applications/almanac/conduit/AlmanacQueryDevicesConduitAPIMethod.php
··· 1 - <?php 2 - 3 - final class AlmanacQueryDevicesConduitAPIMethod 4 - extends AlmanacConduitAPIMethod { 5 - 6 - public function getAPIMethodName() { 7 - return 'almanac.querydevices'; 8 - } 9 - 10 - public function getMethodDescription() { 11 - return pht('Query Almanac devices.'); 12 - } 13 - 14 - protected function defineParamTypes() { 15 - return array( 16 - 'ids' => 'optional list<id>', 17 - 'phids' => 'optional list<phid>', 18 - 'names' => 'optional list<phid>', 19 - ) + self::getPagerParamTypes(); 20 - } 21 - 22 - protected function defineReturnType() { 23 - return 'list<wild>'; 24 - } 25 - 26 - protected function execute(ConduitAPIRequest $request) { 27 - $viewer = $request->getUser(); 28 - 29 - $query = id(new AlmanacDeviceQuery()) 30 - ->setViewer($viewer); 31 - 32 - $ids = $request->getValue('ids'); 33 - if ($ids !== null) { 34 - $query->withIDs($ids); 35 - } 36 - 37 - $phids = $request->getValue('phids'); 38 - if ($phids !== null) { 39 - $query->withPHIDs($phids); 40 - } 41 - 42 - $names = $request->getValue('names'); 43 - if ($names !== null) { 44 - $query->withNames($names); 45 - } 46 - 47 - $pager = $this->newPager($request); 48 - 49 - $devices = $query->executeWithCursorPager($pager); 50 - 51 - $data = array(); 52 - foreach ($devices as $device) { 53 - $data[] = $this->getDeviceDictionary($device); 54 - } 55 - 56 - $results = array( 57 - 'data' => $data, 58 - ); 59 - 60 - return $this->addPagerResults($results, $pager); 61 - } 62 - 63 - }
-86
src/applications/almanac/conduit/AlmanacQueryServicesConduitAPIMethod.php
··· 1 - <?php 2 - 3 - final class AlmanacQueryServicesConduitAPIMethod 4 - extends AlmanacConduitAPIMethod { 5 - 6 - public function getAPIMethodName() { 7 - return 'almanac.queryservices'; 8 - } 9 - 10 - public function getMethodDescription() { 11 - return pht('Query Almanac services.'); 12 - } 13 - 14 - protected function defineParamTypes() { 15 - return array( 16 - 'ids' => 'optional list<id>', 17 - 'phids' => 'optional list<phid>', 18 - 'names' => 'optional list<phid>', 19 - 'devicePHIDs' => 'optional list<phid>', 20 - 'serviceClasses' => 'optional list<string>', 21 - ) + self::getPagerParamTypes(); 22 - } 23 - 24 - protected function defineReturnType() { 25 - return 'list<wild>'; 26 - } 27 - 28 - protected function execute(ConduitAPIRequest $request) { 29 - $viewer = $request->getUser(); 30 - 31 - $query = id(new AlmanacServiceQuery()) 32 - ->setViewer($viewer) 33 - ->needBindings(true); 34 - 35 - $ids = $request->getValue('ids'); 36 - if ($ids !== null) { 37 - $query->withIDs($ids); 38 - } 39 - 40 - $phids = $request->getValue('phids'); 41 - if ($phids !== null) { 42 - $query->withPHIDs($phids); 43 - } 44 - 45 - $names = $request->getValue('names'); 46 - if ($names !== null) { 47 - $query->withNames($names); 48 - } 49 - 50 - $classes = $request->getValue('serviceClasses'); 51 - if ($classes !== null) { 52 - $query->withServiceClasses($classes); 53 - } 54 - 55 - $device_phids = $request->getValue('devicePHIDs'); 56 - if ($device_phids !== null) { 57 - $query->withDevicePHIDs($device_phids); 58 - } 59 - 60 - $pager = $this->newPager($request); 61 - 62 - $services = $query->executeWithCursorPager($pager); 63 - 64 - $data = array(); 65 - foreach ($services as $service) { 66 - $phid = $service->getPHID(); 67 - 68 - $service_bindings = $service->getBindings(); 69 - $service_bindings = array_values($service_bindings); 70 - foreach ($service_bindings as $key => $service_binding) { 71 - $service_bindings[$key] = $this->getBindingDictionary($service_binding); 72 - } 73 - 74 - $data[] = $this->getServiceDictionary($service) + array( 75 - 'bindings' => $service_bindings, 76 - ); 77 - } 78 - 79 - $results = array( 80 - 'data' => $data, 81 - ); 82 - 83 - return $this->addPagerResults($results, $pager); 84 - } 85 - 86 - }
+13 -13
src/applications/almanac/controller/AlmanacServiceEditController.php
··· 34 34 $this->requireApplicationCapability( 35 35 AlmanacCreateServicesCapability::CAPABILITY); 36 36 37 - $service_class = $request->getStr('serviceClass'); 38 - $service_types = AlmanacServiceType::getAllServiceTypes(); 39 - if (empty($service_types[$service_class])) { 40 - return $this->buildServiceTypeResponse($service_types, $cancel_uri); 37 + $service_type = $request->getStr('serviceType'); 38 + 39 + try { 40 + $service = AlmanacService::initializeNewService($service_type); 41 + } catch (Exception $ex) { 42 + return $this->buildServiceTypeResponse($cancel_uri); 41 43 } 42 44 43 - $service_type = $service_types[$service_class]; 44 - if ($service_type->isClusterServiceType()) { 45 + if ($service->isClusterService()) { 45 46 $this->requireApplicationCapability( 46 47 AlmanacManageClusterServicesCapability::CAPABILITY); 47 48 } 48 49 49 - $service = AlmanacService::initializeNewService(); 50 - $service->setServiceClass($service_class); 51 - $service->attachServiceType($service_type); 52 50 $is_new = true; 53 51 54 52 $title = pht('Create Service'); ··· 125 123 $form = id(new AphrontFormView()) 126 124 ->setUser($viewer) 127 125 ->addHiddenInput('edit', true) 128 - ->addHiddenInput('serviceClass', $service->getServiceClass()) 126 + ->addHiddenInput('serviceType', $service->getServiceType()) 129 127 ->appendChild( 130 128 id(new AphrontFormTextControl()) 131 129 ->setLabel(pht('Name')) ··· 177 175 )); 178 176 } 179 177 180 - private function buildServiceTypeResponse(array $service_types, $cancel_uri) { 178 + private function buildServiceTypeResponse($cancel_uri) { 179 + $service_types = AlmanacServiceType::getAllServiceTypes(); 180 + 181 181 $request = $this->getRequest(); 182 182 $viewer = $this->getViewer(); 183 183 ··· 197 197 198 198 $type_control = id(new AphrontFormRadioButtonControl()) 199 199 ->setLabel(pht('Service Type')) 200 - ->setName('serviceClass') 200 + ->setName('serviceType') 201 201 ->setError($e_service); 202 202 203 203 foreach ($service_types as $service_type) { ··· 211 211 } 212 212 213 213 $type_control->addButton( 214 - get_class($service_type), 214 + $service_type->getServiceTypeConstant(), 215 215 $service_type->getServiceTypeName(), 216 216 array( 217 217 $service_type->getServiceTypeDescription(),
+1 -1
src/applications/almanac/controller/AlmanacServiceViewController.php
··· 76 76 77 77 $properties->addProperty( 78 78 pht('Service Type'), 79 - $service->getServiceType()->getServiceTypeShortName()); 79 + $service->getServiceImplementation()->getServiceTypeShortName()); 80 80 81 81 return $properties; 82 82 }
+13 -11
src/applications/almanac/query/AlmanacServiceQuery.php
··· 6 6 private $ids; 7 7 private $phids; 8 8 private $names; 9 - private $serviceClasses; 9 + private $serviceTypes; 10 10 private $devicePHIDs; 11 11 private $namePrefix; 12 12 private $nameSuffix; ··· 28 28 return $this; 29 29 } 30 30 31 - public function withServiceClasses(array $classes) { 32 - $this->serviceClasses = $classes; 31 + public function withServiceTypes(array $types) { 32 + $this->serviceTypes = $types; 33 33 return $this; 34 34 } 35 35 ··· 109 109 $hashes); 110 110 } 111 111 112 - if ($this->serviceClasses !== null) { 112 + if ($this->serviceTypes !== null) { 113 113 $where[] = qsprintf( 114 114 $conn, 115 - 'service.serviceClass IN (%Ls)', 116 - $this->serviceClasses); 115 + 'service.serviceType IN (%Ls)', 116 + $this->serviceTypes); 117 117 } 118 118 119 119 if ($this->devicePHIDs !== null) { ··· 141 141 } 142 142 143 143 protected function willFilterPage(array $services) { 144 - $service_types = AlmanacServiceType::getAllServiceTypes(); 144 + $service_map = AlmanacServiceType::getAllServiceTypes(); 145 145 146 146 foreach ($services as $key => $service) { 147 - $service_class = $service->getServiceClass(); 148 - $service_type = idx($service_types, $service_class); 149 - if (!$service_type) { 147 + $implementation = idx($service_map, $service->getServiceType()); 148 + 149 + if (!$implementation) { 150 150 $this->didRejectResult($service); 151 151 unset($services[$key]); 152 152 continue; 153 153 } 154 - $service->attachServiceType($service_type); 154 + 155 + $implementation = clone $implementation; 156 + $service->attachServiceImplementation($implementation); 155 157 } 156 158 157 159 return $services;
+12 -3
src/applications/almanac/query/AlmanacServiceSearchEngine.php
··· 16 16 } 17 17 18 18 public function newResultObject() { 19 - return AlmanacService::initializeNewService(); 19 + return new AlmanacService(); 20 20 } 21 21 22 22 protected function buildQueryFromParameters(array $map) { ··· 32 32 33 33 if ($map['devicePHIDs']) { 34 34 $query->withDevicePHIDs($map['devicePHIDs']); 35 + } 36 + 37 + if ($map['serviceTypes']) { 38 + $query->withServiceTypes($map['serviceTypes']); 35 39 } 36 40 37 41 return $query; ··· 48 52 ->setLabel(pht('Exact Names')) 49 53 ->setKey('names') 50 54 ->setDescription(pht('Search for services with specific names.')), 55 + id(new PhabricatorSearchDatasourceField()) 56 + ->setLabel(pht('Service Types')) 57 + ->setKey('serviceTypes') 58 + ->setDescription(pht('Find services by type.')) 59 + ->setDatasource(id(new AlmanacServiceTypeDatasource())), 51 60 id(new PhabricatorPHIDsSearchField()) 52 61 ->setLabel(pht('Devices')) 53 62 ->setKey('devicePHIDs') ··· 98 107 ->setHref($service->getURI()) 99 108 ->setObject($service) 100 109 ->addIcon( 101 - $service->getServiceType()->getServiceTypeIcon(), 102 - $service->getServiceType()->getServiceTypeShortName()); 110 + $service->getServiceImplementation()->getServiceTypeIcon(), 111 + $service->getServiceImplementation()->getServiceTypeShortName()); 103 112 104 113 $list->addItem($item); 105 114 }
+2
src/applications/almanac/servicetype/AlmanacClusterDatabaseServiceType.php
··· 3 3 final class AlmanacClusterDatabaseServiceType 4 4 extends AlmanacClusterServiceType { 5 5 6 + const SERVICETYPE = 'cluster.database'; 7 + 6 8 public function getServiceTypeShortName() { 7 9 return pht('Cluster Database'); 8 10 }
+2
src/applications/almanac/servicetype/AlmanacClusterRepositoryServiceType.php
··· 3 3 final class AlmanacClusterRepositoryServiceType 4 4 extends AlmanacClusterServiceType { 5 5 6 + const SERVICETYPE = 'cluster.repository'; 7 + 6 8 public function getServiceTypeShortName() { 7 9 return pht('Cluster Repository'); 8 10 }
+2
src/applications/almanac/servicetype/AlmanacCustomServiceType.php
··· 2 2 3 3 final class AlmanacCustomServiceType extends AlmanacServiceType { 4 4 5 + const SERVICETYPE = 'almanac.custom'; 6 + 5 7 public function getServiceTypeShortName() { 6 8 return pht('Custom'); 7 9 }
+2
src/applications/almanac/servicetype/AlmanacDrydockPoolServiceType.php
··· 2 2 3 3 final class AlmanacDrydockPoolServiceType extends AlmanacServiceType { 4 4 5 + const SERVICETYPE = 'drydock.pool'; 6 + 5 7 public function getServiceTypeShortName() { 6 8 return pht('Drydock Pool'); 7 9 }
+7 -1
src/applications/almanac/servicetype/AlmanacServiceType.php
··· 30 30 abstract public function getServiceTypeDescription(); 31 31 32 32 33 + final public function getServiceTypeConstant() { 34 + return $this->getPhobjectClassConstant('SERVICETYPE', 64); 35 + } 36 + 37 + 33 38 public function getServiceTypeIcon() { 34 39 return 'fa-cog'; 35 40 } ··· 38 43 * Return `true` if this service type is a Phabricator cluster service type. 39 44 * 40 45 * These special services change the behavior of Phabricator, and require 41 - * elevated permission to create. 46 + * elevated permission to create and edit. 42 47 * 43 48 * @return bool True if this is a Phabricator cluster service type. 44 49 */ ··· 63 68 public static function getAllServiceTypes() { 64 69 return id(new PhutilClassMapQuery()) 65 70 ->setAncestorClass(__CLASS__) 71 + ->setUniqueMethod('getServiceTypeConstant') 66 72 ->setSortMethod('getServiceTypeName') 67 73 ->execute(); 68 74 }
+40
src/applications/almanac/storage/AlmanacProperty.php
··· 39 39 return $this; 40 40 } 41 41 42 + public static function newPropertyUpdateTransactions( 43 + AlmanacPropertyInterface $object, 44 + array $properties, 45 + $only_builtins = false) { 46 + 47 + $template = $object->getApplicationTransactionTemplate(); 48 + $builtins = $object->getAlmanacPropertyFieldSpecifications(); 49 + 50 + $xactions = array(); 51 + foreach ($properties as $name => $property) { 52 + if ($only_builtins && empty($builtins[$name])) { 53 + continue; 54 + } 55 + 56 + $xactions[] = id(clone $template) 57 + ->setTransactionType(AlmanacTransaction::TYPE_PROPERTY_UPDATE) 58 + ->setMetadataValue('almanac.property', $name) 59 + ->setNewValue($property); 60 + } 61 + 62 + return $xactions; 63 + } 64 + 65 + public static function newPropertyRemoveTransactions( 66 + AlmanacPropertyInterface $object, 67 + array $properties) { 68 + 69 + $template = $object->getApplicationTransactionTemplate(); 70 + 71 + $xactions = array(); 72 + foreach ($properties as $property) { 73 + $xactions[] = id(clone $template) 74 + ->setTransactionType(AlmanacTransaction::TYPE_PROPERTY_REMOVE) 75 + ->setMetadataValue('almanac.property', $property) 76 + ->setNewValue(null); 77 + } 78 + 79 + return $xactions; 80 + } 81 + 42 82 public function save() { 43 83 $hash = PhabricatorHash::digestForIndex($this->getFieldName()); 44 84 $this->setFieldIndex($hash);
+43 -13
src/applications/almanac/storage/AlmanacService.php
··· 17 17 protected $mailKey; 18 18 protected $viewPolicy; 19 19 protected $editPolicy; 20 - protected $serviceClass; 20 + protected $serviceType; 21 21 22 22 private $almanacProperties = self::ATTACHABLE; 23 23 private $bindings = self::ATTACHABLE; 24 - private $serviceType = self::ATTACHABLE; 24 + private $serviceImplementation = self::ATTACHABLE; 25 25 26 - public static function initializeNewService() { 26 + public static function initializeNewService($type) { 27 + $type_map = AlmanacServiceType::getAllServiceTypes(); 28 + 29 + $implementation = idx($type_map, $type); 30 + if (!$implementation) { 31 + throw new Exception( 32 + pht( 33 + 'No Almanac service type "%s" exists!', 34 + $type)); 35 + } 36 + 27 37 return id(new AlmanacService()) 28 38 ->setViewPolicy(PhabricatorPolicies::POLICY_USER) 29 39 ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN) 30 - ->attachAlmanacProperties(array()); 40 + ->attachAlmanacProperties(array()) 41 + ->setServiceType($type) 42 + ->attachServiceImplementation($implementation); 31 43 } 32 44 33 45 protected function getConfiguration() { ··· 37 49 'name' => 'text128', 38 50 'nameIndex' => 'bytes12', 39 51 'mailKey' => 'bytes20', 40 - 'serviceClass' => 'text64', 52 + 'serviceType' => 'text64', 41 53 ), 42 54 self::CONFIG_KEY_SCHEMA => array( 43 55 'key_name' => array( ··· 47 59 'key_nametext' => array( 48 60 'columns' => array('name'), 49 61 ), 50 - 'key_class' => array( 51 - 'columns' => array('serviceClass'), 62 + 'key_servicetype' => array( 63 + 'columns' => array('serviceType'), 52 64 ), 53 65 ), 54 66 ) + parent::getConfiguration(); ··· 78 90 return $this->assertAttached($this->bindings); 79 91 } 80 92 93 + public function getActiveBindings() { 94 + $bindings = $this->getBindings(); 95 + 96 + // Filter out disabled bindings. 97 + foreach ($bindings as $key => $binding) { 98 + if ($binding->getIsDisabled()) { 99 + unset($bindings[$key]); 100 + } 101 + } 102 + 103 + return $bindings; 104 + } 105 + 81 106 public function attachBindings(array $bindings) { 82 107 $this->bindings = $bindings; 83 108 return $this; 84 109 } 85 110 86 - public function getServiceType() { 87 - return $this->assertAttached($this->serviceType); 111 + public function getServiceImplementation() { 112 + return $this->assertAttached($this->serviceImplementation); 88 113 } 89 114 90 - public function attachServiceType(AlmanacServiceType $type) { 91 - $this->serviceType = $type; 115 + public function attachServiceImplementation(AlmanacServiceType $type) { 116 + $this->serviceImplementation = $type; 92 117 return $this; 93 118 } 94 119 95 120 public function isClusterService() { 96 - return $this->getServiceType()->isClusterServiceType(); 121 + return $this->getServiceImplementation()->isClusterServiceType(); 97 122 } 98 123 99 124 ··· 128 153 } 129 154 130 155 public function getAlmanacPropertyFieldSpecifications() { 131 - return $this->getServiceType()->getFieldSpecifications(); 156 + return $this->getServiceImplementation()->getFieldSpecifications(); 132 157 } 133 158 134 159 public function newAlmanacPropertyEditEngine() { ··· 246 271 ->setKey('name') 247 272 ->setType('string') 248 273 ->setDescription(pht('The name of the service.')), 274 + id(new PhabricatorConduitSearchFieldSpecification()) 275 + ->setKey('serviceType') 276 + ->setType('string') 277 + ->setDescription(pht('The service type constant.')), 249 278 ); 250 279 } 251 280 252 281 public function getFieldValuesForConduit() { 253 282 return array( 254 283 'name' => $this->getName(), 284 + 'serviceType' => $this->getServiceType(), 255 285 ); 256 286 } 257 287
+3 -3
src/applications/almanac/typeahead/AlmanacServiceDatasource.php
··· 28 28 // selected, or show all services but mark the invalid ones disabled and 29 29 // prevent their selection. 30 30 31 - $service_classes = $this->getParameter('serviceClasses'); 32 - if ($service_classes) { 33 - $services->withServiceClasses($service_classes); 31 + $service_types = $this->getParameter('serviceTypes'); 32 + if ($service_types) { 33 + $services->withServiceTypes($service_types); 34 34 } 35 35 36 36 $services = $this->executeQuery($services);
+43
src/applications/almanac/typeahead/AlmanacServiceTypeDatasource.php
··· 1 + <?php 2 + 3 + final class AlmanacServiceTypeDatasource 4 + extends PhabricatorTypeaheadDatasource { 5 + 6 + public function getBrowseTitle() { 7 + return pht('Browse Service Types'); 8 + } 9 + 10 + public function getPlaceholderText() { 11 + return pht('Type a service type name...'); 12 + } 13 + 14 + public function getDatasourceApplicationClass() { 15 + return 'PhabricatorAlmanacApplication'; 16 + } 17 + 18 + public function loadResults() { 19 + $results = $this->buildResults(); 20 + return $this->filterResultsAgainstTokens($results); 21 + } 22 + 23 + protected function renderSpecialTokens(array $values) { 24 + return $this->renderTokensFromResults($this->buildResults(), $values); 25 + } 26 + 27 + private function buildResults() { 28 + $results = array(); 29 + 30 + $types = AlmanacServiceType::getAllServiceTypes(); 31 + 32 + $results = array(); 33 + foreach ($types as $key => $type) { 34 + $results[$key] = id(new PhabricatorTypeaheadResult()) 35 + ->setName($type->getServiceTypeName()) 36 + ->setIcon($type->getServiceTypeIcon()) 37 + ->setPHID($key); 38 + } 39 + 40 + return $results; 41 + } 42 + 43 + }
+2 -2
src/applications/config/check/PhabricatorRepositoriesSetupCheck.php
··· 10 10 11 11 $cluster_services = id(new AlmanacServiceQuery()) 12 12 ->setViewer(PhabricatorUser::getOmnipotentUser()) 13 - ->withServiceClasses( 13 + ->withServiceTypes( 14 14 array( 15 - 'AlmanacClusterRepositoryServiceType', 15 + AlmanacClusterRepositoryServiceType::SERVICETYPE, 16 16 )) 17 17 ->setLimit(1) 18 18 ->execute();
+2 -2
src/applications/diffusion/controller/DiffusionRepositoryCreateController.php
··· 47 47 // allocations, we fail. 48 48 $services = id(new AlmanacServiceQuery()) 49 49 ->setViewer(PhabricatorUser::getOmnipotentUser()) 50 - ->withServiceClasses( 50 + ->withServiceTypes( 51 51 array( 52 - 'AlmanacClusterRepositoryServiceType', 52 + AlmanacClusterRepositoryServiceType::SERVICETYPE, 53 53 )) 54 54 ->needProperties(true) 55 55 ->execute();
+4 -4
src/applications/drydock/blueprint/DrydockAlmanacServiceHostBlueprintImplementation.php
··· 184 184 'type' => 'datasource', 185 185 'datasource.class' => 'AlmanacServiceDatasource', 186 186 'datasource.parameters' => array( 187 - 'serviceClasses' => $this->getAlmanacServiceClasses(), 187 + 'serviceTypes' => $this->getAlmanacServiceTypes(), 188 188 ), 189 189 'required' => true, 190 190 ), ··· 213 213 $services = id(new AlmanacServiceQuery()) 214 214 ->setViewer($viewer) 215 215 ->withPHIDs($service_phids) 216 - ->withServiceClasses($this->getAlmanacServiceClasses()) 216 + ->withServiceTypes($this->getAlmanacServiceTypes()) 217 217 ->needBindings(true) 218 218 ->execute(); 219 219 $services = mpull($services, null, 'getPHID'); ··· 283 283 return $this->freeBindings; 284 284 } 285 285 286 - private function getAlmanacServiceClasses() { 286 + private function getAlmanacServiceTypes() { 287 287 return array( 288 - 'AlmanacDrydockPoolServiceType', 288 + AlmanacDrydockPoolServiceType::SERVICETYPE, 289 289 ); 290 290 } 291 291
+1 -1
src/applications/repository/storage/PhabricatorRepository.php
··· 2047 2047 'be loaded.')); 2048 2048 } 2049 2049 2050 - $service_type = $service->getServiceType(); 2050 + $service_type = $service->getServiceImplementation(); 2051 2051 if (!($service_type instanceof AlmanacClusterRepositoryServiceType)) { 2052 2052 throw new Exception( 2053 2053 pht(