LPology / Simple-Ajax-Uploader

Javascript file upload plugin with progress bar support. Works in all major browsers, including IE7+, Chrome, Firefox, Safari, and Opera. No dependencies - use it with or without jQuery.
995 stars 267 forks source link

change name of saved file using variables? #80

Closed moxita closed 8 years ago

moxita commented 9 years ago

Hello,

Thank you so much for developing Simple-Ajax-Uploader!

It is working very well for me, except that I am unable to figure out how to change the filename. Here is the code on my page, mostly copied verbatim from your examples. I wonder if you could explain where I am going wrong? The file gets uploaded and saved fine, but it is found only as "/docs/_.pdf".

<form action="../Simple-Ajax-Uploader-master/UploadHandler.php" method="post" enctype="multipart/form-data" id="upload_cert">
    <input type="hidden" name="item" id="item" value="<?php echo $item; ?>">
    <input type="hidden" name="id" id="id" value="<?php echo $id; ?>">
    <div class="clear">
        <div style="padding-top:0px;padding-bottom:10px;" class="clearbox" id="picbox"></div>
        <input type="submit" value="Choose file" class="btn" id="upload-btn">
        <span style="font-size:11px;padding-left:5px;vertical-align:middle;"><i>TXT, DOC, DOCX, PDF, and RTF (5MB max file size)</i></span>
    <div class="errortxt" id="errormsg"></div>
       <div style="margin-top:10px;margin-bottom:10px;" id="progressBox"></div>
       <div style="margin-top:10px;margin-bottom:10px;display:none;" id="loaderImg"><img src="../../images/progress_bar.gif" alt="progress_bar" width="" height="" /></div>
    </div>
</form>

Here's my upload handler:

require_once("../../inc/config.php");
require_once("extras/Uploader.php");
$item = (isset($_POST["item"]) ? $_POST["item"] : '');
$id = (isset($_POST["id"]) ? $_POST["id"] : '');

$uploader = new FileUpload('uploadFile');        
$uploader->uploadDir  = $root_path.'/docs/';
$uploader->allowedExtensions = array('txt', 'doc', 'docx', 'pdf', 'rtf');
$uploader->sizeLimit = 10485760;

$ext = $uploader->getExtension();
$newname = $id.'_'.$item.'.'.$ext;
echo $newname;
$uploader->newFileName = $newname;
$result = $uploader->handleUpload();

if (!$result) {
  echo json_encode(array(
          'success' => false,
          'msg' => $uploader->getErrorMsg()
       ));    
} else {
    echo json_encode(array(
            'success' => true,
            'file' => $uploader->getFileName()
         ));
}  

and here's the script from my head.php file

