Upload Progress when upload multiple files

3.5k views Asked by At

I want to upload multi-file (more than 1000 files, with total more than 2GB). In PHP, i use function

if (move_uploaded_file($_FILES['files']['tmp_name'][$i], $original_file))
                    {
                        $stamp = '../contents/wm_watermark.png';
                        $this->create_watermark_photo($original_file, $stamp, $view_file, $ext);
                        $this->makeThumbnail($view_file, $thumb_file, $this->max_width_thumb, $this->max_width_thumb);

                        //insert photo info to DB
                        $this->Photo->create();
                        $this->Photo->save(
                            array(
                                'Photo' =>  array(
                                    'folder_id' =>  $data_from_preparing_fileInfoList[$i]['sub'],
                                    'name'      =>  $filename
                                )
                            )
                        );

                        $status = '1';
                        $count++;
                    }

I found out that, when use move_upload_file , it didn't upload right now. It only keep in waiting stack. When this function run completedly, then it move file to server. So, when i use upload process, it gain 100% , this ajax url still run.

$("#image_upload_form").ajaxSubmit({
                    //url: '/admin/photoGroup/ajax_upload_photo', //photo upload process bar
                    type: 'POST',
                    dataType: 'json',
                    data: { data_from_preparing: data_from_preparing},
                    beforeSend: function() {
                        //dialog 1
                        $("#upload-photo-process .progress-bar").css('width', '0');
                        $('#upload-photo-process').modal('show');

                    },
                    /* progress bar call back*/
                    uploadProgress: function(event, position, total, percentComplete) {
                        console.log('percentComplete' + percentComplete);
                        console.log('position: ' + position);
                        console.log('total' + total);
                        var mbPosition = position / 1024 / 1024;
                        var mbTotal = total / 1024 / 1024;
                        var txtProcess = percentComplete + '% | ' + mbPosition + 'Mb/' + mbTotal + 'Mb';
                        var pVel = percentComplete + '%';
                        $("#upload-photo-process .process-status").html(txtProcess);

                        $("#upload-photo-process .progress-bar").css('width', pVel);

                    },

                    /* complete call back */
                    complete: function(xhr) {
                        if (xhr.statusText == "OK") {
                            $('#upload-photo-process').modal('hide');
                            $('#upload-done').modal('show');
                        }

                    }
                    /*success: function(data_from_photo_upload) {

                    }*/

                });

enter image description here

Now, i want to when upload progress gain 100%, all of files uploaded to server. How do i can that? Thank in advanced.

2

There are 2 answers

1
Ahosan Karim Asik On

