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

Make Herald custom field integration modular

Summary: Ref T8726. The existing implementation is largely made redundant by the newer modular implementation.

Test Plan: Created a custom field rule, set custom field to various values until it matched, saw effect and proper transcripts.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: eadler, joshuaspence, epriestley

Maniphest Tasks: T8726

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

+83 -221
+2
src/__phutil_library_map__.php
··· 1709 1709 'PhabricatorCustomFieldAttachment' => 'infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php', 1710 1710 'PhabricatorCustomFieldConfigOptionType' => 'infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php', 1711 1711 'PhabricatorCustomFieldDataNotAvailableException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldDataNotAvailableException.php', 1712 + 'PhabricatorCustomFieldHeraldField' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldField.php', 1712 1713 'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php', 1713 1714 'PhabricatorCustomFieldIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldIndexStorage.php', 1714 1715 'PhabricatorCustomFieldInterface' => 'infrastructure/customfield/interface/PhabricatorCustomFieldInterface.php', ··· 5339 5340 'PhabricatorCustomFieldAttachment' => 'Phobject', 5340 5341 'PhabricatorCustomFieldConfigOptionType' => 'PhabricatorConfigOptionType', 5341 5342 'PhabricatorCustomFieldDataNotAvailableException' => 'Exception', 5343 + 'PhabricatorCustomFieldHeraldField' => 'HeraldField', 5342 5344 'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception', 5343 5345 'PhabricatorCustomFieldIndexStorage' => 'PhabricatorLiskDAO', 5344 5346 'PhabricatorCustomFieldList' => 'Phobject',
+4 -218
src/applications/herald/adapter/HeraldAdapter.php
··· 1 1 <?php 2 2 3 - /** 4 - * @task customfield Custom Field Integration 5 - */ 6 3 abstract class HeraldAdapter extends Phobject { 7 4 8 5 const FIELD_TITLE = 'title'; ··· 100 97 private $contentSource; 101 98 private $isNewObject; 102 99 private $applicationEmail; 103 - private $customFields = false; 104 100 private $customActions = null; 105 101 private $queuedTransactions = array(); 106 102 private $emailPHIDs = array(); ··· 199 195 } 200 196 return $value; 201 197 default: 202 - if ($this->isHeraldCustomKey($field_name)) { 203 - return $this->getCustomFieldValue($field_name); 204 - } 205 - 206 198 throw new Exception(pht("Unknown field '%s'!", $field_name)); 207 199 } 208 200 } ··· 365 357 } 366 358 367 359 public function getFields() { 368 - $fields = array_keys($this->getFieldImplementationMap()); 369 - 370 - $custom_fields = $this->getCustomFields(); 371 - if ($custom_fields) { 372 - foreach ($custom_fields->getFields() as $custom_field) { 373 - $key = $custom_field->getFieldKey(); 374 - $fields[] = $this->getHeraldKeyFromCustomKey($key); 375 - } 376 - } 377 - 378 - return $fields; 360 + return array_keys($this->getFieldImplementationMap()); 379 361 } 380 362 381 363 public function getFieldNameMap() { ··· 417 399 self::FIELD_TASK_STATUS => pht('Task status'), 418 400 self::FIELD_PUSHER_IS_COMMITTER => pht('Pusher same as committer'), 419 401 self::FIELD_PATH => pht('Path'), 420 - ) + $this->getCustomFieldNameMap(); 402 + ); 421 403 } 422 404 423 405 ··· 552 534 self::CONDITION_IS_FALSE, 553 535 ); 554 536 default: 555 - if ($this->isHeraldCustomKey($field)) { 556 - return $this->getCustomFieldConditions($field); 557 - } 558 537 throw new Exception( 559 538 pht( 560 539 "This adapter does not define conditions for field '%s'!", ··· 933 912 return $impl->getHeraldFieldValueType($condition); 934 913 } 935 914 936 - if ($this->isHeraldCustomKey($field)) { 937 - $value_type = $this->getCustomFieldValueTypeForFieldAndCondition( 938 - $field, 939 - $condition); 940 - if ($value_type !== null) { 941 - return $value_type; 942 - } 943 - } 944 - 945 915 switch ($condition) { 946 916 case self::CONDITION_CONTAINS: 947 917 case self::CONDITION_NOT_CONTAINS: ··· 1205 1175 1206 1176 $field_type = $condition->getFieldName(); 1207 1177 1208 - $default = $this->isHeraldCustomKey($field_type) 1209 - ? pht('(Unknown Custom Field "%s")', $field_type) 1210 - : pht('(Unknown Field "%s")', $field_type); 1178 + $default = pht('(Unknown Field "%s")', $field_type); 1211 1179 1212 1180 $field_name = idx($this->getFieldNameMap(), $field_type, $default); 1213 1181 ··· 1226 1194 1227 1195 $action_type = $action->getAction(); 1228 1196 1229 - $default = $this->isHeraldCustomKey($action_type) 1230 - ? pht('(Unknown Custom Action "%s") equals', $action_type) 1231 - : pht('(Unknown Action "%s") equals', $action_type); 1197 + $default = pht('(Unknown Action "%s") equals', $action_type); 1232 1198 1233 1199 $action_name = idx( 1234 1200 $this->getActionNameMap($rule_global), ··· 1361 1327 1362 1328 return $phids; 1363 1329 } 1364 - 1365 - /* -( Custom Field Integration )------------------------------------------- */ 1366 - 1367 - 1368 - /** 1369 - * Returns the prefix used to namespace Herald fields which are based on 1370 - * custom fields. 1371 - * 1372 - * @return string Key prefix. 1373 - * @task customfield 1374 - */ 1375 - private function getCustomKeyPrefix() { 1376 - return 'herald.custom/'; 1377 - } 1378 - 1379 - 1380 - /** 1381 - * Determine if a field key is based on a custom field or a regular internal 1382 - * field. 1383 - * 1384 - * @param string Field key. 1385 - * @return bool True if the field key is based on a custom field. 1386 - * @task customfield 1387 - */ 1388 - private function isHeraldCustomKey($key) { 1389 - $prefix = $this->getCustomKeyPrefix(); 1390 - return (strncmp($key, $prefix, strlen($prefix)) == 0); 1391 - } 1392 - 1393 - 1394 - /** 1395 - * Convert a custom field key into a Herald field key. 1396 - * 1397 - * @param string Custom field key. 1398 - * @return string Herald field key. 1399 - * @task customfield 1400 - */ 1401 - private function getHeraldKeyFromCustomKey($key) { 1402 - return $this->getCustomKeyPrefix().$key; 1403 - } 1404 - 1405 - 1406 - /** 1407 - * Get custom fields for this adapter, if appliable. This will either return 1408 - * a field list or `null` if the adapted object does not implement custom 1409 - * fields or the adapter does not support them. 1410 - * 1411 - * @return PhabricatorCustomFieldList|null List of fields, or `null`. 1412 - * @task customfield 1413 - */ 1414 - private function getCustomFields() { 1415 - if ($this->customFields === false) { 1416 - $this->customFields = null; 1417 - 1418 - 1419 - $template_object = $this->newObject(); 1420 - if ($template_object instanceof PhabricatorCustomFieldInterface) { 1421 - $object = $this->getObject(); 1422 - if (!$object) { 1423 - $object = $template_object; 1424 - } 1425 - 1426 - $fields = PhabricatorCustomField::getObjectFields( 1427 - $object, 1428 - PhabricatorCustomField::ROLE_HERALD); 1429 - $fields->setViewer(PhabricatorUser::getOmnipotentUser()); 1430 - $fields->readFieldsFromStorage($object); 1431 - 1432 - $this->customFields = $fields; 1433 - } 1434 - } 1435 - 1436 - return $this->customFields; 1437 - } 1438 - 1439 - 1440 - /** 1441 - * Get a custom field by Herald field key, or `null` if it does not exist 1442 - * or custom fields are not supported. 1443 - * 1444 - * @param string Herald field key. 1445 - * @return PhabricatorCustomField|null Matching field, if it exists. 1446 - * @task customfield 1447 - */ 1448 - private function getCustomField($herald_field_key) { 1449 - $fields = $this->getCustomFields(); 1450 - if (!$fields) { 1451 - return null; 1452 - } 1453 - 1454 - foreach ($fields->getFields() as $custom_field) { 1455 - $key = $custom_field->getFieldKey(); 1456 - if ($this->getHeraldKeyFromCustomKey($key) == $herald_field_key) { 1457 - return $custom_field; 1458 - } 1459 - } 1460 - 1461 - return null; 1462 - } 1463 - 1464 - 1465 - /** 1466 - * Get the field map for custom fields. 1467 - * 1468 - * @return map<string, string> Map of Herald field keys to field names. 1469 - * @task customfield 1470 - */ 1471 - private function getCustomFieldNameMap() { 1472 - $fields = $this->getCustomFields(); 1473 - if (!$fields) { 1474 - return array(); 1475 - } 1476 - 1477 - $map = array(); 1478 - foreach ($fields->getFields() as $field) { 1479 - $key = $field->getFieldKey(); 1480 - $name = $field->getHeraldFieldName(); 1481 - $map[$this->getHeraldKeyFromCustomKey($key)] = $name; 1482 - } 1483 - 1484 - return $map; 1485 - } 1486 - 1487 - 1488 - /** 1489 - * Get the value for a custom field. 1490 - * 1491 - * @param string Herald field key. 1492 - * @return wild Custom field value. 1493 - * @task customfield 1494 - */ 1495 - private function getCustomFieldValue($field_key) { 1496 - $field = $this->getCustomField($field_key); 1497 - if (!$field) { 1498 - return null; 1499 - } 1500 - 1501 - return $field->getHeraldFieldValue(); 1502 - } 1503 - 1504 - 1505 - /** 1506 - * Get the Herald conditions for a custom field. 1507 - * 1508 - * @param string Herald field key. 1509 - * @return list<const> List of Herald conditions. 1510 - * @task customfield 1511 - */ 1512 - private function getCustomFieldConditions($field_key) { 1513 - $field = $this->getCustomField($field_key); 1514 - if (!$field) { 1515 - return array( 1516 - self::CONDITION_NEVER, 1517 - ); 1518 - } 1519 - 1520 - return $field->getHeraldFieldConditions(); 1521 - } 1522 - 1523 - 1524 - /** 1525 - * Get the Herald value type for a custom field and condition. 1526 - * 1527 - * @param string Herald field key. 1528 - * @param const Herald condition constant. 1529 - * @return const|null Herald value type constant, or null to use the default. 1530 - * @task customfield 1531 - */ 1532 - private function getCustomFieldValueTypeForFieldAndCondition( 1533 - $field_key, 1534 - $condition) { 1535 - 1536 - $field = $this->getCustomField($field_key); 1537 - if (!$field) { 1538 - return self::VALUE_NONE; 1539 - } 1540 - 1541 - return $field->getHeraldFieldValueType($condition); 1542 - } 1543 - 1544 1330 1545 1331 /* -( Applying Effects )--------------------------------------------------- */ 1546 1332
+9 -3
src/applications/herald/field/HeraldField.php
··· 71 71 'FIELDCONST')); 72 72 } 73 73 74 - if (!is_string($const) || (strlen($const) > 32)) { 74 + $limit = self::getFieldConstantByteLimit(); 75 + if (!is_string($const) || (strlen($const) > $limit)) { 75 76 throw new Exception( 76 77 pht( 77 78 '"%s" class "%s" has an invalid "%s" property. Field constants '. 78 - 'must be strings and no more than 32 bytes in length.', 79 + 'must be strings and no more than %s bytes in length.', 79 80 __CLASS__, 80 81 get_class($this), 81 - 'FIELDCONST')); 82 + 'FIELDCONST', 83 + new PhutilNumber($limit))); 82 84 } 83 85 84 86 return $const; 87 + } 88 + 89 + final public static function getFieldConstantByteLimit() { 90 + return 64; 85 91 } 86 92 87 93 final public static function getAllFields() {
+68
src/infrastructure/customfield/herald/PhabricatorCustomFieldHeraldField.php
··· 1 + <?php 2 + 3 + final class PhabricatorCustomFieldHeraldField extends HeraldField { 4 + 5 + const FIELDCONST = 'herald.custom'; 6 + 7 + private $customField; 8 + 9 + public function setCustomField(PhabricatorCustomField $custom_field) { 10 + $this->customField = $custom_field; 11 + return $this; 12 + } 13 + 14 + public function getCustomField() { 15 + return $this->customField; 16 + } 17 + 18 + public function supportsObject($object) { 19 + return ($object instanceof PhabricatorCustomFieldInterface); 20 + } 21 + 22 + public function getFieldsForObject($object) { 23 + $field_list = PhabricatorCustomField::getObjectFields( 24 + $object, 25 + PhabricatorCustomField::ROLE_HERALD); 26 + $field_list->setViewer(PhabricatorUser::getOmnipotentUser()); 27 + $field_list->readFieldsFromStorage($object); 28 + 29 + $prefix = 'herald.custom/'; 30 + $limit = self::getFieldConstantByteLimit(); 31 + 32 + $map = array(); 33 + foreach ($field_list->getFields() as $field) { 34 + $key = $field->getFieldKey(); 35 + 36 + // NOTE: This use of digestToLength() isn't preferred (you should 37 + // normally digest a key unconditionally, so that it isn't possible to 38 + // arrange a collision) but preserves backward compatibility. 39 + 40 + $full_key = $prefix.$key; 41 + if (strlen($full_key) > $limit) { 42 + $full_key = PhabricatorHash::digestToLength($full_key, $limit); 43 + } 44 + 45 + $map[$full_key] = id(new PhabricatorCustomFieldHeraldField()) 46 + ->setCustomField($field); 47 + } 48 + 49 + return $map; 50 + } 51 + 52 + public function getHeraldFieldName() { 53 + return $this->getCustomField()->getHeraldFieldName(); 54 + } 55 + 56 + public function getHeraldFieldValue($object) { 57 + return $this->getCustomField()->getHeraldFieldValue(); 58 + } 59 + 60 + public function getHeraldFieldConditions() { 61 + return $this->getCustomField()->getHeraldFieldConditions(); 62 + } 63 + 64 + public function getHeraldFieldValueType($condition) { 65 + return $this->getCustomField()->getHeraldFieldValueType($condition); 66 + } 67 + 68 + }