Drupal-Version: 7.21
Version des Feldsammlungsmoduls: 7.x-1.0-beta5
Kurze Erklärung : Ich bin damit beschäftigt, Feldsammlungen programmgesteuert zu importieren, aber beim Löschen einiger von ihnen bleibt immer eine gefälschte Feldsammlung übrig.
Lange Erklärung : Meine Benutzer haben ein Feldsammlungsfeld in ihrem Profil. Diese Feldsammlung enthält 3 Textfelder. Ich möchte Daten aus einer benutzerdefinierten SQL-Datenbank in die Feldsammlung des Benutzers importieren. Diese Feldsammlung kann mehrere Werte haben. Wenn ich die Daten zum ersten Mal importiere, funktioniert alles einwandfrei. Ich sehe die Daten in den Feldern der Feldsammlung. Toll.
Aber hier kommt der schwierige Teil. Angenommen, ich importiere für einen bestimmten Benutzer 5 Zeilen aus der benutzerdefinierten Datenbank. Sie werden der Feldsammlung hinzugefügt, sodass diese Feldsammlung 5 Elemente enthält, die jeweils 3 Felder enthalten. Dann lösche ich einige Zeilen aus meiner benutzerdefinierten Datenbank, sodass nur noch 3 Zeilen für diesen Benutzer übrig sind. Ich führe den Import erneut aus und aktualisiere die ersten 3 Elemente der Feldsammlung, aber dann bleiben mir 2 Elemente aus dem vorherigen Import übrig. Sie sollten gelöscht werden, da ich nur 3 importierte Zeilen, aber noch 5 Feldsammlungselemente habe.
Also habe ich versucht, diese Feldsammlungselemente zu löschen, aber es sind immer noch ein oder mehrere Elemente übrig. Die Felder sind leer, wenn ich mir das Benutzerprofil ansehe, aber da ist noch etwas. Angenommen, ich füge an dieser Stelle 5 neue Zeilen für den Benutzer in meine benutzerdefinierte Datenbank ein, sodass ich insgesamt 8 Zeilen für diesen Benutzer habe. Dann führe ich den Import erneut aus. Die ersten 3 Elemente werden aktualisiert, aber wenn ich versuche, die 4. Zeile hinzuzufügen, wird immer noch eine Entitäts-ID aus dem 4. Feldsammlungselement abgerufen, versucht, sie zu aktualisieren, schlägt jedoch fehl und gibt diesen Fehler zurück:
Fatal error: Call to undefined method stdClass::save()
Ich habe versucht, die Feldsammlungselemente mit jeder der folgenden Methoden zu löschen:
// 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();
Dies ist mein vollständiger Code:
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();
}
}
}
}
Meine Frage lautet also: Wie lösche ich Feldsammlungselemente, damit sie tatsächlich verschwunden sind?
entity_delete_multiple()
. Möglicherweise müssen Sie cron ein paar Mal ausführen, nachdem Sie Felder gelöscht haben (Felddaten werden nach einem Zeitplan gelöscht, um das Laden einer einzelnen Seite nicht mit all dieser Verarbeitung zu belasten)
entity_delete_multiple
ist definitiv 100% der richtige Weg, dies zu tun - werfen Sie einen Blick auf diefield_collection_field_delete
Funktion, mit der Field Collection selbst Elemente bereinigt, wenn das Feld, auf das verwiesen wird, entfernt wird