One of the most power features about Drupal is it's API. Sometimes it's necessary to manually create content such as a story or page (aka: nodes) using a PHP program/script. The current documentation about this is very limited or hard to follow. So I provide complete instructions here. They have been tested in Drupal 5.x but they should also work in version 6.x without much modification.
Consider the following example, lets create a new "Page". Set-up your PHP script as follows:
<?php require_once './includes/bootstrap.inc';drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);$new_page_node = array('type' => 'page');?>
The first two lines are required to initialize the Drupal system, function, and variables. The 3rd line creates a node object (an associative array). The index "type" tells Drupal the Content Type that we want to create. We use the internal system name of the content type here. You can substitute any content types that exists in your Drupal site, including ones you created with the CCK module.
For example, if I have a custom type called "Help File", and it's internal system name is "helpfile" then I would use the following code:
<?php...$new_page_node = array('type' => 'helpfile');?>
The next step is to fill out the fields. The fields are contained in an array variable. So lets say we wanted to specify the Page Title:
<?php$values = array();$values['title'] = "Welcome to Unibia";?>
The array variable name does not matter, I just chose that for no reason at all. The key piece here is the array index, this has to match up to the field you want to populate. Page nodes are simple. The only fields you need to worry about are "title" and "body". Their are two other important fields , "uid" is the user ID that this node is created as, and "name" is the username that this node is created as. To keep things simple, we will just use the admin user with ID 1. (Your admin user may have a different name).
<?php$values['title'] = "Welcome to Unibia";$values['body'] = "This is the content that appears on the page";$values['uid'] = 1;$values['name'] = "admin";$values['status'] = 1;?>
The "status" field with a value of "1" marks the new node as "Published".
TIP: If you've created a custom content type with custom fields using the CCK module, just include the additional fields in your code. However, bear in mind that CCK fields may need to be in the form of an array of arrays. For example:
<?php$values['field_address'] = array(array('street1' => '132 N Main St.', 'city' => 'Naples', 'state' => 'FL', 'zip' => '34100', 'country' => 'US'));$values['field_phone_number'] = array(array('value' => '239-123-1111'));?>
It's possible to take a look at the node/field structure by loading an existing node and printing out the array structure using PHP's print_r() function. First get the node ID of an existing node, just look at the link to and existing page. The end of the URL looks something like this: "node/2". The ID would be "2".
Let us load the node into an associative array by using the built in Drupal "node_load()" function:
<?php$existing_pagenode = node_load(2);print_r($existing_pagenode);?>
It's relatively simple, the function takes one argument, that is the node ID. It returns the node data structure. Then we just print out the array structure to our web browser. You'll have to look at the page source so it's better formatted. It should look similar to this:
[nid] => 2
[vid] => 2
[type] => page
[status] => 1
[created] => 1226008263
[changed] => 1226010433
[comment] => 0
You may ask yourself what "vid" stands for. Pay no mind to it for now, it simply refers to the revision number, usually the same as the node id.
Now for the last step, to actually save the node to the Drupal DB. It's as simple as one line.
<?php ...$result = drupal_execute('page_node_form', $values, $new_page_node);...?>
- The first parameter is always in the following format, "
_node_form". Tells Drupal to load the form for the node you are creating.
- The second parameter is the array containing the fields and values.
- The last parameter is the node variable
Lets say you want to categorize your new page, that is assign it a term/vocabulary that you created using the taxonomy module. It's not as difficult as you would believe. You do this part after you have created your node. The drupal_execute() function returns your node ID in the form of "node/XX" where XX is your node ID.
The PHP code to assign a term to a node is as follows:
<?php...$result = drupal_execute('page_node_form', $values, $new_page_node); //From above//Extract the node ID from the result string$nid = str_replace("node/", "", $result);//Get the term ID by name$term = taxonomy_get_term_by_name('Legacy');//Assign it to the nodetaxonomy_node_save($nid, $term);?>
That's all their is to it! However, lets say we want to update the newly submitted node. Just load it with the node_load() function and make your changes. The following example is done with a custom created Content Type using the CCK Module. You can apply the same concept by omitting the extra fields.
<?php$contact_node = node_load(32);$values['title'] = 'New Title.';$values['body'] = $node->body;$values['status'] = 1;$values['field_address'] = $node->field_address; //CCK Field$values['field_email'] = $node->field_email; //CCK Field$values['field_fax'] = $node->field_fax; //CCK Field$values['field_phone_number'] = $node->field_phone_number; //CCK Field$result = drupal_execute('contact_node_form', $values, $contact_node);?>
When you have required fields (with CCK), you need to copy the existing values. Most of the time, you can omit the fields that don't need updating.
Their is another item worth mentioning which seems to also lack proper documentation. That is how to properly build the array for a CCK node reference field. It's very simple, but the lack of documentation can frustrate you. The example below assigns a node reference field named "mynode_reference" to the node with and id of 30:
<?php$values['field_mynode_reference'] = array('nids' => '30');?>
Once thing to add, their appears to be an issue in Drupal which prevents Drupal from properly assigning a node's author. To work around this issue, do insert the following code before executing "drupal_execute" (replace "uid" with the user id of the user you want to appear as the author).
<?php global $user; $user = user_load(array(uid => 1));?>
The above will tell Drupal to create nodes as the specified user. In this example, it's the admin user.