@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

Move generateDiffusionURI() into PhabricatorRepository

Summary: Ref T4245. This further reduces the reliance on callsigns in Diffusion.

Test Plan:
- Pretty reasonable test coverage already exists.
- Browsed repository list, browse view, history view, content view, change view, commit view, tag view, branch view of repositories.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4245

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

+154 -195
+7 -9
src/applications/diffusion/controller/DiffusionExternalController.php
··· 45 45 46 46 if ($best_match) { 47 47 $repository = $repositories[$best_match]; 48 - $redirect = DiffusionRequest::generateDiffusionURI( 48 + $redirect = $repository->generateURI( 49 49 array( 50 - 'action' => 'browse', 51 - 'repository' => $repository, 52 - 'branch' => $repository->getDefaultBranch(), 53 - 'commit' => $id, 50 + 'action' => 'browse', 51 + 'branch' => $repository->getDefaultBranch(), 52 + 'commit' => $id, 54 53 )); 54 + 55 55 return id(new AphrontRedirectResponse())->setURI($redirect); 56 56 } 57 57 } ··· 83 83 } else if (count($commits) == 1) { 84 84 $commit = head($commits); 85 85 $repo = $repositories[$commit->getRepositoryID()]; 86 - $redirect = DiffusionRequest::generateDiffusionURI( 86 + $redirect = $repo->generateURI( 87 87 array( 88 88 'action' => 'browse', 89 - 'repository' => $repo, 90 89 'branch' => $repo->getDefaultBranch(), 91 90 'commit' => $commit->getCommitIdentifier(), 92 91 )); ··· 96 95 $rows = array(); 97 96 foreach ($commits as $commit) { 98 97 $repo = $repositories[$commit->getRepositoryID()]; 99 - $href = DiffusionRequest::generateDiffusionURI( 98 + $href = $repo->generateURI( 100 99 array( 101 100 'action' => 'browse', 102 - 'repository' => $repo, 103 101 'branch' => $repo->getDefaultBranch(), 104 102 'commit' => $commit->getCommitIdentifier(), 105 103 ));
+2 -171
src/applications/diffusion/request/DiffusionRequest.php
··· 448 448 /* -( Managing Diffusion URIs )-------------------------------------------- */ 449 449 450 450 451 - /** 452 - * Generate a Diffusion URI using this request to provide defaults. See 453 - * @{method:generateDiffusionURI} for details. This method is the same, but 454 - * preserves the request parameters if they are not overridden. 455 - * 456 - * @param map See @{method:generateDiffusionURI}. 457 - * @return PhutilURI Generated URI. 458 - * @task uri 459 - */ 460 451 public function generateURI(array $params) { 461 452 if (empty($params['stable'])) { 462 453 $default_commit = $this->getSymbolicCommit(); ··· 465 456 } 466 457 467 458 $defaults = array( 468 - 'repository' => $this->getRepository(), 469 459 'path' => $this->getPath(), 470 460 'branch' => $this->getBranch(), 471 461 'commit' => $default_commit, 472 462 'lint' => idx($params, 'lint', $this->getLint()), 473 463 ); 464 + 474 465 foreach ($defaults as $key => $val) { 475 466 if (!isset($params[$key])) { // Overwrite NULL. 476 467 $params[$key] = $val; 477 468 } 478 469 } 479 - return self::generateDiffusionURI($params); 480 - } 481 470 482 - 483 - /** 484 - * Generate a Diffusion URI from a parameter map. Applies the correct encoding 485 - * and formatting to the URI. Parameters are: 486 - * 487 - * - `action` One of `history`, `browse`, `change`, `lastmodified`, 488 - * `branch`, `tags`, `branches`, or `revision-ref`. The action specified 489 - * by the URI. 490 - * - `repository` Repository. 491 - * - `callsign` Repository callsign. 492 - * - `branch` Optional if action is not `branch`, branch name. 493 - * - `path` Optional, path to file. 494 - * - `commit` Optional, commit identifier. 495 - * - `line` Optional, line range. 496 - * - `lint` Optional, lint code. 497 - * - `params` Optional, query parameters. 498 - * 499 - * The function generates the specified URI and returns it. 500 - * 501 - * @param map See documentation. 502 - * @return PhutilURI Generated URI. 503 - * @task uri 504 - */ 505 - public static function generateDiffusionURI(array $params) { 506 - $action = idx($params, 'action'); 507 - 508 - $repository = idx($params, 'repository'); 509 - 510 - if ($repository) { 511 - $callsign = $repository->getCallsign(); 512 - } else { 513 - $callsign = idx($params, 'callsign'); 514 - } 515 - 516 - $path = idx($params, 'path'); 517 - $branch = idx($params, 'branch'); 518 - $commit = idx($params, 'commit'); 519 - $line = idx($params, 'line'); 520 - 521 - if (strlen($callsign)) { 522 - $callsign = phutil_escape_uri_path_component($callsign).'/'; 523 - } 524 - 525 - if (strlen($branch)) { 526 - $branch = phutil_escape_uri_path_component($branch).'/'; 527 - } 528 - 529 - if (strlen($path)) { 530 - $path = ltrim($path, '/'); 531 - $path = str_replace(array(';', '$'), array(';;', '$$'), $path); 532 - $path = phutil_escape_uri($path); 533 - } 534 - 535 - $path = "{$branch}{$path}"; 536 - 537 - if (strlen($commit)) { 538 - $commit = str_replace('$', '$$', $commit); 539 - $commit = ';'.phutil_escape_uri($commit); 540 - } 541 - 542 - if (strlen($line)) { 543 - $line = '$'.phutil_escape_uri($line); 544 - } 545 - 546 - $req_callsign = false; 547 - $req_branch = false; 548 - $req_commit = false; 549 - 550 - switch ($action) { 551 - case 'history': 552 - case 'browse': 553 - case 'change': 554 - case 'lastmodified': 555 - case 'tags': 556 - case 'branches': 557 - case 'lint': 558 - case 'refs': 559 - $req_callsign = true; 560 - break; 561 - case 'branch': 562 - $req_callsign = true; 563 - $req_branch = true; 564 - break; 565 - case 'commit': 566 - $req_callsign = true; 567 - $req_commit = true; 568 - break; 569 - } 570 - 571 - if ($req_callsign && !strlen($callsign)) { 572 - throw new Exception( 573 - pht( 574 - "Diffusion URI action '%s' requires callsign!", 575 - $action)); 576 - } 577 - 578 - if ($req_commit && !strlen($commit)) { 579 - throw new Exception( 580 - pht( 581 - "Diffusion URI action '%s' requires commit!", 582 - $action)); 583 - } 584 - 585 - switch ($action) { 586 - case 'change': 587 - case 'history': 588 - case 'browse': 589 - case 'lastmodified': 590 - case 'tags': 591 - case 'branches': 592 - case 'lint': 593 - case 'pathtree': 594 - case 'refs': 595 - $uri = "/diffusion/{$callsign}{$action}/{$path}{$commit}{$line}"; 596 - break; 597 - case 'branch': 598 - if (strlen($path)) { 599 - $uri = "/diffusion/{$callsign}repository/{$path}"; 600 - } else { 601 - $uri = "/diffusion/{$callsign}"; 602 - } 603 - break; 604 - case 'external': 605 - $commit = ltrim($commit, ';'); 606 - $uri = "/diffusion/external/{$commit}/"; 607 - break; 608 - case 'rendering-ref': 609 - // This isn't a real URI per se, it's passed as a query parameter to 610 - // the ajax changeset stuff but then we parse it back out as though 611 - // it came from a URI. 612 - $uri = rawurldecode("{$path}{$commit}"); 613 - break; 614 - case 'commit': 615 - $commit = ltrim($commit, ';'); 616 - $callsign = rtrim($callsign, '/'); 617 - $uri = "/r{$callsign}{$commit}"; 618 - break; 619 - default: 620 - throw new Exception(pht("Unknown Diffusion URI action '%s'!", $action)); 621 - } 622 - 623 - if ($action == 'rendering-ref') { 624 - return $uri; 625 - } 626 - 627 - $uri = new PhutilURI($uri); 628 - 629 - if (isset($params['lint'])) { 630 - $params['params'] = idx($params, 'params', array()) + array( 631 - 'lint' => $params['lint'], 632 - ); 633 - } 634 - 635 - if (idx($params, 'params')) { 636 - $uri->setQueryParams($params['params']); 637 - } 638 - 639 - return $uri; 471 + return $this->getRepository()->generateURI($params); 640 472 } 641 - 642 473 643 474 /** 644 475 * Internal. Public only for unit tests.
+8 -11
src/applications/diffusion/request/__tests__/DiffusionURITestCase.php
··· 86 86 } 87 87 88 88 public function testURIGeneration() { 89 + $actor = PhabricatorUser::getOmnipotentUser(); 90 + 91 + $repository = PhabricatorRepository::initializeNewRepository($actor) 92 + ->setCallsign('A') 93 + ->makeEphemeral(); 94 + 89 95 $map = array( 90 96 '/diffusion/A/browse/branch/path.ext;abc$1' => array( 91 97 'action' => 'browse', 92 - 'callsign' => 'A', 93 98 'branch' => 'branch', 94 99 'path' => 'path.ext', 95 100 'commit' => 'abc', ··· 97 102 ), 98 103 '/diffusion/A/browse/a%252Fb/path.ext' => array( 99 104 'action' => 'browse', 100 - 'callsign' => 'A', 101 105 'branch' => 'a/b', 102 106 'path' => 'path.ext', 103 107 ), 104 108 '/diffusion/A/browse/%2B/%20%21' => array( 105 109 'action' => 'browse', 106 - 'callsign' => 'A', 107 110 'path' => '+/ !', 108 111 ), 109 112 '/diffusion/A/browse/money/%24%24100$2' => array( 110 113 'action' => 'browse', 111 - 'callsign' => 'A', 112 114 'path' => 'money/$100', 113 115 'line' => '2', 114 116 ), 115 117 '/diffusion/A/browse/path/to/file.ext?view=things' => array( 116 118 'action' => 'browse', 117 - 'callsign' => 'A', 118 119 'path' => 'path/to/file.ext', 119 120 'params' => array( 120 121 'view' => 'things', ··· 122 123 ), 123 124 '/diffusion/A/repository/master/' => array( 124 125 'action' => 'branch', 125 - 'callsign' => 'A', 126 126 'branch' => 'master', 127 127 ), 128 128 'path/to/file.ext;abc' => array( ··· 132 132 ), 133 133 '/diffusion/A/browse/branch/path.ext$3-5%2C7-12%2C14' => array( 134 134 'action' => 'browse', 135 - 'callsign' => 'A', 136 135 'branch' => 'branch', 137 136 'path' => 'path.ext', 138 137 'line' => '3-5,7-12,14', ··· 140 139 ); 141 140 142 141 foreach ($map as $expect => $input) { 143 - $actual = DiffusionRequest::generateDiffusionURI($input); 144 - $this->assertEqual( 145 - $expect, 146 - (string)$actual); 142 + $actual = $repository->generateURI($input); 143 + $this->assertEqual($expect, (string)$actual); 147 144 } 148 145 } 149 146
+1 -2
src/applications/owners/controller/PhabricatorOwnersDetailController.php
··· 268 268 if (!$repo) { 269 269 continue; 270 270 } 271 - $href = DiffusionRequest::generateDiffusionURI( 271 + $href = $repo->generateURI( 272 272 array( 273 - 'repository' => $repo, 274 273 'branch' => $repo->getDefaultBranch(), 275 274 'path' => $path->getPath(), 276 275 'action' => 'browse',
+1 -2
src/applications/repository/query/PhabricatorRepositorySearchEngine.php
··· 175 175 176 176 $size = $repository->getCommitCount(); 177 177 if ($size) { 178 - $history_uri = DiffusionRequest::generateDiffusionURI( 178 + $history_uri = $repository->generateURI( 179 179 array( 180 - 'repository' => $repository, 181 180 'action' => 'history', 182 181 )); 183 182
+135
src/applications/repository/storage/PhabricatorRepository.php
··· 610 610 return "/r{$callsign}{$identifier}"; 611 611 } 612 612 613 + public function generateURI(array $params) { 614 + $req_branch = false; 615 + $req_commit = false; 616 + 617 + $action = idx($params, 'action'); 618 + switch ($action) { 619 + case 'history': 620 + case 'browse': 621 + case 'change': 622 + case 'lastmodified': 623 + case 'tags': 624 + case 'branches': 625 + case 'lint': 626 + case 'pathtree': 627 + case 'refs': 628 + break; 629 + case 'branch': 630 + $req_branch = true; 631 + break; 632 + case 'commit': 633 + case 'rendering-ref': 634 + $req_commit = true; 635 + break; 636 + default: 637 + throw new Exception( 638 + pht( 639 + 'Action "%s" is not a valid repository URI action.', 640 + $action)); 641 + } 642 + 643 + $path = idx($params, 'path'); 644 + $branch = idx($params, 'branch'); 645 + $commit = idx($params, 'commit'); 646 + $line = idx($params, 'line'); 647 + 648 + if ($req_commit && !strlen($commit)) { 649 + throw new Exception( 650 + pht( 651 + 'Diffusion URI action "%s" requires commit!', 652 + $action)); 653 + } 654 + 655 + if ($req_branch && !strlen($branch)) { 656 + throw new Exception( 657 + pht( 658 + 'Diffusion URI action "%s" requires branch!', 659 + $action)); 660 + } 661 + 662 + if ($action === 'commit') { 663 + return $this->getCommitURI($commit); 664 + } 665 + 666 + 667 + $identifier = $this->getID(); 668 + 669 + $callsign = $this->getCallsign(); 670 + if ($callsign !== null) { 671 + $identifier = $callsign; 672 + } 673 + 674 + if (strlen($identifier)) { 675 + $identifier = phutil_escape_uri_path_component($identifier); 676 + } 677 + 678 + if (strlen($path)) { 679 + $path = ltrim($path, '/'); 680 + $path = str_replace(array(';', '$'), array(';;', '$$'), $path); 681 + $path = phutil_escape_uri($path); 682 + } 683 + 684 + if (strlen($branch)) { 685 + $branch = phutil_escape_uri_path_component($branch); 686 + $path = "{$branch}/{$path}"; 687 + } 688 + 689 + if (strlen($commit)) { 690 + $commit = str_replace('$', '$$', $commit); 691 + $commit = ';'.phutil_escape_uri($commit); 692 + } 693 + 694 + if (strlen($line)) { 695 + $line = '$'.phutil_escape_uri($line); 696 + } 697 + 698 + switch ($action) { 699 + case 'change': 700 + case 'history': 701 + case 'browse': 702 + case 'lastmodified': 703 + case 'tags': 704 + case 'branches': 705 + case 'lint': 706 + case 'pathtree': 707 + case 'refs': 708 + $uri = "/diffusion/{$identifier}/{$action}/{$path}{$commit}{$line}"; 709 + break; 710 + case 'branch': 711 + if (strlen($path)) { 712 + $uri = "/diffusion/{$identifier}/repository/{$path}"; 713 + } else { 714 + $uri = "/diffusion/{$identifier}/"; 715 + } 716 + break; 717 + case 'external': 718 + $commit = ltrim($commit, ';'); 719 + $uri = "/diffusion/external/{$commit}/"; 720 + break; 721 + case 'rendering-ref': 722 + // This isn't a real URI per se, it's passed as a query parameter to 723 + // the ajax changeset stuff but then we parse it back out as though 724 + // it came from a URI. 725 + $uri = rawurldecode("{$path}{$commit}"); 726 + break; 727 + } 728 + 729 + if ($action == 'rendering-ref') { 730 + return $uri; 731 + } 732 + 733 + $uri = new PhutilURI($uri); 734 + 735 + if (isset($params['lint'])) { 736 + $params['params'] = idx($params, 'params', array()) + array( 737 + 'lint' => $params['lint'], 738 + ); 739 + } 740 + 741 + if (idx($params, 'params')) { 742 + $uri->setQueryParams($params['params']); 743 + } 744 + 745 + return $uri; 746 + } 747 + 613 748 public function getNormalizedPath() { 614 749 $uri = (string)$this->getCloneURIObject(); 615 750