Drag and Drop Jquery upload to PHP - php

I have seen many topics about this problem but none of them got a legit answer or a including PHP file.
I want to make a drag & drop saving tool. The problem is that my files are not getting uploaded to my ftp folder.
I got the following code:
HTML:
<div id="drop_zone">
<p>Drop Here</p>
</div>
<form enctype="multipart/form-data" id="yourregularuploadformId">
<input type="file" name="files[]" multiple="multiple">
</form>
JS:
$(function() {
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
etc.... dropping part
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
files = evt.dataTransfer.files;
uploadFile(files);
etc... getting file to my method
function uploadFile(droppedFiles){
// add your files to the regular upload form
var uploadFormData = new FormData($("#yourregularuploadformId")[0]);
if(droppedFiles.length > 0) { // checks if any files were dropped
for(f = 0; f < droppedFiles.length; f++) { // for-loop for each file dropped
uploadFormData.append("files[]",droppedFiles[f]); // adding every file to the form so you could upload multiple files
}
}
// the final ajax call
alert(uploadFormData);
$.ajax({
url : "php/uploadFile.php", // use your target
type : "POST",
data : uploadFormData,
cache : false,
contentType : false,
processData : false,
success : function(ret) {
alert(ret);
}
});
}
Got the above code from another topic. (alert(uploadFormData); -> gives me a Formdata aboject)
PHP:
move_uploaded_file($_FILES["file"]["tmp_name"],
"ftp/" . $_FILES["file"]["name"]);
echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
Can't make it work :<
The message i get from the callback function in my JS is:
Undefined index: file

Your PHP code needs to iterate over all of the files in the request. Based on your javascript, your PHP code should look something like this:
foreach ($_FILES["files"] as $file) {
move_uploaded_file($file['tmp_name'], $target);
}
The $target variable must point at the local destination for your file. See the PHP manual for more details.

Related

Summernote upload image not showing in the editor after submitting to update

I have been working on a project, using Summernote. My project is like a blog system and I need to upload contents and images.
I have checked the other posts here and other places and managed to insert images to the file with ajax where I want to save the images. However, when I am editing, an image is there but once I click "update button" (submit button in a form), the images won't be there anymore.
I also check the inspect and resource says
Request URL: http://localhost/cms/admin/includes/images/42a0e188f5033bc65bf8d78622277c4e.JPG
This is the right path but after updating, I get a message like
Request URL: http://localhost/%22includes/images/42a0e188f5033bc65bf8d78622277c4e.JPG/%22
Also status code says
Status Code: 403 Forbidden
Here is my code
$('#summernote').summernote({
callbacks: {
onImageUpload: function(files) {
for(let i=0; i < files.length; i++) {
$.upload(files[i]);
}
}
},
height: 300,
});
$.upload = function (file) {
let out = new FormData();
out.append('file', file, file.name);
$.ajax({
method: 'POST',
url: './includes/editor-upload.php',
contentType: false,
cache: false,
processData: false,
data: out,
success: function(url) {
$('#summernote').summernote("insertImage", url, 'filename');
},
error: function (jqXHR, textStatus, errorThrown) {
console.error(textStatus + " " + errorThrown);
}
});
};
And this is my php code (editor-upload.php)
if ($_FILES['file']['name']) {
if (!$_FILES['file']['error']) {
$name = md5(rand(100, 200));
$ext = explode('.', $_FILES['file']['name']);
$filename = $name . '.' . $ext[1];
$destination = 'images/' . $filename; //change this directory
$location = $_FILES["file"]["tmp_name"];
move_uploaded_file($location, $destination);
echo 'includes/images/' . $filename;//change this URL
}
else
{
echo $message = 'Ooops! Your upload triggered the following error: '.$_FILES['file']['error'];
}
}
Insert uploaded image to summernote editor
Summernote image upload
Summernote 0.8.12 Image Upload And Delete
I have tried these but nothing worked for me.
I have of course Summernote js and css file and am using Summernote 0.8.18
I am sure I am doing something wrong but I can't figure this out yet.
I am hoping somebody can help me out.
If the images folder is inside of the includes folder, change the following line:
$destination = 'images/' . $filename;
to
$destination = './includes/images/' . $filename;
Next, enter the full URL name and the full path to the image instead of
echo 'includes/images/' . $filename;
Also, the editor-upload.php file in your Ajax upload script may be causing the 403 errors. if the upload file is not in the same folder as your form and index.php page, it can prove problematic.
Try moving the file to the same folder as your form with the summer note editor, and enter the file in your Ajax script as
'editor-upload.php'

How to access a file after it was uploaded with Dropzone.js and PHP

I would like to access a file after it was uploaded to the server via dropzone.js (v5) and PHP, i.e. I'd like to retrieve the file URL. How can I get it?
form.php:
<form action="upload.php" class="dropzone" enctype="multipart/form-data">
<div class="fallback">
<input name="file" type="file" multiple />
</div>
</form>
<script src="/js/dropzone.js"></script>
<script>
Dropzone.autoDiscover = false;
$('.dropzone').dropzone({
init: function () {
this.on("complete", function (file) {
runthisfunction();
}) // end on complete
}
});
</script>
upload.php:
<?php
if (!empty($_FILES)) {
$random = randomString(18);
$tempFile = $_FILES['file']['tmp_name'];
$name = $_FILES['file']['name'];
$fileExt = strtolower(substr(basename($name), strrpos(basename($name), ".") + 1));
$newname = $random.'.'.$fileExt;
move_uploaded_file($tempFile,"images/$newname");
} // end if files not empty
?>
I have tried retrieving the uploaded file URL via the file object, but no success:
this.on("complete", function (file) {
console.log(file);
console.log(file.dataURL);
console.log(file.name);
}) // end on complete
Since the file is uploaded with PHP and renamed within the upload.php, I believe I would need to "POST" this filename somehow to another file and then retrieve it back. How can I do that?
Your intuition about needing to get the filename back from the server is correct. There's a simple example in the Dropzone FAQ which shows the basic idea.
1) Your server has to respond to the upload POST with the details of where it put the file - eg URL, filename, path, etc. So in your case, at the end of your PHP code, you'd need to do something like:
// ... rest of your PHP ...
move_uploaded_file($tempFile,"images/$newname");
// Let the browser/JS know we are sending a JSON response back. Make sure there
// is no output before this.
header('Content-type: application/json');
echo json_encode([
'status' => 'OK', // Not required, but maybe useful
'image' => "images/$newname",
]);
2) In your JS, you need to accept that response from the server, and do something with it. The Dropzone docs show for the success event:
The file has been uploaded successfully. Gets the server response as second argument.
This sounds like the one we need. So replace your complete handler with one for success, and add a 2nd argument:
this.on("success", function (file, response) {
console.dir(response);
// response.image will be the relative path to your uploaded image.
// You could also use response.status to check everything went OK,
// maybe show an error msg from the server if not.
});
The Dropzone FAQ item I linked to above shows using an .emit() method to display the image, I'm not familiar with that and it doesn't seem to be described in the docs. Try it, maybe that works and suits your needs. If not, you could do something like:
// Maybe you have an <img class='thumbnail'> in your HTML, ready to show the upload
$('.thumbnail').attr('src', response.image).fadeIn();

