Ich habe mich mittlerweile etwas mit der Module Entwicklung in Drupal beschäftigt. Irgendwann wollte ich dann direkt aus einem PHP Script neue Nodes erstellen und editieren und Dateien anhängen. Dazu sucht man sich natürlich ein paar bereits fertige Module raus und guckt: "Wie machen die das denn?". So findet man schnell die Funktionen node_save und node_load. Was ich allerdings so direkt nicht finden konnte, waren relativ einfache Funktionen um Dateien an einen Node anzuhängen. Hier brechen sich die meisten einen ab, in dem direkt die Datenbank manipuliert wird.
Das liegt wohl daran, dass Dateihängen meisten nicht über die CCK (Content) Felder realisiert werden. Ist auch logisch, da dieses Module erst ab Drupal 7 im Core enthalten ist. Allerdings hat man hiermit dann direkt alles mit drin. Sogar die wunderbaren Hooks und Interaktion mit anderen Modulen wird gewährleistet. Also bloß nichts anderes nutzen. :)
Zum Testen der unten genannten Funktionen kann man sich entweder ein neues Module erstellen oder einfach in einen normale Seiten erstellen und das Eingabeformat auf PHP-Filter setzen. Ein includen von Dateien und Modulen ist nicht nötig.
Neuen Node erstellen
Um einen neuen Node zu erstellen, müssen wir nur ein blanko Objekt erstellen und die erforderlichen Felder übergeben. Dazu gehört natürlich der Inhaltstyp und ein Titel, alle anderen Felder könnten zur Not auch ausgelassen werden, hängt aber auch vom Inhaltstyp ab (z.B. Pflichtfelder, Taxonomie). Per node_save wird aus dem Objekt ein neuer Node erzeugt und bei Erfolg die neue Nid als Zahlenwert zurückgegeben.
$node = new stdClass(); $node->title = 'Title of Node'; #you must set a content type! $node->type = 'page'; #set author of node (if not set: anonymous) $node->uid = 1; #show node on frontpage $node->promote = 1; #save the node; and get the new nid node_save($node); $nid = $node->nid;
Node Editieren
Zum Editieren eines Node kann ein bekannter Node per Nid geladen werden und alle Felder verändert werden. Es ist auch möglich wie oben ein neues Objekt zu erstellen mit dem Wert $objekt->nid des bekannten Nodes. Beim Speichern werden dann nur die veränderten Werte gespeichert.
#load the old node or you can also create a new node #template and set $node->nid; $node = node_load($nid); #change something $node->title = 'new title'; #and save the new node node_save($node);
Taxonomy nutzen
Auch Taxonomien können an einen Node-Objekt gehangen werden. Es muss hier allerdings bedacht werden, dass die Begriffe sowohl innerhalb von mehreren Taxonomien eingetragen werden können, als auch eine Verschachtelung vorhanden sein kann. Will man dem aus dem Weg gehen, so setzt man einfach ein Taxonomy Feld auf Tags, somit kann man einfach die einzelnen Begriffe per Komma getrennt übergeben.
#we must know the vid of taxonomy where we want to add
#the tags, so get it by the name
$vid = taxonomy_get_term_by_name('mytagsholder')
#it is very simple if you use taxonomy as ´Tags´, so dont do other things :)
#you can give a simple string seperated by , all other stuff does drupal for you
$tags='apple, windows, drupal is funny, '
$node->taxonomy=array('tags' => array($vid => $tags));Datei hochladen und anhängen
Wie bereits erwähnt ist das anhängen einer Datei in Drupal 6 nicht ganz so einfach, ohne CKK und FileField. Da genannte Module Standard in der Drupal Installation seinen sollten und ab Drupal 7 zum Core gehören, werden ich den "Standard Dateianhang Modus" nicht weiter beschreiben.
FileField gibt und die Funktion field_file_save_file. Per einfachem Parameter übergeben wir den Pfad zu einer Datei (remote oder lokal möglich), die Datei wird dann runtergeladen, im temporären Ordner abgelegt, eine eindeutige Fid erstellt, ein Verweis in der Drupal Datenbank angelegt und ein File Objekt zum weiteren Verarbeiten zurückgeben.
Dieses File Objekt müssen wir dann an einen Node anhängen, genauer gesagt an ein CCK (Content) Field vom Typ FileField. Erst nach dem Aufruf von node_save wird dann die bis dahin temporäre Datei im Drupal Dateisystem angelegt (sites/all/files). Nutzen wir weitere Module wie z.B. FileField Path auf dem Field, so werden die Aktionen automatisch durchgeführt, da wir direkt die Drupal Funktionen benutzen.
#upload a file with FileField: you can use remote and local files/urls
#the file is saved in the temporary dir, only if you attach it to a node and
#save it you will find it in the drupal files dir
$file=field_file_save_file('your/file/isfine.jpg');
#after uploading the file attach it to a node:
#we take our uploaded $file array andput it into a
#FileField. here we have a single value field. so we are using [0]
$cck_field='field_image';
$node->{$cck_field}[0]=$file;
node_save($node);Datei ersetzen
Zum Löschen und Ersetzen einer Datei innerhalb eines FileField Feld, brauchen wir dessen File Objekt. Dazu laden wir uns den Node, wo die gewünschte Datei angehängt ist und suchen uns die gewünschte Datei raus. Nun können wir mittels field_file_delete die Datei löschen. So werden dann auch die entsprechenden hooks ausgeführt. Wir können natürlich zu gleich auch wieder eine neue Datei hochladen, sollten aber eventuell vorher den editierten Node speichern, da machen Module erst hier drauf reagieren.
#our FileField; only a single value field
$cck_field='field_image';
#load the node with attached file and delete the file object
$node = node_load($file_obj['nid']);
field_file_delete($node->{$cck_field}[0]);
#think of save the node before attach a new file, some
#extra modules need the delete hook
#node_save($node);
#attach new file
$file=field_file_save_file($file_obj['sourcepath']);
$node->{$cck_field}[0]=$file;
node_save($node);Menü eintragen
Das ist wohl über einfache node_save Methoden nicht möglich. Die Zuordnung eines Node zu einem Menü wird über das Menüsystem geregelt und nicht über das Nodesystem. Sobald ich aber eine Funktion finde, trage ich sie nach.
Disqus - noscript
War mir sehr hilfreich!
Das beispiel unter "Neuen Node erstellen" müsste so aussehen:
#save the node; and get the new nid
node_save($node);
$nid = $node->nid