En el artículo anterior “Validación de formularios con CodeIgniter”, se comentaba sobre la importancia de validar los datos de entrada por formularios en nuestra aplicación web, así como sanearlos, formatearlos y prepararlos para la inserción en la base de datos, de forma que mantengamos la integridad de la BD y el funcionamiento del servidor y el sitio web.
Comentaba también sobre el uso del FormValidation de CodeIgniter, que nos permite asociar reglas existentes (como required) a los componentes visuales, con lo cual se mostrarán mensajes de errores predefinidos, a los cuales les podemos dar el formato de salida que queramos.
A todo esto, podemos adicionar reglas y mensajes propios, y es sobre esto que quiero compartir mis recientes experiencias.
Parto de la necesidad que tuve de subir al servidor un archivo de imagen (un avatar para los usuarios de mi sistema). Con el siguiente código incorporas el componente visual que te permite escoger un fichero.
<input type="file" name="userfile_pic" >
El input de tipo file permite seleccionar ficheros cuyos datos puedes acceder a través de las variables de php$HTTP_POST_FILES o $_FILESa partir de PHP 4.1.0. Por ejemplo puedes usar:
$HTTP_POST_FILES['userfile_pic']['name'];
//nombre original del fichero en la PC cliente
$HTTP_POST_FILES['userfile_pic']['type'];
//tipomime delfichero, ej. "image/gif"
$HTTP_POST_FILES['userfile_pic']['size'];
//tamaño del fichero
Lo primero que debes notar es que he usado el nombre del componente tipo file dentro del primer corchete. La mayoría de los ejemplos que puedas encontrar toman por defecto el nombre userfile, pero debes tener cuidado de que el nombre coincida con el que has puesto en la vista.
Si pruebas este código es probable que obtengas un mensaje de que no se ha seleccionado ningún fichero. En ese caso seguramente te faltó poner tu formulario comomultipart. Usando CodeIgniter lo pones así:
<?php echo form_open_multipart('direccion_fichero_script');?>
Bueno, si decides continuar con php básico, utilizas el is_uploaded_file(), que te sube el archivo y te retorna el error en caso de haberlo. Pero mi propósito es usar FormValidation para asegurarme de que el fichero es válido, usando el mismo mecanismo de validación que para el resto de los componentes visuales.
Para esto empleamos la clase de subir ficheros de CodeIgniter.En el siguiente ejemplo he indicado la carpeta hacia la que voy a subir el fichero en el servidor, el tipo de fichero que quiero recibir (* para cualquier tipo), el tamaño máximo de fichero y el ancho y alto, pues en mi caso voy a subir imágenes.El overwrite permite sobrescribir los ficheros en el servidor. He cargado la clase upload que trae CodeIgniter en una de sus bibliotecas, y al cargarla le he pasado mi configuración. También he capturado el error en caso de haberlo.do_uploadintentasubir el fichero.
function valid_file()
{
$config['upload_path'] = './uploads/';
$config['allowed_types'] = 'gif|jpg|png';
$config['overwrite'] = TRUE;
$config['max_size'] = '100';
$config['max_width'] = '1024';
$config['max_height'] = '768';
$this->load->library('upload', $config);
if ( ! $this->upload->do_upload()){
$error = array('error' => $this->upload->display_errors());
…
}
else
…
}
Hasta ahí el código funciona si el componente visual se llama userfile, que es el que espera CodeIgniter por defecto. Si el nombre es otro, como en mi ejemplo, basta decir:
$this->upload->do_upload('userfile_pic');
Bien, ahora transformaremos la función anterior para combinarla con FormValidation. Te pongo solamente el segmento que cambia:
function valid_file()
{
…
if ( ! $this->upload->do_upload('userfile_pic'))
{
$error = array('error' => $this->upload->display_errors());
$this->form_validation->set_message('valid_file',$error);
return FALSE;
}
else
{
return TRUE;
}
}
Si se cargó retorno TRUE, sino retorno FALSE y declaro que el mensaje de error para la función valid_file es $error. En lugar de $error puedes poner un mensaje propio, pero aquí reutilizo el que me retorna CodeIgniter que es más informativo.
Ahora creamos la regla para validar el componente userfile_pic. Esto lo pones en la función donde haces la validación de los demás componentes. El detalle está en ponerle callback_ a la función que hace el chequeo.
$this->form_validation->set_rules('userfile_pic', 'Imagen', 'callback_valid_file');
Esta es la manera de crear nuevas reglas, haces una función que revise lo que quieres validar y que retorna verdadero o falso (para que funcione el if ($this->form_validation->run() == FALSE)), y creas una regla poniendo callback_nombre_de_la_funcion.
Si resultó positivo puedes acceder al nombre del fichero, que ya está en el servidor, a través del mismo$_FILES['userfile_pic']['name'], y guardar el nombre en la base de datos.
Si quieres subir varios ficheros desde un mismo formulario, puedes ponerle a todos los input files el mismo nombre con corchete (ej. file_name[]), y accedes a ellos a través de:
$_FILES['filename']['name'][0];
$_FILES['filename']['name'][1];
…
O puedes ponerles nombres distintos y usar
$this->upload->do_upload('filename1');
$this->upload->do_upload('filename2');
…
Bueno, como puedes ver no es complicado crear nuevas reglas de validación. A la vez, hemos usado otra clase de CodeIgniter que nos permite cargar ficheros, demostrando así sus potencialidades para desarrollar sitios seguros, funcionales y con un código organizado, necesario para posteriores mantenimientos.