Zum Inhalt springen

Conditions und dynamische Anzeigen bzw. Menues

Erstellt am 15. April 2011 · 3 Antworten · letzte Antwort am 16. April 2011

Tags: PHP, Frage

ÁndreMansfeld ·

Hallo Freunde,
habe hier ein komplexeres Problem.
Ich möchte, dass beim Aufrufen einer Seite ein Sessioncookie bzw. eine Session ausgelesen wird und damit dann das Menu aus einem Seitenbaum aufgerufen wird.
Ich habe dazu in der Vorbereitung eine Extension geschrieben, die immer (eingebunden im TS der ROOTSeite) folgendes macht. (Es geht um Stadtspezifische und Deutschlandweite Ausgaben)

Wenn POST und SESSION leer -> erzeuge POST und SESSION sowie Cookie mit einem WERT in -> anzeige (für Erstbesucher)
Diese sollten dann auf der Startseite das Menu für DEUTSCHLAND erhalten.

Sollten diese dann über ein DropDown Menu eine Stadt wählen, wird ein POST erzeugt, der als Wert den Namen der Stadt erhält. Gleichzeitig wird mit dem POST auch eine Session und ein Cookie erzeugt.

In der Extension steht somit-> Wenn POST = STADTNAME erzeuge auch eine Session sowie ein Cookie mit dem Stadtnamen (damit beim Seitenumschalten auch immer Ausgaben aus dieser Stadt erscheinen).

Solange bis ein neuer POST mit einem anderen Stadtname oder wieder Deutschland aufgerufen wird.

Ich mache das so in der EXTENSION:

if(!isset($_SESSION['anzeige'])){$_SESSION['anzeige'] = 'Deutschland';}
if(!empty($_POST['anzeige'])){
	$_SESSION['anzeige'] = $_POST['anzeige'];
	setcookie("anzeige", $_POST['anzeige']);
}elseif(!empty($_COOKIE["anzeige"]) AND $_COOKIE["anzeige"] != $_SESSION['anzeige']){
	$_SESSION['anzeige'] = $_COOKIE["anzeige"];
}

Im TS der ROOTSEITE steht:

# grundsätzlicher Navigationstree einstieg
temp.nav  = TEXT
temp.nav  = 38
...
[globalVar = GP:anzeige = *]
temp.nav  = TEXT
temp.nav  = 38
[globalVar = GP:anzeige = Deutschland]
temp.nav  = TEXT
temp.nav  = 38
[else]
temp.nav  = TEXT
temp.nav  = 39
[global]

Was dazu führen sollte, dass wenn kein POST Wert vorhanden oder Deutschland als Wert ausgelesen wird, die Navigation für Deutschland (38-)
und bei vorhandenem Postwert für eine Stadt die 39 (für die Städte) ausgegeben wird.

Außerdem soll dauerhaft diese AUSWAHL auf der Seite gezeigt werden (damit man weiss wo man sich befindet).
Dieses erledigt:

seite.10.marks.STADTANZEIGE = TEXT
seite.10.marks.STADTANZEIGE.data = GPvar : anzeige
seite.10.marks.STADTANZEIGE.ifEmpty = nicht gesetzt

Der Wert anzeige ist sowohl der POST als auch der SESSION und Cookie Wert.

Grundsätzlich funktioniert das auch, aber nun zu meinen Problemen.

1: Wenn ich mit dem DropDown umschalte erhalte ich gewünschte Ausgaben, aber sobald ich auf Unterseiten gehen möchte, verschwindet meine Anzeige.
Mit einem Print auf SESSION und POST erhalte ich aber die richtigen Ausgaben im Header der Seite. Das heißt ja, dass meine POST/SESSION und Cookie Daten da sind!

POSTDATEN werden so im Header angezeigt -> Array ( [anzeige] => Deutschland ) 
SESSIONDATEN werden ebenfalls so angezeigt -> Array ( [anzeige] => Deutschland )

Ich denke also, dass meine Abfrage mit globalVar auf die GP:anzeige nicht richtig ist.
Beim ersten Aufrufen nach dem DropDown umschalten wird die "ANZEIGE" richtig angezeigt dann nicht mehr.

Hier meine konkrete Frage:
Mit welchem TS Code erhalte ich dauerhaft die Ausgabe des gerade aufgerufenen Session/Post Werts?

