contao / core

Contao 3 → see contao/contao for Contao 4
GNU Lesser General Public License v3.0
492 stars 213 forks source link

Rootpage wird bei Sprachenfallback nicht korrekt erkannt #3453

Closed ghost closed 12 years ago

ghost commented 12 years ago

Seit 2.10 wurde die Abfrage der Root-Page in der Frontend.php in Zeile 130 geändert und um die Nutzung der MySQL-Funktion "FIND IN SET" erweitert. Sobald die Sprache, die als Fallback konfiguriert ist, nicht als Sprache vom Browser übermittelt wird, liefert "FIND IN SET" 0 zurück und gibt die Fallbacksprache in der Reihenfolge vor der eigentlichen Browsersprache aus. So wird also eine englische Seite ausgegeben, obwohl eine deutsche Variante existiert. Dies tritt z.B. im Safari unter Mac OS X auf, der lediglich die Systemsprache als Browsersprache übermittelt. Nachvollziehbar ist das Problem auch auf conto.org. Hier wird neuerdings in einem deutschen Safari die englische Website ausgegeben. Abhilfe schafft folgender Query:

$objRootPage = $this->Database->prepare("SELECT id, dns, language, fallback FROM tl_page WHERE type='root' AND (language IN (?) OR fallback=1) AND (dns=? OR dns='') AND (start='' OR start<UNIX_TIMESTAMP()) AND published=1 LIMIT 0,1") ->execute(implode(',', $accept_language), $host);

Funktional ist dieser verkürzte Query identisch mit jenem aus < 2.10, lediglich das zusätzliche Berücksichtigen des "www"-Aliases wurde entfernt.

Download the attachments

--- Originally created by r00xster on September 9th, 2011, at 05:42pm (ID 3453)

ghost commented 12 years ago

Im Eifer des Gefechts ist mir oben ein Fehler mit implode unterlaufen. Außerdem traten nun Fehler bei Browsern mit mehreren Sprachkennungen auf. In unseren 2.10 Installationen haben wir die entsprechende Funktion auf den Code von 2.9 zurückgestellt, lediglich die Unterstützung des www-Aliases wurde entfernt:

$objRootPage = $this->Database->prepare("SELECT id, dns, language, fallback FROM tl_page WHERE type='root' AND (dns=? OR dns='')" . ((count($accept_language) > 0) ? " AND (language IN('". implode("','", $accept_language) ."') OR fallback=1)" : " AND fallback=1") . (!BE_USER_LOGGED_IN ? " AND (start='' OR start<$time) AND (stop='' OR stop>$time) AND published=1" : "") . " ORDER BY dns DESC" . ((count($accept_language) > 0) ? ", language='". implode("' DESC, language='", $accept_language) ."' DESC" : "")) ->limit(1) ->execute($host);

--- Originally created by r00xster on September 9th, 2011, at 08:13pm

leofeyer commented 12 years ago

Wie genau lässt sich das im Core reproduzieren?

--- Originally created on September 12th, 2011, at 04:43pm

ghost commented 12 years ago

Das Problem lässt sich reproduzieren, indem man einen Browser verwendet, der als Sprache beispielsweise nur Deutsch übergibt. Anschließend legt man in Contao zwei Startpunkte an, die beide auf dieselbe Domain reagieren. Einen Startpunkt stellt man auf Deutsch, den anderen auf Englisch. Bei Aufrufen der Seite wird nun immer der englische Startpunkt verwendet, obwohl ein Deutscher ja existiert. In $this->Environment->httpAcceptLanguage hingegen wird korrekterweise als einziger Eintrag des Arrays "de" ausgegeben.

--- Originally created by r00xster on September 12th, 2011, at 05:29pm

xchs commented 12 years ago

Nachvollziehbar ist das Problem auch auf contao.org. Hier wird neuerdings in einem deutschen Safari die englische Website ausgegeben.

Ich hab' das im Safari unter SL und Lion probiert, konnte aber kein diesbezügliches Problem feststellen.

--- Originally created on September 12th, 2011, at 06:24pm

Aybee commented 12 years ago

Dieses Verhalten hatte ich mal im Forum erwähnt contao.org Sprache mal Englisch mal Deutsch . Den Effekt habe ich diese Woche auch immer wieder gehabt.

