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

Modernize task/revision edges and write inverse transactions

Summary:
Ref T5245. See some discussion in D9838.

When we attach object A to object B, we'd like to write transactions on both sides but only write the actual edges once.

To do this, allow edge types to `shouldWriteInverseTransactions()`. When an edge type opts into this, have editors apply the inverse transactions before writing the edge. These inverse transactions don't actually apply effects, they just show up in the transaction log.

Test Plan: Attached and detached revisions from tasks, saw transactions appear on both sides of the operation.

Reviewers: chad, btrahan, joshuaspence

Reviewed By: btrahan, joshuaspence

Subscribers: epriestley

Maniphest Tasks: T5245

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

+323 -37
+1 -1
resources/sql/patches/migrate-maniphest-revisions.php
··· 19 19 foreach ($revs as $rev) { 20 20 $editor->addEdge( 21 21 $task->getPHID(), 22 - PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV, 22 + ManiphestTaskHasRevisionEdgeType::EDGECONST, 23 23 $rev); 24 24 } 25 25 $editor->save();
+4
src/__phutil_library_map__.php
··· 438 438 'DifferentialRevisionControlSystem' => 'applications/differential/constants/DifferentialRevisionControlSystem.php', 439 439 'DifferentialRevisionDetailView' => 'applications/differential/view/DifferentialRevisionDetailView.php', 440 440 'DifferentialRevisionEditController' => 'applications/differential/controller/DifferentialRevisionEditController.php', 441 + 'DifferentialRevisionHasTaskEdgeType' => 'applications/differential/edge/DifferentialRevisionHasTaskEdgeType.php', 441 442 'DifferentialRevisionIDField' => 'applications/differential/customfield/DifferentialRevisionIDField.php', 442 443 'DifferentialRevisionLandController' => 'applications/differential/controller/DifferentialRevisionLandController.php', 443 444 'DifferentialRevisionListController' => 'applications/differential/controller/DifferentialRevisionListController.php', ··· 944 945 'ManiphestTaskDescriptionPreviewController' => 'applications/maniphest/controller/ManiphestTaskDescriptionPreviewController.php', 945 946 'ManiphestTaskDetailController' => 'applications/maniphest/controller/ManiphestTaskDetailController.php', 946 947 'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php', 948 + 'ManiphestTaskHasRevisionEdgeType' => 'applications/maniphest/edge/ManiphestTaskHasRevisionEdgeType.php', 947 949 'ManiphestTaskListController' => 'applications/maniphest/controller/ManiphestTaskListController.php', 948 950 'ManiphestTaskListView' => 'applications/maniphest/view/ManiphestTaskListView.php', 949 951 'ManiphestTaskMailReceiver' => 'applications/maniphest/mail/ManiphestTaskMailReceiver.php', ··· 3153 3155 ), 3154 3156 'DifferentialRevisionDetailView' => 'AphrontView', 3155 3157 'DifferentialRevisionEditController' => 'DifferentialController', 3158 + 'DifferentialRevisionHasTaskEdgeType' => 'PhabricatorEdgeType', 3156 3159 'DifferentialRevisionIDField' => 'DifferentialCustomField', 3157 3160 'DifferentialRevisionLandController' => 'DifferentialController', 3158 3161 'DifferentialRevisionListController' => 'DifferentialController', ··· 3700 3703 'ManiphestTaskDescriptionPreviewController' => 'ManiphestController', 3701 3704 'ManiphestTaskDetailController' => 'ManiphestController', 3702 3705 'ManiphestTaskEditController' => 'ManiphestController', 3706 + 'ManiphestTaskHasRevisionEdgeType' => 'PhabricatorEdgeType', 3703 3707 'ManiphestTaskListController' => 'ManiphestController', 3704 3708 'ManiphestTaskListView' => 'ManiphestView', 3705 3709 'ManiphestTaskMailReceiver' => 'PhabricatorObjectMailReceiver',
+2 -2
src/applications/differential/customfield/DifferentialManiphestTasksField.php
··· 42 42 43 43 return PhabricatorEdgeQuery::loadDestinationPHIDs( 44 44 $revision->getPHID(), 45 - PhabricatorEdgeConfig::TYPE_DREV_HAS_RELATED_TASK); 45 + DifferentialRevisionHasTaskEdgeType::EDGECONST); 46 46 } 47 47 48 48 public function getApplicationTransactionType() { ··· 51 51 52 52 public function getApplicationTransactionMetadata() { 53 53 return array( 54 - 'edge:type' => PhabricatorEdgeConfig::TYPE_DREV_HAS_RELATED_TASK, 54 + 'edge:type' => DifferentialRevisionHasTaskEdgeType::EDGECONST, 55 55 ); 56 56 } 57 57
+105
src/applications/differential/edge/DifferentialRevisionHasTaskEdgeType.php
··· 1 + <?php 2 + 3 + final class DifferentialRevisionHasTaskEdgeType extends PhabricatorEdgeType { 4 + 5 + const EDGECONST = 12; 6 + 7 + public function getInverseEdgeConstant() { 8 + return ManiphestTaskHasRevisionEdgeType::EDGECONST; 9 + } 10 + 11 + public function shouldWriteInverseTransactions() { 12 + return true; 13 + } 14 + 15 + public function getTransactionAddString( 16 + $actor, 17 + $add_count, 18 + $add_edges) { 19 + 20 + return pht( 21 + '%s added %s task(s): %s.', 22 + $actor, 23 + $add_count, 24 + $add_edges); 25 + } 26 + 27 + public function getTransactionRemoveString( 28 + $actor, 29 + $rem_count, 30 + $rem_edges) { 31 + 32 + return pht( 33 + '%s removed %s task(s): %s.', 34 + $actor, 35 + $rem_count, 36 + $rem_edges); 37 + } 38 + 39 + public function getTransactionEditString( 40 + $actor, 41 + $total_count, 42 + $add_count, 43 + $add_edges, 44 + $rem_count, 45 + $rem_edges) { 46 + 47 + return pht( 48 + '%s edited %s task(s), added %s: %s; removed %s: %s.', 49 + $actor, 50 + $total_count, 51 + $add_count, 52 + $add_edges, 53 + $rem_count, 54 + $rem_edges); 55 + } 56 + 57 + public function getFeedAddString( 58 + $actor, 59 + $object, 60 + $add_count, 61 + $add_edges) { 62 + 63 + return pht( 64 + '%s added %s task(s) to %s: %s.', 65 + $actor, 66 + $add_count, 67 + $object, 68 + $add_edges); 69 + } 70 + 71 + public function getFeedRemoveString( 72 + $actor, 73 + $object, 74 + $rem_count, 75 + $rem_edges) { 76 + 77 + return pht( 78 + '%s removed %s task(s) from %s: %s.', 79 + $actor, 80 + $rem_count, 81 + $object, 82 + $rem_edges); 83 + } 84 + 85 + public function getFeedEditString( 86 + $actor, 87 + $object, 88 + $total_count, 89 + $add_count, 90 + $add_edges, 91 + $rem_count, 92 + $rem_edges) { 93 + 94 + return pht( 95 + '%s edited %s task(s) for %s, added %s: %s; removed %s: %s.', 96 + $actor, 97 + $total_count, 98 + $object, 99 + $add_count, 100 + $add_edges, 101 + $rem_count, 102 + $rem_edges); 103 + } 104 + 105 + }
+2 -2
src/applications/differential/editor/DifferentialTransactionEditor.php
··· 254 254 $status_plan = ArcanistDifferentialRevisionStatus::CHANGES_PLANNED; 255 255 256 256 $edge_reviewer = PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER; 257 - $edge_ref_task = PhabricatorEdgeConfig::TYPE_DREV_HAS_RELATED_TASK; 257 + $edge_ref_task = DifferentialRevisionHasTaskEdgeType::EDGECONST; 258 258 259 259 $is_sticky_accept = PhabricatorEnv::getEnvConfig( 260 260 'differential.sticky-accept'); ··· 1250 1250 ->execute(); 1251 1251 1252 1252 if ($tasks) { 1253 - $edge_related = PhabricatorEdgeConfig::TYPE_DREV_HAS_RELATED_TASK; 1253 + $edge_related = DifferentialRevisionHasTaskEdgeType::EDGECONST; 1254 1254 $edges[$edge_related] = mpull($tasks, 'getPHID', 'getPHID'); 1255 1255 } 1256 1256 }
+1 -1
src/applications/differential/event/DifferentialHovercardEventListener.php
··· 28 28 29 29 $rev->loadRelationships(); 30 30 $reviewer_phids = $rev->getReviewers(); 31 - $e_task = PhabricatorEdgeConfig::TYPE_DREV_HAS_RELATED_TASK; 31 + $e_task = DifferentialRevisionHasTaskEdgeType::EDGECONST; 32 32 $edge_query = id(new PhabricatorEdgeQuery()) 33 33 ->withSourcePHIDs(array($phid)) 34 34 ->withEdgeTypes(
+7 -7
src/applications/maniphest/controller/ManiphestTaskDetailController.php
··· 54 54 $e_commit = PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT; 55 55 $e_dep_on = PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK; 56 56 $e_dep_by = PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK; 57 - $e_rev = PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV; 57 + $e_rev = ManiphestTaskHasRevisionEdgeType::EDGECONST; 58 58 $e_mock = PhabricatorEdgeConfig::TYPE_TASK_HAS_MOCK; 59 59 60 60 $phid = $task->getPHID(); ··· 590 590 591 591 $edge_types = array( 592 592 PhabricatorEdgeConfig::TYPE_TASK_DEPENDED_ON_BY_TASK 593 - => pht('Blocks'), 593 + => pht('Blocks'), 594 594 PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK 595 - => pht('Blocked By'), 596 - PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV 597 - => pht('Differential Revisions'), 595 + => pht('Blocked By'), 596 + ManiphestTaskHasRevisionEdgeType::EDGECONST 597 + => pht('Differential Revisions'), 598 598 PhabricatorEdgeConfig::TYPE_TASK_HAS_MOCK 599 - => pht('Pholio Mocks'), 599 + => pht('Pholio Mocks'), 600 600 ); 601 601 602 602 $revisions_commits = array(); ··· 616 616 $revision_phid = key($drev_edges[$phid][$commit_drev]); 617 617 $revision_handle = idx($handles, $revision_phid); 618 618 if ($revision_handle) { 619 - $task_drev = PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV; 619 + $task_drev = ManiphestTaskHasRevisionEdgeType::EDGECONST; 620 620 unset($edges[$task_drev][$revision_phid]); 621 621 $revisions_commits[$phid] = hsprintf( 622 622 '%s / %s',
+105
src/applications/maniphest/edge/ManiphestTaskHasRevisionEdgeType.php
··· 1 + <?php 2 + 3 + final class ManiphestTaskHasRevisionEdgeType extends PhabricatorEdgeType { 4 + 5 + const EDGECONST = 11; 6 + 7 + public function getInverseEdgeConstant() { 8 + return DifferentialRevisionHasTaskEdgeType::EDGECONST; 9 + } 10 + 11 + public function shouldWriteInverseTransactions() { 12 + return true; 13 + } 14 + 15 + public function getTransactionAddString( 16 + $actor, 17 + $add_count, 18 + $add_edges) { 19 + 20 + return pht( 21 + '%s added %s revision(s): %s.', 22 + $actor, 23 + $add_count, 24 + $add_edges); 25 + } 26 + 27 + public function getTransactionRemoveString( 28 + $actor, 29 + $rem_count, 30 + $rem_edges) { 31 + 32 + return pht( 33 + '%s removed %s revision(s): %s.', 34 + $actor, 35 + $rem_count, 36 + $rem_edges); 37 + } 38 + 39 + public function getTransactionEditString( 40 + $actor, 41 + $total_count, 42 + $add_count, 43 + $add_edges, 44 + $rem_count, 45 + $rem_edges) { 46 + 47 + return pht( 48 + '%s edited %s revision(s), added %s: %s; removed %s: %s.', 49 + $actor, 50 + $total_count, 51 + $add_count, 52 + $add_edges, 53 + $rem_count, 54 + $rem_edges); 55 + } 56 + 57 + public function getFeedAddString( 58 + $actor, 59 + $object, 60 + $add_count, 61 + $add_edges) { 62 + 63 + return pht( 64 + '%s added %s revision(s) to %s: %s.', 65 + $actor, 66 + $add_count, 67 + $object, 68 + $add_edges); 69 + } 70 + 71 + public function getFeedRemoveString( 72 + $actor, 73 + $object, 74 + $rem_count, 75 + $rem_edges) { 76 + 77 + return pht( 78 + '%s removed %s revision(s) from %s: %s.', 79 + $actor, 80 + $rem_count, 81 + $object, 82 + $rem_edges); 83 + } 84 + 85 + public function getFeedEditString( 86 + $actor, 87 + $object, 88 + $total_count, 89 + $add_count, 90 + $add_edges, 91 + $rem_count, 92 + $rem_edges) { 93 + 94 + return pht( 95 + '%s edited %s revision(s) for %s, added %s: %s; removed %s: %s.', 96 + $actor, 97 + $total_count, 98 + $object, 99 + $add_count, 100 + $add_edges, 101 + $rem_count, 102 + $rem_edges); 103 + } 104 + 105 + }
+2 -2
src/applications/search/controller/PhabricatorSearchAttachController.php
··· 295 295 $t_task => array( 296 296 $t_cmit => PhabricatorEdgeConfig::TYPE_TASK_HAS_COMMIT, 297 297 $t_task => PhabricatorEdgeConfig::TYPE_TASK_DEPENDS_ON_TASK, 298 - $t_drev => PhabricatorEdgeConfig::TYPE_TASK_HAS_RELATED_DREV, 298 + $t_drev => ManiphestTaskHasRevisionEdgeType::EDGECONST, 299 299 $t_mock => PhabricatorEdgeConfig::TYPE_TASK_HAS_MOCK, 300 300 ), 301 301 $t_drev => array( 302 302 $t_drev => PhabricatorEdgeConfig::TYPE_DREV_DEPENDS_ON_DREV, 303 - $t_task => PhabricatorEdgeConfig::TYPE_DREV_HAS_RELATED_TASK, 303 + $t_task => DifferentialRevisionHasTaskEdgeType::EDGECONST, 304 304 ), 305 305 $t_mock => array( 306 306 $t_task => PhabricatorEdgeConfig::TYPE_MOCK_HAS_TASK,
+83 -3
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 24 24 25 25 private $isPreview; 26 26 private $isHeraldEditor; 27 + private $isInverseEdgeEditor; 27 28 private $actingAsPHID; 28 29 private $disableEmail; 29 30 ··· 118 119 119 120 public function getIsPreview() { 120 121 return $this->isPreview; 122 + } 123 + 124 + public function setIsInverseEdgeEditor($is_inverse_edge_editor) { 125 + $this->isInverseEdgeEditor = $is_inverse_edge_editor; 126 + return $this; 127 + } 128 + 129 + public function getIsInverseEdgeEditor() { 130 + return $this->isInverseEdgeEditor; 121 131 } 122 132 123 133 public function setIsHeraldEditor($is_herald_editor) { ··· 377 387 378 388 break; 379 389 case PhabricatorTransactions::TYPE_EDGE: 390 + if ($this->getIsInverseEdgeEditor()) { 391 + // If we're writing an inverse edge transaction, don't actually 392 + // do anything. The initiating editor on the other side of the 393 + // transaction will take care of the edge writes. 394 + break; 395 + } 396 + 380 397 $old = $xaction->getOldValue(); 381 398 $new = $xaction->getNewValue(); 382 399 $src = $object->getPHID(); 383 - $type = $xaction->getMetadataValue('edge:type'); 400 + $const = $xaction->getMetadataValue('edge:type'); 401 + 402 + $type = PhabricatorEdgeType::getByConstant($const); 403 + if ($type->shouldWriteInverseTransactions()) { 404 + $this->applyInverseEdgeTransactions( 405 + $object, 406 + $xaction, 407 + $type->getInverseEdgeConstant()); 408 + } 384 409 385 410 foreach ($new as $dst_phid => $edge) { 386 411 $new[$dst_phid]['src'] = $src; ··· 395 420 continue; 396 421 } 397 422 } 398 - $editor->removeEdge($src, $type, $dst_phid); 423 + $editor->removeEdge($src, $const, $dst_phid); 399 424 } 400 425 401 426 foreach ($new as $dst_phid => $edge) { ··· 409 434 'data' => $edge['data'], 410 435 ); 411 436 412 - $editor->addEdge($src, $type, $dst_phid, $data); 437 + $editor->addEdge($src, $const, $dst_phid, $data); 413 438 } 414 439 415 440 $editor->save(); ··· 2333 2358 } 2334 2359 2335 2360 $editor->save(); 2361 + } 2362 + 2363 + private function applyInverseEdgeTransactions( 2364 + PhabricatorLiskDAO $object, 2365 + PhabricatorApplicationTransaction $xaction, 2366 + $inverse_type) { 2367 + 2368 + $old = $xaction->getOldValue(); 2369 + $new = $xaction->getNewValue(); 2370 + 2371 + $add = array_keys(array_diff_key($new, $old)); 2372 + $rem = array_keys(array_diff_key($old, $new)); 2373 + 2374 + $add = array_fuse($add); 2375 + $rem = array_fuse($rem); 2376 + $all = $add + $rem; 2377 + 2378 + $nodes = id(new PhabricatorObjectQuery()) 2379 + ->setViewer($this->requireActor()) 2380 + ->withPHIDs($all) 2381 + ->execute(); 2382 + 2383 + foreach ($nodes as $node) { 2384 + if (!($node instanceof PhabricatorApplicationTransactionInterface)) { 2385 + continue; 2386 + } 2387 + 2388 + $editor = $node->getApplicationTransactionEditor(); 2389 + $template = $node->getApplicationTransactionTemplate(); 2390 + $target = $node->getApplicationTransactionObject(); 2391 + 2392 + if (isset($add[$node->getPHID()])) { 2393 + $edge_edit_type = '+'; 2394 + } else { 2395 + $edge_edit_type = '-'; 2396 + } 2397 + 2398 + $template 2399 + ->setTransactionType($xaction->getTransactionType()) 2400 + ->setMetadataValue('edge:type', $inverse_type) 2401 + ->setNewValue( 2402 + array( 2403 + $edge_edit_type => array($object->getPHID() => $object->getPHID()), 2404 + )); 2405 + 2406 + $editor 2407 + ->setContinueOnNoEffect(true) 2408 + ->setContinueOnMissingFields(true) 2409 + ->setParentMessageID($this->getParentMessageID()) 2410 + ->setIsInverseEdgeEditor(true) 2411 + ->setActor($this->requireActor()) 2412 + ->setContentSource($this->getContentSource()); 2413 + 2414 + $editor->applyTransactions($target, array($template)); 2415 + } 2336 2416 } 2337 2417 2338 2418 }
+2 -16
src/infrastructure/edges/constants/PhabricatorEdgeConfig.php
··· 19 19 const TYPE_BLOG_HAS_BLOGGER = 9; 20 20 const TYPE_BLOGGER_HAS_BLOG = 10; 21 21 22 - const TYPE_TASK_HAS_RELATED_DREV = 11; 23 - const TYPE_DREV_HAS_RELATED_TASK = 12; 24 - 25 22 const TYPE_PROJ_MEMBER = 13; 26 23 const TYPE_MEMBER_OF_PROJ = 14; 27 24 ··· 137 134 return $map; 138 135 } 139 136 140 - public static function getInverse($edge_type) { 137 + private static function getInverse($edge_type) { 141 138 static $map = array( 142 139 self::TYPE_TASK_HAS_COMMIT => self::TYPE_COMMIT_HAS_TASK, 143 140 self::TYPE_COMMIT_HAS_TASK => self::TYPE_TASK_HAS_COMMIT, ··· 152 149 self::TYPE_POST_HAS_BLOG => self::TYPE_BLOG_HAS_POST, 153 150 self::TYPE_BLOG_HAS_BLOGGER => self::TYPE_BLOGGER_HAS_BLOG, 154 151 self::TYPE_BLOGGER_HAS_BLOG => self::TYPE_BLOG_HAS_BLOGGER, 155 - 156 - self::TYPE_TASK_HAS_RELATED_DREV => self::TYPE_DREV_HAS_RELATED_TASK, 157 - self::TYPE_DREV_HAS_RELATED_TASK => self::TYPE_TASK_HAS_RELATED_DREV, 158 152 159 153 self::TYPE_PROJ_MEMBER => self::TYPE_MEMBER_OF_PROJ, 160 154 self::TYPE_MEMBER_OF_PROJ => self::TYPE_PROJ_MEMBER, ··· 226 220 return idx($map, $edge_type); 227 221 } 228 222 229 - public static function shouldPreventCycles($edge_type) { 223 + private static function shouldPreventCycles($edge_type) { 230 224 static $map = array( 231 225 self::TYPE_TEST_NO_CYCLE => true, 232 226 self::TYPE_TASK_DEPENDS_ON_TASK => true, ··· 272 266 case self::TYPE_COMMIT_HAS_TASK: 273 267 case self::TYPE_TASK_DEPENDS_ON_TASK: 274 268 case self::TYPE_TASK_DEPENDED_ON_BY_TASK: 275 - case self::TYPE_DREV_HAS_RELATED_TASK: 276 269 case self::TYPE_MOCK_HAS_TASK: 277 270 return '%s edited task(s), added %d: %s; removed %d: %s.'; 278 271 case self::TYPE_DREV_DEPENDS_ON_DREV: 279 272 case self::TYPE_DREV_DEPENDED_ON_BY_DREV: 280 - case self::TYPE_TASK_HAS_RELATED_DREV: 281 273 case self::TYPE_COMMIT_HAS_DREV: 282 274 case self::TYPE_REVIEWER_FOR_DREV: 283 275 return '%s edited revision(s), added %d: %s; removed %d: %s.'; ··· 354 346 case self::TYPE_TASK_DEPENDED_ON_BY_TASK: 355 347 return '%s added %d blocked task(s): %s.'; 356 348 case self::TYPE_COMMIT_HAS_TASK: 357 - case self::TYPE_DREV_HAS_RELATED_TASK: 358 349 case self::TYPE_MOCK_HAS_TASK: 359 350 return '%s added %d task(s): %s.'; 360 351 case self::TYPE_DREV_DEPENDED_ON_BY_DREV: 361 - case self::TYPE_TASK_HAS_RELATED_DREV: 362 352 case self::TYPE_COMMIT_HAS_DREV: 363 353 case self::TYPE_REVIEWER_FOR_DREV: 364 354 return '%s added %d revision(s): %s.'; ··· 432 422 case self::TYPE_TASK_DEPENDED_ON_BY_TASK: 433 423 return '%s removed %d blocked task(s): %s.'; 434 424 case self::TYPE_COMMIT_HAS_TASK: 435 - case self::TYPE_DREV_HAS_RELATED_TASK: 436 425 case self::TYPE_MOCK_HAS_TASK: 437 426 return '%s removed %d task(s): %s.'; 438 427 case self::TYPE_DREV_DEPENDS_ON_DREV: 439 428 case self::TYPE_DREV_DEPENDED_ON_BY_DREV: 440 - case self::TYPE_TASK_HAS_RELATED_DREV: 441 429 case self::TYPE_COMMIT_HAS_DREV: 442 430 case self::TYPE_REVIEWER_FOR_DREV: 443 431 return '%s removed %d revision(s): %s.'; ··· 507 495 case self::TYPE_COMMIT_HAS_TASK: 508 496 case self::TYPE_TASK_DEPENDS_ON_TASK: 509 497 case self::TYPE_TASK_DEPENDED_ON_BY_TASK: 510 - case self::TYPE_DREV_HAS_RELATED_TASK: 511 498 case self::TYPE_MOCK_HAS_TASK: 512 499 return '%s updated tasks of %s.'; 513 500 case self::TYPE_DREV_DEPENDS_ON_DREV: 514 501 case self::TYPE_DREV_DEPENDED_ON_BY_DREV: 515 - case self::TYPE_TASK_HAS_RELATED_DREV: 516 502 case self::TYPE_COMMIT_HAS_DREV: 517 503 case self::TYPE_REVIEWER_FOR_DREV: 518 504 return '%s updated revisions of %s.';
+5 -3
src/infrastructure/edges/editor/PhabricatorEdgeEditor.php
··· 180 180 'data' => $data, 181 181 ); 182 182 183 - $inverse = PhabricatorEdgeConfig::getInverse($type); 184 - if ($inverse) { 183 + $type_obj = PhabricatorEdgeType::getByConstant($type); 184 + $inverse = $type_obj->getInverseEdgeConstant(); 185 + if ($inverse !== null) { 185 186 186 187 // If `inverse_data` is set, overwrite the edge data. Normally, just 187 188 // write the same data to the inverse edge. ··· 398 399 $edge_types[$edge['type']] = true; 399 400 } 400 401 foreach ($edge_types as $type => $ignored) { 401 - if (!PhabricatorEdgeConfig::shouldPreventCycles($type)) { 402 + $type_obj = PhabricatorEdgeType::getByConstant($type); 403 + if (!$type_obj->shouldPreventCycles()) { 402 404 unset($edge_types[$type]); 403 405 } 404 406 }
+4
src/infrastructure/edges/type/PhabricatorEdgeType.php
··· 42 42 return false; 43 43 } 44 44 45 + public function shouldWriteInverseTransactions() { 46 + return false; 47 + } 48 + 45 49 public function getTransactionAddString( 46 50 $actor, 47 51 $add_count,