1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<?php
/**
* @see https://github.com/laminas/laminas-view for the canonical source repository
* @copyright https://github.com/laminas/laminas-view/blob/master/COPYRIGHT.md
* @license https://github.com/laminas/laminas-view/blob/master/LICENSE.md New BSD License
*/
namespace Laminas\View\Helper;
use Laminas\Mvc\ModuleRouteListener;
use Laminas\Mvc\Router\RouteMatch as LegacyRouteMatch;
use Laminas\Mvc\Router\RouteStackInterface as LegacyRouteStackInterface;
use Laminas\Router\RouteMatch;
use Laminas\Router\RouteStackInterface;
use Laminas\View\Exception;
use Traversable;
/**
* Helper for making easy links and getting urls that depend on the routes and router.
*/
class Url extends AbstractHelper
{
/**
* Router instance.
*
* @var LegacyRouteStackInterface|RouteStackInterface
*/
protected $router;
/**
* Route matches returned by the router.
*
* @var LegacyRouteMatch|RouteMatch.
*/
protected $routeMatch;
/**
* Generates a url given the name of a route.
*
* @see Laminas\Mvc\Router\RouteInterface::assemble()
* @see Laminas\Router\RouteInterface::assemble()
* @param string $name Name of the route
* @param array $params Parameters for the link
* @param array|Traversable $options Options for the route
* @param bool $reuseMatchedParams Whether to reuse matched parameters
* @return string Url For the link href attribute
* @throws Exception\RuntimeException If no RouteStackInterface was
* provided
* @throws Exception\RuntimeException If no RouteMatch was provided
* @throws Exception\RuntimeException If RouteMatch didn't contain a
* matched route name
* @throws Exception\InvalidArgumentException If the params object was not
* an array or Traversable object.
*/
public function __invoke($name = null, $params = [], $options = [], $reuseMatchedParams = false)
{
if (null === $this->router) {
throw new Exception\RuntimeException('No RouteStackInterface instance provided');
}
if (3 == func_num_args() && is_bool($options)) {
$reuseMatchedParams = $options;
$options = [];
}
if ($name === null) {
if ($this->routeMatch === null) {
throw new Exception\RuntimeException('No RouteMatch instance provided');
}
$name = $this->routeMatch->getMatchedRouteName();
if ($name === null) {
throw new Exception\RuntimeException('RouteMatch does not contain a matched route name');
}
}
if (! is_array($params)) {
if (! $params instanceof Traversable) {
throw new Exception\InvalidArgumentException(
'Params is expected to be an array or a Traversable object'
);
}
$params = iterator_to_array($params);
}
if ($reuseMatchedParams && $this->routeMatch !== null) {
$routeMatchParams = $this->routeMatch->getParams();
if (isset($routeMatchParams[ModuleRouteListener::ORIGINAL_CONTROLLER])) {
$routeMatchParams['controller'] = $routeMatchParams[ModuleRouteListener::ORIGINAL_CONTROLLER];
unset($routeMatchParams[ModuleRouteListener::ORIGINAL_CONTROLLER]);
}
if (isset($routeMatchParams[ModuleRouteListener::MODULE_NAMESPACE])) {
unset($routeMatchParams[ModuleRouteListener::MODULE_NAMESPACE]);
}
$params = array_merge($routeMatchParams, $params);
}
$options['name'] = $name;
return $this->router->assemble($params, $options);
}
/**
* Set the router to use for assembling.
*
* @param LegacyRouteStackInterface|RouteStackInterface $router
* @return Url
* @throws Exception\InvalidArgumentException for invalid router types.
*/
public function setRouter($router)
{
if (! $router instanceof RouteStackInterface
&& ! $router instanceof LegacyRouteStackInterface
) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects a %s or %s instance; received %s',
__METHOD__,
RouteStackInterface::class,
LegacyRouteStackInterface::class,
(is_object($router) ? get_class($router) : gettype($router))
));
}
$this->router = $router;
return $this;
}
/**
* Set route match returned by the router.
*
* @param LegacyRouteMatch|RouteMatch $routeMatch
* @return Url
*/
public function setRouteMatch($routeMatch)
{
if (! $routeMatch instanceof RouteMatch
&& ! $routeMatch instanceof LegacyRouteMatch
) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects a %s or %s instance; received %s',
__METHOD__,
RouteMatch::class,
LegacyRouteMatch::class,
(is_object($routeMatch) ? get_class($routeMatch) : gettype($routeMatch))
));
}
$this->routeMatch = $routeMatch;
return $this;
}
}