Handle PHP upload file Error codes from and to AJAX request/response NO JQuery

I want to submit a form without selecting a file, normally i get php error code number 4 => no file uploaded from $_FILES['file']['error'] Everything is ok if i work with HTML and PHP only, but not when i add AJAX !
My problems :
i don't know how to post/send empty file array to be able to handle
it in php script !
i don't know how to write a response back to AJAX script, should it be in progress handler, or error handler or i don't know... !
I don't want to work with JQuery, I copy/paste all my codes to build anything since am at level 0 in coding so i need to understand every line and JQuery seems to me like interstellar space !
The form :
<form id="upload_form" enctype="multipart/form-data" method="post" >
<input type="file" name="file" id="file_id" /><br />
<input type="button" value="Upload File" onclick="uploadFile()" /><br />
</form>
The JS script :
<script>
function uploadFile(){
// target the file that is to be uploaded
var file = document.getElementById("file_id").files[0];
// var file = document.getElementById("file_id"); is not working,
// what is files ? why do i need .files[0]?
// Create a new formdata object instance
var formdata = new FormData();
// append the file to the formdata
formdata.append("file", file);
// on submit, if no file selected, the error index is 4 in php
// do i have to append the file error here ?
// Build the AJAX request
var xhr = new XMLHttpRequest();
// add event listeners
// progress handler
xhr.upload.addEventListener("progress", progress_handler, false);
// complete handler
xhr.addEventListener("load", complete_handler, false);
// error handler
xhr.addEventListener("error", error_handler, false);
// abort handler
xhr.addEventListener("abort", abort_handler, false);
// open a php script
xhr.open("POST", "file_upload.php");
// send the AJAX request
xhr.send(formdata);
}
function progress_handler(event){
// create a progress bar, or a % of uploading...
// using event.loaded and event.total (returns size in bytes)
}
// when the operation is finished
function complete_handler(event){
// the message php is echoing will be put inside that div
// using responseText !
document.getElementById("some_div").innerHTML = event.target.responseText;
// can we echo back other things beside strings, like an array, int... ?
//set the progress bar to full
}
function error_handler(event){
document.getElementById("status").innerHTML = "Upload failed !";
// do i need to append the error here instead ? how ?
// nothing that i tried around $_FILES[file]['error'] in php worked back here !
}
function abort_handler(event){
//cancel listener if the file upload is aborted
document.getElementById("status").innerHTML = "Upload aborted !";
}
</script>
the php file : file_upload.php
<?php
echo '<pre>'; print_r($_FILES); echo '</pre>';
// this is working when file is selected and echo back all array elements
// but why there NOTHING returned when no file selected, not even en empty array !!!
// -----------------------------------------------------
if(isset($_FILES['file']) AND $_FILES['file']['error'] == 0)
{
// move the file from the tmp folder to upload folder in website
}
else
{
echo "Error : Please select a file before clicking the Upload button !";
// i don't want this which is working!
echo $_FILES["file"]["error"];
// i want this which is working only without AJAX !!!
// and would be :
// 1 > The uploaded file exceeds the upload_max_filesize directive in php.ini
// ...
// 4 > No file was uploaded at all !
// until
// 8 > a php extension stopped the upload...
}
?>
Thank you very very much.
You should prevent content-type autodetection.
I make it such way ( using jQuery )
$.ajax({
url: "<YOUR URL HERE>",
data: formData, //filled formData instance
type: "POST",
dataType: 'json',
contentType: false,
cache: false,
processData: false
})
And it works proper for me.

