Guide to programmatic node creation in Drupal 7

Revised 2013-07-18

 

See also Updating nodes programmatically in Drupal 7.

 

Please note that most of this was written in 2011 and while everything is still perfectly usable, there’s more ground that should be covered, such as working with i18n, media, etc. Also, you’ll probably want to use the entity metadata wrappers provided by the entity module. Consider ignoring this post and instead reading Programmatically creating nodes using Entity Wrapper and Death to Field Arrays.

 

I had to import a few thousand items from a legacy database to a Drupal 7 site and found that it was quite easy to do so programmatically. Here I’ll first show you the basic code for adding nodes and then I’ll talk about different field types, including how to add images and term references (taxonomy). If you have any questions, just ask in the comments and I’ll be happy to help!

Basic node creation – example

Put the code below in e.g. foo_create.php. Make sure it’s not accessible through the web (unless you don’t have shell access and must execute it through the browser and really know what you are doing). In other words, put it outside your Drupal directory, and then just run php foo_create.php. Note that you have to make sure that the input is valid! Test and test again, always make backups and get used to examining nodes with e.g. drush php-eval 'print_r(node_load($nid))' (see below for more about that).

If you use drush, you can skip the bootstrap part and, from your Drupal root directory, run drush scr ../foo_create.php (assuming foo_create.php is one directory above).

<?php
# Bootstrap start
define('DRUPAL_ROOT', '/path/to/drupal/root/directory');
$_SERVER['REMOTE_ADDR'] = "localhost"; // Necessary if running from command line
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
# Bootstrap end

$bodytext = "Foo m bar fnord?";
 
$node = new stdClass(); // Create a new node object
$node->type = "article"; // Or page, or whatever content type you like
node_object_prepare($node); // Set some default values
// If you update an existing node instead of creating a new one,
// comment out the three lines above and uncomment the following:
// $node = node_load($nid); // ...where $nid is the node id
 
$node->title    = "A new node sees the light of day";
$node->language = LANGUAGE_NONE; // Or e.g. 'en' if locale is enabled
 
$node->uid = 1; // UID of the author of the node; or use $node->name
 
$node->body[$node->language][0]['value']   = $bodytext;
$node->body[$node->language][0]['summary'] = text_summary($bodytext);
$node->body[$node->language][0]['format']  = 'filtered_html';
 
// I prefer using pathauto, which would override the below path
$path = 'node_created_on' . date('YmdHis');
$node->path = array('alias' => $path);
 
if($node = node_submit($node)) { // Prepare node for saving
    node_save($node);
    echo "Node with nid " . $node->nid . " saved!\n";
}
?>

$node->language is important! If you don’t have the locale module enabled, the node will not be assigned any particular language. Or rather, the language code used then is LANGUAGE_NONE, which is a constant with the value und (undefined) in Drupal. If you have locale enabled nodes can exist in more than one language, and you should specify the language code. Go to Configuration -> Regional and language -> Languages to configure languages and see what code you should use. For English, it would be en; for Swedish, it would be sv; etc.

Other things you might want to set:

  • $node->status (1 or 0): published or not
  • $node->promote (1 or 0): promoted to front page
  • $node->sticky (1 or 0): sticky at top of lists
  • $node->comment: 2 = comments open, 1 = comments closed, 0 = comments hidden

This all you need for basic node creation. I will continue with different field types. The code below should be placed before the node_submit line. All fields can be accessed with $node->field_fieldname, where fieldname is the name you find in Structure -> Content types -> Manage fields.

The best way to see how Drupal nodes are made up, and how to work with the various fields, is to simply look at the structure of an existing node. Just create a new PHP file with the first bunch of lines above (including drupal_bootstrap()) and add print_r(node_load($nid)), where $nid is the node id. Or use drush: drush php-eval 'print_r(node_load($nid))'.

Setting various field types

Text or integer field

Nothing special:

$node->field_fnordtext[$node->language][0]['value'] = "Fnord fnord fnord";

Multiple values (make sure the field is configured to allow this):

$node->field_author[$node->language][]['value'] = "Ford, Tom";
$node->field_author[$node->language][]['value'] = "Fnord, Dom";

Creation time

To set a node’s creation time, you’d think you could just set $node->created. And you can – if you don’t use node_submit() (or if you set it after node_submit()). Looking at the node_submit() function in node.module, we find this line:

