Yii Framework Forum: Subir Archivos Multiples - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Subir Archivos Multiples subida multiple de archivos y guardar en bd Rate Topic: -----

#1 User is offline   codecobalea 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 02-January 13

Posted 25 February 2013 - 07:10 AM

Saludos:

Estoy intentado subir archivo de manera multiple, que se puedan seleccionar de manera multiple.

He probado
- cmultifileupload ( pero no deja seleccionar multiples archivos)
- coco pero no puedo guardar en la base de datos
- plupload, no sube los archivos

Alguien podria darme alguna opcion , ayudarme o mostrarme un tutorial con los mencionados para que lo pueda realizar.

Gracias por vuestra ayuda.
0

#2 User is offline   playdog 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 17
  • Joined: 02-April 12

Posted 25 February 2013 - 09:36 AM

Hola amigo, claro que puedes, yo desarrollé una aplicación que hace lo mismo que quieres.



Use la extension: EAjaxUpload


Descargas la extension, y la dejas en la carpeta extension.

Ahora en la carpeta raiz de tu proyecto web, crear una carpeta llamada: uploads.

En tu controlador creas un nuevo metodo llamado: actionUpload

public function actionUpload() {
        Yii::import("ext.EAjaxUpload.qqFileUploader");

        $folder = 'uploads/'; // folder for uploaded files
        $allowedExtensions = array("pdf", "mp3", "mp4", "wmv"); //array("jpg","jpeg","gif","exe","mov" and etc...
        $sizeLimit = 10 * 1024 * 1024; // maximum file size in bytes
        $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
        $result = $uploader->handleUpload($folder);
        $return = htmlspecialchars(json_encode($result), ENT_NOQUOTES);

        $fileSize = filesize($folder . $result['filename']); //GETTING FILE SIZE
        $fileName = $result['filename']; //GETTING FILE NAME

        echo $return; // it's array 
    }



En la vista inserta este codigo para que aparezca el boton de subir archivos:



<?php
                        $this->widget('application.extensions.EAjaxUpload.EAjaxUpload', array(
                            'id' => 'fileUploader',
                            'config' => array(
                                'action' => Yii::app()->createUrl('/publicacion/upload'),
                                'allowedExtensions' => array("pdf","mp3","mp4"), //array("jpg","jpeg","gif","exe","mov" and etc...
                                'sizeLimit' => 1 * 1024 * 1024 * 100, // maximum file size in bytes
                                'minSizeLimit' => 1024, // minimum file size in bytes
                                'onComplete' => "js:function(id, fileName, responseJSON){ $('#archivo').val(fileName); $('#botones').css('display','inline'); }",
                           
                            )
                        ));
                        ?>


Mucha atanecion en la linea: Action, esta llamando al controlador y despues llama al metodo upload que creamos en el inicio.


Ahora el la carpeta de la extension, edita el archivo: EAjaxUploadAction.

Yii::import("ext.EAjaxUpload.qqFileUploader");

class EAjaxUploadAction extends CAction
{

        public function run()
        {
                // list of valid extensions, ex. array("jpeg", "xml", "bmp")
                $allowedExtensions = array("pdf","mp3","mp4","wmv");
                // max file size in bytes
                $sizeLimit = 1 * 1024 * 1024;

                $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
                $result = $uploader->handleUpload('uploads/');
                // to pass data through iframe you will need to encode all html tags
                $result=htmlspecialchars(json_encode($result), ENT_NOQUOTES);
                echo $result;
        }
}





Esta forma el sube los archivos a la carpeta: uploads. Y lo que hago es guardar la ruta del archivo en la base de datos y asi llamo los archivos cuando los necesite.

Otro dato que te doy es: en el momento de subir los archivos yo creo un randomico que al final del nombre del archivo me le agregue el resultado, esto para evitar que en un futuro 2 archivos tengan el mismo nombre.

Recuerda que para subir archivos pesados, debes ademas editar la configuración de tu php para expandir el limite de subidas por archivo
1

#3 User is offline   codecobalea 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 02-January 13

Posted 25 February 2013 - 01:27 PM

Saludos playdog:



gracias por tu respuesta, estoy intentando hacerlo correr, pero de momento me arroja failed y no sube. te comento donde creo que puede fallar haber si me puedes ayudar. lanza este

