public function setUp()
 {
     $this->globalFile = __DIR__ . '/TestAsset/Auth2/config/autoload/global.php';
     $this->localFile = __DIR__ . '/TestAsset/Auth2/config/autoload/local.php';
     copy($this->globalFile . '.dist', $this->globalFile);
     copy($this->localFile . '.dist', $this->localFile);
     $writer = new ConfigWriter();
     $global = new ConfigResource(require $this->globalFile, $this->globalFile, $writer);
     $local = new ConfigResource(require $this->localFile, $this->localFile, $writer);
     $moduleModel = $this->getMockBuilder('ZF\\Apigility\\Admin\\Model\\ModuleModel')->disableOriginalConstructor()->getMock();
     $model = new AuthenticationModel($global, $local, $moduleModel);
     $this->controller = new AuthenticationController($model);
     $this->plugins = new ControllerPluginManager();
     $this->plugins->setService('bodyParams', new BodyParams());
     $this->plugins->setService('bodyParam', new BodyParam());
     $this->plugins->setService('params', new Params());
     $this->controller->setPluginManager($this->plugins);
     $this->routeMatch = new RouteMatch([]);
     $this->routeMatch->setMatchedRouteName('zf-apigility/api/authentication');
     $this->event = new MvcEvent();
     $this->event->setRouteMatch($this->routeMatch);
     $config = (require __DIR__ . '/../../config/module.config.php');
     $router = new SimpleRouteStack();
     $router->addRoute('zf-apigility/api/authentication', $config['router']['routes']['zf-apigility']['child_routes']['api']['child_routes']['authentication']);
     $this->event->setRouter($router);
     $this->controller->setEvent($this->event);
 }
예제 #2
0
 public function setUp()
 {
     $this->controller = $controller = new RestController();
     $this->router = $router = new SimpleRouteStack();
     $route = new Segment('/resource[/[:id]]');
     $router->addRoute('resource', $route);
     $this->event = $event = new MvcEvent();
     $event->setRouter($router);
     $event->setRouteMatch(new RouteMatch([]));
     $controller->setEvent($event);
     $controller->setRoute('resource');
     $pluginManager = new PluginManager();
     $pluginManager->setService('bodyParams', new BodyParams());
     $controller->setPluginManager($pluginManager);
     $urlHelper = new UrlHelper();
     $urlHelper->setRouter($this->router);
     $serverUrlHelper = new ServerUrlHelper();
     $serverUrlHelper->setScheme('http');
     $serverUrlHelper->setHost('localhost.localdomain');
     $linksHelper = new HalHelper();
     $linksHelper->setUrlHelper($urlHelper);
     $linksHelper->setServerUrlHelper($serverUrlHelper);
     $linkExtractor = new LinkExtractor($serverUrlHelper, $urlHelper);
     $linkCollectionExtractor = new LinkCollectionExtractor($linkExtractor);
     $linksHelper->setLinkCollectionExtractor($linkCollectionExtractor);
     $pluginManager->setService('Hal', $linksHelper);
     $linksHelper->setController($controller);
     $this->resource = $resource = new Resource();
     $controller->setResource($resource);
 }
 public function setUp()
 {
     $this->controller = $controller = new ResourceController();
     $this->router = $router = new SimpleRouteStack();
     $route = new Segment('/resource[/[:id]]');
     $router->addRoute('resource', $route);
     $this->event = $event = new MvcEvent();
     $event->setRouter($router);
     $event->setRouteMatch(new RouteMatch(array()));
     $controller->setEvent($event);
     $controller->setRoute('resource');
     $pluginManager = new PluginManager();
     $controller->setPluginManager($pluginManager);
     $urlHelper = new UrlHelper();
     $urlHelper->setRouter($this->router);
     $serverUrlHelper = new ServerUrlHelper();
     $serverUrlHelper->setScheme('http');
     $serverUrlHelper->setHost('localhost.localdomain');
     $linksHelper = new Plugin\HalLinks();
     $linksHelper->setUrlHelper($urlHelper);
     $linksHelper->setServerUrlHelper($serverUrlHelper);
     $pluginManager->setService('HalLinks', $linksHelper);
     $linksHelper->setController($controller);
     $this->resource = $resource = new Resource();
     $controller->setResource($resource);
 }