$node->created = !empty($node->date) ? strtotime($node->date) : REQUEST_TIME;

Which means that node_submit() will set $node->created to the current time if $node->date doesn’t exist. So, if you want to set the creation time, you have to do something like this:

$node->date = "2009-05-27";

This also means that if you are updating a node programmatically, don’t forget to set $node->date; otherwise node_submit() will change the creation time. Or, when updating a node, simply don’t use node_submit(), since all it does is populate author and creation time. See Updating nodes programmatically in Drupal 7 for more about updating.

Date field (datetime, date, datestamp)

If you use the date module, you get three new field types – date, datetime and datestamp. (See this page to read about the differences; also check out this discussion.)

If your field is named datetest, you could do:

// For datetime
$node->field_datetest[$node->language][0][value] = "2011-05-25 10:35:58";
 
// For date
$node->field_datetest[$node->language][0][value] = "2011-05-25T10:35:58";
 
// For datestamp
$node->field_datetest[$node->language][0][value] = strtotime("2011-05-25 10:35:58");

Note that you don’t need to specify a complete date; for datetime and date you can just pad with zeros, e.g. 2011-05-00 00:00:00 (datetime), 2011-00-00T00:00:00 (date), etc. For datestamp you could just do e.g. strtotime("2011-05-25").

Important: Also note that while the exact value you specify will be stored in the database, the actual time displayed on the site might be different depending on timezone settings. When you create a new datetime/date/datestamp field, you get to choose between five different timezone handling methods. The default one is “site’s time zone”:

When entering data into the field, the data entered is assumed to be in the site’s time zone. When the data is saved to the database, it is converted to UTC.

However, if you set a date field programmatically like in the above example then no conversion takes place, so make sure you account for the field’s timezone settings. Or in other words, if you use “site’s time zone”, make sure the time is in UTC.

Boolean field

Single on/off checkbox:

$node->field_bork[$node->language][0]['value'] = 1;

Term reference (taxonomy) field

Set the term reference field tags to taxonomy term id 25 (for more than one term, just repeat the line; and note that it doesn’t matter whether the widget type is select list, check boxes/radio buttons or autocomplete):

$node->field_tags[$node->language][]['tid'] = 25;

Note: If you are trying this with the tags field in the default article content type, and have locale enabled, and have set $node->language to e.g. ‘en’, and it doesn’t seem to work: I also encountered this oddity (bug?). For some reason tags are saved to $node->field_tags[und] instead of $node->field_tags[en], while e.g. body is saved to $node->body[en] as expected. If I create a new term reference field, it works as it should. So either do that, or change the above to $node->field_tags[und][]['tid'].

 

As you can see, you need the know the taxonomy term’s id. Fortunately, there’s a Drupal function to help us with this: taxonomy_get_term_by_name(). You supply the name (“Italy”) and it returns an array of matching term objects, so you can do something like this:

if ($foo = taxonomy_get_term_by_name('Italy')) {
    $foo_keys = array_keys($foo);
    $node->field_tags[$node->language][]['tid'] = $foo_keys[0];
}

Unfortunately, you can’t specify a certain vocabulary with this function. This means that if you have the same term name in more than one vocabulary, the above code will just use whatever happens to come first. If you want to specify a certain vocabulary, say the one with id 9, you could do something like this:

$foo = taxonomy_get_term_by_name('Italy');
foreach ($foo as $term) {
    if ($term->vid == 9) {
        $node->field_tags[$node->language][]['tid'] = $term->tid;
    }
}

(One way of figuring out the vocabulary id is to run print_r(taxonomy_get_vocabularies());)

But what if you want to create new vocabulary terms for those that aren’t already in the database? You can use taxonomy_term_save(), like this:

$new_term = array(
    'vid' => 1,
    'name' => 'Fugazi',
    // You can optionally also set id of parent term, e.g. 'parent' => 25
);
$new_term = (object) $new_term;
taxonomy_term_save($new_term);

$new_term is very conveniently updated with the tid of our newly created term, which you can get with $new_term->tid.

Node references

If you use the references module for node/user references you can set a reference like this:

// 453 is the id of the referenced node
$node->field_author[$node->language][]['nid'] = 453;

This way you can also add multiple references in the same field – just repeat.

Entity field references

I haven’t had time to update this document properly (yet!) but Mark Losey wrote the following in a comment (thanks Mark!):

