2011-06-05 87 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; 
}