Added the zend framework 2 library, the path is specified in line no.26 in zend_modul...
[openemr.git] / interface / modules / zend_modules / library / Zend / Mvc / Router / Http / TreeRouteStack.php
blobc6b8c94f7c03f799e20ffdf9fa4358389da8b2ae
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Mvc\Router\Http;
12 use ArrayObject;
13 use Traversable;
14 use Zend\Mvc\Router\Exception;
15 use Zend\Mvc\Router\SimpleRouteStack;
16 use Zend\Stdlib\ArrayUtils;
17 use Zend\Stdlib\RequestInterface as Request;
18 use Zend\Uri\Http as HttpUri;
20 /**
21 * Tree search implementation.
23 class TreeRouteStack extends SimpleRouteStack
25 /**
26 * Base URL.
28 * @var string
30 protected $baseUrl;
32 /**
33 * Request URI.
35 * @var HttpUri
37 protected $requestUri;
39 /**
40 * Prototype routes.
42 * We use an ArrayObject in this case so we can easily pass it down the tree
43 * by reference.
45 * @var ArrayObject
47 protected $prototypes;
49 /**
50 * factory(): defined by RouteInterface interface.
52 * @see \Zend\Mvc\Router\RouteInterface::factory()
53 * @param array|Traversable $options
54 * @return SimpleRouteStack
55 * @throws Exception\InvalidArgumentException
57 public static function factory($options = array())
59 if ($options instanceof Traversable) {
60 $options = ArrayUtils::iteratorToArray($options);
61 } elseif (!is_array($options)) {
62 throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable set of options');
65 $instance = parent::factory($options);
67 if (isset($options['prototypes'])) {
68 $instance->addPrototypes($options['prototypes']);
71 return $instance;
74 /**
75 * init(): defined by SimpleRouteStack.
77 * @see SimpleRouteStack::init()
79 protected function init()
81 $this->prototypes = new ArrayObject;
83 $routes = $this->routePluginManager;
84 foreach (array(
85 'chain' => __NAMESPACE__ . '\Chain',
86 'hostname' => __NAMESPACE__ . '\Hostname',
87 'literal' => __NAMESPACE__ . '\Literal',
88 'method' => __NAMESPACE__ . '\Method',
89 'part' => __NAMESPACE__ . '\Part',
90 'query' => __NAMESPACE__ . '\Query',
91 'regex' => __NAMESPACE__ . '\Regex',
92 'scheme' => __NAMESPACE__ . '\Scheme',
93 'segment' => __NAMESPACE__ . '\Segment',
94 'wildcard' => __NAMESPACE__ . '\Wildcard',
95 ) as $name => $class
96 ) {
97 $routes->setInvokableClass($name, $class);
102 * addRoute(): defined by RouteStackInterface interface.
104 * @see RouteStackInterface::addRoute()
105 * @param string $name
106 * @param mixed $route
107 * @param int $priority
108 * @return TreeRouteStack
110 public function addRoute($name, $route, $priority = null)
112 if (!$route instanceof RouteInterface) {
113 $route = $this->routeFromArray($route);
116 return parent::addRoute($name, $route, $priority);
120 * routeFromArray(): defined by SimpleRouteStack.
122 * @see SimpleRouteStack::routeFromArray()
123 * @param string|array|Traversable $specs
124 * @return RouteInterface
125 * @throws Exception\InvalidArgumentException When route definition is not an array nor traversable
126 * @throws Exception\InvalidArgumentException When chain routes are not an array nor traversable
127 * @throws Exception\RuntimeException When a generated routes does not implement the HTTP route interface
129 protected function routeFromArray($specs)
131 if (is_string($specs)) {
132 if (null === ($route = $this->getPrototype($specs))) {
133 throw new Exception\RuntimeException(sprintf('Could not find prototype with name %s', $specs));
136 return $route;
137 } elseif ($specs instanceof Traversable) {
138 $specs = ArrayUtils::iteratorToArray($specs);
139 } elseif (!is_array($specs)) {
140 throw new Exception\InvalidArgumentException('Route definition must be an array or Traversable object');
143 if (isset($specs['chain_routes'])) {
144 if (!is_array($specs['chain_routes'])) {
145 throw new Exception\InvalidArgumentException('Chain routes must be an array or Traversable object');
148 $chainRoutes = array_merge(array($specs), $specs['chain_routes']);
149 unset($chainRoutes[0]['chain_routes']);
151 $options = array(
152 'routes' => $chainRoutes,
153 'route_plugins' => $this->routePluginManager,
154 'prototypes' => $this->prototypes,
157 $route = $this->routePluginManager->get('chain', $options);
158 } else {
159 $route = parent::routeFromArray($specs);
162 if (!$route instanceof RouteInterface) {
163 throw new Exception\RuntimeException('Given route does not implement HTTP route interface');
166 if (isset($specs['child_routes'])) {
167 $options = array(
168 'route' => $route,
169 'may_terminate' => (isset($specs['may_terminate']) && $specs['may_terminate']),
170 'child_routes' => $specs['child_routes'],
171 'route_plugins' => $this->routePluginManager,
172 'prototypes' => $this->prototypes,
175 $priority = (isset($route->priority) ? $route->priority : null);
177 $route = $this->routePluginManager->get('part', $options);
178 $route->priority = $priority;
181 return $route;
185 * Add multiple prototypes at once.
187 * @param Traversable $routes
188 * @return TreeRouteStack
189 * @throws Exception\InvalidArgumentException
191 public function addPrototypes($routes)
193 if (!is_array($routes) && !$routes instanceof Traversable) {
194 throw new Exception\InvalidArgumentException('addPrototypes expects an array or Traversable set of routes');
197 foreach ($routes as $name => $route) {
198 $this->addPrototype($name, $route);
201 return $this;
205 * Add a prototype.
207 * @param string $name
208 * @param mixed $route
209 * @return TreeRouteStack
211 public function addPrototype($name, $route)
213 if (!$route instanceof RouteInterface) {
214 $route = $this->routeFromArray($route);
217 $this->prototypes[$name] = $route;
219 return $this;
223 * Get a prototype.
225 * @param string $name
226 * @return RouteInterface|null
228 public function getPrototype($name)
230 if (isset($this->prototypes[$name])) {
231 return $this->prototypes[$name];
234 return null;
238 * match(): defined by \Zend\Mvc\Router\RouteInterface
240 * @see \Zend\Mvc\Router\RouteInterface::match()
241 * @param Request $request
242 * @param integer|null $pathOffset
243 * @param array $options
244 * @return RouteMatch|null
246 public function match(Request $request, $pathOffset = null, array $options = array())
248 if (!method_exists($request, 'getUri')) {
249 return null;
252 if ($this->baseUrl === null && method_exists($request, 'getBaseUrl')) {
253 $this->setBaseUrl($request->getBaseUrl());
256 $uri = $request->getUri();
257 $baseUrlLength = strlen($this->baseUrl) ?: null;
259 if ($pathOffset !== null) {
260 $baseUrlLength += $pathOffset;
263 if ($this->requestUri === null) {
264 $this->setRequestUri($uri);
267 if ($baseUrlLength !== null) {
268 $pathLength = strlen($uri->getPath()) - $baseUrlLength;
269 } else {
270 $pathLength = null;
273 foreach ($this->routes as $name => $route) {
274 if (
275 ($match = $route->match($request, $baseUrlLength, $options)) instanceof RouteMatch
276 && ($pathLength === null || $match->getLength() === $pathLength)
278 $match->setMatchedRouteName($name);
280 foreach ($this->defaultParams as $paramName => $value) {
281 if ($match->getParam($paramName) === null) {
282 $match->setParam($paramName, $value);
286 return $match;
290 return null;
294 * assemble(): defined by \Zend\Mvc\Router\RouteInterface interface.
296 * @see \Zend\Mvc\Router\RouteInterface::assemble()
297 * @param array $params
298 * @param array $options
299 * @return mixed
300 * @throws Exception\InvalidArgumentException
301 * @throws Exception\RuntimeException
303 public function assemble(array $params = array(), array $options = array())
305 if (!isset($options['name'])) {
306 throw new Exception\InvalidArgumentException('Missing "name" option');
309 $names = explode('/', $options['name'], 2);
310 $route = $this->routes->get($names[0]);
312 if (!$route) {
313 throw new Exception\RuntimeException(sprintf('Route with name "%s" not found', $names[0]));
316 if (isset($names[1])) {
317 if (!$route instanceof TreeRouteStack) {
318 throw new Exception\RuntimeException(sprintf('Route with name "%s" does not have child routes', $names[0]));
320 $options['name'] = $names[1];
321 } else {
322 unset($options['name']);
325 if (isset($options['only_return_path']) && $options['only_return_path']) {
326 return $this->baseUrl . $route->assemble(array_merge($this->defaultParams, $params), $options);
329 if (!isset($options['uri'])) {
330 $uri = new HttpUri();
332 if (isset($options['force_canonical']) && $options['force_canonical']) {
333 if ($this->requestUri === null) {
334 throw new Exception\RuntimeException('Request URI has not been set');
337 $uri->setScheme($this->requestUri->getScheme())
338 ->setHost($this->requestUri->getHost())
339 ->setPort($this->requestUri->getPort());
342 $options['uri'] = $uri;
343 } else {
344 $uri = $options['uri'];
347 $path = $this->baseUrl . $route->assemble(array_merge($this->defaultParams, $params), $options);
349 if (isset($options['query'])) {
350 $uri->setQuery($options['query']);
353 if (isset($options['fragment'])) {
354 $uri->setFragment($options['fragment']);
357 if ((isset($options['force_canonical']) && $options['force_canonical']) || $uri->getHost() !== null || $uri->getScheme() !== null) {
358 if (($uri->getHost() === null || $uri->getScheme() === null) && $this->requestUri === null) {
359 throw new Exception\RuntimeException('Request URI has not been set');
362 if ($uri->getHost() === null) {
363 $uri->setHost($this->requestUri->getHost());
366 if ($uri->getScheme() === null) {
367 $uri->setScheme($this->requestUri->getScheme());
370 return $uri->setPath($path)->normalize()->toString();
371 } elseif (!$uri->isAbsolute() && $uri->isValidRelative()) {
372 return $uri->setPath($path)->normalize()->toString();
375 return $path;
379 * Set the base URL.
381 * @param string $baseUrl
382 * @return self
384 public function setBaseUrl($baseUrl)
386 $this->baseUrl = rtrim($baseUrl, '/');
387 return $this;
391 * Get the base URL.
393 * @return string
395 public function getBaseUrl()
397 return $this->baseUrl;
401 * Set the request URI.
403 * @param HttpUri $uri
404 * @return TreeRouteStack
406 public function setRequestUri(HttpUri $uri)
408 $this->requestUri = $uri;
409 return $this;
413 * Get the request URI.
415 * @return HttpUri
417 public function getRequestUri()
419 return $this->requestUri;