Copy a multiple file from client system to server - php

I don't have any idea to copy a file from client system to server.
Short Description
I am using upload folder dialog box to upload a multiple file from particular path.
XML file is mandatory, because i need to extract some information to process
While upload event i read all the information i need to process
$("#myInput").change(function() {
var names = [];
var formData = new FormData();
for (var i = 0; i < $(this).get(0).files.length; ++i)
{
var F_name= $(this).get(0).files[i].name;
var extension = F_name.replace(/^.*\./, '');
if(extension != "xml" && extension != "db"){
formData.append('userfiles[]', $(this).get(0).files[i], F_name);
}
else if(extension == "xml"){
//Gathering info
}} });
User interface fields are filled automatically after this process and user have to fill some more fields. While user click process button in server side i create folder and some new XML files too. Everything is fine except , copy a file from client to server.
//Jquery
$("#process_but" ).click(function() {
$.ajax({
type: "POST",
url: "Asset/PHP/function.php",
data: {action: "action1", DOI:doi, TLA:tla, STITLE:S_Title, SHEAD:S_Head, SLINK:S_Link, LTYPE:link_type, DESC:description, ATITLE:Art_title, JTitle:JOU_title, ANAME:Author_name, FSHARE:Fig_share, FNAMES:filenames, FCOUNT:filecount},
success: function(response) {
if(response == 1)
{alert("success");}
else
{alert("Something goes wrong.....");}
},
error: function() {
alert("Error");
}
});
});
//php
<?php
session_start();
$action = $_POST['action'];
if($action == "action1")
{
//what i have to do
}
?>

Related

zip multiple files on server and echo back zip file

