Модификация коллекции полей программно отсутствующими полями hostEntity
Я пытаюсь изменить коллекцию полей в узле, который уже существует, чтобы я мог изменить изображение на первом элементе в массиве 3. Проблема в том, что информация hostEntity не устанавливается, когда я делаю entity_load или entity_load_single, поэтому, когда я сделать:
$field_collection_item->save(true); // with or without the true
// OR
$fc_wrapper->save(true); // with or without the true
Я получаю следующую ошибку:
Exception: Unable to save a field collection item without a valid reference to a host entity. in FieldCollectionItemEntity->save()
Когда я печатаю _r объект коллекции полей, поля hostEntity: protected действительно пусты. Моя коллекция полей настроена следующим образом:
- field_home_experts
- Expert Image<--- Хотите изменить только эти данные, а остальные оставить ниже
- field_expert_image
- Образ
- Имя эксперта
- field_expert_name
- Текст
- Название эксперта
- field_expert_title
- Текст
- Expert Image<--- Хотите изменить только эти данные, а остальные оставить ниже
Вот код, который я пытаюсь использовать для изменения существующей коллекции полей узлов:
$node = getNode(1352); // Get the node I want to modify
// There can be up to 3 experts, and I want to modify the image of the first expert
$updateItem = $node->field_home_experts[LANGUAGE_NONE][0];
if ($updateItem) { // Updating
// Grab the field collection that currently exists in the 0 spot
$fc_item = reset(entity_load('field_collection_item', array($updateItem)));
// Wrap the field collection entity in the field API wrapper
$fc_wrapper = entity_metadata_wrapper('field_collection_item', $fc_item);
// Set the new image in place of the current
$fc_wrapper->field_expert_image->set((array)file_load(4316));
// Save the field collection
$fc_wrapper->save(true);
// Save the node with the new field collection (not sure this is needed)
node_save($node);
}
Любая помощь будет принята с благодарностью, я все еще новичок в Drupal в целом (конечный пользователь или разработчик)
2 ответа
Хорошо, так что я думаю, что я понял это, я написал функцию, которая будет устанавливать значения коллекции полей:
// $node: (obj) node object returned from node_load()
// $collection: (string) can be found in drupal admin interface:
// structure > field collections > field name
// $fields: (array) see usage below
// $index: (int) the index to the element you wish to edit
function updateFieldCollection($node, $collection, $fields = Array(), $index = 0) {
if ($node && $collection && !empty($fields)) {
// Get the field collection ID
$eid = $node->{$collection}[LANGUAGE_NONE][$index]['value'];
// Load the field collection with the ID from above
$entity = entity_load_single('field_collection_item', array($eid));
// Wrap the loaded field collection which makes setting/getting much easier
$node_wrapper = entity_metadata_wrapper('field_collection_item', $entity);
// Loop through our fields and set the values
foreach ($fields as $field => $data) {
$node_wrapper->{$field}->set($data);
}
// Once we have added all the values we wish to change then we need to
// save. This will modify the node and does not require node_save() so
// at this point be sure it is all correct as this will save directly
// to a published node
$node_wrapper->save(true);
}
}
ИСПОЛЬЗОВАНИЕ:
// id of the node you wish to modify
$node = node_load(123);
// Call our function with the node to modify, the field collection machine name
// and an array setup as collection_field_name => value_you_want_to_set
// collection_field_name can be found in the admin interface:
// structure > field collections > manage fields
updateFieldCollection(
$node,
'field_home_experts',
array (
'field_expert_image' => (array)file_load(582), // Loads up an existing image
'field_expert_name' => 'Some Guy',
'field_expert_title' => 'Some Title',
)
);
Надеюсь, что это поможет кому-то еще, так как я потратил целый день, пытаясь заставить это работать (надеюсь, я не буду нубом в Drupal7). Может быть проблема с получением отформатированного текста для set() правильно, но я не уверен, что это в данный момент, так что просто имейте это в виду (если у вас есть поле, которое имеет формат отфильтрованного_html, например, не уверен, что это будет установить правильно, не делая ничего другого).
Удачи! Джейк
Я все еще получал ошибку, упомянутую в вопросе, после использования вышеупомянутой функции. Вот что сработало для меня:
function updateFieldCollection($node, $collection, $fields = Array(), $index = 0) {
$eid = $node->{$collection}[LANGUAGE_NONE][$index]['value'];
$fc_item = entity_load('field_collection_item', array($eid));
foreach ($fields as $field => $data) {
$fc_item[$eid]->{$field}[LANGUAGE_NONE][0]['value'] = $data;
}
$fc_item[$eid]->save(TRUE);
}
Я надеюсь, что это кому-то поможет, потому что мне потребовалось довольно много времени, чтобы заставить это работать.