Last updated February 18, 2013. Created by Siripong on December 30, 2011.
Edited by tripper54, jacobson, chadhester, pfrenssen. Log in to edit this page.
The code below presents a simple example of the means by which you can create a node in PHP code. This example makes no use of the Entity API module.
<?php
function a_page_submit($form, &$form_state) {
global $user;
$node = new stdClass();
$node->title = "YOUR TITLE";
$node->type = "YOUR_NODE_TYPE";
node_object_prepare($node); // Sets some defaults. Invokes hook_prepare() and hook_node_prepare().
$node->language = LANGUAGE_NONE; // Or e.g. 'en' if locale is enabled
$node->uid = $user->uid;
$node->status = 1; //(1 or 0): published or not
$node->promote = 0; //(1 or 0): promoted to front page
$node->comment = 1; //2 = comments on, 1 = comments off
// Term reference (taxonomy) field
$node->field_product_tid[$node->language][]['tid'] = $form_state['values']['a taxonomy term id'];
// Entity reference field
$node->field_customer_nid[$node->language][] = array(
'target_id' => $form_state['values']['entity id'],
'target_type' => 'node',
);
// 'node' is default,
// Other possible values are "user" and "taxonomy_term"
$node = node_submit($node); // Prepare node for saving
node_save($node);
//drupal_set_message( "Node with nid " . $node->nid . " saved!\n");
$form_state['redirect'] = 'SOME WHERE';
}
?>The same result can be achieved with the contrib Entity API module but with fewer lines of code, better clarity, and less trouble from language / translation issues. (Note that there is an effort underway to move at least some of the Entity API module into core for Drupal 8.)
<?php
function my_create_a_node() {
global $user;
// entity_create replaces the procedural steps in the first example of
// creating a new object $node and setting its 'type' and uid property
$values = array(
'type' => 'YOUR_NODE_TYPE',
'uid' => $user->uid,
'status' => 1,
'comment' => 1,
'promote' => 0,
);
$entity = entity_create('node', $values);
// The entity is now created, but we have not yet simplified use of it.
// Now create an entity_metadata_wrapper around the new node entity
// to make getting and setting values easier
$ewrapper = entity_metadata_wrapper('node', $entity);
// Using the wrapper, we do not have to worry about telling Drupal
// what language we are using. The Entity API handles that for us.
$ewrapper->title->set('YOUR TITLE');
// Setting the body is a bit different from other properties or fields
// because the body can have both its complete value and its
// summary
$my_body_content = 'A bunch of text about things that interest me';
$ewrapper->body->set(array('value' => $my_body_content));
$ewrapper->body->summary->set('Things that interest me');
// Setting the value of an entity reference field only requires passing
// the entity id (e.g., nid) of the entity to which you want to refer
// The nid 15 here is just an example.
$ref_nid = 15;
// Note that the entity id (e.g., nid) must be passed as an integer not a
// string
$ewrapper->field_my_entity_ref->set(intval($ref_nid));
// Entity API cannot set date field values so the 'old' method must
// be used
$my_date = new DateTime('January 1, 2013');
$entity->field_my_date[LANGUAGE_NONE][0] = array(
'value' => date_format($my_date, 'Y-m-d'),
'timezone' => 'UTC',
'timezone_db' => 'UTC',
);
// Now just save the wrapper and the entity
// There is some suggestion that the 'true' argument is necessary to
// the entity save method to circumvent a bug in Entity API. If there is
// such a bug, it almost certainly will get fixed, so make sure to check.
$ewrapper->save(true);
entity_save('node', $entity);
}
?>Be sure to note that in the Entity API example, the functions node_object_prepare and node_submit are not necessary and should not be used. Again, the Entity API handles those tasks.
For more on using the Entity API, just search the web for "drupal entity_api". The number of articles, tutorials, and videos on the subject is a testament to the fantastic work done by fago -- the entity api maintainer.
Comments
Language of the node is not the language of the field
With the locale module enabled, I struggled to find out why when $node->language was LANGUAGE_NONE, the node was programatically created with all its field values, but when $node->language was 'en' the field values, except for title, were NULL.
At last (from a comment here) I realized that the language for a node wasn't necessarily the language for each field in the node. This revised code using field_language() worked with locale enabled and $node->language set to 'en'.
$node->language = 'en';
$field_langcode = field_language('node', $node, 'body');
$node->body[$field_langcode][0]['value'] = $body_text;
$node->body[$field_langcode][0]['summary'] = text_summary($body_text);
$node->body[$field_langcode][0]['format'] = filter_default_format();
And so on for all the other fields in the examples.
would it not be better to do
would it not be better to do this
$wrapper = entity_metadata_wrapper('node', $node);
$wrapper->field_customer_nid = $form_state['values']['entity id'];
I think this way we don't have to worry about the field language. Please correct me if I am wrong.
Thank you
Ali M
Assigning an ID, created, changed
Hello,
I'm trying to write some code to migrate from my old D5 site, I know there are modules like Migrate, but I've tried that and they don't work for me. I'm pretty fine with some code like:
for each row in node in the old site DB
create a new node in D7
a problem I have with this is that I would like to preserve the node IDs (might be useful if there are still links around that point to them. Is that possible? Is there a way to assign an ID to a new node being inserted in Drupal and bypass the node generation?
Another problem is that I cannot assign $node->created, $node->changed (ie, creation and last-update date).
Thanks in advance.
Entity ref assignment
If I'm not mistaken, shouldn't this read:
$node->field_customer_nid[$node->language][] = array('target_id' => $form_state['values']['entity id'],
'target_type' => 'node',
);
The reason I ask is that by using two calls with "[]" will create two array entries, so your assignments would be similar to this:
$node->field_customer_nid[$node->language][0]['target_id'] = $form_state['values']['entity id'];$node->field_customer_nid[$node->language][1]['target_type'] = "node";
As in:
array(0 => array('target_id' => $form_state['values']['entity id']),
1 => array('target_type' => "node")
);
__________
Regards,
Chad Hester
Wrapper Multi-Entity Ref Assignment
Is there a similar techique for entity wrappers?
I've seen how Drupal Commerce uses it's own Fields in wrappers like so:
$order_wrapper->commerce_line_items[] = $line_item;where $line_item was Commerce line Item non-wrapped object.
Lacking any examples, I see how to do it the *old* way, but it would be handy if I could do:
foreach (... something ...){
...
$node = node_load($nid);
$myOneObject_wrapper->field_multi_node_entity_reference[] = $node;
...
}
$myOneObject_wrapper->save();
Or, following (sic) the wrapper example above, maybe this is how we do it:
foreach (... something ...){
...
$myOneObject_wrapper->field_multi_node_entity_reference[]->set($nid);
...
}
$myOneObject_wrapper->save();
But the first one seems both cooler and easier to follow.
my example for user & entity reference..
if u have entity reference field in your content/node then you should use 'target_id' instead of value ..
I have a content type called 'Incentives' which are auto generated as soon as someone joins network..
//Generation 1 Basic Incentive..
$g1 = new stdClass();
$g1->type = 'incentives';
node_object_prepare($g1); // is it required??
$g1->language = LANGUAGE_NONE; // is it required??
$g1->uid = 1;
$g1->name = 'root'; // is it required??
$g1->status = 1; // 1 means published
$g1->title = 'G1'; // my title comes from autonodetitle hence..
$g1->field_distributor[LANGUAGE_NONE][0]['target_id'] = $node->uid; //**************** ['value'] will not work here..
$g1->field_joining_distributor[LANGUAGE_NONE][0]['target_id'] = $joining->uid; //**************** ['value'] will not work here..
$g1->field_amount[LANGUAGE_NONE][0]['value'] = $pv * $rate / 100;
$g1->field_tds[LANGUAGE_NONE][0]['value'] = $tds;
$g1->field_nett[LANGUAGE_NONE][0]['value'] = ($pv * $rate / 100) * (100 - $tds) / 100;
$g1->field_incentive_type[LANGUAGE_NONE][0]['target_id'] = 24;
$g1->field_description[LANGUAGE_NONE][0]['value'] = 'Generation ' . $_SESSION['generation'] . ' Basic Incentive ($rate %)';
node_save( $g1 ); //VIMP ... otherwise whatever u have done is wasted :(
is it correct approach? correct me if i m wrong..
Ananya MultiTech Private Limited.
Adding date values
I successfully updated a date value with the following:
// Update the Acceptance Date of Current Agreement.$acceptance_date = new DateTime(date('Y-m-d 00:00:00'));
$company_wrapper->field_acceptance_date->set($acceptance_date->getTimestamp());
Using Date 7.x-2.6+2-dev and Entity API 7.x-1.0.