예제 #4
0
파일: UrlTest.php 프로젝트: nevvermind/zf2
 /**
  * Sets up the fixture, for example, open a network connection.
  * This method is called before a test is executed.
  */
 protected function setUp()
 {
     $router = new Router();
     $router->addRoute('home', array('type' => 'Zend\\Mvc\\Router\\Http\\Literal', 'options' => array('route' => '/')));
     $router->addRoute('default', array('type' => 'Zend\\Mvc\\Router\\Http\\Segment', 'options' => array('route' => '/:controller[/:action]')));
     $this->url = new UrlHelper();
     $this->url->setRouter($router);
 }
예제 #5
0
 public function setUp()
 {
     $router = new SimpleRouteStack();
     $router->addRoute('home', LiteralRoute::factory(array('route' => '/', 'defaults' => array('controller' => 'ZendTest\\Mvc\\Controller\\TestAsset\\SampleController'))));
     $event = new MvcEvent();
     $event->setRouter($router);
     $this->controller = new SampleController();
     $this->controller->setEvent($event);
     $this->plugin = $this->controller->plugin('url');
 }
예제 #6
0
 protected function setUp()
 {
     $router = new Router();
     $router->addRoute('home', array('type' => 'Zend\\Mvc\\Router\\Http\\Literal', 'options' => array('route' => '/')));
     $router->addRoute('default', array('type' => 'Zend\\Mvc\\Router\\Http\\Segment', 'options' => array('route' => '/:controller[/:action]')));
     $this->request = new Request();
     $serviceManager = new ServiceManager();
     $serviceManager->setService('router', $router);
     $serviceManager->setService('request', $this->request);
     $pluginManager = new HelperPluginManager();
     $pluginManager->setServiceLocator($serviceManager);
     $this->pluginManager = $pluginManager;
 }
예제 #7
0
 /**
  * {@inheritDoc}
  */
 public function setUp()
 {
     $this->setApplicationConfig(include __DIR__ . '/../../../../../../tests/config/application.config.php');
     parent::setUp();
     $this->controller = new IdeaController();
     $this->request = new Request();
     $this->response = null;
     $this->routeMatch = new RouteMatch(['controller' => 'project-idea']);
     $this->event = new MvcEvent();
     $router = new SimpleRouteStack();
     $router->addRoute('idea/idea', ['type' => 'Zend\\Mvc\\Router\\Http\\Literal', 'options' => ['route' => "project/idea.html"]]);
     $this->event->setRouter($router);
     $this->event->setRouteMatch($this->routeMatch);
     $this->controller->setEvent($this->event);
     //Get the serviceLocation and inject it into the controller
     $serviceLocator = $this->getApplicationServiceLocator();
     $this->controller->setServiceLocator($serviceLocator);
     $formService = $serviceLocator->get(FormService::class);
     $this->controller->setFormService($formService);
     $ideaServiceMock = $this->getMockBuilder('Project\\Service\\IdeaService')->disableOriginalConstructor()->getMock();
     $newEntityResult = new Idea();
     $newEntityResult->setId(1);
     $ideaServiceMock->expects($this->any())->method('newEntity')->will($this->returnValue($newEntityResult));
     $ideaServiceMock->expects($this->any())->method('findAll')->will($this->returnValue([]));
     $this->controller->setIdeaService($serviceLocator->get(IdeaService::class));
     $serviceManager = $this->getApplicationServiceLocator();
     $serviceManager->setAllowOverride(true);
     $serviceManager->setService(IdeaService::class, $ideaServiceMock);
     $authorizeServiceMock = $this->getMockBuilder('BjyAuthorize\\View\\Helper\\IsAllowed')->disableOriginalConstructor()->getMock();
     $authorizeServiceMock->expects($this->any())->method('__invoke')->will($this->returnValue(true));
     $serviceManager = $this->getApplicationServiceLocator()->get('viewhelpermanager');
     $serviceManager->setAllowOverride(true);
     $serviceManager->setService('isAllowed', $authorizeServiceMock);
     $this->controller->getPluginManager()->setFactory('zfcUserAuthentication', function ($sm) {
         $serviceLocator = $sm->getController()->getServiceLocator();
         $authService = new AuthenticationService();
         $nonPersistent = new NonPersistent();
         /**
          * Store a reference if the contact in the session
          */
         $entityManager = $serviceLocator->get('doctrine.entitymanager.orm_default');
         $contact = $entityManager->getReference("Contact\\Entity\\Contact", 1);
         $nonPersistent->write($contact);
         $authService->setStorage($nonPersistent);
         $authAdapter = $serviceLocator->get('ZfcUser\\Authentication\\Adapter\\AdapterChain');
         $controllerPlugin = new \ZfcUser\Controller\Plugin\ZfcUserAuthentication();
         $controllerPlugin->setAuthService($authService);
         $controllerPlugin->setAuthAdapter($authAdapter);
         return $controllerPlugin;
     });
 }
