Zum Inhalt springen

Repository->findBy*

Erstellt am 17. April 2013 · 4 Antworten · letzte Antwort am 21. April 2013

Tags: Datenbank, Frage

tobla ·

Hallo Zusammen

Ich hab vermutlich einfach ein Brett vor dem Kopf. Wie kann ich über alle Attribute eines Objektes suchen, ohne dass ich diese spezifiere?

Wir haben eine Klasse Produkt mit Eigenschaften.
Nun möchten wir eine Volltextsuche über alle Felder implementieren, so a la "findByAll" oder "findBy*" ohne die Felder explizit anzugeben:

public findByAll($term) {
    $query = $this->createQuery();
    $constraint = $query->equals('*',$term);
    return $query->matching($constraint)->execute();
}

Wie kann ich das umsetzen? Geht das gar nicht, muss ich das mit DQL machen?

harald1972 ·

Hallo auch,

wenn du an die Grenzen von extbase stößt, kannst du deinem Repository eine function geben; ich würde sie nicht findByAll() oder findByIrgendwas() nennen, weil sonst womöglich nach dem Attribut 'all', bzw. 'irgendwas' gesucht wird; diese function lässt du dann den SQL-string ausführen.
...ungefähr so:

public function getByAllProperties($term){
      $extbaseFrameworkConfiguration = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
      $pidList = implode(', ', t3lib_div::intExplode(',', $extbaseFrameworkConfiguration['persistence']['storagePid']));
      $sql = "DEIN_SQL_STRING";
      $query = $this->createQuery();
      $query->statement($sql);
      return $query->execute();
}

Die entsprechenden Properties müssen logischerweise in den SQL-String rein.
Hier kannst du z.B. dieser function noch ein Array("name", "vorname", "comment", "foo", "bar" ) als Parameter mitgeben, womit du dann den SQL-string zusammensetzt.
Ich weiß nicht, ob du an eine Liste à la getAllProperties() rankommst, aber dann musst du immer noch aufpassen, nicht z.B. in der $uid zu suchen (Zahlen können schonmal im Such-string sein).
Die andere Option ist, du übergibst selbst eine Liste (Array oder sonst irgendeinen passablen Container) mit den Properties und gehst die in einer Schleife durch.

Wenn du dann richtig pfiffig bist, machst du dir eine magic-function, die dir

foreach($propertyList as $property){
  call_user_func('findBy', $property); // oder sowas in der Art
}

aufruft.

Ich denke nicht, daß ich jetzt _DIE_ Lösung für dein Problem hab, aber vielleicht hilft dir das als Ansatz.
Noch zu bemerken:
1.) Einen SQL-string zu schreiben und derart abzusenden, bedeutet einen Paradigmenbruch, weil der String ja auf mysql (oder was du eben verwendest) passen muss. Ab hier kannst du mit deiner Extension nicht mehr so einfach mit jeder beliebigen DB komunizieren. (War bei mir auch schonmal notwendig, weil extbase an sich keinen JOIN kann)
2.) Ich denke, du musst die gewünschten Properties wenigstens einmal irgendwo aufzählen (beim Namen nennen), sonst würdest du, wenn du ALLE Properties nimmst, auch über uid, pid, tstamp usw. suchen.
3.) call_user_func wäre dann nochmal ein Thema für sich (php), das aber glaub nicht mehr in diese Forum gehört.

Gruß

tobla ·

Danke für deine ausführliche Antwort. Mit DQL (Direct Query Language) hab ich genau das gemeint, was du beschrieben hast.

Ich habe für Joins auch schon zu dieser Methode greifen müssen. Bin aber grundsätzlich nur bedingt ein Fan davon. Auch aus Sicherheitsgründen nicht. Vermutlich ist es sinnvoller, alle String-Attribute der Klasse zu ermitteln und mit einer Schleife das QOM zusammenzubauen.
Ich werde mir mal die Extbase Klassen ansehen und schauen, ob ich dort irgend etwas in der Art von 'getProperties()' oder anderweitigen Methoden finde, die Klasseninfos ausgeben.

kainobi ·

Den TCA würde ich dafür nicht nehmen. Die sauberste und zukunftssicherste Lösung wäre mMn, die Reflection-Klassen (extbase/Classes/Reflection) von Extbase zu verwenden.