Para descargarlo sigue el vinculo "Download" que esta al lado de Size 40.6 KB (download) en la ventana de leyenda a la derecha. Ir al repositorio de Coco !
'Coco' es un widget (aparte de ser el menor y mas temeroso de mis Yorkies) para manejar subidas de archivos a tu website. Con este widget se pretende crear una herramienta que te ayude a olvidarte de la complejidad de este asunto, sacando provecho de Yii Framework, jQuery, Ajax y UML/MVC
La implementación del widget en tu proyecto es muy simple, se hace en dos partes: Primero, Pones el widget en la vista o formulario en donde lo requieras y Segundo en algun controller pones un action fijo en cualquier controller, no solamente aquel del formulario (un action fijo es aquel que se coloca en el metodo de actions() del controller), este action tiene como proposito conectar el código javascript del widget con tu aplicación Yii.
Coco toma su funcionalidad de una librería PHP muy buena que consegui hace un año y que decidí implementar para Yii framework en forma de Widget. La licencia del autor de la libreria original es respetada y matiene sus creditos. Puedes hallarlo en el repositorio valums de github.
- DESCARGA O CLONA COCO.
Si no usas GIT simplemente copia el contenido de la extension directamente dentro de 'extensions', si usas GIT haz lo siguiente:cd /home/blabla/myapp/protectedmkdir extensionscd extensionsgit clone git@bitbucket.org:christiansalazarh/coco.git - SETUP EN CONFIG/MAINEdita tu archivo /protected/config/main.php'import'=>array(
'application.models.*',
'application.components.*',
'application.extensions.coco.*', // <------agrega esto
),
- CONECTA A "COCO" A TU APLICACION CON UN ACTION ESTATICOEdita protected/controllers/siteController.php (aunque puedes usar otra).Este action solo es requerido una vez para todo el proyecto !!
y agregale lo siguiente (coloreado) :public function actions(){return array('captcha'=>array('class'=>'CCaptchaAction','backColor'=>0xFFFFFF,),'page'=>array('class'=>'CViewAction',),'coco'=>array('class'=>'CocoAction',),);} - INSERTA EL WIDGET EN UNA VISTA<?php$this->widget('ext.coco.CocoWidget',array('id'=>'cocowidget1','onCompleted'=>'function(id,filename,jsoninfo){ }','onCancelled'=>'function(id,filename){ alert("cancelled"); }','onMessage'=>'function(m){ alert(m); }','allowedExtensions'=>array('jpeg','jpg','gif','png'),'sizeLimit'=>2000000,'uploadDir' => 'assets/',// para recibir el archivo subido:'receptorClassName'=>'application.models.MyModel','methodName'=>'onFileUploaded','userdata'=>$model->primaryKey,));?>
¿ CÓMO FUNCIONA COCO ?
- Cuando alguien visite la vista en donde insertaste el Widget verás que aparece un botón con el texto que pusiste en el argumento "buttonText", el cual por defecto dice: "Find & Upload".
- Alguien podrá arrastrar un archivo a ese botón o podrá darle clic y éste le presentará una caja de selección de archivo a subir.
- El usuario envia el archivo, y coco internamente invoca a tu action: index.php?r=site/coco con algunos argumentos. Va a transferir a ese action el archivo a subir mediante llamadas ajax. Tu no haces nada en este punto, solo mirar como coco lo hace, incluso te presentará una caja de progreso cancelable.
- Cuando el action determina que el archivo fue subido (lo sube en la carpeta que tu indicas en el atributo "uploadDir") entonces, hara una de estas dos cosas:
a) Si no has configurado los argumentos: receptorClassName y methodName entonces Coco dejará el archivo en el directorio assets (o donde tu digas en "uploadDir") y solo recibiras una notificacion via ajax en el metodo javascript que has definido en "onCompleted".
b) Si has configurado los argumentos: receptorClassName y methodName, entonces coco desde el lado del servidor creara una instancia de la clase que tu configures en "receptorClassName" y luego invocará un método: aquel que pusiste en "methodName". En ese método podrás recibir la notificacion del archivo subido.
Por tanto, para que esta opción B funcione deberás crear una clase asi:
// creas la clase en: protected/models/MyModel.php (o donde quieras)class MyModel {public function onFileUploaded($fullFileName,$userdata) {// userdata es el mismo valor que pusiste en config/main// fullFileName es la ruta del archivo listo para leer.}}
y los argumentos a pasarle al widget serían:'receptorClassName'=>'application.models.MyModel','methodName'=>'onFileUploaded',
OTRAS OPCIONES DEL WIDGET:
'buttonText'=>'Find & Upload',
'dropFilesText'=>'Drop Files Here !',
'htmlOptions'=>array('style'=>'width: 300px;'),
'defaultControllerName'=>'site',
'defaultActionName'=>'coco',
un favor tengo un error me sale lo siguiente
ResponderEliminarinclude(CJavaScriptExpression.php) [function.include]: failed to open stream: No such file or directory
no se a que se debe te agradesco de antemano
https://bitbucket.org/christiansalazarh/coco/issue/2/include-cjavascriptexpressionphp
Eliminarhola. eso es porque tu versión de yii framework es muy baja. actualizala. CJavaScriptExpression es usada para mapear eventos que serán invocados por javascript.
ResponderEliminarBuenisimo!!! ya funciona solo que al subir el archivo sale error estoy revisandotu pagina para encontrar cual el problema
Eliminarahora me sale el error failed despues de elegir el archivo intenta subirlo pero al final sale un error diciendo "Failed" probe con diferentes tamaños de archivos creyendo que era por el tamaño en todos me sale ese error.
Eliminary una consulta una ves que se sube el archivo se guarda en alguna variale la direccion? ya que me serviria para almacenarlo en mi BD
gracias por tu colaboracion
hola en la doc o en la lista de issues puedes ayudarte mejor, aunque te adelanto que eso normalmente ocurre por dos cosas:
Eliminar1. permisos insuficientes en el directorio de uploads, que se resuelven de primera mano con un chmod 777.
2. el argumento sizeLimit del widget tiene un valor mayor que el definido en php.ini (max_upload_size).
Mira intente los dos metodos que dijiste en el primero use attrib ya que uso Windows en el tema de sizeLimit ya modifique en varias instancias y no resulto. Es mas intente cambiar de extension por eajaxupload y al final tengo el mismo error de Failed ya estoy super estresado que no sale una ayuda clamorosa
Eliminargracias
hola raul.
Eliminarya revisaste el log de coco ? que dice ?
Christian
Eliminarimagino que te refieres al archivo access.log
encontre lo siguiente:
127.0.0.1 - - [10/Nov/2012:19:35:21 -0400] "POST /proyecto/SiteController/coco&action=upload&nocache=1352590514170&data=a:6:%7Bs:17:%22allowedExtensions%22;a:4:%7Bi:0;s:4:%22jpeg%22;i:1;s:3:%22jpg%22;i:2;s:3:%22gif%22;i:3;s:3:%22png%22;%7Ds:9:%22sizeLimit%22;i:200000;s:9:%22uploadDir%22;s:7:%22assets/%22;s:17:%22receptorClassName%22;s:26:%22application.models.MyModel%22;s:10:%22methodName%22;s:14:%22onFileUploaded%22;s:8:%22userdata%22;N;%7D?qqfile=Desert.jpg HTTP/1.1" 404 364 "http://localhost/proyecto/documentos/create" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20100101 Firefox/16.0"
no, me refiero al archivo de log de Yii framework. esta ahi anotado en la documentacion de coco.
Eliminareste archivo se halla en:
/tu/app/protected/runtime/application.log
coco informará bajo el key "info" o "error", ambos se deben habilitar en la seccion de log de tu config/main.php sino no verás el registro de error.
revise el archivo y el ultimo registro en ese archivo dice:
Eliminar2012/11/12 11:42:28 [error] [exception.CHttpException.404] exception 'CHttpException' with message 'No es posible resolver la solicitud "SiteController/coco&action=upload&nocache=1352734938165&data=a:6:{s:17:"allowedExtensions";a:4:{i:0;s:4:"jpeg";i:1;s:3:"jpg";i:2;s:3:"gif";i:3;s:3:"png";}s:9:"sizeLimit";i:200000;s:9:"uploadDir";s:7:"assets/";s:17:"receptorClassName";s:26:"application.models.MyModel";s:10:"methodName";s:14:"onFileUploaded";s:8:"userdata";N;}"' in C:\xampplite\htdocs\yii\framework\web\CWebApplication.php:287
Stack trace:
#0 C:\xampplite\htdocs\yii\framework\web\CWebApplication.php(142): CWebApplication->runController('SiteController/...')
#1 C:\xampplite\htdocs\yii\framework\base\CApplication.php(162): CWebApplication->processRequest()
#2 C:\xampplite\htdocs\proyecto\index.php(13): CApplication->run()
#3 {main}
REQUEST_URI=/proyecto/SiteController/coco&action=upload&nocache=1352734938165&data=a:6:%7Bs:17:%22allowedExtensions%22;a:4:%7Bi:0;s:4:%22jpeg%22;i:1;s:3:%22jpg%22;i:2;s:3:%22gif%22;i:3;s:3:%22png%22;%7Ds:9:%22sizeLimit%22;i:200000;s:9:%22uploadDir%22;s:7:%22assets/%22;s:17:%22receptorClassName%22;s:26:%22application.models.MyModel%22;s:10:%22methodName%22;s:14:%22onFileUploaded%22;s:8:%22userdata%22;N;%7D?qqfile=Desert.jpg
HTTP_REFERER=http://localhost/proyecto/documentos/create
---
hola un 404 es un indicador de "page not found". algo malo tienes en tu codigo respecto a las URL. Muestrame cómo configuraste a coco en config/main y en El widget como tal. En ambas, no me mandes solo una
Eliminarok esta es mi vista con el wiget:
EliminarrenderPartial('_form', array('model'=>$model)); ?>
widget('ext.coco.CocoWidget'
,array(
'id'=>'cocowidget1',
'onCompleted'=>'function(id,filename,jsoninfo){ }',
'onCancelled'=>'function(id,filename){ alert("cancelled"); }',
'onMessage'=>'function(m){ alert(m); }',
'allowedExtensions'=>array('jpeg','jpg','gif','png'),
'sizeLimit'=>200000,
'uploadDir' => 'assets/', // coco will @mkdir it
// this arguments are used to send a notification
// on a specific class when a new file is uploaded,
... 'receptorClassName'=>'application.models.MyModel',
'methodName'=>'onFileUploaded',
'userdata'=>$model->primaryKey,
));
?>
....
y el este parte del codigo de main
....
'sourceLanguage'=>'en',
'charset'=>'iso-8859-1',
'preload'=>array('log'),
'import'=>array(
'application.models.*',
'application.components.*',
'application.extensions.coco.*',
),
'modules'=>array(
'gii'=>array(
'class'=>'system.gii.GiiModule',
'password'=>'prietor',
....
y la conexión de coco al site controller la pusiste ? el widget esta bien configurado segun me muestras, pero si éste no está conectado al sitecontroller (u otro controller) no va a funcionar.
Eliminarigualmente agrego, porqué dice
Eliminar"... 'receptorClassName'=>'application.models.MyModel',"
y no: (sin ...)
'receptorClassName'=>'application.models.MyModel',
tu clase MyModel existe ? y el metodo onFileUploaded existe en esa clase ?
el SiteController esta configurado coloque el codigo que se describe
Eliminar'page'=>array(
'class'=>'CViewAction',
),
'coco'=>array(
'class'=>'CocoAction',
),
La clase MyModel Existe, tiene el metodo onFileUploaded
<?php
class MyModel {
public function onFileUploaded($fullFileName,$userdata) {
}
}
ahora lo comente y tampoco funciona
1. igualmente, asegurate que no hayas cambiado a defaultControllerName, si vas a pones a coco en un controller distinto, solo pones ahi el controllerName, es decir "site" no "siteController".
Eliminar2. limpia los assets. (no los de coco dentro de la extension), la ruta de los assets es: /tuapp/assets, no borres el directorio, borra su contenido y vuelve a iniciar la aplicación.
volvi a recrear tu caso, y efectivamente el error da si tu has modificado el valor de defaultControllerName por "siteController" en vez del valor por defecto "site".
EliminarDebido a que en la config que me muestras no aparece tal modificación, asumo que hiciste modificaciones dentro del codigo fuente de "coco".
si efectivamente Chistian modifique el codigo, volvi a implementar todo de cero en una nuevo proyecto subio sin problemas, ya lo adaptae a mi proyecto original y fubciona de 10 adicione otras extensiones que son las que necesito y funciona
Eliminarte agradezco de mil por el tiempo que dedicaste a resolver mi problema ahora puedo avanzar con mi proyecto gracias de nuevo!!!!!
que bueno que ya resolviste, solo debiste haber puesto $defaultControllerName = 'site'; como viene de fabrica y listo debio funcionar.
EliminarHola, ademas de subir el archivo debo guardar la ruta en base de datos,¿Como lo puedo hacer?
ResponderEliminarhola, bueno eso se sale un poco de este tutorial, pero te informo de todos modos a modo de guia, para que tengas mayor información te invito a visitar:
Eliminarhttp://facebook.com/Yiiframeworkenespanol
y
http://www.yiiframeworkenespanol.org
como habrás visto, coco pide un metodo en una clase
cualquiera, ese metodo sera invocado con la
ruta del archivo recientemente cargado.
public function onFileUploaded($fullFileName,$userdata)
{
// fullFileName es la ruta del archivo
// listo para leer.
podrias hacer:
$userid = Yii::app()->user->id;
o
$userid = $userdata;
siendo este ultimo algun ID pasado al widget
en la vista en donde lo pusiste. supon que es
el ID del usuario activo que tu tienes.
bueno, simple:
$nuevaRuta = crea_nueva_ruta($userid);
mover_archivo($fullFileName, $nuevaRuta);
$usuario = Tuusuario::model()->findByPk($userid);
// podrias usar esa foto como perfil:
$usuario->fotoPerfil = $nuevaRuta;
// o podrias almacenar esa foto o archivo
// en su lista de archivos...
$almacen = $usuario->getAlmacen();
$almacen->agregar($nuevaRuta);
}
este tema de obtener la ruta como se logra?, tengo implementado el modelo MyModel.php
ResponderEliminar<?php
class MyModel {
public function onFileUploaded($fullFileName,$userdata) {
}
}
la idea es que pueda guardar en un registro(ubicacion) en mi BD la ruta del archivo que acabo de subir quedando asi:
assets/prueba.xls
Excelente trabajo. Una pregunta que widget compatible con este para la crop de imagenes.. Yo retorno la vista previa de la imagen subida pero no veo como integrarlo con algo como jiicrop para el cortado. Pistas quiza muchas gracias de nuevo por tu ayuda con Upload y esperando si alguien sabe de lo otro
ResponderEliminarhola, en el metodo onFileUploaded podrias tomar la imagen y convertirla a una version reducida usando esto:
Eliminarhttp://pastebin.com/REixhKaB
hola, en el metodo onFileUploaded podrias tomar la imagen y convertirla a una version reducida usando esto:
ResponderEliminarhttp://pastebin.com/REixhKaB
Christian como estas? logre hacer funcionar coco pero no funciona cuando lo ejecuto en una ventana modal cjuidialog, alguna solución?
ResponderEliminarHola, aqui tienes un ejemplo, no va mas alla de insertar el CJui y listo funciona,
EliminarpageTitle=Yii::app()->name;
?>
beginWidget('zii.widgets.jui.CJuiDialog',array(
'id'=>'mydialog',
'options'=>array(
'title'=>'Dialog box 1',
'autoOpen'=>false,
),
));
?>
widget('ext.coco.CocoWidget'
,array(
'id'=>'cocowidget1',
'onCompleted'=>'function(id,filename,jsoninfo){ }',
'onCancelled'=>'function(id,filename){ alert("cancelled"); }',
'onMessage'=>'function(m){ alert(m); }',
'allowedExtensions'=>array('jpeg','jpg','gif','png'),
//'sizeLimit'=>2000000,
'uploadDir' => 'assets/', // coco will @mkdir it
// this arguments are used to send a notification
// on a specific class when a new file is uploaded,
'receptorClassName'=>'application.models.ContactForm',
'methodName'=>'onFileUploaded',
'userdata'=>'',
'multipleFileSelection'=>true,
'maxConnections'=>3,
'maxUploads'=>2,
'maxUploadsReachMessage'=>'No puede subir mas archivos',
));
?>
endWidget('zii.widgets.jui.CJuiDialog');
echo CHtml::link('open dialog', '#', array(
'onclick'=>'$("#mydialog").dialog("open"); return false;',
));
?>
Este comentario ha sido eliminado por el autor.
ResponderEliminar