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

Modularize workboard column transactions

Summary: Depends on D20279. Ref T5474. Modernize these transactions before I add a new "TriggerTransaction" for setting triggers.

Test Plan: Created a column. Edited a column name and point limit. Hid and un-hid a column. Grepped for removed symbols.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T5474

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

+209 -194
+9 -1
src/__phutil_library_map__.php
··· 4059 4059 'PhabricatorProjectColumnEditController' => 'applications/project/controller/PhabricatorProjectColumnEditController.php', 4060 4060 'PhabricatorProjectColumnHeader' => 'applications/project/order/PhabricatorProjectColumnHeader.php', 4061 4061 'PhabricatorProjectColumnHideController' => 'applications/project/controller/PhabricatorProjectColumnHideController.php', 4062 + 'PhabricatorProjectColumnLimitTransaction' => 'applications/project/xaction/column/PhabricatorProjectColumnLimitTransaction.php', 4063 + 'PhabricatorProjectColumnNameTransaction' => 'applications/project/xaction/column/PhabricatorProjectColumnNameTransaction.php', 4062 4064 'PhabricatorProjectColumnNaturalOrder' => 'applications/project/order/PhabricatorProjectColumnNaturalOrder.php', 4063 4065 'PhabricatorProjectColumnOrder' => 'applications/project/order/PhabricatorProjectColumnOrder.php', 4064 4066 'PhabricatorProjectColumnOwnerOrder' => 'applications/project/order/PhabricatorProjectColumnOwnerOrder.php', ··· 4070 4072 'PhabricatorProjectColumnQuery' => 'applications/project/query/PhabricatorProjectColumnQuery.php', 4071 4073 'PhabricatorProjectColumnSearchEngine' => 'applications/project/query/PhabricatorProjectColumnSearchEngine.php', 4072 4074 'PhabricatorProjectColumnStatusOrder' => 'applications/project/order/PhabricatorProjectColumnStatusOrder.php', 4075 + 'PhabricatorProjectColumnStatusTransaction' => 'applications/project/xaction/column/PhabricatorProjectColumnStatusTransaction.php', 4073 4076 'PhabricatorProjectColumnTitleOrder' => 'applications/project/order/PhabricatorProjectColumnTitleOrder.php', 4074 4077 'PhabricatorProjectColumnTransaction' => 'applications/project/storage/PhabricatorProjectColumnTransaction.php', 4075 4078 'PhabricatorProjectColumnTransactionEditor' => 'applications/project/editor/PhabricatorProjectColumnTransactionEditor.php', 4076 4079 'PhabricatorProjectColumnTransactionQuery' => 'applications/project/query/PhabricatorProjectColumnTransactionQuery.php', 4080 + 'PhabricatorProjectColumnTransactionType' => 'applications/project/xaction/column/PhabricatorProjectColumnTransactionType.php', 4077 4081 'PhabricatorProjectConfigOptions' => 'applications/project/config/PhabricatorProjectConfigOptions.php', 4078 4082 'PhabricatorProjectConfiguredCustomField' => 'applications/project/customfield/PhabricatorProjectConfiguredCustomField.php', 4079 4083 'PhabricatorProjectController' => 'applications/project/controller/PhabricatorProjectController.php', ··· 10166 10170 'PhabricatorProjectColumnEditController' => 'PhabricatorProjectBoardController', 10167 10171 'PhabricatorProjectColumnHeader' => 'Phobject', 10168 10172 'PhabricatorProjectColumnHideController' => 'PhabricatorProjectBoardController', 10173 + 'PhabricatorProjectColumnLimitTransaction' => 'PhabricatorProjectColumnTransactionType', 10174 + 'PhabricatorProjectColumnNameTransaction' => 'PhabricatorProjectColumnTransactionType', 10169 10175 'PhabricatorProjectColumnNaturalOrder' => 'PhabricatorProjectColumnOrder', 10170 10176 'PhabricatorProjectColumnOrder' => 'Phobject', 10171 10177 'PhabricatorProjectColumnOwnerOrder' => 'PhabricatorProjectColumnOrder', ··· 10180 10186 'PhabricatorProjectColumnQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 10181 10187 'PhabricatorProjectColumnSearchEngine' => 'PhabricatorApplicationSearchEngine', 10182 10188 'PhabricatorProjectColumnStatusOrder' => 'PhabricatorProjectColumnOrder', 10189 + 'PhabricatorProjectColumnStatusTransaction' => 'PhabricatorProjectColumnTransactionType', 10183 10190 'PhabricatorProjectColumnTitleOrder' => 'PhabricatorProjectColumnOrder', 10184 - 'PhabricatorProjectColumnTransaction' => 'PhabricatorApplicationTransaction', 10191 + 'PhabricatorProjectColumnTransaction' => 'PhabricatorModularTransaction', 10185 10192 'PhabricatorProjectColumnTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 10186 10193 'PhabricatorProjectColumnTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 10194 + 'PhabricatorProjectColumnTransactionType' => 'PhabricatorModularTransactionType', 10187 10195 'PhabricatorProjectConfigOptions' => 'PhabricatorApplicationConfigOptions', 10188 10196 'PhabricatorProjectConfiguredCustomField' => array( 10189 10197 'PhabricatorProjectStandardCustomField',
+2 -3
src/applications/project/controller/PhabricatorProjectColumnEditController.php
··· 76 76 77 77 $xactions = array(); 78 78 79 - $type_name = PhabricatorProjectColumnTransaction::TYPE_NAME; 80 - $type_limit = PhabricatorProjectColumnTransaction::TYPE_LIMIT; 79 + $type_name = PhabricatorProjectColumnNameTransaction::TRANSACTIONTYPE; 80 + $type_limit = PhabricatorProjectColumnLimitTransaction::TRANSACTIONTYPE; 81 81 82 82 if (!$column->getProxy()) { 83 83 $xactions[] = id(new PhabricatorProjectColumnTransaction()) ··· 93 93 $editor = id(new PhabricatorProjectColumnTransactionEditor()) 94 94 ->setActor($viewer) 95 95 ->setContinueOnNoEffect(true) 96 - ->setContinueOnMissingFields(true) 97 96 ->setContentSourceFromRequest($request) 98 97 ->applyTransactions($column, $xactions); 99 98 return id(new AphrontRedirectResponse())->setURI($view_uri);
+3 -1
src/applications/project/controller/PhabricatorProjectColumnHideController.php
··· 82 82 $new_status = PhabricatorProjectColumn::STATUS_HIDDEN; 83 83 } 84 84 85 - $type_status = PhabricatorProjectColumnTransaction::TYPE_STATUS; 85 + $type_status = 86 + PhabricatorProjectColumnStatusTransaction::TRANSACTIONTYPE; 87 + 86 88 $xactions = array( 87 89 id(new PhabricatorProjectColumnTransaction()) 88 90 ->setTransactionType($type_status)
+4 -122
src/applications/project/editor/PhabricatorProjectColumnTransactionEditor.php
··· 11 11 return pht('Workboard Columns'); 12 12 } 13 13 14 - public function getTransactionTypes() { 15 - $types = parent::getTransactionTypes(); 16 - 17 - $types[] = PhabricatorProjectColumnTransaction::TYPE_NAME; 18 - $types[] = PhabricatorProjectColumnTransaction::TYPE_STATUS; 19 - $types[] = PhabricatorProjectColumnTransaction::TYPE_LIMIT; 20 - 21 - return $types; 22 - } 23 - 24 - protected function getCustomTransactionOldValue( 25 - PhabricatorLiskDAO $object, 26 - PhabricatorApplicationTransaction $xaction) { 27 - 28 - switch ($xaction->getTransactionType()) { 29 - case PhabricatorProjectColumnTransaction::TYPE_NAME: 30 - return $object->getName(); 31 - case PhabricatorProjectColumnTransaction::TYPE_STATUS: 32 - return $object->getStatus(); 33 - case PhabricatorProjectColumnTransaction::TYPE_LIMIT: 34 - return $object->getPointLimit(); 35 - 36 - } 37 - 38 - return parent::getCustomTransactionOldValue($object, $xaction); 39 - } 40 - 41 - protected function getCustomTransactionNewValue( 42 - PhabricatorLiskDAO $object, 43 - PhabricatorApplicationTransaction $xaction) { 44 - 45 - switch ($xaction->getTransactionType()) { 46 - case PhabricatorProjectColumnTransaction::TYPE_NAME: 47 - case PhabricatorProjectColumnTransaction::TYPE_STATUS: 48 - return $xaction->getNewValue(); 49 - case PhabricatorProjectColumnTransaction::TYPE_LIMIT: 50 - $value = $xaction->getNewValue(); 51 - if (strlen($value)) { 52 - return (int)$xaction->getNewValue(); 53 - } else { 54 - return null; 55 - } 56 - } 57 - 58 - return parent::getCustomTransactionNewValue($object, $xaction); 59 - } 60 - 61 - protected function applyCustomInternalTransaction( 62 - PhabricatorLiskDAO $object, 63 - PhabricatorApplicationTransaction $xaction) { 64 - 65 - switch ($xaction->getTransactionType()) { 66 - case PhabricatorProjectColumnTransaction::TYPE_NAME: 67 - $object->setName($xaction->getNewValue()); 68 - return; 69 - case PhabricatorProjectColumnTransaction::TYPE_STATUS: 70 - $object->setStatus($xaction->getNewValue()); 71 - return; 72 - case PhabricatorProjectColumnTransaction::TYPE_LIMIT: 73 - $object->setPointLimit($xaction->getNewValue()); 74 - return; 75 - } 76 - 77 - return parent::applyCustomInternalTransaction($object, $xaction); 78 - } 79 - 80 - protected function applyCustomExternalTransaction( 81 - PhabricatorLiskDAO $object, 82 - PhabricatorApplicationTransaction $xaction) { 83 - 84 - switch ($xaction->getTransactionType()) { 85 - case PhabricatorProjectColumnTransaction::TYPE_NAME: 86 - case PhabricatorProjectColumnTransaction::TYPE_STATUS: 87 - case PhabricatorProjectColumnTransaction::TYPE_LIMIT: 88 - return; 89 - } 90 - 91 - return parent::applyCustomExternalTransaction($object, $xaction); 14 + public function getCreateObjectTitle($author, $object) { 15 + return pht('%s created this column.', $author); 92 16 } 93 17 94 - protected function validateTransaction( 95 - PhabricatorLiskDAO $object, 96 - $type, 97 - array $xactions) { 98 - 99 - $errors = parent::validateTransaction($object, $type, $xactions); 100 - 101 - switch ($type) { 102 - case PhabricatorProjectColumnTransaction::TYPE_LIMIT: 103 - foreach ($xactions as $xaction) { 104 - $value = $xaction->getNewValue(); 105 - if (strlen($value) && !preg_match('/^\d+\z/', $value)) { 106 - $errors[] = new PhabricatorApplicationTransactionValidationError( 107 - $type, 108 - pht('Invalid'), 109 - pht( 110 - 'Column point limit must either be empty or a nonnegative '. 111 - 'integer.'), 112 - $xaction); 113 - } 114 - } 115 - break; 116 - case PhabricatorProjectColumnTransaction::TYPE_NAME: 117 - $missing = $this->validateIsEmptyTextField( 118 - $object->getName(), 119 - $xactions); 120 - 121 - // The default "Backlog" column is allowed to be unnamed, which 122 - // means we use the default name. 123 - 124 - if ($missing && !$object->isDefaultColumn()) { 125 - $error = new PhabricatorApplicationTransactionValidationError( 126 - $type, 127 - pht('Required'), 128 - pht('Column name is required.'), 129 - nonempty(last($xactions), null)); 130 - 131 - $error->setIsMissingFieldError(true); 132 - $errors[] = $error; 133 - } 134 - break; 135 - } 136 - 137 - return $errors; 18 + public function getCreateObjectTitleForFeed($author, $object) { 19 + return pht('%s created %s.', $author, $object); 138 20 } 139 21 140 22 }
+3 -67
src/applications/project/storage/PhabricatorProjectColumnTransaction.php
··· 1 1 <?php 2 2 3 3 final class PhabricatorProjectColumnTransaction 4 - extends PhabricatorApplicationTransaction { 5 - 6 - const TYPE_NAME = 'project:col:name'; 7 - const TYPE_STATUS = 'project:col:status'; 8 - const TYPE_LIMIT = 'project:col:limit'; 4 + extends PhabricatorModularTransaction { 9 5 10 6 public function getApplicationName() { 11 7 return 'project'; ··· 15 11 return PhabricatorProjectColumnPHIDType::TYPECONST; 16 12 } 17 13 18 - public function getTitle() { 19 - $old = $this->getOldValue(); 20 - $new = $this->getNewValue(); 21 - $author_handle = $this->renderHandleLink($this->getAuthorPHID()); 22 - 23 - switch ($this->getTransactionType()) { 24 - case self::TYPE_NAME: 25 - if ($old === null) { 26 - return pht( 27 - '%s created this column.', 28 - $author_handle); 29 - } else { 30 - if (!strlen($old)) { 31 - return pht( 32 - '%s named this column "%s".', 33 - $author_handle, 34 - $new); 35 - } else if (strlen($new)) { 36 - return pht( 37 - '%s renamed this column from "%s" to "%s".', 38 - $author_handle, 39 - $old, 40 - $new); 41 - } else { 42 - return pht( 43 - '%s removed the custom name of this column.', 44 - $author_handle); 45 - } 46 - } 47 - case self::TYPE_LIMIT: 48 - if (!$old) { 49 - return pht( 50 - '%s set the point limit for this column to %s.', 51 - $author_handle, 52 - $new); 53 - } else if (!$new) { 54 - return pht( 55 - '%s removed the point limit for this column.', 56 - $author_handle); 57 - } else { 58 - return pht( 59 - '%s changed point limit for this column from %s to %s.', 60 - $author_handle, 61 - $old, 62 - $new); 63 - } 64 - 65 - case self::TYPE_STATUS: 66 - switch ($new) { 67 - case PhabricatorProjectColumn::STATUS_ACTIVE: 68 - return pht( 69 - '%s marked this column visible.', 70 - $author_handle); 71 - case PhabricatorProjectColumn::STATUS_HIDDEN: 72 - return pht( 73 - '%s marked this column hidden.', 74 - $author_handle); 75 - } 76 - break; 77 - } 78 - 79 - return parent::getTitle(); 14 + public function getBaseTransactionClass() { 15 + return 'PhabricatorProjectColumnTransactionType'; 80 16 } 81 17 82 18 }
+63
src/applications/project/xaction/column/PhabricatorProjectColumnLimitTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectColumnLimitTransaction 4 + extends PhabricatorProjectColumnTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'project:col:limit'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getPointLimit(); 10 + } 11 + 12 + public function generateNewValue($object, $value) { 13 + if (strlen($value)) { 14 + return (int)$value; 15 + } else { 16 + return null; 17 + } 18 + } 19 + 20 + public function applyInternalEffects($object, $value) { 21 + $object->setPointLimit($value); 22 + } 23 + 24 + public function getTitle() { 25 + $old = $this->getOldValue(); 26 + $new = $this->getNewValue(); 27 + 28 + if (!$old) { 29 + return pht( 30 + '%s set the point limit for this column to %s.', 31 + $this->renderAuthor(), 32 + $this->renderNewValue()); 33 + } else if (!$new) { 34 + return pht( 35 + '%s removed the point limit for this column.', 36 + $this->renderAuthor()); 37 + } else { 38 + return pht( 39 + '%s changed the point limit for this column from %s to %s.', 40 + $this->renderAuthor(), 41 + $this->renderOldValue(), 42 + $this->renderNewValue()); 43 + } 44 + } 45 + 46 + public function validateTransactions($object, array $xactions) { 47 + $errors = array(); 48 + 49 + foreach ($xactions as $xaction) { 50 + $value = $xaction->getNewValue(); 51 + if (strlen($value) && !preg_match('/^\d+\z/', $value)) { 52 + $errors[] = $this->newInvalidError( 53 + pht( 54 + 'Column point limit must either be empty or a nonnegative '. 55 + 'integer.'), 56 + $xaction); 57 + } 58 + } 59 + 60 + return $errors; 61 + } 62 + 63 + }
+66
src/applications/project/xaction/column/PhabricatorProjectColumnNameTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectColumnNameTransaction 4 + extends PhabricatorProjectColumnTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'project:col:name'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getName(); 10 + } 11 + 12 + public function applyInternalEffects($object, $value) { 13 + $object->setName($value); 14 + } 15 + 16 + public function getTitle() { 17 + $old = $this->getOldValue(); 18 + $new = $this->getNewValue(); 19 + 20 + if (!strlen($old)) { 21 + return pht( 22 + '%s named this column %s.', 23 + $this->renderAuthor(), 24 + $this->renderNewValue()); 25 + } else if (strlen($new)) { 26 + return pht( 27 + '%s renamed this column from %s to %s.', 28 + $this->renderAuthor(), 29 + $this->renderOldValue(), 30 + $this->renderNewValue()); 31 + } else { 32 + return pht( 33 + '%s removed the custom name of this column.', 34 + $this->renderAuthor()); 35 + } 36 + } 37 + 38 + public function validateTransactions($object, array $xactions) { 39 + $errors = array(); 40 + 41 + if ($this->isEmptyTextTransaction($object->getName(), $xactions)) { 42 + // The default "Backlog" column is allowed to be unnamed, which 43 + // means we use the default name. 44 + if (!$object->isDefaultColumn()) { 45 + $errors[] = $this->newRequiredError( 46 + pht('Columns must have a name.')); 47 + } 48 + } 49 + 50 + $max_length = $object->getColumnMaximumByteLength('name'); 51 + foreach ($xactions as $xaction) { 52 + $new_value = $xaction->getNewValue(); 53 + $new_length = strlen($new_value); 54 + if ($new_length > $max_length) { 55 + $errors[] = $this->newInvalidError( 56 + pht( 57 + 'Column names must not be longer than %s characters.', 58 + new PhutilNumber($max_length)), 59 + $xaction); 60 + } 61 + } 62 + 63 + return $errors; 64 + } 65 + 66 + }
+55
src/applications/project/xaction/column/PhabricatorProjectColumnStatusTransaction.php
··· 1 + <?php 2 + 3 + final class PhabricatorProjectColumnStatusTransaction 4 + extends PhabricatorProjectColumnTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'project:col:status'; 7 + 8 + public function generateOldValue($object) { 9 + return $object->getStatus(); 10 + } 11 + 12 + public function applyInternalEffects($object, $value) { 13 + $object->setStatus($value); 14 + } 15 + 16 + public function getTitle() { 17 + $new = $this->getNewValue(); 18 + 19 + switch ($new) { 20 + case PhabricatorProjectColumn::STATUS_ACTIVE: 21 + return pht( 22 + '%s unhid this column.', 23 + $this->renderAuthor()); 24 + case PhabricatorProjectColumn::STATUS_HIDDEN: 25 + return pht( 26 + '%s hid this column.', 27 + $this->renderAuthor()); 28 + } 29 + } 30 + 31 + public function validateTransactions($object, array $xactions) { 32 + $errors = array(); 33 + 34 + $map = array( 35 + PhabricatorProjectColumn::STATUS_ACTIVE, 36 + PhabricatorProjectColumn::STATUS_HIDDEN, 37 + ); 38 + $map = array_fuse($map); 39 + 40 + foreach ($xactions as $xaction) { 41 + $value = $xaction->getNewValue(); 42 + if (!isset($map[$value])) { 43 + $errors[] = $this->newInvalidError( 44 + pht( 45 + 'Column status "%s" is unrecognized, valid statuses are: %s.', 46 + $value, 47 + implode(', ', array_keys($map))), 48 + $xaction); 49 + } 50 + } 51 + 52 + return $errors; 53 + } 54 + 55 + }
+4
src/applications/project/xaction/column/PhabricatorProjectColumnTransactionType.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorProjectColumnTransactionType 4 + extends PhabricatorModularTransactionType {}