--- Originally created on September 14th, 2011, at 12:24am

ghost commented 12 years ago

contao.org ist bei kurioserweise auch immer wieder deutsch und englisch wobei englisch eindeutig überwiegt.

Zum Nachvollziehen des Problems habe ich mal eine Testumgebung aufgebaut. Diese ist erreichbar unter http://contao.dev.werbecafe.de/. Es sind zwei Startpunkte angelegt, einer in deutsch und einer in englisch, der gleichzeitig als Fallback dient. Im Template habe ich zusätzlich die Ausgabe von $this->Environment->httpAcceptLanguage eingebaut.

Unter OS X 10.7 mit Safari 5.1 öffnet sich standardmäßig nun die englische Seite. Im Firefox 5 ist dies ebenfalls der Fall, sofern ich die Sprachen auf Deutsch reduziere. Sobald zusätzlich Englisch als Browsersprache mit übermittelt wird, wird der deutsche Startpunkt ausgegeben.

--- Originally created by r00xster on September 14th, 2011, at 09:18am

leofeyer commented 12 years ago

Kann ich im Core nicht reproduzieren.

--- Originally created on September 14th, 2011, at 01:07pm

ghost commented 12 years ago

Und wie erklärt sich dann der beschriebene Fehler auf der angegebenen Testseite? Ich bekomme da folgende Ausgabe:

Ich bin eine englische Website.

Array ( [0] => de )

Mein Browser ist Safari 5.1 unter Mac OS X Snow Leopard. Einzige erlaubte Inhaltssprache im Browser ist Deutsch.

--- Originally created by vbinsider on September 14th, 2011, at 02:28pm

aschempp commented 12 years ago

@leo: Ich würde das Problem nicht als "Invalid" abtun, sondern besser "Pending". Das Problem haben einige schon gemeldet...

--- Originally created on September 14th, 2011, at 04:00pm

leofeyer commented 12 years ago

Ich würde es sehr gerne als "pending" einstufen, aber leider kann ich das Problem anhand der vorhandenen Informationen nicht reproduzieren. Was also soll ich machen? Das Ticket für immer "pending" lassen?

--- Originally created on September 14th, 2011, at 04:11pm

ghost commented 12 years ago

Mit welchen Einstellungen und welcher Umgebung rufst du denn die Seite auf? Insbesondere die Ausgabe von http://contao.dev.werbecafe.de wäre da interessant.

--- Originally created by vbinsider on September 14th, 2011, at 04:15pm

aschempp commented 12 years ago

Nicht für immer, sondern bis wird die Lösung haben :-P Ich habe noch gar nicht versucht das nachzustellen, aber wir können ja mal einen Ticket-Branch anlegen damit die Hilfsentwickler (Stefan, Chris und ich) uns das ansehen können.

--- Originally created on September 14th, 2011, at 04:16pm

leofeyer commented 12 years ago

Insbesondere die Ausgabe von http://contao.dev.werbecafe.de wäre da interessant

Leider nicht wirklich, denn wer weiß was Du installiert hast (Core, Extensions etc.) und wie Deine Serverkonfiguration aussieht. Als Referenz kann ich nur meine Testumgebung verwenden.

--- Originally created on September 14th, 2011, at 04:19pm

Aybee commented 12 years ago

Wieso wird denn selbst das Array schon unterschiedlich ausgegeben???

FF 6 Ich bin eine englische Website. Array ( [0] => de [1] => ch )

Opera 11.51 Ich bin eine deutsche Seite. Array ( [0] => de [1] => en )

Safari 5.1 Ich bin eine englische Website. Array ( [0] => de )

IE 7/8 Ich bin eine englische Website. Array ( [0] => de )

--- Originally created on September 14th, 2011, at 04:22pm

ghost commented 12 years ago

Das Array ist die Rangliste der Sprachen, in denen der Browser die Inhalte haben will.

--- Originally created by vbinsider on September 14th, 2011, at 04:26pm

ghost commented 12 years ago

Es ist ein Contao nach der Installation ohne zusätzliche Module. Die PHP-Konfiguration ist über http://contao.dev.werbecafe.de/phpinfo.php einzusehen. Gerne kann ich ein Backendzugang bereitstellen oder das installierte System in Gänze zur Verfügung stellen.

