Grüße, BugBuster"view source" is your guide.Danke an alle Amazon Wunschlisten Erfüller
So, nach knapp 5 Stunden wurden 32 Dateien für die Startseite von contao.org angelegt.
Das ist durchaus vertretbar für den Gewinn, die Startseite cachen zu können, die ja in der Regel am häufigsten aufgerufen wird.Code:empty.de.en. empty.fr empty.fr.en empty.pl.en empty.cs.en empty.es empty.pl empty.ru empty.de.en.es empty.sv.en empty.de.en empty.zh.en empty.pt.en empty.en.fr.ja.de.es.it.nl.sv.nb empty.ru.en empty.ru. empty.de.ch empty.lt empty.da empty.en.de empty.zh. empty.sv empty.en.cs empty.en empty.de.fr.en empty.nl.en empty.en.de.fr.it empty.es.en empty.pt empty.en.es empty. empty.de
Wird denn auch kontrolliert, ob das "valide" Sprachen sind ?
Weil du ja nur im Environment auf die $_SERVER['HTTP_ACCEPT_LANGUAGE'] zugreifst. Ich kann meinen Browser ja irgendwas vorgeben, womit das System dann gleich eine neue gecachte Seite erstellt.
So kann ich nicht nur den Server unnoetig beschaeftigen, weil ich mittels gefakter HTTP_ACCEPT_LANGUAGEs immer mehr den Server zuknallen kann, sondern kann auch gezielt Prozesse lahmlegen, weil ich ueberlange Dateinamen dadurch provozieren kann.
Ich habs noch nicht ausprobiert die HTTP_ACCEPT_LANGUAGE abzuaendern, aber theoretisch koennte man auch Dateien erzeugen, die andere ueberschreiben.
Kaeme auf einen Versuch an ;-)
von Willi Voltz aus PR 500: Henry George sagte einmal: »Kultur ist Zusammenarbeit.«
Contao-Hosting: begeisterter Uberspace-Nutzer
OK, gerade im Code nachgelesen. Dateien ueberschreiben wird nicht klappen, da du die erlaubten Sprachen mittels substr auf 2 Zeichen reduzierst.
Aber damit liesse sich sehr schnell ein Server dicht machen. EInfach alle Kombinationen durchgehen ;-)
Du solltest evt. nur Sprachen cachen, die das System auch unterstuetzt, ansonsten eben eine empty.default erzeugen. (guter Tip von leo-unglaub)
von Willi Voltz aus PR 500: Henry George sagte einmal: »Kultur ist Zusammenarbeit.«
Contao-Hosting: begeisterter Uberspace-Nutzer
Habe ich mir auch schon angeschaut. Geht leider nur bedingt. Zwar prüft Contao Anfangs welche Sprache er für die Module nehmen kann, aber innerhalb der Module nicht. Wenn im backend-Modul nur "de" und "en" vertreten sind, kannst du ja trotzdem einen Startpunkt mit "fr" haben. Contao nimmt dann aus den Sprachpaketen den englischen oder deutschen Teil, aus der DB dann aber z.B. das für französisch. Von daher ist die Einschränkung nicht so leicht möglich, da dann in irgendeiner Datei stehen müsste, welche Sprachen genutzt werden.
Kühne Behauptung.
Ich habs getestet. Für jede Sprachkombi wird eine neue Cache Datei angelegt der Startseite, obwohl (bei mir) der Inhalt der Cache Seite völlig identisch ist.
Darum gehts hier denke ich.
Vielleicht habe ich den Sinn ja noch nicht vollends verstanden.
(Startseite cachen schon, nur nicht warum es nicht reicht sich auf die erste Sprache zu beschränken bzw. auf die ausgelieferte durch fallback)
Wenn wir testen sollen, was sehr gut ist, dann müssen wir schon verstehen was.
Grüße, BugBuster"view source" is your guide.Danke an alle Amazon Wunschlisten Erfüller
von Willi Voltz aus PR 500: Henry George sagte einmal: »Kultur ist Zusammenarbeit.«
Contao-Hosting: begeisterter Uberspace-Nutzer
Wenn Du mal genau liest, was ich geschrieben habe, wirst Du feststellen, dass sich meine Aussage auf die "empty.default" bezieht und auf nichts anders (extra deswegen noch mal zitiert). Das andere Problem besteht zweifelsohne und mir fällt dazu auch keine Lösung ein. Also werden wir damit leben müssen, dass wir die leere Domain nicht cachen können.
War etwas missverstaendlich, da der Erste Teilsatz dominierte (check ob unterstytzte Sprache) gegenyber der kleinen Klammer worin das mit der empty.default stand.
Das ist geklaert und nun beruhigen wir uns wieder.
Mail ist raus. IMO ist dies ein genereller Schwachpunkt in Environment (siehe hierzu auch vorgeschlagenen Fix in der Mail).
Die Frage die ich mir hier stelle ist jedoch, wozu brauchen wir alle kombinationen?
Ein File pro pageroot sollte doch reichen (schliesslich klebt hier der Sprachcode).
Ausnahme hiervon ist doch lediglich der fallback, welcher alle moeglichen Sprachen haben kann.
Ich muss zugeben, ich hab mich mit dem zugrundeliegenden Problem des caches in diesem Sinne noch nicht wirklich beschaeftigt, lediglich die Idee gehabt das cachen in der vorliegenden Version zu exploiten. Fyr genaueres fehlt mir leider momentan die Zeit.
Gruss
Chris
Bedenke stets: Wenn Du ungenaue oder unzureichende Angaben machst, so koennte dies die Bearbeitung deiner Frage endlos verzoegern (oder sogar dazu fyhren, dass ich zu viel nachdenken muss und die Antwort vergesse!). Kein Support per PN.
Nunja, das mögliche Angriffsproblem könnte man schon ein bisschen dadurch einschränken, dass für die httpAcceptLanguage nur Sprachen erlaubt sind, die /[a-z]{2}/ entsprechen. Wenn man aktuell als akzeptierte Sprache irgendeinen anderen Wert liefert, dürften einige SQL-Befehle defekt sein (kann man aber durch die Beschränkung auf 2 Zeichen nicht wirklich ausnutzen). Allerdings gibt es immernoch zuviele möglichkeiten.
Gibt es eigentlich noch Stellen wo das die Sprache wichtig ist? Wenn es nur für die Modulsprache und die Webseitensprache ist, könnte man beim Hinzufügen eines Webseitenstartpunktes in den Cache alle erlaubten Sprachen schreiben. Dann ein array_intersect drüberlaufen lassen und schon sind es nur noch einige Dateien die erzeugt werden können.
Nu ja, ich habe genau gelesen, ich kenne dein System und den Code.
tl_page laesst sich durchsuchen, so laesst sich auch herausfinden, welche Seitensprachen unterstuetzt werden. Es gibt mit SIcherheit auch noch andere Stellen, wo man Sprachen definiert, hab ich gerade nicht parat (Sorry)
Aber zur Not, muss eben kontrolliert werden, ob die angeforderte Sprache in deinen eigens definierten Languages ist (TL_ROOT/system/config/languages.php) Damit laesst sich das schon deutlich reduzieren......
von Willi Voltz aus PR 500: Henry George sagte einmal: »Kultur ist Zusammenarbeit.«
Contao-Hosting: begeisterter Uberspace-Nutzer
Der Cache funktioniert so: Beim "starten" des CMS wird eine Prüfsumme der URL gebildet. Diese Prüfsumme sucht er dann in system/tmp/ und überprüft, ob er die noch verwenden darf. Wenn ja wird der Inhalt zurückgegeben und ansonsten der normale Code ausgeführt. Das ganze passiert, bevor irgendeine DB-Verbindung gestartet wird.
Bei der Startseite passiert nun folgendes: Das System wird hochgefahren und der Host, in Kombination mit der Sprache, in der DB nachgeschlagen und eine passende pageRoot gesucht (siehe Änderung rev 518). Wenn etwas passendes gefunden wurde, wird die entsprechende Seite genommen (oder der Fallback).
Problem an der Stelle mit cachen ist, dass der Cache keine Ahnung von der Sprache hat. Wenn dein Browser "en,de;0.9" als akzeptierte Sprache liefert, zieht er englische Webseiten vor, gefolgt von deutschen. Wenn es nun nur eine deutsche gibt, dann versucht Contao erst eine englische Seite für den aktuellen Host zu finden, findet dabei nichts, und anschließend nach einer deutschen, die er findet. Die zurückgelieferte Seite hängt somit immer von httpAcceptLanguages ab - und dabei sogar noch von der Reihenfolge (abgesehen davon das Leo da eine Annahme macht an die sich zwar jeder Browser hält, aber nicht ganz korrekt ist [bei en;0.9,de würde Contao nen Fehler machen]).
Und da der Cache keine Ahnung von den erlaubten Sprachen im System hat, muss httpAcceptLanguages im Cachedateinamen enthalten sein, damit er dem Browser nicht ausversehen die deutsche Seite aufliefert, wenn er eigentlich die deutsche zeigen sollte.
Btw: Der geänderte Code in #518 erlaubt es übrigens den MySQL-Server ziemlich leicht mit SQL-Anfragen zu bombardieren. Da wäre eine Abfrage in der Richtung :
besser, da es maximal zwei Abfragen wären, statt viele, denn bei 10 akzeptierenden Browsersprachen, wobei keine einen Treffer erzeugt, wären alleine da jetzt schon 22 Abfragen von Nöten. Mit einem angepassten SQL-Code wären nur zwei nötig: alle in Frage kommenden pageRoots, wobei PHP dann den besten ermitteln muss (abhängig von der Anzahl der zurückgeleiferten Pageroots und nicht von den Browsersprachen), und evtl. die Fallback-Seite (könnte man auch noch zur ersten packen, wenn man bissl mehr in die PHP-Logik steckt).PHP-Code:
SELECT id FROM tl_page WHERE type='root' AND (dns=? OR dns=? OR dns='') AND language IN ('', ?, ?, ?, ...) AND (dns<>'' and language<>'')
Gut beschrieben, kleine Anmerkungen:
Da ich mehrmals staunte musste ich in den Quelltext schauen wie du das meinst.
Im Dateinamen nicht direkt, die Prüfsumme wird aus URL + httpAcceptLanguages gebildet.
Cache Dateiname: 1ba8fcef37a6fd774662e3b5bcec471b (hier suche ich immer das de-en)
In der erste Zeile wird die auch nochmal eingetragen.
IP maskiertCode:<?php $expire = 1280433357; /* http://256.256.256.256/typolight-trunk/empty.de.en */ ?>
Hier meinste bestimmt die englische Seite.
Grüße, BugBuster"view source" is your guide.Danke an alle Amazon Wunschlisten Erfüller
Und warum geht man nicht so vor, dass pro Sprache eine Cache-Datei angelegt werden kann, beim Aufruf je Sprache auf eine im Cache liegende Datei geprüft wird und wenn nichts gefunden wurde danach die DB abgefragt wird?
Edit: OK, ich sehe darin schon ein Problem: Wenn die erste Sprache existiert, aber nicht im Cache abgelegt ist, die zweite aber schon, bekommt der Besucher die falsche Sprache serviert. Kann man das irgendwie umgehen?
Edit 2: Kann man nicht einfach eine Maximalzahl (z. B. 3 oder 5) für alternative Sprachen angeben, um den DDoS-Vektor zu versperren? Also max. möglicher Dateiname z. B. 'empty.de.en.fr'. Mehr alternative Sprachen halte ich für äußerst selten, sollte dabei mal eine falsche Sprache ausgegeben werden, halte ich das für vernachlässigbar.
Geändert von FloB (29.07.2010 um 21:22 Uhr)
So long,
FloB since Nov. 2007 +706P +115P and counting
Ja, sorry. Ich war zu faul alles wieder auszuschreiben und da die, die hier mitschreiben, den Code zum Teil kennen, dahcte ich mir das sie sich denken können was mit httpAcceptLanguages gemeint ist .
Jop, wobei um ehrlich zu sein gefällt mir diese Variante nicht. Da ich ein eigenes Templatesystem geschrieben haben (achja, die If-Abfragen müsste ich auch mal fertig implementieren^^) und dort auch einen Cache habe, habe ich mich mal damit beschäftigt, wie man erkennt ob er den Cache noch verwenden darf oder nicht. Meine erste Variante war auch die Zeit in den Cache zu schreiben. Aber bei mir hat filemtime unter Unix und Windows problemlos funktioniert. Contao hätte sogar einen Performancevorteil davon, wenn statt include ein readfile dastehen würde, da das parsen wegfällt.
Jo, hast Recht. Bin sowieso erstaunt das ich vorhin noch einen halbwegs zusammenhängenden Text hinbekommen habe (hat jemand Lust für mich morgen die Klausur in theoretische Informatik zu schreiben [geht ja nur um reduction von NPC-Problemen und so ])
Wenn Du das System so gut kennst, solltest Du auch wissen, dass der Vorteil des Cache ist, dass eben keine DB-Verbindung aufgebaut wird. Und somit kann man auch nicht die tl_page durchsuchen. Deswegen sage ich: Theorien sind nett, aber bevor wir hier ernsthaft diskutieren können, solltet ihr eure Ideen zumindest mal implementiert und getestet haben.
Das ist mir klar.
Auch dies ist unstrittig jedoch IMO unnoetig, da der Cache vorher einsetzen koennte, siehe unten.
Ebenfalls klar, deine Befyrchtung der "Annahme" teile ich btw.
Generell sollte Environment die languages filtern und nach ihrer Gewichtung sortieren.
Dies ist nichtmal so aufwendig.
Der Cache MUSS keine Ahnung von den Seiten im System haben. Wozu auch?
Er muss lediglich checken ob eine(!) Seite existiert, welche in den akzeptierten Sprachen enthalten ist, zur Domain passt und obendrein einen leeren alias besitzt.
Diese Informationen koennen wir komplett ohne Datenbank erhalten.
Hierbei muss er lediglich die akzeptierten Sprachen durchlaufen (welche wie oben beschrieben nach Gewichtung sortiert sein myssten).
Hat er hierbei einen "[domainname].empty.[langcode]" Hit, muss er diesen ausliefern.
Hierbei ist es vollkommen egal was es war, ob fallback oder richtiger match. Ein vorheriger Aufruf hat naemlich bereits entschieden, dass wer unter dieser Domain mit Sprache XY vorbeikommt diese Seite erhalten soll.
Domainname bezieht sich hierbei auf die im Pageroot hinterlegte Domain (Womit Mehrfachinstallationen abgedeckt waeren).
Einzig verbleibende Faelle sind nun noch:
- der Fall, wo keine Sprachen vom Browser angefragt werden (HTTP 1.0 etc.). Hierzu koennten wir, in genau jenem Falle, eine "www.example.com.empty.nolang" o.ae. im cache ablegen.
- der Fall, wo keine vom Browser gesendeten Sprachen im System bekannt sind und somit der Fallback generiert werden muss. Dieser wird anschliessend auch ohne Cache generiert aber mit dem vom Browser praeferierten Sprachcode im Cache abgelegt (z.B. "www.example.com.empty.cz"), beinhaltet de facto aber eine Kopie der Startseite. Bei jedem subsequenten Aufruf wird die Seite mit entsprechendem LangCode ausgeliefert.
Der Einfachheit halber haben wir nun:
IMO ist es doch so (Mal aus Sicht des Browsers gesehen):Code:de,en => www.example.com.empty.de en,de => www.example.com.empty.en de => www.example.com.empty.de en => www.example.com.empty.en fr => www.example.com.empty.fr (im System nicht abgelegt, also fallback) '' => www.example.com.empty.nolang (Browser sagt nicht was er will, also fallback) 'cz,ru' => (Browser sagt nur unbekannte Sprachen, also fallback) www.example.com.empty.cz
Generell kann eine Seite immer nur eine Sprache haben.
Ebenfalls hat eine Seite auch nur einen URI bzw. alias.
Der Sinn und Zweck nun alle Browsersprachen in das hash zu ybernehmen hat sich mir nicht erschlossen. IMO erzeugt das nur massig duplicate cache content. Da koennte man auch (ybertrieben gesagt) auch das Cookie ins Hash einfliessen lassen.
Klaert mich auf, wo sind meine Denkfehler?
€dith: Argument von Flob oben macht Sinn, kann jedoch umgangen werden... muss mal ne Referenzimplementierung zusammenschmeissen.
Full ACK.
Grysse Chris
PS: warum nicht gleich eine allgemeine Cache Klasse bauen, welche strikt Hashes entgegen nimmt, vergleicht und bei matches den Wert returned und ansonsten false.
Dann koennten auch Extensions Teile von sich cachen (ich habe in einigen immer einen eigenen kleinene Cache Mechanismus einbauen myssen um Request-Ergebnisse zu puffern).
Geändert von xtra (29.07.2010 um 21:33 Uhr)
Bedenke stets: Wenn Du ungenaue oder unzureichende Angaben machst, so koennte dies die Bearbeitung deiner Frage endlos verzoegern (oder sogar dazu fyhren, dass ich zu viel nachdenken muss und die Antwort vergesse!). Kein Support per PN.
@FloB: Den Vorschlag wollte ich vorhin auch schon machen, bis mir der Fehler daran auffiel (so wie dir per Edit ).
Einzige Möglichkeit das zu umgehen ist der zusätzliche Cache, den ich in #59 ansprach. Problem daran: Man muss wissen, wo die erlaubten Sprachen gecacht sind, was Erweiterungen einschränken könnte (auch wenn es unwahrscheinlich ist)
Nur würde eine solche Abfrage nicht die Reihenfolge der Sprachen und somit ihre Wertigkeit berücksichtigen. Das ließe sich natürlich mit FIND_IN_SET() korrigieren, aber das entspricht nicht dem SQL92-Standard und kann daher nicht verwendet werden.
Und deswegen noch mal die Bitte: Implementiert eure Ideen zuerst und stellt sie dann hier zur Diskussion.
Geändert von FloB (29.07.2010 um 21:42 Uhr) Grund: typo
So long,
FloB since Nov. 2007 +706P +115P and counting
Hab gerade die r524 committed, die eine Kompromisslösung darstellt und einige andere Anregungen aus diesem Thread implementiert.
1. Die Suche nach der passenden Root-Seite simuliert nun FIND_IN_SET() und kommt dafür mit einer einzigen DB-Abfrage aus.
2. Die Funktion httpAcceptLanguage() prüft die Tags anhand einer Regexp und filtert leere Tags heraus.
3. Leere Requests werden nicht mehr in Abhängigkeit der Browsersprache sondern der Seitensprache gecacht. Stimmt die erste Browsersprache mit einer Seite überein, kann diese aus dem Cache geladen werden. Das funktioniert aber nur für die primäre Browsersprache und auch nur bei einem echten Treffer - also nicht bei Fallback-Seiten. Ist aber immer noch besser als gar nichts
Ich habe eben nur kurz drübergeschaut: Die MySQL-Rückgabe kannst du eigentlich beschränken, also dns eingrenzen etc. Der SQL-Befehl wird dadurch zwar länger, aber dafür braucht PHP danach weniger Records durchsuchen (MySQL wird mit Filtern effizienter sein).
Allerdings sehe ich ein Problem bei der Implementierung:
Ist das Ergebnis folgender Funktion beabsichtigt:
Bei eienr Domain wie meinwww.de (bzw. www.meinwww.de )PHP-Code:
str_replace('www.', '', $objRootPage->dns);
Ist das $strTag != '' nicht unnötig? pregmatch dürfte den Fall doch auch herausfiltern, wenn ich mich nicht irre.
Ist ein guter Kompromiss . In vielen Fällen dürfte der Cache da greifen und wenn nicht, gibt es auch keine Probleme, die durch den neuen Cache verursacht hätten werden können.
Ich habe eine Implementation, auch gegengetestet. Und der Geschwindigkeitsverlust ist vernachlaessigbar.
Getestet habe ich mit dem ApacheBench, der mir neutrale Daten liefern kann.
Und selbst eine DB Abfrage mittels SELECT DISTINCT(language) verschelchtert mir mein Ergebnis nicht nennenswert.
Bei 200 Anfragen, mit 10 parallel gestarteten Requests, ist beim Original eine Auslieferungszeit von 67ms. Wenn ich meine DBAbfrage nutze liegt diese bei 75ms.
Ja gut, mag einer sagen, 10% mehr. Aber dem Browser ist es egal, ob es nun nach 67ms da ist oder erst nach 75ms. Da er dann erst anfaengt und den Header auswertet, um JavaScript nachzuladen usw. Da faellt dieser kleine Versatz nicht mehr auf.
Alles getestet mit der MusicAcademy.
Ich werd heute abend einen Bericht mit den Beispielen hochladen. Sitze gerad ein Paris am Flughafen....
von Willi Voltz aus PR 500: Henry George sagte einmal: »Kultur ist Zusammenarbeit.«
Contao-Hosting: begeisterter Uberspace-Nutzer
Ich habe eben mal rumgespielt. In Anbetracht dessen das es meistens nur sehr wenige pageroots gibt, lohnt sich ein unübersichtliger SQL-Befehl da nicht wirklich.
Was ich am aber Code evtl. noch ändern würde: Statt über die Browser-Sprachen zu iterieren würde ich nur über die PageRoots iterieren und dabei schauen welches am besten passt (per array_flip geht da nen schneller Zugriff auf die Sprachpriorität)
So patch fertig.
Ich habe mal den längeren SQL-Ausdruck drin. Dürfte Geschmackssache sein ob man den nimmt, oder den aus rev524, wie ich ja bereits in meinem letzten Post schrieb.
Ansonsten habe ich den Code so geschrieben, dass er verständlich ist. Ich hatte zwar überlegt FIND_IN_SET wegzulassen und die ganze Logik dorthin zu packen, allerdings wäre das ungesund für die Gehirnwindungen gewesen (und auf die 1-2µs kommt es nun auch nicht an, die man evtl. gewinnen könnte).
Anonsten habe ich im Patch ein ganz paar Codestellen mit deutschen Kommentaren begründet (rev. 524 verhält sich anders als die davor [ob by design oder nicht, weiß ich nicht])
Kleine Korrektur für den Patch:
Statt
wäre das hier wohl besser:PHP-Code:
$key = preg_replace('/^www./', '', $objRootPage->dns);
Die domain www.de ist ja leider auch gültig - und wenn der Benutzer dann in den pageRoot nur www.de einträgt, käme es sonst zu einem Fehler, da dass preg_replace immer ein "de" darauf machen würde, was natürlich nicht mehr zum host passt.PHP-Code:
if ($host != $objRootPage->dns)
{
$key = preg_replace('/^www./', '', $objRootPage->dns);
}
else
{
$key = $host;
}
Ich habe mal noch ein Patch gemacht wegen der Sprachpriorität, also das Contao sich korrekt verhält, falls der Input mal "de;q=0.9,en" statt "en,de;q=0.9" sein sollte. Außerdem habe ich das Ergebnis gecacht, da die Methode doch mehrfach aufgerufen wird (Cache, initialize.php, Frontend und ggf. für Log-Einträge) und das Ergebnis konstant sein sollte.
Nebenbei habe ich in der initialize.php mal eine kleine Performanceoptimierung eingebaut. Zwar ist die Stelle immer noch abhängig von der Anzahl der Browsersprachen, aber ich hatte keine Lust erst alle Unterordner auszulesen (warum bietet php dafür keine fertige Funktion? ). Die Anzahl der Festplattenzugriffe habe ich trotzdem reduziert.
@Leo: Nicht wundern das im Patch mache unwichtige Zeilen modifiziert sind. Meine IDE entfernt automatisch nutzlose Leerzeichen (was ich praktisch finde)
SPL / DirectoryIterator et al.
So long,
FloB since Nov. 2007 +706P +115P and counting
Ich wollte mich hier schon ganz zu beginn mit meinen ersten Gedanken zu Wort melden, habe dann aber gemerkt dass Leo einiges mehr bedacht hatte, als ich im ersten Moment
Nun habe ich trotzdem/noch folgende Anmerkungen/Fragen zu Rev. 526:
1: Frontend.php, Zeile 132 sollte doch "OR fallback=1" auch gefragt werden, wenn der Browser keine Sprachen übergibt? Das erübrigt sich aber mit Punkt 3.
2: Das parsen der Sprachen könnte doch mit Regex enorm vereinfacht werden? Zumindest array_values ist nicht nötig, weil array_slice die Keys sowieso neu generiert.
3: Danach habe ich mir noch die getRootIdFromUrl angeschaut. Ich hatte bereits mal das Problem dass ich die Sortierung eines WHERE ... IN realisieren musste. Hier meine Variante der FunktionPHP-Code:
protected function httpAcceptLanguage()
{
preg_match_all('/([a-z]{2})[^,]*/', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']), $matches);
return array_slice(array_unique($matches[1]), 0, 8);
}
PHP-Code:
protected function getRootIdFromUrl()
{
$host = $this->Environment->host;
$accept_language = $this->Environment->httpAcceptLanguage;
$time = time();
$objRootPage = $this->Database->prepare("SELECT id, dns, language, fallback FROM tl_page WHERE type='root' AND (dns=? OR 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, 'www.'.$host);
return intval($objRootPage->id);
}
Als Anmerkung: Ja, ich habe alles implementiert und getestet... Bei Punk 3 habe ich alle 4 Varianten geprüft und es hat immer funktioniert.
terminal42 gmbh
Wir sind Contao Premium-Partner! Für Modulwünsche oder Programmierungen kannst du uns gerne kontaktieren.
Hilfe für Isotope eCommerce kann man auch kaufen: Isotope Circle
Stimmt, er fällt nicht auf die Fallback-Seite zurück, falls der Browser Sprachenlos ist. Eben getestet.
Sieht zu einfach aus . Aber um ehrlich zu sein würde ich es trotzdem besser finden, wenn der q=-Part beachtet wird.
Allerdings finde ich den Rückgabewert der Methode unschön. Stellt euch vor, ihr habt 2 Hotels. Eins in der Schweiz und eins in Deutschland. Momentan kann man nur eine gemeinsame Seite erstellen. Es ist aber nicht möglich für die Schweizer vlt. einen Header mit einem Bild des schweizerischen Hotels zu zeigen und den deutschen das vom deutschen Hotel - zu mindestens nicht ohne das man im Template selber noch $_SERVER['HTTP_ACCEPT_LANGUAGE'] ausgewertet wird, da httpAcceptLanguage den Unterschied zwischen de-DE und de-CH unterschlägt. Im Normallfall wäre es überhaupt kein Problem, wenn man nicht aus de-DE ein de macht, da die Browser im Normallfall beide Versionen senden. Und wenn nicht: Man kann aus "de-CH,en" auch ein array('de-CH', 'de', 'en') machen. Dem System selber sollte es nicht stören, wenn es aufeinmal noch eine solche Unterscheidung gibt (es gibt halt keinen Sprachordner de-CH, also wird de genommen).
@Leo: Was ich im Patch als Kommentar-Frage gestellt hatte: Ist es beabsichtigt, dass wenn für den aktuellen DNS zwar eine Host gibt, die Sprache aber nicht passt und kein Sprach-Fallback für diesen Host gibt, dass er nicht mehr auf den globalen Sprachfallback zurückfällt? Ich kann beide Verhalten verstehen - ich wudner emich nur, da es bei Bigfix-Releases ja eigentlich nicht unbedingt das Verhalten geändert werden sollte (auch wenn es vermutlich keinen trifft ).
Das ist ein Iterator-Objekt, über eine Schleife fragt man die Elemente ab, und kann diese dann darauf überprüfen, ob es sich um ein Verzeichnis handelt. Die Funktion getSubDirs($strDir) ist in 5 Code-Zeilen abgehandelt:
Aber das gehört eigentlich nicht zum Thema. Wenn du darüber weiter diskutieren möchtest, soll doch bitte ein Mod die nicht relevanten Beiträge auslagern. Danke!PHP-Code:
function getSubDirs($strDir)
{
$arrDirs = array();
$objDirIt = new DirectoryIterator($strDir);
foreach ($objDirIt as $objFileInfo)
{
if ($objFileInfo->isDir())
{
$arrDirs[] = $objFileInfo->getFilename();
}
}
return $arrDirs;
}
Edit: Wohl besser wäre (die leider kaum dokumentierte) RecursiveDirectoryIterator-Klasse, die eine Methode '::getChildren' besitzt.
Geändert von FloB (02.08.2010 um 22:22 Uhr) Grund: ein '}' zu viel
So long,
FloB since Nov. 2007 +706P +115P and counting
Sieht auf jeden Fall gut aus. Aber nur weil der Code kompakter geschrieben ist, heißt es nicht, dass er auch effizienter läuft. Und nur darauf kommt es letztendlich an.
Das ist sehr interessant und könnte die Fallback-Lösung für DB-Treiber werden, die kein FIND_IN_SET() unterstützen. Muss ich unbedingt mal versuchen
Nach aktuellem Trunk, bekomme ich immer angezeigt:
Es gehen auch einige Funktionen im BE nicht mehr. (der Pfeil zum Aufklappen der verkürzten Elemente fehlt)Code:Fehler: CONTAO_THEME is not defined Quelldatei: http://meinedomain/contaotrunk/contao/contao.js?2.9.1 Zeile: 30
Habe Session-Daten und Temp Verzeichnisse schon gelöscht.
UPDATE
Hinweis für alle, be_main.tpl hat sich geändert! Aufpassen.
Jetzt gehts bei mir.
Geändert von BugBuster (03.08.2010 um 09:50 Uhr)
Grüße, BugBuster"view source" is your guide.Danke an alle Amazon Wunschlisten Erfüller
Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
Lesezeichen