Load a file, edit it and the save it (server side) PHP

I got a page that loads html code from a text file into an textarea and I need to be able to save the contents of it using a script.
I'm using a PHP script to load the code from a file and echo it out to the textarea, but how can I send back the contents to the script and save it either to the same file or to a file with a new name?
I was thinking if getElementById would help me but I'm not sure how.
The load script(it has the ability to delete files too)
// The file hierarchy:
//
//Web root - admin - This file
// - pages - in here are the page text files
// The variable pagesList is the filename chosen in a dropdown list earlier
$page = $_GET["pagesList"];
$action = $_GET["action"];
//get the path to the page( all pages are in a folder named 'pages')
$filename = dirname(dirname(__FILE__))."/pages/".$page;
if(file_exists($filename) and is_file($filename)){
//If I want to load a file
if($action == "open"){
$f = fopen($filename,"rt");
$content = fread($f, filesize($filename));
echo $content;
#fclose($f);
//If I want to delete a file
}elseif($action == "delete" && is_file($filename)){
//move the working directory to where the file is
$old = getcwd();
chdir(dirname(dirname(__FILE__))."/pages/");
//----
if(unlink($filename))
echo "File deleted,".$filename;
else
echo "Error deleting file!";
//change back the working directory to where it was
chdir($old);
//If I want to save a file
}elseif($action == "save"){
if(file_exists($filename)){
//Unknown script, need help!
}else{
}
}
}
The textarea is only one line with an include in it:
<textarea id="html_content" style="width:600;height:200;"><?php include("loader.php") ?></textarea>
To sum it up: I need help getting the contents of an textarea to a script for saving later.
EDIT: Thanks to davidkonrad I just had to add a few POST receives in the script and add file_put_content with the content sent to it.
The problem that arised is that jQuery apparently puts \ before each " or '. That messes up all the html code that is supposed to be clean and valid. I'll have to replace the \" with " somehow, str_replace wont cut it. Any ideas?
EDIT2: Thanks again to davidkonrad that fixed it by using encodeURIComponent(jQuery) clientside and urldecode(PHP) serverside.
Update, OK if you just are in doubt how to submit a textarea to your loader.php :
<form method="post" action="loader.php">
<input type="hidden" name="filename" value="test.html">
<input type="hidden" name="action" value="save">
<textarea name="html_content"></textarea>
<input type="submit" value="save">
</form>
loader.php, now you have
$filename=$_POST['filename'];
$action=$_POST['action'];
$html_content=$_POST['html_content'];
Which here is "test.html", "save" and any text typed into the textarea. use those variables in your if .. else loop as above, eg
} elseif($action == "save"){
if(file_exists($filename)){
//Unknown script, need help!
file_put_contents($filename, $html_content); //or how you want to do it
}
}
The disadvantages is
the page needs to be reloaded on each action
you need to echo the inserted content again, between <textarea> .. </textarea> once it is inserted (as I understand, the HTML is part of loader.php)
likewise keeping track of the current filename is more complicated
NB : Unless there is a particular reason, you dont have to check if a file already exists before writing to it. And still thinks travelling around in the directories just makes it complicated :) Is /pages/ not just a relative path?
It does not need to be so complicated. I would use a more simple and structured approach, consisting of
A PHP class that performs each task by simple file_put_contents, file_get_contents and unlink, including some small error handling
A system of $.ajax calls (jQuery) calling the above PHP class
The following working example performs save, load and delete of HTML files to a directoty /files, which you must give RW permissions.
file.php
class File {
private $filename;
private $dir = 'files/';
public function __construct() {
$action = isset($_POST['action']) ? $_POST['action'] : false;
$this->filename = isset($_POST['filename']) ? $_POST['filename'] : false;
if ((!$action) || (!$this->filename)) return;
switch ($action) {
case 'save' :
$this->save(); break;
case 'load' :
$this->load(); break;
case 'delete' :
$this->delete(); break;
default :
return;
break;
}
}
private function save() {
$content = isset($_POST['content']) ? $_POST['content'] : '';
file_put_contents($this->dir.$this->filename, urldecode($content));
}
private function load() {
$content = #file_get_contents($this->dir.$this->filename);
echo $content;
}
private function delete() {
unlink($this->dir.$this->filename);
}
}
$file = new File();
file.html, markup
<input type="text" id="filename" value="test.txt"><br>
<textarea id="html_content" style="width:600;height:200;"></textarea>
<br>
<button id="save">save</button>
<button id="load">load</button>
<button id="delete">delete</button>
file.html, script :
var url = 'file.php';
$("#save").click(function() {
$.ajax({
url : url,
type: 'post',
data : {
filename : $("#filename").val(),
action : 'save',
content : encodeURIComponent($('#html_content').val())
}
});
});
$("#delete").click(function() {
$.ajax({
url : url,
type: 'post',
data : {
filename : $("#filename").val(),
action : 'delete'
}
});
});
$("#load").click( function() {
$.ajax({
url : url,
type: 'post',
data : {
filename : $("#filename").val(),
action : 'load'
},
success : function(html) {
$("#html_content").val(html);
}
});
});
The HTML content (tags, HTML entities) is maintained upon save by the use of encodeURIComponent and urldecode. Try it out yourself, and consider this as the base for a more complex system. If you want to create a new file, just enter a new filename in the filename box. If you want to load a file, enter that filename in the filename box. I think file_put_contents etc is by far more robust than dealing with file handles, chdir(dirname(dirname(__FILE__))."/pages/"); (??) and so on.
try using php fputs function to save file

