Zum Inhalt springen

Extbase - Sortierung von Datensätzen?! sorting, sortby

Erstellt am 29. November 2011 · 5 Antworten · letzte Antwort am 10. Juli 2012

Tags: Frage

zappzarapp ·

Hallo,

ich habe eine Extension mit dem extension_builder erstellt und danach händisch noch sorting Felder eingefügt damit man die Datensätze dann im Backend anordnen kann.

Extbase übernimmt diese Sortierung aber nicht (was ich seltsam/schwach finde). Deswegen habe ich jetzt bei meinen Models die findAll() Methode überschrieben:

public function findAll() {
	$query = $this->createQuery();
	$query->setOrderings (Array('sorting' => Tx_Extbase_Persistence_Query::ORDER_ASCENDING));
	return $query->execute();
}

Damit kann ich jetzt im Controller sortiert auslesen.

Das Problem, das ich jetzt aber noch habe ist, wenn ich einen Datensatz mit einer 1:n verknüfpung habe die ich in Fluid durchlaufe, dass die n-Datensätze nicht nach dem sorting Field sortiert werden.

Beispiel:

Projekt 1
- Bild 1 uid 4, sorting 1
- Bild 2 uid 3, sorting 2
- Bild 3 uid 1, sorting 3
- Bild 4 uid 2, sorting 4
Projekt 2

Projekte und Bilder haben eine sorting Spalte und können im Backend sortiert werden. Die findAll() Methode habe ich bei beiden Repositories geändert.

Mit folgendem FLUID Snippet werden die Bilder aber nicht sortiert ausgegeben sondern einfach nach der Reihenfolge der Eingabe:

<h1>{project.title}</h1>
<h2>{project.subtitle}</h2>
<f:for each="{project.images}" as="image" iteration="blockIteration">
 {image.title}
</f:for>

Mir ist auch klar warum, denn hier wird natürlich nicht die findAll() Methode der Bilder aufgerufen, aber wie kann ich bewerkstelligen, dass auch diese Datensätze korrekt sortiert werden wie im Backend und nicht nach der UID?

Habe schon ein bisschen auf Google gesucht und nix dazu gefunden. Das kann ja nicht sein, dass das nicht funktioniert, denn dann wäre ExtBase/Fluid ja nicht wirklich ordentlich zu gebrauchen - also habe ich hoffentlich etwas übersehen.

lg Matthias

zappzarapp ·

Hallo,

ich habe jetzt noch folgendes entdeckt und in meine Repositories eingefügt:

protected $defaultOrderings = array("sorting"=> Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING);

Damit kann ich mir das überschreiben der findAll() Funktionen ersparen, aber bei den Relations-Datensätzen wird das anscheinend nicht beachtet und die werden noch immer falsch sortiert ausgegeben.

lg Matthias

zappzarapp ·

Okay.. man muss im TCA wo die Relation beschrieben ist noch folgendes eingeben:

'foreign_sortby' => 'sorting'

Dann klappts auch mit der Sortierung 😉

lg

rztki ·

Super thread! Hat mir auf Anhieb geholfen (1:n-Beziehung, mittels Fremdschlüssel).

Einzig diese Formulierung hat mir etwas Kopfzerbrechen bereitet:

zappzarapp schrieb

Okay.. man muss im TCA wo die Relation beschrieben ist noch folgendes eingeben

Diese Dateien liegen in Configuration/TCA und heißen je nach den Domain-Objekten {yourDomainObject}.php (ohne Präfix).

Darin erweitert man $TCA um das angegebene key=>value-Paar.

Genauer: Man erweitert den Array, mit dem die Spalte konfiguriert wird, in der die Anzahl der Kind-Objekte gespeichert ist. (Diese Spalte trägt den Namen des Kind-Objekts, wie im Extension-Builder festgelegt.)

Noch genauer:

$TCA['tx_{extkey}_domain_model_{yourDomainObject}']['columns']['{yourDomainObjectChild}']['config']