예제 #8
0
 public function setUp()
 {
     $router = new SimpleRouteStack();
     $router->addRoute('home', LiteralRoute::factory(array('route' => '/', 'defaults' => array('controller' => 'ZendTest\\Mvc\\Controller\\TestAsset\\SampleController'))));
     $this->controller = new SampleController();
     $this->request = new Request();
     $this->event = new MvcEvent();
     $this->routeMatch = new RouteMatch(array('controller' => 'controller-sample', 'action' => 'postPage'));
     $this->event->setRequest($this->request);
     $this->event->setRouteMatch($this->routeMatch);
     $this->event->setRouter($router);
     $this->sessionManager = new SessionManager();
     $this->sessionManager->destroy();
     $this->controller->setEvent($this->event);
     $this->controller->flashMessenger()->setSessionManager($this->sessionManager);
 }
예제 #9
0
 public function setUp()
 {
     $this->response = new Response();
     $router = new SimpleRouteStack();
     $router->addRoute('home', LiteralRoute::factory(array('route' => '/', 'defaults' => array('controller' => 'ZendTest\\Mvc\\Controller\\TestAsset\\SampleController'))));
     $this->router = $router;
     $routeMatch = new RouteMatch(array());
     $routeMatch->setMatchedRouteName('home');
     $this->routeMatch = $routeMatch;
     $event = new MvcEvent();
     $event->setRouter($router);
     $event->setResponse($this->response);
     $this->event = $event;
     $this->controller = new SampleController();
     $this->controller->setEvent($event);
     $this->plugin = $this->controller->plugin('redirect');
 }
예제 #10
0
 public function setUp()
 {
     $this->form = new Form();
     $this->collection = new Collection('links', array('count' => 1, 'allow_add' => true, 'target_element' => array('type' => 'ZendTest\\Mvc\\Controller\\Plugin\\TestAsset\\LinksFieldset')));
     $router = new SimpleRouteStack();
     $router->addRoute('home', LiteralRoute::factory(array('route' => '/', 'defaults' => array('controller' => 'ZendTest\\Mvc\\Controller\\TestAsset\\SampleController'))));
     $router->addRoute('sub', SegmentRoute::factory(array('route' => '/foo/:param', 'defaults' => array('param' => 1))));
     $router->addRoute('ctl', SegmentRoute::factory(array('route' => '/ctl/:controller', 'defaults' => array('__NAMESPACE__' => 'ZendTest\\Mvc\\Controller\\TestAsset'))));
     $this->controller = new SampleController();
     $this->request = new Request();
     $this->event = new MvcEvent();
     $this->routeMatch = new RouteMatch(array('controller' => 'controller-sample', 'action' => 'postPage'));
     $this->event->setRequest($this->request);
     $this->event->setRouteMatch($this->routeMatch);
     $this->event->setRouter($router);
     $this->sessionManager = new SessionManager();
     $this->sessionManager->destroy();
     $this->controller->setEvent($this->event);
     $this->controller->flashMessenger()->setSessionManager($this->sessionManager);
 }
 public function configureControllerForAGivenRoute($controller, $routeName)
 {
     //CONFIGURE ROUTING
     $event = new MvcEvent();
     //build the router and set it as event's router.
     $routeStack = new SimpleRouteStack();
     $route = new Literal('/' . $routeName);
     $routeStack->addRoute($routeName, $route);
     //so that "route >home< not found" error did not show up - add home route.
     $routeHome = new Literal('/');
     $routeStack->addRoute('home', $routeHome);
     $event->setRouter($routeStack);
     //set route match for the event
     $routeMatch = new RouteMatch(['controller' => 'Index', 'action' => $routeName]);
     $routeMatch->setMatchedRouteName($routeName);
     $event->setRouteMatch($routeMatch);
     //finish configuring controller
     $controller->setEvent($event);
     return $controller;
 }
