Ik loop een beetje vast met op welk moment ik een Cookie moet zetten voor een geselecteerde taal (drie talige website) met het gebruik van AltoRouter. De situatie is momenteel als volgt. In mijn controller file heb ik momenteel het volgende:

$lang  = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');

if ( !$lang ) {
    if ( isset($_COOKIE["language"]) ) {
        $lang = $_COOKIE["language"];
    } else {
        $lang = 'nl';
    }
    header("Location: /$lang/$route");
}

Met andere woorden als $_Cookie{"language"] bestaat (nl, en, de) dan dient de uitgangs- taal (bij een tweede bezoek) de waarde van het Cookie te zijn (www.website.com/de/ of een van de andere twee), bestaat het Cookie nog niet zet de taal dan op Nederlands (www.website.com/nl/).

In de navigatie wil ik graag een taal dropdown hebben waar de Cookie taal de link voor de dropdown is:

<?php if (!isset($_COOKIE["lang"]) || isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'nl' ): ?>
<li class="nav-item dropdown">
	<a id"languageDropdown" class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">
		<img src="/images/flaggs/nl.png">&nbsp;&nbsp;Nederlands
	</a>
	<div class="dropdown-menu" aria-labelledby="languageDropdown">
		<a href="/en<?php echo $current_route?>" class="dropdown-item">
			<img src="/images/flaggs/uk.png">&nbsp;&nbsp;English
		</a>
		<a href="/de<?php echo $current_route?>" class="dropdown-item">
			<img src="/images/flaggs/de.png">&nbsp;&nbsp;Deutsch
		</a>		
	</div>
</li>
<?php elseif(isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'en'): ?>	
	// Zelfde als boven met Engels als uitgangs taal	
<?php elseif(isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'de'): ?>
	// Zelfde als boven met Duits als uitgangs taal
<?php endif; ?>


Ik kom er alleen niet uit op welk moment en waar ik het best het Cookie kan zetten. Zit me nu al een uur of wat rot te tobben. Iedere hulp zou ik zeer op prijs stellen.





[size=xsmall]Toevoeging op 30/09/2018 18:11:46:[/size]

Ik heb dit op de volgende wijze opgelost:

$lang  = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');

if ( !$lang ) {
    if ( isset($_COOKIE["language"]) ) {
        $lang = $_COOKIE["language"];
    } else {
        $lang = 'nl';
    }
    header("Location: /$lang/$route");
} else {
    $lang = (string)$lang; 
    setcookie( 'language', $lang, time() + 60*60*24*365, '/' );	
}

En dat werkt prima. Het enige probleem dat ik nu nog ondervind is de content voor de dropdown niet wijzigd, althans niet met gebruik van de header("Location") Als iemand bijvoorbeeld Engels kies veranderd de waarde van het Cookie naar en maar de nederlandse vlag met bijbehorende tekst blijven staan.

<img src="/images/flaggs/nl.png">&nbsp;&nbsp;Nederlands

Als ik daarna de pagina handmatig ververs veranderd de content wel naar de engelse versie:

<img src="/images/flaggs/uk.png">&nbsp;&nbsp;English

Hoe zou ik dit kunnen oplossen? Alvast bedankt
Frank Nietbelangrijk op 01/10/2018 14:00:11

/* Een andere taal instellen kan maar moet wel voordat je enige output verstuurd met: */
// LanguageManager::setLanguage('de'); // (bijvoorbeeld als een gebruiker dit kiest in een dropdown)


@Frank Nietbelangrijk. Ik heb de klas gemaakt en geinitieerd. als ik die echo geeft deze de juiste taal aan maar hoe verwerk ik dit in een dropdown?
Donald Boers op 01/10/2018 13:49:09
@- Ariƫn - Ik gebruik een auto-loader zoals ik in mijn antwoord aan @Frank reeds aangaf. Dit is mijn auto-loader:
function auto_loader($file)
{
    $file = APP_PATH . '/includes/classes/' . str_replace('_', '/', $file) . '.php';
    if (file_exists($file)) {
        require_once $file;
    } 
}
    
spl_autoload_register('auto_loader');

Heb je die functie wel eens gebenchmarkerd? Dit lijkt mij een extreem "dure" autoloader variant. De default implementatie van spl_autoload_register() is nagenoeg altijd het snelste en regelt alles eigenlijk al automatisch. Als de directorystructuur van de class-bestanden de naamgeving volgt dan werkt het eigenlijk al out-of-the-box.

Het enige wat je zou moeten doen is ergens een include path instellen waarin de classes staan. Sterker nog, hier kun je zelfs een volgorde in aanbrengen waarbij je bijvoorbeeld eerst een directory include voor alternatieve implementaties van "core" classes, en vervolgens de directory van de standaard implementaties. Dit zodat je af kunt wijken van standaard implementaties zonder de "core" functionaliteit aan te passen.

Dit is ook handig als je met externe libraries werkt waarin je waarschijnlijk beter niet zelf kunt gaan lopen modderen (en dat wordt ook een ramp als je die dingen versioned).
Donald Boers op 01/10/2018 14:05:24

Maar op welk moment/waar roep ik deze Class aan?

