Zum Inhalt springen

Problematische Repositoryabfrage wenn Plugin mehrfach auf einer Seite

Erstellt am 21. Juni 2013 · 2 Antworten · letzte Antwort am 25. Juni 2013

Tags: FlexForms, TYPO3 4, Frage

gsnerf ·

Guten Abend,

ich bin noch relativ neu in der extbase Entwicklung und erstelle gerade auf Basis von extbase 1.4.6 auf typo3 4.6.18 eine Erweiterung. Enthalten sind bisher eine Domainklasse, für dessen Verwaltung ein Repository sowie einen Controller mit zwei actions incl. dazu passenden views. Ich habe ein Plugin registriert, welches mittels flexform konfiguriert wird um eine der beiden actions auszuwählen (switchableControllerActions). So lange ich nur ein Plugin auf eine Seite packe funktioniert auch alles, ich kann den Modus des Plugins switchen und bekomme die jeweils erwarteten richtigen Daten ausgegeben. Packe ich nun das Plugin ein zweites mal auf die Seite (mit gleicher oder anderen konfiguration ist egal) wird auch die richtige view angesprochen (überprüft mittels devlog) allerdings liefert das Repository für die zweite Abfrage kein Ergebnis aus der DB. Habt ihr eine Idee woran das liegen könnte? Hier noch der (leicht gekürzte und anonymisierte) Code von meinem Controller und dem Repository:

class Tx_MyExtension_Controller_MyCurrentController extends Tx_Extbase_MVC_Controller_ActionController {

    private $extKey = 'my_extension';
    protected $myRepository;

    public function initializeAction() {
        $this->myRepository = t3lib_div::makeInstance('Tx_MyExtension_Domain_Repository_MyObjectRepository');
    }

    public function listFutureAction() {
        t3lib_div::devLog('[listFutureAction] loading objects from DB', $this->extKey);
        $myObjects = $this->myRepository->findFuture();

        if ($myObjects->count() > 0) {
            // do something
        } else {
            t3lib_div::devLog("[listFutureAction] no result from repository data!", $this->extKey);
        }

        $this->view->assign(/* not important */);
    }

    public function listPastAction() {
        t3lib_div::devLog('[listPastAction] loading objects from DB', $this->extKey);
        $myObjects = $this->myRepository->findPast();

        if ($myObjects->count() > 0) {
            // do something
        } else {
            t3lib_div::devLog("[listPastAction] no result from repository data!", $this->extKey);
        }

        $this->view->assign(/* not important */);
    }
}
class Tx_MyExtension_Domain_Repository_MyObjectRepository extends Tx_Extbase_Persistence_Repository {

    /**
     * Finds all of my objects that are supposed happen in the future.
     * @return Tx_Extbase_Persistence_QueryResultInterface
     */
    public function findFuture() {
        $query = $this->createQuery();
        $query->matching($query->greaterThanOrEqual('dateTime', new DateTime()));
        return $query->execute();
    }

    /**
     * Gets all of my objects in the past that are intended to be shown.
     * @return Tx_Extbase_Persistence_QueryResultInterface
     */
    public function findPast() {
        $query = $this->createQuery();
        $query->matching(
            $query->logicalAnd(
                $query->lessThan('dateTime', new DateTime()),
                $query->equals('visibleWhenPast', true)
            )
        );

        return $query->execute();
    }
}

Noch als Anmerkung zur Nutzung des Repository: Ursprünglich habe ich t3lib_div::makeInstance sowohl in listFutureAction, als auch in listPastAction verwendet um das Repository zu erhalten es aber zu debugging zwecken in initializeAction ausgelagert was wohl eh besser ist. Mir wurde auch schon angetragen, statt t3lib_div::makeInstance lieber $this->objectManager->get('...') zu verwenden, das hat allerdings auch keine Veränderung gebracht.

KarlKappe ·

Hi,

Du kannst das Repo auch mittels Dependency Injection einbinden

/**
 * @param Tx_MyExtension_Domain_Repository_MyObjectRepository $myObjectRepository
 */
public function injectMyObjectRepository(Tx_MyExtension_Domain_Repository_MyObjectRepository $myObjectRepository) {
    $this->myRepository = $myObjectRepository;
}

Das löst aber nicht Dein Problem 😉

Da Du Dein Skript anonymisiert hast, kann ich leider nicht den Zweck der Anwendung erkennen. Aber wie wäre es mit einem Cache? Soweit ich weiß, ist das Repo ein Singleton und wenn Du zum ersten Mal die findPast() aufrufst, speicherst Du das Ergebnis in einer Cache-Variable. Diese liest Du beim zweiten Aufruf aus (if($cache!==NULL)...). Erhöht auch die Performance.
Das löst zwar immer noch nicht das eigentliche Problem, bringt Dich aber erstmal weiter (sofern das mit dem Singleton stimmt), wenn Du nicht zwischendurch etwas in die DB schreibst, was Du beim zweiten Aufruf benötigst, dann ist mein Plan natürlich sinnfrei.

VG Karl

gsnerf ·

Hi,

das Plugin selbst macht nichts anderes, als Daten (Ereignisse) aus der Datenbank abzurufen und in Listenform darzustellen. Da ich unterschiedliche Darstellungen für zukünftige und vergangene Ereignisse benötige und die Möglichkeit haben will nur zukünftige oder nur vergangene Ereignisse darzustellen die Umsetzung mit einem konfigurierbaren Plugin. Das Problem ist nach wie vor, dass das 2. Plugin keine Daten aus der Datenbank geliefert bekommt (obwohl sie da sind, und das erste Plugin im gleichen Modus die gleichen Daten auch bekommt) :/

@injection: hab ich schon von gehört, aber mich noch nicht tiefer mit beschäftigt. Was für einen Vorteil bringt mir das und ist das in extbase 1.4.6 schon enthalten oder erst ab 6.x?