Zum Inhalt springen

Extbase und Ajax und PageType

Erstellt am 9. Januar 2014 · 10 Antworten · letzte Antwort am 23. Juli 2014

Tags: JavaScript & AJAX, Frage

Unbekannter Benutzer ·

Hallo alle miteinander!

Ich hänge mal wieder bei der Arbeit mit Extbase. Mein Ziel ist es, via Ajax vom Frontend aus eine Action in meinem Controller aufzurufen, damit diese irgend etwas tut und evtl. noch einen Wert zurück gibt.
Es handelt sich hierbei erstmal nur um einen Testaufruf, um zu verstehen, wie das Zusammenspiel von Extbase und Ajax funktioniert.

Ich habe mich bei dem Test an folgende Beschreibung gehalten, wobei ich mich für die Variante mit dem PageType entschieden habe:
http://daniel.lienert.cc/blog/blog-post/2011/04/23/typo3-extbase-und-ajax/

Erstmal zu meinem Code:

TypoScript:

# Prototyp für alle Ajax-Aufrufe
lib.AJAXPrototype= PAGE
lib.AJAXPrototype {
  typeNum = 100000
  config {
    disableAllHeaderCode = 1
    xhtml_cleaning = 0
    admPanel = 0
    debug = 0
    no_cache = 1
    additionalHeaders = Content-type:text/plain
  }
}

# Testaufruf für bestimmtes Plugin
AJAX_Plugintyp < lib.AJAXPrototype
AJAX_Plugintyp{
  typeNum = 100001
  10 < tt_content.list.20.tx_myextension_pi1blubb
}

Controller-Action:

/**
 * action for ajax-test
 *
 * @return void
 */
public function myajaxAction(){
	file_put_contents("BLUBB.txt", "TEST");
	echo "erfolg"; exit;
}

Ajax-Aufruf:

function testAjax(){	 
	var url_controller = 'tx_myextension_pi1blubb[controller]=Myextension';
	var url_action = 'tx_myextension_pi1blubb[action]=myajax';
	var url_data = 'tx_myextension_pi1blubb[uid]=7';
	var url_type = 'type=100001';

	$.ajax({
		url: 'index.php',
		data: url_controller + '&' + url_action + '&' + url_data + '&' + url_type,
		success: function(result){
			alert(result);
		}
	});
}

Der Ajax-Aufruf an sich scheint zu funktionieren (er führt zumindest die success-Funktion aus). Die Ausgabe der alert-Methode in der success-Funktion ist allerdings leer. Um zu prüfen, ob wenigstens meine Action aufgerufen wird, wollte ich mit der Zeile file_put_contents("BLUBB.txt", "TEST"); eine existierende (mit vollen Rechten versehene) Textdatei beschreiben. Diese bleibt aber leer. Also gehe ich davon aus, dass die Action nicht aufgerufen wird.
Folgendes habe ich schon geprüft und soweit als Fehlerquelle ausgeschlossen:
- Die Action myajax ist eine erlaubte und ungecachte Aktion für das Plugin.
- Die Action habe ich mit und ohne Template-Datei getestet - gleiches Resultat.
- Ich habe die Zeile echo "erfolg"; exit; zum Testen rausgenommen und eingefügt - gleiches Resultat.
- Ich habe nach jeder Änderung den Konfig- und Alle Seitencaches geleert.

Hat irgend jemand eine Idee, wo mein Fehler liegen könnte? Ich arbeite mit der Typo3 6.2 beta3 - falls das hier eine Rolle spielt. Ich habe das Gefühl, dass es an folgender TypoScript-Zeile liegt:
10 < tt_content.list.20.tx_myextension_pi1blubb
Diese sollte - soweit ich das verstehe - doch dazu führen, dass das Plugin aufgerufen und die übergebene Aktion im entsprechenden Controller ausgeführt wird. Oder verstehe ich das falsch?

Danke schonmal für eure Hilfe 🙂

Schweriner ·

