Doctrine Nested Sets in Symfony

Ich musste letzte Woche ein Symfony-Projekt um verschachtelte Kategorien erweitern. Auf Grund von Doctrine ist das eigentlich kein großes Ding. Die Nested-Sets sind dort bereits an Bord. Auch Plugins zur Verwaltung und Ausgabe gibt es. Um die Sache zum Laufen zu bekommen musste ich dann aber doch in einigen Quellen stöbern. Meinen Weg zum Ziel möchte ich hier kurz beschreiben.

Erst einmal gibt es da eine sehr gute Schritt für Schritt Anleitung. Sie erklärt das Anlegen des Models und die Ausgabe der Bäume. Hier geht es los mit Teil 1 von 3. Abtippen ist aber nicht nötig. Der Verfasser des Tutorials hat sich letztlich sogar dazu entschieden seine Arbeit als Plugin zu veröffentlichen. Dazu zum Ende mehr.

Los geht es erst einmal mit dem Model. Hier ist es mit wenigen Zeilen Konfiguration getan. Im Folgenden mein sehr übersichtliches Model für die Kategorien. Einmal generiert, muss man sich um die Methoden zur Navigation durch die Baumstruktur keinen Gedanken mehr machen. Auch der Performance ist mit gerade mal einer Datenbank-Abfrage ideal. Weitere Infos zu Nested Sets gibt es hier direkt in der sehr guten Doctrine-Dokumentation. So, jetzt aber die YAML-Schema Konfiguration:

Category:
  actAs:
    NestedSet:
      hasManyRoots: true
      rootColumnName: root_id
  columns:
    name: string(255)

Jetzt will das Ganze auch noch irgendwie verwaltet werden. Hier hat mir das Plugin sfJqueryTreeDoctrineManagerPlugin die Arbeit abgenommen. Innerhalb einer netten JavaScript gestützten Baumstruktur lassen sich darin die Daten des eben erstellten Models komfortabel anlegen und bearbeiten.

Das Kontextmenü zum editieren bestehender Einträge wollte allerdings nicht auf Anhieb. Da Einträge aber auch per Doppelklick umzubenennen sind, habe ich mich um dieses Problem jedoch gar nicht weiter gekümmert. Um Irritationen beim Nutzer zu vermeiden ist das Kontextmenü mit folgender Konfiguration in der app.yml zu deaktivieren:

all:
  sfJqueryTree:
    withContextMenu : false

Abschließend zum weiter oben angesprochenen Plugin sfDoctrineNestedSetPlugin. Dieses bringt einen Validator und ein Widget zur Erweiterung der Formular-Funktionen mit. Mit Hilfe des Widgets sfWidgetFormDoctrineChoiceNestedSet ist es möglich die Baumstruktur innerhalb eines Select-Felds entsprechend strukturiert zur Auswahl anzubieten. Der Validator sfValidatorDoctrineChoiceNestedSet wiederum kontrolliert das die Eingabe seine Richtigkeit hat.

Damit wäre es dann auch möglich existierende Models mit den Kategorien zu verbinden und mein kleiner Rundgang am Ende angelangt.