Fields are attached to instances of entities; that is the reason why
field_attach_load() requires an entity ID.
Suppose you want to attach a field to a node; without knowing which node is, how do you know what value to use for the field?
DrupalEntityControllerInterface, the interface that all the entity controllers implement, doesn't define the
DrupalEntityControllerInterface::create() method, but it defines the DrupalEntityControllerInterface::load() method, that is implemented by DrupalDefaultEntityController in DrupalDefaultEntityController::load(), which in turn calls DrupalDefaultEntityController::attachLoad(). The documentation for this method contains the following paragraph:
Attaches data to entities upon loading. This will attach fields, if the entity is fieldable. It calls hook_entity_load() for modules which need to add data to all entities. It also calls
hook_TYPE_load() on the loaded entities. For example hook_node_load() or hook_user_load(). If your
hook_TYPE_load() expects special parameters apart from the queried entities, you can set
$this->hookLoadArguments prior to calling the method. See NodeController::attachLoad() for an example.
If your entity controller extends
DrupalDefaultEntityController, then the code for attaching fields to the entity instance is already implemented in that class, and you don't need to write extra code.
For the code to use when saving the entity, you can take node_save() as example. You will notice that the function contains the following code:
// Let modules modify the node before it is saved to the database.
module_invoke_all('entity_presave', $node, 'node');
// Call the node specific callback (if any). This can be
// node_invoke($node, 'insert') or
// node_invoke($node, 'update').
// Save fields.
$function = "field_attach_$op";
module_invoke_all('node_' . $op, $node);
module_invoke_all('entity_' . $op, $node, 'node');
The code calls field_attach_insert(), or field_attach_update(); those functions are responsible for saving the fields in the appropriate database tables.
The default implementation of an entity controller doesn't have support for saving an entity; there is a third-party module that implement the support for saving entities: the Entity API module.
- The module provides API functions allowing modules to create, save, delete, view or to determine access for any entity, i.e.
- The entity API introduces a unique place for metadata about entity relationships and entity properties:
hook_entity_property_info(). This information about entity properties contains the data type and callbacks for how to get and set the data of a property. Modules may rely on this information in order to support any entity property, e.g. Rules and the Search API build upon that.
- Furthermore the module provides data wrappers that make use of the available information to provide a simple and unified access to entities and their properties. For usage examples have a look at the README or the provided tests.
- Beside that, the module helps you defining a new entity type. For that, it provides an entity controller, which implements full CRUD functionality for your entities. Optionally, entities may be created based on classes derived from the provided Entity class.