I'm attempting to include some code in the head.inc file that will check if the page is available in the user's location language and if so it'll redirect to that page. Obviously this isn't a great for UX but alas my client is keen.
The only issue I need to overcome is if the user has already been redirected then don't do it for every page... store the fact that the user was redirected and don't do it again until the session has ended. Something like that.
I have written the code below but a) I'm unsure this is the best way to do it and b) it seems to get stuck in a redirect loop (which I thought I'd avoided by my second session check).
I'm using the ipapi.com to check the user's location. I’m also using ProcessWire’s ‘$session’ which is effectively the same as PHP session.
if (!$session->get("lucentLightingRegion")) {
$session->set("lucentLightingSessionRedirected", "false");
if ($page->ipapiGetUserLocation()['continent_code'] === 'NA') {
$session->set("lucentLightingRegion", "NA");
if ($page->viewable('na')) {
$url = $page->localUrl('na');
$session->redirect($url);
}
} else {
$session->set("lucentLightingRegion", "INT");
if ($page->viewable('default')) {
$url = $page->localUrl('default');
$session->redirect($url);
}
}
} else {
$sessionRegion = $session->get("lucentLightingRegion");
bd($sessionRegion);
if ($page->viewable($sessionRegion) && $session->get("lucentLightingSessionRedirected") == "false") {
$url = $page->localUrl($sessionRegion);
$session->redirect($url);
$session->set("lucentLightingSessionRedirected", "true");
}
}
Calling $session->redirect($url);
before $session->set("lucentLightingSessionRedirected", "true");
appears to be your issue.
Looking at the source code of $session->redirect()
it executes:
header("Location: $url");
exit(0);
Which is preventing $session->set("lucentLightingSessionRedirected", "true");
from being called, resulting in the redirect loop, as lucentLightingSessionRedirected
was never set to "true"
.
To resolve the issue, you should be able to change the order of operations.
if ($page->viewable($sessionRegion) && $session->get("lucentLightingSessionRedirected") == "false") {
$session->set("lucentLightingSessionRedirected", "true");
$url = $page->localUrl($sessionRegion);
$session->redirect($url);
}
Do Keep in mind that Wire::__call()
is being used to issue Session::__redirect()
However it appears that you also have a logic flaw with the sessions and regional redirects, that may result in an undesired state. Since $page->localUrl()
is using lowercase values but lucentLightingRegion
is uppercase, I am not aware of how your application is designed to handle them. Additionally the default region of INT
loading the default
page, which may not work as desired when redirecting to $sessionRegion = 'INT'
. I would need more details on how this is expected to work and if there is indeed different states for NA
, na
, INT
and default
and what is supposed to happen when none of the specified values are a viewable()
page when lucentLightingRegion
is set. Currently if lucentLightingRegion
is set and is not viewable()
or lucentLightingSessionRedirected
is "true"
, none of the conditions will be met.