5

I'm using Entity API to work with some entities but I cannot figure out how to create a new entity with its fields attached. I created a bundle and added some fields to that bundle. I'm looking to do this:

$a = entity_create(...);

return an array:

isNew => TRUE,
title => '',
attachedField1 => '',
attachedField2 => '',
etc...

I'd then like to be able to simply update the values and then entity_save() them:

isNew => TRUE,
title => 'Title of my entity',
attachedField1 => 'data for attached field 1',
attachedField2 => 'data for attached field 2',
etc...

Is this doable? If so, how? I'm having a tough time working with entities.

Here's my entity info:

  $return['k_profile'] = array(
      'label' => t('Profile'),
      'entity class' => 'Entity',
      'controller class' => 'EntityAPIController',
      'base table' => 'k_profile',
      'fieldable' => TRUE,
      'entity keys' => array(
        'id' => 'pid',
        'bundle' => 'type',
        ),
      'bundles' => array(), //added later in hook_entity_info_alter()
      'bundle keys' => array(
        'bundle' => 'type',
        ),
      'label callback' => 'entity_class_label',
      'uri callback' => 'entity_class_uri',
      'access callback' => TRUE,
      'module' => 'k_profile',
    );
4

Here's some code that creates a product programmatically, including fields and properties.

/**
 * Create a product programmatically.
 *
 * This is stolen shamelessly from commerce_bpc. However, I'm not comfortable
 * with the field saving using form api. Seems quite odd.
 *
 * @param $product_type
 *   (string) The name of the product type for which products should be created.
 * @param $values
 *   Keyed array with
 *   - 'price' => actual amount owed on this installment; decimal text like '1.50'
 *   - 'amount_paid' => price amount already paid as a decimal text like '1.50';
 *   - 'original_order' => order id of the original order
 *   - 'original_line_item' => line item id of original line item
 *   - 'original_product => product id of the original product from which the
 *     new product is being created.
 * @param $extras
 *   An array for the values of  'extra fields' defined for the product type
 *   entity, or patterns for these. Recognized keys are:
 *   - status
 *   - uid
 *   - sku
 *   - title
 *   Note that the values do NOT come in the form of complex arrays (as they
 *   are not translatable, and can only have single values).
 * @return
 *   The ID of the created product.
 */
function commerce_installments_create_product($product_type, $values, $extras) {
  $form_state = array();
  $form_state['values'] = $values;
  $form = array();
  $form['#parents'] = array();

  // Generate a new product object
  $new_product = commerce_product_new($product_type);

  $new_product->status = $extras['status'];
  $new_product->uid = $extras['uid'];

  $new_product->sku = $extras['sku'];
  $new_product->title = $extras['title'];
  $new_product->created = $new_product->changed = time();

  // field_original_order[und][0][target_id]
  $order = array(LANGUAGE_NONE => array(0 => array('target_id' => $values['original_order'])));
  $form_state['values']['field_original_order'] = $order;

  // field_original_line_item[und][0][target_id]
  $line_item = array(LANGUAGE_NONE => array(0 => array('target_id' => $values['original_line_item'])));
  $form_state['values']['field_original_line_item'] = $line_item;

  $product = array(LANGUAGE_NONE => array(0 => array('target_id' => $values['original_product'])));
  $form_state['values']['field_original_product'] = $product;

  //commerce_price[und][0][amount]
  $price = array(LANGUAGE_NONE => array(0 => array(
    'amount' => $values['price'],
    'currency_code' => commerce_default_currency(),
  )));
  $form_state['values']['commerce_price'] = $price;

  // field_due_date[und][0][value][date]
  $due_date = array(LANGUAGE_NONE => array(0 => array('date' => $values['due_date'])));
  $form_state['values']['field_due_date'] = $due_date;

  // Notify field widgets to save their field data
  field_attach_submit('commerce_product', $new_product, $form, $form_state);

  commerce_product_save($new_product);
  return $new_product->product_id;
}
  • Shouldn't you take care of the language of the field instead of putting LANGUAGE_NONE ? – tostinni Sep 21 '11 at 6:32
  • Yes - these fields happen not to be translatable. A translatable field would need a little more work. – rfay Sep 21 '11 at 12:43
  • In Drupal Commerce you'll find lots of examples of entities like line items and orders being created programmatically. – rfay Sep 21 '11 at 12:44
  • I like this answer better solved my doubt +1 – Necronet Feb 8 '12 at 22:07
2

If I'm not mistaken the Node Example in the Examples Project does just what you want.

  • node example shows how to create several field instances, but it does not show how the node gets loaded and it's fields filled out programatically. I believe this is what user1750 is after. – Arosboro Sep 11 '11 at 21:20
2

For those who created their entity with eck, an explanation is here : http://drupal.org/node/1377614

simply put, it should be enough to write

$e = entity_create('type',array());
$e->field_a = ...;
$e->save();
0

Model Entities is what you need. It is a a starter kit for entities. You should read the module description and the README file before installing this.

It comes with everything you need so you can actually use it as it is. You can add fields, manage displays and everything else.

0

With the contrib Entity API module, use entity_create, for example:

try {
  $entity_type = 'entity_type';
  $entity = entity_create($entity_type, array('type' => 'type_or_bundle')); 
  $wrapper = entity_metadata_wrapper($entity_type, $entity);
  $wrapper->type = 'some_type'; // When entity type has bundles, you can specify a type.
  $wrapper->isNew = TRUE;
  $wrapper->title = '';
  $wrapper->attachedField1 = '';
  $wrapper->attachedField2 = '';
  $wrapper->some_other_property = 'foo';
  $wrapper->field_some_field = 'bar';
  $wrapper->field_multiple_field = array('foo', 'bar');
  $wrapper->save();
}
catch (EntityMetadataWrapperException $e) {
  watchdog_exception('my_module', $e); 
}

See also: Drupal 7 - Create a Node in Code page which provides the following example:

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();
}

To create a new entity using Drupal core entity - try Examples module, using contrib Entity API - try Model Entities module.

For more examples, search on GitHub.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.