How to upload image using ajax and zend? - ajax

Thank you for the consideration, I'm sorry for my non-informative question.
Actually I am using ajax and zend for uploading a file.
My ajax code looks like this:
$.ajax({
type: "POST",
url: "/business_general/imagesave",
enctype: 'multipart/form-data',
data: {'file': files.getAsBinary(), 'fname' : file.fileName},
success: function(arrReturn){
alert( "Data Uploaded: ");
}
});
Here, I called a controller action(imagesave) to save my image in database
My Controller file action looks like this:
$config = Zend_Registry::get('config');
$vehiclelogo = $config->paths->vehiclelogo;
$file = $objRequest->getParam('file');
$ret = $objRequest->getParam('fname');
$path_parts = pathinfo($ret);
echo $path_parts['extension'], "\n";
echo $path_parts['filename'], "\n";
$targetPath = mktime(date("H"), date("i"), date("s"), date("m"), date("d"), date("Y"));
try {
echo "POSTED FILE NAME"." ". $ret;
echo "TYPE OF FILE UPLOADED"." "."-". gettype($ret);
$strFilePath = $vehiclelogo.'/'.$targetPath.'.'.$path_parts['extension'];
$OPfile = fopen($strFilePath,"w");
fwrite($OPfile,$file);
fclose($OPfile);
echo "completed";
}
catch (Exception $e) {
echo "error";
}
Here, I am uploading the selected image into a folder.Acually, I am able to upload text files. But if I upload png/jpeg files,it gets uploaded into the folder, But the fact is that it could not be opened.
I should be able to able to upload every type of files.
How to execute this in zend-php and ajax?

Sorry .I think getAsBinary() doesn't support in modern browsers.you can use an invisible canvas for uploding files using ajax.
Example
var canvas = document.getElementById("canvas")
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0);
var strdata = canvas.toDataURL("image/png");
document.getElementById("company_logo").src=strdata;
$.ajax({
type: "POST",
url: "/business_vehicle/vehiclegeneralsave",
data: "&data="+strdata,
success: function(arrResult) {
//do something
}
});
In controller side you can recive the image ` public function vehiclegeneralsaveAction() {
$file = $arrVehicleDetails = trim($objRequest->getParam('data'));
$strEncodedData = str_replace(' ', '+', $file);
$strFilteredData = explode(',', $strEncodedData);
$strUnencoded = base64_decode($strFilteredData[1]);
file_put_contents('../public/image/image.png', $strUnencoded);
}`

Related

How to programatically update dropzone preview filename after using fileRename option