me lanza este error en el log 2013/02/25 19:43:08 [error] [exception.CHttpException.404] exception 'CHttpException' with message 'No es posible resolver la solicitud "upload"' in public_html/framework/web/CWebApplication.php:287


este es mi variable folder en el controlador--> $folder = Yii::app()->basePath.'/../galeria/'; // folder for uploaded files

esta linea en el widget no se exactamente que poner segun lo que me dices.

esta linea en EAjaxuploaderAction.php debo cambiarla-->$result = $uploader->handleUpload('upload/');

Otra pregunta seria que este plugin es multiple solo con drag an drop o debo colocar en el widget algun parametro para que me deje seleccionar mas de una imagen.

De nuevo muchas gracias
0

#4 User is offline   ferminako 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 64
  • Joined: 27-February 13

Posted 05 March 2013 - 04:14 PM

View Postcodecobalea, on 25 February 2013 - 01:27 PM, said:

Saludos playdog:



gracias por tu respuesta, estoy intentando hacerlo correr, pero de momento me arroja failed y no sube. te comento donde creo que puede fallar haber si me puedes ayudar. lanza este

me lanza este error en el log 2013/02/25 19:43:08 [error] [exception.CHttpException.404] exception 'CHttpException' with message 'No es posible resolver la solicitud "upload"' in public_html/framework/web/CWebApplication.php:287


este es mi variable folder en el controlador--> $folder = Yii::app()->basePath.'/../galeria/'; // folder for uploaded files

esta linea en el widget no se exactamente que poner segun lo que me dices.

esta linea en EAjaxuploaderAction.php debo cambiarla-->$result = $uploader->handleUpload('upload/');

Otra pregunta seria que este plugin es multiple solo con drag an drop o debo colocar en el widget algun parametro para que me deje seleccionar mas de una imagen.

De nuevo muchas gracias


Estoy interesado en un sistema de subida de archivos, esta funcionando este finalmente con subida multiple?
Gracias.
0

#5 User is offline   ferminako 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 64
  • Joined: 27-February 13

Posted 06 March 2013 - 05:15 PM

tampoco me funciona...
0

#6 User is offline   playdog 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 17
  • Joined: 02-April 12

Posted 11 March 2013 - 10:50 AM

Hola, bueno aquí dejo explicado con mas detalle el proceso de subir múltiples archivos en YII Framework:



El sistema funciona asi: en el momento de seleccionar el archivo, este quedara almacenado en la carpeta llamada "uploads" esta carpeta ha sido creada en la raiz principal del proyecto Web, se forma paralela, se guarda en la base de datos la ruta donde esta almacenado el archivo (carpeta uploads) y concatenamos con el nombre del archivo. Esto dará como resultado ejemplo: "/uploads/nombre_archivo.pdf".

Esto lo hacemos porque en bases de datos MYSQ no es recomendable almacenar archivos en los campos, y si buscamos en google tutoriales de como subir imágenes en MYSQL, nos darán ejemplo para subir imágenes directamente a los campos.


EMPEZAMOS:

1. Descomprimimos la extension llamada EAjaxUpload (la cual adjunto con este mensaje) en la ruta: "/protected/extensions/". El resultado nos dara asi: "/protected/extensions/EAjaxUpload/".



2. en la carpeta EAjaxUpload, debemos editar 2 archicvos llamados: EAjaxUploadAction y qqFileUploader; Iniciamos editando el primero:

<?php

Yii::import("ext.EAjaxUpload.qqFileUploader");

class EAjaxUploadAction extends CAction
{

        public function run()
        {
                // list of valid extensions, ex. array("jpeg", "xml", "bmp")
                $allowedExtensions = array("pdf","mp3","mp4","wmv");
                // max file size in bytes
                $sizeLimit = 1 * 1024 * 1024;

                $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
                $result = $uploader->handleUpload('uploads/');
                // to pass data through iframe you will need to encode all html tags
                $result=htmlspecialchars(json_encode($result), ENT_NOQUOTES);
                echo $result;
        }
}


De este archivo, las Lineas de codigo 11 y 16 son importantes.

linea 11:
$allowedExtensions = array("pdf","mp3","mp4","wmv");

Muestra las extensiones de archivos que son permitidas subir.

linea 16:
$result = $uploader->handleUpload('uploads/');