Consider a site which allows user to store files (pdf, docx, jpeg, png, gif only). Part of the html:
<ul>
<li>lola.doc</li>
<li>lola.pdf</li>
<li>lola.jpeg</li>
<li>lola.docx</li>
</ul>
When a user clicks on any of the above, the file either opens or a save dialpg appears. This is fine.
Now I want user to be able to select some of these files (which are on the server). The files will be zipped and echo back to user with a prompt to save. I cannot use above, so I have this option:
html:
<select class="multiple_select " multiple>
<option value="../folder/lola.doc">lola.doc</option>
<option value="../folder/lola.pdf">lola.pdf</option>
<option value="../folder/lola.jpeg">lola.jpeg</option>
<option value="../folder/lola.docx">lola.docx</option>
</select>
<button id="btn" type="button">Download</button>
js:
js:
$('#btn').on('click', function() {
var options_selected = $('select').find('option:selected');
options_selected_le = options_selected.length;
var i;
var options_selected_arr = [];
var options_names_arr = [];
for (i=0; i<options_selected_le; i++) {
options_selected_arr.push(options_selected.eq(i).val());
options_names_arr.push(options_selected.eq(i).text());
}
var fd = new FormData();
fd.append('zipname', zipname);
fd.append('options_selected_arr', JSON.stringify(options_selected_arr));
fd.append('options_names_arr', JSON.stringify(options_names_arr));
$.ajax({
url: 'download_multiple_files.php',
type: 'post',
data: fd,
cache: false,
contentType: false,
processData: false,
beforeSend: function(xhr) {
xhr.setRequestHeader("X-Download", "yes");
},
success: function(response){
alert(response); //I am sure this is wrong
// Do I need js to handle zip file here. I guess php should automatically do this
}
});
});
<?php
session_start();
require 'server_conn.php'; // for connection and holds test_input function
// do some security checks ...
$zipname = 'file.zip';
$arr = json_decode($_POST['options_selected_arr']);
$file_arr = [];
foreach ($arr as $obj) {
array_push($files_arr, test_input($obj));
}
$arr = json_decode($_POST['options_names_arr']);
$files_names_arr = [];
foreach ($arr as $obj) {
array_push($files_names_arr, test_input($obj));
}
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
for ($i=0; $i<$c; $i++) {
$zip->addFile($file_arr[$i], $files_names_arr[$i]);
}
$zip->close();
header('Content-Type: application/zip');
header('Content-Length: ' . filesize($zipname));
header('Content-Disposition: attachment; filename="file.zip"');
readfile($zipname);
unlink($zipname);
?>
Response from server is giberish and there is no error indication. I suspect my php is defective.
I have solved this using 2 methods:
Method 1:
JSZip without php (Each select option already contains file path as value)
The advantage of this method: It does not store the new zip file on the server, so storage is not a problem.
I believe using blob will also allow ziping large files, max size I don't know.
To use this method, one needs to download Filesaver, jszip and jszip utility and add following lines to the html doc body
<script src="../js/lib/jszip.min.js"></script>
<script src="../js/lib/jszip-utils.min.js"></script>
<script src="../js/lib/FileSaver.js"></script>
The js script makes use of Promisejs, which I haven't studied before (but will now do). Below is the js:
$('#btn').on('click', function() {
function urlToPromise(url) {
return new Promise(function(resolve, reject) {
JSZipUtils.getBinaryContent(url, function (err, data) {
if(err) {
reject(err);
} else {
resolve(data);
}
});
});
}
var options_selected = $('select').find('option:selected');
options_selected_le = options_selected.length;
var zipname = 'file.zip';
var Promise = window.Promise;
if (!Promise) {
Promise = JSZip.external.Promise;
}
var i;
var zip = new JSZip();
for (i=0; i<options_selected_le; i++) {
var url = options_selected.eq(i).val();
var filename = options_selected.eq(i).text();
zip.file(filename, urlToPromise(url), {binary:true});
}
zip.generateAsync({type:"blob"}).then(function callback(blob) {
//see FileSaver.js
saveAs(blob, zipname);
//alert('success');
}, function (e) {
alert('Error zipping file(s). Retry');
});
});
Method 2:
Using js and PHP:
First create a folder on the server to hold the zip file, I name the folder 'archive'
This is why I may not vote for this method.
New js:
$('#btn').on('click', function() {
var options_selected = $('select').find('option:selected');
options_selected_le = options_selected.length;
var zipname = 'file.zip';
var fd = new FormData();
fd.append('zipname', zipname);
fd.append('options_selected_arr', JSON.stringify(options_selected_arr));
fd.append('options_names_arr', JSON.stringify(options_names_arr));
$.ajax ({
url: 'download_multiple_files.php',
type: 'post',
data: fd,
cache: false,
contentType: false,
processData: false,
success: function(response){
window.location = response;
}
});
});
New php:
<?php
session_start();
// connect to server, scan input data and do some security checks ...
$zipname = 'file.zip';
$arr = json_decode($_POST['options_selected_arr']);
$file_arr = [];
foreach ($arr as $obj) {
array_push($files_arr, test_input($obj));
}
$arr = json_decode($_POST['options_names_arr']);
$files_names_arr = [];
foreach ($arr as $obj) {
array_push($files_names_arr, test_input($obj));
}
$zip = new ZipArchive();
$path = '/archive/'.$zipname;
if ($zip->open($path, ZipArchive::CREATE)!==TRUE) {
echo 'Cannot zip files'; die;
}
$c = count($file_arr);
for ($i=0; $i<$c; $i++) {
$zip->addFile($file_arr[$i], $files_names_arr[$i]);
}
$zip->close();
echo $path;
mysqli_close($conn);
?>
This will force save dialog to appear. Two pending challenges I have for this method are:
Prevent a new window to open
The save dialog appears with download as file name but without extension .zip. So user should type .zip along with the name. I would prefer the computed zip filename to appear in the save dialog

Showing docx without page refresh