try this it may work..

   //attach
  function sendFileToServer(formData, status, file) {
    var uploadURL = "index.php?p=ticket-attach&ajax=1"; //Upload URL
    var extraData = {}; //Extra Data.
    var jqXHR = $.ajax({
      xhr: function() {
        var xhrobj = $.ajaxSettings.xhr();
        if (xhrobj.upload) {
          xhrobj.upload.addEventListener('progress', function(event) {
            var percent = 0;
            var position = event.loaded || event.position;
            var total = event.total;
            if (event.lengthComputable) {
              percent = Math.ceil(position / total * 100);
            }
            //Set progress
            status.setProgress(percent);
          }, false);
        }
        return xhrobj;
      },
      url: uploadURL,
      type: "POST",
      contentType: false,
      processData: false,
      cache: false,
      data: formData,
      dataType: "json",
      success: function(data) {
        if (data['error'] == "") {
          status.setProgress(100);
          status.setFileNameSize(data['fname'].split(",")[0], file.size);
          status.appendFN(data['fname']);
          //var namef= ;
        } else {
          //alert(data['error']);
          status.errorMsg();
        }
      }
    });
    status.setAbort(jqXHR);
  }

  function createStatusbar(obj) {
    this.statusbar = $("<div class='statusbar'  id=''></div>");
    this.filename = $("<div class='filename'></div>").appendTo(this.statusbar);
    this.size = $("<div class='filesize'></div>").appendTo(this.statusbar);
    this.abort = $("<div class='abort'>&times;</div>").appendTo(this.statusbar);
    this.progressBar = $("<div class='progressBar'><div></div></div>").appendTo(this.statusbar);
    obj.append(this.statusbar);
    this.setFileNameSize = function(name, size) {
      var sizeStr = "";
      var sizeKB = size / 1024;
      if (parseInt(sizeKB) > 1024) {
        var sizeMB = sizeKB / 1024;
        sizeStr = sizeMB.toFixed(2) + " MB";
      } else {
        sizeStr = sizeKB.toFixed(2) + " KB";
      }
      this.filename.html(name);
      this.size.html("(" + sizeStr + ")");
      this.statusbar.attr("sizev", size);
      $("#attach_size").attr("sizev", parseInt($("#attach_size").attr("sizev")) + size);
      this.setTotalSize();
    }
    this.setTotalSize = function() {
      //set total size
      var size = parseInt($("#attach_size").attr("sizev"));

      var sizeStr = "";
      var sizeKB = size / 1024;
      if (parseInt(sizeKB) > 1024) {
        var sizeMB = sizeKB / 1024;
        sizeStr = sizeMB.toFixed(2) + " MB";
      } else {
        sizeStr = sizeKB.toFixed(2) + " KB";
      }
      if (sizeStr != "" && size > 0) $("#attach_size").html("(" + sizeStr + ")");
      else $("#attach_size").html("");
    }
    this.setProgress = function(progress) {

      var progressBarWidth = progress * this.progressBar.width() / 100;
      this.progressBar.find('div').animate({
        width: progressBarWidth
      }, 10).html(progress + "%");
      if (parseInt(progress) >= 100) {
        this.progressBar.hide();
        if ($.isFunction(tinymce.get)) tinymce.get('mail_body').isNotDirty = 0;
        $("#save_status").html("Not saved");

        //this.abort.hide();
      } else {
        if ($.isFunction(tinymce.get)) tinymce.get('mail_body').isNotDirty = 1;
        $("#save_status").html("Not saved");
      }
    }
    this.setAbortFD = function() {
      var sb = this.statusbar;
      var ts = this;
      this.abort.click(function() {
        $.ajax({
          type: "POST",
          url: "index.php?p=ticket-dattach&ajax=1",
          data: "fname=" + sb.children(".filename").children("input").val(),
          //dataType: "json",
          success: function(data) {
            tinymce.get('mail_body').isNotDirty = 0;
            $("#save_status").html("Not saved");
          },
          error: function() {
            alert('File is not deleted');
          }
        });
        //alert(sb.children(".filename").children("input").val());
        $("#attach_size").attr("sizev", (parseInt($("#attach_size").attr("sizev")) - parseInt(sb.attr("sizev"))));
        sb.remove();
        ts.setTotalSize();
      });
    }
    this.setAbort = function(jqxhr) {
      var sb = this.statusbar;
      var ts = this;
      this.abort.click(function() {
        jqxhr.abort();
        if (sb.children(".progressBar").children("div").html() == "100%") {
          $.ajax({
            type: "POST",
            url: "index.php?p=ticket-dattach&ajax=1",
            data: "fname=" + sb.children(".filename").children("input").val(),
            //dataType: "json",
            success: function(data) {
              tinymce.get('mail_body').isNotDirty = 0;
              $("#save_status").html("Not saved");
            },
            error: function() {
              alert('File is not deleted');
            }
          });
          $("#attach_size").attr("sizev", (parseInt($("#attach_size").attr("sizev")) - parseInt(sb.attr("sizev"))));
          sb.remove();
        } else {
          sb.remove();
        }
        ts.setTotalSize();
      });
    }
    this.appendFN = function(fn) {
      this.filename.append("<input type=\"hidden\"  name=\"ticket_attach[]\"  value=\"" + fn + "\"   />");
    }
    this.errorMsg = function() {
      var sb = this.statusbar;
      sb.children(".progressBar").children("div").html("File Error");
      sb.children(".progressBar").show();
      sb.children(".filename").children("input").remove()
    }
  }

  function toggle_class(clas) {
    $("." + clas).toggle();
  }

  function insert_attach(input) {
    var files = input.files;
    $.each(files, function(idx, file) {
      var fd = new FormData();
      fd.append('ticket_attach', file);
      var obj = $(".note-attachbox");
      var status = new createStatusbar(obj); //Using this we can set progress.
      status.setFileNameSize(file.name, file.size);
      sendFileToServer(fd, status, file);
    });
    $("#afile_browser").val("");
  }
