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

Show task duplicates as related objects in Maniphest and migrate old duplicates

Summary: Does the UI work that's part of T12234 and adds migrations for both of the old-style duplicate transactions.

Test Plan:
- Started with a clean DB.
- Checked out really old code that marks tasks as dupes using comments.
- Made a bunch of tasks and closed some as dupes. Made a bunch of additional comments.
- Checked out D10427 and did a `storage upgrade`.
- Made a bunch more new tasks and dupes.
- Snapshotted DB.
- Ran migration repeatedly until all expected edges showed up in the `phabricator_maniphest.edge`table.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

Maniphest Tasks: T12234

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

+96
+68
resources/sql/autopatches/20170528.maniphestdupes.php
··· 1 + <?php 2 + 3 + $table = new ManiphestTransaction(); 4 + $add_edges = array(); 5 + 6 + foreach (new LiskMigrationIterator($table) as $txn) { 7 + $txn_type = $txn->getTransactionType(); 8 + 9 + if ($txn_type == 'mergedinto') { 10 + // dupe handling as implemented in D10427, which creates a specific txn 11 + $add_edges[] = array( 12 + 'src' => $txn->getObjectPHID(), 13 + 'dst' => $txn->getNewValue(), 14 + ); 15 + } else if ($txn_type == 'status' && $txn->getNewValue() == 'duplicate') { 16 + // dupe handling as originally implemented, which just changes the status 17 + // and adds a comment 18 + $src_phid = $txn->getObjectPHID(); 19 + 20 + // get all the comment transactions associated with this task 21 + $viewer = PhabricatorUser::getOmnipotentUser(); 22 + $comment_txns = id(new ManiphestTransactionQuery()) 23 + ->setViewer($viewer) 24 + ->withObjectPHIDs(array($src_phid)) 25 + ->needComments(true) 26 + ->execute(); 27 + 28 + // check each comment, looking for the "Merged Into" message 29 + foreach ($comment_txns as $comment_txn) { 30 + if ($comment_txn->hasComment()) { 31 + $comment = $comment_txn->getComment()->getContent(); 32 + $pattern = '/^\xE2\x9C\x98 Merged into T(\d+)\.$/'; 33 + $matches = array(); 34 + 35 + if (preg_match($pattern, $comment, $matches)) { 36 + $dst_task = id(new ManiphestTaskQuery()) 37 + ->setViewer($viewer) 38 + ->withIDs(array($matches[1])) 39 + ->executeOne(); 40 + 41 + if ($dst_task) { 42 + $dst_phid = $dst_task->getPHID(); 43 + $add_edges[] = array( 44 + 'src' => $src_phid, 45 + 'dst' => $dst_phid, 46 + ); 47 + } 48 + } 49 + } 50 + } 51 + } 52 + } 53 + 54 + if ($add_edges) { 55 + foreach ($add_edges as $edge) { 56 + $src_phid = $edge['src']; 57 + $dst_phid = $edge['dst']; 58 + 59 + $type = ManiphestTaskIsDuplicateOfTaskEdgeType::EDGECONST; 60 + try { 61 + $editor = id(new PhabricatorEdgeEditor()) 62 + ->addEdge($src_phid, $type, $dst_phid) 63 + ->save(); 64 + } catch (PhabricatorEdgeCycleException $ex) { 65 + // Some earlier or later merge made this invalid, just skip it. 66 + } 67 + } 68 + }
+28
src/applications/maniphest/controller/ManiphestTaskDetailController.php
··· 36 36 ManiphestTaskHasMockEdgeType::EDGECONST, 37 37 PhabricatorObjectMentionedByObjectEdgeType::EDGECONST, 38 38 PhabricatorObjectMentionsObjectEdgeType::EDGECONST, 39 + ManiphestTaskHasDuplicateTaskEdgeType::EDGECONST, 39 40 ); 40 41 41 42 $phid = $task->getPHID(); ··· 159 160 160 161 $related_tabs[] = $this->newMocksTab($task, $query); 161 162 $related_tabs[] = $this->newMentionsTab($task, $query); 163 + $related_tabs[] = $this->newDuplicatesTab($task, $query); 162 164 163 165 $tab_view = null; 164 166 ··· 550 552 return id(new PHUITabView()) 551 553 ->setName(pht('Mentions')) 552 554 ->setKey('mentions') 555 + ->appendChild($view); 556 + } 557 + 558 + private function newDuplicatesTab( 559 + ManiphestTask $task, 560 + PhabricatorEdgeQuery $edge_query) { 561 + 562 + $in_type = ManiphestTaskHasDuplicateTaskEdgeType::EDGECONST; 563 + $in_phids = $edge_query->getDestinationPHIDs(array(), array($in_type)); 564 + 565 + $viewer = $this->getViewer(); 566 + $in_handles = $viewer->loadHandles($in_phids); 567 + $in_handles = $this->getCompleteHandles($in_handles); 568 + 569 + $view = new PHUIPropertyListView(); 570 + 571 + if (!count($in_handles)) { 572 + return null; 573 + } 574 + 575 + $view->addProperty( 576 + pht('Duplicates Merged Here'), $in_handles->renderList()); 577 + 578 + return id(new PHUITabView()) 579 + ->setName(pht('Duplicates')) 580 + ->setKey('duplicates') 553 581 ->appendChild($view); 554 582 } 555 583