Muestra la ruta donde se encuentra la carpeta destinada para almacenar los archivos, esta Ruta es muy importante, recomiendo no editar su nivel de profundidad, por esto yo la he dejado en la carpeta principal de nuestro proyecto Web.


Pasamos al siguiente Nivel, por el momento no editaremos el archivo "qqFileUploader", lo explicaré mas adelante.


3. Agregando el método a nuestro controlador
Es muy importante agregar el Método que llama a la extensión a nuestro controlador, el código es el siguiente:

    public function actionUpload() {
        Yii::import("ext.EAjaxUpload.qqFileUploader");

        $folder = 'uploads/'; // folder for uploaded files
        $allowedExtensions = array("pdf", "mp3", "mp4", "wmv"); //array("jpg","jpeg","gif","exe","mov" and etc...
        $sizeLimit = 10 * 1024 * 1024; // maximum file size in bytes
        $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
        $result = $uploader->handleUpload($folder);
        $return = htmlspecialchars(json_encode($result), ENT_NOQUOTES);

        $fileSize = filesize($folder . $result['filename']); //GETTING FILE SIZE
        $fileName = $result['filename']; //GETTING FILE NAME

        echo $return; // it's array 
    }


De este metodo las lineas mas importantes son:

$folder = 'uploads/'; // folder for uploaded files

Esta Linea debe llevar la Ruta de la carpeta que almacena los archivos, esta ruta debe ser la misma que contiene el archivo "EAjaxUploadAction" de nuestra extension EAjaxUpload.


La siguiente linea:
 $allowedExtensions = array("pdf", "mp3", "mp4", "wmv"); //array("jpg","jpeg","gif","exe","mov" and etc...

Muestra las estensiones permitidas, tengan en cuenta que el mismo orden de las extensiones debe ser el mismo como se encuentra en el archivo: "EAjaxUploadAction" de nuestra extension EAjaxUpload.


4. Dando Permisos a nuestro Método actionUpload().
Muy importante dar estos permisos en el accessRules() del controlador donde creamos nuestro método actionUpload(). Ejemplo de como quedarían los permisos:

array('allow', // allow authenticated user to perform 'create' and 'update' actions
                'actions' => array('create', 'index', 'upload'),
                'users' => array('*'),
            ),


Aqui en este código, tengan en cuenta que nuestro metodo se llama: actionUpload() y lo estamos llamando como: upload y con "u" minuscula, en yii framework la palabra Action no se usa para llamar a los métodos.



5. Llamando la extensión en la vista
Ahora por Ultimo paso, necesitamos llamar la extensión en la vista del Controlador, el codigo es el siguiente:

<?php
                        $this->widget('application.extensions.EAjaxUpload.EAjaxUpload', array(
                            'id' => 'fileUploader',
                            'config' => array(
                                'action' => Yii::app()->createUrl('/publicacion/upload'),
                                'allowedExtensions' => array("pdf","mp3","mp4"), //array("jpg","jpeg","gif","exe","mov" and etc...
                                'sizeLimit' => 1 * 1024 * 1024 * 100, // maximum file size in bytes
                                'minSizeLimit' => 1024, // minimum file size in bytes
                                'onComplete' => "js:function(id, fileName, responseJSON){ $('#archivo').val(fileName); $('#botones').css('display','inline'); }",
                           
                            )
                        ));
                        ?>


La linea de codigo:
'action' => Yii::app()->createUrl('/publicacion/upload'),

Esta linea de codigo es muy importante, porque es la que esta llamando al metodo upload en el nuestro Controlador, para este caso, el Controlador se llama publicacion, seguido de "/" y el nombre del metodo "upload".

La siguiente linea de código explica de nuevo la extensiones que son permitidas Adjuntar.

--------------------------------------------------------------------------------------


Hasta aquí vamos todo bien, el permite adjuntar archivos en una carpeta que están dentro de nuestro proyecto Web, PERO el sistema informático no SABE donde se están guardando.

Para esto y para subir múltiples archivos me idee de la siguiente forma.

1. Para subir múltiples archivos, podríamos tener en un futuro el problema que 2 archivos coincidan con el mismo nombre y llegado este caso, el sistema informático lo que va a realizar es reemplazar y copiar el archivo nuevo por el que ya se encuentra almacenado.

LA SOLUCION:

Para solucionar este problema requerimos que los archivos no se llamen igual. Pero esta responsabilidad no se la podemos dejar encargada al usuario, para esto se deja encargado al sistema informático con lo siguiente: vamos a generar un número randomico (número al azar) entre 10 y 99 y el resultado se concatena con el nombre del archivo, osea, renombramos el archivo que subimos y le agregamos al nombre el número.

Con esto evitamos que en el futuro que 2 archivos tengan el mismo nombre, no sean reemplazados.

Y COMO HACEMOS ESTO?

Agregamos en la vista el sigueinte codigo:
<?php
    Yii::app()->user->setState('salt', rand(10, 99));
?>

Esta acción funciona así: en el momento que el usuario visualiza la vista, se genera una cookie que contiene el numero randomico, esta cookie la podemos llamar como si fuera una variable global que sera utilizada.



ULTIMO PASO:

Ahora si, podemos editar el archivo "qqFileUploader" que se encuentra en la carpeta de la extension EAjaxUpload.
En este archivo buscamos la funcion handleUpload.

    function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
        if (!is_writable($uploadDirectory)){
            return array('error' => "Server error. Upload directory isn't writable.");
        }

        if (!$this->file){
            return array('error' => 'No files were uploaded.');
        }

        $size = $this->file->getSize();

        if ($size == 0) {
            return array('error' => 'File is empty');
        }

        if ($size > $this->sizeLimit) {
            return array('error' => 'File is too large');
        }

        $pathinfo = pathinfo($this->file->getName());
        $filename = $pathinfo['filename'];
        //$filename = md5(uniqid());
        $ext = $pathinfo['extension'];

        if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
            $these = implode(', ', $this->allowedExtensions);
            return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
        }


        if ($this->file->save($uploadDirectory . $filename.Yii::app()->user->getState('salt'). '.' . $ext)){
            
            $modelo = new Archivos();
            
            $modelo->identificador = Yii::app()->user->getState('salt');
            $modelo->ruta = Yii::app()->request->baseUrl.'/uploads/'.$filename.Yii::app()->user->getState('salt').'.'.$ext;
            $modelo->titulo = $filename;
           
            
            $modelo->save();

            return array('success'=>true,'filename'=>$filename.Yii::app()->user->getState('salt').'.'.$ext); 
            
        } else {
            return array('error'=> 'Could not save uploaded file.' .
                'The upload was cancelled, or server error encountered');
        }

    }


De esta función la parte que nos interesa es donde se encuentra el último if:
if ($this->file->save($uploadDirectory . $filename.Yii::app()->user->getState('salt'). '.' . $ext)){
            
            $modelo = new Archivos();
            
            $modelo->identificador = Yii::app()->user->getState('salt');
            $modelo->ruta = Yii::app()->request->baseUrl.'/uploads/'.$filename.Yii::app()->user->getState('salt').'.'.$ext;
            $modelo->titulo = $filename;
           
            
            $modelo->save();

            return array('success'=>true,'filename'=>$filename.Yii::app()->user->getState('salt').'.'.$ext); 
            
        } else {
            return array('error'=> 'Could not save uploaded file.' .
                'The upload was cancelled, or server error encountered');
        }


En esta condicional IF esta preguntando si el archivo llamado: nombre_archivo + Numero randomico + la extension del archivo, fue almacenado en la carpeta uploads.

Como vemos el sigueinte codigo esta rescatando el numero randomico que generamos como una cookie:
$filename.Yii::app()->user->getState('salt')



Y dentro de la condicional se encuentra una instancia del Modelo llamado: Archivos(), esta instancia se almacena en la variable llamada: $modelo.

Este modelo: "Archivos" es una tabla de la base de datos que esta almacenando 3 campos:

1 Identificador: este es el numero que generamos de forma randomica, la cuestion es que como vamos a subir múltiples archivos, los que se suban por un usuario, contengan el mismo numero randomico, para pode identificarlos y así saber que es una subida múltiple de 1 solo usuario.

2 la RUTA donde se encuentra almacenado el archivo, el sigueinte codigo muestra el nombre real de archivo junto con la concatenacion del numero randomico.
$modelo->ruta = Yii::app()->request->baseUrl.'/uploads/'.$filename.Yii::app()->user->getState('salt').'.'.$ext;

Esta Ruta y Nombre del archivo deben coincidir con los que se encuentran en la carpeta uploads.

3 El Titulo, guardo el titulo o nombre del archivo para poder mostrarlo al usuario sin necesidad de mostrar toda la ruta donde se encuentra almacenado.




FIN

--------------------------------------------------------------------------------


Espero les sea de ayuda, Adjunto la extensión para que la usen:

Attached File(s)


1

#7 User is offline   codecobalea 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 02-January 13

Posted 12 March 2013 - 12:59 PM

Saludos playdog :

ahora funciona perfectamente, darte las gracias por haberme ayudado.

Tengo una pregunta por si me pudieras ayudar, estoy intentando pasarle un parametro y los hago de esta manera:

action' => Yii::app()->createUrl('/TblImagenes/upload',
array(
'ide'=>'el parametros',
)),
El problema es que intento recogerlo de un DropDownList, pero no puedo recoger el valor con una funcion, tienes alguna idea o algo que pueda orientarme.

Te he dado dos votos, De nuevo muchas gracias por tu ayuda.
0

#8 User is offline   codecobalea 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 02-January 13

Posted 13 March 2013 - 06:31 PM

View Postcodecobalea, on 12 March 2013 - 12:59 PM, said:

Saludos playdog :

ahora funciona perfectamente, darte las gracias por haberme ayudado.

Tengo una pregunta por si me pudieras ayudar, estoy intentando pasarle un parametro y los hago de esta manera:

action' => Yii::app()->createUrl('/TblImagenes/upload',
array(
'ide'=>'el parametros',
)),
El problema es que intento recogerlo de un DropDownList, pero no puedo recoger el valor con una funcion, tienes alguna idea o algo que pueda orientarme.

Te he dado dos votos, De nuevo muchas gracias por tu ayuda.



Saludos:

Por si a alguien le puede ayudar.

Al final lo he solucionado con una llamada ajax a un controlador y que pusiera una cookie, y esa cookie la recogo y se la asigno a la variable que quiera y la recogo en el controlador.

Si alguien conoce una forma mejor que nos la muestre, gracias a todos.
0

#9 User is offline   Miguel Garcia 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 28
  • Joined: 06-November 12

Posted 17 March 2013 - 03:17 AM

El valor del dropdown, lo puedes recoger con javascript; para enviarlo, deberás incluirlo en la construcción de la url y ya dependerá como lo estés haciendo, pero seria algo como
valor=$('#nombreDropdown').val();
url="http://www.example.com/pagina/parametro/"+valor;


Se que es una simplificación, pero sin conocer el codigo..., espero que te ayude
0

#10 User is offline   bluyell 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 222
  • Joined: 28-October 11

Posted 12 April 2013 - 09:57 PM

esta es la extensión mas facil de usar de todas, admite "multiple and single file uploads", via ajax...permite controlar el archivo subido, es muy simple de utilizar:
coco | Extension | Yii Framework
0

#11 User is offline   bluyell 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 222
  • Joined: 28-October 11

Posted 12 April 2013 - 09:57 PM

la extensión coco permite hacer todo eso que aqui necesitan, de la manera mas facil posible,
coco | Extension | Yii Framework
0

#12 User is offline   playdog 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 17
  • Joined: 02-April 12

Posted 15 April 2013 - 10:57 AM

View Postbluyell, on 12 April 2013 - 09:57 PM, said:

la extensión coco permite hacer todo eso que aqui necesitan, de la manera mas facil posible,
coco | Extension | Yii Framework



Muy Interesante, gracias por el aporte
1

#13 User is offline   MisterD 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 03-June 13

Posted 12 June 2013 - 03:36 PM

Estoy teniendo problemas con la extensión, no se que he hecho mal, estoy con el framework .13 y recibo este error:
class CocoWidget extends CWidget implements EYuiActionRunnable {

He cargado en extensions con el nombre de carpeta coco, y salta como que no existe EYuiActionRunnable.

include(EYuiActionRunnable.php): failed to open stream: No such file or directory??

Alguno le paso algo similar? Gracias.
0

#14 User is offline   MaestroOscuro 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 14-June 13
  • Location:Uruapan, Michoacán

Posted 16 August 2013 - 10:47 AM

Yo utilicé un pequeño truco, o una mexicanada, como lo quieran ver: ocupaba subir múltiples archivos, específicamente varias fotos relacionadas a un mismo registro, y manejar una especie de galería del mismo, al visualizar el registro (view) me muestra la info y las fotos al final, utilicé al inicio EAjaxUpload, pero Coco me resultó más simple para la subida, y Ad-gallery para mostrar las fotos, pero no meto en la db nada relacionado con las imágenes subidas, el "truco" fue: al visualizar el registro 1, por ejemplo, en la carpeta uploads creo con mkdir una carpeta llamada "1", y ahí es donde subo todas las imágenes, el visualizador add-gallery busca esa carpeta y muestra las fotos.
L.I. Enrique Campos Gómez
Desarrollador de Software
Municipio de Uruapan Michoacán
0

#15 User is offline   Siobeth 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 27
  • Joined: 14-June 13

Posted 21 August 2013 - 11:16 AM

Buenos Dias... Aplique lo que explico playdog para la subida de archivos.. y si efectivamente funciona perfectamente.. Ahora lo que puedo ver es que guarda automaticamente cuando sube el archivo la ruta, el identificador y el titulo.. Ahora bien caundo le doy en el boton crear para guardar en la BD me crea un registro nuevo con los datos del formulario y los del archivo pdf (identifacdor, ruta y titulo)no lo guarda(ya que se guardo en el registro anterior)..
Como hago para que esta acción se ejecute o guarde cuando le de al boton Crear o Guardar y no se guarde automaticamente??? ya que tengo varios campos en mi formulario... Gracias de Antemano..!!
0

#16 User is offline   ArturoGP 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 31-October 13

Posted 13 November 2013 - 01:15 PM

View Postplaydog, on 11 March 2013 - 10:50 AM, said:

Hola, bueno aquí dejo explicado con mas detalle el proceso de subir múltiples archivos en YII Framework:



El sistema funciona asi: en el momento de seleccionar el archivo, este quedara almacenado en la carpeta llamada "uploads" esta carpeta ha sido creada en la raiz principal del proyecto Web, se forma paralela, se guarda en la base de datos la ruta donde esta almacenado el archivo (carpeta uploads) y concatenamos con el nombre del archivo. Esto dará como resultado ejemplo: "/uploads/nombre_archivo.pdf".

Esto lo hacemos porque en bases de datos MYSQ no es recomendable almacenar archivos en los campos, y si buscamos en google tutoriales de como subir imágenes en MYSQL, nos darán ejemplo para subir imágenes directamente a los campos.


EMPEZAMOS:

1. Descomprimimos la extension llamada EAjaxUpload (la cual adjunto con este mensaje) en la ruta: "/protected/extensions/". El resultado nos dara asi: "/protected/extensions/EAjaxUpload/".



2. en la carpeta EAjaxUpload, debemos editar 2 archicvos llamados: EAjaxUploadAction y qqFileUploader; Iniciamos editando el primero:

<?php

Yii::import("ext.EAjaxUpload.qqFileUploader");

class EAjaxUploadAction extends CAction
{

        public function run()
        {
                // list of valid extensions, ex. array("jpeg", "xml", "bmp")
                $allowedExtensions = array("pdf","mp3","mp4","wmv");
                // max file size in bytes
                $sizeLimit = 1 * 1024 * 1024;

                $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
                $result = $uploader->handleUpload('uploads/');
                // to pass data through iframe you will need to encode all html tags
                $result=htmlspecialchars(json_encode($result), ENT_NOQUOTES);
                echo $result;
        }
}


De este archivo, las Lineas de codigo 11 y 16 son importantes.

linea 11:
$allowedExtensions = array("pdf","mp3","mp4","wmv");

Muestra las extensiones de archivos que son permitidas subir.

linea 16:
$result = $uploader->handleUpload('uploads/');

Muestra la ruta donde se encuentra la carpeta destinada para almacenar los archivos, esta Ruta es muy importante, recomiendo no editar su nivel de profundidad, por esto yo la he dejado en la carpeta principal de nuestro proyecto Web.


Pasamos al siguiente Nivel, por el momento no editaremos el archivo "qqFileUploader", lo explicaré mas adelante.


3. Agregando el método a nuestro controlador
Es muy importante agregar el Método que llama a la extensión a nuestro controlador, el código es el siguiente:

