5

I've created a field, an instance of it, and attached it to a bundle that I've defined in hook_entity_info().

When I call up a new entity using entity_get_controller('module_content')->create($type), it doesn't have any field attached.

I've heard that I have to call field_attach_load(), but that requires an ID for the entity. I'm wondering how to fill out the data for the fields that I've attached to my bundle with a newly created instance of that bundle.

The create() method is the following one:

  /**
   * Create a default module_content.
   *
   * @param $type
   *   The machine-readable type of the module_content.
   *
   * @return
   *   A module_content object with all default fields initialized.
   */
  public function create($type = '') {
    return (object) array(
      'cid' => '',
      'type' => $type,
      'crc' => '',
      'class' => '',
      'conid' => '',
    );
  }
5

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('node_presave', $node);
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').
node_invoke($node, $op);

// Save fields.
$function = "field_attach_$op";
$function('node', $node);

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. entity_create(), entity_save(), entity_delete(), entity_view() and entity_access().
  • 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.
  • Thanks for the response and research kiamlaluno, I am trying to achieve the same result as drupal.stackexchange.com/questions/7405/… so that I can save values to my fields on a new entity. Do I have to create, then save my entity to get the fields to appear after loading it, and then save it again? – Arosboro Sep 11 '11 at 23:14
  • That is the normal workflow: You retrieve the field's values for an entity that has been saved; if the entity has not been saved, then you cannot retrieve the values of its fields. – kiamlaluno Sep 12 '11 at 14:48
  • But how can your module know which fields are available to save content into? I've queried a 3rd party server to see what data is available and created fields for that data within my module. Later I go back and store data into those fields, I have the fieldname stored, should I just save the data like this: $content->{$field_name} = array('und' => array(array('value' => $value))); – Arosboro Sep 12 '11 at 16:26
  • I updated my answer with more information about saving an entity. – kiamlaluno Sep 12 '11 at 17:32

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.