Mein Vorgehen bei der Testinstallation war wie folgt:

1.) Installation von Contao 2.) Anlegen eines Startpunktes mit Sprache Deutsch und der entsprechenden Domain. Dieser Startpunkt ist kein Sprachenfallback. 3.) Anlegen einer regulären Seite unterhalb dieses Startpunktes inkl. eines Artikels mit der Ausgabe "Ich bin eine deutsche Seite". 4.) Anegen eines Startpunktes mit Sprache Englisch und der entsprechenden Domain. Dieser Startpunkt ist das Sprachenfallback. 5.) Anlegen einer regulären Seiten unterhalb dieses zweiten Startpunktes inkl. eines Artikels mit der Ausgabe "Ich bin eine englische Seite". 6.) Anlegen eines Demothemes unter Verwendung der mitgelieferte fe_page.html5. Eine Ausgabe erfolgt im Bereich "Hauptspalte". Zum Test habe ich in diesem Template zusätzlich $this->Environment->httpAcceptLanguage ausgeben lassen, um die verwendeten Browsersprachen anzuzeigen.

--- Originally created by r00xster on September 14th, 2011, at 04:28pm

ghost commented 12 years ago

Ich habe nun einmal die Ergebnisse des zur Bestimmung des Startpunktes verwendeten SQL-Queries überprüft.

FIND_IN_SET() gibt allen Sprachen in $accept_language eine Position gemäß ihrer Reihenfolge in $accept_language, beginnend ab 1. Ist die Fallbacksprache nicht in $accept_language enthalten, wird diese trotzdem aufgrund der Where-Bedingung "fallback = 1" erfasst. FIND_IN_SET() kennt diese Sprache aber nicht, da sie ja nicht in $accept_language enthalten ist und weist ihr daher die Position 0 zu. Folglich wird die Fallbacksprache bei der aufsteigenden Sortierung zuerst beachtet.

Umgehen kann man dieses Problem nur, indem man auf die Abfrage von Contao < 2.10 zurückgreift und FIND_IN_SET() nicht weiterverwendet oder eine Unterabfrage einbaut. Die Abfrage in der Frontend.php müsste dann wie folgt aussehen:

$objRootPage = $this->Database->prepare("SELECT p.id, p.dns, p.language, p.fallback, (SELECT l.language FROM tl_page as l WHERE l.type = 'root' AND (l.dns=p.dns OR dns='') AND l.fallback=1" . (

![](BE_USER_LOGGED_IN ? " AND (l.start='' OR l.start<UNIX_TIMESTAMP()) AND (l.stop='' OR l.stop<UNIX_TIMESTAMP())" : "") . " AND published = 1) as fallbackLanguage FROM tl_page as p WHERE p.type='root' AND (p.dns=? OR dns='')" . ((count($accept_language) > 0) ? " AND (p.language IN('". implode("','", $accept_language) ."') OR p.fallback=1)" : " AND p.fallback=1") . ()BE_USER_LOGGED_IN ? " AND (p.start='' OR p.start<UNIX_TIMESTAMP()) AND (p.stop='' OR stop>UNIX_TIMESTAMP()) AND p.published=1" : "") . " ORDER BY p.dns DESC" . ((count($accept_language) > 0) ? ", " . "FIND_IN_SET(p.language, CONCAT('".implode(',', $accept_language)."', ',', fallbackLanguage) )" : "") . ", p.sorting")
->limit(1)
->execute($host);

Diese Unterabfrage fragt die Fallback-Sprache ab und übergibt diese zusätzlich als letzten Wert an FIND_IN_SET().

Auf unseren Servern war bei der geänderten Abfrage kein signifikanter Geschwindigkeitsverlust festzustellen.

--- Originally created by r00xster on September 14th, 2011, at 07:28pm

leofeyer commented 12 years ago

So umständlich muss es glaube ich gar nicht sein. Bitte teste mal den angehängten Patch.

--- Originally created on September 15th, 2011, at 02:11pm

Aybee commented 12 years ago

Ich wollte nur nochmal bestätigen, dass der Effekt erst so ca. im Juni, July 2011 aufgetreten ist, wenn mich nicht alles täuscht.

