So I've been developing a plugin for WordPress.
As I already have made an application which uploads files for me, I thought it would be easy but alas, I can't think of what I am doing wrong.
The problem is; my $_FILES['image'] is not set.
Can anyone tell me what is wrong with my code, because I can't find out what it is.
Form
<form action="" method="POST" enctype="multipart/form-data">
<table class="table ws-form-table">
<tbody>
<tr>
<td>
Add Text:
</td>
<td>
<input type="text" id="ws-text">
</td>
<td>
<button type="button" class="btn btn-primary ws-add-text ws-add-button">+</button>
</td>
</tr>
<tr>
<td>
Add Image:
</td>
<td>
<input type="file" name="image"><progress></progress>
</td>
<td>
<button type="button" class="btn btn-primary ws-add-image ws-add-button">+</button>
</td>
</tr>
</tbody>
</table>
<div class="preview-container">
<div class="preview-strict">
<img class="ws-image" src="<?php echo $feat_image; ?>" alt="" style="width: 300px; height: 300px;">
</div>
</div>
</form>
JS
jQuery('.ws-add-image').click(function() {
var formData = new FormData(jQuery('form')[0]);
console.log('Click Initiated');
console.log('Ajax Try...');
jQuery.ajax({
url: '../../wp-content/plugins/my-plugin/my-plugin-handler.php',
type: 'POST',
xhr: function() {
var myXhr = jQuery.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
}
return myXhr;
},
data: formData,
cache: false,
contentType: false,
processData: false,
error: function() {
console.log('Error Initiated');
},
}).done(function() {
alert('dsa');
jQuery('.preview-strict').prepend('<div id="dragHelper" style="display:inline-block; z-index: 999; cursor: move;"><img id="theImg" src="../../wp-content/plugins/my-plugin/images/' + readCookie('image') + '" width="200px" height=200px; /></div>');
jQuery("#dragHelper").draggable({drag: function(){
var offset = jQuery(this).offset();
var xPos = offset.left;
var yPos = offset.top;
jQuery('#posX').text('x: ' + xPos);
jQuery('#posY').text('y: ' + yPos);
}
});
jQuery("#theImg").resizable();
});
alert(readCookie('image'));
console.log('Done!');
});
function progressHandlingFunction(e){
if(e.lengthComputable){
jQuery('progress').attr({value:e.loaded,max:e.total});
}
}
PHP
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
include_once($_SERVER['DOCUMENT_ROOT'].'/test/wp-load.php' );
global $wpdb;
$table_name = $wpdb->prefix . "my-plugin";
if(isset($_FILES['image'])) {
$wty = 'ISSET';
$sql = $wpdb->get_results("SELECT ID FROM " . $table_name . " ORDER BY ID DESC LIMIT 1");
echo $_FILES['image']['name'];
foreach( $wpdb->get_results("SELECT ID FROM " . $table_name . " ORDER BY ID DESC LIMIT 1") as $key => $row) {
$id = $row->ID;
}
$temp = explode(".", $_FILES["image"]["name"]);
$last = $id . round(microtime(true)) . '.' . end($temp);
$errors= array();
$file_name = $_FILES['image']['name'];
$file_size = $_FILES['image']['size'];
$file_tmp = $_FILES['image']['tmp_name'];
$file_type = $_FILES['image']['type'];
$file_ext=strtolower(end(explode('.',$_FILES['image']['name'])));
$ext = end((explode(".", $file_name)));
$expensions= array("jpeg","jpg","png");
if(empty($errors)==true) {
move_uploaded_file($file_tmp, ABSPATH . "test/wp-content/plugins/my-plugin/images/" . $last);
}
else
{
print_r($errors);
}
}
$cookie_name = "image";
$cookie_value = $wty;
$cookie_exp = time() + (86400 * 30);
setcookie($cookie_name, $cookie_value, $cookie_exp, "/");
?>
So this is how it works: Image gets chosen, button gets clicked, click event runs, ajax runs a PHP file. The PHP file (needs to) upload image, creates cookie with image name. Image name gets pulled from cookie, and adds it to the DOM after ajax done.
I've tried to look this up but for some reason I can't find anything but peoples saying that I might be forgetting enctype="multipart/form-data".
So what am I doing wrong?
Keep in mind that this is a WordPress plugin. So it may be something WordPress related. But I don't think so.
I'm still learning so any help with improving the code is appreciated!
This code will work for single or multiple files.
$('.ws-add-image').click(function() {
var data = new FormData();
//Append files infos
jQuery.each($(this)[0].files, function(i, file) {
data.append('file-'+i, file);
});
$.ajax({
url: "my_path",
type: "POST",
data: data,
cache: false,
processData: false,
contentType: false,
context: this,
success: function (msg) {
alert(msg);
}
});
});
Then in your php file you will get file using..
$_FILES['file-0']
$_FILES['file-1']
You are missing following while cooking up your AJAX request:
formData.append('image', $('input[type=file]')[0].files[0]);
Related
im using ajax to post file and text in a form, When I use the file and the text input simultaneously, I get into trouble , this is my form:
<form action="insertbook.php" method="post" id="addBookForm" enctype="multipart/form-data">
<table >
<!-- 1- IMAGE -->
<tr>
<td>Image:</td>
<td>
<input accept="image/gif, image/png, image/jpeg, image/jpg"
type="file" name="img_data" id="img_data">
</td>
</tr>
<!-- 2- NAME-->
<tr>
<td>Book Name: </td>
<td >
<input type="text" name="title" id="title">
</td>
</tr>
<!-- 3- CATEGORY -->
<tr>
<td>Book Cat: </td>
<td>
<select id="cat_dropdown" onchange="selectionCatchange()">
<?php for ($i=0; $i< sizeof($cats); $i++ ) {
echo '<option value="'.$cats[$i]['id'].'" >'. $cats[$i]['cat_name'] .'</option>';
} ?>
</select>
<?php echo
'<input id="cat_id" name="cat_id" value="'. $cats[0]['id'] .'" type="hidden">' ;
?>
</td>
</tr>
<!-- SUBMIT -->
<tr>
<th colspan="2" >
<input id="insertbook" type="submit" name="submit" >
</th>
</tr>
</table>
</form>
In Javascript codes, We have:
$("#addBookForm").submit(function(e) {
/* Stop form from submitting normally */
e.preventDefault();
/* Get some values from elements on the page: */
var title = document.getElementById('title').value;
var img_data = $('#img_data').prop('files')[0];
var cat_id = document.getElementById('cat_id').value;
var submit = "submit";
$.ajax({
url: "insertbook.php",
type: "POST",
data: {'title':title,
'img_data':img_data,
'cat_id':cat_id,
'submit':submit
},
dataType:'html',
success: function(data){
console.log(data);
},
error:function(data){
alert(data);
}
});
});
But in PHP Code, following this:
<?php
$conn = mysqli_connect(****);
mysqli_set_charset($conn,"utf8");
if(
isset($_POST['title']) &&
isset($_POST['cat_id']) &&
isset($_POST['submit'])
&&
isset($_FILES['img_data'])
){
$title = $_POST['title'];
$cat_id = $_POST['cat_id'];
// THIS SECTION RELATE TO IMAGE UPLOAD
$name_img = basename($_FILES['img_data']['name']);
$type_img = strtolower($_FILES['img_data']['type']);
$data_img = file_get_contents($_FILES['img_data']['tmp_name']);
$uploadOk = 1;
// Check file size
if ($_FILES["img_data"]["size"] > 2097152) {
echo "Sorry, your file is too large > 2 Mb!";
$uploadOk = 0;
}
if ($uploadOk == 0) {
echo "Sorry, your image file was not uploaded.";
// if everything is ok, try to upload file
} else {
if (mysqli_query( $conn,"INSERT INTO `books`( `title`, `img`, `cat_id`, `created_at`) VALUES ('$title','".addslashes($data_img)."', '$cat_id', NOW())" )) {
echo "New record created successfully";
} else {
echo "Error: " . "<br>" . mysqli_error($conn);
}
}}else{echo "Please set all information...!!! ";}
?>
But in the end I get the following error every time:
Notice: Undefined index: img_data in \insertbook.php on line 6
Notice: Undefined index: img_data in \insertbook.php on line 22
Notice: Undefined index: img_data in *\insertbook.php on line 23
Notice: Undefined index: img_data in ***insertbook.php on line 24
Warning: file_get_contents(): Filename cannot be empty in *\insertbook.php on line 24
Notice: Undefined index: img_data in ***\insertbook.php on line 34New record created successfully
But in the end there is no file stored in the database and only one empty record is created, hopefully you can help guide me through the problem.
Thanks
You should try this
Remove action method and enctype attributes from from tag element.
Try with sending data using new FormData() in ajax.
$("#addBookForm").on('submit', function (e) {
e.preventDefault();
var formData = new FormData(this);
formData.append('submit', 'submit');
$.ajax({
type: 'POST',
url: 'insertbook.php',
data: formData,
contentType: false,
cache: false,
processData: false,
success: function (data) {
console.log(data);
},
error: function (jqXHR, textStatus, errorThrown) {
alert("Some problem occurred, please try again.");
}
});
});
To check a file input if it is set or not is this.
Change this art in your if condition
isset($_FILES['img_data'])
To this
isset($_FILES['img_data']['name'])
Hi I have a modal to upload multiple images as shown below and would like to upload the images and return back the error message or a successful message. The problem is I cannot seem to process all images.I have created a formdata in the javascript where I am appending all files but from the php I seem not to be able to handle all of them. Any idea why?
<!-- Modal -->
<div class="modal fade" id="uploadImages" role="dialog">
<div class="modal-dialog modal-lg">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Upload Scanned Images</h4>
</div>
<div class="modal-body" id="body">
<form method="POST" enctype="multipart/form-data">
Select file : <input type='file' name='file[]' id='file' class='form-control' multiple=""><br>
<input type='submit' class="btn btn-info" value="Upload File" id='but_upload' name='submit'>
</form>
<script src="uploadImages.js"></script>
</div>
<div class="modal-footer">
<p>Only jpeg, png, bmp and tiff Images are allowed to be uploaded</p>
</div>
</div>
</div>
</div>
I also have a javascript to send an ajax post:
$(document).ready(function () {
$("#but_upload").click(function () {
var filedata = $('#file')[0];
var formdata = false;
if (window.FormData) {
formdata = new FormData();
}
var i = 0,
len = filedata.files.length,
img, reader, file;
for (i = 0; i < len; i++) {
file = filedata.files[i];
if (formdata) {
formdata.append("file", file);
}
}
$.ajax({
url: 'uploadImages3.php',
type: 'post',
data: formdata,
contentType: false,
processData: false,
success: function (response) {
alert(response);
},
});
});
});
and this is my php file
<?php
/* Getting file name */
$filename = $_FILES['file']['name'];
/* Location */
$location = "SavedImages/" . $filename;
$uploadOk = "No Errors";
$imageFileType = pathinfo($location, PATHINFO_EXTENSION);
$extensions = ['jpg', 'jpeg', 'png', 'gif', 'tiff'];
$all_files = count($_FILES['file']['name']);
for ($i = 0; $i < $all_files; $i++) {
$file_name = $_FILES['file']['name'][$i];
$file_tmp = $_FILES['file']['tmp_name'][$i];
$file_type = $_FILES['file']['type'][$i];
$file_size = $_FILES['file']['size'][$i];
$file_ext = strtolower(end(explode('.', $_FILES['file']['name'][$i])));
$file = $path . $file_name;
if (!in_array($file_ext, $extensions)) {
$uploadOk = $uploadOk . 'Extension not allowed: ' . $file_name . ' ' . $file_type;
}
if ($file_size > 2097152) {
$uploadOk = $uploadOk . 'File size exceeds limit: ' . $file_name . ' ' . $file_type;
}
if (file_exists($file)) {
$uploadOk = $uploadOk . 'File already exists: ' . $file_name . ' ' . $file_type;
}
if ($uploadOk != "No Errors") {
echo $uploadOk;
} else {
/* Upload file */
if (move_uploaded_file($_FILES['file']['tmp_name'], $location)) {
echo "File saved";
} else {
echo $uploadOk;
}
}
}
You have:
formdata.append("file", file);
When working with PHP, if you have multiple form fields with the same name, that name must end in [] or only one of them will be available.
Looping over the files manually in the JS is pointlessly overcomplicated though.
Bind the event handler to the submit event of the form
Use the form to populate the FormData object
You also need to prevent the default behaviour - at the moment you are running your JS when the submit button is clicked, but the normal form submission is going to continue and load a new page (killing the JS program as it goes).
Such:
$("form").on("submit", function(e) {
e.preventDefault();
var formdata = new FormData(this);
$.ajax({
url: 'uploadImages3.php',
type: 'post',
data: formdata,
contentType: false,
processData: false,
success: function(response) {
alert(response);
},
});
});
Then your PHP will have an array of files, each of which will have name, etc. It won't have a file, containing an array of names etc.
$_FILES['file']['name'][$i]; should be $_FILES['file'][$i]['name']; and your count method is wrong too.
It's easier to work with a foreach loop though:
foreach ($_FILES['file'] as $file) {
$file_name = $file['name'];
# etc
}
Im looking for help here. Cant figure it out where is problem here. Im trying to make multiple file upload to database using Ajax and PHP. I am getting this error:
Warning: file_get_contents(iamge.png): failed to open stream: No such
file or directory in /var/www/html/includes/forms/addProductSteps/BTR/upload.php on line 12
Can you please check code below:
index.php:
<form id="fourthStepForm" class="" action="" method="post" enctype="multipart/form-data">
<input type="file" multiple id="imagesToUpload" name="files[]" value="">
<div class="col-xs-3 col-md-3"><input type="submit" onclick="fourthStep();return false" name="submit" value="Finalize" class="btn btn-primary btn-block btn-md" tabindex="5"></div>
</form>
function fourthStep(){
var formData = new FormData();
var ins = document.getElementById('imagesToUpload').files.length;
for (var x = 0; x < ins; x++) {
formData.append("files[]",
document.getElementById('imagesToUpload').files[x]);
}
$.ajax({
url: 'includes/forms/addProductSteps/BTR/upload.php',
dataType: 'text',
cache: false,
contentType: false,
processData: false,
data: formData,
type: 'post',
success: function (response) {
alert(response);
},
error: function (response) {
alert(response);
}
});
}
upload.php:
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
include_once'../../../connections_multi.php';
$p_id = 1001; //for testing purpose
$no_files = count($_FILES["files"]['name']);
for ($i = 0; $i < $no_files; $i++) {
if ($_FILES["files"]["error"][$i] > 0) {
echo "Error: " . $_FILES["files"]["error"][$i] . "<br>";
} else {
$file = addslashes(file_get_contents($_FILES["files"]["name"][$i]));
if (!($stmt = $db->prepare("INSERT INTO products.battery_lobs ( p_id,img) VALUES (?,?)"))) {
$response = $stmt->error;
}
if (!$stmt->bind_param("sb", $p_id, $file )) {
$response = $stmt->error;
}
if (!$stmt->execute()) {
$response = $stmt->error;
}else{
$response = "true";
}
}
}
echo $response;
and $response i get here is "true". So data is inserted but BLOB is 0 bytes. No image.
Thanks!
Problem is in your upload.php file.
This line:
$file = addslashes(file_get_contents($_FILES["files"]["name"][$i]));
You need change it like this:
$file = addslashes(file_get_contents($_FILES["files"]["tmp_name"][$i]));
Then you upload file, file is saved in temporary directory and using random name, you can get it used $_FILES["files"]["tmp_name"].
This question already has answers here:
How can I upload files asynchronously with jQuery?
(34 answers)
Closed 6 years ago.
I have tried to convert my php code using php to javascript ajax. Could you please correct me what supposed to gone wrong since my php code is still activate.
html code:
<form method="post" enctype="multipart/form-data" action="testadd.php">
<input type="file" name="image" id="image">
<br/>
<input type="submit" name="submit" value="upload" id="submit">
</form>
php:
<?php
if(isset($_POST['submit'])){
if(getimagesize($_FILES['image']['tmp_name']) == false){
echo "Please select an image";
echo "<br/>";
}else{
$image = addslashes($_FILES['image']['tmp_name']);
$name = addslashes($_FILES['image']['name']);
$image = file_get_contents($image);
$image = base64_encode($image);
saveImage($name, $image);
}
}
displayImage();
function saveImage($name, $image){
$con = new PDO("mysql:host=localhost; dbname=testimages", "root", "");
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $con->query("INSERT INTO images(id, name, image) VALUES(38836929, '$name', '$image') ON DUPLICATE KEY UPDATE image='$image', name='$name'");
$stmt->execute();
}
function displayImage(){
$con = new PDO("mysql:host=localhost; dbname=testimages", "root", "");
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $con->query("SELECT * FROM images");
$stmt->execute();
while($result = $stmt->fetch(PDO::FETCH_OBJ)){
echo '<img height="24" width="24" src="data:image;base64,' . $result->image . '">';
echo '<br/>';
echo $result->name . ' ';
}
}
?>
javascript:
$(document).ready(function(){
$("#submit").click(function(){
var image = document.getElementById("image").value;
alert(" " + image);
if(image == ""){
alert("please select image");
}else{
$.ajax({
type: "POST",
url: "testadd.php",
data: "image=" + image,
success: function(data){
if(data == success){
alert("test");
}else{
alert("fail");
}
}
});
}
return false;
});
});
Could you please check what supposed to be the problem in order to be fixed.
AJAX must have content Type , ProcessData to upload the image files
$.ajax({
url: 'Your url here',
data: formData,
type: 'POST',
// THIS MUST BE DONE FOR FILE UPLOADING
contentType: false,
processData: false,
// ... Other options like success and etc
success : function(data){
//Do stuff for ahed process....
}
});
I'm using Twitter Modal Bootstrap for my Web Application. In one of the feature of the app is to display a table with corresponding information (I used mysql_query to populate the information). For each row of the table, there is a "View" button. Clicking that View Button will open a "Modal" pop-up which includes a form inside. As you can see, I'm trying to upload a file using AJAX. This is successfully done when I try to do it on the first row. But when I try to do it on the following row, I can't upload the file as if there's no form in it.
Table:
<table border = '1' width = "30%">
<tr>
<th>Asset Picture</th>
<th>Asset Name</th>
<th>Action</th>
</tr>
<?php
$data=mysql_query("SELECT * FROM assets") or die("No records found.".mysql_error());
while($row = mysql_fetch_array($data))
{
echo "<tr>
<td><img src = '$row[asset_Picture]' width = '100%'></td>
<td>$row[asset_Name]></td>
<td><button data-toggle='modal' id = 'buttonView' style = '$row[asset_ID]' data-target='#myModalEdit-$row['asset_ID']' type='button' class='btn btn-link'>View</button></td>
</tr>";
echo "<div class='modal fade' id='myModalEdit-$row['asset_ID']' tabindex='-1' role='dialog' aria-labelledby='myModalLabel' aria-hidden='true'>"; ?>
<div class='modal-dialog'>
<div class='modal-content'>
<div class='modal-header'>
<button type='button' class='close' data-dismiss='modal' aria-hidden='true'>×</button>
<h4 class='modal-title' id='myModalLabel'><b>Testing</b></h4>
</div>
<div class='modal-body'>
<?php
echo "<form style = '$row[asset_ID]' id='uploadForm-$row[asset_ID]' action = 'upload.php' method = 'POST'>
<center><img value = '$row[asset_Picture]' id = asset_Picture-$row[asset_ID]' class = 'img-thumbnail' src = '$row[asset_Picture]' width = '60%'></center><br><br>
<b class = 'text-danger'>Change Asset Picture?</b><br><br>
<input class = 'form-controlModal' type = 'file' name = 'userImage' id = 'file-$row[asset_ID]' accept='image/x-png, image/gif, image/jpeg, image/pjpeg, image/jpg, image/png' style = 'width:460px;'>
<input type='submit' id = 'uploadPicture' style = '$row[asset_ID]' class='btn btn-primary' value = 'Upload'>
</form>";
?>
</div>
<div align = 'left' class='modal-footer'>
<button type='button' class='btn btn-warning' data-dismiss='modal'>Close</button>
</div>
</div>
</div>
</div>
<?php
}
?>
</table>
Javascript:
$('#uploadPicture').click( function(e) {
var edit_id = $(this).attr("style");
$.ajax({
url: "upload.php",
type: "POST",
data: new FormData($("form#uploadForm-"+edit_id)[0]),
contentType: false,
cache: false,
processData:false,
success: function(data)
{
alert("success!");
},
error: function()
{
}
});
e.preventDefault();
});
upload.php
<?php
if(is_array($_FILES)) {
if(is_uploaded_file($_FILES['userImage']['tmp_name'])) {
$sourcePath = $_FILES['userImage']['tmp_name'];
$targetPath = "upload/".$_FILES['userImage']['name'];
if(move_uploaded_file($sourcePath,$targetPath)) {
echo $targetPath;
}
}
}
?>
Thanks in advance! :)
Instead of using 'id' use 'class'. Using 'id' the binding is only working for the first element. The even is only being binded to the first ID that's hitting that. Instead use
<input type='submit' style = '$row[asset_ID]' class='uploadPicture btn btn-primary' value = 'Upload'>
Now modify the script like this
$('.uploadPicture').click( function(e) { // <-- starting with '.' means for all objects of this class
var edit_id = $(this).attr("style");
$.ajax({
url: "upload.php",
type: "POST",
data: new FormData($("form#uploadForm-"+edit_id)[0]),
contentType: false,
cache: false,
processData:false,
success: function(data)
{
alert("success!");
},
error: function()
{
}
});
e.preventDefault();
});
That should do the trick.
And if you want to take my advice then I'd say using an ID in 'style' attribute is really bad idea. I'd say use it like this
<input type='submit' id = '$row[asset_ID]' class='uploadPicture btn btn-primary' value = 'Upload'>
And identify it in the script like
$('.uploadPicture').click( function(e) {
var edit_id = $(this).attr("id"); // <------ pick from id
$.ajax({
url: "upload.php",
type: "POST",
data: new FormData($("form#uploadForm-"+edit_id)[0]),
contentType: false,
cache: false,
processData:false,
success: function(data)
{
alert("success!");
},
error: function()
{
}
});
e.preventDefault();
});
Instead of using $('#uploadPicture').click( function(e) { ...
use $('#uploadPicture').on('click', function(e) {...