Sortierung eines Dropdownwidgets in Symfony ändern (Doctrine)

Frameworks sind toll. Man kann in vielen tausend Zeilen das tun, wozu man früher nur ein paar Statements gebraucht hat… Oder war es umgekehrt? Hier etwas Symfony spezifisches, das mir ein paar gefärbte Haare gekostet hat, weil ich sie mir ausreissen musste.

Das Problem

Es sei gegeben eine dreistufige Hierarchie: Kategorien → Fächer → Kurse. Es sind ganz saubere 1:n-Beziehungen: Jedes Fach gehört zu einer Kategorie und ein Kurs ist genau ein durchgeführtes Fach.

Folgt man dem (wirklich guten) Symfony-Tutorial, so wird an Tag 3 ganz unten gezeigt, wie aus der Tabellendefinition automatisch ein Formular generiert wird. Clevererweise werden für 1:n-Beziehungen Dropdowns generiert.

Wenn ein neuer Kurs generiert wird, so soll man angeben können, was für ein Fach er unterrichtet. Standardmässig werden Fächer wie folgt angezeigt:

  1. Ein Kategorienkürzel („I“ für Informatik, „A“ für Ausdruckstanz (haha), …)
  2. Einer „Nummer“ (normalerweise „01“ bis „15“ oder so)
  3. Dem Namen des Fachs

Das Fach braucht für seine Darstellung also das Kürzel aus dem Kategorien-Model (bin ich der Einzige der bei Models immer grinsen muss?).

Das generierte Dropdown zeigt die Namen der Fächer falsch und alles Kreuz und Rüben durcheinander an. Ha, nun ist guter Rat teuer.

dropdownstart

Lösung

Namen der Fächer

Das geht noch relativ einfach: Jedes Model besitzt eine __toString() Methode, die überschrieben werden kann:

# File: lib/model/doctrine/modelnamefach.class.php
[...]
  public function __toString() {
        return sprintf('%s %s %s', $this->FreifachNgKategorie->getKuerzel(), $this->getNummer(), $this->getName());
  }
[...]

Und tatsächlich:

dropdownbefore

Sortierung

Ich hätte mir eigentlich gewünscht, für jedes Model eine Defaultsortierung angeben zu können. Aber da nicht Weihnachten ist, werden meine Wünsche nicht erfüllt. Da hilft nur Quellcodestudium und glückliches Zusammenpuzzeln der Doctrine Anleitung, dem Symfony-Doctrine Buch und der API-Dokumentation (scrollen bis Doctrine): Beispiele gibts leider fast keine.

Nungut: Das Formular wird automatisch generiert (lib/form/doctrine/base/), darum sollte hier nur wer was ändern, der per Stunde bezahlt wird und das nach jeder Generierung wieder neu tun kann :). Für uns Andere müssen wir das Choice in der Kinderklasse hacken und eine table_method reinbringen, die die Einträge nach unserem Gusto liefert:

# File: lib/form/doctrine/modelnamekurs.class.php
[...]
  public function configure()  {
      $this->setWidget('freifach_id', new sfWidgetFormDoctrineChoice(array('model' => 'FreifachNgFreifach', 'table_method' => 'retrieveFreifachOrderedByCategory')));
  }
[...]

Diese table_method muss auch noch codiert werden. Und das in der Tabellenklasse der Fächer (dochdoch, wenn man sich das überlegt ist es ganz logisch *irres_grinsen*).

# File: lib/model/freifachmodelnameTable.class.php
[...]
    function retrieveFreifachOrderedByCategory() {
        $q=Doctrine_Query::create()->from('FreifachNgFreifach f')->innerJoin('f.FreifachNgKategorie k')->orderby('k.kuerzel, f.nummer, f.name');
        //echo $q->getSql();
        return $q;
    }
[...]

Toll, und dann klappts auch mit dem Dropdown:

dropdownordered

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.