I implemented a multiple file uploading mechanism with jQuery and PHP. This is tested to be working on Linux/Windows Firefox, Chrome, IE, Opera, Chrome on Android and Windows Safari but not on iPhone 4g with iOS 8.3 and Safari?!
Since I am not the owner of the iPhone I cannot test by myself and I am not sure which browser is used ("I use the browser that came with it", the user says), I presume it is a mobile variant of Safari. Problem is, I really do not know what could be the fallpit of my code and how to debug or test it without an iPhone at hand?
Userstory:
User says that he is able to select a picture from his iPhone, it shows the progress bar that it is getting uploaded on the webpage and the page also says "Successfully uploaded" when it is done, but than the uploaded picture is never showing up anywhere. Like it is just vanished.
Here is some relevant code, maybe you see something that misbehaves or won't work on iPhones, I do not see.
If you got an idea on how to debug this on Linux, without an iPhone, be my guest to leave a comment.
Thank you in advance.
Relevant Javascript:
var uploadFile = function () {
var subdir = $('#subdir').val();
var fileType = $('#fileType').val();
var data = new FormData();
jQuery.each($('#file')[0].files, function (i, file) {
data.append('file-' + i, file);
});
data.append('subdir', subdir);
data.append('fileType', fileType);
$.ajax({
url: reLangUrl + "files/index?uploadFile",
data: data,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (html) {
console.log('file Upload success!');
$('#selectFileContent').replaceWith(html);
modules.files.handlers();
modules.files.selectClickHandler();
}
,
progress: function (evt) {
if (evt.lengthComputable) {
var percent = parseInt((evt.loaded / evt.total * 100), 10) + "%";
$('#uploadProgress > span').html(percent);
$('#uploadProgress').css('width', percent);
//console.log("Progress: " + parseInt( (evt.loaded / evt.total * 100), 10) + "%");
}
else {
console.log("Progress: Length not computable.");
}
},
progressUpload: function (evt) {
if (evt.lengthComputable) {
if ($('#uploadProgress').hasClass('hidden')) {
$('#uploadProgress').removeClass('hidden');
}
var percent = parseInt((evt.loaded / evt.total * 100), 10) + "%";
$('#uploadProgress > span').html(percent);
$('#uploadProgress').css('width', percent);
//console.log("Upload " + parseInt( (evt.loaded / evt.total * 100), 10) + "%");
}
else {
console.log("Upload: Length not computable.");
}
}
});
}
PHP Code:
private function uploadFile($fileType, $subdir = "") {
$n = 0;
$filesUploaded = 0;
while (isset($_FILES['file-' . $n]) && is_file($_FILES['file-' . $n]['tmp_name'])) {
$currentFile = $_FILES['file-' . $n];
if ($fileType == 'image') {
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($currentFile['tmp_name']), array(
'jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
), true
)) {
//throw new RuntimeException('Invalid file format.');
echo "<div class='error'>" . $this->ts("Invalid file format. Only jpg, png and gif is allowed.") . "</div>";
unset($currentFile['tmp_name']);
return;
}
}
$sh = $this->loadHelper('Session');
$id = $sh->get('uid');
if (substr($subdir, -1, 1) != "/") {
$subdir .= "/";
}
$target_dir = "upload/users/" . $id . "/" . $fileType . "s/" . $subdir; //$sh->get('uid');
$target_path = $target_dir;
if (!is_dir($target_path)) {
mkdir($target_path, 0777, true);
chmod($target_path, 0777);
}
$filename = basename($currentFile['name']);
$target_file_path = dirname(__FILE__) . '/../../' . $target_path . $filename;
if (move_uploaded_file($currentFile['tmp_name'], $target_file_path)) {
chmod($target_file_path, 0777);
//echo "<div class='system'>" . $this->ts("File uploaded successful") . "</div>";
++$filesUploaded;
} else {
//echo "<div class='error'>" . $this->ts("Error uploading Image.") . "</div>";
}
++$n;
}
if ($filesUploaded > 0) {
echo "<div class='system'>" . $filesUploaded . " " . $this->ts("file(s) uploaded successful") . "</div>";
} else {
echo "<div class='error'>" . $this->ts("Error uploading file(s).") . "</div>";
}
return;
}
And finally the HTML Form:
<div class="uploadFilesForm">
<div class="help">
<?php echo $this->ts('Only jpeg, png and gif files allowed!'); ?>
</div>
<form class="pure-form" action="<?php echo $this->action("files/index") ?>" method="post" enctype="multipart/form-data">
<input id="subdir" name="subdir" type="hidden" value="<?php echo $subdir ?>" />
<input id="fileType" name="fileType" type="hidden" value="<?php echo $fileType ?>" />
<label for="file" ><?php echo $this->ts("upload " . $fileType) ?></label>
<input class="pure-button" id="file" name="file[]" multiple="multiple" accept="<?php echo $fileType ?>/*" type="file"/>
<a class="pure-button pure-button-primary" id="uploadFile" onclick="return false;" name="uploadFile" >
<?php echo $this->icon('mono/white/16x16/round_and_up.png');?>
<?php echo $this->ts("upload") ?>
</a>
</form>
<div id="uploadProgress" class="hidden"><span class="percent">0%</span></div>
</div>