Versão do Drupal: 7.21
Versão do módulo de coleta de campos: 7.x-1.0-beta5
Breve explicação : estou ocupado tentando importar coleções de campos de forma programática, mas ao excluir algumas delas sempre há alguma coleção de campos "falsas".
Explicação longa : meus usuários têm um campo de coleção de campos em seu perfil. Esta coleção de campos contém 3 campos de texto. Quero importar dados de um banco de dados sql personalizado para a coleção de campos do usuário. Essa coleção de campos pode ter vários valores. Quando importo os dados pela primeira vez, tudo funciona bem, vejo os dados nos campos da coleção de campos. Ótimo.
Mas aqui vem a parte complicada. Digamos que eu importe para um usuário específico 5 linhas do banco de dados personalizado. Eles são adicionados à coleção de campos, portanto, essa coleção de campos possui 5 itens, cada um contendo 3 campos. Em seguida, excluo algumas linhas do meu banco de dados personalizado para que eu tenha apenas 3 linhas restantes para este usuário. Eu executo a importação novamente, atualizando os 3 primeiros itens da coleção de campos, mas resta 2 itens da importação anterior. Eles devem ser excluídos porque tenho apenas 3 linhas importadas, mas ainda 5 itens de coleção de campos.
Tentei excluir esses itens da coleção de campos, mas sempre há um ou mais itens. Os campos estão vazios quando olho para o perfil do usuário, mas ainda há algo lá. Digamos que neste momento eu adiciono 5 novas linhas para o usuário no meu banco de dados personalizado, portanto, tenho 8 linhas no total para esse usuário. Então eu executo a importação novamente. Os três primeiros itens são atualizados, mas quando tento adicionar a quarta linha, ele ainda recebe um ID de entidade do 4º item da coleção de campos, tenta atualizá-lo, mas falha e retorna esse erro:
Fatal error: Call to undefined method stdClass::save()
Tentei excluir os itens da coleção de campos com cada um destes métodos abaixo:
// 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 é o meu 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();
}
}
}
}
Portanto, minha pergunta é: como faço para excluir itens da coleção de campos para que eles não sejam mais usados?
entity_delete_multiple()
. Talvez seja necessário executar cron um par de vezes depois que você campos de exclusão (dados de campo são purgados em uma programação de modo a não sobrecarregar um único carregamento da página com tudo o que o processamento de fazer)
entity_delete_multiple
é 100% definitivamente o caminho certo para fazê-lo - ter um olhar para afield_collection_field_delete
função, que é o que coleção de campo em si usa para limpar itens quando o campo referenciado é removido