[EXTENSION] FancyUpload

finally fucking got it to work – what a pain in the ass, I wish they did a better job on the forum/FAQ section explaining this stuff.


data: 'Submit_Id='+$('submit_id').get('value'),

The problems were the missing comma at the end, and the fact that the <input> was using ‘name’ and not ‘id’ to specify that it was ‘submit_id’.

I’m testing single file upload. In the sample code that comes with the extension, I tried to upload a non-jpg file, it’s showing the same message whether the file is jpg or not. How can it display ‘File Type must be jpg’ as shown in the code at the end of the function in UploadAction.php:




public function run() {

..... some codes here ....


    $return = array(

          'status' => '0',

          'name' => 'File Type must be jpg'

    );

  }

}

echo json_encode($return);

}



How do you access the status and name in this array in ‘onFileComplete’? I don’t know jquery that well and don’t know how to access data returned by that function.

hey!

fancyupload uses mootools javascript framework

I’ve never tried to do this in single upload, but the mootools code is like




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

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


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

                        file.info.set('html', 'Success: ' + json.get('name') );

                } else {

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

                }

            }",



also, i’m not sure if you’ll be able to change the text below the picture, maybe you could put a custom div, which would receive the status messages

hope it helps

regards!

Hi all,

I need two upload buttons on one page. I played around for a while but only one of the two is recognized.

Does anyone tried this too and has a solution?

Has anyone had any success validating other form fields with FancyUpload?

I have 1 dropdown and 1 textbox that are required and I would like to check if they’re filled in before uploading the files.

How would I go about doing this?

Thanks for the reply. Managed to get it to work for single upload based on the pseudo code provided:




'onFileComplete' => "function(file) {

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

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

        window.alert('Upload done!');

    }

    else {

        if (file.response.error) {

           window.alert('Failed - ' + this.fileList[0].name + '. Please try again. (Erro: #' + this.fileList[0].response.code + ' ' + this.fileList[0].response.error + ')');

        } else {

           window.alert(json.get('error'));

        }

    }

 }",



In the function that does the upload, just add ‘error’ key to the result array for error message and that will be displayed when there are errors.

Hope this helps someone.

good!!

thanks for sharing the solution with us!!

regards!

:)

Hi.

How can i use single upload in the same page?

When i add two singlebutton upload, the second button doesnt work :(

Hey,

I solved this issue for testing yesterday but i didn’t have time to release the file for download. Basically, you’ll be able to create as many instances as you want in the same page, but there are a few changes that you have to do for it to work properly.

I’ll post the complete solution at night, as soon as I get home, so I’ll add a reply to this topic.

Thanks for your patience and for using the extension,

:)

Regards!

NO MORE!

I change the upload component to generate the scripts to each upload button that i want.

It is based now on component name.

the major change is in protected/extensions/fancyupload/SBaseFancy.php, in the run() method:




...

$this->clientScript->registerScript($this->name, $js, CClientScript::POS_HEAD);

...



before it was registering the javascript code with the same name, so it was working only for one instance

i’ve also made some changes to the css classes and widget instantiation, if you’re interested, please let me know

:)

regards!

Hello People, I don’t know if someone suffers like me about this issue which gives me a headache:

THE CSRF TOKEN COULD NOT BE VERIFIED.

My fancycontroller.php:




<?php


class FancyController extends CController

{


    public $breadcrumbs;

    public $defaultAction = 'fancyQueue';


    /* this shows you how to create a reusable action in cases that

     * you need to perform the same steps with files in various controllers

     * by using this, you could attach the action to your controller and tell

     * it to save the files in some folder by changing the savePath property

     * in this sample we will use this action in the single file upload view

     */

    public function actions(){

        return array(

            'uploadedSingle'=>array(

                'class'=>'application.components.UploadAction',

                'savePath'=>Yii::app()->getBasePath().DIRECTORY_SEPARATOR. 'single'.DIRECTORY_SEPARATOR,

            )

        );

    }


    public function filters()

    {

return array( 'accessControl' );

        

    }

   

    

    /**

     * Specifies the access control rules.

     * This method is used by the 'accessControl' filter.

     * @return array access control rules

     */

    public function accessRules()

    {

return array(

            array('allow',

                'actions'=>array('uploadedFiles'),

                'users'=>array('@'),

            ),

            );

        


    }


    //render view

    public function actionFancyQueue(){

        $this->render('fancyqueue');

    }


    //render single file upload view

    public function actionFancySingle(){

        $this->render('fancysingle');

    }




    //handles uploaded files comming from fancyQueue view

