En la documentación de CodeIgniter, disponemos de un breve pero útil tutorial para el buen uso de File Uploading class, que nos permite procesar input files, y obtener las propiedades del archivo en cuestión para el uso que estimemos oportuno.
El problema se presenta cuando estamos procesando el formulario en el que se encuentra el hipotético input file mediante de ajax. En ese punto hay diversas alternativas. Lo habitual, imagino, es usar uno de esos cómodos y efectivos plugins de jquery (el framework de js que uso para el proyecto). Sin embargo, me encontré con problemas graves a la hora de integrar la lógica del plugin con la estructura MVC de CodeIgniter.
Eso, y que soy un tipo perezoso poco dado a abrir nuevos caminos a la humanidad, me ha llevado a buscar el camino más directo y rápido. La idea es la siguiente:
- Presentamos un formulario, y en vez de incluir el input file, mostramos un vínculo “Upload File”.
- Cuando el usuario pincha en el vínculo, mostramos pop-up (mi opción personal) desde el que subiremos el archivo.
- Una vez subido el archivo, mostramos confirmación y pasamos toda la información del archivo a la pantalla inicial, donde podemos mostrar la previsualización de la imagen (si es una imagen) y disponernos a guardar la información precisa cuando enviemos el formulario a procesar.
A continuación os paso el código, que sigue en todo lo posible el tutorial original de File Uploading Class de Codeigniter, con las modificaciones necesarias.
Primero creamos el controlador upload.php, que es muy parecido al del tutorial original.
<?php
class Upload extends Controller {
function Upload()
{
parent::Controller();
$this->load->helper(array(’form’, ‘url’));
}
function index()
{
$this->load->view(’index_form’);
}
function popup_file()
{
$this->load->view(’upload_form’, array(’error’ => ‘ ‘ ));
}
function do_upload()
{
$config['upload_path'] = ‘./uploads/’;
$config['allowed_types'] = ‘gif|jpg|png’;
$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());
$this->load->view(’upload_form’, $error);
}
else
{
$data = array(’upload_data’ => $this->upload->data());
$this->load->view(’upload_success’, $data);
}
}
}
?>
A continuación creamos las 3 vistas que carga el controlador.
Primero, index_form.php, la vista inicial donde queremos cargar la imagen sin que haya refresco de pantalla, junto con las propiedades que más tarde guardaremos en una base de datos, o utilizaremos como creamos conveniente.
<head>
<title>Upload Form</title>
</head>
<body>
<?php
$atts = array(
‘width’ => ‘400′,
‘height’ => ‘500′,
’scrollbars’ => ‘yes’,
’status’ => ‘yes’,
‘resizable’ => ‘yes’,
’screenx’ => ‘0′,
’screeny’ => ‘0′
);
echo anchor_popup(’upload/popup_file’, ‘Upload file’, $atts);
?>
<div id=”file_info”></div>
</body>
</html>
Ahora, creamos upload_form.php, el formulario donde se realiza el envío del archivo, y que se cargará dentro del pop-up:
<html>
<head>
<title>Upload Form</title>
<script type=”text/javascript” src=”<?php echo base_url();?>js/jquery/jquery.js”></script>
<script language=”javascript” type=”text/javascript”>
$(document).ready(function(){
$(”#btn_send”).click( function (e) {
e.preventDefault();
$(”#frm_image”).submit();
});
});
</script>
</head>
<body>
<?php echo $error;?>
<form
action=”<?php echo site_url(’upload/do_upload’); ?>”
enctype=”multipart/form-data”
method=”post”
id=”frm_image” >
<input type=”file” name=”userfile” id=”userfile” size=”20″ />
<a href=”" id=”btn_send”>Enviar</a>
</form>
</body>
</html>
Finalmente, la vista upload_success.php, que en el tutorial muestra las propiedades del archivo procesado, nos va a servir para reenvíar mediante jquery todas esas interesantes propiedades a la ventana original:
<html>
<head>
<title>Upload Form</title>
<script type=”text/javascript” src=”<?php echo base_url();?>js/jquery/jquery.js”></script>
<script language=”javascript” type=”text/javascript”>
$(document).ready(function(){
$(”#volver”).click(function(e){
e.preventDefault();
var op = window.opener.document;
$(”#file_info”,op).append($(”#file_info”).html());
window.close();
});
});
</script>
</head>
<body>
<h3>Your file was successfully uploaded!</h3>
<div id=”file_info”>
<ul>
<?php foreach($upload_data as $item => $value):?>
<li><?php echo $item;?>: <?php echo $value;?></li>
<?php endforeach; ?>
</ul>
<img src=”<?php echo base_url() . ‘uploads/’ . $upload_data['file_name']; ?>” border=”0″ />
</div>
<a href=”" id=”volver”>Volver</a>
</body>
</html>
Bueno, cómo veis es muy sencillo y básico. Infinitamente mejorable. Pero cuando sientes el aliento del cliente en el cogote, lo “perfecto” puede ser enemigo de lo “bueno”.
Felices fiestas.