"Komplexere" Beziehungen zwischen Nodes
![](http://www.drupalcenter.de/files/noavatar_mini.gif)
am 26.06.2010 - 21:48 Uhr in
Hallo allerseits!
Ich fange gerade an, mich in Drupal (und einige Module wie beispielsweise CCK) einzuarbeiten, und bin jetzt auf mein erstes größeres Problem gestoßen: Ich möchte eine Art Bewerbungssystem basteln.
Ziel ist folgendes: Es gibt einen Inhaltstypen namens "Projekt" (mit dem man Informationen über Projekte speichern kann)... ein Benutzer soll nun für ein Projekt eine Bewerbung abgeben können, die über ein Online-Eingabeformular eingegeben wird und dann dem Projekt zugeordnet wird.
Ich hatte mir das so gedacht, dass ich mir neben dem Inhaltstypen "Projekt" einen zweiten Inhaltstypen namens "Projektbewerbung" mit einem nodereference-Feld bastle und irgendwie einen Link zur Erstellung einer Seite dieses Typs an den Inhaltstypen "Projekt" ranbaue.
Probleme dabei sind jedoch folgende:
- Wie kann ich das nodereference-Feld in der Projektbewerbung vom Benutzer verstecken bzw. automatisch im Hintergrund ausfüllen lassen, wenn man einem Link à la node/add/projektbewerbung/123 folgt? Da der Benutzer das Feld dann auf keinen Fall (erst recht nicht nachträglich) bearbeiten können soll, würde ein CSS-Hack in der Art von "display: none;" nicht genügen. (Wäre diese Bedingung nicht vorhanden, würde das Modul Prepopulate ziemlich genau das sein, wonach ich suche.)
- Wie kann ich sicher gehen, dass ein Benutzer zu einem Projekt nur genau eine Node vom Typ Projektbewerbung erstellt?
- Welches ist die schlaueste Art, sämtliche Projektbewerbungen zu einem Projekt auf der Projektseite in Tabellenform darzustellen?
Habt ihr dazu Vorschläge oder Anregungen? Über jede Art von Hilfe würde ich mich sehr freuen!
Viele Grüße
Hauke
- Anmelden oder Registrieren um Kommentare zu schreiben
Ich muss leider zugeben, dass
am 26.06.2010 - 23:31 Uhr
Ich muss leider zugeben, dass sich mir der Zusammenhang zwischen "Projekt" und "Projektbewerbung" nicht ganz erschließt. Wann soll welcher Inhaltstyp erstellt werden? Dürfen mehrere User sich für ein Projekt bewerben oder wie kann man sich das vorstellen?
Mir ist dazu spontan eine Möglichkeit eingefallen:
Du hast deine beiden Inhaltstypen "Projekt" und "Projektbewerbung". Bei letzterem fügst du ein Node-Reference-Feld hinzu. Außerdem aktivierst du das Modul "Content Permission" (gehört zu CCK), damit kannst du festlegen, wer die Felder bearbeiten und sehen darf etc.
Damit verbietest du den Leuten, dein Node-Reference-Feld zu bearbeiten.
Außerdem stellst du es in den Berechtigungen (also die normalen Drupal-Berechtigungen) so ein, dass die User KEINE Inhalte vom Typ "Projektbewerbung" erstellen dürfen, allerdings dürfen sie eigene Inhalte dieses Typs editieren (klingt zwar komisch, wird später aber noch sinnvoll ^^ evtl. benötigst du dafür das Modul Content Access)
Nun ist also die Ausgangssituation, dass die Benutzer Inhalte vom Typ "Projekt" erstellen können, aber keine Inhalte vom Typ "Projektbewerbung". Wenn allerdings ein Inhalt vom Typ Projektbewerbung existiert, dem sie als Autor zugeordnet sind, dann dürfen sie Ihn bearbeiten. Dabei können sie aber nicht das Node-Reference-Feld ändern - so weit, so gut.
Jetzt (oder auch schon vorher) installiert man die Module Rules und Token.
Damit erstellt man sich eine Regel, die ausgelöst wird, wenn ein neuer Inhalt gespeichert werden soll. Als Bedingung, dass die Regel ihre Aktionen ausführt, wird angegeben, dass der Inhalt vom Typ "Projekt" sein muss.
Als Aktionen werden im wesentlichen zwei Dinge ausgeführt:
Zuerst wird ein neuer Inhalt erstellt. Man lässt also per Rules-Aktion einen neuen Node anlegen und wählt als Typ "Projektbewerbung". Außerdem wählt man die Einstellung so, dass als Node-Autor der User eingetragen wird, der die Rule ausgelöst, also das Projekt zuvor gespeichert hat. Schon haben wir einen Node vom Typ "Projektbewerbung", der als Autor ein User zugeordnet ist, der solche Nodes eigentlich nicht erstellen darf.
Als zweite Aktion wählen wir aus, dass ein CCK-Feld gefüllt werden soll. Dort wählen wir als zu behandelnden Node den gerade per Rule erstellten Node aus (in Rules bekommen diese Objekte Arbeitsnamen zugewiesen. Z.B. wird in diesem Fall der Node, den der User erstellt hat als "Inhalt erstellt" beschrieben und der per Rule erstellte Node als "neuer Inhalt vom Typ projektbewerbung"; Letzteres kann man in der Aktion aber beliebig anpassen). Also wählen wir den per Rule erstellten Node sowie das entsprechende CCK-Feld aus und füllen es (dafür wird allerdings PHP nötig sein, aber das dürfte nur ein 4-Zeiler oder so werden, da könnte man dir bei Bedarf helfen).
Ergänzend könnte man als letzte Aktion noch den Body des ursprünglichen Nodes (vom Typ "Projekt") ändern, um einen Link zur zugehörigen Projektbewerbung anzuhängen.
So, nochmal kurz eine Zusammenfassung, wie in diesem Fall der Arbeitsablauf für einen User aussehen würde:
Damit wäre zumindest Problem Nr. 1 aus dem Weg, dass der User das Reference-Feld nicht ändern darf. Er darf es nicht (via Content Permission) und die Referenz auf das Projekt wird automatisch erstellt.
Außerdem dürfen die User nicht eigenständig Projektbewerbungen erstellen, also können sie auch nicht zu einem Projekt mehrere Bewerbungen erstellen, sondern ein Projekt --> eine Bewerbung.
Zum dritten Punkt:
Installiere Views, arbeite dich ein wenig darin ein und du wirst feststellen, dass du damit so ziemlich alle Darstellungen erreichen kannst, die du willst.
So, ich hoffe, es war einigermaßen verständlich, was ich heir aufgeschrieben habe. Ich weiß auch nicht so recht, ob ich damit dein Problem getroffen habe, aber wenn ich es richtig verstanden haben sollte, finde ich die Lösung ganz in Ordnung ;-) So erspart man den Usern auch, dass sie eine extra Bewerbung erstellen müssen und extra den zu referenzierenden Node raussuchen müssen etc.
Wow!
am 26.06.2010 - 23:56 Uhr
Ich muss sagen: Ich bin echt sprachlos! Vielen Dank für deine so schnelle und gleichzeitig ausführliche Antwort!!
Ich werde im Laufe des morgigen Tages deinen Lösungsvorschlag mal ausprobieren - dass Rules ein so mächtiges Werkzeug ist, war mir vorher noch nicht klar.
Views hatte ich bereits installiert, nur verstand ich noch nicht so recht, wie man einen View zu einem Inhaltstyp sozusagen "hinzufügt". Ich bin dann auf den Page Manager der Ctools gekommen - und da hilflos verloren gegangen... aber ich denke, ich schaue mir dann nochmal intensiv in aller Ruhe die Doku zu Views an.
Dürfen mehrere User sich für ein Projekt bewerben oder wie kann man sich das vorstellen?
Es gibt eine Benutzergruppe (nennen wir sie hier Admins), die Projekte erstellen darf. Eine andere Benutzergruppe (nennen wir sie hier User) soll sich dann auf die Projekte bewerben können. Und ja - eine beliebige Anzahl an Benutzern darf sich auf eine beliebige Anzahl an Projekten bewerben.
Vielen Dank nochmals und viele Grüße
Hauke
Zitat: Und ja - eine
am 27.06.2010 - 00:07 Uhr
Und ja - eine beliebige Anzahl an Benutzern darf sich auf eine beliebige Anzahl an Projekten bewerben.
Mmmh, das ändert ein wenig den Sachverhalt, weil der oben beschriebene Weg darauf ausgelegt ist, dass ein User ein Projekt erstellt und gleichzeitig eine Projektbewerbung.
Also wird man das ganze ein wenig ändern müssen, glaube ich. Was genau gehört denn zu der Bewerbung? Gehört dazu noch ein "Bewerbungstext", oder wäre es eher so, dass ein User sich einfach nur für das Projekt bewirbt (also Kontakt-Infos angibt und alles andere regelt man dann per Mail oder Telefon oder sonst wie). Was genau gehört zu der Bewerbung?
Ich merke auch gerade, dass
am 27.06.2010 - 00:47 Uhr
Ich merke auch gerade, dass das leider doch nicht ganz so funktioniert, wie ich mir das ursprünglich Vorgestellt hatte. (Ich konnte mit dem Ausprobieren doch nicht bis morgen warten. ;-) )
Zu der Bewerbung gehört eine ganze Reihe von Feldern, z.B. einige Textfelder wie beispielsweise für "Motivation" etc. Zudem müssen aber auch noch Checkboxes zur Auswahl von Qualifikationen angekreuzt werden. Hattest du an eine Lösung mithilfe von Kommentaren gedacht? Wenn ja, scheidet das wohl leider aus.
Ich glaube aber jetzt durch Zufall auf eine andere Lösung gekommen zu sein: Node Reference URL Widget. Das erlaubt sogar fast genau die gleiche Syntax zur Erstellung einer Bewerbung, die ich in meinem ersten Post hier im Thread geschrieben hatte. Sogar die nachträgliche Veränderung des Inhalts verbietet das Widget. Jetzt muss ich es nur noch in den Griff bekommen, dass man sich nicht doppelt auf ein Projekt bewerben kann... aber ich glaube, das mit einem View (à la "Projekte, auf die man sich noch nicht beworben hat") hinbekommen kann - der View kann ja dann in den Einstellungen des Nodereference-Felds bei "Erweitert - Beiträge, auf die referenziert werden kann (Ansicht)" festgelegt werden.
Ich werds morgen mal ausprobieren und mich dann nochmal hier melden, obs geklappt hat.
Viele Grüße
Hauke
Tja, die Lösung oben hätte
am 27.06.2010 - 01:32 Uhr
Tja, die Lösung oben hätte eben ganz gut zu dem Fall gepasst, von dem ich ausgegangen bin ;-) Habe nur das Problem falsch verstanden ^^
Das URL Widget ist schonmal eine gute Sache. Aber dann hast du eben noch die Sache mit den potentiellen Mehrfachanmeldungen für ein Projekt. Das kannst du auch mit einer entsprechenden View nicht sicher umgehen, denn wenn jemand eine Bewerbung für den Node 123 abgibt und nach dem Speichern nochmal das Node-Formular mit der Referenz auf den Node 123 aufruft, kann er theoretisch unbegrenzt Bewerbungen abgeben. Das lässt sich auf verschiedene Arten umgehen:
Du könntest die gesamte Node-Reference-Sache verwerfen und das Signup-Modul verwenden. Damit kannst du dir direkt unter dem Projekt ein "Bewerbungsformular" für diesen Node ausgeben lassen. Das hat zwar standardmäßig nur wenige Felder, aber es ist eine Anleitung dabei, wie man weitere Felder hinzufügt. Damit kannst du dir alle nötigen Felder erstellen (allerdings musst du dir vorher die Form API von Drupal ansehen, die ist aber recht einfach). Das hätte natürlich einen großen Vorteil hinsichtlich der Usability. Die User müssen nicht mehr ein extra Node-Formular ausfüllen, sondern haben das Formular direkt unter dem Node. Auserdem können sie sich pro Node nur einmal einschreiben. Wäre vielleicht mal einen Versuch wert. Wenn das mit den zusätzlichen Feldern so klappt, wie es soll (ich habe die Signup-Felder noch nie bearbeitet, ich weiß nur, dass es gehen dürfte), würde ich es einem extra Inhaltstyp mit Nodereference vorziehen.
Sollte das so nicht gehen wie gewünscht, könnte man die Mehrfachbewerbung mit einem eigenen kleinen Modul verhindern.
Wäre auch gar keine große Sache, nur ein winziger hook_form_alter und eine eigene Validierungsfunktion:
Im hook_form_alter fügt man dem Node-Formular nur eine eigene Validierungs-Funktion hinzu, das ist ganz genau eine Zeile Code.
In der Validierungsfunktion macht man nur eine Datenbank-Abfrage in der CCK-Tabelle des Inhaltstyps, die in etwa so aussehen würde:
$sql = "SELECT ctp.nid FROM {content_type_projektbewerbung} ctp INNER JOIN {node} n ON ctp.nid = n.nid WHERE n.uid = $uid AND ctp.nid = $nid;";
Wenn diese Abfrage ein Ergebnis liefert, dann bedeutet das, dass der Benutzer schon eine Bewerbung für diesen Node gespeichert hat. Also gibt man in diesem Fall einfach einen Form-Error aus, in dem man mitteilt, dass für das Projekt schon eine Bewerbung gespeichert ist und der Node kann nicht gespeichert werden. Klingt zwar etwas aufwändig, ist aber eigentlich eine recht simple Angelegenheit, kann man in 30 Minuten erstellen.