Bloque

Vitaminando un webform. [Modulo Drupal]

Bloque

Cuando repetimos un código muchas veces para usarlo en los proyectos, es cuando llega el momento de crear un módulo. Eso nos ha pasado con una necesidad que teníamos al tratar con usuarios anónimos en webform: que no se pudieran duplicar envíos con un mismo email o un mismo DNI.

WebformData

La solución era sencilla, modificamos el formulario con  hook_form_alter(&$form, &$form_state, $form_id), comprobamos el ID del webform y lo validamos con una funcion que comprueba si está ese dato en la tabla  webform_submitted_data :

/* validar formularios */ 
function EJEMPLO_form_alter(&$form, &$form_state, $form_id){ 
 if ($form['form_id']['#value']=='webform_client_form_'.$ID_WEBFORM):
   $form['#validate'][] = 'EJEMPLO_form_validate'; 
  endif; 
 } 
        
function EJEMPLO_form_validate($form, $form_state) { 
/* VALIDAMOS QUE EXISTE */ 
 $id = $form['#form_id']; 
 $dato = $form_state['values']['submitted']['email']; /* En este caso el email */ 

 /* el id_formulario lo toma de una funcion que le indica donde está el cid dentro de la tabla webform_submitted_data */ 
 if (count(_existsdato($dato, $id_formulario)) >= 1) { //Si hay 1 es que ya está en la bbdd 
  form_set_error('email', t('El email ya está dado de alta')); // display error and highlight 
 } 
} 
        
function _existsdato($dato, $id) { 
 $result = db_select('webform_submitted_data', 'u')
        	 ->fields('u', array('sid', 'data')) 
        	 ->condition('nid', $id[0], ' = ') 
        	 ->condition('cid', $id[1], ' = ') 
        	 ->condition('data',$dato, ' = ') 
        	 ->execute() 
        	 ->fetchAll(); 
 return $result; 
}

No está mal la solución, pero siempre que se genera un nuevo webform hay que modificar el código e incluir el nuevo id, y eso hace que el trabajo que no vaya tan rápido porque no soy yo el que me encargo de crearlos (sí,  @jlucles, te miro a ti) .

Así que para evitar todo esto "tiramos" del módulo Webform Validation y su  hook _webform_validation_validate($validator_name, $items, $components, $rule) y todos nuestros problemas desaparecieron ;)

Ahora todos los valores que necesitamos para validar el formulario los obtenemos del parametro $rules de la función anterior. De esta forma tenemos:

  • id del formulario : $rule['nid'];
  • cid del campo de busqueda: $rule['components'][0]['cid'];

Ya se puede validar que un campo no esté duplicado en otro envío. Y como de costumbre, hemos añadido un extra:  que también valide el DNI, algo que hemos necesitado alguna que otra vez ;)

Descarga el módulo desde nuestra cuenta sandbox.

Bloque

En geekia diseñamos servicios y productos digitales pensados para las personas. Si quieres que te ayudemos a crear experiencias relevantes para tus clientes, contacta con nosotros.