Versión de Drupal: 7.21
Versión del módulo de colección de campo: 7.x-1.0-beta5
Breve explicación : estoy ocupado tratando de importar colecciones de campos mediante programación, pero al eliminar algunas de ellas siempre queda alguna colección de campo 'falsa'.
Explicación larga : Mis usuarios tienen un campo de colección de campos en su perfil. Esta colección de campos contiene 3 campos de texto. Quiero importar datos de una base de datos SQL personalizada a la colección de campo del usuario. Esta colección de campos puede tener múltiples valores. Cuando importo los datos por primera vez, todo funciona bien, veo los datos en los campos de la colección de campos. Excelente.
Pero aquí viene la parte difícil. Digamos que importo para un usuario específico 5 filas de la base de datos personalizada. Se agregan a la colección de campos, por lo que esta colección de campos tiene 5 elementos, cada uno con 3 campos. Luego elimino algunas filas de mi base de datos personalizada para que solo me queden 3 filas para este usuario. Ejecuto la importación nuevamente, actualizando los primeros 3 elementos de la colección de campos, pero luego me quedan 2 elementos de la importación anterior. Deben eliminarse porque solo tengo 3 filas importadas pero todavía 5 elementos de colección de campo.
Así que intenté eliminar estos elementos de la colección de campo, pero siempre quedan uno o más elementos. Los campos están vacíos cuando miro el perfil del usuario, pero todavía hay algo allí. Digamos que en este punto agrego 5 filas nuevas para el usuario en mi base de datos personalizada, por lo que tengo 8 filas en total para este usuario. Luego ejecuto la importación nuevamente. Los primeros 3 elementos se actualizan, pero luego, cuando intento agregar la cuarta fila, aún obtiene una identificación de entidad del cuarto elemento de la colección de campos, intenta actualizarlo pero falla y devuelve este error:
Fatal error: Call to undefined method stdClass::save()
Intenté eliminar los elementos de la colección de campos con cada uno de estos métodos a continuación:
// 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();
Este es mi código completo:
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();
}
}
}
}
Entonces mi pregunta es: ¿cómo elimino los elementos de la colección de campo para que realmente se hayan ido?
entity_delete_multiple()
. Es posible que deba ejecutar cron un par de veces después de eliminar campos (los datos de campo se depuran en un horario para no cargar una sola carga de página con todo ese procesamiento que hacer)
entity_delete_multiple
es 100% definitivamente la forma correcta de hacerlo: eche un vistazo a lafield_collection_field_delete
función, que es lo que Field Collection usa para limpiar los elementos cuando se elimina el campo de referencia