Check out the EAjaxUpload extension also.
It seems to be well suited for single file upload.
Check out the EAjaxUpload extension also.
It seems to be well suited for single file upload.
Hi,
As I see, validation approach in XUploadAction won’t allow to receive error messages. Please check this line:
XUploadAction, line 277 :
echo json_encode(array(array("error" => $model->getErrors($this->fileAttribute),)));
I can’t find where and how you suppose error message will be handled.
For proper validation I’m passing validation options directly to fileupload script, e.g.
$mime = '/^image\/('. implode('|', Image::$allowedExt).')$/';
$this->widget('common.extensions.xupload.XUpload', array(
'url' => url("/dashboard/image/upload"),
'model' => $xupload,
'attribute' => 'file',
'multiple' => true,
'htmlOptions' => array(
'id' => 'gallery-form'
),
'options'=>array(
'maxFileSize'=>Image::getServerLimits(),
'minFileSize'=>Image::$minSize,
'maxNumberOfFiles'=>'10',
'acceptFileTypes'=>'js:'.$mime,
'previewSourceFileTypes'=>'js:'.$mime
)
));
And with this approach I started to have proper validation with correct messages.
Am I loosing some point on your implementation?
Thank you.
You always have 2 validations, client side and server side, client side validation is not reliable, you should never trust user input. you always have to validate again server side, the XUpload implementation validates server side and sends the errors back to the client on the ajax response. so that you can display them. I dont remember if the jquery widget does that automatically.
Yes, this is the main question. Looks like the error sent from the line I showed in the previous message is never handled.
Hi Asgaroth,
I tried to add new fields by following the steps in the URL below:
http://www.yiiframework.com/wiki/395/additional-form-data-with-xupload/
I removed ‘title’ as I don’t need the title field. When I started the upload, I received the following error message from the log:
2013/01/03 11:46:22 [error] [exception.CException] exception 'CException' with message 'Property "XUploadForm.description" is not defined.' in /Applications/MAMP/framework/yii/1.1.12/framework/base/CComponent.php:174
Any advice?
Below is my action method
public function actionPostPhotos()
{
Yii::import("xupload.models.XUploadForm");
$path = realpath(Yii::app()->getBasePath()."/../images/") . "/tmp/";
$publicPath = Yii::app()->getBaseUrl()."/images/";
header('Vary: Accept');
if(isset($_SERVER['HTTP_ACCEPT'])
&& (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
header('Content-type: application/json');
} else {
header('Content-type: text/plain');
}
if(isset($_GET["_method"])) {
if($_GET["_method"] == "delete") {
$success = is_file($_GET["file"]) && $_GET["file"][0] !== '.' && unlink($_GET["file"]);
echo json_encode($success);
}
} else {
$this->init();
$model = new XUploadForm; //Here we instantiate our model
//We get the uploaded instance
$model->file = CUploadedFile::getInstance($model, 'file');
if($model->file !== null) {
$model->mime_type = $model->file->getType();
$model->size = $model->file->getSize();
$model->name = $model->file->getName();
//(optional) Generate a random name for our file
$filename = md5(Yii::app()->user->id.microtime().$model->name);
$filename .= ".".$model->file->getExtensionName();
//Initialize the ddditional Fields, note that we retrieve the
//fields as if they were in a normal $_POST array
$model->description = Yii::app()->request->getPost('description', '');
if($model->validate()) {
// $path = Yii::app() -> getBasePath() . "/../images/uploads";
// $publicPath = Yii::app()->getBaseUrl()."/images/uploads";
if(!is_dir($path)) {
mkdir($path, 0777, true);
chmod ($path , 0777);
}
if(!is_dir($thumbsPath)) {
mkdir($path, 0777, true);
chmod ($path , 0777);
}
$model->file->saveAs($path.$filename);
chmod($path.$filename, 0777);
//Now we return our json
echo json_encode(array(array(
"name" => $model->name,
"type" => $model->mime_type,
"size" => $model->size,
//And the description
"description" => $model->description,
"url" => $publicPath.$filename,
"thumbnail_url" => $publicPath.$filename,
"delete_url" => $this->createUrl("postPhotos", array(
"_method" => "delete",
"file" => $path.$filename
)),
"delete_type" => "POST"
)));
} else {
// echo json_encode(array(array("error" => $model->getErrors('file'),)));
// Yii::log("XUploadAction: ".CVarDumper::dumpAsString($model->getErrors()), CLogger::LEVEL_ERROR, "xupload.actions.XUploadAction");
}
} else {
throw new CHttpException(500, "Could not upload file");
}
}
}
and my view:
<?php
$this->widget('xupload.XUpload', array(
'url' => Yii::app()->createUrl("photo/postPhotos"),
//our XUploadForm
'model' => $photos,
//We set this for the widget to be able to target our own form
'htmlOptions' => array('id'=>'upload-photos-form', "class"=>"span7"),
'attribute' => 'file',
'multiple' => true,
//Note that we are using a custom view for our widget
//Thats becase the default widget includes the 'form'
//which we don't want here
'uploadView' => 'application.views.photo.upload',
'downloadView' => 'application.views.photo.download',
'options' => array(
'maxNumberOfFiles'=>2,
'maxFileSize'=>10000000,
'acceptFileTypes' => "js:/(\.|\/)(jpe?g|png)$/i",
'submit' => "js:function (e, data) {
var inputs = data.context.find(':input');
data.formData = inputs.serializeArray();
return true;
}",
),
));
?>
<?php $this->endWidget(); ?>
The error is very clear, there is no such attribute defined in the XUploadForm, the tutorial uses a diferent model named ‘Image’ which has the additional attributes defined, I have updated the tutorial to have more clarity on that.
In your case, you need a new model, with all the attributes defined that you’d need.
I’m not sure, its been a long time, please check the official jquery plugin documentation for more information, if it doesn’t handle the error by it self then you are free to handle the errors any way you like, giving you more flexibility.
Thank you Asgaroth, I instantiated my model and included all the attributes and it seems to work
I’m looking into using this extension and so far I’ve found it to work fine when javascript is enabled in the browser… though when js is disabled xupload is only uploading one single file instead of the multiple files selected. Is this something that needs to be modified, and if so how? Thanks.
Anyone knows how we can check/detect if there’s no uploaded file on the list?
Hi Asgaroth,
First of all thanks a lot for the great extension - it helped me a lot!
I would like to clarify with you one problem that I’m facing while using this extension.
I need users to have opportunity to upload 3 images. And Xupload solves this easily BUT when I submit the form I quite often find only 1 or 2 images actually uploaded to target directory even though 3 was uploaded with Xupload.
After some research I found that this happens because only those 1 or 2 files appear in ‘xuploadFiles’ session state. Therefore I came to conclusion that this happens because there is no locking of session information (I store my sessions in DB) in this piece of code:
protected function beforeReturn() {
$path = $this->getPath();
// Now we need to save our file info to the user's session
$userFiles = Yii::app( )->user->getState( $this->stateVariable, array());
$userFiles[$this->formModel->{$this->fileNameAttribute}] = array(
"path" => $path.$this->formModel->{$this->fileNameAttribute},
//the same file or a thumb version that you generated
"thumb" => $path.$this->formModel->{$this->fileNameAttribute},
"filename" => $this->formModel->{$this->fileNameAttribute},
'size' => $this->formModel->{$this->sizeAttribute},
'mime' => $this->formModel->{$this->mimeTypeAttribute},
'name' => $this->formModel->{$this->displayNameAttribute},
);
Yii::app( )->user->setState( $this->stateVariable, $userFiles );
return true;
}
Because of this absence of locking 3 quick AJAX upload requests (e.g. with small files to upload) can simply overwrite ‘xuploadFiles’ state array set by another concurrent request.
This problem seems to be partially related to the following issue that won’t be fixed in Yii and needs to be resolved in each certain case:
http://code.google.com/p/yii/issues/detail?id=1403
Can you suggest some kind of general workaround for this problem that can be introduced within the extension?
I think I can do the one for my particular case (MySQL) but I have no idea how this can be done universally.
Thank you a lot for any help in advance!
i want to select and upload image simultaneisly means when user select file its upload immediately or upload file when user submit the form .i donot want start upload button .Start upload button functionality done by addimage button or main form submit button
Hi all,
I’m using xupload for my website for about few months, however I never figured out how to solve the CSRF validation when I delete the thumbnail after upload. I tried this way but dosn’t work :
echo json_encode(array(array(
"name" => $model->name,
"type" => $model->mime_type,
"size" => $model->size,
"url" => $publicPath . $filename,
"thumbnail_url" => $publicPath . $filename,
"delete_url" => Yii::app()->createUrl("product/upload", array(
"_method" => "delete",
"file" => $filename,
'YII_CSRF_TOKEN' => Yii::app()->getRequest()->getCsrfToken(),
)),
"delete_type" => "POST",
)));
I get same error: "The CSRF token could not be verified."
It is possible to support CSRF validation?
Thank you.
I resolved the onComplete issue not resonding by instead changing onComplete to simply complete. This is odd but it worked for me.
While I put this widget on activeform (enabledAjaxValidation on), it’s hijack original submit button, and the “Start Upload” button become the submit functionality, it’s so wierd,
I just want the original submit button, still as the submit form, and the "Start Upload" still as ajax background process,
any solution?
set enabledAjaxValidation to Off, and see if that works
Hi,
can someone tell me how to display uploaded files in xupload form after error validation form.
When I adding files, uploading all files are visible in form, but when i submit main form and got error then all files are’nt display in form.
I’m try load state to model but not working:
$photos = new XUploadForm;
if(empty(Yii::app()->user->getState( 'images'))) $photos->attributes = Yii::app()->user->getState( 'images');
I fixed. I edit upload form editing table
<?php if(count(Yii::app()->user->getState('images')) > 0) : ?>
<?php foreach(Yii::app()->user->getState('images') as $photo) : ?>
<tr class="template-download fade in" style="height: 53px;">
<td class="preview">
<a href="/uploads/tmp/<?=$photo["filename"]?>" title="<?=$photo["name"]?>" rel="gallery" download="<?=$photo["name"]?>"><img src="/uploads/tmp/thumbs/<?=$photo["filename"]?>"></a>
</td>
<td class="name">
<a href="/uploads/tmp/<?=$photo["filename"]?>" title="<?=$photo["name"]?>" rel="gallery" download="<?=$photo["name"]?>"><?=$photo["name"]?></a>
</td>
<td class="size"><span><?= $photo["size"];?> b</span></td>
<td colspan="2"></td>
<td class="delete">
<button class="btn btn-danger" data-type="POST" data-url="/index.php/backoffice/photo/upload/_method/delete/file/<?=$photo["filename"]?>.html">
<i class="icon-trash icon-white"></i>
<span>Delete</span>
</button>
<input type="checkbox" name="delete" value="1">
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
Hi Gambler,
The same thing happens to me and also, I guess, to so many people, due to this funcionality is not the main goal of this plugin.
So… I would like to know how you have solved this problem, I have tried by editing the upload & download file, but It doesn’t work and even it doesn’t get displayed correctly due to
<?php foreach(Yii::app()->user->getState('images') as $photo) : ?>
is returning more rows, one for each uploaded image in the user session, that might not be correct.
Could you please share your solution with us? maybe Asgaroth can also update the workflow-wiki for the rest of users.
Thanks in advance
Saludos!
PS: sorry for my english…
Hi All,
I have been trying to find a solution for the update view, that’s… to view the files already upladed from an user when he/she tries to modify some input data.
I have seen that some people got some solution, like the ones bellow but no one say the steps clearly, I have been trying to develop a solution for a long time now but no success, so I’m kind of stuck.
I have all the image info saved on DB, so I can compose a json, but from here I’m lost, I don’t know what steps are next. I don’t know if someone could raise some inputs here, it would be so much appreciate.
@Asgaroth, I know that you have never tried to implement this, but any hint from you is helpfull.
Saludos!
PS: sorry for my english…
Hi…
Does someone know how to change the value of maxNumberOfFiles option in runtime?
Thanks!