2011-06-05 83 views
3

我想动态添加“field collection”。但我不熟悉Field API或实体API。 Drupal中的新实体API记录很差。通过脚本在Drupal 7中动态添加“字段集合”?

这里是我的代码,到现在为止:

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

“现场收集”模块利用函数“entity_form_submit_build_entity”这我不能使用,因为在我的情况下,没有形式。

如果你能告诉我如何添加字段,我将不胜感激。

回答

7

基于一些代码,我在现场的项目中使用:

// 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(); 
1

一个更完整的例子:

使用上面的代码示例应该考虑使用entity_metadata_wrapper功能从实体API
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); 
4

任何人设置实体上的字段值而不是使用赋值运算符。所以,从“更完整的例子”上面的代码将是:

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); 
+0

感谢这个非常有用的例子。我确实注意到,尽管在最后调用或不调用node_save时都保存了新的值。我对此没有解释。 – Countzero 2013-02-16 06:01:54

+0

这对我来说非常合适,不过node_save()是不需要的,除非我失去了一些东西? – 2013-03-17 21:44:30

0

使用entity_metadata_wrapper时,您不需要调用node_save($节点)。它将确保只保存实体的数据和对主机的引用,而不触发任何node_save,这是一个很好的性能提升。

但是,如果您有任何使用此字段集的节点触发操作(例如,在编辑节点时发送电子邮件的规则),您仍然需要node_save()。

0

使用包装,他们是你的朋友:

// 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(); 
0

您可以在Drupal.org在Entity API Tutorial记录实体API。

在那里你可以找到一些有用的例子,尤其是检查Entity metadata wrappers页面。

这里是根据你的变量例如:

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

下面是一个使用领域集合从上面的文档页面又如:

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

这里是我的更高级的例子为如果给定实体从field_rs_property_features加载分类术语引用,则对于具有父项的每个次级术语,将其术语名称和其父项名称添加到field_feed_characteristics_value将它们组合成标题(父母)和值(孩子)。没有看到代码可能会更难解释。所以这里是:

/** 
* 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; 
}