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

Expose modern `*.search` Conduit endpoints in Almanac

Summary: Fixes T10411. Ref T10246. There are probably still some rough edges with this, but replace the old-school endpoints with modern ones so we don't unprototype with deprecated stuff.

Test Plan:
- Made a bunch of calls to the new endpoints with various constraints/attachments.
- Created and edited services, devices, interfaces, bindings, and properties on everything.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10246, T10411

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

+401 -109
+16 -4
src/__phutil_library_map__.php
··· 20 20 'AlmanacBindingTransaction' => 'applications/almanac/storage/AlmanacBindingTransaction.php', 21 21 'AlmanacBindingTransactionQuery' => 'applications/almanac/query/AlmanacBindingTransactionQuery.php', 22 22 'AlmanacBindingViewController' => 'applications/almanac/controller/AlmanacBindingViewController.php', 23 + 'AlmanacBindingsSearchEngineAttachment' => 'applications/almanac/engineextension/AlmanacBindingsSearchEngineAttachment.php', 23 24 'AlmanacClusterDatabaseServiceType' => 'applications/almanac/servicetype/AlmanacClusterDatabaseServiceType.php', 24 25 'AlmanacClusterRepositoryServiceType' => 'applications/almanac/servicetype/AlmanacClusterRepositoryServiceType.php', 25 26 'AlmanacClusterServiceType' => 'applications/almanac/servicetype/AlmanacClusterServiceType.php', ··· 42 43 'AlmanacDevicePHIDType' => 'applications/almanac/phid/AlmanacDevicePHIDType.php', 43 44 'AlmanacDevicePropertyEditEngine' => 'applications/almanac/editor/AlmanacDevicePropertyEditEngine.php', 44 45 'AlmanacDeviceQuery' => 'applications/almanac/query/AlmanacDeviceQuery.php', 46 + 'AlmanacDeviceSearchConduitAPIMethod' => 'applications/almanac/conduit/AlmanacDeviceSearchConduitAPIMethod.php', 45 47 'AlmanacDeviceSearchEngine' => 'applications/almanac/query/AlmanacDeviceSearchEngine.php', 46 48 'AlmanacDeviceTransaction' => 'applications/almanac/storage/AlmanacDeviceTransaction.php', 47 49 'AlmanacDeviceTransactionQuery' => 'applications/almanac/query/AlmanacDeviceTransactionQuery.php', ··· 90 92 'AlmanacNetworkTransactionQuery' => 'applications/almanac/query/AlmanacNetworkTransactionQuery.php', 91 93 'AlmanacNetworkViewController' => 'applications/almanac/controller/AlmanacNetworkViewController.php', 92 94 'AlmanacPropertiesDestructionEngineExtension' => 'applications/almanac/engineextension/AlmanacPropertiesDestructionEngineExtension.php', 95 + 'AlmanacPropertiesSearchEngineAttachment' => 'applications/almanac/engineextension/AlmanacPropertiesSearchEngineAttachment.php', 93 96 'AlmanacProperty' => 'applications/almanac/storage/AlmanacProperty.php', 94 97 'AlmanacPropertyController' => 'applications/almanac/controller/AlmanacPropertyController.php', 95 98 'AlmanacPropertyDeleteController' => 'applications/almanac/controller/AlmanacPropertyDeleteController.php', ··· 101 104 'AlmanacQueryDevicesConduitAPIMethod' => 'applications/almanac/conduit/AlmanacQueryDevicesConduitAPIMethod.php', 102 105 'AlmanacQueryServicesConduitAPIMethod' => 'applications/almanac/conduit/AlmanacQueryServicesConduitAPIMethod.php', 103 106 'AlmanacSchemaSpec' => 'applications/almanac/storage/AlmanacSchemaSpec.php', 107 + 'AlmanacSearchEngineAttachment' => 'applications/almanac/engineextension/AlmanacSearchEngineAttachment.php', 104 108 'AlmanacService' => 'applications/almanac/storage/AlmanacService.php', 105 109 'AlmanacServiceController' => 'applications/almanac/controller/AlmanacServiceController.php', 106 110 'AlmanacServiceDatasource' => 'applications/almanac/typeahead/AlmanacServiceDatasource.php', ··· 111 115 'AlmanacServicePHIDType' => 'applications/almanac/phid/AlmanacServicePHIDType.php', 112 116 'AlmanacServicePropertyEditEngine' => 'applications/almanac/editor/AlmanacServicePropertyEditEngine.php', 113 117 'AlmanacServiceQuery' => 'applications/almanac/query/AlmanacServiceQuery.php', 118 + 'AlmanacServiceSearchConduitAPIMethod' => 'applications/almanac/conduit/AlmanacServiceSearchConduitAPIMethod.php', 114 119 'AlmanacServiceSearchEngine' => 'applications/almanac/query/AlmanacServiceSearchEngine.php', 115 120 'AlmanacServiceTransaction' => 'applications/almanac/storage/AlmanacServiceTransaction.php', 116 121 'AlmanacServiceTransactionQuery' => 'applications/almanac/query/AlmanacServiceTransactionQuery.php', ··· 4007 4012 'AlmanacBindingTransaction' => 'AlmanacTransaction', 4008 4013 'AlmanacBindingTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 4009 4014 'AlmanacBindingViewController' => 'AlmanacServiceController', 4015 + 'AlmanacBindingsSearchEngineAttachment' => 'AlmanacSearchEngineAttachment', 4010 4016 'AlmanacClusterDatabaseServiceType' => 'AlmanacClusterServiceType', 4011 4017 'AlmanacClusterRepositoryServiceType' => 'AlmanacClusterServiceType', 4012 4018 'AlmanacClusterServiceType' => 'AlmanacServiceType', ··· 4029 4035 'AlmanacPropertyInterface', 4030 4036 'PhabricatorDestructibleInterface', 4031 4037 'PhabricatorNgramsInterface', 4038 + 'PhabricatorConduitResultInterface', 4032 4039 ), 4033 4040 'AlmanacDeviceController' => 'AlmanacController', 4034 4041 'AlmanacDeviceEditController' => 'AlmanacDeviceController', ··· 4038 4045 'AlmanacDevicePHIDType' => 'PhabricatorPHIDType', 4039 4046 'AlmanacDevicePropertyEditEngine' => 'AlmanacPropertyEditEngine', 4040 4047 'AlmanacDeviceQuery' => 'AlmanacQuery', 4048 + 'AlmanacDeviceSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 4041 4049 'AlmanacDeviceSearchEngine' => 'PhabricatorApplicationSearchEngine', 4042 4050 'AlmanacDeviceTransaction' => 'AlmanacTransaction', 4043 4051 'AlmanacDeviceTransactionQuery' => 'PhabricatorApplicationTransactionQuery', ··· 4052 4060 'AlmanacInterfaceDatasource' => 'PhabricatorTypeaheadDatasource', 4053 4061 'AlmanacInterfaceEditController' => 'AlmanacDeviceController', 4054 4062 'AlmanacInterfacePHIDType' => 'PhabricatorPHIDType', 4055 - 'AlmanacInterfaceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4063 + 'AlmanacInterfaceQuery' => 'AlmanacQuery', 4056 4064 'AlmanacInterfaceTableView' => 'AphrontView', 4057 4065 'AlmanacKeys' => 'Phobject', 4058 4066 'AlmanacManagementLockWorkflow' => 'AlmanacManagementWorkflow', ··· 4098 4106 'AlmanacNetworkListController' => 'AlmanacNetworkController', 4099 4107 'AlmanacNetworkNameNgrams' => 'PhabricatorSearchNgrams', 4100 4108 'AlmanacNetworkPHIDType' => 'PhabricatorPHIDType', 4101 - 'AlmanacNetworkQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4109 + 'AlmanacNetworkQuery' => 'AlmanacQuery', 4102 4110 'AlmanacNetworkSearchEngine' => 'PhabricatorApplicationSearchEngine', 4103 4111 'AlmanacNetworkTransaction' => 'PhabricatorApplicationTransaction', 4104 4112 'AlmanacNetworkTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 4105 4113 'AlmanacNetworkViewController' => 'AlmanacNetworkController', 4106 4114 'AlmanacPropertiesDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension', 4115 + 'AlmanacPropertiesSearchEngineAttachment' => 'AlmanacSearchEngineAttachment', 4107 4116 'AlmanacProperty' => array( 4108 4117 'AlmanacDAO', 4109 4118 'PhabricatorPolicyInterface', 4110 4119 ), 4111 4120 'AlmanacPropertyController' => 'AlmanacController', 4112 - 'AlmanacPropertyDeleteController' => 'AlmanacDeviceController', 4113 - 'AlmanacPropertyEditController' => 'AlmanacDeviceController', 4121 + 'AlmanacPropertyDeleteController' => 'AlmanacPropertyController', 4122 + 'AlmanacPropertyEditController' => 'AlmanacPropertyController', 4114 4123 'AlmanacPropertyEditEngine' => 'PhabricatorEditEngine', 4115 4124 'AlmanacPropertyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4116 4125 'AlmanacQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 4117 4126 'AlmanacQueryDevicesConduitAPIMethod' => 'AlmanacConduitAPIMethod', 4118 4127 'AlmanacQueryServicesConduitAPIMethod' => 'AlmanacConduitAPIMethod', 4119 4128 'AlmanacSchemaSpec' => 'PhabricatorConfigSchemaSpec', 4129 + 'AlmanacSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment', 4120 4130 'AlmanacService' => array( 4121 4131 'AlmanacDAO', 4122 4132 'PhabricatorPolicyInterface', ··· 4125 4135 'AlmanacPropertyInterface', 4126 4136 'PhabricatorDestructibleInterface', 4127 4137 'PhabricatorNgramsInterface', 4138 + 'PhabricatorConduitResultInterface', 4128 4139 ), 4129 4140 'AlmanacServiceController' => 'AlmanacController', 4130 4141 'AlmanacServiceDatasource' => 'PhabricatorTypeaheadDatasource', ··· 4135 4146 'AlmanacServicePHIDType' => 'PhabricatorPHIDType', 4136 4147 'AlmanacServicePropertyEditEngine' => 'AlmanacPropertyEditEngine', 4137 4148 'AlmanacServiceQuery' => 'AlmanacQuery', 4149 + 'AlmanacServiceSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 4138 4150 'AlmanacServiceSearchEngine' => 'PhabricatorApplicationSearchEngine', 4139 4151 'AlmanacServiceTransaction' => 'AlmanacTransaction', 4140 4152 'AlmanacServiceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
+1 -1
src/applications/almanac/conduit/AlmanacConduitAPIMethod.php
··· 8 8 } 9 9 10 10 public function getMethodStatus() { 11 - return self::METHOD_STATUS_UNSTABLE; 11 + return self::METHOD_STATUS_DEPRECATED; 12 12 } 13 13 14 14 public function getMethodStatusDescription() {
+18
src/applications/almanac/conduit/AlmanacDeviceSearchConduitAPIMethod.php
··· 1 + <?php 2 + 3 + final class AlmanacDeviceSearchConduitAPIMethod 4 + extends PhabricatorSearchEngineAPIMethod { 5 + 6 + public function getAPIMethodName() { 7 + return 'almanac.device.search'; 8 + } 9 + 10 + public function newSearchEngine() { 11 + return new AlmanacDeviceSearchEngine(); 12 + } 13 + 14 + public function getMethodSummary() { 15 + return pht('Read information about Almanac devices.'); 16 + } 17 + 18 + }
+18
src/applications/almanac/conduit/AlmanacServiceSearchConduitAPIMethod.php
··· 1 + <?php 2 + 3 + final class AlmanacServiceSearchConduitAPIMethod 4 + extends PhabricatorSearchEngineAPIMethod { 5 + 6 + public function getAPIMethodName() { 7 + return 'almanac.service.search'; 8 + } 9 + 10 + public function newSearchEngine() { 11 + return new AlmanacServiceSearchEngine(); 12 + } 13 + 14 + public function getMethodSummary() { 15 + return pht('Read information about Almanac services.'); 16 + } 17 + 18 + }
+1
src/applications/almanac/controller/AlmanacBindingViewController.php
··· 15 15 $binding = id(new AlmanacBindingQuery()) 16 16 ->setViewer($viewer) 17 17 ->withIDs(array($id)) 18 + ->needProperties(true) 18 19 ->executeOne(); 19 20 if (!$binding) { 20 21 return new Aphront404Response();
+1
src/applications/almanac/controller/AlmanacDeviceViewController.php
··· 15 15 $device = id(new AlmanacDeviceQuery()) 16 16 ->setViewer($viewer) 17 17 ->withNames(array($name)) 18 + ->needProperties(true) 18 19 ->executeOne(); 19 20 if (!$device) { 20 21 return new Aphront404Response();
+54 -1
src/applications/almanac/controller/AlmanacPropertyController.php
··· 1 1 <?php 2 2 3 - abstract class AlmanacPropertyController extends AlmanacController {} 3 + abstract class AlmanacPropertyController extends AlmanacController { 4 + 5 + private $propertyObject; 6 + 7 + public function getPropertyObject() { 8 + return $this->propertyObject; 9 + } 10 + 11 + protected function loadPropertyObject() { 12 + $viewer = $this->getViewer(); 13 + $request = $this->getRequest(); 14 + $object_phid = $request->getStr('objectPHID'); 15 + 16 + 17 + switch (phid_get_type($object_phid)) { 18 + case AlmanacBindingPHIDType::TYPECONST: 19 + $query = new AlmanacBindingQuery(); 20 + break; 21 + case AlmanacDevicePHIDType::TYPECONST: 22 + $query = new AlmanacDeviceQuery(); 23 + break; 24 + case AlmanacServicePHIDType::TYPECONST: 25 + $query = new AlmanacServiceQuery(); 26 + break; 27 + default: 28 + return new Aphront404Response(); 29 + } 30 + 31 + $object = $query 32 + ->setViewer($viewer) 33 + ->withPHIDs(array($object_phid)) 34 + ->requireCapabilities( 35 + array( 36 + PhabricatorPolicyCapability::CAN_VIEW, 37 + PhabricatorPolicyCapability::CAN_EDIT, 38 + )) 39 + ->needProperties(true) 40 + ->executeOne(); 41 + 42 + if (!$object) { 43 + return new Aphront404Response(); 44 + } 45 + 46 + if (!($object instanceof AlmanacPropertyInterface)) { 47 + return new Aphront404Response(); 48 + } 49 + 50 + $this->propertyObject = $object; 51 + 52 + return null; 53 + } 54 + 55 + 56 + }
+5 -15
src/applications/almanac/controller/AlmanacPropertyDeleteController.php
··· 1 1 <?php 2 2 3 3 final class AlmanacPropertyDeleteController 4 - extends AlmanacDeviceController { 4 + extends AlmanacPropertyController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $request->getViewer(); 8 8 9 - $object = id(new PhabricatorObjectQuery()) 10 - ->setViewer($viewer) 11 - ->withPHIDs(array($request->getStr('objectPHID'))) 12 - ->requireCapabilities( 13 - array( 14 - PhabricatorPolicyCapability::CAN_VIEW, 15 - PhabricatorPolicyCapability::CAN_EDIT, 16 - )) 17 - ->executeOne(); 18 - if (!$object) { 19 - return new Aphront404Response(); 9 + $response = $this->loadPropertyObject(); 10 + if ($response) { 11 + return $response; 20 12 } 21 13 22 - if (!($object instanceof AlmanacPropertyInterface)) { 23 - return new Aphront404Response(); 24 - } 14 + $object = $this->getPropertyObject(); 25 15 26 16 $key = $request->getStr('key'); 27 17 if (!strlen($key)) {
+5 -15
src/applications/almanac/controller/AlmanacPropertyEditController.php
··· 1 1 <?php 2 2 3 3 final class AlmanacPropertyEditController 4 - extends AlmanacDeviceController { 4 + extends AlmanacPropertyController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 7 $viewer = $request->getViewer(); 8 8 9 - $object = id(new PhabricatorObjectQuery()) 10 - ->setViewer($viewer) 11 - ->withPHIDs(array($request->getStr('objectPHID'))) 12 - ->requireCapabilities( 13 - array( 14 - PhabricatorPolicyCapability::CAN_VIEW, 15 - PhabricatorPolicyCapability::CAN_EDIT, 16 - )) 17 - ->executeOne(); 18 - if (!$object) { 19 - return new Aphront404Response(); 9 + $response = $this->loadPropertyObject(); 10 + if ($response) { 11 + return $response; 20 12 } 21 13 22 - if (!($object instanceof AlmanacPropertyInterface)) { 23 - return new Aphront404Response(); 24 - } 14 + $object = $this->getPropertyObject(); 25 15 26 16 $cancel_uri = $object->getURI(); 27 17 $property_key = $request->getStr('key');
+1
src/applications/almanac/controller/AlmanacServiceViewController.php
··· 15 15 $service = id(new AlmanacServiceQuery()) 16 16 ->setViewer($viewer) 17 17 ->withNames(array($name)) 18 + ->needProperties(true) 18 19 ->executeOne(); 19 20 if (!$service) { 20 21 return new Aphront404Response();
+30
src/applications/almanac/engineextension/AlmanacBindingsSearchEngineAttachment.php
··· 1 + <?php 2 + 3 + final class AlmanacBindingsSearchEngineAttachment 4 + extends AlmanacSearchEngineAttachment { 5 + 6 + public function getAttachmentName() { 7 + return pht('Almanac Bindings'); 8 + } 9 + 10 + public function getAttachmentDescription() { 11 + return pht('Get Almanac bindings for the service.'); 12 + } 13 + 14 + public function willLoadAttachmentData($query, $spec) { 15 + $query->needProperties(true); 16 + $query->needBindings(true); 17 + } 18 + 19 + public function getAttachmentForObject($object, $data, $spec) { 20 + $bindings = array(); 21 + foreach ($object->getBindings() as $binding) { 22 + $bindings[] = $this->getAlmanacBindingDictionary($binding); 23 + } 24 + 25 + return array( 26 + 'bindings' => $bindings, 27 + ); 28 + } 29 + 30 + }
+26
src/applications/almanac/engineextension/AlmanacPropertiesSearchEngineAttachment.php
··· 1 + <?php 2 + 3 + final class AlmanacPropertiesSearchEngineAttachment 4 + extends AlmanacSearchEngineAttachment { 5 + 6 + public function getAttachmentName() { 7 + return pht('Almanac Properties'); 8 + } 9 + 10 + public function getAttachmentDescription() { 11 + return pht('Get Almanac properties for the object.'); 12 + } 13 + 14 + public function willLoadAttachmentData($query, $spec) { 15 + $query->needProperties(true); 16 + } 17 + 18 + public function getAttachmentForObject($object, $data, $spec) { 19 + $properties = $this->getAlmanacPropertyList($object); 20 + 21 + return array( 22 + 'properties' => $properties, 23 + ); 24 + } 25 + 26 + }
+64
src/applications/almanac/engineextension/AlmanacSearchEngineAttachment.php
··· 1 + <?php 2 + 3 + abstract class AlmanacSearchEngineAttachment 4 + extends PhabricatorSearchEngineAttachment { 5 + 6 + protected function getAlmanacPropertyList($object) { 7 + $builtins = $object->getAlmanacPropertyFieldSpecifications(); 8 + 9 + $properties = array(); 10 + foreach ($object->getAlmanacProperties() as $key => $property) { 11 + $is_builtin = isset($builtins[$key]); 12 + 13 + $properties[] = array( 14 + 'key' => $key, 15 + 'value' => $property->getFieldValue(), 16 + 'builtin' => $is_builtin, 17 + ); 18 + } 19 + 20 + return $properties; 21 + } 22 + 23 + protected function getAlmanacBindingDictionary(AlmanacBinding $binding) { 24 + $interface = $binding->getInterface(); 25 + 26 + return array( 27 + 'id' => (int)$binding->getID(), 28 + 'phid' => $binding->getPHID(), 29 + 'properties' => $this->getAlmanacPropertyList($binding), 30 + 'interface' => $this->getAlmanacInterfaceDictionary($interface), 31 + ); 32 + } 33 + 34 + protected function getAlmanacInterfaceDictionary( 35 + AlmanacInterface $interface) { 36 + 37 + return array( 38 + 'id' => (int)$interface->getID(), 39 + 'phid' => $interface->getPHID(), 40 + 'address' => $interface->getAddress(), 41 + 'port' => (int)$interface->getPort(), 42 + 'device' => $this->getAlmanacDeviceDictionary($interface->getDevice()), 43 + 'network' => $this->getAlmanacNetworkDictionary($interface->getNetwork()), 44 + ); 45 + } 46 + 47 + protected function getAlmanacDeviceDictionary(AlmanacDevice $device) { 48 + return array( 49 + 'id' => (int)$device->getID(), 50 + 'phid' => $device->getPHID(), 51 + 'name' => $device->getName(), 52 + 'properties' => $this->getAlmanacPropertyList($device), 53 + ); 54 + } 55 + 56 + protected function getAlmanacNetworkDictionary(AlmanacNetwork $network) { 57 + return array( 58 + 'id' => (int)$network->getID(), 59 + 'phid' => $network->getPHID(), 60 + 'name' => $network->getName(), 61 + ); 62 + } 63 + 64 + }
+16 -22
src/applications/almanac/query/AlmanacBindingQuery.php
··· 34 34 return $this; 35 35 } 36 36 37 - protected function loadPage() { 38 - $table = new AlmanacBinding(); 39 - $conn_r = $table->establishConnection('r'); 37 + public function newResultObject() { 38 + return new AlmanacBinding(); 39 + } 40 40 41 - $data = queryfx_all( 42 - $conn_r, 43 - 'SELECT * FROM %T %Q %Q %Q', 44 - $table->getTableName(), 45 - $this->buildWhereClause($conn_r), 46 - $this->buildOrderClause($conn_r), 47 - $this->buildLimitClause($conn_r)); 48 - 49 - return $table->loadAllFromArray($data); 41 + protected function loadPage() { 42 + return $this->loadStandardPage($this->newResultObject()); 50 43 } 51 44 52 45 protected function willFilterPage(array $bindings) { ··· 58 51 ->setParentQuery($this) 59 52 ->setViewer($this->getViewer()) 60 53 ->withPHIDs($service_phids) 54 + ->needProperties($this->getNeedProperties()) 61 55 ->execute(); 62 56 $services = mpull($services, null, 'getPHID'); 63 57 ··· 65 59 ->setParentQuery($this) 66 60 ->setViewer($this->getViewer()) 67 61 ->withPHIDs($device_phids) 62 + ->needProperties($this->getNeedProperties()) 68 63 ->execute(); 69 64 $devices = mpull($devices, null, 'getPHID'); 70 65 ··· 72 67 ->setParentQuery($this) 73 68 ->setViewer($this->getViewer()) 74 69 ->withPHIDs($interface_phids) 70 + ->needProperties($this->getNeedProperties()) 75 71 ->execute(); 76 72 $interfaces = mpull($interfaces, null, 'getPHID'); 77 73 ··· 93 89 return $bindings; 94 90 } 95 91 96 - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 97 - $where = array(); 92 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 93 + $where = parent::buildWhereClauseParts($conn); 98 94 99 95 if ($this->ids !== null) { 100 96 $where[] = qsprintf( 101 - $conn_r, 97 + $conn, 102 98 'id IN (%Ld)', 103 99 $this->ids); 104 100 } 105 101 106 102 if ($this->phids !== null) { 107 103 $where[] = qsprintf( 108 - $conn_r, 104 + $conn, 109 105 'phid IN (%Ls)', 110 106 $this->phids); 111 107 } 112 108 113 109 if ($this->servicePHIDs !== null) { 114 110 $where[] = qsprintf( 115 - $conn_r, 111 + $conn, 116 112 'servicePHID IN (%Ls)', 117 113 $this->servicePHIDs); 118 114 } 119 115 120 116 if ($this->devicePHIDs !== null) { 121 117 $where[] = qsprintf( 122 - $conn_r, 118 + $conn, 123 119 'devicePHID IN (%Ls)', 124 120 $this->devicePHIDs); 125 121 } 126 122 127 123 if ($this->interfacePHIDs !== null) { 128 124 $where[] = qsprintf( 129 - $conn_r, 125 + $conn, 130 126 'interfacePHID IN (%Ls)', 131 127 $this->interfacePHIDs); 132 128 } 133 129 134 - $where[] = $this->buildPagingClause($conn_r); 135 - 136 - return $this->formatWhereClause($where); 130 + return $where; 137 131 } 138 132 139 133 }
+8
src/applications/almanac/query/AlmanacDeviceSearchEngine.php
··· 21 21 ->setLabel(pht('Name Contains')) 22 22 ->setKey('match') 23 23 ->setDescription(pht('Search for devices by name substring.')), 24 + id(new PhabricatorSearchStringListField()) 25 + ->setLabel(pht('Exact Names')) 26 + ->setKey('names') 27 + ->setDescription(pht('Search for devices with specific names.')), 24 28 ); 25 29 } 26 30 ··· 29 33 30 34 if ($map['match'] !== null) { 31 35 $query->withNameNgrams($map['match']); 36 + } 37 + 38 + if ($map['names']) { 39 + $query->withNames($map['names']); 32 40 } 33 41 34 42 return $query;
+3 -1
src/applications/almanac/query/AlmanacInterfaceQuery.php
··· 1 1 <?php 2 2 3 3 final class AlmanacInterfaceQuery 4 - extends PhabricatorCursorPagedPolicyAwareQuery { 4 + extends AlmanacQuery { 5 5 6 6 private $ids; 7 7 private $phids; ··· 50 50 ->setParentQuery($this) 51 51 ->setViewer($this->getViewer()) 52 52 ->withPHIDs($network_phids) 53 + ->needProperties($this->getNeedProperties()) 53 54 ->execute(); 54 55 $networks = mpull($networks, null, 'getPHID'); 55 56 ··· 57 58 ->setParentQuery($this) 58 59 ->setViewer($this->getViewer()) 59 60 ->withPHIDs($device_phids) 61 + ->needProperties($this->getNeedProperties()) 60 62 ->execute(); 61 63 $devices = mpull($devices, null, 'getPHID'); 62 64
+1 -1
src/applications/almanac/query/AlmanacNetworkQuery.php
··· 1 1 <?php 2 2 3 3 final class AlmanacNetworkQuery 4 - extends PhabricatorCursorPagedPolicyAwareQuery { 4 + extends AlmanacQuery { 5 5 6 6 private $ids; 7 7 private $phids;
+34 -36
src/applications/almanac/query/AlmanacPropertyQuery.php
··· 5 5 6 6 private $ids; 7 7 private $objectPHIDs; 8 + private $objects; 8 9 private $names; 9 - private $disablePolicyFilteringAndAttachment; 10 10 11 11 public function withIDs(array $ids) { 12 12 $this->ids = $ids; ··· 18 18 return $this; 19 19 } 20 20 21 - public function withNames(array $names) { 22 - $this->names = $names; 21 + public function withObjects(array $objects) { 22 + $this->objects = mpull($objects, null, 'getPHID'); 23 + $this->objectPHIDs = array_keys($this->objects); 23 24 return $this; 24 25 } 25 26 26 - public function setDisablePolicyFilteringAndAttachment($disable) { 27 - $this->disablePolicyFilteringAndAttachment = $disable; 27 + public function withNames(array $names) { 28 + $this->names = $names; 28 29 return $this; 29 30 } 30 31 31 - protected function shouldDisablePolicyFiltering() { 32 - return $this->disablePolicyFilteringAndAttachment; 32 + public function newResultObject() { 33 + return new AlmanacProperty(); 33 34 } 34 35 35 36 protected function loadPage() { 36 - $table = new AlmanacProperty(); 37 - $conn_r = $table->establishConnection('r'); 38 - 39 - $data = queryfx_all( 40 - $conn_r, 41 - 'SELECT * FROM %T %Q %Q %Q', 42 - $table->getTableName(), 43 - $this->buildWhereClause($conn_r), 44 - $this->buildOrderClause($conn_r), 45 - $this->buildLimitClause($conn_r)); 46 - 47 - return $table->loadAllFromArray($data); 37 + return $this->loadStandardPage($this->newResultObject()); 48 38 } 49 39 50 40 protected function willFilterPage(array $properties) { 51 - if (!$this->disablePolicyFilteringAndAttachment) { 52 - $object_phids = mpull($properties, 'getObjectPHID'); 41 + $object_phids = mpull($properties, 'getObjectPHID'); 53 42 43 + $object_phids = array_fuse($object_phids); 44 + 45 + if ($this->objects !== null) { 46 + $object_phids = array_diff_key($object_phids, $this->objects); 47 + } 48 + 49 + if ($object_phids) { 54 50 $objects = id(new PhabricatorObjectQuery()) 55 51 ->setViewer($this->getViewer()) 56 52 ->setParentQuery($this) 57 53 ->withPHIDs($object_phids) 58 54 ->execute(); 59 55 $objects = mpull($objects, null, 'getPHID'); 56 + } else { 57 + $objects = array(); 58 + } 60 59 61 - foreach ($properties as $key => $property) { 62 - $object = idx($objects, $property->getObjectPHID()); 63 - if (!$object) { 64 - unset($properties[$key]); 65 - continue; 66 - } 67 - $property->attachObject($object); 60 + $objects += $this->objects; 61 + 62 + foreach ($properties as $key => $property) { 63 + $object = idx($objects, $property->getObjectPHID()); 64 + if (!$object) { 65 + unset($properties[$key]); 66 + continue; 68 67 } 68 + $property->attachObject($object); 69 69 } 70 70 71 71 return $properties; 72 72 } 73 73 74 - protected function buildWhereClause(AphrontDatabaseConnection $conn_r) { 75 - $where = array(); 74 + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { 75 + $where = parent::buildWhereClauseParts($conn); 76 76 77 77 if ($this->ids !== null) { 78 78 $where[] = qsprintf( 79 - $conn_r, 79 + $conn, 80 80 'id IN (%Ld)', 81 81 $this->ids); 82 82 } 83 83 84 84 if ($this->objectPHIDs !== null) { 85 85 $where[] = qsprintf( 86 - $conn_r, 86 + $conn, 87 87 'objectPHID IN (%Ls)', 88 88 $this->objectPHIDs); 89 89 } ··· 94 94 $hashes[] = PhabricatorHash::digestForIndex($name); 95 95 } 96 96 $where[] = qsprintf( 97 - $conn_r, 97 + $conn, 98 98 'fieldIndex IN (%Ls)', 99 99 $hashes); 100 100 } 101 101 102 - $where[] = $this->buildPagingClause($conn_r); 103 - 104 - return $this->formatWhereClause($where); 102 + return $where; 105 103 } 106 104 107 105 public function getQueryApplicationClass() {
+14 -10
src/applications/almanac/query/AlmanacQuery.php
··· 3 3 abstract class AlmanacQuery 4 4 extends PhabricatorCursorPagedPolicyAwareQuery { 5 5 6 + private $needProperties; 7 + 8 + public function needProperties($need_properties) { 9 + $this->needProperties = $need_properties; 10 + return $this; 11 + } 12 + 13 + protected function getNeedProperties() { 14 + return $this->needProperties; 15 + } 16 + 6 17 protected function didFilterPage(array $objects) { 7 - if (head($objects) instanceof AlmanacPropertyInterface) { 8 - // NOTE: We load properties for obsolete historical reasons. It may make 9 - // sense to re-examine that assumption shortly. 18 + $has_properties = (head($objects) instanceof AlmanacPropertyInterface); 10 19 20 + if ($has_properties && $this->needProperties) { 11 21 $property_query = id(new AlmanacPropertyQuery()) 12 22 ->setViewer($this->getViewer()) 13 23 ->setParentQuery($this) 14 - ->withObjectPHIDs(mpull($objects, 'getPHID')); 15 - 16 - // NOTE: We disable policy filtering and object attachment to avoid 17 - // a cyclic dependency where objects need their properties and properties 18 - // need their objects. We'll attach the objects below, and have already 19 - // implicitly checked the necessary policies. 20 - $property_query->setDisablePolicyFilteringAndAttachment(true); 24 + ->withObjects($objects); 21 25 22 26 $properties = $property_query->execute(); 23 27
+6 -1
src/applications/almanac/query/AlmanacServiceQuery.php
··· 65 65 return $this; 66 66 } 67 67 68 + public function newResultObject() { 69 + return new AlmanacService(); 70 + } 71 + 68 72 protected function loadPage() { 69 - return $this->loadStandardPage(new AlmanacService()); 73 + return $this->loadStandardPage($this->newResultObject()); 70 74 } 71 75 72 76 protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) { ··· 172 176 $bindings = id(new AlmanacBindingQuery()) 173 177 ->setViewer($this->getViewer()) 174 178 ->withServicePHIDs($service_phids) 179 + ->needProperties($this->getNeedProperties()) 175 180 ->execute(); 176 181 $bindings = mgroup($bindings, 'getServicePHID'); 177 182
+17
src/applications/almanac/query/AlmanacServiceSearchEngine.php
··· 26 26 $query->withNameNgrams($map['match']); 27 27 } 28 28 29 + if ($map['names']) { 30 + $query->withNames($map['names']); 31 + } 32 + 33 + if ($map['devicePHIDs']) { 34 + $query->withDevicePHIDs($map['devicePHIDs']); 35 + } 36 + 29 37 return $query; 30 38 } 31 39 ··· 36 44 ->setLabel(pht('Name Contains')) 37 45 ->setKey('match') 38 46 ->setDescription(pht('Search for services by name substring.')), 47 + id(new PhabricatorSearchStringListField()) 48 + ->setLabel(pht('Exact Names')) 49 + ->setKey('names') 50 + ->setDescription(pht('Search for services with specific names.')), 51 + id(new PhabricatorPHIDsSearchField()) 52 + ->setLabel(pht('Devices')) 53 + ->setKey('devicePHIDs') 54 + ->setDescription( 55 + pht('Search for services bound to particular devices.')), 39 56 ); 40 57 } 41 58
+28 -1
src/applications/almanac/storage/AlmanacDevice.php
··· 9 9 PhabricatorSSHPublicKeyInterface, 10 10 AlmanacPropertyInterface, 11 11 PhabricatorDestructibleInterface, 12 - PhabricatorNgramsInterface { 12 + PhabricatorNgramsInterface, 13 + PhabricatorConduitResultInterface { 13 14 14 15 protected $name; 15 16 protected $nameIndex; ··· 240 241 return array( 241 242 id(new AlmanacDeviceNameNgrams()) 242 243 ->setValue($this->getName()), 244 + ); 245 + } 246 + 247 + 248 + /* -( PhabricatorConduitResultInterface )---------------------------------- */ 249 + 250 + 251 + public function getFieldSpecificationsForConduit() { 252 + return array( 253 + id(new PhabricatorConduitSearchFieldSpecification()) 254 + ->setKey('name') 255 + ->setType('string') 256 + ->setDescription(pht('The name of the device.')), 257 + ); 258 + } 259 + 260 + public function getFieldValuesForConduit() { 261 + return array( 262 + 'name' => $this->getName(), 263 + ); 264 + } 265 + 266 + public function getConduitSearchAttachments() { 267 + return array( 268 + id(new AlmanacPropertiesSearchEngineAttachment()) 269 + ->setAttachmentKey('properties'), 243 270 ); 244 271 } 245 272
+30 -1
src/applications/almanac/storage/AlmanacService.php
··· 8 8 PhabricatorProjectInterface, 9 9 AlmanacPropertyInterface, 10 10 PhabricatorDestructibleInterface, 11 - PhabricatorNgramsInterface { 11 + PhabricatorNgramsInterface, 12 + PhabricatorConduitResultInterface { 12 13 13 14 protected $name; 14 15 protected $nameIndex; ··· 221 222 return array( 222 223 id(new AlmanacServiceNameNgrams()) 223 224 ->setValue($this->getName()), 225 + ); 226 + } 227 + 228 + 229 + /* -( PhabricatorConduitResultInterface )---------------------------------- */ 230 + 231 + 232 + public function getFieldSpecificationsForConduit() { 233 + return array( 234 + id(new PhabricatorConduitSearchFieldSpecification()) 235 + ->setKey('name') 236 + ->setType('string') 237 + ->setDescription(pht('The name of the service.')), 238 + ); 239 + } 240 + 241 + public function getFieldValuesForConduit() { 242 + return array( 243 + 'name' => $this->getName(), 244 + ); 245 + } 246 + 247 + public function getConduitSearchAttachments() { 248 + return array( 249 + id(new AlmanacPropertiesSearchEngineAttachment()) 250 + ->setAttachmentKey('properties'), 251 + id(new AlmanacBindingsSearchEngineAttachment()) 252 + ->setAttachmentKey('bindings'), 224 253 ); 225 254 } 226 255
+4
src/applications/search/field/PhabricatorSearchTextField.php
··· 15 15 return new AphrontFormTextControl(); 16 16 } 17 17 18 + protected function newConduitParameterType() { 19 + return new ConduitStringParameterType(); 20 + } 21 + 18 22 }