.abort {
  color: red;
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="note-attachbox" id="attachbox" style="position: relative; display: inline;"></div>
<input type='file' id='afile_browser' onchange='return insert_attach(this);' style="opacity: 0; position: relative; display: inline; cursor: pointer; width: 100px; padding: 1px 0px; border: medium none;" multiple>
<div style="cursor: pointer; color: rgb(59, 179, 36); display: inline-block; font-weight: bold; font-size: 20px; vertical-align: middle; background: none; width: auto; padding: 5px 0px; margin-left: -105px;">+<i style="font-size: 15px; font-weight: normal;">Attach files<span id="attach_size" sizev="0"></span ></i>
</div>

1
Veerendra On

Hello You can follow the below approach to get it done.

I have try my best to make the example as simple as possible.

You need to implement this approach in your code to reach the result.

The below code is working and tested.

Users

Contains user details username, password, email, profile_image and profile_image_small etc.

CREATE TABLE `users` (
`user_id` int(11) AUTO_INCREMENT PRIMARY KEY,
`username` varchar(255) UNIQUE KEY,
`password` varchar(100),
`email` varchar(255) UNIQUE KEY
)

User Uploads

Contains user upload details upload_id, image_name, user_id_fk(foreign key) and timestamp etc.

CREATE TABLE  `user_uploads` (
`upload_id` int(11) AUTO_INCREMENT PRIMARY KEY,
`image_name` text,
`user_id_fk` int(11),
`created` int(11)
) 

Javascript Code

$("#photoimg").live('change',function(){})- photoimg is the ID name of INPUT FILE tag and $('#imageform').ajaxForm() - imageform is the ID name of FORM. While changing INPUT it calls FORM submit without refreshing page using ajaxForm() method. Uploaded images will prepend inside #preview tag.

<script type="text/javascript" src="http://ajax.googleapis.com/
ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script type="text/javascript" src="jquery.wallform.js"></script>
<script type="text/javascript">
$(document).ready(function()
{

$('#photoimg').live('change', function()
 {
var A=$("#imageloadstatus");
var B=$("#imageloadbutton");

$("#imageform").ajaxForm({target: '#preview',
beforeSubmit:function(){
A.show();
B.hide();
},
success:function(){
A.hide();
B.show();
},
error:function(){
A.hide();
B.show();
} }).submit();
});

});
</script>

Here hiding and showing #imageloadstatus and #imageloadbutton based on form upload submit status.

index.php

Contains simple PHP and HTML code. Here $session_id=1 means user id session value.

<?php
include('db.php');
session_start();
$session_id='1'; // User login session value
?>
<div id='preview'>
</div>
<form id="imageform" method="post" enctype="multipart/form-data" action='ajaxImageUpload.php' style="clear:both">
Upload image: 
<div id='imageloadstatus' style='display:none'><img src="loader.gif" alt="Uploading...."/></div>
<div id='imageloadbutton'>
<input type="file" name="photos[]" id="photoimg" multiple="true" />
</div>
</form>

ajaxImageUpload.php

Contains PHP code. This script helps you to upload images into uploads folder and it will rename image file into timestamp+session_id.extention format to avoid duplicates. This system will store image files into user_uploads with user session id tables

<?php
error_reporting(0);
session_start();
include('db.php');
$session_id='1'; //$session id
define ("MAX_SIZE","2000"); // 2MB MAX file size
function getExtension($str)
{
$i = strrpos($str,".");
if (!$i) { return ""; }
$l = strlen($str) - $i;
$ext = substr($str,$i+1,$l);
return $ext;
}
// Valid image formats 
$valid_formats = array("jpg", "png", "gif", "bmp","jpeg");
if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST")
{
$uploaddir = "uploads/"; //Image upload directory
foreach ($_FILES['photos']['name'] as $name => $value)
{
$filename = stripslashes($_FILES['photos']['name'][$name]);
$size=filesize($_FILES['photos']['tmp_name'][$name]);
//Convert extension into a lower case format
$ext = getExtension($filename);
$ext = strtolower($ext);
//File extension check
if(in_array($ext,$valid_formats))
{
//File size check
if ($size < (MAX_SIZE*1024))
{
$image_name=time().$filename;
echo "<img src='".$uploaddir.$image_name."' class='imgList'>";
$newname=$uploaddir.$image_name;
//Moving file to uploads folder
if (move_uploaded_file($_FILES['photos']['tmp_name'][$name], $newname))
{
$time=time();
//Insert upload image files names into user_uploads table
mysql_query("INSERT INTO user_uploads(image_name,user_id_fk,created) VALUES('$image_name','$session_id','$time')");
}
else
{
echo '<span class="imgList">You have exceeded the size limit! so moving unsuccessful! </span>'; }
}

else
{
echo '<span class="imgList">You have exceeded the size limit!</span>';
}

}

else
{
echo '<span class="imgList">Unknown extension!</span>';
}

} //foreach end

}
?> 

db.php

Database configuration file, just modify database credentials.

<?php
$mysql_hostname = "localhost";
$mysql_user = "username";
$mysql_password = "password";
$mysql_database = "database";
$prefix = "";
$bd = mysql_connect($mysql_hostname, $mysql_user, $mysql_password) or die("Opps some thing went wrong");
mysql_select_db($mysql_database, $bd) or die("Opps some thing went wrong");
?>

CSS

Style for image blocks.

#preview
{
color:#cc0000;
font-size:12px
}
.imgList
{
max-height:150px;
margin-left:5px;
border:1px solid #dedede;
padding:4px;
float:left;
}