Backend Plugin: Mehrere Controller

Ich habe ein Backend Plugin, welches ein Fenster mit zwei Tabs öffnet. Mein Model enthält ein Datum-Feld. Im ersten Tab soll jetzt eine Liste mit all meinen Entitäten ausgegeben werden, wo das Datum in der Zukunft liegt. Im zweiten Tab soll genau das gleiche ausgegeben werden, nur mit allen Entitäten, wo das Datum in der Vergangenheut liegt. Die “Zukunfts”-Funktionweise habe ich soweit mit folgendem Controller hinbekommen:

where($builder->expr()->gte('future.date', ':today'));
        $builder->setParameter(':today', $today->format('Y-m-d'));

        $builder->addOrderBy('future.date');
        $builder->leftJoin('future.article', 'article');
        $builder->addSelect(array('article'));

        return $builder;
    }
}

Meine Idee war es jetzt einen zweiten Controller zu machen, wo einfach nur die WHERE Bedingung umgedreht wird. Außerdem habe ich den Store und das Model für den zweiten Tab kopiert und dort dann den Controller Namen angepasst. Jetzt bekomme ich aber folgende Fehlermeldung:

Fatal error :  Uncaught Enlight_Controller_Exception: Controller “Past” not found in /project/shopware/engine/Library/Enlight/Controller/Dispatcher/Default.php:488
Stack trace:
#0 /project/shopware/engine/Library/Enlight/Controller/Front.php(223): Enlight_Controller_Dispatcher_Default->dispatch(Object(Enlight_Controller_Request_RequestHttp), Object(Enlight_Controller_Response_ResponseHttp))
#1 /project/shopware/engine/Shopware/Kernel.php(191): Enlight_Controller_Front->dispatch()
#2 /project/shopware/shopware.php(118): Shopware\Kernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#3 {main}
  thrown in /project/shopware/engine/Library/Enlight/Controller/Dispatcher/Default.php on line 488

Kann man überhaupt mehrere Controller definieren? Weil in der menu.xml muss man ja auch einen Controller angeben. Da müsste ich dann ja theoretisch beide angeben. Kann mir jemand sagen, wie ich das am besten umsetze? Geht es vielleicht auch ohne einen zweiten Controller? Also könnte man an einer anderen Stelle noch die Daten filtern?

Hallo iNono,

du kannst natürlich so viele Controller registrieren, wie du möchtest in deinem Plugin. Für den Menüpunkt (menu.xml) kann nur ein Controller angegben werden. 
Für deinen UseCase würde ich zwei Extjs Stores und zwei Extjs Models anlegen, die dann jewweils einen der beiden Controller ansprechen. In dem einen Grid benutzt du dann den ersten Store, in dem anderen Grid den zweiten. 
Du könntest aber auch das Laden des Stores, also das Laden der Daten, überschreiben und je nach dem in welchem Grid du bist, einen Parameter mitsenden, um dann in deinen Controller eine Unterscheidung machen zu können. 

Deine Fehlermeldung deutet aber erstmal darauf hin, dass der Controller “Past” nicht richtig registriert worden ist. 
Welche Shopware Version nutzt du? Und wie ist deine Plugin Struktur? Liegen die Controller im richtigen Ordner? siehe Plugin quick Startup Guide

Viele Grüße aus Schöppingen

cool Michael Telgmann

Hallo Michael!

Danke für die Antwort! Ich werde morgen nochmal überprüfen, ob der Controller richtig registriert ist.

Aber schon mal zu der Variante mit dem Parameter: Könntest du mir mehr Details dazu geben, wie ich den Parameter mitsende und wie ich dann im Controller in der getListQuery() Methode darauf zugreifen kann? Ich denke das wäre die schönere Variante.

Viele Grüße

Hab eine schöne Variante entwickelt. Im Controller habe ich eine eigene Action, in der nur ein Parameter gesetzt wird und dann die listAction() vom Parent aufgerufen wird. In der getListQuery() wird der Parameter dann abgefragt. Und im Store habe ich dann einen Proxy definiert, der meine Action aufruft:

Controller:

class Shopware_Controllers_Backend_MyPlugin extends Shopware_Controllers_Backend_Application
{
    protected $model = Scheduler::class;
    protected $alias = 'scheduler';
    protected $futureOrPast = null;

    protected function getListQuery()
    {
        $builder = parent::getListQuery();

        $today = new \DateTime();
        if($this->futureOrPast === "past"){
            $builder->where($builder->expr()->lt($this->alias.'.date', ':today'));
            $builder->addOrderBy($this->alias.'.date', 'DESC');
        }
        else{
            $builder->where($builder->expr()->gte($this->alias.'.date', ':today'));
            $builder->addOrderBy($this->alias.'.date');
        }
        $builder->leftJoin($this->alias.'.article', 'article');
        $builder->setParameter(':today', $today->format('Y-m-d'));
        $builder->addSelect(array('article'));

        return $builder;
    }

    public function getPastAction()
    {
        $this->futureOrPast = "past";
        parent::listAction();
    }
}

Store:

Ext.define('Shopware.apps.MyPlugin.store.Past', {
    extend:'Shopware.store.Listing',

    configure: function() {
        return {
            controller: 'MyPlugin',
            proxy: {
                type: 'ajax',
                url: '{url controller="MyPlugin" action="getPast"}',
                reader: { type: 'json', root: 'data', totalProperty: 'total' }
            }
        };
    },
    model: 'Shopware.apps.MyPlugin.model.Past'
});