--- Originally created on September 15th, 2011, at 03:23pm

ghost commented 12 years ago

Mit dem Patch funktionierte nun alles im Safari bei einer einziger Browsersprache, im Firefox hingegen mit EN, DE, FR (in dieser Reihenfolge) wurde ebenfalls die deutsche Seite anstelle der englischen ausgegeben.

--- Originally created by r00xster on September 15th, 2011, at 03:30pm

leofeyer commented 12 years ago

Klar, wenn die Fallback-Sprache auch unter den akzeptierten Sprachen ist, wird sie dank der Patches trotzdem ans Ende sortiert. Ich überlege mir was anderes :)

--- Originally created on September 15th, 2011, at 08:17pm

ghost commented 12 years ago

Mit dem Patch funktionierte nun alles im Safari bei einer einziger Browsersprache, im Firefox hingegen mit EN, DE, FR (in dieser Reihenfolge) wurde ebenfalls die deutsche Seite anstelle der englischen ausgegeben.

Kann ich bestätigen. Dies ist ein kritischer Bug. Die Gecko-Engine wird auf über 30% aller Clients eingesetzt.

Wird es vor dem Relese von contao_2.10.2 noch einen neuen Patch geben?

OS: Windows 7

--- Originally created by maemaemae on September 19th, 2011, at 07:54pm

ghost commented 12 years ago

Nein, ich glaube, dass das Problem in diesem Falle eher daher rührt, dass Safari unter Mac OS X immer genau eine Sprache (nämlich die Systemsprache) übermittelt, unter Firefox und Chrome hingegen mehrere ausgewählt werden können.

Mein Firefox übermittelt deutsch und englisch - in dieser Reihenfolge.

--- Originally created by vbinsider on September 19th, 2011, at 08:02pm

ghost commented 12 years ago

Nein, ich glaube, dass das Problem in diesem Falle eher daher rührt, dass Safari unter Mac OS X immer genau eine Sprache (nämlich die Systemsprache) übermittelt, unter Firefox und Chrome hingegen mehrere ausgewählt werden können.

Mein Firefox übermittelt deutsch und englisch - in dieser Reihenfolge.

ich benutze firefox unter windows 7, gleicher fehler unter firefox.

mit diesem snippet erkennt er die sprache richtig: http://stackoverflow.com/questions/1043339/javascript-for-detecting-browser-language-preference

--- Originally created by maemaemae on September 19th, 2011, at 10:18pm

leofeyer commented 12 years ago

Ausgehend von der Feststellung, dass die Fallback-Sprache von FIND_IN_SET den Wert 0 erhält, wenn sie nicht im Sprach-Array vorhanden ist, habe ich einfach mal die Sortierung umgekehrt (kleinster Wert am Ende, nicht am Anfang). Ein erster Test hat funktioniert; Patch anbei. Bitte um Feedback.

--- Originally created on September 30th, 2011, at 02:24pm

ghost commented 12 years ago

Ich hab' den Patch in meiner 2.10.1-Installation eingespielt, und Contao liefert jetzt auch auf Smartphones (Android, iOS) die richtige Sprache aus.

--- Originally created by andypillip on October 3rd, 2011, at 05:52pm

ghost commented 12 years ago

Also in meiner Testumgebung hat nun auch alles einwandfrei funktioniert.

--- Originally created by r00xster on October 4th, 2011, at 10:38am

Aybee commented 12 years ago

Ist der Patch schon auf contao.org? Denn dort bekomme ich noch die englische Seite.

--- Originally created on October 4th, 2011, at 05:00pm

leofeyer commented 12 years ago

Nein, noch nicht. Behoben in 3c69da53f734c36c993e7d256ae0874f.

--- Originally created on October 5th, 2011, at 02:11pm

leofeyer commented 12 years ago

Ist der Patch schon auf contao.org?

Aber jetzt :)

--- Originally created on October 5th, 2011, at 02:12pm

Aybee commented 12 years ago

Jetzt kommt bei mir auch die deutsche Seite ;)

--- Originally created on October 5th, 2011, at 04:01pm

leofeyer commented 12 years ago

--- Originally completed on October 5th, 2011, at 02:11pm