Plugin - Anzeige nur für eingeloggte User - Problem mit Cache?

Hallo Community, 

ich hatte mir überlegt in einem Plugin die zusätzlichen tpl-Dateien und Bearbeitungen im  Frontend nur für eingeloggte Benutzer anzuzeigen. Das ganze kann über die Plugin-Config eingestellt werden.

 

Dazu kann ich in meiner Bootstrap.php abfragen, ob ein Benutzer eingeloggt ist: 

public function onFrontendPostDispatch(Enlight_Event_EventArgs $args)
{

    // Hole Variable aus der Config
    $showUsersOnly = $this->Config()->get('usersOnly');


    // Prüfe ob Option false ist oder ob Option true und User eingeloggt. Erst dann übergebe den View und mache, was sonst noch so in onFrontendPostDispatch passiert
    if($showUsersOnly == false || (Shopware()->Modules()->Admin()->sCheckUser() && $showUsersOnly == true)) {

        /** @var \Enlight_Controller_Action $controller */
		$controller = $args->get('subject');
		$view = $controller->View();
		$view->addTemplateDir(
			__DIR__. '/Views'
		);

    }
}

Problem:

  • Stelle ich die Option auf true in der Plugin-Config und leere den Cache wird das Plugin als ausgeloggter Benutzer korrekterweise nicht angezeigt.
  • Logge ich mich mit einem Benutzer ein, wird das Plugin nicht dargestellt, bis ich im Backend NOCHMALS den Cache geleert habe (während ein Nutzer im Frontend eingeloggt ist)
  • Danach kann ich mich aus- und wieder einloggen und die Dastellung ist jeweils korrekt.

 

Info:

  • Testshop lief dazu im Produktivmodus
  • In der Entwicklungsumgebung konnte ich dieses Verhalten so nicht feststellen (nicht im Produktivmodus)

 

Frage: 

  1. Woran liegt das?
  2. Wäre das mit einer anderen Variante nicht so? Man könnte ja auch mit $args->getSubject()->View()->assign(‚sUserloggedIn‘, Shopware()->Modules()->Admin()->sCheckUser()); dem View eine Variable assignen und dann in den einzelnen tpl-Dateien abfragen.

Ja, liegt am cache. In ein widget auslagern und via action-Tag den Bereich einbinden - oder eben betroffene Controler vom Cache ausklammern. Mal im Forum nach suchen, gibt es einiges zu, oder Doku lesen. Besonders ein Thread, wo es um den Namen oben im Account-Button ging.

1 „Gefällt mir“

Damit erklärt sich, warum beim Testen mit {if $sUserLoggedIn} in den Topsellern (= Widgets) die Anzeige korrekt und im allgemeinen Listing falsch war. 

 

Auslagern in Widgets ist schlecht, da das Plugin an vielen Stellen Blöcke des Bare-Themes überschreibt. Im Listing zum Beispiel.

Controller ausklammern sehe ich auch als schwierig… Ich kann doch nicht einfach den Controller für das Listing aus dem Cache ausschließen?

Deinen besagten Beitrag habe ich leider nicht gefunden  Frown

 