I am curious to know that is it possible to show a docx file (which is available on server) inside a div without refreshing that page (using google doc viewer API or any other possible way).
Let me clear my requirement:-
HTML+JQUERY code:
<div class="browse-flie col-md-7">
<div class="alert alert-danger" style = "display:none;"></div>
<input type="file" id="uploaddocfile">
<button name="upload" value="Upload" class="btn EditBtn uplaod_file">Upload</button>
</div>
<div id = "myid" style = "height:500px;width:600px;"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$('.uplaod_file').on('click', function() {
var file_data = $('#uploaddocfile').prop('files')[0];
var ext = file_data.name.split('.').pop();
if(ext == 'docx'){
var form_data = new FormData();
form_data.append('file', file_data);
$.ajax({
url: 'upload.php', // point to server-side PHP script
dataType: 'text', // what to expect back from the PHP script, if anything
cache: false,
contentType: false,
processData: false,
data: form_data,
type: 'post',
success: function(php_script_response){
var response = $.parseJSON(php_script_response);
if(response.status == 'error'){
$('.alert-danger').css({'display':'block'});
$('.alert-danger').html('file upload failed please try again');
}
if(response.status == 'success'){
$('#myid').html("http://docs.google.com/gview?url=http://loalhost:8888/Grade/uploads/IEP Form-1.docx&embedded=true");
}
}
});
}else{
$('.alert-danger').css({'display':'block'});
$('.alert-danger').html('file extension must be docx'); return false;
}
});
</script>
PHP code:
<?php
// A list of permitted file extensions
$allowed = array('docx');
//echo "<pre/>";print_r($_FILES); die;
if(isset($_FILES['file']) && $_FILES['file']['error'] == 0){
$extension = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
if(!in_array(strtolower($extension), $allowed)){
echo '{"status":"error"}';
exit;
}
if(move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/'.$_FILES['file']['name'])){
echo '{"status":"success"}';
exit;
}
}
echo '{"status":"error"}';
exit;
Now:
I have simple file upload code through jquery and php (working perfectly fine).
Now what I want is, after upload file when it comes success as a response then I want to show a doc file using API to my <div id = "myid" style = "height:500px;width:600px;"></div> (without refresh)
So what I tried:
$('#myid').html("http://docs.google.com/gview?url=http://loalhost:8888/Grade/uploads/IEP Form-1.docx&embedded=true");
(link changed for security reason but docx is available on server and I am able to open it directly)
But obviously it's not going to work.
So how can I do that?
Normally you'd do :
if(response.status == 'success'){
$('#myid').load("http://docs.google.com/gview?url=http://loalhost:8888/Grade/uploads/IEP Form-1.docx&embedded=true");
}
Instead of .html (which does something else).
However it's unlikely to work because the document you are accessing is not one that is managed by GoogleDocs (there may be cross-origin issues), so make sure you're allowing remote requests from Google to be made.
Instead you could try
if(response.status == 'success'){
$('#myid').html("<iframe src=\"http://docs.google.com/gview?url=http://loalhost:8888/Grade/uploads/IEP Form-1.docx&embedded=true\"></iframe>");
}
In case Google allows embedding of gview in iframes (though they may not).

TCPDF - AJAX - Download file without saving it to webserver from AJAX call

