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

Move Almanac Services to EditEngine

Summary: Ref T10449. This modernizes the service creation/editing flow and updates the list view code a little bit.

Test Plan:
- Created a service.
- Edited a service.
- Browsed services.
- Hit policy exception for editing cluster services with no permission.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10449

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

+151 -201
+2
src/__phutil_library_map__.php
··· 106 106 'AlmanacServiceController' => 'applications/almanac/controller/AlmanacServiceController.php', 107 107 'AlmanacServiceDatasource' => 'applications/almanac/typeahead/AlmanacServiceDatasource.php', 108 108 'AlmanacServiceEditController' => 'applications/almanac/controller/AlmanacServiceEditController.php', 109 + 'AlmanacServiceEditEngine' => 'applications/almanac/editor/AlmanacServiceEditEngine.php', 109 110 'AlmanacServiceEditor' => 'applications/almanac/editor/AlmanacServiceEditor.php', 110 111 'AlmanacServiceListController' => 'applications/almanac/controller/AlmanacServiceListController.php', 111 112 'AlmanacServiceNameNgrams' => 'applications/almanac/storage/AlmanacServiceNameNgrams.php', ··· 4145 4146 'AlmanacServiceController' => 'AlmanacController', 4146 4147 'AlmanacServiceDatasource' => 'PhabricatorTypeaheadDatasource', 4147 4148 'AlmanacServiceEditController' => 'AlmanacServiceController', 4149 + 'AlmanacServiceEditEngine' => 'PhabricatorEditEngine', 4148 4150 'AlmanacServiceEditor' => 'AlmanacEditor', 4149 4151 'AlmanacServiceListController' => 'AlmanacServiceController', 4150 4152 'AlmanacServiceNameNgrams' => 'PhabricatorSearchNgrams',
+1 -1
src/applications/almanac/application/PhabricatorAlmanacApplication.php
··· 45 45 '' => 'AlmanacConsoleController', 46 46 '(?P<objectType>service)/' => array( 47 47 $this->getQueryRoutePattern() => 'AlmanacServiceListController', 48 - 'edit/(?:(?P<id>\d+)/)?' => 'AlmanacServiceEditController', 48 + $this->getEditRoutePattern('edit/') => 'AlmanacServiceEditController', 49 49 'view/(?P<name>[^/]+)/' => 'AlmanacServiceViewController', 50 50 ), 51 51 '(?P<objectType>device)/' => array(
+5
src/applications/almanac/controller/AlmanacServiceController.php
··· 11 11 return $crumbs; 12 12 } 13 13 14 + public function buildApplicationMenu() { 15 + return $this->newApplicationMenu() 16 + ->setSearchEngine(new AlmanacServiceSearchEngine()); 17 + } 18 + 14 19 protected function getPropertyDeleteURI($object) { 15 20 $id = $object->getID(); 16 21 return "/almanac/service/delete/{$id}/";
+16 -168
src/applications/almanac/controller/AlmanacServiceEditController.php
··· 4 4 extends AlmanacServiceController { 5 5 6 6 public function handleRequest(AphrontRequest $request) { 7 - $viewer = $request->getViewer(); 8 - 9 - $list_uri = $this->getApplicationURI('service/'); 7 + $engine = id(new AlmanacServiceEditEngine()) 8 + ->setController($this); 10 9 11 10 $id = $request->getURIData('id'); 12 - if ($id) { 13 - $service = id(new AlmanacServiceQuery()) 14 - ->setViewer($viewer) 15 - ->withIDs(array($id)) 16 - ->requireCapabilities( 17 - array( 18 - PhabricatorPolicyCapability::CAN_VIEW, 19 - PhabricatorPolicyCapability::CAN_EDIT, 20 - )) 21 - ->executeOne(); 22 - if (!$service) { 23 - return new Aphront404Response(); 24 - } 25 - 26 - $is_new = false; 27 - $service_uri = $service->getURI(); 28 - $cancel_uri = $service_uri; 29 - $title = pht('Edit Service'); 30 - $save_button = pht('Save Changes'); 31 - } else { 32 - $cancel_uri = $list_uri; 33 - 11 + if (!$id) { 34 12 $this->requireApplicationCapability( 35 13 AlmanacCreateServicesCapability::CAPABILITY); 36 14 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); 43 - } 44 - 45 - if ($service->isClusterService()) { 46 - $this->requireApplicationCapability( 47 - AlmanacManageClusterServicesCapability::CAPABILITY); 48 - } 49 - 50 - $is_new = true; 51 - 52 - $title = pht('Create Service'); 53 - $save_button = pht('Create Service'); 54 - } 55 - 56 - $v_name = $service->getName(); 57 - $e_name = true; 58 - $validation_exception = null; 59 - 60 - if ($is_new) { 61 - $v_projects = array(); 62 - } else { 63 - $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs( 64 - $service->getPHID(), 65 - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); 66 - $v_projects = array_reverse($v_projects); 67 - } 68 - 69 - if ($request->isFormPost() && $request->getStr('edit')) { 70 - $v_name = $request->getStr('name'); 71 - $v_view = $request->getStr('viewPolicy'); 72 - $v_edit = $request->getStr('editPolicy'); 73 - $v_projects = $request->getArr('projects'); 74 - 75 - $type_name = AlmanacServiceTransaction::TYPE_NAME; 76 - $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY; 77 - $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY; 78 - 79 - $xactions = array(); 80 - 81 - $xactions[] = id(new AlmanacServiceTransaction()) 82 - ->setTransactionType($type_name) 83 - ->setNewValue($v_name); 84 - 85 - $xactions[] = id(new AlmanacServiceTransaction()) 86 - ->setTransactionType($type_view) 87 - ->setNewValue($v_view); 88 - 89 - $xactions[] = id(new AlmanacServiceTransaction()) 90 - ->setTransactionType($type_edit) 91 - ->setNewValue($v_edit); 92 - 93 - $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST; 94 - $xactions[] = id(new AlmanacServiceTransaction()) 95 - ->setTransactionType(PhabricatorTransactions::TYPE_EDGE) 96 - ->setMetadataValue('edge:type', $proj_edge_type) 97 - ->setNewValue(array('=' => array_fuse($v_projects))); 98 - 99 - $editor = id(new AlmanacServiceEditor()) 100 - ->setActor($viewer) 101 - ->setContentSourceFromRequest($request) 102 - ->setContinueOnNoEffect(true); 103 - 104 - try { 105 - $editor->applyTransactions($service, $xactions); 15 + $list_uri = $this->getApplicationURI('service/'); 106 16 107 - $service_uri = $service->getURI(); 108 - return id(new AphrontRedirectResponse())->setURI($service_uri); 109 - } catch (PhabricatorApplicationTransactionValidationException $ex) { 110 - $validation_exception = $ex; 111 - $e_name = $ex->getShortMessage($type_name); 112 - 113 - $service->setViewPolicy($v_view); 114 - $service->setEditPolicy($v_edit); 17 + $service_type = $request->getStr('serviceType'); 18 + $service_types = AlmanacServiceType::getAllServiceTypes(); 19 + if (empty($service_types[$service_type])) { 20 + return $this->buildServiceTypeResponse($list_uri); 115 21 } 116 - } 117 22 118 - $policies = id(new PhabricatorPolicyQuery()) 119 - ->setViewer($viewer) 120 - ->setObject($service) 121 - ->execute(); 122 - 123 - $form = id(new AphrontFormView()) 124 - ->setUser($viewer) 125 - ->addHiddenInput('edit', true) 126 - ->addHiddenInput('serviceType', $service->getServiceType()) 127 - ->appendChild( 128 - id(new AphrontFormTextControl()) 129 - ->setLabel(pht('Name')) 130 - ->setName('name') 131 - ->setValue($v_name) 132 - ->setError($e_name)) 133 - ->appendChild( 134 - id(new AphrontFormPolicyControl()) 135 - ->setName('viewPolicy') 136 - ->setPolicyObject($service) 137 - ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) 138 - ->setPolicies($policies)) 139 - ->appendChild( 140 - id(new AphrontFormPolicyControl()) 141 - ->setName('editPolicy') 142 - ->setPolicyObject($service) 143 - ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) 144 - ->setPolicies($policies)) 145 - ->appendControl( 146 - id(new AphrontFormTokenizerControl()) 147 - ->setLabel(pht('Projects')) 148 - ->setName('projects') 149 - ->setValue($v_projects) 150 - ->setDatasource(new PhabricatorProjectDatasource())) 151 - ->appendChild( 152 - id(new AphrontFormSubmitControl()) 153 - ->addCancelButton($cancel_uri) 154 - ->setValue($save_button)); 155 - 156 - $box = id(new PHUIObjectBoxView()) 157 - ->setValidationException($validation_exception) 158 - ->setHeaderText($title) 159 - ->appendChild($form); 160 - 161 - $crumbs = $this->buildApplicationCrumbs(); 162 - if ($is_new) { 163 - $crumbs->addTextCrumb(pht('Create Service')); 164 - } else { 165 - $crumbs->addTextCrumb($service->getName(), $service_uri); 166 - $crumbs->addTextCrumb(pht('Edit')); 23 + $engine 24 + ->addContextParameter('serviceType', $service_type) 25 + ->setServiceType($service_type); 167 26 } 168 27 169 - return $this->newPage() 170 - ->setTitle($title) 171 - ->setCrumbs($crumbs) 172 - ->appendChild( 173 - array( 174 - $box, 175 - )); 28 + return $engine->buildResponse(); 176 29 } 177 30 178 31 private function buildServiceTypeResponse($cancel_uri) { ··· 193 46 AlmanacManageClusterServicesCapability::CAPABILITY, 194 47 pht('You have permission to create cluster services.'), 195 48 pht('You do not have permission to create new cluster services.')); 196 - 197 49 198 50 $type_control = id(new AphrontFormRadioButtonControl()) 199 51 ->setLabel(pht('Service Type')) ··· 239 91 ->setHeaderText($title) 240 92 ->setForm($form); 241 93 242 - return $this->buildApplicationPage( 243 - array( 244 - $crumbs, 245 - $box, 246 - ), 247 - array( 248 - 'title' => $title, 249 - )); 94 + return $this->newPage() 95 + ->setTitle($title) 96 + ->setCrumbs($crumbs) 97 + ->appendChild($box); 250 98 } 251 99 252 100 }
+6 -32
src/applications/almanac/controller/AlmanacServiceListController.php
··· 8 8 } 9 9 10 10 public function handleRequest(AphrontRequest $request) { 11 - $controller = id(new PhabricatorApplicationSearchController()) 12 - ->setQueryKey($request->getURIData('queryKey')) 13 - ->setSearchEngine(new AlmanacServiceSearchEngine()) 14 - ->setNavigation($this->buildSideNavView()); 15 - 16 - return $this->delegateToController($controller); 11 + return id(new AlmanacServiceSearchEngine()) 12 + ->setController($this) 13 + ->buildResponse(); 17 14 } 18 15 19 16 protected function buildApplicationCrumbs() { 20 17 $crumbs = parent::buildApplicationCrumbs(); 21 18 22 - $can_create = $this->hasApplicationCapability( 23 - AlmanacCreateServicesCapability::CAPABILITY); 24 - 25 - $crumbs->addAction( 26 - id(new PHUIListItemView()) 27 - ->setName(pht('Create Service')) 28 - ->setHref($this->getApplicationURI('service/edit/')) 29 - ->setIcon('fa-plus-square') 30 - ->setDisabled(!$can_create) 31 - ->setWorkflow(!$can_create)); 19 + id(new AlmanacServiceEditEngine()) 20 + ->setViewer($this->getViewer()) 21 + ->addActionToCrumbs($crumbs); 32 22 33 23 return $crumbs; 34 24 } 35 - 36 - public function buildSideNavView() { 37 - $viewer = $this->getViewer(); 38 - 39 - $nav = new AphrontSideNavFilterView(); 40 - $nav->setBaseURI(new PhutilURI($this->getApplicationURI())); 41 - 42 - id(new AlmanacServiceSearchEngine()) 43 - ->setViewer($viewer) 44 - ->addNavigationItems($nav->getMenu()); 45 - 46 - $nav->selectFilter(null); 47 - 48 - return $nav; 49 - } 50 - 51 25 52 26 }
+97
src/applications/almanac/editor/AlmanacServiceEditEngine.php
··· 1 + <?php 2 + 3 + final class AlmanacServiceEditEngine 4 + extends PhabricatorEditEngine { 5 + 6 + const ENGINECONST = 'almanac.service'; 7 + 8 + private $serviceType; 9 + 10 + public function setServiceType($service_type) { 11 + $this->serviceType = $service_type; 12 + return $this; 13 + } 14 + 15 + public function getServiceType() { 16 + return $this->serviceType; 17 + } 18 + 19 + public function isEngineConfigurable() { 20 + return false; 21 + } 22 + 23 + public function getEngineName() { 24 + return pht('Almanac Services'); 25 + } 26 + 27 + public function getSummaryHeader() { 28 + return pht('Edit Almanac Service Configurations'); 29 + } 30 + 31 + public function getSummaryText() { 32 + return pht('This engine is used to edit Almanac services.'); 33 + } 34 + 35 + public function getEngineApplicationClass() { 36 + return 'PhabricatorAlmanacApplication'; 37 + } 38 + 39 + protected function newEditableObject() { 40 + $service_type = $this->getServiceType(); 41 + return AlmanacService::initializeNewService($service_type); 42 + } 43 + 44 + protected function newObjectQuery() { 45 + return new AlmanacServiceQuery(); 46 + } 47 + 48 + protected function getObjectCreateTitleText($object) { 49 + return pht('Create Service'); 50 + } 51 + 52 + protected function getObjectCreateButtonText($object) { 53 + return pht('Create Service'); 54 + } 55 + 56 + protected function getObjectEditTitleText($object) { 57 + return pht('Edit Service: %s', $object->getName()); 58 + } 59 + 60 + protected function getObjectEditShortText($object) { 61 + return pht('Edit Service'); 62 + } 63 + 64 + protected function getObjectCreateShortText() { 65 + return pht('Create Service'); 66 + } 67 + 68 + protected function getEditorURI() { 69 + return '/almanac/service/edit/'; 70 + } 71 + 72 + protected function getObjectCreateCancelURI($object) { 73 + return '/almanac/service/'; 74 + } 75 + 76 + protected function getObjectViewURI($object) { 77 + return $object->getURI(); 78 + } 79 + 80 + protected function getCreateNewObjectPolicy() { 81 + return $this->getApplication()->getPolicy( 82 + AlmanacCreateServicesCapability::CAPABILITY); 83 + } 84 + 85 + protected function buildCustomEditFields($object) { 86 + return array( 87 + id(new PhabricatorTextEditField()) 88 + ->setKey('name') 89 + ->setLabel(pht('Name')) 90 + ->setDescription(pht('Name of the service.')) 91 + ->setTransactionType(AlmanacServiceTransaction::TYPE_NAME) 92 + ->setIsRequired(true) 93 + ->setValue($object->getName()), 94 + ); 95 + } 96 + 97 + }
+24
src/applications/almanac/editor/AlmanacServiceEditor.php
··· 152 152 return $errors; 153 153 } 154 154 155 + 156 + protected function validateAllTransactions( 157 + PhabricatorLiskDAO $object, 158 + array $xactions) { 159 + 160 + $errors = parent::validateAllTransactions($object, $xactions); 161 + 162 + if ($object->isClusterService()) { 163 + $can_manage = PhabricatorPolicyFilter::hasCapability( 164 + $this->getActor(), 165 + new PhabricatorAlmanacApplication(), 166 + AlmanacManageClusterServicesCapability::CAPABILITY); 167 + if (!$can_manage) { 168 + $errors[] = new PhabricatorApplicationTransactionValidationError( 169 + null, 170 + pht('Restricted'), 171 + pht('You do not have permission to manage cluster services.'), 172 + null); 173 + } 174 + } 175 + 176 + return $errors; 177 + } 178 + 155 179 }