3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Mvc\Router\Http
;
14 use Zend\Mvc\Router\Exception
;
15 use Zend\Mvc\Router\PriorityList
;
16 use Zend\Mvc\Router\RoutePluginManager
;
17 use Zend\Stdlib\ArrayUtils
;
18 use Zend\Stdlib\RequestInterface
as Request
;
23 class Chain
extends TreeRouteStack
implements RouteInterface
30 protected $chainRoutes;
33 * List of assembled parameters.
37 protected $assembledParams = [];
40 * Create a new part route.
42 * @param array $routes
43 * @param RoutePluginManager $routePlugins
44 * @param ArrayObject|null $prototypes
46 public function __construct(array $routes, RoutePluginManager
$routePlugins, ArrayObject
$prototypes = null)
48 $this->chainRoutes
= array_reverse($routes);
49 $this->routePluginManager
= $routePlugins;
50 $this->routes
= new PriorityList();
51 $this->prototypes
= $prototypes;
55 * factory(): defined by RouteInterface interface.
57 * @see \Zend\Mvc\Router\RouteInterface::factory()
58 * @param mixed $options
59 * @throws Exception\InvalidArgumentException
62 public static function factory($options = [])
64 if ($options instanceof Traversable
) {
65 $options = ArrayUtils
::iteratorToArray($options);
66 } elseif (!is_array($options)) {
67 throw new Exception\
InvalidArgumentException(__METHOD__
. ' expects an array or Traversable set of options');
70 if (!isset($options['routes'])) {
71 throw new Exception\
InvalidArgumentException('Missing "routes" in options array');
74 if (!isset($options['prototypes'])) {
75 $options['prototypes'] = null;
78 if ($options['routes'] instanceof Traversable
) {
79 $options['routes'] = ArrayUtils
::iteratorToArray($options['child_routes']);
82 if (!isset($options['route_plugins'])) {
83 throw new Exception\
InvalidArgumentException('Missing "route_plugins" in options array');
88 $options['route_plugins'],
89 $options['prototypes']
94 * match(): defined by RouteInterface interface.
96 * @see \Zend\Mvc\Router\RouteInterface::match()
97 * @param Request $request
98 * @param int|null $pathOffset
99 * @param array $options
100 * @return RouteMatch|null
102 public function match(Request
$request, $pathOffset = null, array $options = [])
104 if (!method_exists($request, 'getUri')) {
108 if ($pathOffset === null) {
109 $mustTerminate = true;
112 $mustTerminate = false;
115 if ($this->chainRoutes
!== null) {
116 $this->addRoutes($this->chainRoutes
);
117 $this->chainRoutes
= null;
120 $match = new RouteMatch([]);
121 $uri = $request->getUri();
122 $pathLength = strlen($uri->getPath());
124 foreach ($this->routes
as $route) {
125 $subMatch = $route->match($request, $pathOffset, $options);
127 if ($subMatch === null) {
131 $match->merge($subMatch);
132 $pathOffset +
= $subMatch->getLength();
135 if ($mustTerminate && $pathOffset !== $pathLength) {
143 * assemble(): Defined by RouteInterface interface.
145 * @see \Zend\Mvc\Router\RouteInterface::assemble()
146 * @param array $params
147 * @param array $options
150 public function assemble(array $params = [], array $options = [])
152 if ($this->chainRoutes
!== null) {
153 $this->addRoutes($this->chainRoutes
);
154 $this->chainRoutes
= null;
157 $this->assembledParams
= [];
159 $routes = ArrayUtils
::iteratorToArray($this->routes
);
162 $lastRouteKey = key($routes);
165 foreach ($routes as $key => $route) {
166 $chainOptions = $options;
167 $hasChild = isset($options['has_child']) ?
$options['has_child'] : false;
169 $chainOptions['has_child'] = ($hasChild ||
$key !== $lastRouteKey);
171 $path .= $route->assemble($params, $chainOptions);
172 $params = array_diff_key($params, array_flip($route->getAssembledParams()));
174 $this->assembledParams +
= $route->getAssembledParams();
181 * getAssembledParams(): defined by RouteInterface interface.
183 * @see RouteInterface::getAssembledParams
186 public function getAssembledParams()
188 return $this->assembledParams
;