    public function actionUploadedFiles(){







        Yii::trace("entra actionUploadeFiles","fichero");

        

        /*here, starts the session with the same Id if needed

         session_id($_POST['PHPSESSID']);

         session_start();


          this is possible because we use in the view

          'options'=> array(

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

          ),

         */




        //gets the file

        $file    = CUploadedFile::getInstanceByName("Filedata");




        /* gets any parameter passed through the view

        'options'=> array(

                'data'=>array('key'=>'value'),  //accessible in the controller via $_POST['extradata'] or $_POST['whatever_you_put_in_the_key']

        ),


        like $modelId = CHttpRequest::getParam('key');

         */


        /* if something goes wrong with the upload, you'd better

           log everything you want with this little piece of code

        */

        $logFile = Yii::app()->getBasePath().DIRECTORY_SEPARATOR.'queue'.DIRECTORY_SEPARATOR.'mylog.txt';

        $result              = array();

        $result['time']      = date('r');

        $result['temp']      = $file->getTempName();

        $result['name']      = $file->getName();

        $result['addr']      = substr_replace(gethostbyaddr($_SERVER['REMOTE_ADDR']), '******', 0, 6);

        $result['agent']     = $_SERVER['HTTP_USER_AGENT'];

        $result['type']      = $file->getType();

        $result['mimename']  = CFileHelper::getMimeType($file->getName());

        $result['extradata'] = CHttpRequest::getParam('extradata');

        $log = @fopen($logFile, 'a');

        if ($log) {

            fputs($log, print_r($result, true) . "\n---\n");

            fclose($log);

        }


        /**

         * this is the main action for saving the files

         */

        if ($file->size > 0) {

        $mime = CFileHelper::getMimeType($file->getName());


        switch($mime){

            case 'image/jpeg':

                $savePath = Yii::app()->getBasePath().DIRECTORY_SEPARATOR.'queue'.DIRECTORY_SEPARATOR;


                $fileName  = $savePath . $file->getName();


                if($file->saveAs($fileName)):

                    $return = array(

                        'status' => '1',

                        'name' => $file->getName()

                    );


                else:

                    $return = array(

                        'status' => '0',

                        'name' => $file->getName()

                    );

                endif;


                break;


            default:

                $return = array(

                    'status' => '0',

                    'name' => 'Only jpg files works on this sample!'

                );

            }


        }

        echo json_encode($return);


    }

}



My views/fancy/fancyqueue.php




<?php

$cs = Yii::app()->clientScript;

$cs->registerCoreScript('jquery');


$cs->registerCss('fancy-mod',

        '#fancy-status{ background: #ddd}'

        );

?>




<h2>Upload</h2>

<br />


<?php


$statusBoxId  = 'fancy-status';

$clearButton  = 'fancy-clear';

$uploadButton = 'fancy-upload';




    $this->widget('application.extensions.fancyupload.SFancyQueue',

    array(

        'name'=>'form-fancy',

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

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

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

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

        'uploadButtonLabel'=>'Send',    //label for "Start Upload" link

        'targetLabel'=>'Select Pictures',          //label for "select files" link

        'options'=> array(

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

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

                'multiple'=>true,                                       //multiple files

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

                'typeFilter'=>array('Images (jpg, jpeg)'=>'*.jpg; *.jpeg'),   //accept only images and compressed files (better check the mimetype in the controller which receives the file)

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

                'data'=>array(

                    'YII_CSRF_TOKEN'=>Yii::app()->request->csrfToken,

                    ),  //accessible in the controller via $_POST['extradata'] or $_POST['whatever_you_put_in_the_key']

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

            ),




        'callbacks' => array(

            'onLoad'=>"function() {

                    document.id('$statusBoxId').removeClass('hide');

                    document.id('fancy-fallback').destroy();


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

                    this.target.addEvents({

                            click: function() {

                                    return false;

                            },

                            mouseenter: function() {

                                    this.addClass('hover');

                            },

                            mouseleave: function() {

                                    this.removeClass('hover');

                                    this.blur();

                            },

                            mousedown: function() {

                                    this.focus();

                            }

                    });


                    // 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 habilitar o sistema de upload, desbloqueie flash no seu browser e atualize a página.");

                                            break;

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

                                            alert("Para habilitar o sistema de upload, habilite o filme flash bloqueado");

                                            break;

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

                                            alert("O sistema de upload parece estar faltando, por favor, tente mais tarde");

                                            break;

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

                                            alert("Precisa ter o plugin do Adobe Flash 9 ou superior para usar o upload")

                            }

                    }',


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

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


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

                        file.element.addClass('file-success');

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

                } else {

                        file.element.addClass('file-failed');

                        file.info.set('html', '<strong>Erro no envio:</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() {

                                                    this.destroy();

                                            }

                                    }

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

                    }, this);

            }",




            /*'onFileComplete'=> "function(file) {

                    up.fileRemove(file);

            }",*/


            'onComplete'=>"function() {

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

               //up.remove();

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

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

               //    el[i].destroy();

               //    window.alert(el[i]);

              // }

               location.reload();

            }",







//'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]);

//}

//});

//

//up.setOptions({

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

//});

//}",





        )


    ));

?>



My config/main.php:




............

        'request'=>array(

            'enableCsrfValidation'=>true,

            'enableCookieValidation'=> true,

        ),

.............



So… what’s wrong??

Hi there Scoob,

