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

Convert Maniphest custom config to new config types

Summary:
Fixes T12870. Ref T12845.

Technically, this addresses the core issue in T12845 too, but I'm going to convert the rest of the `custom:...` types before closing that.

In particular, for T12870:

- Validates that keywords are unique across priorities.
- Fixes missing newline in documentation.
- Updates documentation to note that keywords are now mandatory and must be unique across priorities.

Test Plan: Edited, deleted and mangled all the Maniphest custom options (priorities, statuses, points, subtypes).

Reviewers: chad, amckinley

Reviewed By: amckinley

Maniphest Tasks: T12870, T12845

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

+120 -83
+8 -8
src/__phutil_library_map__.php
··· 1488 1488 'ManiphestHovercardEngineExtension' => 'applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php', 1489 1489 'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php', 1490 1490 'ManiphestNameIndex' => 'applications/maniphest/storage/ManiphestNameIndex.php', 1491 - 'ManiphestPointsConfigOptionType' => 'applications/maniphest/config/ManiphestPointsConfigOptionType.php', 1492 - 'ManiphestPriorityConfigOptionType' => 'applications/maniphest/config/ManiphestPriorityConfigOptionType.php', 1491 + 'ManiphestPointsConfigType' => 'applications/maniphest/config/ManiphestPointsConfigType.php', 1492 + 'ManiphestPrioritiesConfigType' => 'applications/maniphest/config/ManiphestPrioritiesConfigType.php', 1493 1493 'ManiphestPriorityEmailCommand' => 'applications/maniphest/command/ManiphestPriorityEmailCommand.php', 1494 1494 'ManiphestPrioritySearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestPrioritySearchConduitAPIMethod.php', 1495 1495 'ManiphestProjectNameFulltextEngineExtension' => 'applications/maniphest/engineextension/ManiphestProjectNameFulltextEngineExtension.php', ··· 1500 1500 'ManiphestReportController' => 'applications/maniphest/controller/ManiphestReportController.php', 1501 1501 'ManiphestSchemaSpec' => 'applications/maniphest/storage/ManiphestSchemaSpec.php', 1502 1502 'ManiphestSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestSearchConduitAPIMethod.php', 1503 - 'ManiphestStatusConfigOptionType' => 'applications/maniphest/config/ManiphestStatusConfigOptionType.php', 1504 1503 'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php', 1505 1504 'ManiphestStatusSearchConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestStatusSearchConduitAPIMethod.php', 1505 + 'ManiphestStatusesConfigType' => 'applications/maniphest/config/ManiphestStatusesConfigType.php', 1506 1506 'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php', 1507 - 'ManiphestSubtypesConfigOptionsType' => 'applications/maniphest/config/ManiphestSubtypesConfigOptionsType.php', 1507 + 'ManiphestSubtypesConfigType' => 'applications/maniphest/config/ManiphestSubtypesConfigType.php', 1508 1508 'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php', 1509 1509 'ManiphestTaskAssignHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignHeraldAction.php', 1510 1510 'ManiphestTaskAssignOtherHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignOtherHeraldAction.php', ··· 6603 6603 'ManiphestHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension', 6604 6604 'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod', 6605 6605 'ManiphestNameIndex' => 'ManiphestDAO', 6606 - 'ManiphestPointsConfigOptionType' => 'PhabricatorConfigJSONOptionType', 6607 - 'ManiphestPriorityConfigOptionType' => 'PhabricatorConfigJSONOptionType', 6606 + 'ManiphestPointsConfigType' => 'PhabricatorJSONConfigType', 6607 + 'ManiphestPrioritiesConfigType' => 'PhabricatorJSONConfigType', 6608 6608 'ManiphestPriorityEmailCommand' => 'ManiphestEmailCommand', 6609 6609 'ManiphestPrioritySearchConduitAPIMethod' => 'ManiphestConduitAPIMethod', 6610 6610 'ManiphestProjectNameFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension', ··· 6615 6615 'ManiphestReportController' => 'ManiphestController', 6616 6616 'ManiphestSchemaSpec' => 'PhabricatorConfigSchemaSpec', 6617 6617 'ManiphestSearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod', 6618 - 'ManiphestStatusConfigOptionType' => 'PhabricatorConfigJSONOptionType', 6619 6618 'ManiphestStatusEmailCommand' => 'ManiphestEmailCommand', 6620 6619 'ManiphestStatusSearchConduitAPIMethod' => 'ManiphestConduitAPIMethod', 6620 + 'ManiphestStatusesConfigType' => 'PhabricatorJSONConfigType', 6621 6621 'ManiphestSubpriorityController' => 'ManiphestController', 6622 - 'ManiphestSubtypesConfigOptionsType' => 'PhabricatorConfigJSONOptionType', 6622 + 'ManiphestSubtypesConfigType' => 'PhabricatorJSONConfigType', 6623 6623 'ManiphestTask' => array( 6624 6624 'ManiphestDAO', 6625 6625 'PhabricatorSubscribableInterface',
+5
src/applications/config/controller/PhabricatorConfigEditController.php
··· 290 290 } catch (PhabricatorConfigValidationException $ex) { 291 291 $errors[] = $ex->getMessage(); 292 292 $xaction = null; 293 + } catch (Exception $ex) { 294 + // NOTE: Some older validators throw bare exceptions. Purely in good 295 + // taste, it would be nice to convert these at some point. 296 + $errors[] = $ex->getMessage(); 297 + $xaction = null; 293 298 } 294 299 295 300 return array(
-10
src/applications/maniphest/config/ManiphestPointsConfigOptionType.php
··· 1 - <?php 2 - 3 - final class ManiphestPointsConfigOptionType 4 - extends PhabricatorConfigJSONOptionType { 5 - 6 - public function validateOption(PhabricatorConfigOption $option, $value) { 7 - ManiphestTaskPoints::validateConfiguration($value); 8 - } 9 - 10 - }
+14
src/applications/maniphest/config/ManiphestPointsConfigType.php
··· 1 + <?php 2 + 3 + final class ManiphestPointsConfigType 4 + extends PhabricatorJSONConfigType { 5 + 6 + const TYPEKEY = 'maniphest.points'; 7 + 8 + public function validateStoredValue( 9 + PhabricatorConfigOption $option, 10 + $value) { 11 + ManiphestTaskPoints::validateConfiguration($value); 12 + } 13 + 14 + }
+14
src/applications/maniphest/config/ManiphestPrioritiesConfigType.php
··· 1 + <?php 2 + 3 + final class ManiphestPrioritiesConfigType 4 + extends PhabricatorJSONConfigType { 5 + 6 + const TYPEKEY = 'maniphest.priorities'; 7 + 8 + public function validateStoredValue( 9 + PhabricatorConfigOption $option, 10 + $value) { 11 + ManiphestTaskPriority::validateConfiguration($value); 12 + } 13 + 14 + }
-10
src/applications/maniphest/config/ManiphestPriorityConfigOptionType.php
··· 1 - <?php 2 - 3 - final class ManiphestPriorityConfigOptionType 4 - extends PhabricatorConfigJSONOptionType { 5 - 6 - public function validateOption(PhabricatorConfigOption $option, $value) { 7 - ManiphestTaskPriority::validateConfiguration($value); 8 - } 9 - 10 - }
-10
src/applications/maniphest/config/ManiphestStatusConfigOptionType.php
··· 1 - <?php 2 - 3 - final class ManiphestStatusConfigOptionType 4 - extends PhabricatorConfigJSONOptionType { 5 - 6 - public function validateOption(PhabricatorConfigOption $option, $value) { 7 - ManiphestTaskStatus::validateConfiguration($value); 8 - } 9 - 10 - }
+14
src/applications/maniphest/config/ManiphestStatusesConfigType.php
··· 1 + <?php 2 + 3 + final class ManiphestStatusesConfigType 4 + extends PhabricatorJSONConfigType { 5 + 6 + const TYPEKEY = 'maniphest.statuses'; 7 + 8 + public function validateStoredValue( 9 + PhabricatorConfigOption $option, 10 + $value) { 11 + ManiphestTaskStatus::validateConfiguration($value); 12 + } 13 + 14 + }
-10
src/applications/maniphest/config/ManiphestSubtypesConfigOptionsType.php
··· 1 - <?php 2 - 3 - final class ManiphestSubtypesConfigOptionsType 4 - extends PhabricatorConfigJSONOptionType { 5 - 6 - public function validateOption(PhabricatorConfigOption $option, $value) { 7 - PhabricatorEditEngineSubtype::validateConfiguration($value); 8 - } 9 - 10 - }
+14
src/applications/maniphest/config/ManiphestSubtypesConfigType.php
··· 1 + <?php 2 + 3 + final class ManiphestSubtypesConfigType 4 + extends PhabricatorJSONConfigType { 5 + 6 + const TYPEKEY = 'maniphest.subtypes'; 7 + 8 + public function validateStoredValue( 9 + PhabricatorConfigOption $option, 10 + $value) { 11 + PhabricatorEditEngineSubtype::validateConfiguration($value); 12 + } 13 + 14 + }
+37 -34
src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
··· 20 20 } 21 21 22 22 public function getOptions() { 23 - $priority_type = 'custom:ManiphestPriorityConfigOptionType'; 23 + $priority_type = 'maniphest.priorities'; 24 24 $priority_defaults = array( 25 25 100 => array( 26 26 'name' => pht('Unbreak Now!'), 27 + 'keywords' => array('unbreak'), 27 28 'short' => pht('Unbreak!'), 28 29 'color' => 'pink', 29 - 'keywords' => array('unbreak'), 30 30 ), 31 31 90 => array( 32 32 'name' => pht('Needs Triage'), 33 + 'keywords' => array('triage'), 33 34 'short' => pht('Triage'), 34 35 'color' => 'violet', 35 - 'keywords' => array('triage'), 36 36 ), 37 37 80 => array( 38 38 'name' => pht('High'), 39 + 'keywords' => array('high'), 39 40 'short' => pht('High'), 40 41 'color' => 'red', 41 - 'keywords' => array('high'), 42 42 ), 43 43 50 => array( 44 44 'name' => pht('Normal'), 45 + 'keywords' => array('normal'), 45 46 'short' => pht('Normal'), 46 47 'color' => 'orange', 47 - 'keywords' => array('normal'), 48 48 ), 49 49 25 => array( 50 50 'name' => pht('Low'), 51 + 'keywords' => array('low'), 51 52 'short' => pht('Low'), 52 53 'color' => 'yellow', 53 - 'keywords' => array('low'), 54 54 ), 55 55 0 => array( 56 56 'name' => pht('Wishlist'), 57 + 'keywords' => array('wish', 'wishlist'), 57 58 'short' => pht('Wish'), 58 59 'color' => 'sky', 59 - 'keywords' => array('wish', 'wishlist'), 60 60 ), 61 61 ); 62 62 63 - $status_type = 'custom:ManiphestStatusConfigOptionType'; 63 + $status_type = 'maniphest.statuses'; 64 64 $status_defaults = array( 65 65 'open' => array( 66 66 'name' => pht('Open'), ··· 265 265 ); 266 266 $fields_json = id(new PhutilJSON())->encodeFormatted($fields_example); 267 267 268 - $points_type = 'custom:ManiphestPointsConfigOptionType'; 268 + $points_type = 'maniphest.points'; 269 269 270 270 $points_example_1 = array( 271 271 'enabled' => true, ··· 299 299 EOTEXT 300 300 )); 301 301 302 - $subtype_type = 'custom:ManiphestSubtypesConfigOptionsType'; 302 + $subtype_type = 'maniphest.subtypes'; 303 303 $subtype_default_key = PhabricatorEditEngineSubtype::SUBTYPE_DEFAULT; 304 304 $subtype_example = array( 305 305 array( ··· 349 349 , 350 350 $subtype_default_key)); 351 351 352 + $priorities_description = $this->deformat(pht(<<<EOTEXT 353 + Allows you to edit or override the default priorities available in Maniphest, 354 + like "High", "Normal" and "Low". The configuration should contain a map of 355 + numeric priority values (where larger numbers correspond to higher priorities) 356 + to priority specifications (see defaults below for examples). 357 + 358 + The keys you can define for a priority are: 359 + 360 + - `name` //Required string.// Name of the priority. 361 + - `keywords` //Required list<string>.// List of unique keywords which identify 362 + this priority, like "high" or "low". Each priority must have at least one 363 + keyword and two priorities may not share the same keyword. 364 + - `short` //Optional string.// Alternate shorter name, used in UIs where 365 + there is less space available. 366 + - `color` //Optional string.// Color for this priority, like "red" or 367 + "blue". 368 + - `disabled` //Optional bool.// Set to true to prevent users from choosing 369 + this priority when creating or editing tasks. Existing tasks will not be 370 + affected, and can be batch edited to a different priority or left to 371 + eventually die out. 372 + 373 + You can choose the default priority for newly created tasks with 374 + "maniphest.default-priority". 375 + EOTEXT 376 + )); 377 + 352 378 353 379 return array( 354 380 $this->newOption('maniphest.custom-field-definitions', 'wild', array()) ··· 367 393 $priority_type, 368 394 $priority_defaults) 369 395 ->setSummary(pht('Configure Maniphest priority names.')) 370 - ->setDescription( 371 - pht( 372 - 'Allows you to edit or override the default priorities available '. 373 - 'in Maniphest, like "High", "Normal" and "Low". The configuration '. 374 - 'should contain a map of priority constants to priority '. 375 - 'specifications (see defaults below for examples).'. 376 - "\n\n". 377 - 'The keys you can define for a priority are:'. 378 - "\n\n". 379 - ' - `name` Name of the priority.'."\n". 380 - ' - `short` Alternate shorter name, used in UIs where there is '. 381 - ' not much space available.'."\n". 382 - ' - `color` A color for this priority, like "red" or "blue".'. 383 - ' - `keywords` An optional list of keywords which can '. 384 - ' be used to select this priority when using `!priority` '. 385 - ' commands in email.'."\n". 386 - ' - `disabled` Optional boolean to prevent users from choosing '. 387 - ' this priority when creating or editing tasks. Existing '. 388 - ' tasks will be unaffected, and can be batch edited to a '. 389 - ' different priority or left to eventually die out.'. 390 - "\n\n". 391 - 'You can choose which priority is the default for newly created '. 392 - 'tasks with `%s`.', 393 - 'maniphest.default-priority')), 396 + ->setDescription($priorities_description), 394 397 $this->newOption('maniphest.statuses', $status_type, $status_defaults) 395 398 ->setSummary(pht('Configure Maniphest task statuses.')) 396 399 ->setDescription($status_description)
+14 -1
src/applications/maniphest/constants/ManiphestTaskPriority.php
··· 203 203 $config)); 204 204 } 205 205 206 + $all_keywords = array(); 206 207 foreach ($config as $key => $value) { 207 208 if (!ctype_digit((string)$key)) { 208 209 throw new Exception( ··· 223 224 $value, 224 225 array( 225 226 'name' => 'string', 227 + 'keywords' => 'list<string>', 226 228 'short' => 'optional string', 227 229 'color' => 'optional string', 228 - 'keywords' => 'list<string>', 229 230 'disabled' => 'optional bool', 230 231 )); 231 232 ··· 242 243 'low', 243 244 'critical')); 244 245 } 246 + 247 + if (isset($all_keywords[$keyword])) { 248 + throw new Exception( 249 + pht( 250 + 'Two different task priorities ("%s" and "%s") have the same '. 251 + 'keyword ("%s"). Keywords must uniquely identify priorities.', 252 + $value['name'], 253 + $all_keywords[$keyword], 254 + $keyword)); 255 + } 256 + 257 + $all_keywords[$keyword] = $value['name']; 245 258 } 246 259 } 247 260 }