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

Use string constants, not integer constants, to represent task status internally

Summary:
Ref T1812. I think integer constants are going to be confusing and error prone for users to interact with. For example, because we use 0-5, adding a second "open" status like "needs verification" without disrupting the existing statuses would require users to define a status with, e.g., constant `6`, but order it between constants `0` and `1`. And if they later remove statuses, they need to avoid reusing existing constants.

Instead, use more manageable string constants like "open", "resolved", etc.

We must migrate three tables:

- The task table itself, to update task status.
- The transaction table, to update historic status changes.
- The saved query table, to update saved queries which specify status sets.

Test Plan:
- Saved a query with complicated status filters.
- Ran migrations.
- Looked at the query, at existing tasks, and at task transactions.
- Forced migrations to run again to verify idempotentcy/safety.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T1812

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

+110 -15
+2
resources/sql/autopatches/20140321.mstatus.1.col.sql
··· 1 + ALTER TABLE {$NAMESPACE}_maniphest.maniphest_task 2 + CHANGE status status VARCHAR(12) NOT NULL COLLATE latin1_bin;
+94
resources/sql/autopatches/20140321.mstatus.2.mig.php
··· 1 + <?php 2 + 3 + $status_map = array( 4 + 0 => 'open', 5 + 1 => 'resolved', 6 + 2 => 'wontfix', 7 + 3 => 'invalid', 8 + 4 => 'duplicate', 9 + 5 => 'spite', 10 + ); 11 + 12 + $conn_w = id(new ManiphestTask())->establishConnection('w'); 13 + 14 + echo "Migrating tasks to new status constants...\n"; 15 + foreach (new LiskMigrationIterator(new ManiphestTask()) as $task) { 16 + $id = $task->getID(); 17 + echo "Migrating T{$id}...\n"; 18 + 19 + $status = $task->getStatus(); 20 + if (isset($status_map[$status])) { 21 + queryfx( 22 + $conn_w, 23 + 'UPDATE %T SET status = %s WHERE id = %d', 24 + $task->getTableName(), 25 + $status_map[$status], 26 + $id); 27 + } 28 + } 29 + 30 + echo "Done.\n"; 31 + 32 + 33 + echo "Migrating task transactions to new status constants...\n"; 34 + foreach (new LiskMigrationIterator(new ManiphestTransaction()) as $xaction) { 35 + $id = $xaction->getID(); 36 + echo "Migrating {$id}...\n"; 37 + 38 + if ($xaction->getTransactionType() == ManiphestTransaction::TYPE_STATUS) { 39 + $old = $xaction->getOldValue(); 40 + if ($old !== null && isset($status_map[$old])) { 41 + $old = $status_map[$old]; 42 + } 43 + 44 + $new = $xaction->getNewValue(); 45 + if (isset($status_map[$new])) { 46 + $new = $status_map[$new]; 47 + } 48 + 49 + queryfx( 50 + $conn_w, 51 + 'UPDATE %T SET oldValue = %s, newValue = %s WHERE id = %d', 52 + $xaction->getTableName(), 53 + json_encode($old), 54 + json_encode($new), 55 + $id); 56 + } 57 + } 58 + echo "Done.\n"; 59 + 60 + $conn_w = id(new PhabricatorSavedQuery())->establishConnection('w'); 61 + 62 + echo "Migrating searches to new status constants...\n"; 63 + foreach (new LiskMigrationIterator(new PhabricatorSavedQuery()) as $query) { 64 + $id = $query->getID(); 65 + echo "Migrating {$id}...\n"; 66 + 67 + if ($query->getEngineClassName() !== 'ManiphestTaskSearchEngine') { 68 + continue; 69 + } 70 + 71 + $params = $query->getParameters(); 72 + $statuses = idx($params, 'statuses', array()); 73 + if ($statuses) { 74 + $changed = false; 75 + foreach ($statuses as $key => $status) { 76 + if (isset($status_map[$status])) { 77 + $statuses[$key] = $status_map[$status]; 78 + $changed = true; 79 + } 80 + } 81 + 82 + if ($changed) { 83 + $params['statuses'] = $statuses; 84 + 85 + queryfx( 86 + $conn_w, 87 + 'UPDATE %T SET parameters = %s WHERE id = %d', 88 + $query->getTableName(), 89 + json_encode($params), 90 + $id); 91 + } 92 + } 93 + } 94 + echo "Done.\n";
+6 -6
src/applications/maniphest/constants/ManiphestTaskStatus.php
··· 2 2 3 3 final class ManiphestTaskStatus extends ManiphestConstants { 4 4 5 - const STATUS_OPEN = 0; 6 - const STATUS_CLOSED_RESOLVED = 1; 7 - const STATUS_CLOSED_WONTFIX = 2; 8 - const STATUS_CLOSED_INVALID = 3; 9 - const STATUS_CLOSED_DUPLICATE = 4; 10 - const STATUS_CLOSED_SPITE = 5; 5 + const STATUS_OPEN = 'open'; 6 + const STATUS_CLOSED_RESOLVED = 'resolved'; 7 + const STATUS_CLOSED_WONTFIX = 'wontfix'; 8 + const STATUS_CLOSED_INVALID = 'invalid'; 9 + const STATUS_CLOSED_DUPLICATE = 'duplicate'; 10 + const STATUS_CLOSED_SPITE = 'spite'; 11 11 12 12 const SPECIAL_DEFAULT = 'default'; 13 13 const SPECIAL_CLOSED = 'closed';
-1
src/applications/maniphest/controller/ManiphestReportController.php
··· 660 660 661 661 $open_status_list = array(); 662 662 foreach (ManiphestTaskStatus::getOpenStatusConstants() as $constant) { 663 - $open_status_list[] = json_encode((int)$constant); 664 663 $open_status_list[] = json_encode((string)$constant); 665 664 } 666 665
+2 -2
src/applications/maniphest/editor/ManiphestTransactionEditor.php
··· 40 40 if ($this->getIsNewObject()) { 41 41 return null; 42 42 } 43 - return (int)$object->getStatus(); 43 + return $object->getStatus(); 44 44 case ManiphestTransaction::TYPE_TITLE: 45 45 if ($this->getIsNewObject()) { 46 46 return null; ··· 75 75 76 76 switch ($xaction->getTransactionType()) { 77 77 case ManiphestTransaction::TYPE_PRIORITY: 78 - case ManiphestTransaction::TYPE_STATUS: 79 78 return (int)$xaction->getNewValue(); 80 79 case ManiphestTransaction::TYPE_CCS: 81 80 case ManiphestTransaction::TYPE_PROJECTS: 82 81 return array_values(array_unique($xaction->getNewValue())); 83 82 case ManiphestTransaction::TYPE_OWNER: 84 83 return nonempty($xaction->getNewValue(), null); 84 + case ManiphestTransaction::TYPE_STATUS: 85 85 case ManiphestTransaction::TYPE_TITLE: 86 86 case ManiphestTransaction::TYPE_DESCRIPTION: 87 87 case ManiphestTransaction::TYPE_ATTACH:
+6 -6
src/applications/maniphest/query/ManiphestTaskQuery.php
··· 351 351 case self::STATUS_OPEN: 352 352 return qsprintf( 353 353 $conn, 354 - 'status IN (%Ld)', 354 + 'status IN (%Ls)', 355 355 ManiphestTaskStatus::getOpenStatusConstants()); 356 356 case self::STATUS_CLOSED: 357 357 return qsprintf( 358 358 $conn, 359 - 'status IN (%Ld)', 359 + 'status IN (%Ls)', 360 360 ManiphestTaskStatus::getClosedStatusConstants()); 361 361 default: 362 362 $constant = idx($map, $this->status); ··· 365 365 } 366 366 return qsprintf( 367 367 $conn, 368 - 'status = %d', 368 + 'status = %s', 369 369 $constant); 370 370 } 371 371 } ··· 374 374 if ($this->statuses) { 375 375 return qsprintf( 376 376 $conn, 377 - 'status IN (%Ld)', 377 + 'status IN (%Ls)', 378 378 $this->statuses); 379 379 } 380 380 return null; ··· 826 826 case self::GROUP_STATUS: 827 827 $columns[] = array( 828 828 'name' => 'task.status', 829 - 'value' => (int)$group_id, 830 - 'type' => 'int', 829 + 'value' => $group_id, 830 + 'type' => 'string', 831 831 ); 832 832 break; 833 833 case self::GROUP_PROJECT: