Contao: {{post::}} insert tag is not working in 4.6

Created on 13 Sep 2018  ·  75Comments  ·  Source: contao/contao

Affected version(s)
contao 4.6.x

Description
The {{post::}} insert tag will not be replaced.

How to reproduce
Make a new form, with a form field named "test", then use {{post::test}} to print the content. (checked at demo.contao.org)
This should be the default behaviour.
contao/core-bundle#1230

Maybe related to
contao/core-bundle#1550

bug

Most helpful comment

@contao/developers we might want to increase the limit then. It shouldn't really harm, it just disables any reverse proxy cache for you for n seconds. I'd propose the following solution:

$waitingTime = max(30, (int) ini_get('max_execution_time')) * 2;

It will take the max_execution_time of the server (which might be configured to 60 seconds, otherwise that form could've never been submitted) if available (otherwise fallback to 30) and multiply this by two so we'll end up having 30 (or configured when higher) seconds for the form submission and 30 (or configured when higher) to load the redirect response. That should definitely do.

All 75 comments

@contao/developers Probably caused by our $_SESSION['FORM_DATA'] changes?

🤦‍♂️ most likely …

The insert tag should work on the redirect target page of the form (but not on any subsequent page). Can you confirm this? If not, please describe more detailed how to reproduce this.

I like the change that the insert-tag is only replaced on the redirect-target-page.
In https://github.com/contao/core-bundle/issues/1230#issuecomment-373421115 you stated its not doable because of multipage forms.
Can one of the pilots tell if contao-mp_forms is still working then?

Can one of the pilots tell if contao-mp_forms is still working then?

It is, mp_forms manages its own session.

Steps to reproduce:

  1. Create a new form (redirect page in my case was Home)
  2. Create a form field (name test)
  3. Add the form to a page (Home in my case)
  4. Add a new content element with type Text and content Form: {{post:test}}
  5. Write something in the form field
  6. The content element should output Form: <input>, but in my case only outputs Form:

I tested this on https://demo.contao.org/

Can confirm that e.g. {{post::name}} is also not working on the redirect-target-page.

We have the same problem!

The problem is that we no longer access $_SESSION['FORM_DATA'] if there is no session. I have no idea how to fix this though. @contao/developers /cc

How can there something be stored in $_SESSION['FORM_DATA'] if there is no session?

Maybe we are using the wrong check currently?
IMO we should check if there is a session for the current request (i.e. a session cookie is present and matches a session stored on the server).

The problem is that we no longer access $_SESSION['FORM_DATA'] if there is no session.

We're not checking if there is a session, but whether the user has a previous session. Which basically means if a session cookie is present.
https://github.com/contao/contao/blob/master/core-bundle/src/Resources/contao/library/Contao/Input.php#L781

We could store the post data as usual in the session and add a response listener which clears the data from the session. This way {{post::}} should be available on the jumpTo page.

As discussed in Mumble on November 22nd, this is a bug that needs to be fixed. @ausi and @Toflar know how (or at least they know where to start looking).

I did know where to start looking but I did not find a way to fix it. There are actually multiple issues here. One is that the ClearFormDataListener clears the form data during replay-header preflight requests. This is something I could actually fix. However, that would not fix the issue either because {{post::*}} insert tags are converted to ESI requests to work around the page cache. Now if you think about having an external proxy such as Varnish or LiteSpeed it would mean that these are all separate requests. Depending on whether you had a cache entry before or not, the first {{post::*}} would work or not even the first one would because the main response would trigger unsetting the form data. Actually we would need to know which one of the {{post::*}} ESI requests is the last one on the same page and only then we can clear the data. And there's no way to determine that. I'm sorry, I don't see how this can be fixed.

We can use route attributes, so the fragments requests dont clears the session? Which would potentially result in the session not being cleared (if all main requests are cached), but that's still better than the current, isn't it?

No that's not possible. I've tried that but the master response is generated before the ESI responses. Otherwise, how would you know what ESI tags are present? :) So at that point, it's already too late.

How about rendering the {{post::}} tag not as ESI but inline and disable the cache if {{post::}} ist used?

With https://github.com/contao/contao/issues/204#issuecomment-442033835 the {{post::}} tag should get obsolete and we could deprecate it IMO.

I don't think the {{post::}} insert tag will get obsolete with those changes. You might still want to show data from the form you just submitted in the contextual text field.

I have another idea which is not ideal but should work: We might add a $SESSION['FORM_DATA']['TIME'] = time(); to the data and delete it only after e.g. 30 seconds. That should be way enough for confirmation pages and it will disable caching only for a very short amount of time. During that time also existing cache entries are being invalidated (as long as we have header-replay) so we have to make sure it's as short as possible. 30 seconds sounds okay to me but we might even lower it to 10 seconds because we're only talking about the time needed from submitting the form to the confirmation page. Also, for maximum compatibility for those that do funny stuff like foreach((array) $SESSION['FORM_DATA']... we might just store it as $SESSION['FORM_DATA_LAST_SUBMITTED_AT'] or something similar.

Hm, 10 seconds might not be enough if an SMTP server is involved (though I don't know which times count). At least I had some cases where the SMTP server took very long to actually process the outgoing email and respond.

It's 10 seconds from the response to the next. So really it's just the redirect. Your SMTP server could take 5 minutes (if your webserver allows it), it would not affect these 10 seconds.

Yeah, then it's fine :)

Ok, then give it a shot @Toflar. 🙈

251 has been merged. @benfolds Can you please check if the changes fix your problem?

Yes, the {{post::}} will now be replaced on the next page - working - with v4.6.13.
The behaviour now is a bit wierd that it will be replaced over some time. Seems more than a workaround than a real fix for me, but it's better than not replacing the tags 👍

Ich habe ebenfalls ein Problem mit der Weiterleitung von Formulareingaben, unter 4.7.1. Dies
dauert solange - >10sec.- das Inserttags nicht mehr genutzt werden
können. Ich habe zu dem Zweck schon eine Portzuweisung vorgenommen, bin
mir aber gar nicht sicher ob diese überhaupt greift.
Bei 5-6 Formularfeldern funktioniert die gesamt Routine, sobald es mehr
Felder werden, dauert der Vorgang zu lange. Auch wenn ich "schwierigere"
Felder wie emailAdresseAbfrage nutze taucht das Problem auch bei weniger
Formularfeldern auf.

Für Hilfe wäre ich dankbar, denn diese Abfragen/ Anmeldungen sind
elementarer Teile meiner Website

Hier mein nicht funktionierendes Formular. Auf der Weiterleitungsseite
werden die Inserttags nicht ausgegeben
http://test.droplimits.de/anmeldung-fuer-die-gesamte-bend-rennserie-2019.html

Hier die funktionierende Version, die die "Conto-Academy" angelegt hat, mit
deutlich weniger Formularfeldern
http://test.droplimits.de/academy.html

Ich habe das Problem auch schon im ContaoForum besprochen.
https://community.contao.org/de/showthread.php?74243-NotificationCenter-inserttags&p=498215#post498215

Hetzner will sich den Port nochmal anschauen.

Seems more than a workaround than a real fix for me, but it's better than not replacing the tags 👍

It's not a workaround at all. The session needs to be cleaned after some time. Right now, it remains in in there forever.

Dies
dauert solange - >10sec.- das Inserttags nicht mehr genutzt werden
können.

Was das mit einen Port zu tun hat, habe ich jetzt noch nicht ganz verstanden aber was du sagst ist, dass es bei dir länger als 10 Sekunden dauert von dem Moment indem du das Formular abschickst bis du auf der Weiterleitungsseite landest?!

Er spricht vom "Port" seiner SMTP-Daten. Das hat meiner Meinung damit aber nichts zu tun.
Das Problem ist, dass es zu lange dauert, bis die Weiterleitungsseite geöffnet wird.

Würde es denn helfen wenn es 30 Sekunden wären?

In dem Fall schon. Ich glaube es dauert ca. 14 oder 15 Sekunden nach meinem letzten Test.

Könnte man den Wert nicht per Default auf 30 Sek einstellen und dann über die config.yml diesen evtl. sogar manuell überschreiben lassen? Oder wäre das ein Sicherheitsrisiko?

Hallo!
Wenn ich das komplette Formular mit allen Abfragen nutzen möchte, sowie ich es früher im EFG hatte incl. Speicherung der Daten mit leads kann die Übersendung der Abfrage sogar fast 59sec. dauern.

Die Speicherung der Daten (die ich aber zwingend brauche) habe ich selber als erstes als "Problem" erkannt. Schalte ich diese ab wird die Wahrscheinlichkeit höher dass der Prozess schnell genug wird um die InsertTags auszugeben.

Im Moment neige ich als Notlösung dazu die Weiterleitungsseite und die Inserttags aufzugeben. Dann hätte ich die Funktionalität ... allerdings mit so langer Verarbeitungszeit, das die User denken könnten ihre Rechner wäre eingefroren ... auch nicht wirklich schön.

Selbst ein Formular mit hundert Feldern wird nicht so lange dauern. Das ist keine Komplexität. Du hast vermutlich ein ganz anderes Problem.

(Und vermutlich wird eh kein Besucher 1 min warten, bis die Weiterleitungsseite angezeigt wird. Da sind 10s schon deutlich zu viel.)

Selbst ein Formular mit hundert Feldern wird nicht so lange dauern. Das ist keine Komplexität. Du hast vermutlich ein ganz anderes Problem.

(Und vermutlich wird eh kein Besucher 1 min warten, bis die Weiterleitungsseite angezeigt wird. Da sind 10s schon deutlich zu viel.)

Da sehe ich auch so, bin aber bei der Lösung komplett überfordert

Es wurde gerade folgende Frage an mich gerichtet mit der ich ebenfalls schon überfordert bin

"Läuft die Verifizierung der Eingaben denn clientseitig - sprich über JavaScript etc. oder serverseitig über PHP ab"

Selbst ein Formular mit hundert Feldern wird nicht so lange dauern.

Mit 3-4 Feldern klappt es aber
siehe hier
http://test.droplimits.de/academy.html

@contao/developers we might want to increase the limit then. It shouldn't really harm, it just disables any reverse proxy cache for you for n seconds. I'd propose the following solution:

$waitingTime = max(30, (int) ini_get('max_execution_time')) * 2;

It will take the max_execution_time of the server (which might be configured to 60 seconds, otherwise that form could've never been submitted) if available (otherwise fallback to 30) and multiply this by two so we'll end up having 30 (or configured when higher) seconds for the form submission and 30 (or configured when higher) to load the redirect response. That should definitely do.

I like the solution, but be aware that ini_get can be disabled…

Ich finde die Lösung von @Toflar eine gute Idee und das wird für die meisten sicher ausreichen.

Es wurde gerade folgende Frage an mich gerichtet mit der ich ebenfalls schon überfordert bin

"Läuft die Verifizierung der Eingaben denn clientseitig - sprich über JavaScript etc. oder serverseitig über PHP ab"

Wenn du bei dem Thema überfordert bist, dann solltest du einen Experten kontaktieren. Jeder hat irgendwo seine Grenzen.
Wenn es ein Contao-Problem ist, dann finden die Core-Entwickler sicher eine Lösung :-)

Pull request for 4.7 can be found here: https://github.com/contao/contao/pull/394
4.6 won't get any fixes as it is not maintained anymore.

Hetzner hat sich das Problem mal auf dem Server angesehen und mir diese Info geschickt:
„Wir haben nun Ihr Skript getestet und zeitgleich auf die Datenbank geschaut, um zu prüfen, welche Verbindungen offen sind. Scheinbar mach Ihr System auch während der Ladezeit eine Verbindung auf, diese befindet sich aber zumeist im Sleep-Modus, es wird also zum Großteil der Zeit keine Anfrage an den SQL-Server geschickt, die Verbindung zum Server jedoch offen gehalten. Das spricht dafür, dass Sie die MySQL-Verbindung beim Start der Routine direkt öffnen, Ihr Skript dann aber sehr lange braucht, um Daten zu senden. Um sicher zu gehen, haben wir noch die genannte Datenbank mittels "mysqlcheck" geprüft - hier war alles in Ordnung. Wir vermuten daher das Problem innerhalb der Programmierung des Formular-Plugins für Contao. Bitte wenden Sie sich hier an den Entwickler des Plugins, da nur dieser genau weiß, was im Hintergrund bei der Verwendung des Plugins passiert.“

Der Core braucht sicher nicht so lange. Das hätten wir längst entdeckt. Also muss es ein Plugin sein. Hast du mal alle Erweiterungen deaktiviert?

Da ich nur Erweiterungen geladen hab die ich brauche, hab ich das noch nicht getestet ... wird nachgeholt, aber frühestens in der Nacht von DO-FR

Gibt es keine elegantere Lösung eine Erweiterung zu deaktivieren, als sie zu löschen?

Nein. Aber du musst ja die dazugehörigen Datenbank-Daten nicht löschen. Einfach nur die Erweiterungen entfernen und dann wieder hinzufügen.

Okay ... bin dabei ... geschmeidig würde ich diesen Workflow aber nicht nennen. Das ging in Contao 3 irgendwie fluffiger.
Nach dem Entfernen von 3 Erweiterungen dachte ich "Leads" wäre es. Weil nach dem Entfernen die Inserttags angezeigt wurden. Nächster Versuch war dann leider wieder negativ.
Werde diese doch recht zeitintensive Suche aufs Wochenende verschieben müssen.
Bei mir dauert 1 Durchlauf mit Entfernen einer Erweiterung aktualisieren der Datenbank, löschen des Cache, Ausprobieren ob die Inserttags angezeigt werden ca. 10min. :-(

Ich habe jetzt endlich die nötige Zeit gefunden und folgende Erweiterungen in meiner Umgebung als Fehlerquelle eingekreist

Ich komme immer noch über 10sec bei der Übertragung, bleibe aber unter den anscheinend kritischen 11sec, nach denen die Insertags nicht mehr übertragen werden

RockSolid Columns
RockSolid AntiSpam
RockSolid Theme Assistant

verzögern in meiner Konstellation zu stark

mehrfach gelöscht und wieder aufgespielt

RockSolid AntiSpam

Diese Erweiterung solltest du seit Contao 4.4 gar nicht mehr benötigen. Da die Erweiterung bereits in Contao 4 enthalten ist.

Nachdem ich jetzt nochmal alle Rocksolid Anwendung eine nach der anderen gelöscht habe und keine nennenswerte Veränderung der Zeit, bis die Weiterleitungsseite angezeigt wird, feststellen konnte, immer knapp über 10 sec, blieb nur noch das Notification Center als "Fremdlösung" übrig.
Notification Center gelöscht, Übertragung bei knapp über 3 sec. ... nur ohne NotificationCenter ist meine Website nur die Hälfte wert :-(
Alle Rocksolid Erweiterung die ich brauche wieder installiert ... Weiterleitungsseite erscheint nach 3 sec.

Lade ich das NotificationCenter neu bin ich wieder bei knapp über 10sec bis die Weiterleitungsseite erscheint

Was hast du denn eingestellt? Als Gateway? Einen eigenen SMTP-Server?

Standard E-Mail-Gateway
"SMTP- Einstellungen überschreiben" NICHT ausgewählt

Ich glaube dein Server hängt einfach ewig beim Mailversand.

Danke für Deine schnelle Reaktion!
Hetzner hat das ja schon überprüft. Was schlägst du vor. Was kann ich tun?

Wir haben nun Ihr Skript getestet und zeitgleich auf die Datenbank geschaut, um zu prüfen, welche Verbindungen offen sind. Scheinbar mach Ihr System auch während der Ladezeit eine Verbindung auf, diese befindet sich aber zumeist im Sleep-Modus, es wird also zum Großteil der Zeit keine Anfrage an den SQL-Server geschickt, die Verbindung zum Server jedoch offen gehalten. Das spricht dafür, dass Sie die MySQL-Verbindung beim Start der Routine direkt öffnen, Ihr Skript dann aber sehr lange braucht, um Daten zu senden. Um sicher zu gehen, haben wir noch die genannte Datenbank mittels "mysqlcheck" geprüft - hier war alles in Ordnung. Wir vermuten daher das Problem innerhalb der Programmierung des Formular-Plugins für Contao. Bitte wenden Sie sich hier an den Entwickler des Plugins, da nur dieser genau weiß, was im Hintergrund bei der Verwendung des Plugins passiert.

Dauert das Abschicken des Formulares auch ohne Notification Center lange, wenn du die Email über die reguläre Contao Funktionalität verschicken lässt?

wenn ich z.B. einen Newsletter verschicke dauert es in der Tat auch fast 10sec bis der raus ist

Wie ich das Formular ohne NFC sende ist mir nicht klar

Naja - teste es zuerst mal mit dem Formular ;)

Ich verstehe nicht wirklich was ich machen soll?
Ich sende das Formular mit "Anmelde" Button ab.
Habe ich das NFC installiert dauert es knapp über 10sec.
Ist das NFC gelöscht dauert es knapp über 3sec.
Sehe ich gerade den Wald vor Bäumen nicht ... ?
Bin, an dieser Stelle leider, Fahrradprofi nicht Websiteprofi ...

Kann ich das NFC auch irgendwo "abschalten", ohne zu löschen?

Ich verstehe nicht wirklich was ich machen soll?

Die Contao-eigene Funktionalität zum Versenden der Formulardaten via Email benutzen, ohne Notification Center. Einfach nur zum zu bestätigen, dass es am SMTP liegt.

Die Idee habe ich schon verstanden, nur wie halte ich das NFC dabei raus.
Bzw. tue ich das nicht durch absenden des Formulars.
Ich verstehe es nicht ...tut mir leid
Ich habe hier noch ein einfaches Formular
http://test.droplimits.de/academy.html
Das hat die ContaoAcademy angelegt.
Nutze ich das, dauert der Aufruf der Weiterleitungsseite 2,7sec

Die Idee habe ich schon verstanden, nur wie halte ich das NFC dabei raus.

Einfach deinstallieren.

Ich habe hier noch ein einfaches Formular
http://test.droplimits.de/academy.html
Das hat die ContaoAcademy angelegt.
Nutze ich das, dauert der Aufruf der Weiterleitungsseite 2,7sec

Und damit wird auch eine Email über den SMTP versendet?

Okay NFC gelöscht.

Aufruf der Weiterleitungsseite dauert jetzt mehr als 16sec, teilweise 20sec .. also noch länger :-(
email kommt an
und erstaunlicher Weise werden die Inserttags weitergegeben ... aber da ist ja vielleicht die weiter oben erwähnte Anpassung schon am Werk?

Beim ContaoAcademy Formular verlängert sich die Zeit auf 24 sec
wenn ich den Formularversand per eMail einstelle

die parameters.yml sieht so aus

parameters:
database_host: sql635.your-server.de
database_port: 3306
database_user: JB_Contao
database_password: xxx
database_name: JB_Contao
secret: xxx
mailer_host: mail.your-server.de
mailer_user: [email protected]
mailer_password: xxx
mailer_port: 587
mailer_encryption: tls

fehlt da nicht noch sowas wie
mailer_transport: smtp

Ergänze den Eintrag um
mailer_transport: smtp

Was passiert dann?

Ich habe das mal unten drunter geschrieben und keinen Unterschied festgestellt.
Mit "mail" habe ich es auch schon probiert.
Ich vermute, dass ich wieder irgendeine Form/ richtige Platzierung nicht beachtet habe in der das eingetragen werden muss

Ich habe das mal unten drunter geschrieben und keinen Unterschied festgestellt.

Hast du danach auch den Symfony Application Cache neu aufbauen lassen? Ohne dieser Angabe hattest du eigentlich bisher nie einen SMTP Server benutzt.

Beim Deinstallieren habe ich den Cache aufgebaut. Hier bin ich mir jetzt nicht sicher. Vielleicht komme ich heute Nacht nochmal dazu es zu probieren. Dazu aber nochmal die Frage:
Muss ich in der Form/ Schreibweise und/ der Position etwas zwingend beachten?

Kleiner Fehler, große Wirkung!
Jetzt erfolgt die Weiterleitung unter 3 sec und die inserttags werden weitergegeben.

Danke an die Helfer und Tippgeber!

bei mir bleibt aber eine Frage:
Ich hatte das Problem hier schon einmal besprochen und die Änderung durchgeführt
https://community.contao.org/de/showthread.php?74243-NotificationCenter-inserttags&p=498065&viewfull=1#post498065

Wie und warum wurde die Einstellung wieder revidiert? Wo oder wann hätte ich besser aufpassen müssen.
Was mich besonders verwirrt: die SMTP Einstellung war komplett weg, aber der manuell von mir eingetragene Port war noch vorhanden?
Ich habe die "parameters.yml" nach der 1. Änderung nämlich nicht wieder angefasst.
Ich würde es gern verstehen ... damit mir das nicht noch einmal passiert.

Die parameters.yml wird wenn dann nur vom Contao Install Tool verändert - beim Eintragen der Datenbank Zugangsdaten. Alle anderen Änderungen müssen von dir (oder jemand Anderen) kommen.

Versuche es nochmal mit mailer_transport: sendmail, nur um zu bestätigen, dass der Email Versand über sendmail so lange dauert - und nicht wie von Hetzner vermutet durch Datenbankabfragen.

Danke dass du mir auch noch den Tipp gegeben hast wie man das Ergebnis verifizieren kann!

Ist positiv verlaufen.
Mit "SMTP" gewünscht Geschwindigkeit, mit "sendmail" wieder elend langsam - allerdings wurden die Insertags trotzdem weitergegeben, was zu Anfang ja auch nicht klappte.
Zurück auf "smtp" ist die Geschwindigkeit wieder in Ordnung!

Vielen, vielen Dank!
Das gleiche Problem hat mir auch bei einer anderen Website zu schaffen gemacht.

Seems more than a workaround than a real fix for me, but it's better than not replacing the tags 👍

It's not a workaround at all. The session needs to be cleaned after some time. Right now, it remains in in there forever.

I'm pretty sure @benfolds was not referencing clearing the session to be a workaround. He's referencing that a timed clear is not a very precise solution.

When I use a session variable to display a text after a form was submitted then that text will be displayed for every request that's made within the 10 (or however many it's configured to now) seconds. I submit a form, see the message. Go to another page for a second, then come back and I still see "Thanks for submitting the form" or the like.

In other cases the request might legitimately take 10+ seconds because someone runs a lot of logic in a protected area that's not exposed to end users, just to users with certain groups. They are fine with a request taking longer, but the developer might want to display session data that is purged in the meantime because another part of the logic took too long.

Maybe a bit of a contrived example, but my point is that clearing the session basically asynchronously is not an ideal solution for many use cases, and hard to understand and debug too from the developer's perspective who doesn't know that this time limit exists.

That's true. However, there's no way to keep that backwards compatible other than the timed solution. Before, the values were kept in the session forever (for as long as the session was valid). Tehre's no way we can determine when to clear it. A better solution would be some special content element that outputs the form details again and then clears the session. But again, that would not have been backwards compatible.

That reminds me of my suggestion here.

The issue was noticed by using the {{post::}} insert tag, so I thought it could make sense to add a modifier to that insert tag that just clears the session (or its one specific value) when set. That would remain backwards compatible as long as people haven't defined such a modifier for this insert tag themselves. It's not perfect in that you'd still have to know to use this modifier, but at least it gives you the option to.

I just don't know if this is something that should remain in userland or if it should be included in Contao.

Nobody would use that new flag and the cache would always be disabled. That's not really an option.

Was this page helpful?
0 / 5 - 0 ratings