[Extension] Xupload

I get 1 empty record in database for every row inserted

Does anyone know what the problem is? Please advice

The view form




<fieldset>

    <?php

    $form = $this->beginWidget('bootstrap.widgets.TbActiveForm', 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,'name'); ?>

		<?php echo $form->textField($model,'name',array('size'=>60,'maxlength'=>255)); ?>

		<?php echo $form->error($model,'name'); ?>

	</div>


	        <div class="row">

            <?php echo $form->labelEx($model,'photos'); ?>

            <?php

            $this->widget( 'xupload.XUpload', array(

                'url' => Yii::app( )->createUrl( "/image/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,

                //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',

				

                )    

            );

            ?>

            

                    <button type="submit">Submit</button>


        </div>

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

</fieldset>



Maybe you defined DB not well, btw you should paste here not your view file, but action from controller (maybe there is something wrong) in view, i think everything is OK.

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 );

        }

hi guys. having trouble with this extension i am getting a

Error 500

Undefined variable: model

have no idea how to correct that. please help. this seems to be a great extension.

model object hasn’t been created most likely

hi. i am basing on the xupload workflow tutorial to create my model. while i can successfully upload to the folders, i cant save anything to the database. pleeeaseee help. here are snippets from my Carousel model. thanks


public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('photo_name', 'required'),

			array('photo_name', 'file', 'types'=>'jpg,jpeg,png,gif'),

			array('photo_name, alt', 'length', 'max'=>256),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('id, photo_name, alt', 'safe', 'on'=>'search'),

		);

	}




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/carousel/{$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->photo_name = "/images/uploads/{$this->id}/".$image["filename"];

                    //$img->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 );

    }

	}




	/**

	 * Returns the static model of the specified AR class.

	 * Please note that you should have this exact method in all your CActiveRecord descendants!

	 * @param string $className active record class name.

	 * @return Carousel the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}



afterSave Not Working!!!

I dunno but I tried many times with afterSave function, and is not working with it.

Every time looks like it set the field with the image value, but doesn’t appear into the database field.


$this->picture = $image['filename'];

echo $this->picture; //Works(prints) but in the database is not in there.

So I have to change $this->addImages to beforeSave and it works.

Does anyone knows why this happens this way.

Solved Add the attr you want to save

$this->saveAttributes(array(‘picture_url’));

Hello,

I can’t seem to use ‘uploadTemplate’ option even after creating another script in upload.php with id=“tempate-upload2”.

What I can do is to manually change all variables in jquery.fileupload-ui.js from ‘template-upload’ to ‘tempate-upload2’ which is absurd.

Am I doing something wrong here?

Also, how can I change the layout of the upload/download?

I tried changing the original code inside upload.php but it will give weird display like two ‘Delete buttons’ and message ‘Error Empty file upload result’.


{% for (var i=0, file; file=o.files[i]; i++) { %}

    <tr class="template-upload fade">

        <td class="preview"><span class="fade"></span></td>

        <td class="name"><span>{%=file.name%}</span></td>

        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>

        </tr><tr class="template-upload fade"> <===================== the only additional code ==================

        {% if (file.error) { %}

            <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>

        {% } else if (o.files.valid && !i) { %}

            <td>

                <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>

            </td>

My widget call:


                    <?php

                    $this->widget( 'xupload.XUpload', array(

                        'url' => Yii::app( )->createUrl( "shop/product/upload"),

                        //our XUploadForm

                        'model' => $photos,

                        //We set this for the widget to be able to target our own form

                        'htmlOptions' => array('id'=>'product-form'),

                        'attribute' => 'file',

                        'multiple' => true,

                        'autoUpload'=>false,

                        'uploadView' => 'application.modules.shop.views.product.upload',

                        'downloadView' => 'application.modules.shop.views.product.download',


                        'uploadTemplate' => '#template-upload2', 

                        'downloadTemplate' => '#template-download2',  

                        //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.modules.shop.views.product.uploadFormHelper',

                        )    

                    );

                    ?>

My upload.php:


<!-- The template to display files available for upload -->

<script id="template-upload2" type="text/x-tmpl">

    <?php

Yii::trace(var_dump("TESSSSSSSSSS"));

?>

    

{% for (var i=0, file; file=o.files[i]; i++) { %}

    <tr class="template-upload2 fade">

        <td class="preview"><span class="fade"></span></td>

        <td class="name"><span>{%=file.name%}</span></td>

        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>


        {% if (file.error) { %}

            <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>

        {% } else if (o.files.valid && !i) { %}

            <td>

                <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>

            </td>

                  

            <td class="start">{% if (!o.options.autoUpload) { %}

                <button class="btn btn-primary">

                    <i class="icon-upload icon-white"></i>

                    <span>{%=locale.fileupload.start%}</span>

                </button>

            {% } %}</td>

        {% } else { %}

            <td colspan="2"></td>

        {% } %}

        <td class="cancel">{% if (!i) { %}

            <br/><br/><br/><br/><br/><br/><br/>

            <button class="btn btn-warning">

                <i class="icon-ban-circle icon-white"></i>

                <span>{%=locale.fileupload.cancel%}</span>

            </button>

        {% } %}</td>

    </tr>

{% } %}

</script>


<!-- The template to display files available for upload -->

<script id="template-upload" type="text/x-tmpl">


{% for (var i=0, file; file=o.files[i]; i++) { %}

    <tr class="template-upload fade">

        <td class="preview"><span class="fade"></span></td>

        <td class="name"><span>{%=file.name%}</span></td>

        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>

        </tr><tr class="template-upload fade">

        {% if (file.error) { %}

            <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>

        {% } else if (o.files.valid && !i) { %}

            <td>

                <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>

            </td>

                  

            <td class="start">{% if (!o.options.autoUpload) { %}

                <button class="btn btn-primary">

                    <i class="icon-upload icon-white"></i>

                    <span>{%=locale.fileupload.start%}</span>

                </button>

            {% } %}</td>

        {% } else { %}

            <td colspan="2"></td>

        {% } %}

        <td class="cancel">{% if (!i) { %}

            <button class="btn btn-warning">

                <i class="icon-ban-circle icon-white"></i>

                <span>{%=locale.fileupload.cancel%}</span>

            </button>

        {% } %}</td>

    </tr>

{% } %}

</script>

Hello Asgaroth and thanks for the awesome extension! I have a question: I need to rename the uploaded file according to an input set in the form which included the widget. How can I pass data from the form to the file handling structure? IE: let’s immagine I want the uploads only have standard names chosen from a dropdownlist. How could I achieve that? Cheers!

Hello. I use Bootstrap3 , and progressbar and loading images are not displayed . Maybe somebody have new view for bootstrap3 ?

Hello, thanks for the extension. Im using it with Twitter Bootstrap 2 and the general progress bar is not working using the extensions view form.

Is there a callback option when all uploaded files are done? I coulnd’t find It.

EDIT: found the callback, It’s called “stop”

I am also not seeing the images, in particular "loading.gif" and "progressbar.gif", although I am not using bootstrap at all. The extension works great other than not being able to visually see your progress which will still discourage me from using the extension.

Edit:

Nevermind, finally got this to work. Those images aren’t normally supposed to load but the loading bar doesn’t seem to normally work without some CSS changes. Don’t remember exactly all the CSS that I did, but I think just setting “.bar” to “position:relative;” did the trick.

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

'id'=&gt;'category-form',


'enableAjaxValidation'=&gt;false,


'htmlOptions' =&gt; array('enctype' =&gt; 'multipart/form-data'),

)); ?>

<!-- Other Fields… -->

    &lt;div class=&quot;row&quot;&gt;


        &lt;?php


        &#036;this-&gt;widget( 'xupload.XUpload', array(


                'url' =&gt; Yii::app( )-&gt;createUrl( &quot;admin/page/upload&quot;),


                //our XUploadForm


                'model' =&gt; &#036;photos,


                //We set this for the widget to be able to target our own form


                'htmlOptions' =&gt; array('id'=&gt;'category-form'),


                'attribute' =&gt; 'file',


                'multiple' =&gt; 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


            )


        );








        ?&gt;


    &lt;/div&gt;


&#60;&#33;-- Other Fields... --&#62;





    &#60;script type=&quot;text/javascript&quot;&gt;


        &#036;(function () {


            'use strict';





            // Initialize the jQuery File Upload widget:


            &#036;('#XUploadForm-form').fileupload({


                url: 'getphotos/'


            });





            &#036;.ajax({


                url: &#036;('#XUploadForm-form').fileupload('option', 'url'),


                dataType: 'json',


                context: &#036;('#XUploadForm-form')[0]


            }).done(function (result) {


                &#036;(this).fileupload('option', 'done')


                    .call(this, null, {result: result});


            });


        });


    &lt;/script&gt;

it’s my form for image upload

i try load exist image

why he make GET http://test.com/admin/page/update/[object%20Object] 400 (Bad Request)

but not "http://test.com/getphotos" or similar?

I hope I’m not being totally obtuse about this, but the tutorial and demo might be helped if there was a database schema to use with them. Basically, I’ve got a standard HAS_MANY/BELONGS_TO relationship between Pattern and Attachment. I don’t see where or how I specify the child model/table and how to pass the pattern_id to the child table. Your demo has no models in it at all, so there’s no way to see how the business logic is proceeding, and the tutorial seems to assume only one table/model. Also the controller does address actionCreate or actionUpdate.

Clearly, since this extension is all about doing multiple uploads for a single model, it would seem that one would have to contend with saving to two tables when using it. How do I do that?

Hello,

I’ve run into a little problem with using the extension when it is being rendered into the page with ajax.

The error I’m getting is that it fails to load in the fileupload.js file


Uncaught TypeError: Object [object Object] has no method 'fileupload' 

Javascript that is loading it in:




$("#shift-history").on("click", ".add-documents-link, .upload-expense-document-link", function(e){

	e.preventDefault();

	var eventId, shiftId, expenseId, uploadType;

	if($(this).hasClass("add-documents-link")){

      uploadType = 'document';

	  eventId = $(this).closest(".documents").data("eventId");

	  shiftId = $(this).closest(".documents").data("shiftId");

	} else {

	  uploadType = 'expense';

	  expenseId = $(this).data("expenseId");

	  shiftId = $(this).data("shiftId");

	}

	$.ajax({

	  url: baseURL + "userShift/getDocumentUploadWidget",

	  type: "GET",

	  data: {"upload_type": uploadType},

	  dataType: "html",

	  success: function(data){

		var $data = $(data);

		$("body").append($data.filter(':not(script[src*="jquery"])').filter(':not(script[src*="min/serve"])'));

		$("#upload-document-dialog").find("input[name='expense_id']").val(expenseId);

		$("#upload-document-dialog").find("input[name='shift_id']").val(shiftId);

		$("#upload-document-dialog").find("input[name='event_id']").val(eventId);

		$("#upload-document-dialog").dialog("open");

	  },

	  error: Parim.errorHandler

	});

  });



The javascript part is working perfectly. In the response I can see that everything is grapped properly.

The PHP controller action:




public function actionGetDocumentUploadWidget()

  {

    $uploadType = $_REQUEST['upload_type'];

    Yii::import("xupload.models.XUploadForm");

    $XUploadForm = new XUploadForm;

    echo $this->renderPartial('/userShift/_documentUpload', array('uploadType'=>$uploadType, 'XUploadForm'=>$XUploadForm), false, true);

  }



The view file:




<?php

if($uploadType == 'expense'){

  $url = Yii::app()->createUrl("document/expenseDocumentUpload");

} else {

  $url = Yii::app()->createUrl("document/userVenueDocumentUpload");

}

?>

<?php

$this->beginWidget('zii.widgets.jui.CJuiDialog', array(

  'id'=>'upload-document-dialog',

  'options'=>array(

    'title'=>'<div class="fl" style="margin:0 10px">Add Documents [ .pdf, .doc, .docx, .txt, .csv, .xls, .odt, .jpg, .jpeg, .png, .gif ]</div>',

    'autoOpen'=>false,

    'modal'=>true,

    'width'=>'auto',

    'height'=>'auto',

    'resizable'=>false,

    'open'=>'js: function(){

      $(".ui-datepicker").hide();

    }',

    'close' => 'js: function(){

      $.fn.getDocuments();

      var shiftId = $("#upload-document-dialog").find("input[name=\'shift_id\']").val();

      $.fn.getExpensesList(shiftId);

    }',

  ),

  'htmlOptions'=>array('style' => 'display:none; padding:0;')

));

?>

<div id="document-dialog-content" style="min-height:120px; margin:10px;">

<?php

  $this->widget('xupload.XUpload', array(

    'url' => $url,

    'model' => $XUploadForm,

    'attribute' => 'file',

    'multiple' => false,

    'formView' => 'documentFormUserVenue',

    'uploadView' => 'documentUpload',

    'downloadView' => 'docDownloadSmall',

    'options' => array(

        'acceptFileTypes' => "js:/(\.|\/)(doc|docx|pdf|xls|txt|odt|csv|jpg|jpeg|gif|png)$/i",

        //  'success' => 'js:function () { }',

    ),

  ));

?>

</div>


<div class="action-bar cf">

  <div class="row buttons">

    <?php echo CHtml::link(_('Upload'),'#',array('class'=>'btn btn-success fr','id'=>'start-upload', 'style'=>'margin:10px 20px; color:white;') ); ?>

  </div>

</div>

<?php $this->endWidget('zii.widgets.jui.CJuiDialog');  ?>



The reason why I’ve gone with this approach was due to problems loading two xupload instances into one page.

The problem I see here is that it probably is trying to init fileupload before fileupload.js actually gets included.

Thanks to all in advance.

Thank for this great extension…

but, I need your help friend…

I combine this extension with a CActiveForm…

When I upload images… and then I submit the CActiveForm… then CActiveForm get some error…

My images that I already upload is gone too… I know that it is saved at Yii::app()->user->setState … but how to show it up again at this extension, like before I submitted form??

Thank before…

hi

I am new to Yii, and stumbled unto your extension which looks amazing.

I am looking into the more complex workflow you posted here

http://www.yiiframework.com/wiki/348/xupload-workflow/#hh2

You mention that you are using a custom view for the widget

because the default widget includes the ‘form’

Can you post the application.views.somemodel._form file?

Hi,

I use the basic example of this extension:

$this->widget(‘xupload.XUpload’, array(

                    'url' =&gt; Yii::app()-&gt;createUrl(&quot;/event/upload&quot;),


                    'model' =&gt; &#036;photos,


                    'attribute' =&gt; 'file',


                    'multiple' =&gt; true,


                ));

But I am unable to add files. I click the "Add files" button, select a file but when the filedialog window closes I see nothing. I get the following JS error:

Uncaught TypeError: Cannot read property ‘options’ of undefined jquery.fileupload-ui.js:88

I use jquery 1.11.0

Please help me

Hi! I start to use this extension and i have this problem with the “Template Upload”, doesn’t show after add an image… but when i run firebug, the template shows…

This is my code for the widget:





<?php

 $this->widget('xupload.XUpload', array(

                    'url' => Yii::app()->createUrl("site/upload"),

                    'model' => $model,

                    'attribute' => 'file',

                    'multiple' => true,

));

?>




There i miss something?

Thanks!