A web developer's blog. PHP, MySQL, CakePHP, Zend Framework, Wordpress, Code Igniter, Django, Python, CSS, Javascript, jQuery, Knockout.js, and other web development topics.

Setting up File Uploader / FineUploader Basic with CakePHP

The configuration:

<?php
// app/Config/core.php
Configure::write("App.SITE_URL", 'http://www.mysite.com');
Configure::write("App.UPLOAD_PATH", '/usr/local/www/vhosts/mysite.com/httpdocs/app/webroot/uploads'); //no trailing slash
Configure::write("App.UPLOAD_PATH_URL", 'http://mysite/uploads'); //no trailing slash

The setting up the .json and .txt extensions in the routes file.
I need the txt. This is because Internet Explorer does not accept 'application/json'.
Without the .txt, IE will send a “Save as” dialog box when the upload is successful.

// app/Config/routes.php
Router::parseExtensions('json', 'txt');

I have the following for the View:

<?php
// app/View/News/json/fineupload.ctp
echo json_encode($result);

And

<?php
// app/View/News/txt/fineupload.ctp
echo json_encode($result);

Take note that both are in different directories.

In my controller:

<?php
class NewsController extends AppController {
    public $helpers = array('Html', 'Form');
    public $components = array('RequestHandler', 'Security');
 
    public function beforeFilter() {
        parent::beforeFilter();
 
        if (AuthComponent::user('role') === 'admin' OR AuthComponent::user('role') === 'user') {
            $this->Auth->allow('index', 'add', 'edit', 'fineupload');
            if(isset($this->Security) && ($this->RequestHandler->isAjax() || $this->RequestHandler->isPost()) && $this->action == 'fineupload'){
                $this->Security->validatePost = false;
                $this->Security->enabled = false;
                $this->Security->csrfCheck = false;
            }
        }
    }
 
    /* --- snipped --- */
 
    public function edit($id = null) {
        $this->layout = 'admin';
 
        $this->News->id = $id;
 
        if(!$this->News->exists()) {
            throw new NotFoundException('News not found');
        }
        if(!($this->request->is('post') || $this->request->is('put'))) {
            $this->set('id', $id);
            $this->request->data = $this->News->read(null, $id);
        } else {
            if($this->News->save($this->request->data)) {
                //$this->Session->setFlash( __('The news has been updated'), 'success');
                return $this->redirect(array('action' => 'index'));
            } else {
                //$this->Session->setFlash('The news could not be saved.', 'error');
            }
        }
    }
 
    /* --- snipped --- */
 
    public function fineupload() {
        $this->layout = false;
 
        $result = array();
 
        // debug($_FILES);
        // array(
        //     [qqfile] => array(
        //         [name] => [share1_glass.gif],
        //         [type] => [image/gif],
        //         [tmp_name] => [C:\wamp\tmp\phpA755.tmp],
        //         [error] => (int) 0,
        //         [size] => (int) 120358
        //     )
        // )
 
        $temp_file       = $_FILES['qqfile']['tmp_name'];
        $target_filename = $_FILES['qqfile']['name'];
        $upload_path     = Configure::read("App.UPLOAD_PATH");
        $target_filepath = $upload_path.'/'.$target_filename;
        move_uploaded_file($temp_file, $target_filepath);
 
        $result['status']   = 'success';
        $result['message']  = 'Upload successful.';
        $result['filename'] = $target_filename;
        $result['webpath']  = Configure::read("App.UPLOAD_PATH_URL").'/'.$target_filename;
        $result['upload_dir'] = Configure::read("App.UPLOAD_PATH_URL");
 
        $this->set('result', $result);
    }

Then in the HTML part – this is the part where we setup the FineUpload Javascript.

<!-- Fine Uploader -->
<!-- You could load these javascript files the CakePHP way -->
<script type="text/javascript" src="/js/fineuploader/header.js"></script>
<script type="text/javascript" src="/js/fineuploader/util.js"></script>
<script type="text/javascript" src="/js/fineuploader/handler.xhr.js"></script>
<script type="text/javascript" src="/js/fineuploader/handler.base.js"></script>
<script type="text/javascript" src="/js/fineuploader/handler.form.js"></script>
<script type="text/javascript" src="/js/fineuploader/button.js"></script>
 
<script type="text/javascript" src="/js/fineuploader/uploader.js"></script>
<script type="text/javascript" src="/js/fineuploader/uploader.basic.js"></script>
 
<script>
    $(document).ready(function() {
    $fub = $('#fine-uploader-basic');
    $messages = $('#messages');
 
    //for IE, we would load the mysite.com/news/fineupload.txt
    //it would return text instead of application/json
    //if we do not do this, Internet Explorer would display a "Save as" dialog box
    if($.browser.msie) {
        var request_ext = 'txt';
        //http://mysite.com/news/fineupload.txt
    } else {
        var request_ext = 'json';
        //http://mysite.com/news/fineupload.json
    }
    var uploader = new qq.FineUploaderBasic({
            button: $fub[0],
            multiple: false,
            request: {
                endpoint: '<?php echo $this->webroot ?>news/fineupload.'+request_ext
            },
            validation: {
            allowedExtensions: ['jpeg', 'jpg', 'gif', 'png', 'pdf'],
            sizeLimit: 204800 // 200 kB = 200 * 1024 bytes
        },
        callbacks: {
            onSubmit: function(id, fileName) {
                $messages.html('<div id="file-' + id + '" class="alert" style="margin: 20px 0 0"></div>');
            },
            onUpload: function(id, fileName) {
                $('#file-' + id).addClass('alert-info')
                                .html('<img src="<?php echo Configure::read("App.SITE_URL") ?>/loading.gif" alt="Initializing. Please hold."> ' +
                                    'Initializing ' +
                                    '“' + fileName + '”');
            },
            onProgress: function(id, fileName, loaded, total) {
                if (loaded < total) {
                progress = Math.round(loaded / total * 100) + '% of ' + Math.round(total / 1024) + ' kB';
                $('#file-' + id).removeClass('alert-info')
                                .html('<img src="<?php echo Configure::read("App.SITE_URL") ?>/loading.gif" alt="In progress. Please hold."> ' +
                                        'Uploading ' +
                                        '“' + fileName + '” ' +
                                        progress);
                } else {
                $('#file-' + id).addClass('alert-info')
                                .html('<img src="<?php echo Configure::read("App.SITE_URL") ?>/loading.gif" alt="Saving. Please hold."> ' +
                                        'Saving ' +
                                        '“' + fileName + '”');
                }
            },
            onComplete: function(id, fileName, responseJSON) {
                console.log('ID: '+id);
                console.log('fileName: '+fileName);
                if (responseJSON.status == 'success') {
                    $('#file-' + id).removeClass('alert-info')
                                    .addClass('alert-success')
                                    .html('<i class="icon-ok"></i> ' +
                                            'Successfully saved ' +
                                            '“' + fileName + '”');
                    $('#NewsExternalUrl').val(responseJSON.webpath);
                } else {
                $('#file-' + id).removeClass('alert-info')
                                .addClass('alert-error')
                                .html('<i class="icon-exclamation-sign"></i> ' +
                                        'Error with ' +
                                        '“' + fileName + '”: ' +
                                        responseJSON.error);
                }
            }
        }
    });
    });
</script>
<div id="fine-uploader-basic" class="btn btn-small">
    <i class="icon-upload icon"></i> Click to upload a file instead of using the Content textarea below.
</div>
(pdf, jpg, gif, png files only)
<div id="messages"></div>

FineUploader / File Uploader
http://fineuploader.com/
https://github.com/valums/file-uploader/

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>