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

Partially move Releeph custom fields to PhabricatorCustomField

Summary:
Fixes T3661. Ref T3718. This makes Releeph custom fields extend PhabricatorCustomField so we can start moving over other pieces of infrastructure (rendering, storage, etc) to run through the same pathways. It's roughly the minimum amount of work required to be able to move forward.

NOTE: This removes per-project custom field selectors. Fields are now configured for an entire install. My understanding is that Facebook does not use this feature, and modern field infrastructure has moved away from selectors.

Test Plan: Viewed and edited projects, branches, and requests in Releeph. Grepped for removed config. Grepped for `field_selector`.

Reviewers: btrahan

Reviewed By: btrahan

CC: LegNeato, aran

Maniphest Tasks: T3661, T3718

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

+121 -63
+5 -1
src/__phutil_library_map__.php
··· 4141 4141 'ReleephDiffSizeFieldSpecification' => 'ReleephFieldSpecification', 4142 4142 'ReleephEvent' => 'ReleephDAO', 4143 4143 'ReleephFieldParseException' => 'Exception', 4144 - 'ReleephFieldSpecification' => 'PhabricatorMarkupInterface', 4144 + 'ReleephFieldSpecification' => 4145 + array( 4146 + 0 => 'PhabricatorCustomField', 4147 + 1 => 'PhabricatorMarkupInterface', 4148 + ), 4145 4149 'ReleephFieldSpecificationIncompleteException' => 'Exception', 4146 4150 'ReleephIntentFieldSpecification' => 'ReleephFieldSpecification', 4147 4151 'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification',
+33 -10
src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php
··· 12 12 } 13 13 14 14 public function getOptions() { 15 + 16 + $default_fields = array( 17 + new ReleephCommitMessageFieldSpecification(), 18 + new ReleephSummaryFieldSpecification(), 19 + new ReleephReasonFieldSpecification(), 20 + new ReleephAuthorFieldSpecification(), 21 + new ReleephRevisionFieldSpecification(), 22 + new ReleephRequestorFieldSpecification(), 23 + new ReleephSeverityFieldSpecification(), 24 + new ReleephOriginalCommitFieldSpecification(), 25 + new ReleephDiffMessageFieldSpecification(), 26 + new ReleephStatusFieldSpecification(), 27 + new ReleephIntentFieldSpecification(), 28 + new ReleephBranchCommitFieldSpecification(), 29 + new ReleephDiffSizeFieldSpecification(), 30 + new ReleephDiffChurnFieldSpecification(), 31 + ); 32 + 33 + $default = array(); 34 + foreach ($default_fields as $default_field) { 35 + $default[$default_field->getFieldKey()] = true; 36 + } 37 + 38 + foreach ($default as $key => $enabled) { 39 + $default[$key] = array( 40 + 'disabled' => !$enabled, 41 + ); 42 + } 43 + 44 + $custom_field_type = 'custom:PhabricatorCustomFieldConfigOptionType'; 45 + 15 46 return array( 16 47 $this->newOption('releeph.installed', 'bool', false) 17 48 ->setSummary(pht('Enable the Releeph application.')) ··· 26 57 "set of alpha testers at Facebook. For the time being you are ". 27 58 "strongly discouraged from relying on Releeph being at all ". 28 59 "stable.")), 29 - $this->newOption( 30 - 'releeph.field-selector', 31 - 'class', 32 - 'ReleephDefaultFieldSelector') 33 - ->setBaseClass('ReleephFieldSelector') 34 - ->setSummary(pht('Field selector class')) 35 - ->setDescription( 36 - pht( 37 - "Control which fields are available when making a new Releeph ". 38 - "request, and which are then shown in the Releeph UI.")), 60 + $this->newOption('releeph.fields', $custom_field_type, $default) 61 + ->setCustomData('ReleephFieldSpecification'), 39 62 $this->newOption( 40 63 'releeph.user-view', 41 64 'class',
-31
src/applications/releeph/controller/project/ReleephProjectEditController.php
··· 31 31 $test_paths = $this->getReleephProject()->getDetail('testPaths', array()); 32 32 } 33 33 34 - $field_selector = $request->getStr('fieldSelector', 35 - get_class($this->getReleephProject()->getReleephFieldSelector())); 36 - 37 34 $release_counter = $request->getInt( 38 35 'releaseCounter', 39 36 $this->getReleephProject()->getCurrentReleaseNumber()); ··· 82 79 ->setTrunkBranch($trunk_branch) 83 80 ->setDetail('pushers', $pusher_phids) 84 81 ->setDetail('pick_failure_instructions', $pick_failure_instructions) 85 - ->setDetail('field_selector', $field_selector) 86 82 ->setDetail('branchTemplate', $branch_template) 87 83 ->setDetail('commitWithAuthor', $commit_author) 88 84 ->setDetail('testPaths', $test_paths); ··· 214 210 ->setDatasource('/typeahead/common/users/') 215 211 ->setValue($pusher_tokens)); 216 212 217 - $field_selector_options = array(); 218 - $field_selector_symbols = id(new PhutilSymbolLoader()) 219 - ->setType('class') 220 - ->setConcreteOnly(true) 221 - ->setAncestorClass('ReleephFieldSelector') 222 - ->selectAndLoadSymbols(); 223 - foreach ($field_selector_symbols as $symbol) { 224 - $selector_name = $symbol['name']; 225 - $field_selector_options[$selector_name] = $selector_name; 226 - } 227 - 228 - $field_selector_blurb = pht( 229 - "If you you have additional information to render about Releeph ". 230 - "requests, or want to re-arrange the UI, implement a ". 231 - "<tt>ReleephFieldSelector</tt> and select it here."); 232 - 233 - $fields_inset = id(new AphrontFormInsetView()) 234 - ->setTitle(pht('Fields')) 235 - ->appendChild($field_selector_blurb) 236 - ->appendChild( 237 - id(new AphrontFormSelectControl()) 238 - ->setLabel(pht('Selector')) 239 - ->setName('fieldSelector') 240 - ->setValue($field_selector) 241 - ->setOptions($field_selector_options)); 242 - 243 213 $commit_author_inset = $this->buildCommitAuthorInset($commit_author); 244 214 245 215 // Build the Template inset ··· 276 246 ->setUser($request->getUser()) 277 247 ->appendChild($basic_inset) 278 248 ->appendChild($pushers_inset) 279 - ->appendChild($fields_inset) 280 249 ->appendChild($commit_author_inset) 281 250 ->appendChild($template_inset); 282 251
+1 -1
src/applications/releeph/controller/request/ReleephRequestEditController.php
··· 246 246 // Fields 247 247 foreach ($fields as $field) { 248 248 if ($field->isEditable()) { 249 - $control = $field->renderEditControl($request); 249 + $control = $field->renderReleephEditControl($request); 250 250 $form->appendChild($control); 251 251 } 252 252 }
+4
src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php
··· 5 5 6 6 private static $authorMap = array(); 7 7 8 + public function getFieldKey() { 9 + return 'author'; 10 + } 11 + 8 12 public function bulkLoad(array $releeph_requests) { 9 13 foreach ($releeph_requests as $releeph_request) { 10 14 $commit = $releeph_request->loadPhabricatorRepositoryCommit();
+4
src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php
··· 3 3 final class ReleephBranchCommitFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'commit'; 8 + } 9 + 6 10 public function getName() { 7 11 return 'Commit'; 8 12 }
+4
src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php
··· 3 3 final class ReleephCommitMessageFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'commit:apply'; 8 + } 9 + 6 10 public function getName() { 7 11 return '__only_for_commit_message!'; 8 12 }
+4
src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php
··· 8 8 const UPDATES_WEIGHT = 10; 9 9 const MAX_POINTS = 100; 10 10 11 + public function getFieldKey() { 12 + return 'churn'; 13 + } 14 + 11 15 public function getName() { 12 16 return 'Churn'; 13 17 }
+4
src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php
··· 3 3 final class ReleephDiffMessageFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'commit:message'; 8 + } 9 + 6 10 public function getName() { 7 11 return 'Message'; 8 12 }
+4
src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php
··· 11 11 const PATHS_WEIGHT = 30; 12 12 const MAX_POINTS = 1000; 13 13 14 + public function getFieldKey() { 15 + return 'commit:size'; 16 + } 17 + 14 18 public function getName() { 15 19 return 'Size'; 16 20 }
+2 -1
src/applications/releeph/field/specification/ReleephFieldSpecification.php
··· 1 1 <?php 2 2 3 3 abstract class ReleephFieldSpecification 4 + extends PhabricatorCustomField 4 5 implements PhabricatorMarkupInterface { 5 6 6 7 abstract public function getName(); ··· 83 84 84 85 /* -( Edit View )---------------------------------------------------------- */ 85 86 86 - public function renderEditControl(AphrontRequest $request) { 87 + public function renderReleephEditControl(AphrontRequest $request) { 87 88 throw new ReleephFieldSpecificationIncompleteException($this); 88 89 } 89 90
+4
src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php
··· 3 3 final class ReleephIntentFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'intent'; 8 + } 9 + 6 10 public function getName() { 7 11 return 'Intent'; 8 12 }
+1 -1
src/applications/releeph/field/specification/ReleephLevelFieldSpecification.php
··· 39 39 return $this->getNameForLevel($level); 40 40 } 41 41 42 - public function renderEditControl(AphrontRequest $request) { 42 + public function renderReleephEditControl(AphrontRequest $request) { 43 43 $control_name = $this->getRequiredStorageKey(); 44 44 $all_levels = $this->getLevels(); 45 45
+4
src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php
··· 3 3 final class ReleephOriginalCommitFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'commit:name'; 8 + } 9 + 6 10 public function getName() { 7 11 return 'Commit'; 8 12 }
+5 -1
src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php
··· 3 3 final class ReleephReasonFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'reason'; 8 + } 9 + 6 10 public function getName() { 7 11 return 'Reason'; 8 12 } ··· 31 35 32 36 private $error = true; 33 37 34 - public function renderEditControl(AphrontRequest $request) { 38 + public function renderReleephEditControl(AphrontRequest $request) { 35 39 $reason = $request->getStr('reason', $this->getValue()); 36 40 return id(new AphrontFormTextAreaControl()) 37 41 ->setLabel('Reason')
+4
src/applications/releeph/field/specification/ReleephRequestorFieldSpecification.php
··· 3 3 final class ReleephRequestorFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'requestor'; 8 + } 9 + 6 10 public function bulkLoad(array $releeph_requests) { 7 11 $phids = mpull($releeph_requests, 'getRequestUserPHID'); 8 12 ReleephUserView::getNewInstance()
+4
src/applications/releeph/field/specification/ReleephRevisionFieldSpecification.php
··· 3 3 final class ReleephRevisionFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'revision'; 8 + } 9 + 6 10 public function getName() { 7 11 return 'Revision'; 8 12 }
+5 -1
src/applications/releeph/field/specification/ReleephRiskFieldSpecification.php
··· 9 9 'HIGH' => 'This is pretty risky, but is also very important.', 10 10 ); 11 11 12 + public function getFieldKey() { 13 + return 'risk'; 14 + } 15 + 12 16 public function getName() { 13 17 return 'Riskiness'; 14 18 } ··· 23 27 24 28 private $error = true; 25 29 26 - public function renderEditControl(AphrontRequest $request) { 30 + public function renderReleephEditControl(AphrontRequest $request) { 27 31 $value = $request->getStr('risk', $this->getValue()); 28 32 $buttons = id(new AphrontFormRadioButtonControl()) 29 33 ->setLabel('Riskiness')
+4
src/applications/releeph/field/specification/ReleephSeverityFieldSpecification.php
··· 6 6 const HOTFIX = 'HOTFIX'; 7 7 const RELEASE = 'RELEASE'; 8 8 9 + public function getFieldKey() { 10 + return 'severity'; 11 + } 12 + 9 13 public function getName() { 10 14 return 'Severity'; 11 15 }
+4
src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php
··· 3 3 final class ReleephStatusFieldSpecification 4 4 extends ReleephFieldSpecification { 5 5 6 + public function getFieldKey() { 7 + return 'status'; 8 + } 9 + 6 10 public function getName() { 7 11 return 'Status'; 8 12 }
+5 -1
src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php
··· 5 5 6 6 const MAX_SUMMARY_LENGTH = 60; 7 7 8 + public function getFieldKey() { 9 + return 'summary'; 10 + } 11 + 8 12 public function getName() { 9 13 return 'Summary'; 10 14 } ··· 15 19 16 20 private $error = false; 17 21 18 - public function renderEditControl(AphrontRequest $request) { 22 + public function renderReleephEditControl(AphrontRequest $request) { 19 23 $summary = $request->getStr('summary', $this->getValue()); 20 24 return id(new AphrontFormTextControl()) 21 25 ->setLabel('Summary')
+1 -11
src/applications/releeph/storage/ReleephProject.php
··· 141 141 } 142 142 143 143 public function getReleephFieldSelector() { 144 - $class = $this->getDetail('field_selector'); 145 - if (!$class) { 146 - $key = 'releeph.field-selector'; 147 - $class = PhabricatorEnv::getEnvConfig($key); 148 - } 149 - 150 - if ($class) { 151 - return newv($class, array()); 152 - } else { 153 - return new ReleephDefaultFieldSelector(); 154 - } 144 + return new ReleephDefaultFieldSelector(); 155 145 } 156 146 157 147 /**
+12 -3
src/infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php
··· 3 3 final class PhabricatorCustomFieldImplementationIncompleteException 4 4 extends Exception { 5 5 6 - public function __construct(PhabricatorCustomField $field) { 7 - $key = $field->getFieldKey(); 8 - $name = $field->getFieldName(); 6 + public function __construct( 7 + PhabricatorCustomField $field, 8 + $field_key_is_incomplete = false) { 9 + 10 + if ($field_key_is_incomplete) { 11 + $key = pht('<incomplete key>'); 12 + $name = pht('<incomplete name>'); 13 + } else { 14 + $key = $field->getFieldKey(); 15 + $name = $field->getFieldName(); 16 + } 17 + 9 18 $class = get_class($field); 10 19 11 20 parent::__construct(
+3 -1
src/infrastructure/customfield/field/PhabricatorCustomField.php
··· 154 154 if ($this->proxy) { 155 155 return $this->proxy->getFieldKey(); 156 156 } 157 - throw new PhabricatorCustomFieldImplementationIncompleteException($this); 157 + throw new PhabricatorCustomFieldImplementationIncompleteException( 158 + $this, 159 + $field_key_is_incomplete = true); 158 160 } 159 161 160 162