-2

I have the following javascript that verifies and passes the 'artwork' file to a PHP script on my server, which then has some redundant verification of its own (one can never be too safe) and then writes the file to /uploads.

I need to dump the $basename PHP variable in its final state back to the javascript to then write that to a hidden input (ID="artwork_filename").

I can echo the $basename to the 'success' handler, but it feels so inelegant to then have to capture that $basename and strip it out of the result - I want an elegant solution, preferably passing $basename directly to a variable on the javascript.

Javascript:

 <script>
   function _(el) {
     return document.getElementById(el);
   }
   function uploadFile() {
     var file = _("file").files[0];
  if (file == null) {
    _("status").innerHTML = "<span style=" + '"color: black;">' + "Please select a file before clicking upload</span>";
  }
  //alert(file.name+" | "+file.size+" | "+file.type);
  if (file.type==="application/zip" 
  || file.type==="application/x-zip" 
  || file.type==="application/x-zip-compressed") {
    if (file.size < 52428800) {
   var formdata = new FormData();
   formdata.append("file", file);
   var ajax = new XMLHttpRequest();
   ajax.upload.addEventListener("progress", progressHandler, false);
   ajax.addEventListener("load", completeHandler, false);
   ajax.addEventListener("abort", abortHandler, false);
   ajax.open("POST", "upload_artwork.php");
   ajax.send(formdata);
  } else {
   //alert("File is too big! Max upload size is 50MB. To upload a bigger file, please contact us for instructions");
   _("status").innerHTML = "<span style=" + '"color: red;">' + "File is too big! Max upload size is 50MB</span>";
   exit();
    }
  } else {
    _("status").innerHTML = "<span style=" + '"color: red;">' + "Upload stopped! Did you 'zip' your file?</span>";
    exit();
  }
   }
   function progressHandler(event) {
     //_("loaded_n_total").innerHTML = "Uploaded: "+event.loaded+" bytes of "+event.total;
  var percent = (event.loaded / event.total) * 100;
  _("progress_bar").value = Math.round(percent);
  _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
   }
   function completeHandler(event) {
  _("status").innerHTML = event.target.responseText;
  _("progress_bar").value = 0;
   }
   function errorHandler(event) {
  _("status").innerHTML = "<span style=" + '"color: red;">' + "Upload failed! Notify site administrator</span>";
   }
   function abortHandler(event) {
  _("status").innerHTML = "<span style=" + '"color: red;">' + "Upload aborted! Please try again</span>";
   }
 </script>
<input id="artwork_filename" type="hidden" name="custom" value="" />

PHP:

<?php
$allowedExts = array("zip", "rar"/*, "ai", "eps", "psd", "bmp", "jpg", "png", "tiff"*/);

if (@$_FILES['file'] == null) {
  echo "<span style=" . '"color: red;">' . "Please choose a file before clicking upload</span>";
  exit();
} else {
  $fileName = $_FILES["file"]["name"];
  $fileTmpLoc = $_FILES["file"]["tmp_name"];
  $fileType = $_FILES["file"]["type"];
  $fileSize = $_FILES["file"]["size"];
  $fileErrorMsg = $_FILES["file"]["error"];
  $temp = explode(".", $_FILES["file"]["name"]);
  $name = pathinfo($_FILES["file"]["name"], PATHINFO_FILENAME);
  $extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
  $i = '';
}

//Check for max file size breach
//OR NOT: stop it on JS side to prevent long file upload 
//and then alerting user that their file is too big! 
//(Also prevents sidestepping ugly PHP error kickout if file is too big.

if ((($_FILES["file"]["type"] == "application/zip")
|| ($_FILES["file"]["type"] == "application/x-zip")
|| ($_FILES["file"]["type"] == "application/x-zip-compressed")
//|| ($_FILES["file"]["type"] == "application/x-rar-compressed")
/*|| ($_FILES["file"]["type"] == "application/postscript")
|| ($_FILES["file"]["type"] == "image/vnd.adobe.photoshop")
|| ($_FILES["file"]["type"] == "image/bmp")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png")
|| ($_FILES["file"]["type"] == "image/tiff")*/)
&& ($_FILES["file"]["size"] < 52428800)
&& in_array($extension, $allowedExts)) {
  if ($_FILES["file"]["error"] > 0) {
    echo "Upload error! Please notify site administrator";
  } else {
      if (file_exists("upload/" . $name . $i . '.' . $extension)) {
        while(file_exists("upload/" . $name . $i . '.' . $extension)) {
          $i++;
        }
        $basename = $name . $i . '.' . $extension;
        if(move_uploaded_file($_FILES["file"]["tmp_name"],
        "upload/" . $basename)) {
          echo "<span style=" . '"color: green;">' . "Artwork successfully uploaded</span>";
        } else {
            echo "<span style=" . '"color: red;">' . "Upload error! Please contact the site administrator and report the issue</span>";
        }
      } else {
      if(move_uploaded_file($fileTmpLoc, "upload/$fileName")) {
          echo "<span style=" . '"color: green;">' . "Artwork successfully uploaded</span>";
        } else {
            echo "<span style=" . '"color: red;">' . "Upload error! Please contact the site administrator and report the issue</span>";
        }
      }
    }
} else {
  error_reporting(E_ERROR ^ E_PARSE);
  echo "<span style=" . '"color: red;">' . "Upload stopped! Did you 'zip' your file?</span>";
}

