[Solved] Multi-file upload problem

I am having some troubles getting a multi-file upload form working as planned. Here is the relevant code, trimmed down to the essentials.

modules/picture/PictureModule.php




<?php

public $basicNumUploads = 5;

?>



modules/picture/models/Upload.php




<?php

class Upload extends CFormModel

{


    public $file;


    public function rules()

    {

        return array(

            array('file', 'file',

                'maxFiles' => Yii::app()->getModule('picture')->basicNumUploads,

                'types' => 'gif png jpg jpeg',

                'maxSize' => Yii::app()->getModule('picture')->maxFileSize,

                'allowEmpty' => TRUE,

            ),

        );

    }


}

?>



modules/picture/controllers/UploadController.php




public function actionIndex()

{

    for ($i = 0; $i < Yii::app()->getModule('picture')->basicNumUploads; $i++)

        $models[] = new Upload;


    if (isset($_POST['Upload']))

    {

        foreach ($models as $index => $model)

        {

            $model->attributes = $_POST['Upload'];

            $model->file = CUploadedFile::getInstance($model, "[$index]file");

            var_dump($model->validate());

        }

    }


    $this->render('index', array('models' => $models));

}



modules/picture/views/upload/index.php




<div class="form">

    <?php $form=$this->beginWidget('CActiveForm', array(

        'htmlOptions' => array('enctype' => 'multipart/form-data'))); ?>

    

    <?php foreach($models as $index => $model): ?>

        <?php echo $form->error($model, "[$index]file"); ?>

        <?php echo $form->fileField($model, "[$index]file"); ?><br />

    <?php endforeach;?>

        

    <?php echo CHtml::submitButton('Upload'); ?>

        

    <?php $this->endWidget(); ?>

</div>



The problem is the following. When I set $basicNumUploads to 1, the form validates correctly, and the var_dump shows FALSE. However, when I set the number to 2 or more, the validation is thrown off. It will always return TRUE, regardless of the fact that I try to upload an invalid file.

Any clues what I might be missing?

Why don’t use CMultiFileUpload?

Hi rei. I am making two versions of the same form: one that is enhanced for ease, where a user can drag and drop and/or select multiple files from a single open dialog. I’m still looking into a solution I like most most for that. Meanwhile, I am also working on a very basic version of the form for users who either don’t want to, or cannot use the enhanced form. This basic form simply contains a number of file fields: very limited but absolutely independend of JavaScript, Flash, Java or whatever. I did check out CMultiFileUpload, but:

  • it doesn’t suit my needs for the enhanced form, as it supports neither drag and drop nor multiselect from a single open dialog;

  • it won’t work for the basic form either, because when JavaScript is not available, it degrades to a single standard upload field, whereas I need at least a few on the upload page.

Hope that clears it up. :)

Managed to fix it by commenting out hte ‘maxFiles’ setting in the Upload model rules. Still not at all sure why it caused the problem, but for now I seem to have it working.

Hi, i see this as marked SOLVED.

Thats great, as i’m trying to do the very same thing (i guess). ;)

I understood, you made a working drag&drop upload using a model for the uploaded file.

I’m trying to do something where i drop a file inside a defined dropzone and use the fileReader (HTML5) to get its contents.

Then i show a thumbnail if it was an image filetype, else a generic icon.

Then on completion of my form i want to upload these files with the form data. My problem is, im using ajax for submitting, which is working for the formdata. also o tried some xhr uploading which also worked.

but i have no clue for the submit of the data i read via filereader…

If you’ve done this, please could you share some code.

Thanks

Hi slp,

I’m affraid you are guessing wrong… :(

This topic was about a form that uses basic file fields for uploading. It is intended as a backup page for users that do not want to use (or cannot use) a page that uses Plupload for easier multi-file uploading. I wrote a custom, but basic, extension for that page which does not show thumbnails prior to or during uploading. So I’m affraid I cannot help you with that.

The file uploading in my case it sort of specific too, in that a UploadsProcessor class processes each upload and does a couple of things:

[list=1]

[*]it creates up to three scaled versions of the images for use on different places on my site

[*]it checks if the combined filesize of the uploaded picture and scaled versions does not exceed the user’s quota

[*]it records the picture details into the database

[/list]

Both the basic upload page as well as the Plupload powered page use this processing class. If you would like to know more about how I implemented it, I suggest you send me a PM, as it is rather off-topic here.

good solution is using AjaxUpload


uploader = $('selector');

new AjaxUpload(uploader, {

  action: 'controller-url'

  name: 'userfile[]',

  multiple: true,

  autoSubmit: true,

  onComplete: function(file,r) {alert(r);}

});

in controller you can get files:


$files = array();

foreach($_FILES['userfile'] as $key=>$file)

{

  $index = 0;

  foreach($file as $i=>$value)

  {

    $files[$i][$key] = $value;

    $index++;

  }

}

var_dump($files);



Thanks for the answers.

@jodev

ok, i see now that there is a difference :( but thanks anyway

@terrasoff

i tried this one and it works fine, but i didn’t wanted to leave the Yii way of handling this as a model. therefore i have a model uploadedFile which contains the rules (like file types and so on).

My problem is now, to extract the posted data in a way i can still use the model and yii’s file handling.

but possibly i may just go with a foreach through the $_files array and try passing each to a $uploadedFile->attributes

Will try this. Many thanks