2: Beim ersten Aufrufen der Seite erhalte ich gar keine Werte. Es müßte ja zumindest das letzte Cookie und auch die letzte Session noch gespeichert sein und somit auch eine Zuweisung per Condition funktionieren. Sowohl im Header (per Print als auch in einem Marker stehen sie ja auch noch drin), aber innerhalb meiner Condition hat das keine Auswirkungen. Auch die ANZEIGE liefert nichts.

Ich weiss, dass das Cookies sowie die Session ja erst nach dem Aufrufen erzeugt werden und somit meine Condition auf Sessions und Cookies nicht greifen kann, aber dann doch zumindest die POST Daten.

Es müßte in den CONDITIONS also heißen:
Wenn kein Cookie oder keine SESSIONDATEN, dann zeige DEUTSCHLAND ansonsten nehme die gerade erzeugten POST Daten.

Das habe ich aber trotz aller Bemühungen noch nicht erreicht.
Ich habe es mit globalVar, globalString, HTTP_SESSION_VAR sowie
globalString = TSFE|fe_user|sesData|auswahl=Deutschland ect.pp. probiert.

Ist ein bisserl kompliziert, aber ich hoffe ihr habt einen Lösungsansatz für mich
Lieben Gruß Andreas

igorshmigor ·

Mit GPVar greifst Du nur auf GET und POST zu, deshalb heißt es ja auch GP, das steht für GET/POST. TYPO3 schmeißt beides zusammen. Die Session Werte stehen da nicht drin.
fe_user|sesData funktioniert, glaube ich, nur mit dem TYPO3 Frontend User Management. Das hat eine eigene API und verwendet auch die Datenbank zum Speichern der Session-Daten, ein einfach $_SESSION[$key]=$value reicht da nicht. Beispiel aus class.tx_felogin_pi1.php:

$GLOBALS['TSFE']->fe_user->setKey('ses', 'forgot_hash', array('forgot_hash' => $hash));

Und da ich annehme, dass der User in Deinem Fall nicht unbedingt angemeldet sein muss, kannst Du das wahrscheinlich eh nicht verwenden.
Was Du aber machen kannst, ist eine eigene Condition zu definieren. Das sieht in TypoScript so aus:

[userFunc = user_checkAnzeige(Deutschland)]

in Deiner localconf.php kannst Du diese Funktion definieren. Sie muss true oder false zurückliefern.
Beispiel:

function user_checkAnzeige($ort){
  // $ort enthält den Wert, der in der Condition in Klammern übergeben wurde
  ... hier Dein Session-Zeug
  if ($ort!=$anzeige){
    return false;
  }
  return true;
}

So ungefähr.

ÁndreMansfeld ·

Vielen Dank für die ausführliche Antwort.
Dachte mir schon, dass evt. die $_SESSION oder $_POST nicht direkt im TS abzurufen sind.
Deine Variante habe ich gerade eingebaut und werde sie noch ein bisschen trimmen 😃.
Nur zur Info (weil ich dachte die Angaben würden reichen!).
Innerhalb der Extension, welche das DropDown erzeugt und auch die Sessions und Cookies erzeugt habe ich schon auch versucht mit den Typo3 eigenen Mitteln die Variabelen zu übergeben.
Mit:

...
$stadtausgabe = $_SESSION['anzeige'];
$GLOBALS["TSFE"]->fe_user->setKey('anzeige',$stadtausgabe);
$GLOBALS["TSFE"]->storeSessionData();
...

habe ich es schon versucht.
Wie du schon erwähntest funktioniert das aber doch nur, wenn der User angemeldet ist.
Wie auch immer, ich werde jetzt mal mit deiner Methode rangehen.

Danke nochmal
Andreas

ÁndreMansfeld ·

So hier nochmal die Zusammenfassung für die jenigen, die sowas auch mal benötigen.
Hiermit wird ein Mechanismus erzeugt, bei dem man abhängig von der Session auf verschiedenen Menutrees bleibt. Bei mir ist das entweder DEUTSCHLANDWEIT oder Stadtspezifisch(mehrere).

Ich habe die Variable anzeige jetzt auswahl genannt.

In der localconfig.php im typo3conf Ordner habe ich an beliebiger Stelle folgenden Code eingefügt.