?>
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Matthew6
  • 47
  • 6
  • 1
    Isolate the problem and put a concise paste here. This is a spaghetti nightmare. – Mulan Oct 13 '14 at 03:59
  • I just want to pass this $basefile variable to javascript as a variable (preferably bypassing Ajax). Once I can do that, I know how to write the variable to the HTML element as a value (the input box with ID="artwork_filename"): – Matthew6 Oct 13 '14 at 04:03
  • I can't even find `$basefile` in your code. – Jon P Oct 13 '14 at 04:21
  • Personally I wouldn't retrun html from your php file. I'd return data JSON formatted and handle that, part of that would be your `basefile` value. – Jon P Oct 13 '14 at 04:26
  • Late night, no coffee - sorry Jon P, its $basename – Matthew6 Oct 13 '14 at 04:52

2 Answers2

0

You should be able to echo the $basefile variable after the '=' for the javascript variable you wish to assign it to.

This may be of some help:

How to pass variables and data from PHP to JavaScript?

Community
  • 1
  • 1
Gabriel Garrett
  • 2,087
  • 6
  • 27
  • 45
0

In my opinion, use ajax, and seperate the concerns better. Let PHP handle the updload and return some data on what has happened. Let javasctipt perform the ajax request and update the DOM as appropriate when the request is complete, using the data returned. Let CSS handle the styling. Do you really want to have to change javascript and PHP if you want to change the styling of your message container?

My PHP is a little rusty and I normally use jQuery for ajax so the following may need some "massaging" to get right but it should get you on your way.

PHP

<?php
$allowedExts = array("zip", "rar");

if (@$_FILES['file'] == null) {
  $dataOut["success"] = false;
  $dataOut["message"] = 'Please choose a file before clicking upload';
  $dataOut["baseName"] = '';
  exit();
} else {
  $fileName = $_FILES["file"]["name"];
  $fileTmpLoc = $_FILES["file"]["tmp_name"];
  $fileType = $_FILES["file"]["type"];
  $fileSize = $_FILES["file"]["size"];
  $fileErrorMsg = $_FILES["file"]["error"];
  $temp = explode(".", $_FILES["file"]["name"]);
  $name = pathinfo($_FILES["file"]["name"], PATHINFO_FILENAME);
  $extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
  $i = '';
  $dataOut["success"] = false;
  $dataOut["message"] = '';
  $dataOut["baseName"] = '';   
}

//Check for fucking max file size breach
//OR NOT: stop it on JS side to prevent long file upload 
//and then alerting user that their file is too big! 
//(Also prevents sidestepping ugly PHP error kickout if file is too big.

if ((($_FILES["file"]["type"] == "application/zip")
|| ($_FILES["file"]["type"] == "application/x-zip")
|| ($_FILES["file"]["type"] == "application/x-zip-compressed")
)
&& ($_FILES["file"]["size"] < 52428800)
&& in_array($extension, $allowedExts)) {
  if ($_FILES["file"]["error"] > 0) {
    echo "Upload error! Please notify site administrator";
  } else {
      if (file_exists("upload/" . $name . $i . '.' . $extension)) {
        while(file_exists("upload/" . $name . $i . '.' . $extension)) {
          $i++;
        }
        $basename = $name . $i . '.' . $extension;
        $dataOut["baseName"] = $basename;
        if(move_uploaded_file($_FILES["file"]["tmp_name"],
        "upload/" . $basename)) {
          $dataOut["success"] = true;
          $dataOut["message"] = "Artwork successfully uploaded";
        } else {
            $dataOut["success"] = false;
            $dataOut["message"] = "Upload error! Please contact the site administrator and report the issue";
        }
      } else {
      if(move_uploaded_file($fileTmpLoc, "upload/$fileName")) {
          $dataOut["success"] = true;
          $dataOut["message"] = "Artwork successfully uploaded";
        } else {
          $dataOut["success"] = false;
          $dataOut["message"] = "Upload error! Please contact the site administrator and report the issue";
        }
      }
    }
} else {
  error_reporting(E_ERROR ^ E_PARSE);
  $dataOut["success"] = false;
  $dataOut["message"] = "Upload stopped! Did you 'zip' your file?";
}

