Chamar ::cleardiretamente não é equivalente a definir o campo para um valor vazio, pois não chama updateParentda mesma forma que chama setcom um valor vazio. Entre outras coisas, updateParentgarante que o setter callbackdefinido nas informações da propriedade (consulte drupalcontrib.org/api/drupal/… ) seja chamado.
Alice Heaton
Respostas:
24
O problema é que você deve definir um valor vazio que seja compatível com o tipo de dados do seu campo. Caso contrário, você receberá uma exceção. Passar NULLou array()quando uma sequência é esperada gerará um erro.
Outro aspecto a ter em mente é que os dados transmitidos também dependerão se o seu campo for um valor único, um campo com vários valores ou um campo com várias propriedades.
Se o seu campo for um valor único (e, portanto, o wrapper do campo for uma instância do EntityValueWrapper ), você deverá atribuir a ele um valor vazio compatível com o tipo de dados em questão . Por exemplo, os dois métodos a seguir são equivalentes:
$wrapper->title ='';
$wrapper->title->set('');
No entanto, os três exemplos a seguir gerarão uma exceção, porque os tipos de dados não são compatíveis com o titlecampo:
Se o seu campo for um campo com várias propriedades (por exemplo, um campo de texto formatado, que definiu a valuee a formatpropriedade) e, portanto, uma instância do EntityStructureWrapper , array()ou NULLserá o valor vazio correto. Então você pode fazer o seguinte:
Mas, nesse caso, passar uma string vazia teria gerado um erro. Observe que você poderia optar por deixar a valuepropriedade vazia . Nesse caso, uma sequência é o tipo de dados correto:
$wrapper->field_formatted_text->value ='';
Finalmente, se o campo é um campo multi-valor (e, assim, o seu invólucro é um exemplo de EntityListWrapper ), em seguida, arrayou NULLsão os valores de correcção vazios, e as três linhas seguintes são equivalentes:
Nota: Chamar o clearmétodo nos wrappers não é equivalente a configurar o campo para um valor vazio. Quando o campo é definido como um valor vazio, ele chama EntityMetadataWrapper :: updateParent no wrapper pai do campo. Isso garante, entre outras coisas, que o setter callbackdefinido por hook_entity_property_info seja chamado. Ligar clearnão faz isso.
Observe que, se o campo for múltiplo e obrigatório, configure como array()ou NULLpode falhar, porque o campo não pode estar vazio. Isso é diferente da $nodeatribuição de campo normal , onde é possível salvar programaticamente um campo obrigatório vazio (ele não será salvo pela interface do Drupal). Nesse caso, uma solução alternativa é array(N), onde N é o ID de uma entidade ainda não existente e referenciada. Observe que ele será salvo com esse ID; portanto, seus dados são "quebrados" em um sentido relacional; mas não deve afetar a camada do tema se você estiver fazendo as coisas certas (por exemplo, usando o Display Suite ou os painéis).
JP
$w->field_allowed_regions->set(array(null));é a única opção que funcionou para o meu campo de referência de taxonomia com vários valores.
Incredible
No meu caso, tenho um campo de referência de entidade com um único valor. O seguinte funcionou para mim: $ wrapper-> field_entity_reference-> set (NULL);
Marcos Buarque
3
Além de outras respostas e comentários, se o campo for múltiplo e obrigatório, conforme observado anteriormente, você não poderá usar
$wrapper->field_example_multiple->set()
$wrapper->field_example_multiple->set(NULL)
nem mesmo $wrapper->field_example_multiple->set(array()),
mas, em vez disso, você pode usar o seguinte se quiser limpar o campo de todos os seus valores:
De fato, isso funciona se o campo de valores múltiplos está ou não definido como 'obrigatório' e, portanto, recomendo sempre usá-lo, para garantir que seu código seja robusto.
(Obviamente, se o campo for 'obrigatório', você talvez não deva limpá-lo completamente, mas seu código pode estar fazendo isso como uma etapa preliminar para excluir a entidade inteira ou algo semelhante, portanto, há momentos em que pode apenas seja legítimo.)
Esteja ciente de que o uso de $ $ wrapper-> field_example_multiple-> set (array (NULL)) `levará a ter um elemento NULL no array de dados. Este método não limpa valores, mas define a matriz de valores para um único NULLvalor.
precisa
Bom ponto. Eu acho que isso nos remete à minha observação sobre não limpar um valor necessário. Provavelmente é impossível de forma intencional.
Martin Q
De fato, um campo obrigatório deve ter pelo menos um valor não nulo. Se você deseja redefinir um campo de vários valores obrigatório, basta substituí-lo pelo novo valor. $product_display->field_product = array($product_id);
Ou
2
Parece que as complexidades listadas nos outros comentários são relevantes apenas para um campo obrigatório. Se o campo não for obrigatório, isso deve ser bastante simples:
$wrapper->field_foo = NULL;
Você pode usar o wrapper para verificar as propriedades do campo:
O método EntityMetadataWrapper :: clear é declarado como "protegido", portanto, não pode ser chamado a partir do seu código: somente métodos "públicos" podem ser acessados diretamente de fora do objeto.
EntityStructureWrapper::clear()
ouEntityValueWrapper::clear()
talvez?::clear
diretamente não é equivalente a definir o campo para um valor vazio, pois não chamaupdateParent
da mesma forma que chamaset
com um valor vazio. Entre outras coisas,updateParent
garante que osetter callback
definido nas informações da propriedade (consulte drupalcontrib.org/api/drupal/… ) seja chamado.Respostas:
O problema é que você deve definir um valor vazio que seja compatível com o tipo de dados do seu campo. Caso contrário, você receberá uma exceção. Passar
NULL
ouarray()
quando uma sequência é esperada gerará um erro.Outro aspecto a ter em mente é que os dados transmitidos também dependerão se o seu campo for um valor único, um campo com vários valores ou um campo com várias propriedades.
Se o seu campo for um valor único (e, portanto, o wrapper do campo for uma instância do EntityValueWrapper ), você deverá atribuir a ele um valor vazio compatível com o tipo de dados em questão . Por exemplo, os dois métodos a seguir são equivalentes:
No entanto, os três exemplos a seguir gerarão uma exceção, porque os tipos de dados não são compatíveis com o
title
campo:Se o seu campo for um campo com várias propriedades (por exemplo, um campo de texto formatado, que definiu a
value
e aformat
propriedade) e, portanto, uma instância do EntityStructureWrapper ,array()
ouNULL
será o valor vazio correto. Então você pode fazer o seguinte:Mas, nesse caso, passar uma string vazia teria gerado um erro. Observe que você poderia optar por deixar a
value
propriedade vazia . Nesse caso, uma sequência é o tipo de dados correto:Finalmente, se o campo é um campo multi-valor (e, assim, o seu invólucro é um exemplo de EntityListWrapper ), em seguida,
array
ouNULL
são os valores de correcção vazios, e as três linhas seguintes são equivalentes:Nota: Chamar o
clear
método nos wrappers não é equivalente a configurar o campo para um valor vazio. Quando o campo é definido como um valor vazio, ele chama EntityMetadataWrapper :: updateParent no wrapper pai do campo. Isso garante, entre outras coisas, que osetter callback
definido por hook_entity_property_info seja chamado. Ligarclear
não faz isso.fonte
array()
ouNULL
pode falhar, porque o campo não pode estar vazio. Isso é diferente da$node
atribuição de campo normal , onde é possível salvar programaticamente um campo obrigatório vazio (ele não será salvo pela interface do Drupal). Nesse caso, uma solução alternativa éarray(N)
, onde N é o ID de uma entidade ainda não existente e referenciada. Observe que ele será salvo com esse ID; portanto, seus dados são "quebrados" em um sentido relacional; mas não deve afetar a camada do tema se você estiver fazendo as coisas certas (por exemplo, usando o Display Suite ou os painéis).$w->field_allowed_regions->set(array(null));
é a única opção que funcionou para o meu campo de referência de taxonomia com vários valores.Além de outras respostas e comentários, se o campo for múltiplo e obrigatório, conforme observado anteriormente, você não poderá usar
$wrapper->field_example_multiple->set()
$wrapper->field_example_multiple->set(NULL)
nem mesmo
$wrapper->field_example_multiple->set(array())
,mas, em vez disso, você pode usar o seguinte se quiser limpar o campo de todos os seus valores:
De fato, isso funciona se o campo de valores múltiplos está ou não definido como 'obrigatório' e, portanto, recomendo sempre usá-lo, para garantir que seu código seja robusto.
(Obviamente, se o campo for 'obrigatório', você talvez não deva limpá-lo completamente, mas seu código pode estar fazendo isso como uma etapa preliminar para excluir a entidade inteira ou algo semelhante, portanto, há momentos em que pode apenas seja legítimo.)
fonte
NULL
valor.$product_display->field_product = array($product_id);
Parece que as complexidades listadas nos outros comentários são relevantes apenas para um campo obrigatório. Se o campo não for obrigatório, isso deve ser bastante simples:
Você pode usar o wrapper para verificar as propriedades do campo:
Dependendo do contexto, você também pode obter as propriedades de um campo usando:
fonte
Outra solução para esse problema pode ser
EntityMetadataWrapper::clear
$entity_wrapper->field->clear()
fonte