1
|
|
|
<?php declare(strict_types = 1); |
2
|
|
|
|
3
|
|
|
namespace Venta\Routing; |
4
|
|
|
|
5
|
|
|
use Psr\Http\Message\ServerRequestInterface; |
6
|
|
|
use Psr\Http\Message\UriInterface; |
7
|
|
|
use Venta\Contracts\Routing\ImmutableRouteCollection as RouteCollectionContract; |
8
|
|
|
use Venta\Contracts\Routing\Route as RouteContract; |
9
|
|
|
use Venta\Contracts\Routing\UrlGenerator as UrlGeneratorContract; |
10
|
|
|
use Venta\Routing\Exception\RouteNotFoundException; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Class UrlGenerator |
14
|
|
|
* |
15
|
|
|
* @package Venta\Routing |
16
|
|
|
*/ |
17
|
|
|
class UrlGenerator implements UrlGeneratorContract |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* @var ServerRequestInterface |
21
|
|
|
*/ |
22
|
|
|
private $request; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @var RouteCollectionContract |
26
|
|
|
*/ |
27
|
|
|
private $routes; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @var UriInterface |
31
|
|
|
*/ |
32
|
|
|
private $uri; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* UrlGenerator constructor. |
36
|
|
|
* |
37
|
|
|
* @param ServerRequestInterface $request |
38
|
|
|
* @param RouteCollectionContract $routes |
39
|
|
|
* @param UriInterface $uri |
40
|
|
|
*/ |
41
|
5 |
|
public function __construct(ServerRequestInterface $request, RouteCollectionContract $routes, UriInterface $uri) |
42
|
|
|
{ |
43
|
5 |
|
$this->request = $request; |
44
|
5 |
|
$this->routes = $routes; |
45
|
5 |
|
$this->uri = $uri; |
46
|
5 |
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @inheritDoc |
50
|
|
|
*/ |
51
|
1 |
|
public function toAsset(string $asset): UriInterface |
52
|
|
|
{ |
53
|
1 |
|
$uri = $this->uri |
54
|
1 |
|
->withScheme($this->request->getUri()->getScheme()) |
55
|
1 |
|
->withHost($this->request->getUri()->getHost()) |
56
|
1 |
|
->withPath($asset); |
57
|
|
|
|
58
|
1 |
|
return $this->addPortToUri($uri); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @inheritDoc |
63
|
|
|
*/ |
64
|
2 |
View Code Duplication |
public function toCurrent(array $variables = [], array $query = []): UriInterface |
65
|
|
|
{ |
66
|
2 |
|
$route = $this->request->getAttribute('route'); |
67
|
|
|
|
68
|
2 |
|
if ($route === null) { |
69
|
1 |
|
throw new RouteNotFoundException( |
70
|
1 |
|
sprintf('Unable to generate an URL for current.') |
71
|
|
|
); |
72
|
|
|
} |
73
|
|
|
|
74
|
1 |
|
return $this->buildRouteUri($route, $variables, $query); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @inheritDoc |
79
|
|
|
*/ |
80
|
2 |
View Code Duplication |
public function toRoute(string $routeName, array $variables = [], array $query = []): UriInterface |
81
|
|
|
{ |
82
|
2 |
|
$route = $this->routes->findByName($routeName); |
83
|
|
|
|
84
|
2 |
|
if ($route === null) { |
85
|
1 |
|
throw new RouteNotFoundException( |
86
|
1 |
|
sprintf('Unable to generate an URL for the named route "%s" as such route does not exist.', $routeName) |
87
|
|
|
); |
88
|
|
|
} |
89
|
|
|
|
90
|
1 |
|
return $this->buildRouteUri($route, $variables, $query); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Adds port to URI if it is needed. |
95
|
|
|
* |
96
|
|
|
* @param UriInterface $uri |
97
|
|
|
* @return UriInterface |
98
|
|
|
*/ |
99
|
3 |
|
private function addPortToUri(UriInterface $uri): UriInterface |
100
|
|
|
{ |
101
|
3 |
|
$requestPort = $this->request->getUri()->getPort(); |
102
|
|
|
|
103
|
3 |
|
if (!in_array($requestPort, [80, 443])) { |
104
|
1 |
|
$uri = $uri->withPort($requestPort); |
105
|
|
|
} |
106
|
|
|
|
107
|
3 |
|
return $uri; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Builds URI for provided route instance. |
112
|
|
|
* |
113
|
|
|
* @param RouteContract $route |
114
|
|
|
* @param array $variables |
115
|
|
|
* @param array $query |
116
|
|
|
* @return UriInterface |
117
|
|
|
*/ |
118
|
2 |
|
private function buildRouteUri(RouteContract $route, array $variables = [], array $query = []): UriInterface |
119
|
|
|
{ |
120
|
2 |
|
$uri = $this->uri |
121
|
2 |
|
->withScheme($route->scheme() ?: $this->request->getUri()->getScheme()) |
122
|
2 |
|
->withHost($route->host() ?: $this->request->getUri()->getHost()) |
123
|
2 |
|
->withPath($route->compilePath($variables)); |
124
|
|
|
|
125
|
2 |
|
if ($query) { |
|
|
|
|
126
|
2 |
|
$uri = $uri->withQuery(http_build_query($query)); |
127
|
|
|
} |
128
|
|
|
|
129
|
2 |
|
return $this->addPortToUri($uri); |
130
|
|
|
} |
131
|
|
|
} |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.