[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PhabricatorJumpNavHandler { 4 5 public static function getJumpResponse(PhabricatorUser $viewer, $jump) { 6 $jump = trim($jump); 7 $help_href = PhabricatorEnv::getDocLink('Jump Nav User Guide'); 8 9 $patterns = array( 10 '/^help/i' => 'uri:'.$help_href, 11 '/^a$/i' => 'uri:/audit/', 12 '/^f$/i' => 'uri:/feed/', 13 '/^d$/i' => 'uri:/differential/', 14 '/^r$/i' => 'uri:/diffusion/', 15 '/^t$/i' => 'uri:/maniphest/', 16 '/^p$/i' => 'uri:/project/', 17 '/^u$/i' => 'uri:/people/', 18 '/^p\s+(.+)$/i' => 'project', 19 '/^u\s+(\S+)$/i' => 'user', 20 '/^task:\s*(.+)/i' => 'create-task', 21 '/^(?:s|symbol)\s+(\S+)/i' => 'find-symbol', 22 '/^r\s+(.+)$/i' => 'find-repository', 23 ); 24 25 foreach ($patterns as $pattern => $effect) { 26 $matches = null; 27 if (preg_match($pattern, $jump, $matches)) { 28 if (!strncmp($effect, 'uri:', 4)) { 29 return id(new AphrontRedirectResponse()) 30 ->setURI(substr($effect, 4)); 31 } else { 32 switch ($effect) { 33 case 'user': 34 return id(new AphrontRedirectResponse()) 35 ->setURI('/p/'.$matches[1].'/'); 36 case 'project': 37 $project = self::findCloselyNamedProject($matches[1]); 38 if ($project) { 39 return id(new AphrontRedirectResponse()) 40 ->setURI('/project/view/'.$project->getID().'/'); 41 } else { 42 $jump = $matches[1]; 43 } 44 break; 45 case 'find-symbol': 46 $context = ''; 47 $symbol = $matches[1]; 48 $parts = array(); 49 if (preg_match('/(.*)(?:\\.|::|->)(.*)/', $symbol, $parts)) { 50 $context = '&context='.phutil_escape_uri($parts[1]); 51 $symbol = $parts[2]; 52 } 53 return id(new AphrontRedirectResponse()) 54 ->setURI("/diffusion/symbol/$symbol/?jump=true$context"); 55 case 'find-repository': 56 $name = $matches[1]; 57 $repositories = id(new PhabricatorRepositoryQuery()) 58 ->setViewer($viewer) 59 ->withNameContains($name) 60 ->execute(); 61 if (count($repositories) == 1) { 62 // Just one match, jump to repository. 63 $uri = '/diffusion/'.head($repositories)->getCallsign().'/'; 64 } else { 65 // More than one match, jump to search. 66 $uri = urisprintf('/diffusion/?order=name&name=%s', $name); 67 } 68 return id(new AphrontRedirectResponse())->setURI($uri); 69 case 'create-task': 70 return id(new AphrontRedirectResponse()) 71 ->setURI('/maniphest/task/create/?title=' 72 .phutil_escape_uri($matches[1])); 73 default: 74 throw new Exception("Unknown jump effect '{$effect}'!"); 75 } 76 } 77 } 78 } 79 80 // If none of the patterns matched, look for an object by name. 81 $objects = id(new PhabricatorObjectQuery()) 82 ->setViewer($viewer) 83 ->withNames(array($jump)) 84 ->execute(); 85 86 if (count($objects) == 1) { 87 $handle = id(new PhabricatorHandleQuery()) 88 ->setViewer($viewer) 89 ->withPHIDs(mpull($objects, 'getPHID')) 90 ->executeOne(); 91 92 return id(new AphrontRedirectResponse())->setURI($handle->getURI()); 93 } 94 95 return null; 96 } 97 98 private static function findCloselyNamedProject($name) { 99 $project = id(new PhabricatorProject())->loadOneWhere( 100 'name = %s', 101 $name); 102 if ($project) { 103 return $project; 104 } else { // no exact match, try a fuzzy match 105 $projects = id(new PhabricatorProject())->loadAllWhere( 106 'name LIKE %~', 107 $name); 108 if ($projects) { 109 $min_name_length = PHP_INT_MAX; 110 $best_project = null; 111 foreach ($projects as $project) { 112 $name_length = strlen($project->getName()); 113 if ($name_length <= $min_name_length) { 114 $min_name_length = $name_length; 115 $best_project = $project; 116 } 117 } 118 return $best_project; 119 } else { 120 return null; 121 } 122 } 123 } 124 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |