Facebook Google+


Aporte Clase de Uploads multiples para CodeIgniter
#1
Necesitaba una clase para manejar uploads multiples en CodeIgniter, he probado algunas de GitHub pero ninguna me funciono como esperaba asi que hice esta que funciona muy bien.

Asumiendo que en la vista que contiene un Form se tiene algo como esto:

Código:
<form role="form" method="post" enctype="multipart/form-data" action="/process">
...

          <div class="form-group">
                <label>Fotos</label><p/>
                <input name="imagenes[]" type="file" class="multi" accept="gif|jpg|png" multiple/>                    
            </div>
...

Donde rescatamos que el Name es "imagenes[]", entonces en el metodo que procesa ese formulario que contiene imagenes tendriamos algo similar a esto:

Código PHP:
...
    if (isset(
$_FILES))
        {     
            
$location 'images/uploads';
    
            
$this->uploadmulti->setName('imagenes');    
            
$this->uploadmulti->setLocation($location);                
            
$this->uploadmulti->doUpload();

            
$files_ok $this->uploadmulti->getFileNames();    
            foreach    (
$files_ok as $file)        
                
$this->fotosproductos_m->createFotosproducto($file,1,$id_insert);    
              
            
$this->images->setFixedRatio(TRUE);
            
$this->images->setLocation($location);
            
$this->images->setWidth(100)->setHeight(100)->makeThumb($files_ok);             
            
$this->images->setWidth(50)->setHeight(50)->makeThumb($files_ok);
        }
... 

Si analizamos ese trozo de codigo de un metodo "process()" o similar donde dijimos que procesamos el formulario vemos que consta de 3 partes:

1) Gestionamos la subida y ubicacion final de las imagenes, dejando a la clase la creacion de un directorio con el nombre del Id del "producto" o de la entidad que contenga imagenes.
2) Insertamos las imagenes en su tabla asociada
3) Podriamos hacer miniaturas (thumbnails) de cada imagen, nuevamente la clase se encarga del scaffolding.

Solo por si aclara alguna duda voy a mostrar mi metodo process() pero es por supuesto ya algo particular porque depende de la aplicacion que esten desarrolllando:

Código PHP:
public function process()
    {                       
        if (!
form_sent()){
            echo 
"Error: No se recibio ningun dato";    
            exit;
        }    
        
        
$this->load->model(['productos_has_categorias_m']);        
            
        
$data form_data(['Categoria']);
        
$data['Estado'] = 1;
        
$id_insert$this->productos_m->insertProducto($data);
        
        if (isset(
$_FILES))
        {     
            
$location 'images/uploads/'.strtolower(__CLASS__).'/'.$id_insert;
    
            
$this->uploadmulti->setName('imagenes');    
            
$this->uploadmulti->setLocation($location);                
            
$this->uploadmulti->doUpload();

            
$files_ok $this->uploadmulti->getFileNames();    
            foreach    (
$files_ok as $file)        
                
$this->fotosproductos_m->createFotosproducto($file,1,$id_insert);    
              
            
$this->images->setFixedRatio(TRUE);
            
$this->images->setLocation($location);
            
$this->images->setWidth(100)->setHeight(100)->makeThumb($files_ok);             
            
$this->images->setWidth(50)->setHeight(50)->makeThumb($files_ok);
        }  
        
        
# Asocio a Categorias 
                
        
foreach ($_POST['Categoria'] as $idCategoria)
            
$this->productos_has_categorias_m->createProductosHasCategoria($id_insert,$idCategoria);        

        
# Asocio a Marcas        
        
....
    } 

Ahora las clases que he creado para manejar los Uploads y crear los Thumbnails:

libraries/MultiUpload.php

Código PHP:
<?php

class UploadMulti
{
    private 
$filenames  = [];
    private 
$settings    = [];
    private 
$nameAttr;
    private 
$location;
    
    
    
// @param string atributo Name del o de los INPUT TYPE='file'
    
public function setName($name){
        
$this->nameAttr $name;
        return 
$this;
    }    
    
    
// @param string path (sin / al final)
    
public function setLocation($path){
        
$this->location $path;
        return 
$this;
    }    
    
    public function 
getFileNames(){
        return 
$this->filenames;
    }
        
    public function 
doUpload()
    {        
        
mkdir_ignore($this->location);            
                
        
$i 0;
        foreach (
$_FILES[$this->nameAttr]["error"] as $key => $error)
        {            
            if (
$error == UPLOAD_ERR_OK)
            {
                
$tmp_name $_FILES[$this->nameAttr]["tmp_name"][$key];
                
$this->filenames[$i] = basename($_FILES[$this->nameAttr]["name"][$key]);
                
move_uploaded_file($tmp_name$this->location."/{$this->filenames[$i]}");
                
$i++;                
            }
        }
    }    

    
    


libraries/Images.php

Código PHP:
<?php

class Images
{
    private 
$CI;
    
    private 
$settings =    ['image_library' =>'gd2',
                         
'create_thumb'=>TRUE,
                         
'maintain_ratio'=>FALSE
                        
];

                        
    public function 
__construct(){        
        
$this->CI = &get_instance();
        
$this->CI->load->library(['image_lib']);         
    }    
                        
    
// @param bool keep aspect ratio
    // si es TRUE, entonces la altura es $height y el ancho es <= $width
    
public function setFixedRatio($ratio){
        
$this->settings['maintain_ratio'] = $ratio
        return 
$this;
    }
    
    public function 
setWidth($width){
        
$this->settings['width'] = $width;
        return 
$this;
    }
        
    public function 
setHeight($height){
        
$this->settings['height']= $height;    
        return 
$this;
    }
    
        
// @param string path (sin / al final)
    
public function setLocation($path){
        
$this->location $path;
        return 
$this;
    }    
    
    
/*
        Thumb de una o varias imagenes
        @param array de nombres de archivos a ser redimensionados ubicados en location
        @param integer
        @param integer
    */        
    
public function makeThumb(array $files,$width=NULL,$height=NULL)
    {               
        if (!empty(
$width))  $this->settings['width']  = $width;
        if (!empty(
$height)) $this->settings['height'] = $height;
        
        if (empty(
$width) || empty($height))
            throw new 
RuntimeException("width y height son requeridos!");
    
        
$ori_path $this->location;
        
$des_path $ori_path.'/'.$width.'x'.$height;     
        
        
mkdir_ignore($des_path);        
    
        foreach (
$files as $file)
        {            
            
$new_file str_replace ('.','_thumb.',$file);
            
            
$this->settings['source_image'] = $ori_path.'/'.$file;      
            
$this->settings['new_image'] = $des_path.'/'.$new_file;    
                        
            
$this->CI->image_lib->initialize($this->settings); // sino se mama
            
$this->CI->image_lib->resize();
            
$this->CI->image_lib->clear();                            
        }
    }        
    


Eso esto amigos Smile
 
Reply
#2
Para que necesito guardar la instancia de CodeIgniter en $CI ? veo que haces eso en la clase Images
 
Reply
#3
Lo que sucede es que no puedo hacer $this->load->library(['alguna_libreria']) dentro de alguna una libreria, simplemente no va a funcionar porque $this normalmente hace referencia a clase que extiende a CI_Controller (pues lo normal es usar librerias en controladores y no dentro de otras librerias), entonces me guardo una instancia de CodeIgniter y soluciono:

Código PHP:
$this->CI = &get_instance();
$this->CI->load->library(['image_lib']); 
 
Reply
  


Salto de foro:


Browsing: 1 invitado(s)