    public function actionUpload() {
        Yii::import("ext.EAjaxUpload.qqFileUploader");

        $folder = 'uploads/'; // folder for uploaded files
        $allowedExtensions = array("pdf", "mp3", "mp4", "wmv"); //array("jpg","jpeg","gif","exe","mov" and etc...
        $sizeLimit = 10 * 1024 * 1024; // maximum file size in bytes
        $uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
        $result = $uploader->handleUpload($folder);
        $return = htmlspecialchars(json_encode($result), ENT_NOQUOTES);

        $fileSize = filesize($folder . $result['filename']); //GETTING FILE SIZE
        $fileName = $result['filename']; //GETTING FILE NAME

        echo $return; // it's array 
    }


De este metodo las lineas mas importantes son:

$folder = 'uploads/'; // folder for uploaded files

Esta Linea debe llevar la Ruta de la carpeta que almacena los archivos, esta ruta debe ser la misma que contiene el archivo "EAjaxUploadAction" de nuestra extension EAjaxUpload.


La siguiente linea:
 $allowedExtensions = array("pdf", "mp3", "mp4", "wmv"); //array("jpg","jpeg","gif","exe","mov" and etc...

Muestra las estensiones permitidas, tengan en cuenta que el mismo orden de las extensiones debe ser el mismo como se encuentra en el archivo: "EAjaxUploadAction" de nuestra extension EAjaxUpload.


4. Dando Permisos a nuestro Método actionUpload().
Muy importante dar estos permisos en el accessRules() del controlador donde creamos nuestro método actionUpload(). Ejemplo de como quedarían los permisos:

array('allow', // allow authenticated user to perform 'create' and 'update' actions
                'actions' => array('create', 'index', 'upload'),
                'users' => array('*'),
            ),


Aqui en este código, tengan en cuenta que nuestro metodo se llama: actionUpload() y lo estamos llamando como: upload y con "u" minuscula, en yii framework la palabra Action no se usa para llamar a los métodos.



5. Llamando la extensión en la vista
Ahora por Ultimo paso, necesitamos llamar la extensión en la vista del Controlador, el codigo es el siguiente:

<?php
                        $this->widget('application.extensions.EAjaxUpload.EAjaxUpload', array(
                            'id' => 'fileUploader',
                            'config' => array(
                                'action' => Yii::app()->createUrl('/publicacion/upload'),
                                'allowedExtensions' => array("pdf","mp3","mp4"), //array("jpg","jpeg","gif","exe","mov" and etc...
                                'sizeLimit' => 1 * 1024 * 1024 * 100, // maximum file size in bytes
                                'minSizeLimit' => 1024, // minimum file size in bytes
                                'onComplete' => "js:function(id, fileName, responseJSON){ $('#archivo').val(fileName); $('#botones').css('display','inline'); }",
                           
                            )
                        ));
                        ?>


La linea de codigo:
'action' => Yii::app()->createUrl('/publicacion/upload'),

Esta linea de codigo es muy importante, porque es la que esta llamando al metodo upload en el nuestro Controlador, para este caso, el Controlador se llama publicacion, seguido de "/" y el nombre del metodo "upload".

La siguiente linea de código explica de nuevo la extensiones que son permitidas Adjuntar.

--------------------------------------------------------------------------------------


Hasta aquí vamos todo bien, el permite adjuntar archivos en una carpeta que están dentro de nuestro proyecto Web, PERO el sistema informático no SABE donde se están guardando.

Para esto y para subir múltiples archivos me idee de la siguiente forma.

1. Para subir múltiples archivos, podríamos tener en un futuro el problema que 2 archivos coincidan con el mismo nombre y llegado este caso, el sistema informático lo que va a realizar es reemplazar y copiar el archivo nuevo por el que ya se encuentra almacenado.

LA SOLUCION:

Para solucionar este problema requerimos que los archivos no se llamen igual. Pero esta responsabilidad no se la podemos dejar encargada al usuario, para esto se deja encargado al sistema informático con lo siguiente: vamos a generar un número randomico (número al azar) entre 10 y 99 y el resultado se concatena con el nombre del archivo, osea, renombramos el archivo que subimos y le agregamos al nombre el número.

Con esto evitamos que en el futuro que 2 archivos tengan el mismo nombre, no sean reemplazados.

Y COMO HACEMOS ESTO?

Agregamos en la vista el sigueinte codigo:
<?php
    Yii::app()->user->setState('salt', rand(10, 99));
?>

Esta acción funciona así: en el momento que el usuario visualiza la vista, se genera una cookie que contiene el numero randomico, esta cookie la podemos llamar como si fuera una variable global que sera utilizada.



ULTIMO PASO:

Ahora si, podemos editar el archivo "qqFileUploader" que se encuentra en la carpeta de la extension EAjaxUpload.
En este archivo buscamos la funcion handleUpload.

