Версия Drupal: 7.21
Версия модуля сбора данных: 7.x-1.0-beta5
Краткое объяснение : Я занят попытками импортировать коллекции полей программно, но при удалении некоторых из них всегда остается какая-то «поддельная» коллекция полей.
Подробное объяснение : у моих пользователей есть поле для сбора полей в их профиле. Эта коллекция полей содержит 3 текстовых поля. Я хочу импортировать данные из пользовательской базы данных SQL в поле коллекции пользователя. Эта коллекция полей может иметь несколько значений. Когда я импортирую данные в первый раз, все работает нормально, я вижу данные в полях коллекции полей. Отлично.
Но здесь начинается сложная часть. Допустим, я импортирую для одного конкретного пользователя 5 строк из пользовательской базы данных. Они добавляются в коллекцию полей, поэтому эта коллекция полей содержит 5 элементов, каждый из которых содержит 3 поля. Затем я удаляю несколько строк из своей пользовательской базы данных, чтобы у меня осталось только 3 строки для этого пользователя. Я снова запускаю импорт, обновляя первые 3 элемента коллекции полей, но затем у меня остаются 2 элемента из предыдущего импорта. Их следует удалить, потому что у меня есть только 3 импортированные строки, но все еще 5 элементов коллекции полей.
Поэтому я попытался удалить эти элементы коллекции полей, но всегда остается один или несколько элементов. Когда я смотрю на профиль пользователя, поля пусты, но что-то там еще есть. Допустим, в этот момент я добавил 5 новых строк для пользователя в своей пользовательской базе данных, поэтому у меня есть 8 строк для этого пользователя. Затем я снова запускаю импорт. Первые 3 элемента обновляются, но затем, когда я пытаюсь добавить 4-ую строку, он все еще получает идентификатор объекта из 4-го элемента коллекции полей, пытается обновить его, но не удается и возвращает эту ошибку:
Fatal error: Call to undefined method stdClass::save()
Я попытался удалить элементы коллекции полей с помощью каждого из следующих методов:
// Method 1
entity_delete_multiple('field_collection_item', array($fc_id));
// Method 2
$field_collection_item = field_collection_item_load($fc_id);
$field_collection_item->delete();
// Method 3
$field_collection_item = field_collection_item_load($fc_id);
$field_collection_item->deleteRevision();
Это мой полный код:
function import_user_field_collection(&$user, $old_user_id) {
// I do a query to get the rows I want to import for this specific user.
db_set_active('custom_sql_database');
$result = db_query("SELECT * FROM {users} WHERE user_id = :user_id", array(':user_id' => $old_user_id));
db_set_active('default');
$i = 0; // Keep count of how many rows I imported.
foreach($result as $row) {
// Check if the field collection item already exists.
if(!empty($user->field_profile_diploma_opleiding[LANGUAGE_NONE][$i]['value'])) {
// If it does exists, update this particular field collection item.
$fc_id = $user->field_profile_diploma_opleiding[LANGUAGE_NONE][$i]['value'];
$field_collection_item = entity_load('field_collection_item', array($fc_id));
// These 3 text fields are children of the field collection field.
$field_collection_item[$fc_id]->field_profile_diploma_instituut[LANGUAGE_NONE][0]['value'] = $row->instituut;
$field_collection_item[$fc_id]->field_profile_diploma_vakgebied[LANGUAGE_NONE][0]['value'] = $row->vakgebied;
$field_collection_item[$fc_id]->field_profile_diploma_jaar[LANGUAGE_NONE][0]['value'] = $row->jaar_diploma;
$field_collection_item[$fc_id]->save(TRUE);
} else {
// If the field collection item doesn't exist I want to create a new field collection item.
$field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_profile_diploma_opleiding'));
$field_collection_item->setHostEntity('user', $user);
$field_collection_item->field_profile_diploma_instituut[LANGUAGE_NONE][0]['value'] = $row->instituut;
$field_collection_item->field_profile_diploma_vakgebied[LANGUAGE_NONE][0]['value'] = $row->vakgebied;
$field_collection_item->field_profile_diploma_jaar[LANGUAGE_NONE][0]['value'] = $row->jaar_diploma;
$field_collection_item->save(TRUE);
}
$i++;
}
$fc_fields = field_get_items('user', $user, 'field_profile_diploma_opleiding');
// Check if there are more field collection items than imported rows
if(count($fc_fields) > $i) {
for($i; $i <= count($fc_fields); $i++) {
// Run through each field collection item that's left from the previous import and delete it.
if(!empty($user->field_profile_diploma_opleiding[LANGUAGE_NONE][$i]['value'])) {
// Method 1
$fc_id = $user->field_profile_diploma_opleiding[LANGUAGE_NONE][$i]['value'];
entity_delete_multiple('field_collection_item', array($fc_id));
// Method 2
//$field_collection_item = field_collection_item_load($fc_id);
//$field_collection_item->delete();
// Method 3
//$field_collection_item = field_collection_item_load($fc_id);
//$field_collection_item->deleteRevision();
}
}
}
}
Итак, мой вопрос: как удалить элементы коллекции полей, чтобы они на самом деле исчезли?
entity_delete_multiple()
. Вам может потребоваться запустить cron пару раз после удаления полей (данные полей очищаются по расписанию, чтобы не загружать загрузку одной страницы всей этой обработкой)
entity_delete_multiple
на 100% определенно правильный способ сделать это - взгляните наfield_collection_field_delete
функцию, которая сама Field Collection использует для очистки элементов при удалении указанного поля