How to keep track of and display uploaded images after uploading? - php

I made a little page where you can upload picture it is simple php upload. I want everyone to be able to upload images and view everyone else's uploads on the site. How can I display images after they're uploaded? I want to be able to globally track all uploaded images so that everyone can browse them.
I think I need to use "AJAX upload" to do that and maybe javascript to display image after upload... but how?
I tried this:
function GetFileName(){
var fileInput = document.getElementById('fileToUpload');
var fileName = fileInput.value.split(/(\\|\/)/g).pop();
var img = document.createElement('img');
img.src = 'uploads/' + fileName;
img.setAttribute('width', '100px');
img.setAttribute('height', '100px');
img.alt = fileName;
document.body.appendChild(img);
alert(fileName);
}
<form method="post" action="upload.php" enctype="multipart/form-data">
<input type="file" name="fileToUpload" id="fileToUpload" class="upload">
<input type="submit" onclick="GetFileName()" value="Upload Image" name="submit" id="submit">
</form>
This is almost work but the image only display few second and then it disappear.

Try some thing like this in Jquery:
$('#upload').on('click', function() {
var img_name = $('#pic').val();
var file_data = $('#pic').prop('files')[0];
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(output){
if(output) // if success
{
$('#img_container').append('<img src="img_path/"'+ img_name +'>'); // It will display the uploaded image
}
}
});
$('#pic').val(''); /* Clear the file container */
});
Html:
<body>
<input id="pic" type="file" name="pic" />
<button id="upload">Upload</button>
<!-- To display image -->
<div id="img_container">
</div>
</body>

I think the key issue to your question here is in how to keep track of all the uploads. This is likely better solved by relying on a persistence store, like a database, to track of all uploaded files on a global level.
For example, when an upload occurs, you can insert a record into an uploads table in your database like so...
// prepare the statement
$stmt = $db->prepare("INSERT INTO uploads (userId, fileName) VALUES(:userId, :fileName)");
if ($_FILES['upload']['error'] == UPLOAD_ERR_OK) { // no errors
// move the file to a permanent location
$tmpName = $_FILES['upload']['tmp_name'];
move_uploaded_file($tmpName, $uploadDir . "/$tmp_name");
$result = $stmt->execute(
[
'userId' => $_SESSION['userId'], // or however you track the user
'fileName' => $_FILES['upload']['tmp_name'],
]
);
if ($result) {
// record added successfully!
} else {
// failed
}
}
Now you can display all uploaded files by looking at the uploads table in your database and display them to users like so...
// prepare the statement
$start = $_GET['start'] ?? 0;
$stmt = $db->prepare("SELECT userId, fileName FROM uploads LIMIT ?,20");
if ($stmt->execute([$start])) {
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach($result as $row) {
echo "<img src='$uploadDir/{$row['fileName']}'>";
}
}
Or you could show only those uploads made by a specific user by adding a WHERE userId = ? clause to that query, for example.

Related

Form field input isn't received by JSON AJAX script

I am unable to catch the $productid from the form. Not sure what I'm doing wrong. Any ideas?
The selected files do upload, but not to the product folder specified, and nothing about the success is returned to index.php
It's strange but stackoverflow also mentions when trying to post "It looks like your post is mostly code; please add some more details", but I have no more info to add?
Thanks
index.php
<form method='post' action='' enctype="multipart/form-data">
<input type="hidden" id='productid' name="productid" value="<?=$productid?>">
<input type="file" id='files' name="files[]" multiple><br>
<input type="button" id='submitphotos' value='Upload'>
<!-- Preview -->
<div id='successupload'></div>
<div id='preview'></div>
<script>
$(document).ready(function(){
$('#submitphotos').click(function(){
var form_data = new FormData();
// Read selected files
var totalfiles = document.getElementById('files').files.length;
var productid= $("#productid").val();
for (var index = 0; index < totalfiles; index++) {
form_data.append("files[]", document.getElementById('files').files[index]);
}
// AJAX request
$.ajax({
url: 'ajaxfile.php',
type: 'post',
data: form_data,
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
for(var index = 0; index < response.length; index++) {
var src = response[index];
// Add img element in <div id='preview'>
$('#preview').append('<img src="'+src+'" width="400px;">');
}
$('#successupload').append('<h6>Successfully uploaded</h6>back');
files.style.display = "none";
submitphotos.style.display = "none";
}
});
});
});
ajaxfile.php
// Count total files
$countfiles = count($_FILES['files']['name']);
// Get product id
$productid = $_POST['productid'];
//Create request id folder if doesn't exist
if (!file_exists($_SERVER['DOCUMENT_ROOT'].'/images/products/'.$productid.'/')) {
mkdir($_SERVER['DOCUMENT_ROOT'].'/images/products/'.$productid.'/', 0777, true);
}
// Upload directory
$upload_location = $_SERVER['DOCUMENT_ROOT']."/images/products/".$productid."/";
// To store uploaded files path
$files_arr = array();
// Loop all files
for($index = 0;$index < $countfiles;$index++){
if(isset($_FILES['files']['name'][$index]) && $_FILES['files']['name'][$index] != ''){
// File name
$filename = $_FILES['files']['name'][$index];
// Get extension
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
// Valid image extension
$valid_ext = array("png","jpeg","jpg","svg");
// Check extension
if(in_array($ext, $valid_ext)){
// File path
$path = $upload_location.$filename;
// Upload file
if(move_uploaded_file($_FILES['files']['tmp_name'][$index],$path)){
$files_arr[] = $path;
}
}
}
}
echo json_encode($files_arr);
die;
</script>
You haven't passed the productid to the ajax call so just before ajax call add this:
form_data.append('productid', productid);
and your code should work fine.

