The Entity API and the Entity System in general makes it really easy to deal with entities programatically.

For this example lets assume that we have an entity type "Vehicle" (machine name: vehicle) and a Bundle for this entity type, "Car" (machine name: car). This entity type has a property "model", and a text field "field_hello".

Creating an Entity

To create an entity of our entity type we simply call the method entity_create(), set up our properties and fields, and save the entity with the save() method.

  $entity = entity_create('vehicle', array('type' =>'car'));
  $entity->model = "Prius";
  $entity->field_hello = array(LANGUAGE_NONE => array(0 => array('value' => "Howdy Partner!")));
  $entity->save();
  //Not all entities have a save method, in which case, use entity_save()
  //entity_save('vehicle', $entity);

We can see that entity_create() takes as its parameters the entity type, and an array of values to initialize the entity. Since we are initializing the values later, I gave the function an empty array.

All entity types created with ECK have a property "type". This property lets the system know what bundle this entity is a part of. The bundle determines which fields are attached to our entity, so in our case the field "field_hello" is a field attached to the "car" bundle.

After we set up which bundle this entity is using, we can start setting up our properties and fields.

Our only property is called "model", and we can set it directly. Fields are more complicated structures than properties as they are trying to handle things like translation, multiple values, and general settings for the field all in one place. So, to try and make clear what is going on with the field, I will attempt to explain.

The first key is the language ('en', 'fr', etc). I have never dealt with multilingual sites, so for all my cases and many of yours, the constant LANGUAGE_NONE can be used. The language key points to another array, that will contain each of our fields. As you can imagine this is mainly relevant when you have multiple values for a field, but since the field_hello is not multi-value, we will be always dealing with index 0. Finally the index of each of the fields points to an array containing our actual field data. If you look at the db table for the "field_hello" (field_data_field_hello if it was created from the UI), there are two things that we can set up for the field: value, and format. Since I don't care about specifying a format for the field (the default can be used), I will just set the value and be done with it.

After that we simply call the save() method, and the entity should be saved.
Note: entity_create does not always return an object with a "save" method. (Notably, nodes, as of, at least, 7.31). If this is the case, you should use entity_save() instead.

If you go back to the list of entities for that bundle provided by ECK you should see your newly created entity there.

Entity in ECK's admin UI

Modifying an Entity

After creating the entity, we can modify it as easily as we created it. To get the previously created entity we use the function entity_load().

  $entities = entity_load('vehicle', array(3));
  $entity = $entities[3]; 

The entity_load() function takes the entity type, and an array of ids as parameters. Annoyingly enough, entity_load can only load multiple entities. The function entity_load returns an array of entities keyed by id, so to get the entity we want we have to get it out of the array.

If we print our entity with something like the dpm() function provided by the Devel module we can see that everything has been set correctly in our entity.

Entity displayed with dpm() after being loaded

To modify any of the values already on the entity simply replace the values as it was done when creating the entity, and call the save() method after the changes have been performed.

Comments

kuson’s picture

Just a comment -- to make it work for me Drupal 7 (Not sure if I have the same version), but I had to put:

$e=entity_create($entity_name,array('type'=>$bundle_name));
do the changes in $e as above and according this article such as $e->field1=array(LANGUAGE_NONE=>array(0=>array($value))); , and to save, do:
entity_save($entity_name,$e);

Maybe the reason why it did not work for me because There is a possibility the entity definition I created for the entity is not complete (i.e. it errored out 'type' not found, so I had to put in 'type' in the initial entity_create array.) Hope this helps.

zarkinfrood’s picture

I just updated,

but i when add, i get duplicate bundles and no edit feature.

not sure where the code is supposed to go

kuson’s picture

Zarkinfrood, the code I just posted is when trying to create an Entity programmatically, by ** trial-and-error**.

For the example in the article, a new instance of data with [ Entity of Vehicle, Bundle of Car ], I would create a new entity by:
1) $new_entity=entity_create('vehicle',array('type'=>'car'));
And then I would go adding the entity properties [ones with $new_entity->property=value] and fields [ones with $new_entity->field_name=array(LANGUAGE_NONE=>array(0=>array('value'=>value)));] before finally calling:
2) entity_save('vehicle',$new_entity);

Why would I do it this way? Because when I did it with $new_entity=entity_create('vehicle',array()); It errored out saying something like 'bundle not found', thus I had to fix it by putting in the array('type'=>'vehicle') in;

REQUEST: On the other hand I think the reason it errored out was because my Entity Definition is not complete (maybe a 'default' bundle type is needed?) -- so can someone share the entity_get_info() of the Entity in this example? I really would like to get the menus or links as per the images in this article (edit and delete links) somehow I am not getting it -- is there some hook I must define extra?

Thanks,

zarkinfrood’s picture

I am not sure this is the route i want to take.
GUI errors are errant, I havent tried spec'ing it all out in code yet.

However, without the flexibility that content types offer, this is rather useless to me.
I need users with no code skills to be able to add new content as an entity of any given type.

It would seem it defeats the purpose, unless i need to build the interface myself. Which still seems buggy at best. I would also need to build an advanced view in order to allow editing, sorting and retrieval of information.

kuson’s picture

To answer myself, I know why my method is not working. Having looked at the code of 'entity_create' Calling entity_create($entity_name) calls the function configured as 'creation callback' in entity_get_info($entity_name); The entity definition I used did not have such function so it failed. So please do not mind my question here, unless it is usesful to others.

To answer why I came this route, I definitely came in it looking for programmatic solutions to automatically creating entities, so it really is very different to what you are doing. Thanks anyway, and good luck.

fmizzell’s picture

If that is what you want, just use ECK. It's UI provides all the features that you are talking about. The example above is just showing how to create one entity programatically.

fmizzell’s picture

@kuson, the UI shown in the image, is provided by the module ECK (Entity Construction Kit). With ECK you can create your entity types with ease from code or from the UI, and then you can create your entities as shown in this example.

fmizzell’s picture

This sounds very odd, the example above is to create an entity, it has nothing to do with creating bundles, so I don't understand how you can get "duplicate bundles" from the example above. the "edit feature" shown in the image is provided by ECK if you create your entity types and bundles through it, not for any other occasion.

fmizzell’s picture

Your are right, if your entity has fields, which is the case int he example, you need to define the property that holds the bundle information during the creation of the entity. In this case that property is 'type', and the example now reflects that. Thanks.

johnhanley’s picture

For those using ECK, entity_load_single() is a wrapper function for loading a single entity (without the array index).

$entity = entity_load_single('vehicle', $entity_id);
// make whatever changes
$entity->save();