1<?php 2/** 3 * Zend Framework (http://framework.zend.com/) 4 * 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 8 */ 9 10namespace Zend\View\Helper; 11 12use Traversable; 13use Zend\Mvc\ModuleRouteListener; 14use Zend\Mvc\Router\RouteMatch; 15use Zend\Mvc\Router\RouteStackInterface; 16use Zend\View\Exception; 17 18/** 19 * Helper for making easy links and getting urls that depend on the routes and router. 20 */ 21class Url extends AbstractHelper 22{ 23 /** 24 * RouteStackInterface instance. 25 * 26 * @var RouteStackInterface 27 */ 28 protected $router; 29 30 /** 31 * RouteInterface match returned by the router. 32 * 33 * @var RouteMatch. 34 */ 35 protected $routeMatch; 36 37 /** 38 * Generates a url given the name of a route. 39 * 40 * @see Zend\Mvc\Router\RouteInterface::assemble() 41 * @param string $name Name of the route 42 * @param array $params Parameters for the link 43 * @param array|Traversable $options Options for the route 44 * @param bool $reuseMatchedParams Whether to reuse matched parameters 45 * @return string Url For the link href attribute 46 * @throws Exception\RuntimeException If no RouteStackInterface was provided 47 * @throws Exception\RuntimeException If no RouteMatch was provided 48 * @throws Exception\RuntimeException If RouteMatch didn't contain a matched route name 49 * @throws Exception\InvalidArgumentException If the params object was not an array or \Traversable object 50 */ 51 public function __invoke($name = null, $params = array(), $options = array(), $reuseMatchedParams = false) 52 { 53 if (null === $this->router) { 54 throw new Exception\RuntimeException('No RouteStackInterface instance provided'); 55 } 56 57 if (3 == func_num_args() && is_bool($options)) { 58 $reuseMatchedParams = $options; 59 $options = array(); 60 } 61 62 if ($name === null) { 63 if ($this->routeMatch === null) { 64 throw new Exception\RuntimeException('No RouteMatch instance provided'); 65 } 66 67 $name = $this->routeMatch->getMatchedRouteName(); 68 69 if ($name === null) { 70 throw new Exception\RuntimeException('RouteMatch does not contain a matched route name'); 71 } 72 } 73 74 if (!is_array($params)) { 75 if (!$params instanceof Traversable) { 76 throw new Exception\InvalidArgumentException( 77 'Params is expected to be an array or a Traversable object' 78 ); 79 } 80 $params = iterator_to_array($params); 81 } 82 83 if ($reuseMatchedParams && $this->routeMatch !== null) { 84 $routeMatchParams = $this->routeMatch->getParams(); 85 86 if (isset($routeMatchParams[ModuleRouteListener::ORIGINAL_CONTROLLER])) { 87 $routeMatchParams['controller'] = $routeMatchParams[ModuleRouteListener::ORIGINAL_CONTROLLER]; 88 unset($routeMatchParams[ModuleRouteListener::ORIGINAL_CONTROLLER]); 89 } 90 91 if (isset($routeMatchParams[ModuleRouteListener::MODULE_NAMESPACE])) { 92 unset($routeMatchParams[ModuleRouteListener::MODULE_NAMESPACE]); 93 } 94 95 $params = array_merge($routeMatchParams, $params); 96 } 97 98 $options['name'] = $name; 99 100 return $this->router->assemble($params, $options); 101 } 102 103 /** 104 * Set the router to use for assembling. 105 * 106 * @param RouteStackInterface $router 107 * @return Url 108 */ 109 public function setRouter(RouteStackInterface $router) 110 { 111 $this->router = $router; 112 return $this; 113 } 114 115 /** 116 * Set route match returned by the router. 117 * 118 * @param RouteMatch $routeMatch 119 * @return Url 120 */ 121 public function setRouteMatch(RouteMatch $routeMatch) 122 { 123 $this->routeMatch = $routeMatch; 124 return $this; 125 } 126} 127