- Workflow
- Action to show the form
- The view file
- The Upload Action
- Handle submitted form
- Moving Files to their final destination
This wiki describes a more complex workflow using the XUpload widget
If you want to know how to send additional data with your files like title, or description, check this other wiki
The workflow will basically go like this:
Workflow ¶
Action to show the form ¶
First we need to create the action that will show the form to the user:
// application/controllers/FancyController.php
public function actionForm( ) {
$model = new SomeModel;
Yii::import( "xupload.models.XUploadForm" );
$photos = new XUploadForm;
$this->render( 'form', array(
'model' => $model,
'photos' => $photos,
) );
}
The view file ¶
And the view form that will display 'SomeModel' fields and our XUpload widget
// application/views/fancy/form.php
<fieldset>
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'somemodel-form',
'enableAjaxValidation' => false,
//This is very important when uploading files
'htmlOptions' => array('enctype' => 'multipart/form-data'),
));
?>
<div class="row">
<?php echo $form->labelEx($model,'field1'); ?>
<?php echo $form->textField($model,'field1'); ?>
<?php echo $form->error($model,'field1'); ?>
</div>
<!-- Other Fields... -->
<div class="row">
<?php echo $form->labelEx($model,'photos'); ?>
<?php
$this->widget( 'xupload.XUpload', array(
'url' => Yii::app( )->createUrl( "/controller/upload"),
//our XUploadForm
'model' => $photos,
//We set this for the widget to be able to target our own form
'htmlOptions' => array('id'=>'somemodel-form'),
'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
'formView' => 'application.views.somemodel._form',
)
);
?>
</div>
<button type="submit">Submit</button>
<?php $this->endWidget(); ?>
</fieldset>
The Upload Action ¶
Now that we have our XUpload widget in place, we need to create the action that will handle the upload of files (we specified as controller/upload), so lets go ahead and create this action. I just copy/pasted the code from the XUploadAction in my own controller and edited as necessary.
<?php
// application/controllers/FancyController.php
public function actionUpload( ) {
Yii::import( "xupload.models.XUploadForm" );
//Here we define the paths where the files will be stored temporarily
$path = realpath( Yii::app( )->getBasePath( )."/../images/uploads/tmp/" )."/";
$publicPath = Yii::app( )->getBaseUrl( )."/images/uploads/tmp/";
//This is for IE which doens't handle 'Content-type: application/json' correctly
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' );
}
//Here we check if we are deleting and uploaded file
if( isset( $_GET["_method"] ) ) {
if( $_GET["_method"] == "delete" ) {
if( $_GET["file"][0] !== '.' ) {
$file = $path.$_GET["file"];
if( is_file( $file ) ) {
unlink( $file );
}
}
echo json_encode( true );
}
} else {
$model = new XUploadForm;
$model->file = CUploadedFile::getInstance( $model, 'file' );
//We check that the file was successfully uploaded
if( $model->file !== null ) {
//Grab some data
$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( );
if( $model->validate( ) ) {
//Move our file to our temporary dir
$model->file->saveAs( $path.$filename );
chmod( $path.$filename, 0777 );
//here you can also generate the image versions you need
//using something like PHPThumb
//Now we need to save this path to the user's session
if( Yii::app( )->user->hasState( 'images' ) ) {
$userImages = Yii::app( )->user->getState( 'images' );
} else {
$userImages = array();
}
$userImages[] = array(
"path" => $path.$filename,
//the same file or a thumb version that you generated
"thumb" => $path.$filename,
"filename" => $filename,
'size' => $model->size,
'mime' => $model->mime_type,
'name' => $model->name,
);
Yii::app( )->user->setState( 'images', $userImages );
//Now we need to tell our widget that the upload was succesfull
//We do so, using the json structure defined in
// https://github.com/blueimp/jQuery-File-Upload/wiki/Setup
echo json_encode( array( array(
"name" => $model->name,
"type" => $model->mime_type,
"size" => $model->size,
"url" => $publicPath.$filename,
"thumbnail_url" => $publicPath."thumbs/$filename",
"delete_url" => $this->createUrl( "upload", array(
"_method" => "delete",
"file" => $filename
) ),
"delete_type" => "POST"
) ) );
} else {
//If the upload failed for some reason we log some data and let the widget know
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" );
}
}
}
Handle submitted form ¶
Now that we have uploaded our images/files, we need to process the form data the user submits using the normal form.
To do that, lets modify our original action, the one with the form, and handle the submitted data.
<?php
// application/controllers/FancyController.php
public function actionForm( ) {
$model = new SomeModel;
Yii::import( "xupload.models.XUploadForm" );
$photos = new XUploadForm;
//Check if the form has been submitted
if( isset( $_POST['SomeModel'] ) ) {
//Assign our safe attributes
$model->attributes = $_POST['SomeModel'];
//Start a transaction in case something goes wrong
$transaction = Yii::app( )->db->beginTransaction( );
try {
//Save the model to the database
if($model->save()){
$transaction->commit();
}
} catch(Exception $e) {
$transaction->rollback( );
Yii::app( )->handleException( $e );
}
}
$this->render( 'form', array(
'model' => $model,
'photos' => $photos,
) );
}
And That's all, nothing fancy, thanks for reading.
Really? aren't you going to ask about moving our files to their final destination? well keep reading.
Moving Files to their final destination ¶
We don't want to put that logic into the controller, I like it slim, we have enough in our controller with the upload action. so instead, lets put that logic in the afterSave method of our model, so we don't have to add/edit our controller.
//in protected/models/SomeModel.php
public function afterSave( ) {
$this->addImages( );
parent::afterSave( );
}
public function addImages( ) {
//If we have pending images
if( Yii::app( )->user->hasState( 'images' ) ) {
$userImages = Yii::app( )->user->getState( 'images' );
//Resolve the final path for our images
$path = Yii::app( )->getBasePath( )."/../images/uploads/{$this->id}/";
//Create the folder and give permissions if it doesnt exists
if( !is_dir( $path ) ) {
mkdir( $path );
chmod( $path, 0777 );
}
//Now lets create the corresponding models and move the files
foreach( $userImages as $image ) {
if( is_file( $image["path"] ) ) {
if( rename( $image["path"], $path.$image["filename"] ) ) {
chmod( $path.$image["filename"], 0777 );
$img = new Image( );
$img->size = $image["size"];
$img->mime = $image["mime"];
$img->name = $image["name"];
$img->source = "/images/uploads/{$this->id}/".$image["filename"];
$img->somemodel_id = $this->id;
if( !$img->save( ) ) {
//Its always good to log something
Yii::log( "Could not save Image:\n".CVarDumper::dumpAsString(
$img->getErrors( ) ), CLogger::LEVEL_ERROR );
//this exception will rollback the transaction
throw new Exception( 'Could not save Image');
}
}
} else {
//You can also throw an execption here to rollback the transaction
Yii::log( $image["path"]." is not a file", CLogger::LEVEL_WARNING );
}
}
//Clear the user's session
Yii::app( )->user->setState( 'images', null );
}
}
And that's it. if you have questions please ask.
Cannot submit form
i cannot submit form i added image schema with one field title and id(primary, auto inc) if i remove xupload part it will work
controller
public function actionIndex() { // renders the view file 'protected/views/site/index.php' // using the default layout 'protected/views/layouts/main.php' $model=new Images; Yii::import( "xupload.models.XUploadForm" ); $photos = new XUploadForm; //Check if the form has been submitted if( isset( $_POST['Images'] ) ) { //Assign our safe attributes $model->attributes = $_POST['Images']; //Start a transaction in case something goes wrong $transaction = Yii::app( )->db->beginTransaction( ); try { //Save the model to the database if($model->save()){ $transaction->commit(); } } catch(Exception $e) { $transaction->rollback( ); Yii::app( )->handleException( $e ); } } $this->render( 'index', array( 'model' => $model, 'photos' => $photos, ) ); }
view
<?php $form = $this->beginWidget('CActiveForm', array( 'id' => 'images-form', 'enableAjaxValidation' => false, //This is very important when uploading files 'htmlOptions' => array('enctype' => 'multipart/form-data'), )); ?> <p class="note">Fields with <span class="required">*</span> are required.</p> <?php echo $form->errorSummary($model); ?> <div class="row"> <?php echo $form->labelEx($model,'title'); ?> <?php echo $form->textField($model,'title'); ?> <?php echo $form->error($model,'title'); ?> </div> <!-- Other Fields... --> <div class="row"> <?php echo $form->labelEx($model,'file'); ?> <?php $this->widget( 'xupload.XUpload', array( 'url' => Yii::app( )->createUrl( "/site/upload"), //our XUploadForm 'model' => $photos, //We set this for the widget to be able to target our own form 'htmlOptions' => array('id'=>'images-form'), 'attribute' => 'file', 'multiple' => true, ) ); ?> </div> <?php echo CHtml::submitButton('Submit'); ?> <?php $this->endWidget(); ?>
upload function
public function actionUpload( ) { Yii::import( "xupload.models.XUploadForm" ); //Here we define the paths where the files will be stored temporarily $path = realpath( Yii::app( )->getBasePath( )."/../images/uploads/tmp/" )."/"; $publicPath = Yii::app( )->getBaseUrl( )."/images/uploads/tmp/"; //This is for IE which doens't handle 'Content-type: application/json' correctly 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' ); } //Here we check if we are deleting and uploaded file if( isset( $_GET["_method"] ) ) { if( $_GET["_method"] == "delete" ) { if( $_GET["file"][0] !== '.' ) { $file = $path.$_GET["file"]; if( is_file( $file ) ) { unlink( $file ); } } echo json_encode( true ); } } else { $model = new XUploadForm; $model->file = CUploadedFile::getInstance( $model, 'file' ); //We check that the file was successfully uploaded if( $model->file !== null ) { //Grab some data $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( ); if( $model->validate( ) ) { //Move our file to our temporary dir $model->file->saveAs( $path.$filename ); chmod( $path.$filename, 0777 ); //here you can also generate the image versions you need //using something like PHPThumb //Now we need to tell our widget that the upload was succesfull //We do so, using the json structure defined in // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup echo json_encode( array( array( "name" => $model->name, "type" => $model->mime_type, "size" => $model->size, "url" => $publicPath.$filename, "thumbnail_url" => $publicPath.$filename, "delete_url" => $this->createUrl( "upload", array( "_method" => "delete", "file" => $filename ) ), "delete_type" => "POST" ) ) ); } else { //If the upload failed for some reason we log some data and let the widget know 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" ); } } }
please help me
thanks in advance..
Demo
Could you please upload a demo of xupload with other model.
It will help all.
Thanks in advance!!!
@vinodc
Please check the comment on the xupload configuration
//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 'formTemplate' => 'application.views.somemodel._form',
What you need to do its, create view, copy the contents of extensions/xupload/views/form.php to your custom view, remove the form tags, and reference that view in the widget configuration.
The reason the xupload widget its not working, for you its because its nesting 2 forms.
Also, please ask your questions in the forum
Property "XUpload.formTemplate" is not defined.
I created custom view in site(_form.php) of your demo and copy the contents of extensions/xupload/views/form.php to _form.php and removed the form tags.
Then i referenced it .
'formTemplate' => 'application.views.site._form',
But it shows an error
Property "XUpload.formTemplate" is not defined.
@vinodc
What version of the plugin are you using? looks like you are using an outdated version.
xupload-v0.4+demo.zip
I think i use the current version.when i remove the form tags of extensions/xupload/views/form.php (and hide formTemplate) it works.i'm near to it but dont know the problem.
@vinodc
Hi there, I' sorry you are totally right, I just corrected the wiki, the correct param name its 'formView'.
Thanks
Thank you very much Asgaroth
it's nice extension that's why i never gave up.
I have one more doubt - can we restrict number of files to be uploaded?
@vinodc
Check this post, and please use the forum for support
File Names
Hi Asgaroth,
Great work! Thank you so much for such a good work.
I am a novice in yii and tyring to build something based on your XUpload module. As I go through with your "XUpload Workflow" tutorial, it is kind of hard to follow because most of the time you did not mention which file I need to put the code in. This must be a trivial issue to experienced yii developers. But it is still confusing and don't know how to proceed for beginners like me. If you could kindly note where I need to put each code segment, it will be a great help! Thank you for a good work again!
@innocube
I just added minimal file hinting, so its clearer, but explaining further is out of the scope of this article. have you gone through the guide and the blog demo?
Have called the view file, i got a one error...
Alias "xupload.models.XUploadForm" is invalid. Make sure it points to an existing directory or file.
Please help me how to rectify dis... b'coz im newbie
done with extract the xupload extension also...
Upload a simple txt file....
Hi, is this worth to upload a simple txt file ?
I test the extension and it upload a txt file, but I con't find how to open dialog box, filtering by file extension... you know : "Text File (.txt)" legend.
Best Regards.
Nicolas
@xNicox
This is more for multifile uploads, but you can use it for single uploads if you wish. kind of misses the point but... whatever
Upload filtered by file type
Hi @Asgaroth,
yes I changed , multiple option to false, and now I can upload one file.
but I can't make xUpload to filter specific file types.
It's not a problem with the extension.
May be you can figure it out how to asign options to "acceptFileTypes" jquery upload file function.
I post and entry in the forum here
Best regards
Source file path before upload
I am trying to upload to Amazon S3 which is expecting source file path as parameter.
How Can I get the full path of selected file?
@venuk
I havent work with Amazon S3, so I wouldn't really know what you need, but if you need the full path to a file on your server, you can use realpath
resolved
Asgaroth, Thanks lot for quick reply.
I am able to get temporary uploaded file path using
"$model->{$this->fileAttribute}->tempName", so files are successfully uploading Amazon S3 storage.
This extension is great. I am just trying to find an efficient way to resize image before or after uploading to AWS S3.
can't submit form
Hi Asgaroth..
i have some problem with my project.
i used Xupload in my form. upload image work like a charm, but when i click submit, submit button can't work, not send additional data. like image description, image category, etc.
how to fix it?
this is my code.
view.
<fieldset> <?php $form = $this->beginWidget('CActiveForm', array( 'id' => 'image-upload-form', 'enableAjaxValidation' => false, //This is very important when uploading files 'htmlOptions' => array('enctype' => 'multipart/form-data'), )); ?> <div class="row"> <?php echo $form->labelEx($model,'category'); ?> <?php echo $form->textField($model,'category'); ?> // when i submit form,this data not send. <?php echo $form->error($model,'category'); ?> </div> <!-- Other Fields... --> <div class="row"> <?php echo $form->labelEx($model,'path'); ?> <?php $this->widget( 'xupload.XUpload', array( 'url' => Yii::app( )->createUrl( "/Image/upload"), 'model' => $photos, 'htmlOptions' => array('id'=>'image-upload-form'), '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 //'formView' =>'application.views.Image._form', ) ); ?> </div> <button type="submit">Submit</button> <?php $this->endWidget(); ?> </fieldset>
my controller
public function actionForm() { $model = new Image; Yii::import( "xupload.models.XUploadForm" ); $photos = new XUploadForm; if( isset( $_POST['Image'] ) ) { //Assign our safe attributes $model->attributes = $_POST['Image']; //Start a transaction in case something goes wrong $transaction = Yii::app( )->db->beginTransaction( ); try { //Save the model to the database if($model->save()){ $transaction->commit(); } } catch(Exception $e) { $transaction->rollback( ); Yii::app( )->handleException( $e ); } } $this->render( 'upload', array( 'model' => $model, 'photos' => $photos, ) ); }
sorry for my english, because my english is not so good.
The submit button not working
To teguh11 I moved the submit button into the last div and it worked
Update Database Issue
Hi,
Hope can someone help me with this,
My issue is that the update record is not reflected into the database.
I can print the record $this->picture_url and its outputs fine with the image filename from the session.
but if I check the record it doesn't appear to be update it.
Sorry my english.
public function afterSave() { if (get_class(Yii::app())=='CWebApplication'&&Profile::$regMode==false) { Yii::app()->user->updateSession(); } $this->addImages(); return parent::afterSave(); } protected function addImages( ) { //If we have pending images if(Yii::app()->user->hasState('xuploadFiles' )) { $userImages = Yii::app()->user->getState('xuploadFiles'); //Resolve the final path for our images $path = Yii::app( )->getBasePath()."/../uploads/avatars/"; foreach($userImages as $image){ $full_image= $path.$image['filename']; if(is_file($full_image)){ $this->picture_url = $image["filename"]; $this->picture_small_url = 'upload'; } } echo $this->picture_url; //$image['filename'] //echo $this->picture_url; Prints fine the record, but in table dont appear reflected //Clear the user's session Yii::app()->user->setState( 'xuploadFiles', null ); }
Error
I have error at you example at $model->file = CUploadedFile::getInstance( $model, 'file' );
how i can debug? What is wrong?
how to load existing files
This extension is great, thanks. Just one question, how could you load your existing files into the plugin?. I mean, I want to retrieve all the files from DB and show them to have the possibilty to make an update. I don't understand how to make that because we're using XUploadForm so there's no DB connection.
Thanks
Loading existing images from DB
To load existing images from DB, you need to add to the view file something like:
<script type="text/javascript"> $.getJSON('<?php echo $this->createUrl("upload", array("_method" => "list", "id" => $model->id)); ?>', function (result) { var objForm = $('#somemodel-form'); if (result && result.length) { objForm.fileupload('option', 'done').call(objForm, null, {result: result}); } }); </script>
And in the actionUpload() method of the controller you need to add the code to load the images from Db:
elseif ($_GET["_method"] == "list") { $intProductId = $_GET['id']; $objProductImages = ProductImage::model()->sorted()->findAllByAttributes(array('product_id' => $intProductId)); if ($objProductImages !== null) { $arrProductImages = array(); foreach ($objProductImages as $objProductImage) { $arrProductImages[] = array( "name" => $objProductImage->name, "id" => $objProductImage->getPrimaryKey(), "type" => $objProductImage->mimeType, "size" => $objProductImage->size, "url" => $objProductImage->path, "thumbnail_url" => $objProductImage->thumb, "delete_url" => $this->getController()->createUrl("upload", array("_method" => "delete", "id" => $objProductImage->id)), "delete_type" => "GET", ); } echo json_encode($arrProductImages); } }
thanks
Thanks for your help. I have to manage how to deal with the ones loaded into the database and the new ones (loaded into the session). Do you have some approach to solve this situation?. I'm not using a ajax form so when you send the form if something is not validated you return to the form but you can visualize your images previously loaded. Besides, I need a way to somehow deal when you realize an update because you have to merge session + database (in the first case you don't have a model ID). Any comment, tip or whatever would be welcome.
Thanks.
@DryKillLogic
My approach was to initially save the model and afterwards give the option to upload the images for it, because if you want to allow uploading images before the model exists you have to store the uploaded images in a temporary folder in case of an error and then move them if the model is successfully saved or delete the temporary folder after a predetermined period of time. That seems like too much of a bother for me.
What about form error on submission?
Wonderful extension, though I'm not quite understanding what happens when there is an error in the "other" form data.
Here's the scenario: A form displays a number of fields, one of which is the XUploadForm widget. You select an image, it's uploaded fine and appears in the widget area, but you forget to enter some other mandatory field. Once you submit, an error appears for the mandatory field and the widget is cleared, forcing the user to select the same image again even though it was correctly accepted by the widget last time around. Am I missing something?
@MeDroogie
I had the same problem with other ajax uploader. After considering and testing few solutions and approaches, I came up, that the easier to implement is to split upload process into two steps. I'm in the beginning of using this particular extension, so I'm not sure yet, if I can use the same approach with it (it worked just perfect with previous uploader, but I had to quit using it due to commercial licensing limitations).
My model save process starts from upload step. User uploads file. Upload action only moves file to final destination and creates new model (record in DB) with only file/path field filed and corresponding to just received/uploaded file. It does not fill out any other fields. It then returns result to browser. This first-step action runs in "create" scenario only. It never updates new record.
I intercept return result (in Javascript, on client site) from upload widget. If upload is successful, I use the same Javascript to route page to second step, where user fills out all other fields (for example enters meta-data for uploaded file, adds tags etc.). This second-step action goes always in "update" scenario only. It never creates new model.
If return results, after upload completed, indicates an error (and in this case -- this means any kind of error, not only upload-related one, but also related to moving file from temporary folder to final destination and all errors coming from creating model), then I display that error and do not redirect browser anywhere.
If user cancels second step, not saving entire model fields, or never reach it due to some error, then this will create an "orphan" record in the DB -- i.e. the one with assigned file, but without other fields filled out.
There is also third, special action, that is fired from time to time (either manually from sys-admin control panel or periodically, using CRON for example), that purges database from all such "orphan" records, deletes all not deleted files in temporary folder and also removes all files from destination folder, which do not belong to any model in database.
Should look like a model active record?
Should look like a model. Which fields and methods should be?
I am a novice and do not understand much.
<?php //in protected/models/Image.php Its my somemodel class Image extends CFormModel { public $item_id; public function tableName() { return '{{image}}'; } public function rules() { // NOTE: you should only define rules for those attributes that // will receive user inputs. return array( //array('name, file, mime_type, size, filename', 'required'), array('name', 'length', 'max'=>300), array('item_id', 'length', 'max'=>300), array('file', 'file'), //array('size, filename', 'length', 'max'=>100), // The following rule is used by search(). // @todo Please remove those attributes that should not be searched. array('id, name, file, mime_type, size, filename, item_id, type', 'safe', 'on'=>'search'), ); } public function attributeLabels() { return array( 'id' => 'ID', 'name' => 'Name', 'file' => 'File', 'mime_type' => 'Mime Type', 'size' => 'Size', 'filename' => 'Filename', 'item_id'=>'item_id', ); } public function addImages() { //If we have pending images if( Yii::app()->user->hasState( 'images' ) ) { $userImages = Yii::app()->user->getState( 'images' ); //Resolve the final path for our images $path = Yii::app()->getBasePath()."/../images/uploads/{$this->id}/"; //Create the folder and give permissions if it doesnt exists if( !is_dir( $path ) ) { die(111); chmod( $path, 0777 ); } //Now lets create the corresponding models and move the files foreach( $userImages as $image ) { if( is_file( $image["path"] ) ) { chmod( $path.$image["filename"], 0777 ); $img = new Image(); $img->size = $image["size"]; $img->mime = $image["mime"]; $img->name = $image["name"]; $img->source = "/images/uploads/{$this->id}/".$image["filename"]; $img->image_id = $this->id; if( !$img->save() ) { var_dump($img); //Its always good to log something Yii::log( "Could not save Image:\n".CVarDumper::dumpAsString( $img->getErrors() ), CLogger::LEVEL_ERROR ); //this exception will rollback the transaction throw new Exception( 'Could not save Image'); } } else { //You can also throw an execption here to rollback the transaction Yii::log( $image["path"]." is not a file", CLogger::LEVEL_WARNING ); } } //Clear the user's session Yii::app()->user->setState( 'images', null ); } } public function afterSave() { $this->addImages(); parent::afterSave(); } public static function model($className=__CLASS__) { return parent::model($className); } }
view form:
<fieldset style="margin-left: 80px;"> <?php $form = $this->beginWidget('CActiveForm', array( 'id' => 'image-form', 'enableAjaxValidation' => false, //This is very important when uploading files 'htmlOptions' => array('enctype' => 'multipart/form-data'), )); ?> <div class="row"> <?php echo $form->labelEx($model,'item_id'); ?>// What role does this field? <?php echo $form->textField($model,'item_id'); ?> <?php echo $form->error($model,'item_id'); ?> </div> <!-- Other Fields... --> <div class="row"> <?php echo $form->labelEx($model,'photos'); ?> <?php $this->widget( 'xupload.XUpload', array( 'url' => Yii::app( )->createUrl( "admin/dog/upload"), //our XUploadForm 'model' => $photos, //We set this for the widget to be able to target our own form 'htmlOptions' => array('id'=>'image-form'), 'attribute' => 'file', 'multiple' => true, ) ); ?> <button type="submit">Submit</button> </div> <?php $this->endWidget(); ?> </fieldset>
Controller:
public function actionForm() { $model = new Image; $photos = new XUploadForm; //Check if the form has been submitted if( isset( $_POST['Image'] ) ) { //Assign our safe attributes $model->attributes = $_POST['Image']; //Start a transaction in case something goes wrong $transaction = Yii::app()->db->beginTransaction( ); try { //Save the model to the database if($model->save()){ $transaction->commit(); } } catch(Exception $e) { $transaction->rollback( ); Yii::app( )->handleException( $e ); } } $this->render( 'form', array( 'model' => $model, 'photos' => $photos, ) ); } public function actionUpload() { // code stantart from example //images saveing in directory }
loop in the action
Please, can anyone explain to me, where is the loop(if there is multiple files to upload) in actionUpdate() ?
Thank you!
@m.dhouibi
There is no loop, the action will be called once per each file, ie. three files, three separate parallel requests
Question: How to preload json before done or submit (don't know name of event, probably on init).
How to preload json, of files already in file system into fileuploader, so I could delete the ones I do not need anymore. I don't know how that is called, probably persistant list or something like that.
somemodel example please?
I'm new to Yii, is there any full working example to integrate this extension?
Some model is a form model or a db model?
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.