¿Cómo se borra un valor de campo con entity_metadata_wrapper ()?


20

Supongamos que tengo una entidad con un campo field_fooy quiero borrar el valor de ese campo.

¿A qué debo pasar $wrapper->set()?

Lo he intentado NULLy array()ambos producen un mensaje de error.


1
¿Estás buscando los métodos EntityStructureWrapper::clear()o EntityValueWrapper::clear()quizás?
Clive

Llamar ::cleardirectamente no es equivalente a establecer el campo en un valor vacío, ya que no llama updateParentde la manera en que lo hace setcon un valor vacío. Entre otras cosas, updateParentasegura que se llame a lo setter callbackdefinido en la información de la propiedad (ver drupalcontrib.org/api/drupal/… ).
Alice Heaton

Respuestas:


24

El problema es que debe establecer un valor vacío que sea compatible con el tipo de datos de su campo. Si no lo hace, obtendrá una excepción. Pasar NULLo array()cuando se espera una cadena generará un error.

Otra cosa a tener en cuenta es que los datos que pase también dependerán de si su campo es un valor único, un campo de valores múltiples o un campo con múltiples propiedades.

Si su campo es un valor único (y, por lo tanto, el contenedor del campo es una instancia de EntityValueWrapper ), debe asignarle un valor vacío compatible con el tipo de datos en cuestión . Por ejemplo, los dos métodos siguientes son equivalentes:

$wrapper->title = '';
$wrapper->title->set('');

Sin embargo, los siguientes tres ejemplos generarán una excepción, porque los tipos de datos no son compatibles con el titlecampo:

$wrapper->title->set();
$wrapper->title->set(NULL);
$wrapper->title->set(array());

Si su campo es un campo con múltiples propiedades (por ejemplo, un campo de texto con formato, que define tanto una valuey formatpropiedad) y por lo tanto una instancia de EntityStructureWrapper , a continuación, array()o NULLserá el valor vacío correcto. Entonces puedes hacer lo siguiente:

$wrapper->field_formatted_text = array();
$wrapper->field_formatted_text = NULL;

Pero en ese caso, pasar una cadena vacía habría provocado un error. Tenga en cuenta que podría haber optado por hacer que la valuepropiedad esté vacía, en cuyo caso una cadena es el tipo de datos correcto:

$wrapper->field_formatted_text->value = '';

Finalmente, si su campo es un campo de valores múltiples (y, por lo tanto, su contenedor es una instancia de EntityListWrapper ), arrayo NULLson los valores vacíos correctos, y las siguientes tres líneas son equivalentes:

$wrapper->field_example_multiple->set();
$wrapper->field_example_multiple = array();
$wrapper->field_example_multiple = NULL;

Nota: Llamar al clearmétodo en los contenedores no es equivalente a configurar el campo en un valor vacío. Cuando el campo se establece en un valor vacío, llama a EntityMetadataWrapper :: updateParent en el contenedor primario del campo. Esto asegura, entre otras cosas, que se llama lo setter callbackdefinido por hook_entity_property_info . Llamar clearno hace eso.


1
Tenga en cuenta que si el campo es múltiple y obligatorio, establecer como array()o NULLpuede fallar, porque el campo no puede estar vacío. Esto es diferente de la $nodeasignación de campo normal , donde puede guardar mediante programación un campo requerido vacío (simplemente no se guardará a través de la propia interfaz de usuario de Drupal). En este caso, existe una solución alternativa array(N), donde N es el ID de una entidad inexistente pero referenciada. Tenga en cuenta que se guardará con esa ID, por lo que sus datos podrían estar "rotos" en un sentido relacional; pero no debería afectar la capa de tema si está haciendo todo lo correcto allí (por ejemplo, usando Display Suite o Panels).
JP

$w->field_allowed_regions->set(array(null));es la única opción que funcionó para mi campo de referencia de taxonomía de valores múltiples.
Increíble el

En mi caso, tengo un campo de referencia de entidad con un solo valor. Lo siguiente funcionó para mí: $ wrapper-> field_entity_reference-> set (NULL);
Marcos Buarque

3

Además de otras respuestas y comentarios, si el campo es múltiple y obligatorio, como se señaló anteriormente, no puede usar

$wrapper->field_example_multiple->set()

$wrapper->field_example_multiple->set(NULL)

ni siquiera $wrapper->field_example_multiple->set(array()),

pero en su lugar, puede usar lo siguiente si desea borrar el campo de todos sus valores:

$wrapper->field_example_multiple->set(array(NULL));

De hecho, esto funciona tanto si el campo de valor múltiple está configurado como 'requerido', por lo que recomendaría usarlo siempre para garantizar que su código sea sólido.

(Por supuesto, si el campo es 'obligatorio', entonces quizás no debería borrarlo por completo de todos modos, pero su código podría estar haciendo esto como un paso preliminar para eliminar toda la entidad o algo similar, por lo que hay momentos en que podría solo se legítimo.)


Tenga en cuenta que usar `$ wrapper-> field_example_multiple-> set (array (NULL))` conducirá a tener un elemento NULL en la matriz de datos. Este método no borra los valores, sino que establece la matriz de valores en un solo NULLvalor.
Alex Skrypnyk

Buen punto. Supongo que eso nos devuelve a mi comentario sobre no borrar un valor requerido. Probablemente se hace imposible intencionalmente.
Martin Q

De hecho, un campo obligatorio debe tener al menos un valor no nulo. Si desea restablecer un campo multivalor requerido, simplemente sobrescríbalo con el nuevo valor. Es decir:$product_display->field_product = array($product_id);
Interdruper

2

Parece que las complejidades enumeradas en los otros comentarios solo son relevantes para un campo obligatorio. Si el campo no es obligatorio, esto debería ser bastante simple:

$wrapper->field_foo = NULL;

Puede usar el contenedor para verificar las propiedades del campo:

$properties = $wrapper->getPropertyInfo();
$field_required = !empty($properties['field_foo']['required']);

Dependiendo del contexto, también puede obtener las propiedades del campo usando:

$wrapper->getPropertyInfo('field_foo');

1

Otra solución para este problema podría ser EntityMetadataWrapper::clear

$entity_wrapper->field->clear()


El método EntityMetadataWrapper :: clear se declara como "protegido", por lo que no se puede llamar desde su código: solo se puede acceder a los métodos "públicos" directamente desde fuera del objeto.
Interdruper
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.