[Frage] komplexe Abfrage für ein Model > Lösung über TCA oder Repository [Gelöst]

  • 0 x
    64 Beiträge
    4 Hilfreiche Beiträge
    13. 02. 2014, 16:36

    Ich muss mal wieder nerven. Langsam komme ich recht gut mit Extbase zurecht, stoße aber immer wieder auf Probleme, wenn es von der Programmierung her etwas von den typischen Beispielen abweicht. So wie jetzt. Ich erkläre erstmal kurz das Ziel anhand eines Beispiels:

    Ich habe ein Model "Thema" und ein Model "Suche". Das Model "Suche" besitzt die Eigenschaft Eigenschaften "Suchbegriffe" (ein kommaseparierter String) und das Model "Thema" besitzt die Eigenschaften "Name". Die genannten Eigenschaften der Models sind in den entsprechenden Tabellen als Spalte vorhanden.
    Nun möchte ich in meinem Model "Thema" eine Eigenschaft "Suchanfragen" einfügen. Diese soll ein ObjectStorage vom Model "Suche" sein und alle Suchanfragen enthalten, in denen das Thema in der Spalte "Suchbegriffe" vorkommt. Das Matching der Datensätze erfolgt also nicht - wie sonst - über einen Fremdschlüssel / eine ID, sondern muss über ein "LIKE" ermittelt werden.
    (Ja ich weiß, man könnte das ganze auch über eine Zuordnungstabelle mit Fremdschlüsseln lösen, aber diese Lösung habe ich bewusst ausgeschlossen, da die Suchanfragen mit den gesuchten Themen noch existieren sollen auch wenn ein Thema gelöscht wurde - das wäre bei einer Zuordnungstabelle nicht der Fall).

    [b]Folgende Lösungen habe ich bereits versucht:[/b]
    1. Ich habe eine Repository-Funktion im "Suche-Repository" erstellt, um eine eigene Abfrage an die Datenbank zu schicken. Ich habe auf verschiedene Art und Weise versucht auf das Repository im Model "Thema" zuzugreifen - leider immer erfolglos (ich habe @inject versucht, die Übergabe im Konstruktor und die Erstellung mittels ObjectManager). Wenn mir jemand sagen könnte, wie ich in Typo3 6.2 beta5 von einem Model aus auf ein Repository zugreifen kann, wäre das vermutlich die einfachste Lösung.

    2. Ich habe versucht die Eigenschaft "Suchanfragen" im TCA von "Thema" anzulegen. Mein Plan war, dass ich die Abfrage im TCA so manipuliere, dass ich die Eigenschaft "Suchanfragen" ganz normal als StorageObjekt nutzen kann. Ich muss gestehen, dass ich noch nicht 100%ig durch das TCA durchsteige. Aktuell sieht meine Konfiguration für die Eigenschaft im TCA so aus:

    1. ...
    2. 'searchrequests' => array(
    3. 'exclude' => 0,
    4. 'label' =>'LLL:EXT:blubb/Resources/Private/Language/locallang_db.xml:tx_blubb_domain_model_topic.searchrequests',
    5. 'config' => array(
    6. 'type' => 'inline',
    7. 'foreign_table' => 'tx_blubb_domain_model_searchrequest',
    8. 'foreign_field' => 'topics',
    9. 'foreign_table_where' => 'OR tx_blubb_domain_model_searchrequest.keywords LIKE CONCAT(\'%\', tx_blubb_domain_model_topic.name, \'%\')',
    10. 'maxitems' => 9999,
    11. 'appearance' => array(
    12. 'collapseAll' => 0,
    13. 'levelLinksPosition' => 'top',
    14. 'showSynchronizationLink' => 1,
    15. 'showPossibleLocalizationRecords' => 1,
    16. 'showAllLocalizationLink' => 1
    17. ),
    18. ),
    19. ),
    20. ...

    Ich habe an Stelle des "komplexen" Codes mit dem CONCAT auch schon ein "OR 1=1" versucht, um auszuschließen, dass diese Lösung aufgrund der "komplexen" Zusatzbedingung scheitert - leider ebenfalls ohne Erfolg. Ich habe auch versucht, den Punkt "foreign_field" weg zu lassen. Auch das hat nicht funktioniert. Egal was ich versucht habe: es wurde nicht mal eine SQL-Abfrage an die Datenbank geschickt (mit sqlDebug=2 in der LocalConfiguration.php kann man sich ja die SQL-Abfragen anzeigen lassen, die gesendet werden).
    Mein Model "Thema" hat auch noch weitere Eigenschaften, wie z.B. Personen, die sich das Thema angesehen haben. Diese haben eine 1:n-Beziehung zum Thema und werden erfolgreich als ObjectStorage erstellt und auch die SQL-Abfrage dafür sehe ich wegen sqlDebug=2. Nur für meine Eigenschaft "Suchanfragen" im TCA wird keine SQL-Abfrage gesendet. Ich habe die Eigenschaft wie alle anderen ObjectStorage-Eigenschaften definiert, initialisiert und eine get-Methode dafür angelegt.

    Ich habe bei allen Versuchen immer den FrontendCache, alle Caches (Gelber Blitz) und den gesamten Cache über das Installtool geleert. Ein Caching-Problem sollte es also nicht sein.
    Nochmal als Hinweis: ich nutze Typo3 6.2 beta5 - falls das irgendwie hilft :-)

    Es wäre schön, wenn mir jemand helfen könnte. Ich bin auch offen für andere Lösungsansätze, wobei ich es gut fände, wenn ich die Lösung mit dem Aufruf des Repositorys vom Model aus nutzen könnte (das bringt meiner Ansciht nach einfach die größte Flexibilität).

  • 1 x
    64 Beiträge
    4 Hilfreiche Beiträge
    19. 02. 2014, 14:53 - Lösung

    Ok, ich habe es selbst hinbekommen. Für alle, die ebenfalls mal ein Repository im Model benötigen, hier noch ein kurzes Beispiel (getestet in Typo3 6.2 beta5):

    1. public function getObjects() {
    2.  
    3. // Objekte nur erstellen, wenn sie noch nicht gesetzt wurden
    4. if(is_null($this->objects)){
    5. // Objekt-Manager erstellen
    6. $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
    7.  
    8. // Repository instanziieren
    9. $myRepository = $objectManager->create('Vendor\\MyExtension\\Domain\\Repository\\MyRepository');
    10.  
    11. // nun kann man ganz normal mit dem Repository arbeiten
    12. $this->objects = $myRepository->findAll();
    13. }
    14.  
    15. return $this->objects;
    16. }

    Vielleicht hilft es ja jemandem.


  • 1
  • 1 x
    64 Beiträge
    4 Hilfreiche Beiträge
    19. 02. 2014, 14:53

    Ok, ich habe es selbst hinbekommen. Für alle, die ebenfalls mal ein Repository im Model benötigen, hier noch ein kurzes Beispiel (getestet in Typo3 6.2 beta5):

    1. public function getObjects() {
    2.  
    3. // Objekte nur erstellen, wenn sie noch nicht gesetzt wurden
    4. if(is_null($this->objects)){
    5. // Objekt-Manager erstellen
    6. $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
    7.  
    8. // Repository instanziieren
    9. $myRepository = $objectManager->create('Vendor\\MyExtension\\Domain\\Repository\\MyRepository');
    10.  
    11. // nun kann man ganz normal mit dem Repository arbeiten
    12. $this->objects = $myRepository->findAll();
    13. }
    14.  
    15. return $this->objects;
    16. }

    Vielleicht hilft es ja jemandem.

  • 1