Also ich hab schon viel mit AJAX gemacht, aber bin gerade leider nicht um Büro um alles mal genau zu vergleichen. Den AJAX Abruf bzw. deine Action würde ich erstmal wirklich ganz simpel halten und einfach nur return "Test"; reinschreiben.
Schreib mal in dein AJAX Plugintype im Typoscript blödsinn rein bzw. ändere mal den Namen der Action und ruf die Seite mal mit deinem Browser auf. Wenns dann Fehler gibt, weißt Du, Du bist auf der richtigen Seite. Also generell erstmal im Browser testen ob dein Typoscript korrekt ist.

Im übrigen kann es sein, dass in Deiner URL der Actionname groß geschrieben sein muss, da bin ich mir aber nicht sicher.

Neulich hatten wir das Phänomen, dass wir manche AJAX Seiten nur ohne die Angaben von tx_ in der URL aufrufen konnten und wissen bis heute nicht so genau warum.

Unbekannter Benutzer ·

Vielen Dank. Das sind einige gute Ansätze zur Fehlersuche! Ich komme leider erst am Montag wieder dazu, das auszuprobieren. Ich gebe auf jeden Fall nochmal Bescheid, ob ich Erfolg hatte 🙂

Unbekannter Benutzer ·

Ok, also ich habe nun folgendes probiert:
- Code im TypoScript so geändert, dass er fehlerhaft ist (fehlerhafte Angabe bei der Plugin-Zuweisung)
- Name der Action geändert im Controller
- Name der Action geändert im Ajax-Aufruf
- Name der Action im Ajax-Aufruf groß geschrieben
- tx_ im Ajax-Aufruf entfernt
- Befehlt in der Controller-Action wie in meinem 1. Post bzw. durch "return 'blubb';" ersetzt
- Controller umbenannt

Die Tests habe ich selbstverständlich nacheinander durchgeführt und den kompletten Cache jedes Mal geleert. Außerdem habe ich die Tests sowohl auf meinem bisherigen Test-Typo3 beta3 als auch auf einem komplett neu installierten Typo3 beta3 durchgeführt (um Fehler durch fehlerhaftes Updaten der Typo3-Version auszuschließen).

Leider überall das selbe Ergebnis: ich erhalte einen leeren String als Ausgabe und die Action wird scheinbar nicht aufgerufen. Ich erhalte auch keine einzige Fehlermeldung - weder von Typo3 noch von PHP (Typo3 läuft aktuell im Debug-Modus).

Wenn ich die URL im Browser aufrufe, die von Ajax aufgerufen wird (index.php?tx_myextension_pi1blubb[controller]=Myextension&tx_myextension_pi1blubb[action]=myajax&tx_myextension_pi1blubb[uid]=7&type=100001) findet scheinbar eine 301-Weiterleitung von Typo3 auf die URL "index.php?id=2&type=100001&no_cache=1" statt. Ich weiß nicht, ob das vielleicht eine Rolle bei dem Problem spielt. Ich nutze zum Testen weder simulate_static noch realurl.

Ich vermute allerdings immernoch, dass es irgendwie am TypoScript liegt, dass Typo3 hier scheinbar noch nicht einmal den Controller lädt (würde Typo3 ihn laden, hätte ich vermutlich eine Fehlermeldung erhalten, als ich den Controller zum Testen umbenannt habe).

Ich wollte zum Testen die Erweiterung mit dem Ajax-Test auf einem aktuellen Typo3 4.5 installieren, um auszuschließen, dass es an der Beta-Version von Typo3 6.2 selbst liegt, aber auf 4.5 läuft die Erweiterung natürlich nicht, da die Extbase-Version eine andere ist etc.

Habt ihr evtl. noch weitere Ideen, woran es liegen könnte? Ich bin mit meinem Latein langsam am Ende...

Unbekannter Benutzer ·

