开发者

Dynamically add a "Field Collection" in Drupal 7 by script?

开发者 https://www.devze.com 2023-03-10 17:48 出处:网络
I want to add a \"field collection\" dynamically. But开发者_开发知识库 I\'m not familiar with Field API or Entity API. New Entity API in Drupal is very poorly documented.

I want to add a "field collection" dynamically. But开发者_开发知识库 I'm not familiar with Field API or Entity API. New Entity API in Drupal is very poorly documented.

Here is my code, until now:

$node = node_load(1);
$field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_book_text'));
$field_collection_item->setHostEntity('node', $node);

// Adding fields to field_collection

$field_collection_item.save();

"Field Collection" module use function "entity_form_submit_build_entity" which I cannot use because there is no form in my case.

I would appreciate if you can tell me how can I add fields?


Based on some code I used in a live project:

// Create and save research field collection for node.
$field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_article_references'));
$field_collection_item->setHostEntity('node', $node);
$field_collection_item->field_reference_text[$node->language][]['value'] = 'ABCD';          
$field_collection_item->field_reference_link[$node->language][]['value'] = 'link-val';
$field_collection_item->field_reference_order[$node->language][]['value'] = 1;
$field_collection_item->save();


Anyone using the above code samples should consider using the entity_metadata_wrapper function from the Entity API to set the values of fields on an entity instead of using an assignment operator. So, the code from the "more complete example" above would be:

  if ($node->field_collection[LANGUAGE_NONE][0]) {
    // update
    $fc_item = reset(entity_load('field_collection_item', array($node->field_collection[LANGUAGE_NONE][0]['value'])));
  }
  else {
    // create
    $fc_item = entity_create('field_collection_item', array('field_name' => 'field_collection'));
    $fc_item->setHostEntity('node', $node);
  }

  // Use the Entity API to "wrap" the field collection entity and make CRUD on the
  // entity easier
  $fc_wrapper = entity_metadata_wrapper('field_collection_item', $fc_item);

  // ... set some values ...
  $fc_wrapper->field_terms->set('lars-schroeter.com');

  // save the wrapper and the node
  // Note that the "true" is required due to a bug as of this time
  $fc_wrapper->save(true);

  node_save($node);


A more complete example:

  if ($node->field_collection[LANGUAGE_NONE][0]) {
    // update
    $fc_item = reset(entity_load('field_collection_item', array($node->field_collection[LANGUAGE_NONE][0]['value'])));
  }
  else {
    // create
    $fc_item = entity_create('field_collection_item', array('field_name' => 'field_collection'));
    $fc_item->setHostEntity('node', $node);
  }

  // ... set some values ...
  $fc_item->field_terms[LANGUAGE_NONE][0]['value'] = 'lars-schroeter.com';

  // save node and field-collection
  $node->field_collection[LANGUAGE_NONE][0] = array('entity' => $fc_item);
  node_save($node);


You don't need to call node_save($node) when using entity_metadata_wrapper. It will ensure that only the entity's data and the reference to the host are saved without triggering any node_save, which is a good performance boost.

However, you would still need node_save() if you have any node_save-triggered actions that use this field collection (e.g. a rule that sends emails when the node is edited).


use the wrappers, they are your friend:

  // Create an Entity
  $e = entity_create('node', array('type' => 'CONTENT_TYPE'));
  // Specify the author.
  $e->uid = 1;
  // Create a Entity Wrapper of that new Entity
  $entity = entity_metadata_wrapper('node',$e);

  // Specify the title
  $entity->title = 'Test node';

  // Add field data... SO MUCH BETTER!
  $entity->field_FIELD_NAME->set(1111);
  // Save the node.
  $entity->save();


You can find Entity API documented in Entity API Tutorial at Drupal.org.

There you can find some useful examples, especially check for Entity metadata wrappers page.

Here is example based on your variables:

$node = node_load(1);
$field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_book_text')); // field_book_text is field collection
$field_collection_item->setHostEntity('node', $node);
$cwrapper = entity_metadata_wrapper('field_collection_item', $field_collection_item);
// Adding fields to field_collection
$cwrapper->field_foo_text->set("value");
$cwrapper->field_foo_multitext->set(array("value1", "value2"));
$cwrapper.save();

Here is another example using field collections from above docs page:

<?php
    // Populate the fields.
    $ewrapper = entity_metadata_wrapper('node', $node);
    $ewrapper->field_lead_contact_name->set($contact_name);
    $ewrapper->field_lead_contact_phone->set($contact_phone);
    $ewrapper->field_lead_contact_email->set($contact_email);  

    // Create the collection entity and set it's "host".
    $collection = entity_create('field_collection_item', array('field_name' => 'field_facilities_requested'));
    $collection->setHostEntity('node', $node);  

    // Now define the collection parameters.
    $cwrapper = entity_metadata_wrapper('field_collection_item', $collection);
    $cwrapper->field_facility->set(intval($offset));
    $cwrapper->save();  

    // Save.
    $ewrapper->save();
?>

Here is more advanced example of mine which for given entity it loads taxonomy term references from field_rs_property_features, then for each secondary term which has a parent term, adds its term name and its parent term name into field_feed_characteristics_value by grouping them together into title (parent) and value (child). It's probably more difficult to explain without seeing the code. So here it is:

/**
 * Function to set taxonomy term names based on term references for given entity.
 */
function MYMODULE_refresh_property_characteristics(&$entity, $save = FALSE) {
  try {
    $w_node = entity_metadata_wrapper('node', $entity);
    $collections = array();
    foreach ($w_node->field_rs_property_features->getIterator() as $delta => $term_wrapper) {
      if ($term_wrapper->parent->count() > 0) {
        $name = $term_wrapper->name->value();
        $pname = $term_wrapper->parent->get(0)->name->value();
        if (array_key_exists($pname, $collections)) {
          $collections[$pname]->field_feed_characteristics_value[] = $name;
        } else {
          // Create the collection entity, set field values and set it's "host".
          $field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_feed_characteristics'));
          $field_collection_item->setHostEntity('node', $w_node->value());
          $collections[$pname] = entity_metadata_wrapper('field_collection_item', $field_collection_item);
          $collections[$pname]->field_feed_characteristics_title = $pname;
          $collections[$pname]->field_feed_characteristics_value = array($name);
        }
      }
    }
    if ($save) {
      $w_node->save();
    }
  } catch (Exception $e) {
    drupal_set_message(t('Error setting values for field collection: @title, message: @error.',
          array('@title' => $w_node->title->value(), '@error' => $e->getMessage())), 'error');
    watchdog_exception('MYMODULE', $e);
    return FALSE;
  }
  return TRUE;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号