"The documentation for CMultiFileUpload isn't clear!"
"I don't know where the uploaded files went!"
"How can I save those files I uploaded in the right directory!"
"!@!##!!!!"
I understand your pain.
I went through a weeks worth of frustration that was unnecessary, so for your benefit, here are the steps towards the uploading of images via CMultiFileUpload so you can focus on the more important thing: your actual work.
In _form.php: - You have to add "multi-part/form-data" to your _form.php file, by two methods: either add the following modification to your header
$form=$this->beginWidget('CActiveForm', array( 'id'=>'topic-form', 'enableAjaxValidation'=>false, 'htmlOptions' => array('enctype' => 'multipart/form-data'), // ADD THIS ));
or this way, before your use of CMultiFileUpload
echo CHtml::form('','post',array('enctype'=>'multipart/form-data'));
The actual CMultiFileUpload implementation is this way:
$this->widget('CMultiFileUpload', array( 'name' => 'images', 'accept' => 'jpeg|jpg|gif|png', // useful for verifying files 'duplicate' => 'Duplicate file!', // useful, i think 'denied' => 'Invalid file type', // useful, i think ));
Algorithm:
load the model in question
check if the model is set
get your uploaded images
save each image in the appropriate place on your server
create new instantiation of your picture model
save that instantiation
save the rest of the data you used in your form
onto the next headache
Before we go on, both your actionCreate() and actionUpdate() methods need to access the folder where you are saving your image. How you handle the OOP design is up to you, but here's the code to create the directory, as well as creating it if it wasn't done already:
// make the directory to store the pic: if(!is_dir(Yii::getPathOfAlias('webroot').'/images/ADD YOUR PATH HERE!/'. $model->name)) { mkdir(Yii::getPathOfAlias('webroot').'/images/ADD YOUR PATH HERE!/'. $model->name)) chmod(Yii::getPathOfAlias('webroot').'/images/ADD YOUR PATH HERE!/'. $model->name)), 0755); // the default implementation makes it under 777 permission, which you could possibly change recursively before deployment, but here's less of a headache in case you don't }
Now in your actionUpdate(), or actionCreate():
$model=$this->loadModel($id); // Uncomment the following line if AJAX validation is needed //$this->performAjaxValidation($model); if(isset($_POST['Topic'])) { $model->attributes=$_POST['Topic']; // THIS is how you capture those uploaded images: remember that in your CMultiFile widget, you set 'name' => 'images' $images = CUploadedFile::getInstancesByName('images'); // proceed if the images have been set if (isset($images) && count($images) > 0) { // go through each uploaded image foreach ($images as $image => $pic) { echo $pic->name.'<br />'; if ($pic->saveAs(Yii::getPathOfAlias('webroot').'/images/ADD YOUR PATH HERE!/'.$pic->name)) { // add it to the main model now $img_add = new Picture(); $img_add->filename = $pic->name; //it might be $img_add->name for you, filename is just what I chose to call it in my model $img_add->topic_id = $model->id; // this links your picture model to the main model (like your user, or profile model) $img_add->save(); // DONE } else // handle the errors here, if you want } // save the rest of your information from the form if ($model->save()) { $this->redirect(array('view','id'=>$model->id)); } } } $this->render('update',array('model'=>$model,));
Obviously, you have to handle the errors, but that's up to you (I haven't coded that yet). However, now you have the files uploaded to your model, and you can play around with it
Hat-tip: Wiseon3 caught a copy/paste error of mine:
"if ($pic->saveAs(Yii::getPathOfAlias('webroot').'/images/ADD YOUR PATH HERE!/'. $model->name)) { // add it to the main model now"
has been updated to
if ($pic->saveAs(Yii::getPathOfAlias('webroot').'/images/ADD YOUR PATH HERE!/'. $pic->name)) { // add it to the main model now
The main code has been updated to reflect this change. Thanks
Total 11 comments
@Temir
You can select multiple files by adding this to the widget array
'htmlOptions' => array( 'multiple' => 'multiple', ),
I need to select Multiple file at once, but this one doesnt allow, does anyone know how to add multi select to this widget..
Dear all
I need some help immediately, i have try CMultiFileUpload to upload multiple file into my database, but the problem is the file is store into directory but the database still empty, does anyone know why this happen?
herewith my form source:
<?php echo $form->labelEx($model,'attachment'); ?>
<?php $this->widget('CMultiFileUpload', array( 'name' => 'attachment', 'accept' => 'jpeg|jpg|gif|png|pdf|doc|docx|xlx|xlsx|zip|rar', 'duplicate' => 'Duplicate file!', 'remove'=>Yii::t('ui','Remove <--'), 'denied' => 'File Is Not Allowed, Upload Only: jpeg,jpg,gif,png,pdf,doc,docx,xlx,xlsx,zip,rar', ));?> <?php echo $form->error($model,'attachment'); ?>
my model source:
array('attachment', 'file', 'types'=>'jpeg,jpg,gif,png,pdf,doc,docx,xlx,xlsx,zip,rar,rtf,ppt,pptx,txt', 'allowEmpty'=>true, 'on'=>'insert,update'), array('title, attachment', 'length', 'max'=>255, 'on'=>'insert,update'),
and my controller source:
public function actionCreate() {
$model=new Content;
// Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($model);
if(isset($_POST['Content'])) { $model->attributes=$_POST['Content']; $images = CUploadedFile::getInstancesByName('attachment'); if(isset($images) && count($images) > 0) { foreach ($images as $i=>$ii) { //echo $ii ->name. '
'; if ($ii->saveAs(Yii::getPathOfAlias('webroot').'/images/'.$ii->name)) { $img_add = new Content(); $img_add->attachment = $ii->name;
//$img_add->topic_id = $model->idpropinsi; $img_add->save(); } else $img_add = new Content(); $img_add->attachment = $ii->name;
//$img_add->topic_id = $model->idpropinsi; $img_add->save(); //}
if($model->save()) { $this->redirect(array('view','id'=>$model->id));
} } } } $this->render('create',array( 'model'=>$model, ));
}
Somebody help me please, today is my deadline for my homework
Assigning the filename field with the name of the CUploadedFile object instance resulted in an error stating "filename cannot be blank". This is assuming you used the file validator in the model (conspicuously missing from the article, can someone add the model code too, for reference?)
What fixed my problem was to assign the object itself to the field.
instead of
Though I am not sure about the nature of the file attribute of a model (the DB table shows the filename). Someone having a better idea please PM me and update this article.
how to select multiple images at once with
?
I mean is there any option or is it possible to upgrade this widget?
Have you tried getInstances($model,'filename') instead?
Hi,
Here is the code for my form
My controller for actionCreate i have included model2 while rendering the form.
It gives me error like this when i submit the form.
And if i comment the
and continuing to the rest of the like this
It gives me this error
Can anyone help me how to handle through models.
At first I thought it would need a custom validator but finally the 'file' validator does the job.
If you want to upload multiple files then you MUST SET maxFiles parameter.
For example for an attribute named 'files' a rule would look like this:
As you can see I commented out the types attribute because this is already checked from CMultiFileUpload ;)
Without setting maxFiles I would get an error at validation that the 'files' attribute is blank!
You can also do:
Don't forget to change post_max_size, upload_max_filesize parameters in you php.ini. There is can be problems with big files uploading.
Shouldn't it be $pic->name in the $pic->saveAs() function, instead of $model->name?
So instead of
it would be
Leave a comment
Please login to leave your comment.