Also ich habe heut mein Typo3 6.2 beta3 auf beta4 geändert, was dazu führte, dass ich endlich wieder die Extension "Template" in meiner Funktionsliste links (unter "web") nutzen kann. Hier habe ich nun nochmal nachgeschaut, ob der Pfad zu meiner Extension im TypoScropt so wirklich existiert (der Teil: 10 < tt_content.list.20.tx_myextension_pi1blubb). Und sieh da: es muss nicht heißen "tx_myextension_pi1blubb" sondern nur "myextension_pi1blubb" (ohne "tx_")!
Ich finde es ziemlich bescheiden, dass Typo3 nicht darauf hinweist, dass der angegebene "Pfad" im Typo3Script falsch ist... Wie auch immer - mein Ajax-Skript kann nun zumindest auf meinen Controller zugreifen.

ABER: Typo3 ignoriert dabei die übergebene Action, die aufgerufen werden soll. Es ist egal, ob ich die Action im Ajax-Aufruf mit großem oder kleinem Buchstabe beginnen lasse - Typo3 ruft meine editAction auf. Die editAction ist die erste Funktion in meinem Cotnroller und auch die erste, die ich in der ext_localconf.php für das Plugin angegeben habe. Die erste Funktion, die in der ext_localconf.php angegeben wird, wird ja standardmäßig genutzt, wenn keine Action übergeben wurde. Da ich aber eine Action übergeben habe, wundert es mich, dass Typo3 trotzdem die Standard-Action nutzt.

Kann es sein, dass ich für den Aufruf einer Controller-Action via Ajax ein eigenständiges Plugin erstellen muss, das nur Zugriff auf diese eine Controller-Action hat, die ich für den Ajax-Aufruf benötige? Oder kann man doch irgendwie auf eine erlaubte Funktion des bestehenden Plugins zugreifen und ich mache nur irgendwo einen Fehler? (Ich fände es unpraktisch, wenn man Funktionalitäten, die eigentlich zusammen gehören, auseinander reißen und in unterschiedliche Plugins packen muss)

Unbekannter Benutzer ·

Hat sich erledigt. Ich habe nun für jeden Ajax-Aufruf ein eigenes Plugin geschrieben. Ist vermutlich auch die sicherere Variante, um die Zugriffe besser zu kapseln.

OnkelEdi · · Beste Antwort

Hallo Susi,

ich habe gerade so ziemlich das gleiche Problem und auch alles mögliche Durchprobiert. Du hast geschrieben "Ich habe nun für jeden Ajax-Aufruf ein eigenes Plugin geschrieben".
Das versteh ich nicht so ganz. Kannst du das vielleicht näher beschreiben und wie das dann zusammen funktioniert. Sitze da schon eine Weile dran. Wäre nett wenn du mir da weiterhelfen könntest.

Gruß
Eduard

Unbekannter Benutzer ·

Was genau funktioniert bei dir nicht? Kommt der Ajax-Aufruf gar nicht im Controller an (wie bei mir im Startpost) oder kommt er dort hin und kann "nur" deine Funktion nicht aufrufen? Hast du den Pluginpfad im TypoScript überprüft? Auf wie viele Actions darf dein Plugin, welches du via Ajax aufrufen möchtest, zugreifen?

Hier nochmal die Logik bzgl. Plugin, Conroller, Action und Ajax-Aufruf an einem kurzen Beispiel erklärt (Code hab ich leider gerade keinen zur Hand):

Wir nehmen an du möchtest z.B. live mit Ajax bei der Eingabe eines Nicknames bei der Registrierung für ein Forum prüfen, ob der Nickname schon registriert ist. Wir nehmen weiter an, dass du einen AccountController hast, der z.B. die Actions "showAccount", "showRegistrationForm", "doRegistration" und "checkNickname" (etc.) besitzt.

Um das Registrier-Formular im Frontend anzuzeigen, würde man nun ein Plugin erstellen (z.B. pi1registration), welches auf die Actions "showRegistrationForm", "doRegistration" und "checkNickname" zugreifen darf (zumindest vom logischen Gedanken her). "showRegistrationForm" ist die Standard-Action, die aufgerufen werden soll, wenn keine Action angegeben wird - sie muss also als erstes bei den erlaubten Actions für das Plugin stehen.

