Hallo Community,
laut der Typo3 QueryInterface Extbase Dokumentation gibt es beim Query Zusammenbau ja einige Methoden die man nutzen kann, was besonders bei Objekten Sinn machen. Ich nutze das Interface in Flow3 und habe im matching() auch schon funktionierende ANDs, ORs und LogicalNots erstellen können.
Mein Problem ist jetzt aber die in() Methode, die scheinbar nicht so einfach funktioniert, wie ich es mir gedacht habe.
in(string $propertyName, mixed $operand)
In meinem Beispiel wäre das folgendes:
$query->logicalNot($query->in('status',$this->statusRepository->findByShow(FALSE)))
Es soll mir also alle Objekte geben, deren Status Objekte (Many-To-One) NICHT einem Status Objekt entspricht, dass ein Attribut "show" auf false gesetzt ist.
Alles in der in() Methode funktioniert. Das Problem dabei scheint zu sein, dass find() entweder NULL, ein Objekt oder ein Array von Objekten zurück gibt und in() nur ein Array von foreign-keys zu aktzeptieren scheint. Ist das der Fehler oder stehe ich nur wieder mal auf dem Schlauch?
Danke, Pete
Versuch mal die "Subquery" extra zu machen und dann eben wenn es NULL zurückgibt ein leeres Array daraus zu machen. Außerdem ->toArray() sonst übergibst Du da ein QueryResult Objekt, ich weiß nicht ob das klappt.
Ich würde auf das find() noch einen count() machen. Wenn er mir gar keinen Wert gibt, gebe ich NULL zurück, bei einem 'Status' werde ich das mit equals() machen und bei mehreren sollte es ja eigentlich mit in() gehen.
Mal schauen ob das funktioniert ...
Die in() Funktion wird mir immer mehr zum Rätsel. Deshalb wäre es schön, wenn mir jemand diese mal erklären könnte.
So wie ich es verstanden habe, ist der erste Parameter, die Tabellen-Spalte (oder das Objekt-Attribut). Der zweite Parameter ist schon schwerer zu verstehen. Besonders wenn bei mir das Attribut ein anderes Objekt ist (Many-to-One verknüpft).
Kombiniert mit findByIdentifier(), die die Objekte einschränken soll, die in das in-Feld kommen soll ergibt es eine für Flow/Doctrine tödliche Mischung:
Fatal error: Method Doctrine\ORM\Query\Expr\Func::__toString() must not throw an exception
Sorry bin gerade etwas im Stress, antworte im Laufe der Woche...
So ich beantworte das mal noch selber, falls jemand über eine Suchmaschine auf das Thema stößt.
Generell ist es recht einfach, eine IN Abfrage zu erzeugen, man muss nur rationaler denken.
Der IN Operator von SQL kann natürlich nicht Objekte vergleichen. Man muss dem Query alles schön häppchenweise geben.
Persistens Manager zum Ermitteln der IDs von Objekten:
/**
* @FLOW3\Inject
* @var \TYPO3\FLOW3\Persistence\PersistenceManagerInterface
*/
protected $persistenceManagerInterface;
Alle IDs aller Objekte der Reihe nach in ein Array packen:
$statusIDs = array();
$stati = $this->statusRepository->findByToshow(1);
foreach($stati as $status)
$statusIDs[] = $this->persistenceManagerInterface->getIdentifierByObject($status);
Nun einfach in die IN Abfrage einpflegen:
$query->matching(
/* ... */
$query->in('status', $statusIDs)
/* ... */
);
unset($statusIDs);
Gelöst ist das Problem. 😉