mirror of
https://we.phorge.it/source/phorge.git
synced 2025-03-08 10:24:48 +01:00
Summary: Fixes T6630. Long ago, "Audit", "Diffusion" and "Repositories" were three totally separate applications. This separation isn't useful and the three rapidly became intertwined. Ideally, they would all be one application. This doesn't take us quite that far, but Audit no longer has any controllers and has little actual behavior. The "Audit" screen has always just been a SearchEngine view of commits with some filters on it, and this formalizes that and puts a link to it in Diffusion. (This view has other uses, too.) Test Plan: - Accessed audit from home page. - Accessed audit/commits from Diffusion. - Could no longer uninstall Audit on its own. - Grepped for `/audit/` and `AuditApplication`. Reviewers: chad Reviewed By: chad Maniphest Tasks: T6630 Differential Revision: https://secure.phabricator.com/D17186
117 lines
3.8 KiB
PHP
117 lines
3.8 KiB
PHP
<?php
|
|
|
|
final class PhabricatorJumpNavHandler extends Phobject {
|
|
|
|
public static function getJumpResponse(PhabricatorUser $viewer, $jump) {
|
|
$jump = trim($jump);
|
|
|
|
$patterns = array(
|
|
'/^a$/i' => 'uri:/diffusion/commit/',
|
|
'/^f$/i' => 'uri:/feed/',
|
|
'/^d$/i' => 'uri:/differential/',
|
|
'/^r$/i' => 'uri:/diffusion/',
|
|
'/^t$/i' => 'uri:/maniphest/',
|
|
'/^p$/i' => 'uri:/project/',
|
|
'/^u$/i' => 'uri:/people/',
|
|
'/^p\s+(.+)$/i' => 'project',
|
|
'/^u\s+(\S+)$/i' => 'user',
|
|
'/^(?:s)\s+(\S+)/i' => 'find-symbol',
|
|
'/^r\s+(.+)$/i' => 'find-repository',
|
|
);
|
|
|
|
foreach ($patterns as $pattern => $effect) {
|
|
$matches = null;
|
|
if (preg_match($pattern, $jump, $matches)) {
|
|
if (!strncmp($effect, 'uri:', 4)) {
|
|
return id(new AphrontRedirectResponse())
|
|
->setURI(substr($effect, 4));
|
|
} else {
|
|
switch ($effect) {
|
|
case 'user':
|
|
return id(new AphrontRedirectResponse())
|
|
->setURI('/p/'.$matches[1].'/');
|
|
case 'project':
|
|
$project = self::findCloselyNamedProject($matches[1]);
|
|
if ($project) {
|
|
return id(new AphrontRedirectResponse())
|
|
->setURI('/project/view/'.$project->getID().'/');
|
|
} else {
|
|
$jump = $matches[1];
|
|
}
|
|
break;
|
|
case 'find-symbol':
|
|
$context = '';
|
|
$symbol = $matches[1];
|
|
$parts = array();
|
|
if (preg_match('/(.*)(?:\\.|::|->)(.*)/', $symbol, $parts)) {
|
|
$context = '&context='.phutil_escape_uri($parts[1]);
|
|
$symbol = $parts[2];
|
|
}
|
|
return id(new AphrontRedirectResponse())
|
|
->setURI("/diffusion/symbol/$symbol/?jump=true$context");
|
|
case 'find-repository':
|
|
$name = $matches[1];
|
|
$repositories = id(new PhabricatorRepositoryQuery())
|
|
->setViewer($viewer)
|
|
->withNameContains($name)
|
|
->execute();
|
|
if (count($repositories) == 1) {
|
|
// Just one match, jump to repository.
|
|
$uri = head($repositories)->getURI();
|
|
} else {
|
|
// More than one match, jump to search.
|
|
$uri = urisprintf('/diffusion/?order=name&name=%s', $name);
|
|
}
|
|
return id(new AphrontRedirectResponse())->setURI($uri);
|
|
default:
|
|
throw new Exception(pht("Unknown jump effect '%s'!", $effect));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// If none of the patterns matched, look for an object by name.
|
|
$objects = id(new PhabricatorObjectQuery())
|
|
->setViewer($viewer)
|
|
->withNames(array($jump))
|
|
->execute();
|
|
|
|
if (count($objects) == 1) {
|
|
$handle = id(new PhabricatorHandleQuery())
|
|
->setViewer($viewer)
|
|
->withPHIDs(mpull($objects, 'getPHID'))
|
|
->executeOne();
|
|
|
|
return id(new AphrontRedirectResponse())->setURI($handle->getURI());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static function findCloselyNamedProject($name) {
|
|
$project = id(new PhabricatorProject())->loadOneWhere(
|
|
'name = %s',
|
|
$name);
|
|
if ($project) {
|
|
return $project;
|
|
} else { // no exact match, try a fuzzy match
|
|
$projects = id(new PhabricatorProject())->loadAllWhere(
|
|
'name LIKE %~',
|
|
$name);
|
|
if ($projects) {
|
|
$min_name_length = PHP_INT_MAX;
|
|
$best_project = null;
|
|
foreach ($projects as $project) {
|
|
$name_length = strlen($project->getName());
|
|
if ($name_length <= $min_name_length) {
|
|
$min_name_length = $name_length;
|
|
$best_project = $project;
|
|
}
|
|
}
|
|
return $best_project;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|