예제 #12
0
    public function setUp()
    {
        $this->response = new Response();

        $router = new SimpleRouteStack;
        $router->addRoute('home', new LiteralRoute(array(
            'route'    => '/',
            'defaults' => array(
                'controller' => 'ZendTest\Mvc\Controller\TestAsset\SampleController',
            ),
        )));

        $event = new MvcEvent();
        $event->setRouter($router);
        $event->setResponse($this->response);

        $this->controller = new SampleController();
        $this->controller->setEvent($event);

        $this->plugin = $this->controller->plugin('redirect');
    }
 protected function setUp()
 {
     StaticEventManager::resetInstance();
     $this->serviceManager = new ServiceManager();
     $this->request = new Request();
     $this->routeMatch = new RouteMatch(array('controller' => 'HtUserRegistration'));
     $this->event = new MvcEvent();
     $this->event->setRouteMatch($this->routeMatch);
     $this->zfcUserMapper = $this->getMock('ZfcUser\\Mapper\\User');
     $this->zfcUserEntity = $this->getMock('ZfcUser\\Entity\\UserInterface');
     $this->userRegistrationService = $this->getMock('HtUserRegistration\\Service\\UserRegistrationServiceInterface');
     $this->userRegistrationMapper = $this->getMock('HtUserRegistration\\Mapper\\UserRegistrationMapperInterface');
     $this->userRegistrationEntity = $this->getMock('HtUserRegistration\\Entity\\UserRegistrationInterface');
     $this->moduleOptions = $this->getMock('HtUserRegistration\\Options\\ModuleOptions');
     $this->moduleOptions->expects($this->any())->method('getPostVerificationRoute')->willReturn($this->redirectRoute);
     $routeStack = new SimpleRouteStack();
     $route = new Segment($this->redirectRoute);
     $routeStack->addRoute($this->redirectRoute, $route);
     $this->event->setRouter($routeStack);
     $this->serviceManager->setService('HtUserRegistration\\ModuleOptions', $this->moduleOptions);
     $this->controller = new UserRegistrationController($this->userRegistrationService);
     $this->controller->setServiceLocator($this->serviceManager);
     $this->controller->setEvent($this->event);
 }
예제 #14
0
 /**
  * {@inheritDoc}
  */
 public function setUp()
 {
     $this->setApplicationConfig(include __DIR__ . '/../../../../../../tests/config/application.config.php');
     parent::setUp();
     $this->controller = new ProjectController();
     $this->request = new Request();
     $this->response = null;
     $this->routeMatch = new RouteMatch(['controller' => 'project-index']);
     $this->event = new MvcEvent();
     $router = new SimpleRouteStack();
     $router->addRoute('route-project_entity_project', ['type' => 'Zend\\Mvc\\Router\\Http\\Literal', 'options' => ['route' => "project/test.html"]]);
     $this->event->setRouter($router);
     $this->event->setRouteMatch($this->routeMatch);
     $this->controller->setEvent($this->event);
     //Get the serviceLocation and inject it into the controller
     $serviceLocator = $this->getApplicationServiceLocator();
     $this->controller->setServiceLocator($serviceLocator);
     $this->controller->setProjectService($serviceLocator->get(ProjectService::class));
     /**
              * Bootstrap the application to have the other information available
     //         */
     //        $application = $serviceLocator->get('application');
     //        $application->bootstrap();
 }
예제 #15
0
    /**
     * routeFromArray(): defined by SimpleRouteStack.
     *
     * @see    SimpleRouteStack::routeFromArray()
     * @param  mixed $specs
     * @return Route
     */
    protected function routeFromArray($specs)
    {
        $route = parent::routeFromArray($specs);
        
        if (isset($specs['routes'])) {      
            $options = array(
                'route'         => $route,
                'may_terminate' => (isset($specs['may_terminate']) && $specs['may_terminate']),
                'child_routes'  => $specs['routes'],
                'plugin_broker' => $this->pluginBroker,
            );

            $route = $this->pluginBroker->load('part', $options);
        }

        return $route;
    }
예제 #16
0
 /**
  * routeFromArray(): defined by SimpleRouteStack.
  *
  * @see    BaseSimpleRouteStack::routeFromArray()
  * @param  array|Traversable $specs
  * @return RouteInterface
  * @throws Exception\InvalidArgumentException
  * @throws Exception\RuntimeException
  */
 protected function routeFromArray($specs)
 {
     if ($specs instanceof Traversable) {
         $specs = ArrayUtils::iteratorToArray($specs);
     } elseif (!is_array($specs)) {
         throw new Exception\InvalidArgumentException('Route definition must be an array or Traversable object');
     }
     // default to 'simple' console route
     if (!isset($specs['type'])) {
         $specs['type'] = 'simple';
     }
     // build route object
     $route = parent::routeFromArray($specs);
     if (!$route instanceof RouteInterface) {
         throw new Exception\RuntimeException('Given route does not implement Console route interface');
     }
     return $route;
 }