Man würde nun denken, dass man im Ajax-Aufruf auf die Action "checkNickname" zugreifen kann. Ich weiß nicht, ob das mittlerweile geht, aber zum Zeitpunkt meines damaligen Posts hat der Aufruf der Action mit Ajax nicht funktioniert, da er statt dessen immer die Standard-Action "showRegistrationForm" vom Plugin aufgerufen hat.
Um das Problem zu lösen, musst du noch ein Plugin (z.B. pi1ajaxchecknickname) erstellen, welches ausschließlich auf die Action "checkNickname" zugreifen darf. Mit Ajax rufst du nun also das neue Plugin auf, und somit die Action "checkNichname". So hat es dann bei mir zumindest funktioniert.

OnkelEdi ·

Hallo,
danke für die Erklärung.
Also Anfangs hat zwar scheinbar der Request funktioniert (success wurde ausgeführt), aber ich bekam kein Ergebnis. Teilweise hatte ich dann irgendwann auch das Problem, dass ich zwar endlich was zurück bekam aber immer nur die standard-Action ausgeführt wurde. Also nicht das gewünschte Ergebnis. Ich habe alles Mögliche ausprobiert wie Schreibweise des Puginnamens, des Controllers, der Actions, verschiedene Arten der Request URL... Hat aber alles nichts geholfen.
Mittlerweile versuche ichs mit der eID... damit geht aber mal garnichts, wird immer nur Leerstring ausgegeben...
Auf jedenfall noch mal Danke. Ich schau mal ob mir das vielleicht weiterhilft.

Gruß
Eduard

Velletti ·

hallo ... ich sehe da oben im Code 2 Ansätze, was in meinen Augen nicht stimmig ist:

im Typoscript kann man den zu nutzenden Controller und die gewünschte Action vorgeben. siehe typoscript Beispiel unten (ist aber für Version 4.5, ggf. muss man da noch was anpassen)

Und ich habe bei den Aktionen, die nur einen json string zurück liefern, noch noch ein "die;" vor dem return in der Action, um zu verhindern, das der renderer anspringt ...

Fühlt sich schneller an ..

nemconnections_ajaxLogin = PAGE
nemconnections_ajaxLogin {

    // Page type ID 9013 - used for showing Login Form
    typeNum = 9013
    config{
		disableAllHeaderCode = 1
		additionalHeaders = Content-Type:text/xml;charset=utf-8
		metaCharset = utf-8
		xhtml_cleaning = 0
		debug = 0
		admPanel = 0
		
		sendCacheHeaders = 1
		cache_period = 1800
		#no_cache = 1
		#Header for Squid
  		additionalHeaders = Cache-Control: must-revalidate, max-age=1800, s-maxage=1800 | Vary: Accept-Encoding

	}
	  20 = USER
	  #20 = COA
	  20 {
		
		userFunc = tx_extbase_core_bootstrap->run
		pluginName = Pi6
		extensionName = NemConnections
		pluginKey = nem_connections
		controller = Login
		action = showVisualLoginCached
		
		switchableControllerActions {
			Login {
				1 = showVisualLoginCached
				2 = logout
				3 = showVisualLogin
				4 = showMiniprofileCached
				5 = showRequestPwd
				6 = showRequestPwdSubmit
				7 = showChangePwd 
			}
		}	
			
		settings < plugin.tx_nemconnections.settings
		persistence < plugin.tx_nemconnections.persistence
		view < plugin.tx_nemconnections.view

   }
}
nemconnections_ajaxMiniProfile < nemconnections_ajaxLogin
nemconnections_ajaxMiniProfile {

    // Page type ID 9013 - used for showing mini Profile
    typeNum = 9014
    20.action = showMiniprofileCached
}