echo json_encode($dataOut);

?>

<script>
   function _(el) {
     return document.getElementById(el);
   }

      function setStats(status, message){
          if(status === null){
            _("status").className = "info";
          }else if(status){
            _("status").className = "success";
          }else{
            _("status").className = "error";
          }
       
          _("status").innerHTML = message;

      }

   function uploadFile() {
     var file = _("file").files[0];
  if (file == null) {
          setStatus(null, "Please select a file before clicking upload");
  }

  //alert(file.name+" | "+file.size+" | "+file.type);
  if (file.type==="application/zip" 
  || file.type==="application/x-zip" 
  || file.type==="application/x-zip-compressed") {
    if (file.size < 52428800) {
   var formdata = new FormData();
   formdata.append("file", file);
   var ajax = new XMLHttpRequest();
            ajax.responseType = "json";
   ajax.upload.addEventListener("progress", progressHandler, false);
   ajax.addEventListener("load", completeHandler, false);
   ajax.addEventListener("abort", abortHandler, false);
   ajax.open("POST", "upload_artwork.php");
   ajax.send(formdata);
  } else {
   //alert("File is too big! Max upload size is 50MB. To upload a bigger file, please contact us for instructions");
            setStatus(false,"File is too big! Max upload size is 50MB");
   exit();
    }
  } else {
          setStatus(false, "Upload stopped! Did you 'zip' your file?");
    exit();
  }
   }
   function progressHandler(event) {
     //_("loaded_n_total").innerHTML = "Uploaded: "+event.loaded+" bytes of "+event.total;
  var percent = (event.loaded / event.total) * 100;
  _("progress_bar").value = Math.round(percent);
  _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
   }
   function completeHandler(event) {
        var jData = JSON.parse(event.target.responseText);
        document.getElementByID("artwork_filename").value = jData["baseName"];
        setStatus(jData["success"], jData["message"] );
  _("progress_bar").value = 0;
   }

   function errorHandler(event) {
        setStatus(false,"Upload failed! Notify site administrator");
   }

   function abortHandler(event) {
  setStatus(flase,"Upload aborted! Please try again");
   }
 </script>
.info {color:#000;}
.error {color:#F00;}
.success {color:#0F0;}
<input id="artwork_filename" type="hidden" name="custom" value="" />

There are other improvements you could make, but this should be a good starting point.

Jon P
  • 19,442
  • 8
  • 49
  • 72
  • Possibly one of the clearest answers I've seen on Stackoverflow! Testing your suggestions now, Jon P. – Matthew6 Oct 13 '14 at 09:00
  • Getting an error on this line: "var jData = JSON.parse(event.target.responseText);" - Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'json'). – Matthew6 Oct 13 '14 at 09:29
  • When I set "ajax.responseType = "text";" I get the returned basename variable as 'Undefined' – Matthew6 Oct 13 '14 at 09:54
  • OK. Looks like we're heading in the right direction. We need to check the json output. Try adding `console.log(event.target.responseText)` to dump the raw string to the console and `console.log(jData)` to inspect data object after the line `var jData = JSON.parse(event.target.responseText);` This should give some insight to what is being returned. – Jon P Oct 13 '14 at 12:45
  • Hi Jon P. Checked the console kickouts and realised the $basename variable is sent as baseName (capital N) not basename. I corrected this in my code and it works perfectly with 'ajax.responseType' set to "text". Many thanks for your effort - you answered my question 100%! – Matthew6 Oct 14 '14 at 01:52
  • Just one thing I noticed, the 'ajax.responseType' method does not work with IE or Mozilla. Only chrome can execute this code and get the desired result. Is there some tweak I need to implement to ensure all major browsers can execute this script? – Matthew6 Oct 14 '14 at 02:38
  • You've come accross one of the reasons to use [jQUery](http://jquery.com/) for ajax http://api.jquery.com/jquery.ajax/ and http://api.jquery.com/jquery.post/. jQuery standardises most cross browser issues. – Jon P Oct 14 '14 at 03:05
  • I found a fix - I just remove the 'responseType' line completely. I have no idea what issues this will cause, but the functionality is restored in uploading the file and writing the baseName variable to the hidden input for IE11 & Mozilla. – Matthew6 Oct 14 '14 at 03:24
  • It should be fine without. Though I would be cautious with older browsers (IE 8 & 9). If you can invest the time to use jQuery, I would. – Jon P Oct 14 '14 at 03:31