I have a DropZone script (as below) that renames the uploaded image into a unique folder with a unique timestamp to avoid duplicates. When I add the file, it creates the unique directory (session_id) and uploads and renames the image correctly, however, the DropZone preview image still shows the original filename so the remove links do not work. If I refresh the page, the thumbnails are labelled correctly with the new filename and the remove links work. How can I update the script to do this after the initial upload/rename?
Dropzone.autoDiscover = false;
$(".dropzone").dropzone({
url: "upload.php",
addRemoveLinks: true,
maxFiles: 5,
acceptedFiles: "image/*",
// Check for previously uploaded images and display in the dropzone
init: function() {
myDropzone = this;
$.ajax({
url: 'upload.php',
type: 'post',
data: {request: 2},
dataType: 'json',
success: function(response) {
$.each(response, function(key,value){
var mockFile = { name: value.name, size: value.size };
myDropzone.emit("addedfile", mockFile);
myDropzone.emit("thumbnail", mockFile, value.path);
myDropzone.emit("complete", mockFile);
});
}
});
},
// Rename uploaded files to unique name
renameFile: function (file) {
let newName = new Date().getTime() + '_' + file.name;
return newName;
},
// Remove the uploaded file if the "Remove file" link is pressed
removedfile: function(file) {
var name = file.name;
$.ajax({
type: 'post',
url: 'delete.php',
data: "id="+name,
dataType: 'html'
});
var _ref;
return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
},
});
This is the upload.php file:
<?php
include $_SERVER['DOCUMENT_ROOT'] . '/inc/config.inc.php';
$upload_folder = "uploads/".session_id();
if(!file_exists($upload_folder)) {
mkdir($upload_folder);
}
$target_dir = $upload_folder."/";
$request = 1;
if(isset($_POST['request'])){
$request = $_POST['request'];
}
// Upload file
if($request == 1){
$target_file = $target_dir . basename($_FILES["file"]["name"]);
if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) {
echo $target_file;
}else{
echo 0;
}
die;
}
// Read files from
if($request == 2){
$file_list = array();
// Target directory
$dir = $target_dir;
if (is_dir($dir)){
if ($dh = opendir($dir)){
// Read files
while (($file = readdir($dh)) !== false){
if($file != '' && $file != '.' && $file != '..'){
// File path
$file_path = $target_dir.$file;
// Check its not folder
if(!is_dir($file_path)){
$size = filesize($file_path);
$file_list[] = array('name'=>$file,'size'=>$size,'path'=>$file_path);
}
}
}
closedir($dh);
}
}
echo json_encode($file_list);
exit;
}
?>
This is the delete.php file:
<?php
include $_SERVER['DOCUMENT_ROOT'] . '/inc/config.inc.php';
$upload_folder = "uploads/".session_id();
$target_dir = $upload_folder."/";
if(isset($_POST['id'])){
$filename = $_POST['id'];
}
// Delete file
$target_file = $target_dir . $filename;
if (unlink($target_file)) {
echo $target_file;
}else{
echo 0;
}
die;
?>
(NOTE: session_start() is called in the included config file)
Feel free to let me know if there are any other bad ideas in here! :)
Ben
So the answer for this has been solved! For reference the following is the fixes applied.
renameFile: and removedfile: have both been updated as per the comments below.
The changes in the renameFile: section make the newly generated filename available to be referenced later when using the removedfile: Ajax call to delete.php
The init: > success: has been updated changing the mockFile variable.
This ensures that removefile: still works correctly on a page reload (e.g. is there was a form POST and an error needed to be corrected) where the images are now read directly from the folder location.
Full code update:
Dropzone.autoDiscover = false;
$(".dropzone").dropzone({
url: "upload.php",
dictDefaultMessage: "", // remove default text
addRemoveLinks: true,
maxFiles: 5,
acceptedFiles: "image/*",
// Check for previously uploaded images and display in the dropzone
init: function() {
myDropzone = this;
$.ajax({
url: 'upload.php',
type: 'post',
data: {request: 2},
dataType: 'json',
success: function(response) {
$.each(response, function(key,value){
var mockFile = {
newName: value.name,
name: value.name.substr(value.name.indexOf('_') + 1),
size: value.size
};
myDropzone.emit("addedfile", mockFile);
myDropzone.emit("thumbnail", mockFile, value.path);
myDropzone.emit("complete", mockFile);
});
}
});
},
// Rename uploaded files to unique name
renameFile: function (file) {
let newName = new Date().getTime() + '_' + file.name;
// Add new name to the file object:
file.newName = newName;
// As an object is handed over by reference it will persist
return newName;
},
// Remove the uploaded file if the "Remove file" link is pressed
removedfile: function(file) {
// Get new name from file object:
var newName = file.newName;
$.ajax({
type: 'post',
url: 'delete.php',
data: "id="+newName,
dataType: 'html'
});
var _ref;
return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
},
});
Thanks to the user "Sempervivum" on webdeveloper.com for the fix.

convert .heic image to jpg image format in laravel