$node->field_my_reference[$node->language][0]['target_id'] = $entity_id;

“If you are using the product reference field in drupal commerce it’s a variation on that:”

$node->field_product_reference[$node->language][0]['product_id'] = $product_id;

Image field

Attaching an image to any given image field is easy. Create a file object, copy the file and associate the file object with the image field:

$file_path = drupal_realpath('foo.jpg');
$file = (object) array(
    'uid' => 1,
    'uri' => $file_path,
    'filemime' => file_get_mimetype($file_path),
    'status' => 1,
);
// You can specify a subdirectory, e.g. public://foo/
$file = file_copy($file, 'public://');
$node->field_image[$node->language][0] = (array) $file;

Pathauto URL aliases

Joakim Hedlund comments (thanks!) that you can turn off the automatic path aliases generated by pathauto with the following:

$node->path['pathauto'] = FALSE;

Note that you have to turn pathauto off like this if you don’t want it to overwrite custom aliases. See How does Pathauto determine if the ‘Automatic URL alias’ checkbox should be checked or not? for more information.

86 comments

      • You are great. I just found it myself ;). But that is great code.

        another feedback: I run the script via the browse as I have no access to the command line. After completion i get a blank sreen, which is just fine for me, but the first time it was confussing: (Did it work? No? It DID!)

        • It depends on how the timezone is configured for that particular field. When you create a new date field you can choose between five different time zone handling methods (you can’t change it afterwards). They are explained here. The default one, site’s timezone, will convert the time you enter in a form to UTC. For me, if I enter 2010-05-25 09:25:00 on the normal add content page, it will actually be stored as 2010-05-25 07:25:00 in the database. But when I add a node programmatically, this conversion doesn’t take place, so I have to account for it.

          Or in other words: if the time zone handling is “site’s time zone”, and you set the field programmatically, make sure you set the UTC time :) Good call, this is very important to mention; I’ll update the post.

          And the script should definitely give some output, I’ll fix that too. I’ll add a more complete example script later.

    • Definitely. I just tested on my old laptop and it took 1 minute 25 seconds to create 10 000 nodes using the script above. Just be careful and make sure the input is exactly the way you want it.

  • Hi, excellent tutorial, this is undoubtedly help me! The taxonomy stuff especially. I’m writing a module to import ~25,000 records several times a day to populate a TV Program guide. I’ll flesh this out to include an update structure as well, for now this provides an excellent starting point.

    Thanks for taking the time!!!

  • Thank you, this is a great resource!

    Beware of the syntax error (should be a ==) in if($term->vid = 9)

    You’ll have a lot of visits, here, why don’t consider using Flattr.com?

  • Meanwhile, just a contribution… for EMAIL and URL fields (via the email and link module), you need to set [’email’] and [‘url’] instead of [‘value’]. Otherwise your field will (silently) not filled up.

    • Cheers for that. I’m thinking maybe I should put together a quick reference that also covers some of these popular modules.

  • Hi, I cam back to post a few things that might help people (thanks again, this page has been a great help).

    A couple of things I ran into that you might be curious about, and may help others. It turns out that while Pathauto does indeed overwrite the path info you created, that path is saved with the node. If folks are using Pathauto they should just omit that bit, the correct path will be created and saved with the node.

    Inserting keyword tags from a delimited list was a bit of a hassle so I came up with a different method. I check for existing tags, inserted new ones then build an array of tid’s to add them to the node object. I’m a newbie so I know there are better ways to do it, but this might be helpful for someone. Here it is:

    //Insert terms
    if(strlen($term_list)) {
     
    //Set variables
    $vid = 9;
    $insert = array();
     
    //My terms are commma separated - explode the new terms into array
    $data = explode(",", $term_list);
    foreach($data AS $id => $row) {
     
    //Get the term object
    $term = taxonomy_get_term_by_name($row);
    //Check for term, if it doesn't exist add it
    if ($term == array()) {
    //Make a new class to hold the term
    $taxonomy = new stdClass();
    $taxonomy->name = $row;
    $taxonomy->vid = $vid;
    $taxonomy->format = 'filtered_html';
    taxonomy_term_save($taxonomy);
    }
     
    //All new terms are saved, now get the correct tid from the vid and term
    $tid = db_query("SELECT tid FROM {taxonomy_term_data} WHERE vid = :vid AND name = :term", array(':vid' => $vid, ':term' => $row))->fetchField();
    //Build an array of the tid's
    $insert[] = $tid;
    }
     
    //Now add the keywords from the tid array to the node object
    foreach($insert as $tid) {
    $node->field_tags[$node->language][]['tid'] = $tid;
    }
     
    //End term Loop
    }
    • Thanks Mark! When I have the time I’ll expand and revise the guide a bit. (But first: redesign and move to a different platform!)

  • Thankyou, thankyou, thankyou! Been struggling with this all day. Thought there was something fundamentally wrong with my node creation but it was just 
    $node->body[$node->language][0][‘value’] that I needed. What’s that zero for? Revision number?Are you familiar with the node_submit function? I think it’s pretty much the same as node_object_prepare but I’m not sure why you’d use one over the other?Another ( kind of ) related issue. Where do you stand on making a form ( using form API ) to create nodes vs using the administrator add content form. This has a lot of stuff that I wouldn’t want my users to be troubled with. I understand I can edit this using a form alter hook but it seems like more work and a messier solution. However, there was somebody on the Drupal site ( can’t find it now ) who seemed to be implying that it would be crazy to create my own form for node creation. Is there security issues or other considerations I’m unaware of?

    I’m still very new to this. You’ve saved me a lot of time. Thanks again.

    • Glad I could help! The zero indicates the value number. If a field only has one value, it’s 0, but you could have a multi-value field (see example under ”
      Text or integer field”) – then it would be 0, 1, etc.

      node_submit: “Prepare node for saving by populating author and creation date.” It just makes sure the node gets a valid $node->uid, sets $node->created, and sets $node->validated to true. My script above is really only a quick’n’dirty thing – not saying it’s best practice; I have to look into that. :) Anyway, many of these functions are very small and simple – check the Drupal API reference to see exactly what they do.

      I’m not sure I fully understand your question about making your own form or not – can you give me an example of what you want to achieve (what you want your users to be able to do)?

      • OK. I just want users to be able to create a node of a custom content type. I could just send them to the add content page for that content type and providing I give them permissions, they can add the node there. However, I wouldn’t really want a standard user to be confronted with a lot of what comes up on this page. At a quick glance I see there’s text formats, menu settings, revision info etc. I assume there are ways and means to manipulate what is shown here to the user but I imagine that might be more work and messier than just creating a form from scratch. So what I am doing is creating a form using the form API and taking input out of the form to create a node. This seems to me a better way of doing things, but I have come across comments from people suggesting this really isn’t the done thing. Just wondered if I’m missing something fundamental.

        • Ah, I see. Don’t mess with custom forms for that. I think the best and easiest way would be to add a new role for these users and set the permissions so that they don’t see more than necessary. Example: I go to People -> Permissions -> Roles and add a new role, and only set “Foobar: Create new content” (nothing else!). I then add a new user with the “authenticated user” role and the role I just created. Result: when logging in, this user won’t get any of the admin stuff, just a new menu entry – “Add content” with a link to “Foobar” under it. That link brings up the Add content page for that content type _without_ menu settings, revisions, etc. I think that’s what you want?

          (If you still see text formats, it’s because it’s enabled for “authenticated user”; just change the role permissions.)

  • How do I do this for a multisite installation? I mean how can I tell the code which site to create the node in? I have the same code base but different databases for each of the sites

    • Sorry for the late reply. I haven’t yet verified this, but AFAIK this worked with Drupal 6, so it might very well work with 7 too. Before the drupal_bootstrap call, try adding:
      $_SERVER[‘HTTP_HOST’] = ‘oneofyoursites.com’;

      • Another way, which may apply only to the nonstandard way I’ve got things laid out:

        One of my test installations has multisite set up so that the subsites are accessed via URLs like “abc.example.com/drupal”.  I puzzled over how to get the node dump with “print_r(node_load($nid))” noted above to work.  It wouldn’t, no matter how many variations of “_SERVER” variables I tried.
        Looking at the bootstrap.inc code, I discovered the function “drupal_override_server_variables”.  Following the directions in the comments to that function, I called it before calling drupal_bootstrap, like so: 
        drupal_override_server_variables(array(‘url’ => ‘http://abc.example.com/drupal’)),
        and all was well.

  • Based partly on content in this article and partly on content in another article, I’m doing the following:

    [code]
    function _addTermToUser($orderUser, $term) {
        $edit = clone $orderUser;
        $edit->field_tags[LANGUAGE_NONE][][‘tid’] = $term->tid;
          error_log(“edited user-data:”);
          error_log(print_r($edit, true));
        user_save($orderUser, (array)$edit);
        error_log(“persisted updated user; updated user:”);
        $updatedUser = user_load($orderUser->uid);
          error_log(print_r($updatedUser, true));
    }
    [/code]

    In my log, I see under “edited user-data:” the following:

         [rdf_mapping] => Array
             (
                [rdftype] => Array
                    (
                        [0] => sioc:UserAccount
                     )
                [name] => Array
                    (
                         [predicates] => Array
                           (
                                 [0] => foaf:name
                             )
                     )
                 [homepage] => Array
                     (
                         [predicates] => Array
                             (
                                 [0] => foaf:page
                
     > Array
                             (
                                 [tid] => 18
                             )
                     )
             )

    Also, after this, I need to reset the password of the user I’m testing as.  That is, by then, I’ve been logged out.  And it seems as if the user-data in the DB is getting corrupted by what I’m doing.

    The ‘tid’ seems  to be getting set in the rdf_mapping  of ‘homepage’.

    And all I get in the browser is this vague error-message:

    “We’re sorry, but due to a technical problem, your order could not be processed. Please try placing the order again later.”

    And nothing of interest, so far as I can see, in the watchdog messages either.

    I’m trying to set a taxonomy-term on a user, only once having received a callback from Authorize.net via Ubercart.  I believe this is something I need to do in custom code as I’m attempting it.

    Is there a better way?

    • and, by the way, I’m attempting the above in a custom Rules Action, in case that’s relevant;  I understand, in such cases, if you update any of the params passed into the Action-function, one is to just rely on the metadata of that param to have the Rules Engine update that param.  However, in this case, I’m getting the Ubercart Order and the current User, and the current User is anonymous, because that’s the user that’s current during the processing of the callback from Authorize.net.  So, instead, I load the user that’s associated with the Order, and that’s the User I’m trying to update; so, I do that explicitly in my Action-function, rather than expecting the Rules engine to somehow do it.

  • Many thanks for this info, it was very helpful for creating 400+ nodes based on text file. D7 rules for flexibility in things like that.

  • Hi, master.

    I have some problem: I want to store my own data creation.
    I followed your tips, but…

    Only the first register (node) store its correct date creation.
    Others (second, third ec.) are using request_time.

    My code is almost identical to your (there is a loop, i won’t show it):

      $node = new stdClass();
      $node->type = ‘efemeride’;
     
      node_object_prepare($node);

     
      $node->language  = LANGUAGE_NONE;
      $node->uid = 1;
      $node->title = utf8_encode($titulo);
      $node->field_origem[$node->language][0][‘value’] = utf8_encode($db_field[‘origem’]);
      $node->field_link_efem[$node->language][0][‘value’] = utf8_encode($db_field[‘link’]);
      $node->field_tipo_efem[$node->language][][‘tid’] = $tipo;
      $node->date    = strtotime($db_field[‘data’]);
      $node->created    = strtotime($db_field[‘data’]);
      kpr($node);

      if($node = node_submit($node)) { // Prepare node for saving
         node_save($node);
         echo “Node with nid ” . $node->nid . ” saved com data ” . $db_field[‘data’] . “” . $titulo;
       } 

     

  • Really a good point of start!
    Only one thing…
    I’m trying to crete an english node but it seems not so easy… it seems node_save always look for ‘und’.
    The only way I found is to set  $node->language=’en’ in the node  but to keep ‘und’ in the fields creation. This way it woks but in the database I found ‘und’ in the fields table.73 all mt

  • Thank you for an excellent tutorial.  I am confused as to why you are using node_submit. Why not just call node save? What is the difference between the two?

    •  Apologies for the late reply. Copied from before: “node_submit: “Prepare node for saving by populating author and creation
      date.” It just makes sure the node gets a valid $node->uid, sets
      $node->created, and sets $node->validated to true.”

  • Hi, great tutorial. But what i try to achieve is to create the node with custom $nid.  I am not sure if that is possible? That way i will have an unique id – same for Drupal and for external database which i am syncing.

    For example, i want to create a new node with all parramterers mentioned but with custom id, lets say, 
    2754.

    I tried to specify $node->nid =2754; , but with no luck

    Other way i can think of is to add a custom field with needed remote ID, but i thought it would be much simpler this way.

  • One more question. I have situation where i conditionally create new nodes if external DB query tells me so, and update fields if node already exists. But i have middle solution where Node exists, but field does not exist! What is the approach – not to update field, but to create one programatically ? Thanks again!

    • Do you mean automatically create a totally new field in the node type’s structure (like if you went to Structure -> Content types -> [name of content type] and added a new field)? I haven’t looked into this but it’s certainly doable, though it feels risky. But maybe you solved it by now :)

  • I’m trying to add a value to a field which has been programattically created.

    So I have

    $node->{$variable}[$node->language][0][‘value’] = “content to be inserted”;

    but it doesn’t seem to be doing the right thing. Should that work?

    The ‘machine field name’ of the field is correct, and my $var is ‘field_’ plus the machine name of a field which definitely exists.

    Any ideas?

    • If $variable is exactly the machine name – e.g. “field_mycustomfield”, that should work. Make sure you’ve set the right $node->type, and that $variable really is correct. Are you getting any errors at all? If $variable is wrong (i.e. a non-existing field), the sample code would silently ignore that. If you try to save, say, text to an integer field, a PDOException would be thrown.

      •  I have checked and double-checked all this stuff and I think it’s right. Just to be clear, you said

        ‘If $variable is exactly the machine name – e.g. “field_mycustomfield”, that should work.’

        my field’s machine name is say “foo_bar” and my field name that I’m using is “field_foo_bar”, so not exactly the machine name, the machine name with ‘field_’ prepended.

        Any chance I can add some code to get an error on adding the value to the field, or when saving the node?

      • I have got it working in a simple sandbox page based on your very helpful suggestion above: “Just create a new PHP file with the first bunch of lines above (including drupal_bootstrap)” which is the single most helpful thing I have learned in my short time with Drupal. I feel like I’m through the looking glass!

        • Regarding machine name: field_ should only be prepended to custom fields. Or rather: your $variable it should be exactly what you see under “Machine name” if you go to Structure->Content types and then “manage fields” for the content type you’re working with.

          So for e.g. the node module element Title (which every content type has), the machine name is “title”, and so $variable should be “title”. Same with Body. But for any fields that you’ve added yourself, you’ll see that the machine name has “field_” prepended.

          However, by the sound of it, you’ve succeeded! Glad you found it helpful. I think it really is the best way to learn – set up a development environment, write small scripts, run them them from the command line, inspect the output and the nodes created (with print_r/node_load – no need for a browser!), repeat.

          And just wait ’til you start using drush, if you haven’t already! Makes Drupal development so much more pleasant (and quicker).

    • John, make sure that $node->language is set to LANGUAGE_NONE or it will not work. Using a specific language in the field API inside a node object AFAIK works only when you are using entity translation. If not, you should always sent the language to ‘und’ using LANGUAGE_NONE.

  • I’m able to create nodes with the above code. But the body is not getting added.
    Like the node table is getting its rows increased by creating new nodes. but the ‘field_data_body ‘ table’s rows are not getting increased. Please help

  • Thx a lot ! This will help me a lot. We have a installation with the domain access modul and about 20 subdomains. The Devel Generate Modue does not provide is with enough functionality to generate nodes by users and domains. So this tutorial will fit perfectly !

  • Just some note with the Image field example. You create an array that you cast to object, then cast back to array again. Isn’t it more effective to create an array, and only cast it to object when you call file_copy()?

  • Great resource, I love it!

    As an added note for anyone wanting to turn off automatic URL aliases (pathauto) you can set the following:
    $node->path['pathauto'] = FALSE;

      • Additionally, if you have the Workbench module and use moderation and reviewing of nodes this may come in handy as well, if you want to skip the manual publishing of your updated content:

        $node->workbench_moderation['updating_live_revision'] = 1;

        However, since you’ll be updated the existing revision rather than creating a new one this should be used with caution; if you screw something up you wont have a previous revision to roll back to. You’ve been warned! :)

  • This is just a fantastic overview of programmatic field setting. I just kept it up for the entire time I worked on this particular project. THANKS.

    I saw someone ask about entity field reference.

    $node->field_my_reference[$node->language][0][‘target_id’] = $entity_id;

    If you are using the product reference field in drupal commerce it’s a variation on that:

    $node->field_product_reference[$node->language][0][‘product_id’] = $product_id;

    Thanks again for this organized well-thought out documentation.

    • Thanks Mark! Creating a new, more comprehensive overview is on my ~/TODO list for later this year. Stay tuned!

  • Thanx for the great tutorial!!

    Little notice concerning the value for $node->comment:
    In the description for the comment column in the node table I found:
    “Whether comments are allowed on this node: 0 = no, 1 = closed (read only), 2 = open (read/write).”

    Kind regards

  • Here is the code that I am using. IT seems to be correct. The node gets created and the title is added. But for the life of me I can not get it to add info to one of the fields. I have looked at a node that i manually created that has all the fields created and verified that I am using the right names and its setup in the same format but they just will not get added when creating my node. Could someone please help me figure out what I could be doing wrong?


    type = 'store_location';
    node_object_prepare($node);

    $node->title = "TEST TITLE"; //$business_info['BusinessName'];
    $node->language = LANGUAGE_NONE;
    $node->uid = $user->uid;
    $node->status = 1;
    $node->revision = FALSE;
    $node->comment = 0;
    $node->promote = 0;
    $node->sticky = 0;
    $node->log = NULL;
    $node->created = time() - (rand( 1,240) * 60);

    $node->gsl_props_phone[$node->language][0]['value'] = "444.4444"; //$business_info['BusinessWorkPhone'];
    $node->gsl_props_phone[$node->language][0]['format'] = NULL;
    $node->gsl_props_phone[$node->language][0]['safe_value'] = "555.555"; //$business_info['BusinessWorkPhone'];

    $node->field_employees_full_time[$node->language][0]['value'] = "456"; //$business_info['BusinessEmployeesFT'];

    $node->field_work_phone_extension[$node->language][0]['value'] =
    "ADDTHIS"; //$business_info['BusinessWorkPhoneExt'];
    $node->field_mobile_phone[$node->language][0]['value'] = "ADDTHIS"; //$business_info['BusinessCellPhone'];

    $node = node_submit($node);
    node_save($node);
    ?>

  • dude, nice tutorial. thanks for sharing.

    two questions:

    1 – what about big, like really big sets of nodes to be checked and updated? my scripts are just dying at some point when iterating over thousands of thousands of nodes, so i have to slice the array and run small packets, which until now is annoying. is there a drupal built in mechanism to run updates and connect them to cron without having to implement that by oneself?

    2 – where actually to run administrative throw-away scripts? im having some thousands of nodes which are invalid due to users misbehavior. im correcting them with a script which is supposed to run only once. i dont like that i have to create a module and jump into a hook to get that done. isnt there a spot where i can put my scripts with the full access to the system? just putting a script as mentioned somewhere into the wild in my system doesnt work cuz theres not always access to node_load and node_save e.g…

  • First of all thank you very much for your teachings, it was just what I needed for my site.

    Secondly I have a question:

    I was able to create nodes programmatically in my site modifying thhe tutorial, the problem is that the tags are generated by obtaining information from a json file which is then decoded for in a php array and it may happen that the same tag is repeated more than once. When I created the nodes through the administration interface of drupal, this was not a problem because even if i entered two identical tags, in the end it appeared only one. But using the system described in this guide at the end tags are repeated. What is the cause?

    Every single tag is created as follow: http://pastebin.com/M6G8bTYz

    Thanks!

  • Escribiré en español esperando que alguien que sepa traducir me ayude a presentar este comentario en ambos idiomas.
    Mi instalación de Drupal está en español y leí este artículo para poder importar, usando un programa, “partes de nodos” existentes de otra instalación.
    Para crear un nodo usé la instrucción:
    $node->language = 'es';

    Pero si al agregar contenido usaba las lineas:

    $node->body[$node->language][0]['value'] = $bodytext;
    $node->body[$node->language][0]['summary'] = text_summary($bodytext);
    $node->body[$node->language][0]['format'] = 'filtered_html';

    NO puedo visualizar ningún contenido. Así que las cambié por:

    $node->body[LANGUAGE_NONE][0]['value'] = $bodytext;
    $node->body[LANGUAGE_NONE][0]['summary'] = text_summary($bodytext);
    $node->body[LANGUAGE_NONE][0]['format'] = 'filtered_html';

    y parece que funcionan bien.

Leave a Reply

Your email address will not be published.