1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* File containing the Generator class. |
5
|
|
|
* |
6
|
|
|
* @copyright Copyright (C) eZ Systems AS. All rights reserved. |
7
|
|
|
* @license For full copyright and license information view LICENSE file distributed with this source code. |
8
|
|
|
*/ |
9
|
|
|
namespace eZ\Publish\Core\MVC\Symfony\Routing; |
10
|
|
|
|
11
|
|
|
use eZ\Publish\Core\MVC\Symfony\SiteAccess; |
12
|
|
|
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware; |
13
|
|
|
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface; |
14
|
|
|
use Psr\Log\LoggerInterface; |
15
|
|
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; |
16
|
|
|
use Symfony\Component\Routing\RequestContext; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Base class for eZ Publish Url generation. |
20
|
|
|
*/ |
21
|
|
|
abstract class Generator implements SiteAccessAware |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* @var \Symfony\Component\Routing\RequestContext |
25
|
|
|
*/ |
26
|
|
|
protected $requestContext; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var \eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface |
30
|
|
|
*/ |
31
|
|
|
protected $siteAccessRouter; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var \eZ\Publish\Core\MVC\Symfony\SiteAccess |
35
|
|
|
*/ |
36
|
|
|
protected $siteAccess; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @var \Psr\Log\LoggerInterface |
40
|
|
|
*/ |
41
|
|
|
protected $logger; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @param \Symfony\Component\Routing\RequestContext $requestContext |
45
|
|
|
*/ |
46
|
|
|
public function setRequestContext(RequestContext $requestContext) |
47
|
|
|
{ |
48
|
|
|
$this->requestContext = $requestContext; |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @param \eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface $siteAccessRouter |
53
|
|
|
*/ |
54
|
|
|
public function setSiteAccessRouter(SiteAccessRouterInterface $siteAccessRouter) |
55
|
|
|
{ |
56
|
|
|
$this->siteAccessRouter = $siteAccessRouter; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param \eZ\Publish\Core\MVC\Symfony\SiteAccess $siteAccess |
61
|
|
|
*/ |
62
|
|
|
public function setSiteAccess(SiteAccess $siteAccess = null) |
63
|
|
|
{ |
64
|
|
|
$this->siteAccess = $siteAccess; |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* @param LoggerInterface $logger |
69
|
|
|
*/ |
70
|
|
|
public function setLogger(LoggerInterface $logger = null) |
71
|
|
|
{ |
72
|
|
|
$this->logger = $logger; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Triggers URL generation for $urlResource and $parameters. |
77
|
|
|
* |
78
|
|
|
* @param mixed $urlResource Type can be anything, depending on the context. It's up to the router to pass the appropriate value to the implementor. |
79
|
|
|
* @param array $parameters Arbitrary hash of parameters to generate a link. |
80
|
|
|
* SiteAccess name can be provided as 'siteaccess' to generate a link to it (cross siteaccess link). |
81
|
|
|
* @param int $referenceType The type of reference to be generated (one of the constants) |
82
|
|
|
* |
83
|
|
|
* @return string |
84
|
|
|
*/ |
85
|
|
|
public function generate($urlResource, array $parameters, $referenceType = UrlGeneratorInterface::ABSOLUTE_PATH) |
86
|
|
|
{ |
87
|
|
|
$siteAccess = $this->siteAccess; |
88
|
|
|
$requestContext = $this->requestContext; |
89
|
|
|
|
90
|
|
|
// Retrieving the appropriate SiteAccess to generate the link for. |
91
|
|
View Code Duplication |
if (isset($parameters['siteaccess'])) { |
|
|
|
|
92
|
|
|
$siteAccess = $this->siteAccessRouter->matchByName($parameters['siteaccess']); |
93
|
|
|
if ($siteAccess instanceof SiteAccess && $siteAccess->matcher instanceof SiteAccess\VersatileMatcher) { |
94
|
|
|
$requestContext = $this->getContextBySimplifiedRequest($siteAccess->matcher->getRequest()); |
95
|
|
|
} elseif ($this->logger) { |
96
|
|
|
$siteAccess = $this->siteAccess; |
97
|
|
|
$this->logger->notice("Could not generate a link using provided 'siteaccess' parameter: {$parameters['siteaccess']}. Generating using current context."); |
98
|
|
|
unset($parameters['siteaccess']); |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
$url = $this->doGenerate($urlResource, $parameters); |
103
|
|
|
|
104
|
|
|
// Add the SiteAccess URI back if needed. |
105
|
|
|
if ($siteAccess && $siteAccess->matcher instanceof SiteAccess\URILexer) { |
106
|
|
|
$url = $siteAccess->matcher->analyseLink($url); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
$url = $requestContext->getBaseUrl() . $url; |
110
|
|
|
|
111
|
|
|
if ($referenceType === UrlGeneratorInterface::ABSOLUTE_URL) { |
112
|
|
|
$url = $this->generateAbsoluteUrl($url, $requestContext); |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
return $url; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Generates the URL from $urlResource and $parameters. |
120
|
|
|
* |
121
|
|
|
* @param mixed $urlResource |
122
|
|
|
* @param array $parameters |
123
|
|
|
* |
124
|
|
|
* @return string |
125
|
|
|
*/ |
126
|
|
|
abstract public function doGenerate($urlResource, array $parameters); |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* Generates an absolute URL from $uri and the request context. |
130
|
|
|
* |
131
|
|
|
* @param string $uri |
132
|
|
|
* @param \Symfony\Component\Routing\RequestContext $requestContext |
133
|
|
|
* |
134
|
|
|
* @return string |
135
|
|
|
*/ |
136
|
|
|
protected function generateAbsoluteUrl($uri, RequestContext $requestContext) |
137
|
|
|
{ |
138
|
|
|
$scheme = $requestContext->getScheme(); |
139
|
|
|
$port = ''; |
140
|
|
|
if ($scheme === 'http' && $requestContext->getHttpPort() != 80) { |
141
|
|
|
$port = ':' . $requestContext->getHttpPort(); |
142
|
|
|
} elseif ($scheme === 'https' && $requestContext->getHttpsPort() != 443) { |
143
|
|
|
$port = ':' . $requestContext->getHttpsPort(); |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
return $scheme . '://' . $requestContext->getHost() . $port . $uri; |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* Merges context from $simplifiedRequest into a clone of the current context. |
151
|
|
|
* |
152
|
|
|
* @param SimplifiedRequest $simplifiedRequest |
153
|
|
|
* |
154
|
|
|
* @return RequestContext |
155
|
|
|
*/ |
156
|
|
View Code Duplication |
private function getContextBySimplifiedRequest(SimplifiedRequest $simplifiedRequest) |
157
|
|
|
{ |
158
|
|
|
$context = clone $this->requestContext; |
159
|
|
|
if ($simplifiedRequest->scheme) { |
160
|
|
|
$context->setScheme($simplifiedRequest->scheme); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
if ($simplifiedRequest->port) { |
164
|
|
|
switch ($simplifiedRequest->scheme) { |
165
|
|
|
case 'https': |
166
|
|
|
$context->setHttpsPort($simplifiedRequest->port); |
167
|
|
|
break; |
168
|
|
|
default: |
169
|
|
|
$context->setHttpPort($simplifiedRequest->port); |
170
|
|
|
break; |
171
|
|
|
} |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
if ($simplifiedRequest->host) { |
175
|
|
|
$context->setHost($simplifiedRequest->host); |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
if ($simplifiedRequest->pathinfo) { |
179
|
|
|
$context->setPathInfo($simplifiedRequest->pathinfo); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
return $context; |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.