Skip to content

Commit 6789e6b

Browse files
author
Marcel Schmäing
committed
Merge pull request #2454 in SW/shopware from bugfix/next/sw-11065-fix-virtuell-url-redirects to next
* commit 'f5ef6643a4d0184714a88a42fad2cfcc5c2adcbc': SW-11065 - Fix shop redirect in post and get requests
2 parents aee0d03 + f5ef664 commit 6789e6b

File tree

6 files changed

+238
-49
lines changed

6 files changed

+238
-49
lines changed

UPGRADE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ In this document you will find a changelog of the important changes related to t
55
* \Shopware\Bundle\SearchBundleDBAL\ConditionHandler\HasPriceConditionHandler now joins the prices as a 1:1 association for a performance improvement.
66
* sCategories::sGetCategoryContent function returns no more the category articleCount. Variable is unused.
77
* sCategories::sGetCategoryIdByArticleId function use now the s_articles_categories table.
8+
* Add __redirect parameter in frontend language switcher. Each language switcher requires now an additionally post parameter to redirect to the new shop `<input type="hidden" name="__redirect" value="1">`
89

910
## 5.0.0 RC2
1011
* SEO URL generation variable "statistic" has been translated and corrected to "static"

engine/Shopware/Controllers/Backend/Article.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4318,8 +4318,7 @@ public function previewDetailAction()
43184318
array(
43194319
'module' => 'frontend',
43204320
'controller' => 'detail',
4321-
'sArticle' => $articleId,
4322-
'appendSession' => true
4321+
'sArticle' => $articleId
43234322
)
43244323
);
43254324

engine/Shopware/Controllers/Backend/Config.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,13 @@ public function getListAction()
296296
'shop.basePath as basePath',
297297
'shop.baseUrl as baseUrl',
298298
'shop.default as default',
299-
'IFNULL(main.default, shop.default) as orderValue1',
300-
'IFNULL(main.name, shop.name) as orderValue2'
299+
'IFNULL(shop.mainId, shop.id) as orderValue0',
300+
'IFNULL(main.default, shop.default) as orderValue1'
301301
));
302-
$builder->orderBy('orderValue1', 'DESC');
303-
$builder->orderBy('orderValue2');
304-
$builder->orderBy('name');
302+
$builder->addOrderBy('orderValue1', 'DESC');
303+
$builder->addOrderBy('orderValue0', 'ASC');
304+
$builder->addOrderBy('shop.host', 'DESC');
305+
$builder->addOrderBy('name');
305306
break;
306307
case 'pageGroup':
307308
$builder->leftJoin('pageGroup.mapping', 'mapping');

engine/Shopware/Plugins/Default/Core/Router/Bootstrap.php

Lines changed: 227 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
* our trademarks remain entirely with us.
2323
*/
2424

25+
use Enlight_Controller_Request_Request as Request;
26+
use Shopware\Models\Shop\Shop;
27+
2528
/**
2629
* Shopware Router Plugin
2730
*
@@ -69,17 +72,7 @@ public function onRouteStartup(Enlight_Controller_EventArgs $args)
6972
try {
7073
/** @var $repository Shopware\Models\Shop\Repository */
7174
$repository = Shopware()->Models()->getRepository('Shopware\Models\Shop\Shop');
72-
if (($shop = $request->getQuery('__shop')) !== null) {
73-
$shop = $repository->getActiveById($shop);
74-
} elseif (($shop = $request->getCookie('shop')) !== null) {
75-
$shop = $repository->getActiveById($shop);
76-
}
77-
if ($shop === null) {
78-
$shop = $repository->getActiveByRequest($request);
79-
}
80-
if ($shop === null) {
81-
$shop = $repository->getActiveDefault();
82-
}
75+
$shop = $this->getShopByRequest($request);
8376
} catch (Exception $e) {
8477
$args->getResponse()->setException($e);
8578
return;
@@ -120,7 +113,9 @@ public function onRouteStartup(Enlight_Controller_EventArgs $args)
120113
}
121114

122115
// Update path info
123-
$request->setPathInfo();
116+
$request->setPathInfo(
117+
$this->createPathInfo($request, $shop)
118+
);
124119

125120
if (($host = $request->getHeader('X_FORWARDED_HOST')) !== null
126121
&& $host === $shop->getSecureHost()
@@ -134,6 +129,92 @@ public function onRouteStartup(Enlight_Controller_EventArgs $args)
134129
$shop->registerResources(Shopware()->Bootstrap());
135130
}
136131