Ab einem gewissen Punkt macht der Cache keinen Sinn mehr. Jedes Widget-Tag {action …}, welches in einen Cache-Miss läuft, erzeugt einen eigenen Request. Das kann dazu führen, dass der Cache die Performance der Seite sogar eher verschlechtert. In diesem Fall solltest du dir überlegen

  • Brauche ich wirklich den HTTP Cache? Reicht der Produktivmodus (Templatecache) nicht aus? (HTTP-Cache ist in der Regel nur bei sehr viel Besuchern gleichzeitg erforderlich.
  • Die dynamischen Stellen beim Nutzer via Ajax zu laden und dann local zu “cachen”. (siehe local/session Storage im Browser)

Viele Grüße

1 „Gefällt mir“

Es wäre nur ein Feature gewesen, welches ich in das Plugin noch aufgenommen hätte. Dazu aber den Cache an ca. 5 -10  Stellen aufzubohren, sehe ich dazu nicht ein. Dachte es wäre mit ein paar Abfragen a la {if $sUserLoggedIn} oder global in der Bootstrap-php getan. Und die Entscheidung über den HTTP-Cache kann und werde ich nicht für den Kunden entscheiden. 

Kann man nicht einfach im TPL die Session abfragen? Oder wird dieser Zustand auch im Cache verankert?

{$smarty.session.Shopware.sUserId}

Gibt es keinen Rückgabewert ist man natürlich nicht eingeloggt.

1 „Gefällt mir“

Ohne zuviel zu versprechen: Der Cache bekommt eine ID - möglich, dass hier der Zustand „angemeldet / nicht angemeldet“ berücksichtigt wird.
Möglich wäre zumindest hier eine Weiche. Ist „angemeldet“ aber einmal im Cache, wird es nicht mehr neu erzeugt. Also geht 100% nichts mit individuellen User-daten / Aktionen.
Lies mal hier durch - da haben wird dann irgendwann aufgegeben  Sticking-out-tongue Und simkli ist schon fitt.
https://forum.shopware.com/discussion/41317/im-login-button-im-topmenue-soll-statt-mein-konto-nach-login-kundenname-oder-text-stehen

1 „Gefällt mir“

@IFF schrieb:

Kann man nicht einfach im TPL die Session abfragen? Oder wird dieser Zustand auch im Cache verankert?

Es geht hier um den HTTP-Cache. (nicht Produktivmodus). Dieser muss explizit eingeschaltet werden 

Dieser Cache macht vereinfacht folgendes: Der Cache wird komplett vor Shopware geschaltet. Er speichert die komplette HTML-Ausgabe* von Shopware und spielt diese aus**, anstatt Shopware erneut aufzurufen. Daher wird dabei Shopware überhaupt nicht angesprochen (keine Template Engine/Smarty, gar nichts). 

Wenn es dich genauer interessiert, wie der HTTP-Cache funktioniert, gibt es hier einen interessanten Artikel:
Understanding the Shopware HTTP Cache

* (vereinfacht) ESI Tags sind zu berücksichtigen
** (vereinfacht) NoCache-Tags sind zu berücksichtigen

Viele Grüße

1 „Gefällt mir“

@sonic schrieb:
Lies mal hier durch - da haben wird dann irgendwann aufgegeben   Und simkli ist schon fitt.

 Ich musste damals mein komplettes Plugin über den Haufen werfen, als ich erfuhr, dass Shopware sowas mitbringt 

 

P.S. Umbedingt mal in die 5.3 reinschauen. Da gibt es den SLC (Shopware Login Cookie). Damit wird sowas dann möglich sein. (Es wird dann für jeden Nutzer ein eigener Cache angelegt. Bisher hat sich mir aber noch nicht erschlossen, ob das in High-Peformance Szenarien überhaupt sinnvol ist?  Vielleicht sagt SW ja noch etwas dazu)

1 „Gefällt mir“

@sonic schrieb:

Ohne zuviel zu versprechen: Der Cache bekommt eine ID - möglich, dass hier der Zustand „angemeldet / nicht angemeldet“ berücksichtigt wird.
Möglich wäre zumindest hier eine Weiche. Ist „angemeldet“ aber einmal im Cache, wird es nicht mehr neu erzeugt. Also geht 100% nichts mit individuellen User-daten / Aktionen.

Hieße das nun, dass man in den tpl-Dateien doch mit {$smarty.session.Shopware.sUserId} abfragen könnte ob jemand eingeloggt ist? Prinzipiell ist mir egal WER da eingeloggt ist. Ich will nur wissen ob der, der gerade auf der Seite ist, eingeloggt ist und dann das Plugin anzeigen oder eben nicht.  

Versuch es mal mit

{if $sUserLoggedIn}

Ich lege meine Hand aber nicht dafür ins Feuer, ob der Cache das auch wirklich zuverlässig trennt.

1 „Gefällt mir“

Achso, ne, das habe ich weiter oben schon geschrieben, dass das nicht funktioniert.

Bei den Widgets / Topsellern hat es dann funktioniert aber im Listing nicht. Je nachdem in welchem Conrtoller man das anwendet… 

 

Dachte {$smarty.session.Shopware.sUserId} wäre etwas anderes als {if $sUserLoggedIn}. Zumal $sUserLoggedIn je nach Controller leer oder voll ist und teilweise auch $userLoggedIn heißt… 

Kannst ja mit  

{debug}

im template und ohne Popupblocker die aktuellen Vars ausgeben lassen.

1 „Gefällt mir“

mache ich mit firephp und dem debug plugin. Daher weiß ich, dass an verschiedenen stellen $sUserLoggedIn auch $userLoggedIn heißt und mal befüllt ist und mal nicht.

Ich kann nur nochmal auf meinen Beitrag von weiter oben verweisen:
vor etwa einer Stunde

Dort ist auch ein Link zu einem Beitrag, der den HTTP-Cache erklärt. Dann versteht man, warum das nicht klappt (klappen kann)  Wink

Viele Grüße

1 „Gefällt mir“

Hab es mal selber eben noch mal getestet. Wenn ich bei den Einstellungen HTTP-Cache frontend/listing lösche, dann gehts auch beim Listing - auch mit $sUserLoggedIn. Sonst, wie bereits erwähnt, natürlich nicht.