[EXTENSION] FancyUpload

Well, I have a little problem.

In the controller function I want to store the name of all files in a array. These are stored in a session variable in this way:

if(isset($_SESSION['titulos'])) {

                $titulos = $_SESSION['titulos'];


            else {

                $_SESSION['titulos'] = array();


            $titulos [] = $file->getName();

            $_SESSION['titulos'] = $titulos;

I will store the files names in the dabase went I click the submit button. In this way:


if(isset($_SESSION['titulos'])) {

            $titulos = $_SESSION['titulos'];


foreach ($titulos as $til) {

     $titulo = new blabla();

     $arch = new blabla2();



But when the code pass by the foreach the variable $titulos is null, it value is "" nothing NULL…

I don’t know how its occurd, because I’m using session variables.

In any part of the code, before the call of the funtion actionCreate, the session variables set to null??

or what’s my problem?

Articles extends from CActiveRecord??

Yes it extends from CActiveRecord

did you put the code for keeping session alive between the flash uploader and the controller/action?

the session is always reseted because flash doesn’t care about it, so we pass the session id by setting the appendcookiedata option of the fancy widget to recover it and restore the session in the controller, like:

Upload controller:

   //here, starts the session with the same Id to recover values






'data'=>array('YII_CSRF_TOKEN'=>Yii::app()->request->csrfToken), //send your csrf token if you're using csrf

'appendCookieData'=>true,  //this will send PHPSESSID automatically

As i have researched, this problem seems to happen in all flash uploaders and the solution is very simple in all cases.

You could log the values to a txt file to see what happens, please, take a look at the previous messages that I sent to "transistor" and the files attached…there is a code to log the session variable

please, let me know if this solved the problem

could you please provide the entire code of your controller, view and model? I’d like to perform some tests and see it in action



Here they are









Yes I had it… but I had a mistake in the part of the definition of data’=>array(‘YII_CSRF_TOKEN’=>Yii::app()->req … Some silly things :)

In the controller I have the code below


            //here, starts the session with the same Id


           // session_start();

            $my_session_id = $_POST['PHPSESSID'];



            $my_session_id = 'Session not recovered';


I comment the line session_start(); Otherwise I get a http 500 error.

Now, int his way the code is working well, Thanks.

Hello, it’s me again :rolleyes:

Well I want to report some bug that I am experiencing.

In a form I have a CGridView and this widget (fancyUpload). But when I delete a row from the CGridView through ajax, this disapears and the fancyupload don’t.

I’m using firebug and I can see the request respond of ajax with the new html code for the page and I can see the updated correct code for the CGridView. The code is the correct but the CGridView isn’t showed.

I tried to hide the fancyUpload code from the form and the CGridView works properly.

If I reload the page manualy (F5) I can see the CGridView properly.

maybe, this is a bug of the widget or bug of yii or a bug of me ja ja…

Would you like to help me to get to the root of the problem?

Hey, Luis,

Well, I’ve noticed a weird behavior of Ajax calls with CHtml::ajaxLink when I use another script in the page registering the jQuery(document).ready and the Ajax button is treated by the other script…

for example, I have a simple gallery and this gallery has an option to generate any html content to show beside the image. If I pass CHtml::ajaxLink in the html option of the widget, Yii generates the code correctly, but the links don’t work, I mean, the code exists and all Ytx ids are registered, but the events are not triggered.

If i put the code outside the Html option of the gallery, all things work. Also if I write the entire ajax call generated by Yii in the link manually and pass it inside the Html option, everything works like a charm also (that’s a workaround I did to go ahead in the project, it’s not teh best solution, but works :) ).

So, I think it’s a challenge to discover why these kind of things happen because fancyupload makes use of mootools javascript framework and in the last version of the extension, I’ve changed in mootools scripts all $() references to mootools compatible way for it to work with jQuery, so, I don’t really know if it’s a javascript incompatibility (to be sincere, I’m not that good with js…heheh), I just downloaded the source code and made the wrapper to write what is in the example page of the official fancy website.

Maybe we could ask for a javascript expert in the forum to help us in this, what do you think?


yes of course, go ahead!:rolleyes:

There will be any solution to this strange situation.

hey, Vand, thanks for sending the files

I’d suggest that you put the widget code in the “show” view, because the code I’ve sent you to set the filename will only work if the record already exists in the database ($model = Articles::model()->findByPk($id);). As $id doesn’t exist yet because the model wasn’t saved, the find method will return null

I’m not sure if fancy would be the most suitable solution if you really need the file upload inside the create/update form because flash upload is kinda independent of the submit button of the form. Thus, the user would be able to upload a file before creating the record in the database and if the process was not finished (meaning, if the user just clicks “back” button of the browser after uploading), how would we delete the uploaded files?

I’ve gone through a similar problem here and the best solution I found was to insert fancy widget in the “show” view. In your case, if the user doesn’t send an image, even if the record has published status, you could avoid showing the article in frontend just by adding a singe scope in your model (the image field would be empty if no image was uploaded).

If you want to use this solution and you need only one file per article, I’d suggest that you take a close look at the singlefile code of fancy. I’ve used it in a project and I can share the code if you want, it worked elegantly :)


Hi scoob!

I’m using FancyUpload 1.2 with Yii 1.1 in singebutton mode.

I used the code that attached to the package, and basically it works.

After the successful upload, I’d like to show some information about the image, so I defined the onFileSuccess callback:

'onFileSuccess'=> "function(file, response) {

                var json = new Hash(JSON.decode(response, true) || {});


                if (json.get('status') == '1') {


                        file.info.set('html', '<strong>File sent:</strong> (' + json.get('width') + ' x ' + json.get('height') + 'px, <em>' + json.get('mime') + '</em>)');

                } else {


                        file.info.set('html', '<strong>Error sending:</strong> (' + (json.get('error') ? (json.get('error') + ' #' + json.get('code')) : response));



But it doesn’t work! So I slightly modified the code above:

'onFileSuccess'=> "function(file, response) {


and it doesn’t show anything :(

(my firefox 3.5 shows some js error after an upload

missing : after property id

try { __flash__toXML(Swiff.Uploader.lo…60e0dab3\";i:2;s:1:\"3\";i:3;i:0;}",en


Hi Scoob.

The saga is not complete yet :D

The uploader works great with Firefox, Safari and Chrome (no errors or warnings).

But our “good” friend Internet Explorer 7 gives me an error and doesn’t show the uploader.

Sorry for the spanish messge, it is translated into something like: Error in execution time.

Then, the "debugger" shows me this line:

This is the code for the widget in the view:

//------------- for multiple file upload (queue) --------------

$statusBoxId  = 'fancy-status';

$clearButton  = 'fancy-clear';

$uploadButton = 'fancy-upload';

if ($cantidad_fotos < 1) {

	$cantidad_fotos = 1;


$cantidad_fotos = sprintf('%d',trim($cantidad_fotos));




        'statusBoxId'=>$statusBoxId,            //id for the container div

        'clearButton'=>$clearButton,            //id for "Clear List" link

        'uploadButton'=>$uploadButton,          //id for "Start Upload" link

        'clearButtonLabel'=>'Limpiar Lista',     //label for "Clear List" link

        'uploadButtonLabel'=>'Comienza a subir tus fotos',    //label for "Start Upload" link

        'targetLabel'=>'Selecciona tus fotos',          //label for "select files" link

        'options'=> array(

                'verbose'=>true,  //remove in production


                'url'=>$this->createUrl('upload/uploadedFiles'),          //send files to this controller/action

                'multiple'=>true,                                       //multiple files

                'target'=>'fancy-browse',                               //id for "select files" link

                'typeFilter'=>array('Images (jpg, jpeg, gif, png)'=>'*.jpg; *.jpeg; *.gif; *.png'),   //accept only images

                'instantStart'=>false,                                  //do not upload right after the selection of files

                'data'=>array('YII_CSRF_TOKEN'=>Yii::app()->request->csrfToken, 'serie_fotos'=>$serie_fotos, 'is_update'=>$is_update, 'tipo'=>$tipo, 'anuncio_id'=>$anuncio_id),  //accessible in the controller via $_POST['extradata'] or $_POST['whatever_you_put_in_the_key']





        'callbacks' => array(

            //'onCancel' => 'function(evt,queueId,fileObj,data){alert("Cancelled");}',


            'onLoad'=>"function() {




                    // We relay the interactions with the overlayed flash to the link


                            click: function() {

                                    return false;


                            mouseenter: function() {



                            mouseleave: function() {




                            mousedown: function() {





                    // Interactions for the 2 other buttons


                    document.id('$clearButton').addEvent('click', function() {

                            up.remove(); // remove all files

                            return false;



                    document.id('$uploadButton').addEvent('click', function() {

                            up.start(); // start upload

                            return false;





            'onFail'=> 'function(error) {

                            switch (error) {

                                    case "hidden": // works after enabling the movie and clicking refresh

                                            alert("Para permitir el sistema de carga de archivos es necesario actualizar tu navegador.");


                                    case "blocked": // This no *full* fail, it works after the user clicks the button

                                            alert("Para permitir el sistema de carga de archivos, es necesario permitir o instalar Flash Player.");


                                    case "empty": // Oh oh, wrong path

                                            alert("Es probable que el sistema de carga no esté presente.");


                                    case "flash": // no flash 9+ <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/sad.gif' class='bbc_emoticon' alt=':(' />

                                            alert("Para permitir el sistema de carga de archivos es necesario tener instalado Adobe Flash 9.")




            'onFileSuccess'=> "function(file, response) {

                var json = new Hash(JSON.decode(response, true) || {});


                if (json.get('status') == '1') {


                        file.info.set('html', '<strong>Archivo enviado:</strong> (' + json.get('width') + ' x ' + json.get('height') + 'px, <em>' + json.get('mime') + '</em>)');

                } else {


                        file.info.set('html', '<strong>Error:</strong> (' + (json.get('error') ? (json.get('error') + ' #' + json.get('code')) : response));





            'onSelectFail'=> "function(files) {

                    files.each(function(file) {

                            new Element('li', {

                                    'class': 'validation-error',

                                    html: file.validationErrorMessage || file.validationError,

                                    title: MooTools.lang.get('FancyUpload', 'removeTitle'),

                                    events: {

                                            click: function() {




                            }).inject(this.list, 'top');

                    }, this);





            'onFileComplete'=> "function(file) {



 			'onBrowse'=>"function() {





            'onComplete'=>"function() {

               // document.id('fancy-status').setStyle('display','none');



               el = document.search('.file-success');

               for (i=0; i<el.length; i++){








//'onBeforeStart'=>"function() {

//var hash = {};

//document.cookie.split(/;\s*/).each(function(cookie) {

//cookie = cookie.split('=');

//if (cookie.length == 2) {

//hash[decodeURIComponent(cookie[0])] = decodeURIComponent(cookie[1]);





//data: {cookieName: hash['myfield'], myfield: document.id('myfield').get('value')}










Can you help me with this, please?



In single upload I’m using the onFileComplete event to display a message after the upload and it works fine, like:

onFileComplete:function(file) {

 if (file.response.error) {

 window.alert('Upload Failed ' + this.fileList[0].name + '. Try again. (Error: #' + this.fileList[0].response.code + ' ' + this.fileList[0].response.error + ')');

 } else {





hope it helps!!! please, let me know

Well, took me a few days but I’ve finally fixed it and thought I should share here.

I found this:

So, I went into SFancyQueue and SFancySingleButton and found that when generating options, the last comma added was giving IE7 a hard time.

To solve this, I added a rtrim in the encode function.

                    foreach($v as $dkey=>$dval)


                        $sd .= $dkey .":'" . $dval ."',";


                    $sd = rtrim($sd,','); //<-- remove the last comma

After this, a new Expected identifier error came up.

This time, was a comma after all the callback functions.

The solution was to remove a comma in the createJsCode, after $options:

   protected function createJsCode($options){


                window.addEvent('domready', function() {

                    var up = new FancyUpload2(document.id('$this->statusBoxId'), document.id('$this->listFilesId'), {

                                $options  //<-- there was a comma after $options, I removed it.




       return $js;



Now it works fine with IE7 and the usual browsers (Safari, Firefox, Chrome, etc.)

Hope this helps someone.

hey, Transistor,

it seems like “your good friend IE7” (hehehe) doesn’t like a trailing comma in a comma-separated list, so, please, try changing the “encode” code in the SFancyQueue.php file, under fancyupload extension directory to the code below. As I wrote in the source code, I borrowed code from some other wrappers and “encode” is a method that I didn’t change. I’ll rewrite this code in a near future. By now, please, try the code above in SFancyQueue file and let me know if it works or if it throws another error (don’t have IE7 around here so I couldn’t test the code)

basically, it’s the same code but note that I removed the trailing comma in:

                    $es[] = $k . ":{" .  substr_replace($sd,'',-1) . "}";

The code for you to try:


    * Encode an array into a javascript array


    * @param array $value

    * @return string


    private static function encode($value)




        if (($n)>0 && array_keys($value)!==range(0,$n-1)) {

            foreach($value as $k=>$v)


                if(is_bool($v) || is_numeric($v) || substr($k,0,2) == "on")         // || substr($k,0,2) == "on"


                    if($v===true) $v = 'true';

                    if($v===false) $v = 'false';

                    $es[] = $k . ":" . $v ;




                    $sd ='';

                    foreach($v as $dkey=>$dval)


                        $sd .= "'".$dkey ."':'" . $dval ."',";


                    $es[] = $k . ":{" .  substr_replace($sd,'',-1) . "}";

                }  else

                    $es[] = $k . ":'" .$v . "'";


            return ''.implode(',',$es).'';

        } else {

            /*foreach($value as $v)


                $es[] = "'" . $v . "'";


            return '[' . implode(',',$es) . ']';*/



thanks and regards!!!


thats great…we posted at the same time…heheh

I’m sorry for the delay

thanks for sharing the solution, I’ll fix it in the source code and release it soon



Hi scoob,

It’s me again!:lol:

Now I’m testing the single upload. To assign a photo to my users system. Well I’m using the same code of the extension page. But I didn’t get the expect results. Well, i can upload a photo, he photo was saved successful BUT… the default image (the blue emoticon) was never update with the new uploaded image…

Do you know how to fix this problem?

hey, Luis,

this is not a default behavior of the fancy plugin, this is done by the author with javascript in http://digitarald.de/project/fancyupload/3-0/showcase/single-file-button/

onFileComplete: function(file) {

 if (file.response.error) {

 log.alert('Failed Upload', 'Uploading <em>' + this.fileList[0].name + '</em> failed, please try again. (Error: #' + this.fileList[0].response.code + ' ' + this.fileList[0].response.error + ')');

 } else {

 var md5 = JSON.decode(file.response.text, true).hash; // secure decode

 log.alert('Successful Upload', 'an MD5 hash was created from <em>' + this.fileList[0].name + '</em>: <code>' + md5 + '</code>.<br />gravatar.com generated a fancy and unique monsterid for it, since we did not save the image.');

 var img = $('demo-portrait');

 img.setStyle('background-image', img.getStyle('background-image').replace(/\w{32}/, md5));



so you have to adapt this to fit your needs



Scoob you are a Guru in this!! Thanks