Anzeige-Preise per Plugin in allen Listen austauschen

Hallo in die Runde,

gerade bin ich dabei einen Shop aufzusetzen, in dem die Preise in den Listenansichten anders sein sollen als in der Detailansicht, Warenkorb usw.

Dazu habe ich ein simpel aufgebautes Plugin geschrieben, in dem das Listing-Event abgefangen wird und die entsprechende Funktion die $sArticles ausliest, ergänzt und neu an die View wieder übergibt. Im Template prüft eine If-Schleife das Vorhandensein der neuen Variable und zeigt in diesem Fall den Wert der neuen Variable statt des normalen ‚price‘ an.

So weit so gut, aber da sich so nur bei Kategorie-Listenansichten der Preis verändert, muss ich bei allen anderen Listen - Suche, AjaxSuche, Topseller - noch das Gleiche machen. Und die bereiten mir gerade Kopfschmerzen, weil sie nicht so wollen, wie ich es gerne hätte …

Deshalb meine Frage: Gibt es nicht vielleicht noch einen eleganteren Weg, wie ich die $sArticles in allen Arten von Listendarstellungen auf einmal verändern kann?

namespace MyPlugin;

class MyPlugin extends \Shopware\Components\Plugin
{
    public static function getSubscribedEvents()
    {
        return [
            'Enlight_Controller_Action_PostDispatch_Frontend_Listing' => 'onPostDispatchListing'
        ];
    }

    public function onPostDispatchListing(\Enlight_Event_EventArgs $args)
    {
        /**@var $controller Shopware_Controllers_Frontend_Listing */
        $controller = $args->getSubject();

        $view = $controller->View();
        $sArticles = $view->getAssign('sArticles');

        /*  
        Ergänze die neuen Preise ...
        */

        $view->assign('sArticles', $sArticles);
    }
}

 

 

Hi,

dieses Plugin macht das über die entsprechenden Komponenten: GitHub - shopwareLabs/SwagUserPrice

Einziger Nachteil: Das greift auch für die Detailseite, da die Listing-Objekte und die Detail-Objekte voneinander ableiten. Du kannst aber analog dazu auch eigene Logik für die Detail-Objekte (ProductStrucs) ausführen und da dann die Preise ebenfalls anpassen. 

Ist etwas komplexer - aber das Plugin zeigt ganz gut, wie man da prinzipiell vorgehen kann.

Schönen Gruß,

Daniel

Hi Daniel,

vielen Dank für den Tipp. Aber leider hilft mir das wenig weiter, denn ich fange gerade erst an, mich mit Shopware zu beschäftigen und das Beispiel ist für mich derzeit noch viel zu komplex,

Daher werde ich mich wohl doch besser erst mal weiter mit dem “uneleganten” Weg beschäftigen und zusätzlich die anderen Events abfangen. Nur habe ich da leider das Problem, die $sArticles nicht auslesen zu können.

    public static function getSubscribedEvents()
    {
        return [
            'Enlight_Controller_Action_Frontend_Search_defaultSearch' => 'onPostDispatchSearch'
            ];
    }

   
    public function onPostDispatchSearch(\Enlight_Event_EventArgs $args)
    {
        /**@var $controller Shopware_Controllers_Frontend */
        $controller = $args->getSubject();

        $view = $controller ->View();
        $sArticles = $view->getAssign('sArticles');
        $view->assign('sArticles', $sArticles);
    }

Auch $sSearchResults bekomme ich auf diese Weise nicht ausgelesen.

Hast Du geprüft ob das Event überhaupt gefeuert wird? Alternativ probiere doch mal Dich auf “Enlight_Controller_Action_PostDispatchSecure_Frontend_Search” zu registrieren (damit hast Du dann alle Aufrufe des SearchControllers). Um dann im Zweifel nur bei der “defaultAction” zu reagieren kannst Du im EventHandler die Bedingung

/** @var $controller \Enlight_Controller_Action */
$controller = $args->getSubject();
if ($controller->Request()->getActionName() === 'defaultSearch') {
    $searchResults = $view->getAssign('sSearchResults');
    # @Todo: Do something with $searchResults
}

einbauen.

Hallo,

 

da führt wohl kein Weg an der Komplexität vorbei.

Also: Shopware bedient ja zwei Datenbanken: MySQL und Elasticsearch. Da das völlig unterschiedliche Datenbanken sind, musste eine Abstraktionsschicht her. Diese „Schicht“ findest Du unter SearchBundle, mit den jeweiligen Gateways (auch bekannt unter Repositories) für die Datenbanken. Wenn ich das richtig in Erinnerung habe, dann liegen die Gateway Implementationen im StorefrontBundle.

Auf jeden Fall musst Du Dich auf die Condition Collect Events (oder so ähnlich) registrieren, und dann deine eigene Implementation von ConditionHandlerInterface schreiben. Das ist zwar eigentlich nur dafür gedacht, eigene Where Bedingungen anzuhängen, aber da das Doctrine ist kannst Du hier auch den Select Teil beeinflussen.

Also meine Erklärung läuft im Prinzip ebenfalls auf das GitHub Projekt hinaus. Müsstest in Deinem Fall das ganze nur in ein Plugin packen, denn die erweitern direkt die Core Dateien, wovon ich Dir stark abraten würde.

 

 

MFG

 

derwunner

Danke @hsoebbing, ja. Ich habe einen var_dump($sArticles) eingebaut, der zwar anspringt, aber nur NULL ausgibt. Auch, wenn ich mich auf Enlight_Controller_Action_PostDispatchSecure_Frontend_Search registriere … leider!

@derwunner, Dir ebenfalls Danke. Auch wenn mich die Antwort wenig begeistert. Wenn das so ist, werde ich wohl erst einmal eine andere Lösung finden müssen, bevor ich irgendwann später, wenn ich mich mal tiefer eingearbeitet habe, eine bessere Vorgehensweise finde.

 

Okay, vielleicht bin ich ja etwas naiv, aber so als “einfaches Gemüt” denke ich mir, wenn Smarty-Debug das gefüllte Array anzeigt, dann muss sich dieses doch auch irgendwie auf halbwegs einfache Weise abgreifen und verändern lassen … schade, dass es nicht so ist …

Im Search-Template gibt es keine Variable namens „sArticles“, vielleicht ist Deine Variable daher null. Die verfügbaren Variablen sind 

 term, criteria, facets, sPage, sSort, sTemplate, sPerPage, sRequests, shortParameters, pageSizes, ajaxCountUrlParams, sSearchResults, productBoxLayout

Die Suchergebnisse findest Du in sSearchResults.

Oh, sorry - mein Fehler. Ich meinte natürlich sSearchResults, und dort dann die sArticles.