    function handleUpload($uploadDirectory, $replaceOldFile = FALSE){
        if (!is_writable($uploadDirectory)){
            return array('error' => "Server error. Upload directory isn't writable.");
        }

        if (!$this->file){
            return array('error' => 'No files were uploaded.');
        }

        $size = $this->file->getSize();

        if ($size == 0) {
            return array('error' => 'File is empty');
        }

        if ($size > $this->sizeLimit) {
            return array('error' => 'File is too large');
        }

        $pathinfo = pathinfo($this->file->getName());
        $filename = $pathinfo['filename'];
        //$filename = md5(uniqid());
        $ext = $pathinfo['extension'];

        if($this->allowedExtensions && !in_array(strtolower($ext), $this->allowedExtensions)){
            $these = implode(', ', $this->allowedExtensions);
            return array('error' => 'File has an invalid extension, it should be one of '. $these . '.');
        }


        if ($this->file->save($uploadDirectory . $filename.Yii::app()->user->getState('salt'). '.' . $ext)){
            
            $modelo = new Archivos();
            
            $modelo->identificador = Yii::app()->user->getState('salt');
            $modelo->ruta = Yii::app()->request->baseUrl.'/uploads/'.$filename.Yii::app()->user->getState('salt').'.'.$ext;
            $modelo->titulo = $filename;
           
            
            $modelo->save();

            return array('success'=>true,'filename'=>$filename.Yii::app()->user->getState('salt').'.'.$ext); 
            
        } else {
            return array('error'=> 'Could not save uploaded file.' .
                'The upload was cancelled, or server error encountered');
        }

    }


De esta función la parte que nos interesa es donde se encuentra el último if:
if ($this->file->save($uploadDirectory . $filename.Yii::app()->user->getState('salt'). '.' . $ext)){
            
            $modelo = new Archivos();
            
            $modelo->identificador = Yii::app()->user->getState('salt');
            $modelo->ruta = Yii::app()->request->baseUrl.'/uploads/'.$filename.Yii::app()->user->getState('salt').'.'.$ext;
            $modelo->titulo = $filename;
           
            
            $modelo->save();

            return array('success'=>true,'filename'=>$filename.Yii::app()->user->getState('salt').'.'.$ext); 
            
        } else {
            return array('error'=> 'Could not save uploaded file.' .
                'The upload was cancelled, or server error encountered');
        }


En esta condicional IF esta preguntando si el archivo llamado: nombre_archivo + Numero randomico + la extension del archivo, fue almacenado en la carpeta uploads.

Como vemos el sigueinte codigo esta rescatando el numero randomico que generamos como una cookie:
$filename.Yii::app()->user->getState('salt')



Y dentro de la condicional se encuentra una instancia del Modelo llamado: Archivos(), esta instancia se almacena en la variable llamada: $modelo.

Este modelo: "Archivos" es una tabla de la base de datos que esta almacenando 3 campos:

1 Identificador: este es el numero que generamos de forma randomica, la cuestion es que como vamos a subir múltiples archivos, los que se suban por un usuario, contengan el mismo numero randomico, para pode identificarlos y así saber que es una subida múltiple de 1 solo usuario.

2 la RUTA donde se encuentra almacenado el archivo, el sigueinte codigo muestra el nombre real de archivo junto con la concatenacion del numero randomico.
$modelo->ruta = Yii::app()->request->baseUrl.'/uploads/'.$filename.Yii::app()->user->getState('salt').'.'.$ext;

Esta Ruta y Nombre del archivo deben coincidir con los que se encuentran en la carpeta uploads.

3 El Titulo, guardo el titulo o nombre del archivo para poder mostrarlo al usuario sin necesidad de mostrar toda la ruta donde se encuentra almacenado.




FIN

--------------------------------------------------------------------------------


Espero les sea de ayuda, Adjunto la extensión para que la usen:

0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users