[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/search/engine/ -> PhabricatorJumpNavHandler.php (source)

   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  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1