I have added intervention/image package to convert image format in laravel.
image converted successfully but after uploading image quality was so bad.
Original Image
Uploaded Image
$img =(string) Image::make($image['base64'])
->resize(500, 500)->encode('jpg',100);;
$img = base64_encode($img);
To convert Heic image you have to use imagick, can you use this instead
This is how to install https://ourcodeworld.com/articles/read/645/how-to-install-imagick-for-php-7-in-ubuntu-16-04
try {
$image = new \Imagick();
$image->readImageBlob($image['base64']));
$image->setImageFormat("jpeg");
$image->setImageCompressionQuality(100);
$image->writeImage($targetdir.$uid.".jpg");
}
catch (\ImagickException $ex) {
/**#var \Exception $ex */
return new JSONResponse(["error" => "Imagick failed to convert the images, check if you fulfill all requirements." , "details" => $ex->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR);
}
A bit late, but I had the same problem.
I managed to do it with the heic2any js library (https://github.com/alexcorvi/heic2any/blob/master/docs/getting-started.md)
I converted the picture on client side, then gave it to the input in client side.
Server is seeing it as it was originally uploaded as jpg.
function convertHeicToJpg(input)
{
var fileName = $(input).val();
var fileNameExt = fileName.substr(fileName.lastIndexOf('.') + 1);
if(fileNameExt == "heic") {
var blob = $(input)[0].files[0]; //ev.target.files[0];
heic2any({
blob: blob,
toType: "image/jpg",
})
.then(function (resultBlob) {
var url = URL.createObjectURL(resultBlob);
$(input).parent().find(".upload-file").css("background-image", "url("+url+")"); //previewing the uploaded picture
//adding converted picture to the original <input type="file">
let fileInputElement = $(input)[0];
let container = new DataTransfer();
let file = new File([resultBlob], "heic"+".jpg",{type:"image/jpeg", lastModified:new Date().getTime()});
container.items.add(file);
fileInputElement.files = container.files;
console.log("added");
})
.catch(function (x) {
console.log(x.code);
console.log(x.message);
});
}
}
$("#input").change(function() {
convertHeicToJpg(this);
});
What I am doing is converting the heic picture to jpg, then previewing it.
After that I add it to the original input. Server side will consider it as an uploaded jpg.
Some delay can appear while converting, therefore I placed a loader gif while uploading.
The heic2any js library helped me accomplish this (https://github.com/alexcorvi/heic2any/blob/master/docs/getting-started.md)
On the client side, I converted the picture, then gave it to the server input. The server sees it as it was originally uploaded as PNG.
$('#files').on('change' , function(){
var total_file=document.getElementById("files").files.length;
for(var i=0;i<total_file;i++)
{
files = event.target.files[i];
var fileName = files.name;
var fileNameExt = fileName.substr(fileName.lastIndexOf('.') + 1);
objURL = URL.createObjectURL(event.target.files[i]);
if(fileNameExt == "heic") {
objURL = await convertHeicToJpg(input , i);
}
})
async function convertHeicToJpg(input , i)
{
var blobfile = $(input)[0].files[i]; //ev.target.files[0];
let blobURL = URL.createObjectURL(blobfile);
// convert "fetch" the new blob url
let blobRes = await fetch(blobURL)
// convert response to blob
let blob = await blobRes.blob()
// convert to PNG - response is blob
let resultBlob = await heic2any({ blob })
console.log(resultBlob)
var url = URL.createObjectURL(resultBlob);
let fileInputElement = $(input)[0];
let container = new DataTransfer();
let file = new File([resultBlob], "heic"+".png",{type:"image/png", lastModified:new Date().getTime()});
container.items.add(file);
fileInputElement.files[0] = container.files;
uploadFile(container.files);
console.log("added");
console.log(url);
return url ;
}
function uploadFile(files)
{
console.log(files);
var error = '';
var form_data = new FormData();
for(var count = 0; count<files.length; count++)
{
var name = files[count].name;
var extension = name.split('.').pop().toLowerCase();
form_data.append("files[]", files[count]);
}
$.ajax({
url:"<?php echo base_url(); ?>Property/upload",
method:"POST",
data:form_data,
contentType:false,
cache:false,
processData:false,
dataType:'JSON',
beforeSend:function(){
//..processing
},
success:function(data)
{
alert('image uploade')
}
})
}

Ajax returned title value for tooltip isn't in one line, in Bootstrap

I am having a weird bug with dynamic created tooltips using ajax. I am creating a simple notes function. When data is coming from the database everything looks nice
But when i am creating a new note, using ajax i am creating the new entry in the db and then return the value to be shown in the new tooltip...But this is how it comes out to the user.
Is there a way to 'force' it to one line like the 1st image ?
Here is the code in question:
.js part
$('[data-toggle="tooltip"]').tooltip({
placement : 'left'
});
////////
var inText = $('.evnt-input').val(); //Whatever the user typed
$.ajax({
type: 'POST',
url: 'request.php',
data: {action:'addnotes', data: inText},
dataType: 'json',
success: function(s){
if(s.status == 'success'){
$('<li id="'+s.id+'">' + inText + ' ✕ </li>').appendTo('.event-list');
}
},
error: function(e)
{
console.log('error');
}
});
.php part
if ($_POST["action"] == "addnotes"){
function addnotes($data)
{
$insert = db_query("insert into notes(description) values('$data')");
if($insert)
return db_inserted_id();
}
$data = $_POST['data'];
$status = addnotes($data);
if($status != ''){
$timestamp = strtotime(date('Y-m-d G:i:s'));
$curTime = date( 'F j, Y, g:i a', $timestamp );
$output = array('status'=>'success','id'=>$status, 'curTime'=>$curTime);
}
else
$output = array('status'=>'error');
echo json_encode($output);
}
I have an identical code with the .js part to show the notes when the page loads...of course that works fine.
Lol it was so easy.... I changed the .js part to this, to 'reinitialize' the tooptip:
if(s.status == 'success'){
var curTime = s.curTime;
$('<li id="'+s.id+'">' + inText + ' ✕ </li>').appendTo('.event-list');
$('[data-toggle="tooltip"]').tooltip({
placement : 'left'
});
}

base64 image post to php results in empty file

My question is very similar to one at this thread. I'm creating a canvas element on the fly, adding one or more img elements to it, and posting each img in turn to a php script on the server that then saves the resulting file. It's a basic drag-and-drop operation for images, much like Facebook's or the one on G+. I have everything working correctly except that the files resulting from the upload and save are all empty-- or rather, they're 2kb each and display nothing but blackness.
Here's the relevant portions of the code:
HTML:
<form method="post" action="upload.php" id="formUpload">
<div id="op">
<label class="lbl">Drop images here to add them,<br>or click an image to see it enlarged</label>
<span style='display:inline-block'>
<input type="file" name="files[]" id='file' class="fileUpload" onchange="startRead()" multiple><br>
<input type='submit' name='submit' value='+' class="fileUpload">
</span>
</div>
</form>
(not bothering with CSS as it's not germane to this)
javascript/jquery:
function addImg(imgSrc) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 5, 5);
};
imageObj.className = "imgThumbnail";
imageObj.style.width = 140 + "px";
imageObj.style.height = 140 + "px";
imageObj.src = imgSrc.currentTarget.result;
var dataURL = canvas.toDataURL();
$.ajax({
type: "POST",
url: "upload.php",
data: {
imgBase64: dataURL
}
}).done(function(data) {
var fileName = data;
if (fileName.substring(1,1) !== "!") {
document.getElementById('op').insertBefore(imageObj);
$("#op").on('click', 'img', imgEnlarge);
$.get($("#path").val() + "/includes/addImage.php", {
imageType: $("#imageType").val(),
idParentObject: $("#idParentObject").val(),
url: fileName
});
} else {
alert("Error in upload processs. Could not save " + data.substring(2, data.length-1) + ".");
imageObj.attr("src", "../images/missing.png");
}
});
}
PHP:
define('UPLOAD_DIR', '../images/');
$img = $_POST["img"];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.png';
$success = file_put_contents($file,$data);
print $success ? $file : '!$file';
Any help figuring out what I'm missing will be greatly appreciated. Correct answers will be even more appreciated.
Got it. It was an order of operations error. I was posting the canvas's base64 representation prior to drawing the image onto it. Here's what the javascript looks like corrected:
function addImg(imgSrc) {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.className = "imgThumbnail";
imageObj.style.width = 140 + "px";
imageObj.style.height = 140 + "px";
imageObj.src = imgSrc.currentTarget.result;
context.drawImage(imageObj, 0, 0, 140, 140);
var dataURL = canvas.toDataURL('image/png');
$.ajax({
type: "POST",
url: $("#path").val() + "/includes/upload.php",
data: {
img: dataURL
}
}).done(function(data) {
var fileName = data;
if (fileName.substring(1,1) !== "!") {
document.getElementById('op').insertBefore(imageObj);
$("#op").on('click', 'img', imgEnlarge);
$.get($("#path").val() + "/includes/addImage.php", {
imageType: $("#imageType").val(),
idParentObject: $("#idParentObject").val(),
url: fileName
});
$("#testOutput").val(data);
$("#testOutput").show();
} else {
alert("Error in upload processs. Could not save " + data.substring(2, data.length-1) + ".");
imageObj.attr("src", "../images/missing.png");
}
});
}

Return array from php to ajax success

I want to return an array from a php function to my ajax call. After that I want to use the array values from the page the ajax call is made.
So this is my ajax call:
$(function() {
$("#find").click(function() {
var url = $("#form_url").val();
var dataString = 'url=' + url;
$.ajax({
type: "POST",
url: "/ajax/add_url.php",
data: dataString,
}).done(function( result ) {
myresult(result);
});
return false;
});
});
function myresult(result) {
var result_lines = result.split("<splitter>");
if (result_lines[0] == '1') {
$('#content_error').html(result_lines[1]).fadeIn(250);
$('#content_error').delay(1500).fadeOut(500);
} else if (result_lines[0] == '2') {
$('#content_success').html('Succesfully get images').fadeIn(250);
$('#url_result').delay(500).fadeIn(500);
$('#content_success').delay(1500).fadeOut(500);
alert(eval(data));
}
return true;
}
and this is my php script:
if($_POST['url']) {
$url = $Db->escape($_POST['url']);
$html = file_get_html($url);
$count = 0;
$goodfiles = array();
foreach($html->find('img') as $element) {
$pic = url_to_absolute($url, $element->src);
if(!empty($pic)){
$pics = parse_url($pic);
list($width, $height, $type, $attr) = getimagesize($pic);
if($pics["scheme"]=="http" && $width >= 300 && $height >= 250) {
array_push($goodfiles,$pic);
$_SESSION['pictures'] = $goodfiles;
$count++;
}
}
}
if($count == 0){
$_SESSION['count'] = 'empty';
echo "1<splitter>";
echo "No items found with the correct size";
}else{
$_SESSION['count'] = $count;
echo "2<splitter>";
echo json_encode($_SESSION['pictures']);
}
$_SESSION['url'] = $url;
$html->clear();
$empty = 1;
}
}
when the ajax call is successful I use json_encode on the array to use it on my php page. But I don't know how I get this array to a javascript on the page the ajax call was made of.
right now I'm receiving the following content:
["image.jpeg","image.jpg"]
And I want to put this in a javascript array...
The error is this with this line:
var result_lines = result.split("<splitter>");
result (the AJAX response) is an object or array (depending on the nature of your JSON) but you are trying to call a string method (split()) on it.
This would cause an error in your JS console - always check the console.
Finally, eval() is evil and almost never required except in exceptional circumstances. Try to avoid it.
I don't know how to work with $.ajax but here is an alternative.
Replace this
$.ajax({
type: "POST",
url: "/ajax/add_url.php",
data: dataString,
}).done(function( result ) {
myresult(result);
});
with
$.post("/ajax/add_url.php",{dataString:dataString},function(data){
alert(data['you array index']);
},'json')
I repeat ,this is my alternative so don't take it hard!

Resources