I’ve downloaded this extension, installed it and made it work in a breeze. Since I think the user experience is the cornerstone of a webapp, this one is a treet.

However, during the test of single upload i’ve found something odd revealed by firebug : document.id(“imageurl”) is null.

Something is not working for me, when I change the image the newly uploaded image doesn’t appear, this line doesn’t seem to work


document.id('$statusBoxId').setStyle('background-image','url('+imageb+')');

.

I had to mix php code in the file generation to achieve the sort of behavior i expected the javascript to do out of the box.

Did anyone got this problem yet ? I don’t know, I might have done something wrong…but what ?

Regards,

Xav

hello!

sorry, maybe i have forgotten some orphan code in the sample…

this line is used to update the picture after the upload, however, there are three steps i’m using in my apps to achieve the expected behavior, as the plugin does nothing about this automatically:

the first step is to include before the widget a code to select the current image (before the upload) and check if it exists…so i insert a hidden field just to hold the value for the javascript to use later




<?php


if (file_exists(dirname(Yii::app()->getBasePath()).'/images/company/'. Yii::app()->numberFormatter->format('00000000000',$model->id). '.jpg')){

    $imageurl = Yii::app()->request->baseUrl.'/images/company/'.Yii::app()->numberFormatter->format('00000000000',$model->id). '.jpg';

} else {

    $imageurl = Yii::app()->request->baseUrl.'/images/shared/noimage.png';

}

?>

<input type="hidden" id="imageurl" name="imageurl" value="<?php echo $imageurl; ?>">




after, change the event onload in the widget as following (set dimensions as needed)




                'onLoad'=>"function() {

                    document.id('$statusBoxId').setStyle('background-image','url('+ document.id('imageurl').get('value')  +')');

                    document.id('$statusBoxId').setStyle('width','250px');

                    document.id('$statusBoxId').setStyle('height','280px');

                }",



finally, by changing the onFileComplete event of the widget we check if there are errors and if no errors are detected, we show a success message and reload the page…so the above code will take place and (usually) update the picture




                '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 {

                        window.alert('It is done!');

                        location.reload();

                    }


                    file.remove();

                    this.setEnabled(true);

                }",



hope this helps!

:)

regards!!

Hi Scoob, many thanks for your input. I do update a field in a database (using activeform and model) also and I have two actions one for the upload, the other for the update when ok with the photo. Maybe I should regroup.

Anyway, thanks a lot.

This will help find my own way.

Nice job :slight_smile:

Cheers.

Hi,

I try to use this extension (I am on windows (easyphp) ).

And it don’t work !

in the application.log, i have this :

2011/01/31 16:57:05 [error] [php] finfo_file() [<a href=‘function.finfo-file’>function.finfo-file</a>]: File or path not found ‘Angelus.jpg’ (E:\PFSF7319\EasyPHP-5.3.4.0\www\yii\framework\utils\CFileHelper.php:224)

Can you help me ?

Thanks a lot

I also need two instances. I’ve changed the registerScript as you mention but I think something is missing.

Thanks for your help.

Hello !

I’m newbie in Yii Frameworks, I’ve dowloaded the extension fancyupload 1.3,

I need some help to understand how recover the file name in my view after upload.

I would like to switch between two folders.

In first time, I want to display the image associated with the model (in protected/images) in my view, after the upload , I want to display the temp image (in protected/ tmp) , i try but I can’t recover the file name from UploadAction.php.

In my controller





public function actions(){

        return array(

            'uploadedSingle'=>array(

                'class'=>'application.components.UploadAction',

                'savePath'=>dirname($_SERVER['SCRIPT_FILENAME']).DIRECTORY_SEPARATOR.Yii::app()->params['ImageTmpFolder'],

            )

        );




In my view





            if (file_exists(Yii::app()->params['ImageTmpFolder'].$file->name)){


               $imageurl = Yii::app()->params['ImageTmpFolder'].$file->name;    // file->name is empty!


            } else { 


                $imageurl = Yii::app()->params['ImageFolder'].$model->image;  


            } 

            ?> 

            <input type="hidden" id="imageurl" name="imageurl" value="<?php echo $imageurl; ?>">




Thanks for your help !

hello!

remember to specify name and Id properties in your view as:




<?php $this->widget('application.extensions.fancyupload.SFancySingleButton',

    array('name'=>'first',

           'statusBoxId'=>'first',

....


<?php $this->widget('application.extensions.fancyupload.SFancySingleButton',

    array('name'=>'second',

           'statusBoxId'=>'second',



and please, use the latest version of the extension also

hope this helps!

regards!

:)

hey!

the following refers to the multi-file upload, ok?

you can retrieve filename by returning it from UploadAction.php, there may be something like the following:




                        if($file->saveAs($this->fileName)):

                            $return = array(

                                'status' => '1',

                                'name' => $file->getName()

                            );



in the end of the script, there is:




echo json_encode($return);



so, in your view file, you can retrieve the filename via onFileSuccess callback (please, take a look at the view sample file distributed with the extension)




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



hope this helps!

regards!

:)