예제 #17
0
 /**
  * @param Acl $acl
  * @param $restriction
  * @param RoleRole $role
  * @param RouteResource $resource
  */
 protected function restrictRoute(Acl $acl, $restriction, RoleRole $role = null, RouteResource $resource = null)
 {
     if (is_null($resource)) {
         return $acl->{$restriction}($role, $resource);
     }
     $func = function ($route, array $names) use(&$func, $acl, $resource, $restriction, $role) {
         if (!count($names)) {
             throw new \DomainException("Names could not be empty");
         }
         if (!$route instanceof SimpleRouteStack) {
             if ($route instanceof \Iterator) {
                 $routes = $route;
             } else {
                 return;
             }
         } else {
             $routes = $route->getRoutes();
         }
         foreach ($routes as $name => $route) {
             $routeNames = array_merge($names, array($name));
             $parentResource = new RouteResource(join('/', $names));
             $childResource = new RouteResource(join('/', $routeNames));
             if (!$acl->hasResource($childResource)) {
                 $acl->addResource($childResource, $parentResource);
             }
             if ($acl->hasResource($resource) && $acl->inheritsResource($childResource, $resource)) {
                 $acl->{$restriction ? 'allow' : 'deny'}($role, $childResource);
             }
             if ($route instanceof SimpleRouteStack) {
                 $func($route->getRoutes(), $routeNames);
             }
         }
     };
     $firstPart = $resource->getFirstPart();
     if (!$acl->hasResource($firstPart)) {
         $acl->addResource(new RouteResource($firstPart), null);
     }
     $func($this->routeStack->getRoute($firstPart), array($firstPart));
     return $acl->{$restriction ? 'allow' : 'deny'}($role, $resource);
 }
예제 #18
0
 /**
  * match(): defined by \Zend\Mvc\Router\RouteInterface
  *
  * @see    \Zend\Mvc\Router\RouteInterface::match()
  * @param  Request $request
  * @return RouteMatch
  */
 public function match(Request $request)
 {
     if (!method_exists($request, 'getUri')) {
         return null;
     }
     if ($this->baseUrl === null && method_exists($request, 'getBaseUrl')) {
         $this->setBaseUrl($request->getBaseUrl());
     }
     $uri = $request->getUri();
     $baseUrlLength = strlen($this->baseUrl) ?: null;
     if ($this->requestUri === null) {
         $this->setRequestUri($uri);
     }
     if ($baseUrlLength !== null) {
         $pathLength = strlen($uri->getPath()) - $baseUrlLength;
         foreach ($this->routes as $name => $route) {
             if (($match = $route->match($request, $baseUrlLength)) instanceof RouteMatch && $match->getLength() === $pathLength) {
                 $match->setMatchedRouteName($name);
                 foreach ($this->defaultParams as $paramName => $value) {
                     if ($match->getParam($paramName) === null) {
                         $match->setParam($paramName, $value);
                     }
                 }
                 return $match;
             }
         }
     } else {
         return parent::match($request);
     }
     return null;
 }