// EIGENER CODE ZUR SESSIONERZEUGUNG UND WEITERGABE AN USER FUNCTION
function user_checkAnzeige($ort){
  // $ort enthält den Wert, der in der Condition in Klammern übergeben wurde
if(!isset($_SESSION['auswahl'])){$_SESSION['auswahl'] = 'Deutschland';}
if(!empty($_POST['auswahl'])){
	$_SESSION['auswahl'] = $_POST['auswahl'];
	setcookie("auswahl", $_POST['auswahl']);
}elseif(!empty($_COOKIE["auswahl"]) AND $_COOKIE["auswahl"] != $_SESSION['auswahl']){
	$_SESSION['auswahl'] = $_COOKIE["auswahl"];
}
$auswahl = $_SESSION['auswahl'];
if ($ort!=$auswahl){
    return false;
  }
  return true;
}

Dieser Code bewirkt folgendes:
1:
Wenn kein Cookie, keine Postdaten, keine Sessiondaten vorhanden, dann werden sie somit erzeugt.
Einfach erklärt: Wenn leer -> dann erzeuge Variable "Deutschland" (Ist die Startseite!).
Dies ist z.B. beim Erstbesucher der Fall und dadurch wird beim Aufrufen der Seite das Menu für Deutschland gezeigt(Erklärung später in der TS Condition).

2:
Egal welche Daten bereits drinstehen(Weil der Besucher z.B. schon mal da war oder sich gerade innerhalb der Seite bewegt), werden alle Daten auf den gleichen Stand gebracht.
Einfach erklärt: Wenn POST Daten übermittelt werden dann werden auch Session- und Cookie Daten angepasst, damit die Seite eine neue Session/Cookie erhält.

Solange man mit dem DROPDOWN Menu nicht eine andere Stadt oder wieder auf Deutschland schaltet... gilt die letzte Session.

3:
IM TS prüfe ich mit der CONDITION

#STADTMENU
temp.nav  = TEXT
temp.nav  = 39

[userFunc = user_checkAnzeige(Deutschland)]
temp.nav  = TEXT
temp.nav  = 38
[global]

ob aus der localconfig.php ein FALSE oder TRUE übermittelt wurde.

Zuerst schalte ich einen IST ZUSTAND in dem ich temp.nav = 39 als BASISWERT erzeuge.
Somit erhalte ich die Navigation für eine Stadt.

Wenn der Wert aber TRUE ist erhalte ich temp.nav = 38 für die Deutschland Navi.

All dies hat folgende Auswirkungen:
Erstbesucher kommen auf die Startseite und haben das DEUTSCHLAND MENU.
Besucher die Infos aus der Stadt haben wollen und auch dort bleiben, erhalten die Session für die Stadt und beim Navigieren durch den gesamten Seitenbaum erhalten Sie auch immer nur STADT spezische Ausgaben/MENUS.
Außerdem wird dauerhaft die Stadt angezeigt, weil ich diese Info aus der Session generiere.

Mein Menu für die Umschaltung ist eine eigene Extension in der ein Formular generiert wird, welches als DROPDOWN eine Liste der Städte enthält, sowie den RÜCKFALL zu DEUTSCHLAND :-).
Hiermal der Code dafür:

$template = $this->cObj->getSubpart($this->templateCode,"###SESSIONSTADT###");

$staedte = array(
	'Deutschland' => 'Deutschland - Pckids Startseite',
	'München' => 'München',
	'Frankfurt' => 'Frankfurt',
	'Darmstadt' => 'Darmstadt',
	'Wiesbaden' => 'Wiesbaden',
);
$markerArray['###STADT###'] = '<form method="post" name="auswahl" action="index.php?id=4"><select name="auswahl" size="1">';

foreach ($staedte as $val => $stadt){

	$markerArray['###STADT###'] .= '<option value="'.$val.'"';
	if($val == $_SESSION['auswahl']){$markerArray['###STADT###'] .= '"selected=selected"';}
	$markerArray['###STADT###'] .= '>'.$stadt.'</option>';
}
$markerArray['###STADT###'] .= '</select>
  <input  type="submit" value="und los!">
  <input name="stadtangabe" type="hidden" id="stadtangabe" value="'.$stadtausgabe.'" />
</form>';
$sess = $_SESSION['auswahl'];
$markerArray['###SESSION###'] = $sess; // Hier lasse ich die ausgewählte Stadt ausgeben
$content= $this->cObj->substituteMarkerArrayCached($template,$markerArray);

Das generiert ein Formular welches ich über die Extension auf der Seite ausgeben lasse.

VIELEN LIEBEN DANK an igorshmigor !!!!!

Lieben Gruß Andreas

NACHTRAG: Da fällt mir ein!!!
DAS SIND KEINE SQL SICHEREN CODES!!!
Die übergeben Variabelen sollten auf jeden Fall noch auf Sicherheit gecoded werden.