@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 "wild" config types to new code

Summary:
Ref T12845. This is the last of the hard-coded types.

These are mostly used for values which users don't directly edit, so it's largely OK that they aren't carefully validated. In some cases, it would be good to introduce a separate validator eventually.

Test Plan: Edited, deleted and mangled these values via the web UI and CLI.

Reviewers: chad, amckinley

Reviewed By: amckinley

Maniphest Tasks: T12845

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

+104 -60
+4
src/__phutil_library_map__.php
··· 3010 3010 'PhabricatorIteratedMD5PasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorIteratedMD5PasswordHasherTestCase.php', 3011 3011 'PhabricatorIteratorFileUploadSource' => 'applications/files/uploadsource/PhabricatorIteratorFileUploadSource.php', 3012 3012 'PhabricatorJIRAAuthProvider' => 'applications/auth/provider/PhabricatorJIRAAuthProvider.php', 3013 + 'PhabricatorJSONConfigType' => 'applications/config/type/PhabricatorJSONConfigType.php', 3013 3014 'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php', 3014 3015 'PhabricatorJiraIssueHasObjectEdgeType' => 'applications/doorkeeper/edge/PhabricatorJiraIssueHasObjectEdgeType.php', 3015 3016 'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php', ··· 4263 4264 'PhabricatorWebContentSource' => 'infrastructure/contentsource/PhabricatorWebContentSource.php', 4264 4265 'PhabricatorWebServerSetupCheck' => 'applications/config/check/PhabricatorWebServerSetupCheck.php', 4265 4266 'PhabricatorWeekStartDaySetting' => 'applications/settings/setting/PhabricatorWeekStartDaySetting.php', 4267 + 'PhabricatorWildConfigType' => 'applications/config/type/PhabricatorWildConfigType.php', 4266 4268 'PhabricatorWordPressAuthProvider' => 'applications/auth/provider/PhabricatorWordPressAuthProvider.php', 4267 4269 'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php', 4268 4270 'PhabricatorWorkerActiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php', ··· 8348 8350 'PhabricatorIteratedMD5PasswordHasherTestCase' => 'PhabricatorTestCase', 8349 8351 'PhabricatorIteratorFileUploadSource' => 'PhabricatorFileUploadSource', 8350 8352 'PhabricatorJIRAAuthProvider' => 'PhabricatorOAuth1AuthProvider', 8353 + 'PhabricatorJSONConfigType' => 'PhabricatorTextConfigType', 8351 8354 'PhabricatorJavelinLinter' => 'ArcanistLinter', 8352 8355 'PhabricatorJiraIssueHasObjectEdgeType' => 'PhabricatorEdgeType', 8353 8356 'PhabricatorJumpNavHandler' => 'Phobject', ··· 9839 9842 'PhabricatorWebContentSource' => 'PhabricatorContentSource', 9840 9843 'PhabricatorWebServerSetupCheck' => 'PhabricatorSetupCheck', 9841 9844 'PhabricatorWeekStartDaySetting' => 'PhabricatorSelectSetting', 9845 + 'PhabricatorWildConfigType' => 'PhabricatorJSONConfigType', 9842 9846 'PhabricatorWordPressAuthProvider' => 'PhabricatorOAuth2AuthProvider', 9843 9847 'PhabricatorWorker' => 'Phobject', 9844 9848 'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask',
+13 -53
src/applications/config/controller/PhabricatorConfigEditController.php
··· 325 325 $e_value = null; 326 326 $errors = array(); 327 327 328 - 329 328 if ($option->isCustomType()) { 330 329 $info = $option->getCustomObject()->readRequest($option, $request); 331 330 list($e_value, $errors, $set_value, $value) = $info; 332 331 } else { 333 - $value = $request->getStr('value'); 334 - if (!strlen($value)) { 335 - $value = null; 336 - 337 - $xaction->setNewValue( 338 - array( 339 - 'deleted' => true, 340 - 'value' => null, 341 - )); 342 - 343 - return array($e_value, $errors, $value, $xaction); 344 - } 345 - 346 - $type = $option->getType(); 347 - $set_value = null; 348 - 349 - switch ($type) { 350 - default: 351 - $json = json_decode($value, true); 352 - if ($json === null && strtolower($value) != 'null') { 353 - $e_value = pht('Invalid'); 354 - $errors[] = pht( 355 - 'The given value must be valid JSON. This means, among '. 356 - 'other things, that you must wrap strings in double-quotes.'); 357 - } else { 358 - $set_value = $json; 359 - } 360 - break; 361 - } 332 + throw new Exception( 333 + pht( 334 + 'Unknown configuration option type "%s".', 335 + $option->getType())); 362 336 } 363 337 364 338 if (!$errors) { ··· 389 363 $option, 390 364 $entry, 391 365 $value); 392 - } else { 393 - $type = $option->getType(); 394 - switch ($type) { 395 - default: 396 - return PhabricatorConfigJSON::prettyPrintJSON($value); 397 - } 398 366 } 367 + 368 + throw new Exception( 369 + pht( 370 + 'Unknown configuration option type "%s".', 371 + $option->getType())); 399 372 } 400 373 401 374 private function renderControls( ··· 417 390 $display_value, 418 391 $e_value); 419 392 } else { 420 - $type = $option->getType(); 421 - switch ($type) { 422 - default: 423 - $control = id(new AphrontFormTextAreaControl()) 424 - ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL) 425 - ->setCustomClass('PhabricatorMonospaced') 426 - ->setCaption(pht('Enter value in JSON.')); 427 - break; 428 - } 429 - 430 - $control 431 - ->setLabel(pht('Database Value')) 432 - ->setError($e_value) 433 - ->setValue($display_value) 434 - ->setName('value'); 435 - 436 - $controls = array($control); 393 + throw new Exception( 394 + pht( 395 + 'Unknown configuration option type "%s".', 396 + $option->getType())); 437 397 } 438 398 439 399 return $controls;
+1
src/applications/config/management/PhabricatorConfigManagementSetWorkflow.php
··· 70 70 throw new PhutilArgumentUsageException($ex->getMessage()); 71 71 } 72 72 } else { 73 + // NOTE: For now, this handles both "wild" values and custom types. 73 74 $type = $option->getType(); 74 75 switch ($type) { 75 76 default:
+8 -6
src/applications/config/option/PhabricatorApplicationConfigOptions.php
··· 24 24 if ($type) { 25 25 try { 26 26 $type->validateStoredValue($option, $value); 27 + $this->didValidateOption($option, $value); 27 28 } catch (PhabricatorConfigValidationException $ex) { 28 29 throw $ex; 29 30 } catch (Exception $ex) { ··· 32 33 // configuration and raise an error. 33 34 throw new PhabricatorConfigValidationException($ex->getMessage()); 34 35 } 36 + 37 + return; 35 38 } 36 39 37 40 if ($option->isCustomType()) { ··· 40 43 } catch (Exception $ex) { 41 44 throw new PhabricatorConfigValidationException($ex->getMessage()); 42 45 } 43 - } 44 - 45 - switch ($option->getType()) { 46 - case 'wild': 47 - default: 48 - break; 46 + } else { 47 + throw new Exception( 48 + pht( 49 + 'Unknown configuration option type "%s".', 50 + $option->getType())); 49 51 } 50 52 51 53 $this->didValidateOption($option, $value);
+38
src/applications/config/type/PhabricatorJSONConfigType.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorJSONConfigType 4 + extends PhabricatorTextConfigType { 5 + 6 + protected function newCanonicalValue( 7 + PhabricatorConfigOption $option, 8 + $value) { 9 + 10 + try { 11 + $value = phutil_json_decode($value); 12 + } catch (Exception $ex) { 13 + throw $this->newException( 14 + pht( 15 + 'Value for option "%s" (of type "%s") must be specified in JSON, '. 16 + 'but input could not be decoded: %s', 17 + $option->getKey(), 18 + $this->getTypeKey(), 19 + $ex->getMessage())); 20 + } 21 + 22 + return $value; 23 + } 24 + 25 + protected function newControl(PhabricatorConfigOption $option) { 26 + return id(new AphrontFormTextAreaControl()) 27 + ->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_TALL) 28 + ->setCustomClass('PhabricatorMonospaced') 29 + ->setCaption(pht('Enter value in JSON.')); 30 + } 31 + 32 + public function newDisplayValue( 33 + PhabricatorConfigOption $option, 34 + $value) { 35 + return PhabricatorConfigJSON::prettyPrintJSON($value); 36 + } 37 + 38 + }
+39
src/applications/config/type/PhabricatorWildConfigType.php
··· 1 + <?php 2 + 3 + final class PhabricatorWildConfigType 4 + extends PhabricatorJSONConfigType { 5 + 6 + const TYPEKEY = 'wild'; 7 + 8 + protected function newCanonicalValue( 9 + PhabricatorConfigOption $option, 10 + $value) { 11 + 12 + $raw_value = $value; 13 + 14 + // NOTE: We're significantly more liberal about canonicalizing "wild" 15 + // values than "JSON" values because they're used to deal with some 16 + // unusual edge cases, including situations where old config has been left 17 + // in the database and we aren't sure what type it's supposed to be. 18 + // Accept anything we can decode. 19 + 20 + $value = json_decode($raw_value, true); 21 + if ($value === null && $raw_value != 'null') { 22 + throw $this->newException( 23 + pht( 24 + 'Value for option "%s" (of type "%s") must be specified in JSON, '. 25 + 'but input could not be decoded. (Did you forget to quote a string?)', 26 + $option->getKey(), 27 + $this->getTypeKey())); 28 + } 29 + 30 + return $value; 31 + } 32 + 33 + public function validateStoredValue( 34 + PhabricatorConfigOption $option, 35 + $value) { 36 + return; 37 + } 38 + 39 + }
+1 -1
src/applications/people/config/PhabricatorUserConfigOptions.php
··· 43 43 $this->newOption('user.fields', $custom_field_type, $default) 44 44 ->setCustomData(id(new PhabricatorUser())->getCustomFieldBaseClass()) 45 45 ->setDescription(pht('Select and reorder user profile fields.')), 46 - $this->newOption('user.custom-field-definitions', 'map', array()) 46 + $this->newOption('user.custom-field-definitions', 'wild', array()) 47 47 ->setDescription(pht('Add new simple fields to user profiles.')), 48 48 $this->newOption('user.require-real-name', 'bool', true) 49 49 ->setDescription(pht('Always require real name for user profiles.'))