Quick suggestion on php multiple file uploading

I'm using thid code this basically helping me getting file which user drops on browser and then post it to php and echoing file name but the problem is with the array in php when ever i drop 2 files and call the php file and try to echo the count of files it gives me 5 always and it echos the 2 file names and + othes as undefined index.... and if i upload 5 files it show all 5 with no problem....plz help me why this is happing...
Here is my jquery code:
function handleFiles(droppedFiles) {
var uploadFormData = new FormData($("#yourregularuploadformId")[0]);
if(droppedFiles.length > 0) {
// checks if any files were dropped
for(var f = 0; f < droppedFiles.length; f++) {
// for-loop for each file dropped
alert(droppedFiles[f]['name']);
uploadFormData.append("files[]",droppedFiles[f]);
// adding every file to the form so you could upload multiple files
}
}
// the final ajax call
alert(uploadFormData);
$.ajax({
url : "try.php?size="+s, // use your target
type : "POST",
data : uploadFormData,
cache : false,
contentType : false,
processData : false,
success : function(ret) {
alert(ret);
}
});
return false;
}
Here is my php code :
if(isset($_FILES["files"])) {
for ($i=0;$i<count($_FILES['files']);$i++) {
echo $_FILES['files']['name'][$i];
echo "\n";
}
}
It doesn't work this way. $_FILES is an associative array containing the uploaded files, indexed by the field name. Each entry has exactly five elements: name,tmp_name,size,type and error. Each of these elements is an array containing as many elements as the uploaded files.
So if you count($_FILES['files']), the result will always be 5. But if you count($_FILES['files'][$xyz]) where $xyz is any of the above keys, that will be the number of uploaded files.
So your code would work like this, for example:
if(isset($_FILES["files"]))
{
for ($i=0;$i<count($_FILES['files']['name']);$i++)
{
echo $_FILES['files']['name'][$i];
echo "\n";
}
}
or better yet (for readability, if nothing else):
if(isset($_FILES["files"]))
{
$filenames=$_FILES['files']['name'];
for ($i=0;$i<count($filenames);$i++)
{
echo $filenames[$i];
echo "\n";
}
}

Categories