Skip to content
This repository has been archived by the owner on May 8, 2024. It is now read-only.

Commit

Permalink
Add prototype assembling functionallity
Browse files Browse the repository at this point in the history
  • Loading branch information
DASPRiD committed Mar 26, 2013
1 parent 603abbe commit 87f1d36
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 9 deletions.
16 changes: 13 additions & 3 deletions library/Zend/Mvc/Router/Http/Chain.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Zend\Mvc\Router\Http;

use ArrayObject;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Mvc\Router\PriorityList;
Expand Down Expand Up @@ -40,13 +41,14 @@ class Chain extends TreeRouteStack implements RouteInterface
*
* @param array $routes
* @param RoutePluginManager $routePlugins
* @throws Exception\InvalidArgumentException
* @param ArrayObject $prototypes
*/
public function __construct(array $routes, RoutePluginManager $routePlugins)
public function __construct(array $routes, RoutePluginManager $routePlugins, ArrayObject $prototypes)
{
$this->chainRoutes = array_reverse($routes);
$this->routePluginManager = $routePlugins;
$this->routes = new PriorityList();
$this->prototypes = $prototypes;
}

/**
Expand All @@ -69,6 +71,10 @@ public static function factory($options = array())
throw new Exception\InvalidArgumentException('Missing "route" in options array');
}

if (!isset($options['prototypes'])) {
throw new Exception\InvalidArgumentException('Missing "prototypes" in options array');
}

if ($options['routes'] instanceof Traversable) {
$options['routes'] = ArrayUtils::iteratorToArray($options['child_routes']);
}
Expand All @@ -77,7 +83,11 @@ public static function factory($options = array())
throw new Exception\InvalidArgumentException('Missing "route_plugins" in options array');
}

return new static($options['routes'], $options['route_plugins']);
return new static(
$options['routes'],
$options['route_plugins'],
$options['prototypes']
);
}

/**
Expand Down
19 changes: 16 additions & 3 deletions library/Zend/Mvc/Router/Http/Part.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Zend\Mvc\Router\Http;

use ArrayObject;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Mvc\Router\PriorityList;
Expand Down Expand Up @@ -48,12 +49,13 @@ class Part extends TreeRouteStack implements RouteInterface
* Create a new part route.
*
* @param mixed $route
* @param bool $mayTerminate
* @param bool $mayTerminate
* @param RoutePluginManager $routePlugins
* @param array|null $childRoutes
* @param ArrayObject $prototypes
* @throws Exception\InvalidArgumentException
*/
public function __construct($route, $mayTerminate, RoutePluginManager $routePlugins, array $childRoutes = null)
public function __construct($route, $mayTerminate, RoutePluginManager $routePlugins, array $childRoutes = null, ArrayObject $prototypes = null)
{
$this->routePluginManager = $routePlugins;

Expand All @@ -68,6 +70,7 @@ public function __construct($route, $mayTerminate, RoutePluginManager $routePlug
$this->route = $route;
$this->mayTerminate = $mayTerminate;
$this->childRoutes = $childRoutes;
$this->prototypes = $prototypes;
$this->routes = new PriorityList();
}

Expand Down Expand Up @@ -95,6 +98,10 @@ public static function factory($options = array())
throw new Exception\InvalidArgumentException('Missing "route_plugins" in options array');
}

if (!isset($options['prototypes'])) {
$options['prototypes'] = null;
}

if (!isset($options['may_terminate'])) {
$options['may_terminate'] = false;
}
Expand All @@ -106,7 +113,13 @@ public static function factory($options = array())
$options['child_routes'] = ArrayUtils::iteratorToArray($options['child_routes']);
}

return new static($options['route'], $options['may_terminate'], $options['route_plugins'], $options['child_routes']);
return new static(
$options['route'],
$options['may_terminate'],
$options['route_plugins'],
$options['child_routes'],
$options['prototypes']
);
}

/**
Expand Down
105 changes: 102 additions & 3 deletions library/Zend/Mvc/Router/Http/TreeRouteStack.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Zend\Mvc\Router\Http;

use ArrayObject;
use Traversable;
use Zend\Mvc\Router\Exception;
use Zend\Mvc\Router\SimpleRouteStack;
Expand All @@ -35,13 +36,50 @@ class TreeRouteStack extends SimpleRouteStack
*/
protected $requestUri;