I have an AJAX call to the create_pdf.php page:
$('body').on('click', '.PrintButtonWithClass', function (event) {
var1 = $('#id1').val();
var2 = $('#id2').val();
dataString='var1='+var1+'&var2='+var2+'&pdf_name=PdfName&pdf_creator=myname';
$.ajax({
type: 'post',
url: '/path/to/createpdf/file/create_pdf.php',
data: dataString,
success: function (data) {
alert('success');
}
});
});
In create_pdf.php I tried to use this line to download the file:
$pdf->Output(str_replace(' ','_',utf8_decode($_POST['pdf_name'])).'.pdf', 'D');
I tried also the FD and I parameters with no success, the file does not get downloaded.
How can I force downloading the file created without saving it to the webserver and without redirecting user to any other page? I want him to stay on the same page, and that the browser pops up a (download or preview dialog box) for the PDF. Is there any way to do it?
EDIT : create_pdf.php is Waiting for POST variables. and uses them to create the HMTL for the pdf.
You can try to submit the form to a new window( like a popup ):
<form method="post" id="myform" action="your_url">
<input name="param1">
</form>
And in javascript
// create popup window
var wind = window.open('about:blank', '__foo', 'width=700,height=500,status=yes,resizable=yes,scrollbars=yes');
// submit form to popup window
$("#myform").attr("target", "__foo");
Do not forget to send content-type header from php:
header("Content-Type", "application/pdf");
Edit:
Browsers should display your pdf content and also show download or print options.
The code is not tested but I think it would do what you requested;
I found a work-around for my problem.
I did an AJAX call inside another AJAX call.
the first AJAX call creates the file on webServer and opens the file in a new Window.
In his success parameter I do the following:
The second AJAX call that deletes the file from Server.
$.ajax({
type: 'post',
url: '/path/to/create_pdf.php',
data: dataString,
success: function (data) {
window.open(
data,
'_blank' // <- This is what makes it open in a new window.
);
window.setTimeout(function () {
dataString2 = 'Downloaded=true';
$.ajax({
type: 'post',
url: '/path/to/create_pdf.php',
data: dataString2,
success: function (data) { alert(data); }, // handler if second request succeeds
});
}, 5000);
},
});
Using this answer to my similar request : send a csv file from php to browser
I needed to (1) get and display a pdf in another window; and
(2) get a CSV file and prompt for saving.
I have 2 simple buttons on the page (http://potoococha.net/) for each. Here is the code:
function getCSVText(evt) {
if (currentChecklistCountry) {
var form = $('<form method="post" action="../php/sendCSV.php?country=' + currentChecklistCountry + '"></form>');
$('body').append(form);
form.submit();
form.remove();
}
else checklistCountryButton.classList.add("needsAttention");
}
function openChecklistPage() {
if (!currentChecklistCountry) {
checklistCountryButton.innerHTML = "Select Country";
checklistCountryButton.classList.add("needsAttention");
return;
}
if (gNumDays == undefined) gNumDays = 12;
vars = "?country=" + currentChecklistCountry;
vars += "&num_days=" + gNumDays;
vars += "&line_nos=" + lineNumbers.checked;
vars += "&left_check=" + leftCheck.checked;
vars += "&endemics=" + showEndemics.checked;
vars += "&sci_names=" + !sciNames.checked;
vars += "&italics=" + !italics.checked;
window.open( '../php/makePDF.php' + vars, '_blank' );
}
So the getCSVText() methods downloads a file using a temporary form appended and then immediately removed, and openChecklistPage() successfully opens another browser window with a pdf file. The pdf file is never saved on the server. The CSV file is already stored there and just retrieved. Perhaps you can modify the code for your purposes.

Phonegap 3.7.0 e-mail file from input[type=file]

I'm having a problem with sending a file from an app I'm developing with phonegap.
I'm new to phonegap, so I might be trying to solve this in an entirely wrong way, so let me describe the the end goal first.
I'm developing a car rental app, I need to make a contact form, so users can leave an order to rent a car.
The form requires user to put in some basic information, like name and phone number, and also attach a photo or a scan of driver's license.
I was able to figure out the basic info part. I'm using $.ajax dataType: 'jsonp', to send the data to the server and then simply e-mail it to my client's address.
But I can find a way to send the file to the server.
I'm using an input[type=file] field to let the user choose what file to upload.
I've tried uploading file using FileTransfer, but apparently input[type=file] gives you some fake file path, that can't be directly used by FileTransfer.upload()
Problem is, I can't understand how can I get a proper file path for FileTransfer.upload function.
I've tried doing it another way, by reading the file using FileReader.
I tried reading the file and setting an image src to the result, but it doesn't work (it show broken image icon instead of an image, the same code works on PC).
I also tried to output it as text, that does output some data (so why doesn't it work for image src?).
Because I did manage to output the data read from the file as text I thought I will send that to the server and save it.
So here is how the code would look like:
On input change I read the file into a global variable
$(".file1").change(function(e){
var caster = e.target;
var files = caster.files;
if(FileReader && files && files.length) {
var fr = new FileReader();
fr.onloadend = function(e) {
//$(".image").attr("src",e.target.result);
window.file1base64 = e.target.result;
}
fr.readAsDataURL(files[0]);
}
});
Then, when user presses a button, I run FileTransfer.upload and then check every 0.1 seconds, whether the file upload is complete
function uploadSuccess(r) {
$(".output").append(" Success ");
window.fileStatus = true;
}
function uploadError(error) {
$(".output").append(" Error "+error.code+" ");
window.fileStatus = true;
window.fileError = error.code;
}
function uploadFile() {
$(".output").append(" uploadFile ");
file = $('.file1').val().split('\\').pop();
$(".output").append(" File-"+file+" ");
if(file){
$(".output").append(" fileExists ");
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = file;
options.mimeType = "image/jpeg";
options.chunkedMode = false;
options.headers = {
Connection: "close"
};
$(".output").append(" FileUploadOptions ");
window.fileStatus = false;
window.fileError = '';
//fileuri = $(".image").attr("src");
fileuri = window.file1base64;
$(".output").append(" fileuri ");
var ft = new FileTransfer();
ft.upload(fileuri, encodeURI("http://***.***/savefile.php"), uploadSuccess, uploadError, options);
$(".output").append(" upload ");
checkFile();
}
}
function checkFile() {
if(!window.fileStatus) {
$(".output").append(" check ");
setTimeout(checkFile, 100);
return;
}
}
After some checks, it prints out Error 3 and I can't figure out what that means or how to fix it.
Server side code is simply this:
Get the file and save it
$dir_name = dirname(__FILE__)."/uploadedimages/";
move_uploaded_file($_FILES["file"]["tmp_name"], $dir_name."test.txt");
But no file is created on the server.
use the FormData object to get the form data (including input file) and submit it this way:
var data = new FormData($('#yourFormID')[0]);
$.ajax({
url: serverURL,
data: data,
cache:false,
contentType: false,
processData: false,
type: 'POST',
error: function(jqXHR,textStatus,errorThrown){
},
success: function(data){
}
});
You should set the FILEURL in some variable and image in some html image element and then use it to transfer the image.
like this:
function onPgCameraSuccess(imageData) {
fileEntry.file(
function(fileObj) {
var previewImage= document.getElementById('SomeImageElement');
fileName=imageData.substr(imageData.lastIndexOf('/')+1);
fileURL=imageData;
previewImage.src =imageData;
$('#SomeTextBox').val(fileName);
});
}
function SubmitPhoto(){
var uOptions = new FileUploadOptions();
var ft = new FileTransfer();
uOptions .fileKey = "keyofyourfileonserver";
uOptions .fileName = fileName;
uOptions .mimeType = "image/jpeg";
uOptions .httpMethod = "POST";
uOptions .params = params;
ft.upload(fileURL,
urlofsvc,
photoSuccess,
photoFail,
uOptions,
true
);}

jQuery-File-Upload used for UI only?

I would like to upload multiple files. The use case is: users on my website can upload multiple photographs.
Right now I am just using
<input type="file" name="myfiles" multiple="multiple">
This works well, but I want more. I'd like a nice interface showing the user what is uploaded AND for it to be more clear about which files are being uploaded.
https://github.com/blueimp/jQuery-File-Upload
So this blueimp jquery file upload script has beautiful UI and is just what I'm looking for. However there are a few issues:
1) I would like to submit the form to a php file which will DECIDE if the files get uploaded or not.
2) My form has many (many..) other fields. I would like this to submit via plain old post submit button along with the rest of my form. Is this possible?
If not, can someone recommend a better option?
Thanks!
All of the above is possible with the blueimp file upload plugin.
1) Decide if files get uploaded or not
Use the add: option in the plugin to make a separate ajax call to the server with the filenames added, and use the response to filter the list of files to be uploaded.
2) Add other data from the form to the upload
Use the formData: option in the plugin to add the other fields in a form to be passed to the server upon submit.
So something like the following:
$('#fileupload').fileupload({
url: url,
dataType: 'json',
autoUpload: false,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
maxFileSize: 5000000, // 5 MB
loadImageMaxFileSize: 15000000, // 15MB
formData: $("#myForm").serializeArray()
}).on('fileuploadadd', function (e, data) {
data.context = $('<div/>').appendTo('#files');
$.ajax(
url: "/checkfiles",
data: { files: data.files },
success: function(result) {
// assume server passes back list of accepted files
$.each(result.files, function (index, file) {
var node = $('<p/>')
.append($('<span/>').text(file.name));
if (!index) {
node
.append('<br>')
.append(uploadButton.clone(true).data(data));
}
node.appendTo(data.context);
});
}
}).on('fileuploadprocessalways', function (e, data) {
var index = data.index,
file = data.files[index],
node = $(data.context.children()[index]);
if (file.preview) {
node
.prepend('<br>')
.prepend(file.preview);
}
if (file.error) {
node
.append('<br>')
.append(file.error);
}
if (index + 1 === data.files.length) {
data.context.find('button')
.text('Upload')
.prop('disabled', !!data.files.error);
}
}).on('fileuploaddone', function (e, data) {
$.each(data.result.files, function (index, file) {
var link = $('<a>')
.attr('target', '_blank')
.prop('href', file.url);
$(data.context.children()[index])
.wrap(link);
});
}).on('fileuploadfail', function (e, data) {
$.each(data.result.files, function (index, file) {
var error = $('<span/>').text(file.error);
$(data.context.children()[index])
.append('<br>')
.append(error);
});
});
});

Categories