php dropzone in an HTML form - submit textarea value to separate database table

I have a form that uploads multiple files using dropzone - I have that working, and have the values posting to the database. In the form I have a text area that I want to upload to the same database, but a different table. For reference the images are uploaded to a table called files, which has a column called post_id that will reference the id column in the posts table. Here's the form:
<form action="file_upload.php" method="POST" enctype="multipart/form-data">
<textarea class="form-control border-bottom" name="gallery_text" id="gallery_text" placeholder="Add gallery message..."></textarea>
<div class="dropzone mt-3" id="myDropzone"></div>
<button class="btn btn-primary mt-3" type="submit" name="gallery_submit" id="gallery_submit"> Post Gallery </button>
</form>
Here's the current file upload PHP file:
// Count # of uploaded files in array
$total = count($_FILES['file']['name']);
$filename_arr = [];
// Loop through each file
for ($i = 0; $i < $total; $i++) {
// Get the temp file path
$tmpFilePath = $_FILES['file']['tmp_name'][$i];
// Make sure we have a file path
if ($tmpFilePath != "") {
// Setup our new file path
$newFilePath = "assets/img/posts/" . $_FILES['file']['name'][$i];
// Upload the file into the temp dir
if (move_uploaded_file($tmpFilePath, $newFilePath)) {
$filename_arr[] = $newFilePath;
$images_sql = "INSERT INTO files (file_name, uploaded_on) VALUES(?,NOW())";
$images_stmt = $pdo->prepare($images_sql);
$images_stmt->execute([$newFilePath]);
}
}
}
And for reference here's the dropzone script:
Dropzone.options.myDropzone= {
url: "file_upload.php",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 20,
maxFilesize: 2,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
dictDuplicateFile: "Duplicate Files Cannot Be Uploaded",
preventDuplicates: true,
init: function() {
var myDropzone = this; // Makes sure that 'this' is understood inside the functions below.
// For Dropzone to process the queue (instead of default form behavior):
document.getElementById("gallery_submit").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Send all the form data along with the files:
// this.on("sendingmultiple", function(data, xhr, formData) {
// formData.append("gallery_text", jQuery("#gallery_text").val());
// });
}
}
I thought I could use isset to get the form textarea value and upload that to the appropriate table, then use lastInsertId to upload the images as well as reference the post. Right now I can't seem to get the textarea value to upload to the database at all. Since I'm relatively new at this I'm struggling to understand where I'm going wrong. I get the feeling I'm missing something. Here's one of the ways I've tried.
if (isset($_POST['submit'])) {
$gallery_text = $_POST['gallery_text'];
$userLoggedIn = $user['username'];
$text_sql = "INSERT INTO posts(body, added_by, user_to, date_added, user_closed, deleted, likes, image) VALUES(?,?,'',NOW(),'no','no',0,'')";
$text_stmt = $pdo->prepare($text_sql);
$text_stmt->execute([$gallery_text, $userLoggedIn]);
}
I would be grateful for some guidance on how to get this working.
EDIT:
I separated out the form to just submit "gallery_text" and it worked. When I add dropzone and the image upload process back in it fails silently. Still searching. Here's the form that worked:
if (isset($_POST['gallery_submit'])) {
$gallery_text = $_POST['gallery_text'];
$userLoggedIn = "steve_shead";
$date_added = date("Y-m-d H:i:s");
$text_sql = "INSERT INTO posts(body, added_by, user_to, date_added, user_closed, deleted, likes, image) VALUES(?,?,?,?,?,?,?,?)";
$text_stmt = $con->prepare($text_sql);
$text_stmt->execute([$gallery_text, $userLoggedIn,"", $date_added, "no", "no", 0, ""]);
echo "<h1 class='display-1 mt-5 text-center'>Success!</h1>";
}
After re-reading the documentation I have it working now. The form remains the same. Here's the form handler, file_upload.php:
<?php
require 'inc/header.php';
$gallery_text = $_POST['gallery_text'];
$userLoggedIn = $user['username'];
$date_added = date("Y-m-d H:i:s");
$text_sql = "INSERT INTO posts(body, added_by, user_to, date_added, user_closed, deleted, likes, image) VALUES(?,?,?,?,?,?,?,?)";
$text_stmt = $pdo->prepare($text_sql);
$text_stmt->execute([$gallery_text, $userLoggedIn, "", $date_added, "no", "no", 0, ""]);
$post_id = $pdo->lastInsertId();
// Count # of uploaded files in array
$total = count($_FILES['file']['name']);
$filename_arr = [];
// Loop through each file
for ($i = 0; $i < $total; $i++) {
// Get the temp file path
$tmpFilePath = $_FILES['file']['tmp_name'][$i];
// Make sure we have a file path
if ($tmpFilePath != "") {
// Setup our new file path
$newFilePath = "assets/img/posts/" . $_FILES['file']['name'][$i];
// Upload the file into the temp dir
if (move_uploaded_file($tmpFilePath, $newFilePath)) {
$filename_arr[] = $newFilePath;
$images_sql = "INSERT INTO files (file_name, uploaded_on, post_id) VALUES(?,?,?)";
$images_stmt = $pdo->prepare($images_sql);
$images_stmt->execute([$newFilePath, $date_added, $post_id]);
}
}
}
?>
<?php include 'inc/footer.php'; ?>
The notable difference is the $_POST function is handled by the Dropzone jquery - therefore - you don't need the if(isset($_POST['gallery_text'] function in file_upload.php. Here's that jquery again - note the last two lines - they tell Dropzone to include the data name="gallery_text" id="gallery_text" in the $_POST to file_upload.php.
<script>
Dropzone.options.myDropzone= {
url: "file_upload.php",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
maxFiles: 20,
maxFilesize: 2,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
dictDuplicateFile: "Duplicate Files Cannot Be Uploaded",
preventDuplicates: true,
init: function() {
var myDropzone = this; // Makes sure that 'this' is understood inside the functions below.
// For Dropzone to process the queue (instead of default form behavior):
document.getElementById("gallery_submit").addEventListener("click", function(e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Send all the form data along with the files:
this.on("sendingmultiple", function(data, xhr, formData) {
formData.append("gallery_text", jQuery("#gallery_text").val());
});
}
}
Note also the PDO function lastInsertId() - I assigned the variable $post_id = $pdo->lastInsertId - that way the text is linked to the images uploaded. When creating the images database table I added an INT row called post_id - by using lastInserId it associated the images with a post (hope that makes sense?)
If anyone is having a similar problem I'd be happy to expand on the solution if you think it would help.

move_uploaded_file doesn't move image to permanent folder || PHP

I am building a PHP application where a new user has to upload an avatar.
I managed to save the uploaded file path into my database,
but now I have to move the uploaded image from the temporary to the permanent directory, which is the folder 'avatars'.
I have searched through many answers on the same problem but haven't managed to find a working one. Since I am really new to PHP I'm gonna need some help for a working solution.
I have also tried copy() instead of move_uploaded_file with no luck.
HTML:
<div class="input-form">
<label for="avatar">Kies een profielfoto</label>
<input type="file" id="avatar-input" name="avatar" accept="image/*" onchange="loadFile(event)">
<img id="output" width="150" />
<input type="submit" id="submit-btn" name="vervolledig-submit" value="START">
</div>
PHP:
if(!empty($_POST)){
$fileSize = $_FILES["avatar"]["size"];
if($fileSize < 2000000){
$fileSizeOk = true;
}else{
throw new Exception("Je profielfoto heeft een grotere file size dan is toegelaten (max 2MB)");
$imgSizeOk = false;
}
$img = $_FILES["avatar"]["name"];
if($imgSizeOk == true){
move_uploaded_file($_FILES["avatar"]["tmp_name"], "avatars/$img");
}
}
EDIT: was asked to share my JS code:
a function that shows a preview of the uploaded picture:
let loadFile = function(event) {
let image = document.getElementById('output');
image.src = URL.createObjectURL(event.target.files[0]);
};
Suggested solution with AJAX
$('#submit-btn').on('click', function() {
var file_data = $('#avatar-input').prop('files')[0];
var form_data = new FormData();
form_data.append('avatar', file_data);
alert(form_data);
$.ajax({
url: 'profielVervolledigen.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){
alert(php_script_response); // display response from the PHP script, if any
}
});
});
with the following php code:
if(!empty($_POST)){
if ( 0 < $_FILES['avatar']['error'] ) {
echo 'Error: ' . $_FILES['avatar']['error'] . '<br>';
}
else {
move_uploaded_file($_FILES['avatar']['tmp_name'], 'avatars/' . $_FILES['avatar']['name']);
}
}
the alert gives [object FormData]
Thanks for any help

Not able to upload image via jquery, ajax and PHP

I have fair knowledge of JS, PHP and Ajax but this simple problem has driven me nuts.
I am trying to upload an image silently, without using a form. I am not using a form because that will lead to nested forms in my HTML, which I read, can cause additional issues.
I have been able to use oFReader, to preview the images.
To upload the image, I am attempting an AJAX call as given below:
HTML
<div id="loginButton2">
<div id="personalimg" >
<img src="photos/seller_photos/<?php echo $profile_pic; ?>" width="70" hight="70" />
</div>
</div>
<div id="loginBox2" style="display:none">
<div id="loginForm2" class="floatLeft" >
<fieldset>
<input id="file" type="file" name="profile_img" value="photos/seller_photos/<?php echo $profile_pic;?>"/>
<input id="file_submit" type="hidden" name="submit4" value="1" >
</fieldset>
</div>
</div>
JS
$('#file').change(function(){
var oFReader = new FileReader();
oFReader.readAsDataURL(this.files[0]);
var fd = new FormData();
var file = $("#file").prop("files")[0];
fd.append('profile_img', file);
fd.append('submit4', 1);
fd.append('filename', 1);
oFReader.onload = function (oFREvent) {
$.ajax({
url: "upload.php",
dataType: 'image',
cache: false,
contentType: false,
processData: false,
type: "POST",
data: fd,
success: function(data){
console.log(data);
},
error: function(){
console.log("image upload failed");
}
});
$('#loginForm2').toggle();
$('#personalimg').html('<img src="'+oFREvent.target.result+'" width="70" height="70">');
};
});
PHP
if(isset($_POST['submit4'])) {
$check_sql = "select profile_pic from profile where user_id=$user_id";
$check_rs = mysql_query($check_sql);
$check_num = mysql_num_rows($check_rs);
if($check_num==0) {
$sql = "insert into profile(user_id) values($user_id)";
$rs = mysql_query($sql);
}
$fName = $_FILES["profile_img"]["name"] ;
$data = explode(".", $fName);
$fileName = $user_id.'.'.$data[1];
if($fName!='')$user->update('profile_pic',$fileName);
$fileTmpLoc= $_FILES["profile_img"]["tmp_name"];
//image store path
$pathAndName = "photos/seller_photos/".$fileName;
$moveResult = move_uploaded_file($fileTmpLoc, $pathAndName);
if(move_uploaded_file) {
$response['status'] = '1';
header('Location: edit_profile_new.php');
} else {
$response['status'] = '0';
}
return $response;
}
But somehow, I have not been able to get this to work. I am using chrome. I get 302 Found status code and "image upload failed" in console.
Can someone please help me out?
ps: I know, mysql is deprecated and will migrate to pdo. This code is inherited and hence has old standards.

upload file using ajax like facebook uploading

My problem is, I want to upload a csv file without pressing a submit button and I used ajax for that case. But now, their is something errors appear, and the error said fopen() Filename cannot be empty. But I already get the file value that I want, but the $_FILES[$fie]['tmp_name'] can't read this value. But if I attach the variable in an alert() they display the exact filename. This is my sample codes.
This is the html:
<form id="Form2">
<input type="file" id="fie" />
</form>
this is the javascript:
<script style="text/javascript">
$(function(){
$('#Form2').change(function(e){
e.preventDefault();
var sub = document.getElementById("fie").files[0].name;
if($('#cat1').hasClass('show')){
$('#cat1').hide();
$('#cat2').html("<img src='pb1.gif' />");
$.ajax({
url:'uploading.php',
action:'get',
data: 'fie='+sub,
success: function(data){
$('#cat2').html(data);
}
});
}
});
});
</script>
This is the Php:
uploading.php
<?php
include("conn.php"); //assuming that connected to a database.
if (isset($_GET['fie'])) {
echo "<script>alert('".$_GET['fie']."')</script>";//IN ALERT THEY EXECUTE THE EXACT VALUE OF THE FILE I INPUT
$fie = $_GET['fie'];
$file = $_FILES[$fie]['tmp_name']; //PROBLEM IS THIS. THEY CAN'T READ THE VALUE AND TELL THEIR IS NO FILE.
$handle = fopen($file,'r') or die ('Cannot open file');
fgets($handle);
do {
if (isset($data[0])) {
mysql_query("INSERT INTO tbl_numbers (numbers,cute) VALUES ('".addslashes($data[0])."','".addslashes($data[1])."')");
}
}
while ($data = fgetcsv($handle,1000,",","'"));
echo "Successful Upload~!";
}
?>
Thanks for the reply.

Categories