Wanneer heb je de taal nodig?
@Ward van der Put. Op het moment dat iemand in de dropdown een andere taal kiest. En op zich werkt het op de manier zoals ik het nu heb alleen wordt de taal dropdown niet geupdate. De huidige(actieve) taal is de link (bootstrap dropdown):

<li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#">
        <img src="/images/flaggs/nl.png">&nbsp;&nbsp;Nederlands
    </a>
</li>

Met in de dropdown de andere talen

<div class="dropdown-menu dropdown-menu-right mt-0">
	<a href="/en<?php echo $current_route?>" class="dropdown-item">
        <img src="/images/flaggs/uk.png">&nbsp;&nbsp;English
    </a>
	// andere talen
</div>

Dus op het moment dat iemand op b.v. de engelse link klikt moet de li nav-item van nederlands in engels veranderen. Op zich werkt dit alleen als ik de pagina handmatig ververs
Is het niet een gevalletje: "Let op: een cookie setten met setcookie() verandert niet de huidige waarde in $_COOKIE"?

In je index.php doe je nu een setcookie(), maar in je template kijk je naar $_COOKIE["lang"] (die dus nog niet is bijgewerkt, dat zie de volgende call pas terug). Als je nu van regel 21 in index.php het volgende maakt:

   setcookie( 'language', $_COOKIE["lang"] = $lang, time() + 60*60*24*365, '/' );
//                        ^^^^^^^^^^^^^^^^^^^ - dit toevoegen

Werkt het dan wel zoals bedoeld?

Bonus: ipv regel 12 t/m 16 kun je tegenwoordig (PHP 7) ook:

$lang = $_COOKIE["language"] ?? 'nl'; //kijk mam, geen foutmeldingen!
@Rob Doemaarwat
Rob Doemaarwat op 01/10/2018 19:55:39

Werkt het dan wel zoals bedoeld?

Nee helaas niet. Ik moet de pagina nog steeds handmatig verversen alvorens de actieve nav-item veranderd naar de nieuwe taal:(
Rob Doemaarwat op 01/10/2018 19:55:39

Bonus: ipv regel 12 t/m 16 kun je tegenwoordig (PHP 7) ook:

$lang = $_COOKIE["language"] ?? 'nl'; //kijk mam, geen foutmeldingen!


Leuke bonus. Scheelt toch weer 4 regels code. Hartelijk bedankt.
Hm, jammer. Nog wel een paar vragen:

- Dit klopt volgens mij niet:
if (!isset($_COOKIE["lang"]) || isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'nl' )
Bedoel je niet ("niet gezet; of wel gezet, en dan 'nl'"):
if (!isset($_COOKIE["lang"]) || ($_COOKIE["lang"] == 'nl'))

Nu is het deel voor de "&&" altijd waar (cookie is altijd niet of wel gezet)

- Waar komt die $current_route vandaan? Echo anders $_COOKIE["lang"] en $current_route in je template (waar je ook het menu in elkaar zet), en kijk eens of daar wel in zit wat je verwacht.
Rob Doemaarwat op 01/10/2018 22:17:12

- Dit klopt volgens mij niet:
if (!isset($_COOKIE["lang"]) || isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'nl' )
Bedoel je niet ("niet gezet; of wel gezet, en dan 'nl'"):
if (!isset($_COOKIE["lang"]) || ($_COOKIE["lang"] == 'nl'))

Nu is het deel voor de "&&" altijd waar (cookie is altijd niet of wel gezet)


Heb je helemaal gelijk in. Dat was inderdaad niet juist. Het werkte wel maar was ietwat omslachtig

Rob Doemaarwat op 01/10/2018 22:17:12

- Waar komt die $current_route vandaan? Echo anders $_COOKIE["lang"] en $current_route in je template (waar je ook het menu in elkaar zet), en kijk eens of daar wel in zit wat je verwacht.


$current_route is gedefinieerd in de Main Controller:

protected $route;

$this->route = $route;

'current_route'   => $this->route

dat is de huidige pagina/template waarop een bezoeker zich bevindt als deze een ander taal kiest. Als ik bijvoorbeeld op www.website.com/nl/over ben dan is $_COOKIE["lang"] /nl/ en $current_route /over. Waneer ik vervolgens voor engels kies dan wordt $_COOKIE["lang"] /en/ en $current_route /about

Is $_COOKIE["lang"] dan letterlijk "/nl/" (dus met die twee slashes - voor & na)!? Is dat dan niet je probleem? "/en/" is niet gelijk aan "en". Dus dan werkt het niet. Waarom het dan de tweede keer wel werkt geen idee, maar dit lijkt in ieder geval niet te (kunnen) werken.
Rob Doemaarwat op 01/10/2018 23:21:29

Is $_COOKIE["lang"] dan letterlijk "/nl/" (dus met die twee slashes - voor & na)!? Is dat dan niet je probleem? "/en/" is niet gelijk aan "en". Dus dan werkt het niet. Waarom het dan de tweede keer wel werkt geen idee, maar dit lijkt in ieder geval niet te (kunnen) werken.

@Rob Doemaarwat. Klein foutje van mijn kant. Is een enkele slash

/nl

de tweedeslash hoort bij de Route

/over

Reageren