예제 #19
0
 /**
  * routeFromArray(): defined by SimpleRouteStack.
  *
  * @see    SimpleRouteStack::routeFromArray()
  * @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 (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');
     }
     if (isset($specs['chain_routes'])) {
         if (!is_array($specs['chain_routes'])) {
             throw new Exception\InvalidArgumentException('Chain routes must be an array or Traversable object');
         }
         $chainRoutes = array_merge(array($specs), $specs['chain_routes']);
         unset($chainRoutes[0]['chain_routes']);
         $options = array('routes' => $chainRoutes, 'route_plugins' => $this->routePluginManager, 'prototypes' => $this->prototypes);
         $route = $this->routePluginManager->get('chain', $options);
     } else {
         $route = parent::routeFromArray($specs);
     }
     if (!$route instanceof RouteInterface) {
         throw new Exception\RuntimeException('Given route does not implement HTTP route interface');
     }
     if (isset($specs['child_routes'])) {
         $options = array('route' => $route, '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;
         $route = $this->routePluginManager->get('part', $options);
         $route->priority = $priority;
     }
     return $route;
 }
예제 #20
0
 public function testDefaultParamDoesNotOverrideParamForAssembling()
 {
     $stack = new SimpleRouteStack();
     $stack->addRoute('foo', new TestAsset\DummyRouteWithParam());
     $stack->setDefaultParam('foo', 'baz');
     $this->assertEquals('bar', $stack->assemble(array('foo' => 'bar'), array('name' => 'foo')));
 }
예제 #21
0
 public function testHasRoute()
 {
     $stack = new SimpleRouteStack();
     $this->assertEquals(false, $stack->hasRoute('foo'));
     $stack->addRoute('foo', new TestAsset\DummyRoute());
     $this->assertEquals(true, $stack->hasRoute('foo'));
 }
예제 #22
0
 /**
  * match(): defined by Route interface.
  *
  * @see    Route::match()
  * @param  Request $request
  * @return RouteMatch
  */
 public function match(Request $request)
 {
     if (!method_exists($request, 'uri')) {
         return null;
     }
     $uri = $request->uri();
     $baseUrlLength = strlen($this->baseUrl) ?: null;
     if ($this->requestUri === null) {
         $this->setRequestUri($uri);
     }
     if ($baseUrlLength !== null) {
         $pathLength = strlen($uri->getPath()) - $baseUrlLength;
         foreach ($this->routes as $route) {
             if (($match = $route->match($request, $baseUrlLength)) instanceof RouteMatch && $match->getLength() === $pathLength) {
                 return $match;
             }
         }
     } else {
         return parent::match($request);
     }
     return null;
 }
예제 #23
0
 /**
  * routeFromArray(): defined by SimpleRouteStack.
  *
  * @see    SimpleRouteStack::routeFromArray()
  * @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 (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');
     }
     if (isset($specs['controller_routes'])) {
         $ctrlRoutes = $specs['controller_routes'];
         if ($ctrlRoutes instanceof Traversable) {
             $ctrlRoutes = ArrayUtils::iteratorToArray($ctrlRoutes);
         } elseif (!is_array($ctrlRoutes)) {
             throw new Exception\InvalidArgumentException('Controller routes must be an array or Traversable object');
         }
         if (!isset($ctrlRoutes['model_route']) || !is_array($ctrlRoutes['model_route']) && !$ctrlRoutes['model_route'] instanceof Traversable) {
             throw new Exception\InvalidArgumentException('Controller routes must have a \'model_route\' key as an array or Traversable object');
         } elseif ($ctrlRoutes['model_route'] instanceof Traversable) {
             $ctrlRoutes['model_route'] = ArrayUtils::iteratorToArray($ctrlRoutes['model_route']);
         }
         if (!isset($ctrlRoutes['controllers']) || !is_array($ctrlRoutes['controllers']) && !$ctrlRoutes['controllers'] instanceof Traversable) {
             throw new Exception\InvalidArgumentException('Controller routes must have a \'controllers\' key as an array or Traversable object');
         } elseif ($ctrlRoutes['model_route'] instanceof Traversable) {
             $ctrlRoutes['controllers'] = ArrayUtils::iteratorToArray($ctrlRoutes['controllers']);
         }
         $modelRoute = $ctrlRoutes['model_route'];
         $controllers = $ctrlRoutes['controllers'];
         foreach ($controllers as $ctrlName) {
             $route = $modelRoute;
             $route['options']['defaults']['controller'] = $ctrlName;
             $route['options']['route'] = str_replace(':controller', $ctrlName, $route['options']['route']);
             $specs['child_routes'][$ctrlName] = $route;
         }
         unset($specs['controller_routes']);
     }
     if (isset($specs['chain_routes'])) {
         if (!is_array($specs['chain_routes'])) {
             throw new Exception\InvalidArgumentException('Chain routes must be an array or Traversable object');
         }
         $chainRoutes = array_merge([$specs], $specs['chain_routes']);
         unset($chainRoutes[0]['chain_routes']);
         if (isset($specs['child_routes'])) {
             unset($chainRoutes[0]['child_routes']);
         }
         $options = ['routes' => $chainRoutes, 'route_plugins' => $this->routePluginManager, 'prototypes' => $this->prototypes];
         $route = $this->routePluginManager->get('chain', $options);
     } else {
         $route = SimpleRouteStack::routeFromArray($specs);
     }
     if (!$route instanceof RouteInterface) {
         throw new Exception\RuntimeException('Given route does not implement HTTP route interface');
     }
     if (isset($specs['child_routes'])) {
         $options = ['route' => $route, '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;
         $route = $this->routePluginManager->get('part', $options);
         $route->priority = $priority;
     }
     return $route;
 }