132+
/**
133+
* @param Request $request
134+
* @param Shop $shop
135+
* @return null|string
136+
*/
137+
private function createPathInfo(Request $request, Shop $shop)
138+
{
139+
$requestUri = $request->getRequestUri();
140+
if ($requestUri === null) {
141+
return null;
142+
}
143+
144+
// Remove the query string from REQUEST_URI
145+
if ($pos = strpos($requestUri, '?')) {
146+
$requestUri = substr($requestUri, 0, $pos);
147+
}
148+
149+
$repository = Shopware()->Models()->getRepository('Shopware\Models\Shop\Shop');
150+
$requestShop = $repository->getActiveByRequest($request);
151+
152+
if ($requestShop && $requestShop->getId() !== $shop->getId()) {
153+
$requestUri = $this->removeShopBaseUrl(
154+
$requestUri,
155+
$request,
156+
$requestShop
157+
);
158+
}
159+
160+
$requestUri = $this->removeShopBaseUrl(
161+
$requestUri,
162+
$request,
163+
$shop
164+
);
165+
166+
if (!$shop->getMain()) {
167+
return $requestUri;
168+
}
169+
170+
return $this->removeShopBaseUrl(
171+
$requestUri,
172+
$request,
173+
$shop->getMain()
174+
);
175+
}
176+
177+
/**
178+
* @param string $requestUri
179+
* @param Request $request
180+
* @param Shop $shop
181+
* @return string
182+
*/
183+
private function removeShopBaseUrl($requestUri, Request $request, Shop $shop)
184+
{
185+
$url = $shop->getBaseUrl();
186+
$path = $shop->getBasePath();
187+
if ($request->isSecure()) {
188+
$url = $shop->getSecureBaseUrl();
189+
$path = $shop->getSecureBasePath();
190+
}
191+
$requestUri = $this->removePartOfUrl($requestUri, $url);
192+
$requestUri = $this->removePartOfUrl($requestUri, $path);
193+
194+
return $requestUri;
195+
}
196+
197+
/**
198+
* @param string $requestUri
199+
* @param string $url
200+
* @return string
201+
*/
202+
private function removePartOfUrl($requestUri, $url)
203+
{
204+
$decode = urldecode($url);
205+
$encode = urlencode($decode);
206+
207+
switch (true) {
208+
case (strpos($requestUri, $url) === 0):
209+
return substr($requestUri, strlen($url));
210+
case (strpos($requestUri, $decode) === 0):
211+
return substr($requestUri, strlen($decode));
212+
case (strpos($requestUri, $encode) === 0):
213+
return substr($requestUri, strlen($encode));
214+
default:
215+
return $requestUri;
216+
}
217+
}
137218

138219
/**
139220
* Event listener method
@@ -147,7 +228,7 @@ public function onRouteShutdown(Enlight_Controller_EventArgs $args)
147228

148229
$bootstrap = $this->Application()->Bootstrap();
149230
if ($bootstrap->issetResource('Shop')) {
150-
/** @var Shopware\Models\Shop\Shop $shop */
231+
/** @var Shop $shop */
151232
$shop = $this->Application()->Shop();
152233

153234
if ($request->isSecure() && $request->getHttpHost() !== $shop->getSecureHost()) {
@@ -175,7 +256,7 @@ public function onRouteShutdown(Enlight_Controller_EventArgs $args)
175256
}
176257

177258
/**
178-
* @param Enlight_Controller_Request_Request $request
259+
* @param Request $request
179260
*/
180261
protected function initServiceMode($request)
181262
{
@@ -188,13 +269,13 @@ protected function initServiceMode($request)
188269
}
189270

190271
/**
191-
* @param Enlight_Controller_Request_Request $request
272+
* @param Request $request
192273
* @param Enlight_Controller_Response_ResponseHttp $response
193274
*/
194275
protected function upgradeShop($request, $response)
195276
{
196277
$bootstrap = $this->Application()->Bootstrap();
197-
/** @var $shop Shopware\Models\Shop\Shop */
278+
/** @var $shop Shop */
198279
$shop = $this->Application()->Shop();
199280

200281
$cookieKey = null;
@@ -221,28 +302,17 @@ protected function upgradeShop($request, $response)
221302
$cookieKey = 'currency';
222303
$cookieValue = $request->getPost('__currency');
223304
break;
224-
case $request->getQuery('__template') !== null:
225-
$cookieKey = 'template';
226-
$cookieValue = $request->getQuery('__template');
227-
break;
228305
}
229306