/**
* Prototype routes.
*
* We use an ArrayObject in this case so we can easily pass it down the tree
* by reference.
*
* @var ArrayObject
*/
protected $prototypes;

/**
* factory(): defined by RouteInterface interface.
*
* @see \Zend\Mvc\Router\RouteInterface::factory()
* @param array|Traversable $options
* @return SimpleRouteStack
* @throws Exception\InvalidArgumentException
*/
public static function factory($options = array())
{
if ($options instanceof Traversable) {
$options = ArrayUtils::iteratorToArray($options);
} elseif (!is_array($options)) {
throw new Exception\InvalidArgumentException(__METHOD__ . ' expects an array or Traversable set of options');
}

$instance = parent::factory($options);

if (isset($options['prototypes'])) {
$instance->addPrototypes($options['prototypes']);
}

return $instance;
}

/**
* init(): defined by SimpleRouteStack.
*
* @see SimpleRouteStack::init()
*/
protected function init()
{
$this->prototypes = new ArrayObject;

$routes = $this->routePluginManager;
foreach (array(
'hostname' => __NAMESPACE__ . '\Hostname',
Expand Down Expand Up @@ -82,15 +120,21 @@ public function addRoute($name, $route, $priority = null)
* routeFromArray(): defined by SimpleRouteStack.
*
* @see SimpleRouteStack::routeFromArray()
* @param array|Traversable $specs
* @param string|array|Traversable $specs
* @return RouteInterface
* @throws Exception\InvalidArgumentException When route definition is not an array nor traversable
* @throws Exception\InvalidArgumentException When chain routes are not an array nor traversable
* @throws Exception\RuntimeException When a generated routes does not implement the HTTP route interface
*/
protected function routeFromArray($specs)
{
if ($specs instanceof Traversable) {
if (is_string($specs)) {
if (null === ($route = $this->getPrototype($specs))) {
throw new Exception\RuntimeException(sprintf('Could not find prototype with name %s', $specs));
}

return $route;
} elseif ($specs instanceof Traversable) {
$specs = ArrayUtils::iteratorToArray($specs);
} elseif (!is_array($specs)) {
throw new Exception\InvalidArgumentException('Route definition must be an array or Traversable object');
Expand All @@ -106,7 +150,8 @@ protected function routeFromArray($specs)

$options = array(
'routes' => $chainRoutes,
'route_plugins' => $this->routePluginManager
'route_plugins' => $this->routePluginManager,
'prototypes' => $this->prototypes,
);

$route = $this->routePluginManager->get('chain', $options);
Expand All @@ -124,6 +169,7 @@ protected function routeFromArray($specs)
'may_terminate' => (isset($specs['may_terminate']) && $specs['may_terminate']),
'child_routes' => $specs['child_routes'],
'route_plugins' => $this->routePluginManager,
'prototypes' => $this->prototypes,
);

$priority = (isset($route->priority) ? $route->priority : null);
Expand All @@ -135,6 +181,59 @@ protected function routeFromArray($specs)
return $route;
}

/**
* Add multiple prototypes at once.
*
* @param Traversable $routes
* @return TreeRouteStack
* @throws Exception\InvalidArgumentException
*/
public function addPrototypes($routes)
{
if (!is_array($routes) && !$routes instanceof Traversable) {
throw new Exception\InvalidArgumentException('addPrototypes expects an array or Traversable set of routes');
}

foreach ($routes as $name => $route) {
$this->addPrototype($name, $route);
}

return $this;
}

/**
* Add a prototype.
*
* @param string $name
* @param mixed $route
* @return TreeRouteStack
*/
public function addPrototype($name, $route)
{
if (!$route instanceof RouteInterface) {
$route = $this->routeFromArray($route);
}

$this->prototypes[$name] = $route;

return $this;
}

/**
* Get a prototype.
*
* @param string $name
* @return RouterInterface|null
*/
public function getPrototype($name)
{
if (isset($this->prototypes[$name])) {
return $this->prototypes[$name];
}

return null;
}

/**
* match(): defined by \Zend\Mvc\Router\RouteInterface
*
Expand Down

0 comments on commit 87f1d36

Please sign in to comment.