function safe_tags( str ) {
  return String( str )
           .replace( /&amp;/g, '&amp;amp;' )
           .replace( /"/g, '&amp;quot;' )
           .replace( /'/g, '&amp;#39;' )
           .replace( /&lt;/g, '&amp;lt;' )
           .replace( /&gt;/g, '&amp;gt;' );
}

$(function() {

var btn = document.getElementById('upload-btn'),
errBox = document.getElementById('errormsg'),
loaderImg = document.getElementById('loaderImg'),  // "loading" animated GIF
uploader = new ss.SimpleUpload({      
    button: btn,
    url: '../Simple-Ajax-Uploader-master/UploadHandler.php', // server side handler
    progressUrl: '../upload_degradable.php', // enables cross-browser progress support (more info below)
    responseType: 'json',
    name: 'uploadFile',
    multipart: true,  //added this because I wanted to use a form
    accept: '.txt,.doc,.docx,.pdf, .rtf', 
    debug:true,
    maxSize: 10000,
    allowedExtensions: ['txt', 'doc', 'docx', 'pdf', 'rtf'],
    onExtError: function(filename, extension) {
    alert(filename + ' is not a permitted file type.'+"\n\n"+'Only TXT, DOC, DOCX, PDF, and RTF files are allowed.');
    },
    onSizeError: function(filename, fileSize) {
         alert(filename + ' is too big. (10MB max file size)');
    },   
    startXHR: function(filename, extension) {
          // Create the elements of our progress bar
          var progress = document.createElement('div'), // container for progress bar
              bar = document.createElement('div'), // actual progress bar
              fileSize = document.createElement('div'), // container for upload file size
              wrapper = document.createElement('div'), // container for this progress bar
              progressBox = document.getElementById('progressBox'); // on page container for progress bars

          // Assign each element its corresponding class
          progress.className = 'progress';
          bar.className = 'progress-bar';            
          fileSize.className = 'size';
          wrapper.className = 'wrapper';

          // Assemble the progress bar and add it to the page
          progress.appendChild(bar); 
          wrapper.innerHTML = '<div class="name">'+safe_tags(filename)+'</div>'; // filename is passed to onSubmit()
          wrapper.appendChild(fileSize);
          wrapper.appendChild(progress);                                       
          progressBox.appendChild(wrapper); // just an element on the page to hold the progress bars    

          // Assign roles to the elements of the progress bar
          this.setProgressBar(bar); // will serve as the actual progress bar
          this.setFileSizeBox(fileSize); // display file size beside progress bar
          this.setProgressContainer(wrapper); // designate the containing div to be removed after upload
           errBox.innerHTML = '';
            btn.value = 'Choose another file';

            progressBox.style.display = 'inline-block'; // show progress bar
          // Dynamically add a "Cancel" button to be displayed when upload begins
          // By doing it here ensures that it will only be added in browses which
          // support cancelling uploads
          var abort = document.createElement('button');

            progressBox.appendChild(abort);
            abort.className = 'btn btn-sm btn-info';
            abort.innerHTML = 'Cancel';

            // Adds click event listener that will cancel the upload
            // The second argument is whether the button should be removed after the upload
            // true = yes, remove abort button after upload
            // false/default = do not remove
            this.setAbortBtn(abort, true);        
         },
        endXHR: function(filename) {
        progressBox.style.display = 'none'; // hide progress bar
      },
      startNonXHR: function(filename) {
              btn.value = 'Uploading...';
          loaderImg.style.display = 'inline-block'; // show animated GIF
      },
      endNonXHR: function(filename) {
                  btn.value = 'Choose another file';

          loaderImg.style.display = 'none'; // hide animated GIF
      },

       // Do something after finishing the upload
       // Note that the progress bar will be automatically removed upon completion because everything 
       // is encased in the "wrapper", which was designated to be removed with setProgressContainer() 
    onComplete: function(filename, response) {
            if (!response) {
              errBox.innerHTML = 'Unable to upload file';
              return;
            }
            if (response.success === true) {
              picBox.innerHTML = '&lt;img src="/code/ajaxuploader/view-img.php?file=' + encodeURIComponent(response.file) + '"&gt;';
            } else {
              if (response.msg)  {
                errBox.innerHTML = response.msg;
              } else {
                errBox.innerHTML = 'Unable to upload file';
              }
            }
          }
          });
});
abdaziz commented 9 years ago

A common and simple solution to this problem is to add a randomly generated query string to each request for the dynamic file. img src="file.png" /> Would become img src="file.png?var=11" /> Or img src="file.png?var=12" /> From the point of view of the web-server the same file is accessed, but from the point of view of the browser no caching can be performed.

LPology commented 8 years ago

The issue is here in your upload handler:

$newname = $id.'_'.$item.'.'.$ext;
echo $newname;
$uploader->newFileName = $newname;

First, you likely want to remove echo $newname; as this is likely resulting in an invalid JSON response being returned to the browser.

If you just need a random file name to avoid overwriting another file, you could do something like this:

$ext = $uploader->getExtension();
$newname = uniqid('upfile_', true) . '.' . $ext;
$uploader->newFileName = $newname;