Page MenuHomec4science

AphrontRoutingMap.php
No OneTemporary

File Metadata

Created
Wed, Jul 10, 14:51

AphrontRoutingMap.php

<?php
/**
* Collection of routes on a site for an application.
*
* @task info Map Information
* @task routing Routing
*/
final class AphrontRoutingMap extends Phobject {
private $site;
private $application;
private $routes = array();
/* -( Map Info )----------------------------------------------------------- */
public function setSite(AphrontSite $site) {
$this->site = $site;
return $this;
}
public function getSite() {
return $this->site;
}
public function setApplication(PhabricatorApplication $application) {
$this->application = $application;
return $this;
}
public function getApplication() {
return $this->application;
}
public function setRoutes(array $routes) {
$this->routes = $routes;
return $this;
}
public function getRoutes() {
return $this->routes;
}
/* -( Routing )------------------------------------------------------------ */
/**
* Find the route matching a path, if one exists.
*
* @param string Path to route.
* @return AphrontRoutingResult|null Routing result, if path matches map.
* @task routing
*/
public function routePath($path) {
$map = $this->getRoutes();
foreach ($map as $route => $value) {
$match = $this->tryRoute($route, $value, $path);
if (!$match) {
continue;
}
$result = $this->newRoutingResult();
$application = $result->getApplication();
$controller_class = $match['class'];
$controller = newv($controller_class, array());
$controller->setCurrentApplication($application);
$result
->setController($controller)
->setURIData($match['data']);
return $result;
}
return null;
}
/**
* Test a sub-map to see if any routes match a path.
*
* @param string Path to route.
* @param string Pattern from the map.
* @param string Value from the map.
* @return dict<string, wild>|null Match details, if path matches sub-map.
* @task routing
*/
private function tryRoute($route, $value, $path) {
$has_submap = is_array($value);
if (!$has_submap) {
// If the value is a controller rather than a sub-map, any matching
// route must completely consume the path.
$pattern = '(^'.$route.'\z)';
} else {
$pattern = '(^'.$route.')';
}
$data = null;
$ok = preg_match($pattern, $path, $data);
if ($ok === false) {
throw new Exception(
pht(
'Routing fragment "%s" is not a valid regular expression.',
$route));
}
if (!$ok) {
return null;
}
$path_match = $data[0];
// Clean up the data. We only want to retain named capturing groups, not
// the duplicated numeric captures.
foreach ($data as $k => $v) {
if (is_numeric($k)) {
unset($data[$k]);
}
}
if (!$has_submap) {
return array(
'class' => $value,
'data' => $data,
);
}
$sub_path = substr($path, strlen($path_match));
foreach ($value as $sub_route => $sub_value) {
$result = $this->tryRoute($sub_route, $sub_value, $sub_path);
if ($result) {
$result['data'] += $data;
return $result;
}
}
return null;
}
/**
* Build a new routing result for this map.
*
* @return AphrontRoutingResult New, empty routing result.
* @task routing
*/
private function newRoutingResult() {
return id(new AphrontRoutingResult())
->setSite($this->getSite())
->setApplication($this->getApplication());
}
}

Event Timeline