Lagerbestand ESI Action-Tag

Hallo, 

ich würde gerne den Lagerbestand {$sArticle.instock} in einer Badge im Shop anzeigen. Leider wird der Lagerbestand im Theme gecached, sodass mir der Hinweis gegeben wurde, über die ESI-Tags den Cache für diesen Bereich auszuschalten.

Wie kann ich also in einem Theme oder Plugin den Lagerbestand mit Hilfe der ESI-Tags aus dem Cache holen? Die Werte werden ja von Shopware bereitgestellt. Jemand eine Idee? 

 

Hallo,

im Prinzip musst du dir nur ein eigenes Plugin erstellen, dort einen Widget-Controller implementieren und das Widget dann automatisch im Frontend ausliefern, damit du dann beispielsweise über {action module=widgets controller=GetInStock action=show articleId=$sArticle.articleID} die entsprechende Ausgabe erzeugst (du fütterst sozusagen das Widget mit der Artikel-ID und lässt dir dann den instock - Wert zurückgeben).

Andernfalls gibt es auch Plugins dafür, die hoffentlich den Cache auch berücksichtigen:

http://store.shopware.com/zenit53271346922/lagerampel/lagerbestand-advanced.html

Beste Grüße

Sebastian

1 „Gefällt mir“

Hallo @sschreier‍,

vielen Dank für deine Hilfe! 

Ich fasse mal zusammen, wie weit ich das verstanden oder auch nicht verstanden habe. Ich würde mich freuen, wenn Du mich dann nochmal in die richtige Richtung schubsen könntest. Ich versuche hierbei auch zu lernen und möchte daher kein externes Plugin verwenden. 

  1. Ich muss ein eigenes Plugin erstellen. Check. Und dort in der bootstrap.php (altes Plugin-System) einen Controller implementieren, quasi eine solche Action? Oder vermische hier etwas? Du schreibst, ich soll einen Widget-Controller erstellen. Woanders habe ich gelesen, dass es mit einem Action-Controller funktioniert. 

    public function getLiveStockAction()
    {
    $articleId = $this->Request()->getParam(‘artid’);

         $liveStock = $this->getLiveStock($articleId);
    
         echo (int)$liveStock;
    
         $this->Front()->Plugins()->ViewRenderer()->setNoRender(true);
     }
    

Den Code habe ich von https://forum.shopware.com/discussion/31656/action-plugin-esi-tag-include-externe-live-bestandsabfrage 

