CodeIgniter + Uploadify. Subir múltiples imágenes y redimensionarlas.
Como muchos sabrán nos encanta trabajar con CodeIgniter y jQuery, por lo que en mucho de nuestros proyectos utilizamos tanto, lo que para nuestro concepto es, el mejor Framework de PHP como la mejor librería de Javascript. En este post trataré de explicar como hicimos funcionar el CodeIgniter junto con Uploadify, un plugin en jQuery para multicargas de archivos.
Subir varios archivos con simple HTML, Javascript y PHP no es fácil y aunque el HTML5 nos trae algunas mejoras al respecto aún no podemos utilizarlas a fondo puesto que no todos los exploradores web permiten estas funcionalidades aún (Google Chrome si, por ejemplo).
En este post explicaremos como hacer una aplicación muy pequeña que permitiría subir múltiples imágenes al servidor y achicarlas en 3 tamaños distintos de forma automática y por medio de jQuery + Uploadify y CodeIgniter.
Cambios en el /applications/config/mimes.php
El primer error que tuvimos fue que, por obligación, la librería “File Upload” necesita un parámetro llamado “allowed_types” en donde se especifican los tipos de archivos (o extensiones) que se pueden utilizar para subir archivos. Como ibamos a subir múltiples imágenes (fotografías) nuestros archivos serían del tipo *.jpg y *.jpeg primordialmente. Sin embargo, recibíamos un error donde nos decía que no podíamos subir archivos de este tipo, aún cuando eran imágenes.
La solución fue muy simple y la encontramos en el foro de CodeIgniter. Debemos ir a: /applications/config/mimes.php (donde se manejan los MIME) y agregar a las extensiones ‘jpg’, ‘jpeg’ lo siguiente:
'jpeg' => array('image/jpeg', 'image/pjpeg', 'application/octet-stream'),
'jpg' => array('image/jpeg', 'image/pjpeg', 'application/octet-stream'),
'jpe' => array('image/jpeg', 'image/pjpeg', 'application/octet-stream'),
'png' => array('image/png', 'image/x-png', 'application/octet-stream'),
El ‘application/octet-stream’ es el que hace la mágia en todo esto.
Controller
<?php
class Index extends Controller
{
public function __construct()
{
parent::__construct();
// Loader
$this->load->helper('url');
$this->load->config('application');
}
public function index()
{
$this->load->view('index');
}
public function upload()
{
# Configuracion de la libreria
# 'img_path' esta en /applications/config/pixmat.php
$config['upload_path'] = $this->config->item('upload_path');
$config['allowed_types'] = 'jpg|gif|png';
$config['encrypt_name'] = 'TRUE';
$config['max_size'] = '71680';
$config['max_width'] = '8000';
$config['max_height'] = '8000';
$this->load->library('upload', $config);
# Uploading
if ( ! $this->upload->do_upload('Filedata')) {
# Error
$errors = $this->upload->display_errors();
# nombre de la imagen, evitando errores
$image_name = NULL;
} else {
# Nombre de la foto
$imageData = $this->upload->data();
$image_name = $imageData['file_name'];
$image_ext = $imageData['file_ext'];
# Achicamos la foto
if( ! $this->resizePhoto($image_name)){
$errors = "La imagen no pudo redimensionarse correctamente";
} else {
# Agregamos a la base de datos
$data = array(
'title' => 'Foto sin titulo',
'image' => $image_name,
'active' => 0
);
# ID recien creado, verificamos
$id = $this->photos_model->create($data);
if ( ! $id) {
$errors = "La imagen no pudo ingresarse a la DB";
}
}
}
// Error?
if (isset($errors)){
# Borramos la foto (si existe)
$id = isset($id) ? $id : NULL;
$this->deletePhoto($id, $image_name);
echo $errors;
}
}
private function resizePhoto($name)
{
# Load library
$this->load->library('image_lib');
// Achicamos a 1024x768
$config['image_library'] = 'gd2';
$config['source_image'] = $this->config->item('upload_path') . $name;
$config['new_image'] = $this->config->item('upload_path') . '1024x768/' . $name;
$config['maintain_ratio'] = TRUE;
$config['width'] = 1024;
$config['height'] = 768;
$this->image_lib->initialize($config);
if ( ! $this->image_lib->resize()){
$error = TRUE;
}
/*
// Le ponemos watermark, tenemos que utilizar otra configuracion, puesto que vamos a trabajar
// con el thumbnail y vamos a ponerle watermark
$config2['image_library'] = 'gd2';
$config2['source_image'] = $this->config->item('upload_path') . '1024x768/' . $name;
$config2['wm_type'] = 'overlay';
$config2['wm_overlay_path'] = $this->config->item('watermark');
$config2['wm_vrt_alignment'] = 'middle';
$config2['wm_hor_alignment'] = 'center';
# Watermark
$this->image_lib->initialize($config2);
if ( ! $this->image_lib->watermark()){
$error = TRUE;
}
*/
// Achicamos a 800x600
$config['source_image'] = $this->config->item('upload_path') . '1024x768/' . $name;
$config['new_image'] = $this->config->item('upload_path') . '800x600/' . $name;
$config['width'] = 800;
$config['height'] = 600;
$this->image_lib->initialize($config);
if ( ! $this->image_lib->resize()){
$error = TRUE;
}
// Achicamos a 400x300
$config['source_image'] = $this->config->item('upload_path') . '1024x768/' . $name;
$config['new_image'] = $this->config->item('upload_path') . '400x300/' . $name;
$config['width'] = 400;
$config['height'] = 300;
$this->image_lib->initialize($config);
if ( ! $this->image_lib->resize()){
$error = TRUE;
}
# Error ?
if (isset($error) and $error === TRUE) {
return FALSE;
} else {
return TRUE;
}
}
private function deletePhoto($id, $image)
{
# Delete from the DB
if ($id !== NULL) {
$this->photos_model->delete($id);
}
if ($image !== NULL) {
# Borramos todas las imagenes (si existen). Evitamos warnings con el @ adelante
@unlink($this->config->item("upload_path") . $image);
@unlink($this->config->item('upload_path') . '1024x768/' . $image);
@unlink($this->config->item('upload_path') . '800x600/' . $image);
@unlink($this->config->item('upload_path') . '400x300/' . $image);
}
}
}
/* End of file index.php */
/* Location: ./application/modules/photos/controllers/index.php */
Hay que tomar en cuenta algunas cosas en el código:
- El nombre del $_FILE que envía el Uploadify se llama “Filedata”.
- El código es básico, no estamos haciendo muchas comprobaciones pero es para tener una idea. Igualmente el verifica si se subió bien y si no se elimina el archivo y el record de la DB.
- No pondremos las operacionse del Model porque son sencillas.
- La librería “image_lib” no es necesaria hacerle el $this->image_lib->clear().
- Usamos los PATH donde están las fotografías en archivos dentro de la configuración para que sea más fácil a la hora de cambiar de servidores.
View
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>index</title>
<script type="text/javascript" charset="utf-8" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>uploadify/scripts/swfobject.js"></script>
<script type="text/javascript" src="<?php echo base_url(); ?>uploadify/scripts/jquery.uploadify.v2.1.0.min.js"></script>
</head>
<body>
<h3>Subir fotos</h3>
<p>
<input id="files" name="files" type="file" />
</p>
<p>
<button class="button" id="subirFotos"><span>Subir fotografías</span></button>
</p>
<script type="text/javascript" charset="utf-8">
// <![CDATA[
$(document).ready(function() {
$("button#subirFotos").click(function() {
// Hay archivos por subir?
if ($('#files').uploadifySettings('queueSize') > 0) {
$('#files').uploadifyUpload();
}
// Return false para evitar cualquier accion en el boton
return false;
});
$('#files').uploadify({
'uploader' : '/uploadify/uploadify/scripts/uploadify.swf',
'script' : '<?php echo base_url(); ?>/index/upload',
'cancelImg' : '/uploadify/uploadify/cancel.png',
'auto' : true,
'folder' : '/uploadify/uploads',
'queueSizeLimit' : '10',
'multi' : true,
'fileDesc' : '.jpg, .png, .gif, .jpeg',
'fileExt' : '*.jpg;*.jpeg;*.png;*gif',
'auto' : false,
'buttonText' : 'SELECCIONAR'
});
});
// ]]>
</script>
</body>
</html>
Esta entrada fue escrita el Viernes Abril 23rd, 2010 a las 11:52 am y fue guardada dentro de la categoría de CodeIgniter, jQuery. Puedes dejar una respuesta, o un trackback desde tu propio sitio.