Version Drupal: 7.21
Version du module de collecte sur le terrain: 7.x-1.0-beta5
Brève explication : Je suis en train d'essayer d'importer des collections de champs par programme, mais lors de la suppression de certaines d'entre elles, il reste toujours une collection de champs «fausse».
Explication longue : Mes utilisateurs ont un champ de collecte de champs sur leur profil. Cette collection de champs contient 3 champs de texte. Je souhaite importer des données d'une base de données SQL personnalisée dans la collection de champs de l'utilisateur. Cette collection de champs peut avoir plusieurs valeurs. Lorsque j'importe les données pour la première fois, tout fonctionne correctement, je vois les données dans les champs de la collection de champs. Génial.
Mais voici la partie délicate. Supposons que j'importe pour un utilisateur spécifique 5 lignes de la base de données personnalisée. Ils sont ajoutés à la collection de champs, donc cette collection de champs contient 5 éléments contenant chacun 3 champs. Ensuite, je supprime certaines lignes de ma base de données personnalisée afin qu'il ne me reste que 3 lignes pour cet utilisateur. J'exécute à nouveau l'importation, en mettant à jour les 3 premiers éléments de la collection de champs, mais je me retrouve avec 2 éléments de l'importation précédente. Ils doivent être supprimés car je n'ai que 3 lignes importées mais toujours 5 éléments de collection de champs.
J'ai donc essayé de supprimer ces éléments de collection de champs, mais il reste toujours un ou plusieurs éléments. Les champs sont vides quand je regarde le profil utilisateur mais il y a encore quelque chose. Disons qu'à ce stade, j'ajoute 5 nouvelles lignes pour l'utilisateur dans ma base de données personnalisée, donc j'ai 8 lignes au total pour cet utilisateur. Ensuite, je lance à nouveau l'importation. Les 3 premiers éléments sont mis à jour, mais lorsque j'essaie d'ajouter la 4e ligne, il obtient toujours un identifiant d'entité du 4e élément de collection de champs, essaie de le mettre à jour mais échoue et renvoie cette erreur:
Fatal error: Call to undefined method stdClass::save()
J'ai essayé de supprimer les éléments de collection de champs avec chacune de ces méthodes ci-dessous:
// 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();
Voici mon code complet:
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();
}
}
}
}
Ma question est donc la suivante: comment supprimer des éléments de collection de champs pour qu'ils soient réellement partis?
entity_delete_multiple()
. Vous devrez peut-être exécuter cron plusieurs fois après avoir supprimé des champs (les données de champ sont purgées selon un calendrier afin de ne pas surcharger un seul chargement de page avec tout ce traitement à faire)
entity_delete_multiple
est 100% certainement la bonne façon de le faire - jetez un œil à lafield_collection_field_delete
fonction, qui est ce que Field Collection utilise lui-même pour nettoyer les éléments lorsque le champ référencé est supprimé