Ganz verstehe ich diesen Code nicht. Verstehe ich das richtig, dass ich nicht mehr mit $sArticle.instock arbeite, sondern mir den aktuellen Wert selbst aus der Datenbank holen muss, weil ich die “offizielle” Variable nicht vom Cache befreien kann?

 

  1. Dann könnte ich innerhalb meines Plugins eine Datei in widgets/getinstock/instock.tpl erzeugen. Ist das notwendig? Also ruft die {action} eine tpl-Datei auf, welche nicht gecached wird und sich dort die Variable für den Bestand geholt wird oder greift diese eigentlich direkt auf die action zu und der Wert könnte in einer Variable gespeichert werden - also ohne, dass es wirklich diese tpl-Datei gibt?:

         {$liveStock}
    

 

  1. Nun binde ich in die frontend/listing/product-box/product-badges.tpl diesen ESI-Action-Tag ein.

    {extends file="parent:frontend/listing/product-box/product-badges.tpl}

    {* add custom badge to ESD product badge *}
    {block name=‘frontend_listing_box_article_esd’}
    {$smarty.block.parent}

     {action module=widgets controller=articlestock action=getLiveStock articleId=$sArticle.articleID}
    

    {/block}

 

Vielen Dank für deine Hilfe!

Du solltest evtl. noch mal dein Konzept überdenken. Mit deiner Lösung feuerst du in jedem Listing für jeden Artikel einen weiteren request ab. Ich will nicht wissen, wie lahm der Shop hinterher sein wird…

Viele Grüße

1 „Gefällt mir“

[@Aquatuning GmbH](http://forum.shopware.com/profile/11752/Aquatuning GmbH “Aquatuning GmbH”)‍

hmmm… hast du eine Idee für eine bessere Umsetzung?

Also ESI Tags (action) sind dafür definitiv ungeeignet. Möglichkeiten wäre:

  • (sehr einfach) Brauchst du den HTTP-Cache wirklich? Ggf. deaktivieren, dann kannst du die Daten auch direkt im Listing ausgeben. Die Seite sollte trotzdem schnell sein außer du hast sehr viel Besucheraufkommen gleichzeitig.
  • (mittel) Auf den Client auslagern. Z.B. ein data-Attribute mit Artikelnummer ausgeben und die Daten gesammelt für alle angzeigten Artikel via Ajax laden und am besten beim Client über den sessionStorage cachen. 
  • (schwieriger) ein eigenes Cache-Tag für den Lagerbestand. => Cache invalidieren, falls sich der Bestand ändert

Viele Grüße

1 „Gefällt mir“

Hallo,

nein mit einem Controller meine ich auch einen Controller (keine Action, sondern ähnlich wie hier: https://forum.shopware.com/discussion/comment/182029/#Comment_182029 ), nicht das subscriben auf ein Event oder die Erweiterung der View. Bei der View-Variante würde ich auch sagen, dass das die Performance betreffen wird.

Ebenso würde ich auch kein Plugin mehr über die alte Pluginstruktur erstellen, da diese irgendwann eh nicht mehr funktionieren wird.

Ja genau, du verwendest nicht die gecachte Variable, sondern holst dir den Wert mit dem Controller selbst aus der Datenbank.

Und es ist ein normales action - Tag, kein ESI-Action-Tag.

Beste Grüße

Sebastian

1 „Gefällt mir“

Hm, okay. 

In meinem Plugin hole ich mir bereits über das Search Bundle und dem LegacyStructConverter eine andere Variable aus der Datenbank und füge sie zu sArticles hinzu. Die liegen allerdings auch im Cache. Ich kann über den LegacyStructConverter mir auch nochmal den Lagerbestand holen und erneut in sArticles.irgendwas speichern. 

Das Problem: das wird auch gecached. Kann ich das vll. aus dem Cache holen und so auf Vorhandenem aufbauen?

Hi @sschreier‍ 

Ich habe nun einen eigenen Controller erstellt:

public function getLiveStockAction()
	{
		$this->Front()->Plugins()->ViewRenderer()->setNoRender(true);

		$articleId = $this->Request()->getParam('articleId');

		echo $articleId;

	}

 Welchen ich in den Bagdes aufrufe: 

{extends file="parent:frontend/listing/product-box/product-badges.tpl"}

{block name='frontend_listing_box_article_hint'}

    {action module=widgets controller=Livestock action=getLiveStock articleId=$articleId}

{/block}

Zur Testweisen Funktionsprüfung habe ich auch mal eine Ausgabe mittels der widgets/livestock/get_live_stock.tpl-Datei erzeugt. Das hat auch funktioniert. Leider bekomme ich keine Ausgabe der Artikelnummer aus der getLiveStockAction().

 

  1. Der nächste Schritt wäre nun anhand der Artikelnummer den Lagerbestand zu ermitteln? Das würde ich in der getLiveStockAction() machen?!
  2. Wie komme ich hier an den Lagerbestand?
  3. Und wie performant wäre das? 
  4. Wie bereits oben angesprochen, nutze ich im Plugin das SearchBundle mit dem LegacyStructConverter. Kann man das hier irgendwie wieder anwenden?

 

Hallo,

wie ich es schon gesagt und Aquatuning gemeint hatte, ein Widget - Controller ist das nicht wirklich, was du da machst, sondern du manipulierst ja nur die View und feuerst einen weiteren Request bei jedem Artikelaufruf auf, das auf die Performance geht (ich hab ja oben einen Link zu einem Beispiel gepostet).

Und bist du dir überhaupt sicher, was: $this->Front()->Plugins()->ViewRenderer()->setNoRender(true); macht oder hast du das nur irgendwo her rein kopiert?

Ich glaub das kannst du nicht wirklich verbinden.

Beste Grüße

Sebastian

Hallo @sschreier‍,

ich habe einen Controller nach https://forum.shopware.com/discussion/comment/182029/#Comment_182029 und der Shopware Doku unter: Shopware controller erstellt. 

Dabei habe ich diesen Controller mit class Shopware_Controllers_Widgets_Livestock extends Enlight_Controller_Action in der Livestock.php erstellt und ein wenig damit herumgespielt. Habe mir in views/widgets/livestock/get_live_stock.tpl mal eine Ausgabe gemacht und über den Action-Tag eingefügt. Das hat funktioniert. 

Dann habe ich $this->Front()->Plugins()->ViewRenderer()->setNoRender(true); hinkopiert. Ich gehe davon aus, dass dies dafür zuständig ist, dass der controller nicht gerendert und aufgerufen wird?!

Ich dachte, das wäre der Weg, den ich laut deinem Link gehen sollte?

Hab ich es falsch verstanden?