230-
// Redirect on shop change
231-
if ($cookieKey === 'shop' && $request->isPost() && $request->getQuery('__shop') === null) {
307+
if ($cookieKey === 'shop' && $this->shouldRedirect($request, $shop) == true) {
232308
/** @var $repository Shopware\Models\Shop\Repository */
233309
$repository = Shopware()->Models()->getRepository('Shopware\Models\Shop\Shop');
310+
234311
$newShop = $repository->getActiveById($cookieValue);
235312

236313
if ($newShop !== null) {
237-
// Remove baseUrl from request url
238-
$url = $request->getRequestUri();
239-
$baseUrl = $request->getBaseUrl();
240-
if (strpos($url, $baseUrl) === 0) {
241-
$url = substr($url, strlen($baseUrl));
242-
}
243-
244-
$baseUrl = $newShop->getBaseUrl() ?: $request->getBasePath();
245-
$response->setRedirect($baseUrl . $url);
314+
$redirectUrl = $this->getNewShopUrl($request, $newShop);
315+
$response->setRedirect($redirectUrl);
246316

247317
if ($newShop->getBasePath()) {
248318
$cookiePath = $newShop->getBasePath();
@@ -261,19 +331,17 @@ protected function upgradeShop($request, $response)
261331
}
262332
}
263333

264-
// Refresh on template change
265-
if ($cookieKey !== null && $cookieKey != 'template') {
334+
//currency switch
335+
if ($cookieKey == 'currency') {
266336
$path = rtrim($shop->getBasePath(), '/') . '/';
267337
$response->setCookie($cookieKey, $cookieValue, 0, $path);
268-
if ($request->isPost() && $request->getQuery('__shop') === null) {
269-
$url = sprintf('%s://%s%s',
270-
$request->getScheme(),
271-
$request->getHttpHost(),
272-
$request->getRequestUri()
273-
);
274-
$response->setRedirect($url);
275-
return;
276-
}
338+
$url = sprintf('%s://%s%s',
339+
$request->getScheme(),
340+
$request->getHttpHost(),
341+
$request->getRequestUri()
342+
);
343+
$response->setRedirect($url);
344+
return;
277345
}
278346

279347
// Upgrade currency
@@ -339,4 +407,121 @@ public function getCapabilities()
339407
'update' => true
340408
);
341409
}
410+
411+
/**
412+
* @param Request $request
413+
* @return Shop
414+
*/
415+
protected function getShopByRequest(Request $request)
416+
{
417+
$repository = Shopware()->Models()->getRepository('Shopware\Models\Shop\Shop');
418+
419+
$shop = null;
420+
if ($request->getPost('__shop') !== null) {
421+
$shop = $repository->getActiveById($request->getPost('__shop'));
422+
}
423+
424+
if ($shop === null && $request->getCookie('shop') !== null) {
425+
$shop = $repository->getActiveById($request->getCookie('shop'));
426+
}
427+
428+
if ($shop === null) {
429+
$shop = $repository->getActiveByRequest($request);
430+
}
431+
432+
if ($shop === null) {
433+
$shop = $repository->getActiveDefault();
434+
}
435+
436+
return $shop;
437+
}
438+
439+
/**
440+
* @param Request $request
441+
* @param Shop $newShop
442+
* @return string
443+
*/
444+
protected function getNewShopUrl(
445+
Request $request,
446+
Shop $newShop
447+
) {
448+
$repository = Shopware()->Models()->getRepository('Shopware\Models\Shop\Shop');
449+
$requestShop = $repository->getActiveByRequest($request);
450+
451+
// Remove baseUrl from request url
452+
$url = $request->getRequestUri();
453+
454+
if ($requestShop && strpos($url, $requestShop->getBaseUrl()) === 0) {
455+
$url = substr($url, strlen($requestShop->getBaseUrl()));
456+
}
457+
458+
$baseUrl = $request->getBaseUrl();
459+
if (strpos($url, $baseUrl) === 0) {
460+
$url = substr($url, strlen($baseUrl));
461+
}
462+
463+
$basePath = $newShop->getBasePath();
464+
if (strpos($url, $basePath) === 0) {
465+
$url = substr($url, strlen($basePath));
466+
}
467+
468+
$host = $newShop->getHost();
469+
$baseUrl = $newShop->getBaseUrl() ?: $request->getBasePath();
470+
471+
if ($request->isSecure()) {
472+
$host = $newShop->getSecureHost() ?: $newShop->getHost();
473+
474+
if ($newShop->getSecureBaseUrl()) {
475+
$baseUrl = $newShop->getSecureBaseUrl();
476+
} elseif ($newShop->getBaseUrl()) {
477+
$baseUrl = $newShop->getBaseUrl();
478+
} else {
479+
$baseUrl = $request->getBaseUrl();
480+
}
481+
}
482+
483+
$host = trim($host, '/');
484+
$baseUrl = trim($baseUrl, '/');
485+
if (!empty($baseUrl)) {
486+
$baseUrl = '/' . $baseUrl;
487+
}
488+
489+
$url = ltrim($url, '/');
490+
if (!empty($url)) {
491+
$url = '/' . $url;
492+
}
493+
494+
//build full redirect url to allow host switches
495+
return sprintf(
496+
'%s://%s%s%s',
497+
$request->getScheme(),
498+
$host,
499+
$baseUrl,
500+
$url
501+
);
502+
}
503+
504+
/**
505+
* @param Request $request
506+
* @param Shop $shop
507+
* @return bool
508+
*/
509+
protected function shouldRedirect(Request $request, Shop $shop)
510+
{
511+
return (
512+
//for example: template preview, direct shop selection via url
513+
(
514+
$request->isGet()
515+
&& $request->getQuery('__shop') !== null
516+
&& $request->getQuery('__shop') != $shop->getId()
517+
)
518+
||
519+
//for example: shop language switch
520+
(
521+
$request->isPost()
522+
&& $request->getPost('__shop') !== null
523+
&& $request->getPost('__redirect') !== null
524+
)
525+
);
526+
}
342527
}

templates/_emotion/widgets/index/shop_menu.tpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
</option>
3131
{/foreach}
3232
</select>
33+
<input type="hidden" name="__redirect" value="1">
3334
</form>
3435
{/if}
3536
</div>

0 commit comments

Comments
 (0)