Geschweifte Klammern mit Kursivschrift kennzeichnen Platzhalter.

Prosit!

Unbekannter Benutzer ·

Hallo,

ich habe auch nach diesem Thread die Sortierung vorgenommen.
Hat erst auch wunderbar funktioniert.
Jedoch scheint es ein Problem mit

'foreign_sortby' => 'sorting'

zu geben.

Laut dieser Mailingliste: http://lists.typo3.org/pipermail/typo3-german/2012-March/084094.html und das ist auch meine Beobachtung, kann "foreign_sortby" nicht z.B. auf Namen angewendet werden. Sind die Namen schon angelegt, so funktioniert es im ersten Moment.

Beispiel:
(Objekt mit 1:n Beziehung zu Kind-Objekten die bereits angelegt und gespeichert sind

Lorenz (Kundenberater)
|->Müller (Kunde)
|->Anton (Kunde)
|->Doden (Kunde)

wird durch "foreign_sortby => Kunde" sortiert zu:
Lorenz (Kundenberater)
|->Anton (Kunde)
|->Doden (Kunde)
|->Müller (Kunde)

Wird nun jedoch ein weiterer Kunde angelegt und gespeichert, so geschieht folgendes:
Lorenz (Kundenberater)
|->1 (Kunde)
|->2 (Kunde)
|->3 (Kunde)
Der Name des Kunden, nach welchem sortiert werden soll, wird beim speichern des Objekts überschrieben.

Dies rührt daher, so der Thread, dass "foreign_sortby" intern im Backend für die Sortierung verwendet wird und der ursprüngliche Wert beim anlegen eines neuen Kind-Objekts dann überschrieben wird.

Extbase, kann zumindest derzeit, out-of-the-box keine Kind-Objekte per Default sortiert, z.B. nach Name, ausgeben. Daher bleibt einem nur dies manuell zu bewerkstelligen. :o

Folgende Möglichkeiten wurden vorgeschlagen:
1) Verwendung des sort-ViewHelpers aus FED
http://fedext.net/fed-viewhelpers/variables/data-sorter.html

2) Eine weitere Möglichkeit beschreibt Felix Örtel hier:
http://lists.typo3.org/pipermail/typo3-project-typo3v4mvc/2010-June/005131.html

Es gibt sicher weitere Möglichkeiten, ich hoffe das es bald eine out-of-the-box Lösung für solch ein Problem gibt.

Hoffe dies hilft jemanden weiter.

Unbekannter Benutzer ·

Hier noch wie ich das Problem nun gelöst habe.

Ich habe mich für Variante 2) entschieden, da hier die Sortierung, auch bei Ausgabe der Child-Objecte z.B. an ein PDF-Template ohne Fluid, erhalten bleibt.

Folgendes habe ich gemacht:
1) Unter Classes/Utility die Datei Array.php erstellt und wie folgt befüllt:

class Tx_MeineExtension_Utility_Array{
	static public function sortByName($array){
		usort($array, 'Tx_MeineExtension_Utility_Array::usortByName');
		return $array;
	}
	
	static public function usortByName($a, $b){
		return strnatcasecmp($a->getName(), $b->getName());
	}
}

2) Unter Classes/Domain/Model das Model meiner Eltern-Klasse bearbeitet. In der get-Methode für die Kind-
Objekte folgenden Code eingefügt:

Vorher:

...

public function getClients() {
	return $this->clients;
}

...

Nachher:

...

public function getClients() {
	return Tx_MeineExtension_Utility_Array::sortByName($this->clients->toArray());
}

...

Mit dieser Methode wird dem Fluid zwar ein Array und kein Objekt mehr geliefert, war aber in meinem Fall kein Problem.

Mit diesem Schema kann man nun auch nach anderen Spalten sortieren.

Ich hoffe, dass dieser "umständliche" Umweg in Zukunft nicht mehr nötig ist...