Symfony 4.4 - Summernote editor upload base64 images to server - javascript

Pretty common problem with a lot of answers here but couldn't make it work for my Symfony 4 application. I tried to debug my action with dump() and die(), it doesn't even enter the action and I think that's why my images won't upload.
My JavaScript code in Twig:
<script>
var url = "{{ path('editor_file_upload') }}";
$(document).ready(function() {
$('.summernote').summernote({
onImageUpload: function(files, editor, welEditable) {
sendFile(files[0], editor, welEditable);
}
});
function sendFile(file, editor, welEditable) {
let formData = new FormData();
formData.append("file", file);
$.ajax({
data: formData,
type: "POST",
url: url,
cache: false,
contentType: false,
processData: false,
success: function(url) {
editor.insertImage(welEditable, url);
}
});
}
});
</script>
My Controller action:
/**
* #Route("/editor-file-upload", name="editor_file_upload")
*/
public function uploadEditorFile(Request $request)
{
/** #var UploadedFile $File */
$File = $request->files->get('file');
if ($File) {
$originalFilename = pathinfo($File->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = transliterator_transliterate('Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()', $originalFilename);
$newFilename = $safeFilename . '-' . uniqid() . '.' . $File->guessExtension();
try {
$File->move(
$this->getParameter('editor_images'),
$newFilename
);
} catch (FileException $e) {
// ... handle exception if something happens during file upload
}
}
}

The problem was that I didn't return any response, here's the edit:
/**
* #Route("/upload-editor", name="admin_upload_editor")
*/
public function uploadEditorFile(Request $request, KernelInterface $kernel) {
/** #var UploadedFile $file */
$file = $request->files->get('img');
if (empty($file))
{
return new Response("No file",Response::HTTP_UNPROCESSABLE_ENTITY, ['content-type' => 'text/plain']);
}
if ($file) {
$originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
$safeFilename = transliterator_transliterate('Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()', $originalFilename);
$newFilename = $safeFilename . '-' . uniqid() . '.' . $file->guessExtension();
try {
$file->move(
$kernel->getProjectDir() . '/' .
$this->getParameter('public_dir') . '/' .
$this->getParameter('editor_dir'),
$newFilename
);
return new Response("/editor_images/" . $newFilename, Response::HTTP_OK);
} catch (FileException $e) {
return new Response("Cannot upload file!",Response::HTTP_UNPROCESSABLE_ENTITY, ['content-type' => 'text/plain']);
}
}
}

Related

How to upload an image to server directory using ajax?

I have this ajax post to the server to send some data to an SQL db :
$.ajax({
method: "POST",
url: "https://www.example.com/main/public/actions.php",
data: {
name: person.name,
age: person.age,
height: person.height,
weight: person.weight
},
success: function (response) {
console.log(response)
}
})
in the server i get this data with php like this :
<?php
include "config.php";
if(isset ( $_REQUEST["name"] ) ) {
$name = $_REQUEST["name"];
$age = $_REQUEST["age"];
$height = $_REQUEST["height"];
$weight = $_REQUEST["weight"];
$sql = "INSERT INTO persons ( name, age, height, weight )
VALUES ( '$name', '$age', '$height', '$weight' )";
if ($conn->query($sql) === TRUE) {
echo "New person stored succesfully !";
exit;
}else {
echo "Error: " . $sql . "<br>" . $conn->error;
exit;
}
};
?>
I also have this input :
<input id="myFileInput" type="file" accept="image/*">
and in the same directory as actions.php i have the folder /images
How can i include an image ( from #myFileInput ) in this ajax post and save it to the server using the same query in php ?
I have searched solutions in SO but most of them are >10 years old,i was wondering if there is a simple and modern method to do it,i'm open to learn and use the fetch api if its the best practice.
You should use the formData API to send your file (https://developer.mozilla.org/fr/docs/Web/API/FormData/FormData)
I think what you are looking for is something like that:
var file_data = $('#myFileInput').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
$.ajax({
url: 'https://www.example.com/main/public/actions.php',
contentType: false,
processData: false, // Important to keep file as is
data: form_data,
type: 'POST',
success: function(php_script_response){
console.log(response);
}
});
jQuery ajax wrapper has a parameter to avoid content processing which is important for file upload.
On the server side, a vrey simple handler for files could look like this:
<?php
if ( 0 < $_FILES['file']['error'] ) {
echo 'Error: ' . $_FILES['file']['error'];
}
else {
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
}
?>
via ajax FormData you can send it . refer here . Note : data: new FormData(this) - This sends the entire form data (incldues file and input box data)
URL : https://www.cloudways.com/blog/the-basics-of-file-upload-in-php/
$(document).ready(function(e) {
$("#form").on('submit', (function(e) {
e.preventDefault();
$.ajax({
url: "ajaxupload.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData: false,
beforeSend: function() {
//$("#preview").fadeOut();
$("#err").fadeOut();
},
success: function(data) {
if (data == 'invalid') {
// invalid file format.
$("#err").html("Invalid File !").fadeIn();
} else {
// view uploaded file.
$("#preview").html(data).fadeIn();
$("#form")[0].reset();
}
},
error: function(e) {
$("#err").html(e).fadeIn();
}
});
}));
});
If you are not averse to using the fetch api then you might be able to send the textual data and your file like this:
let file=document.querySelector('#myFileInput').files[0];
let fd=new FormData();
fd.set('name',person.name);
fd.set('age',person.age);
fd.set('height',person.height);
fd.set('weight',person.weight);
fd.set('file', file, file.name );
let args={// edit as appropriate for domain and whether to send cookies
body:fd,
mode:'same-origin',
method:'post',
credentials:'same-origin'
};
let url='https://www.example.com/main/public/actions.php';
let oReq=new Request( url, args );
fetch( oReq )
.then( r=>r.text() )
.then( text=>{
console.log(text)
});
And on the PHP side you should use a prepared statement to mitigate SQL injection and should be able to access the uploaded file like so:
<?php
if( isset(
$_POST['name'],
$_POST['age'],
$_POST['height'],
$_POST['weight'],
$_FILES['file']
)) {
include 'config.php';
$name = $_POST['name'];
$age = $_POST['age'];
$height = $_POST['height'];
$weight = $_POST['weight'];
$obj=(object)$_FILES['file'];
$name=$obj->name;
$tmp=$obj->tmp_name;
move_uploaded_file($tmp,'/path/to/folder/'.$name );
#add file name to db????
$sql = 'INSERT INTO `persons` ( `name`, `age`, `height`, `weight` ) VALUES ( ?,?,?,? )';
$stmt=$conn->prepare($sql);
$stmt->bind_param('ssss',$name,$age,$height,$weight);
$stmt->execute();
$rows=$stmt->affected_rows;
$stmt->close();
$conn->close();
exit( $rows ? 'New person stored succesfully!' : 'Bogus...');
};
?>

Save image from blob-url (javascript / php)

With pdf-js I filter images of an PDF-File. After this I display all of the images in a div. The elements look like this:
<img src="blob:http://myhost/07eee62c-8632-4d7f-a086-c06f1c920808">
What I want to do, is to save all of this images in a server's directory. But I don't know how to do this.
i tried this, but I think it's totally wrong:
let form_data = new FormData();
fetch(url)
.then(res => res.blob()) // Gets the response and returns it as a blob
.then(blob => {
// Here's where you get access to the blob
// And you can use it for whatever you want
// Like calling ref().put(blob)
// Here, I use it to make an image appear on the page
let objectURL = URL.createObjectURL(blob);
let myImage = new Image();
myImage.src = objectURL;
console.log(id, url, selectedProject, pdfName);
form_data.append('file', myImage);
form_data.append('path', dest);
form_data.append('project', selectedProject);
form_data.append('url', url);
});
$.ajax({
url: 'upload_referenceFile.php',
dataType: 'text',
cache: false,
contentType: false,
processData: false,
data: form_data,
type: 'post',
success: function (php_script_response) {
}
});
php:
$project = $_REQUEST['project'];
$script = $_REQUEST['path'];
$dest = 'data/' . $project . '/' . $script . '/media/';
_log($_REQUEST['file']);
$exists = file_exists($dest . $_FILES['file']['name']);
if($exists){
}else{
if (!file_exists($dest)) {
if (!mkdir($dest, 0777, true) && !is_dir($dest)) {
throw new \RuntimeException(sprintf('Directory "%s" was not created', $dest));
}
}
move_uploaded_file($_FILES['file']['tmp_name'], $dest . $_FILES['file']['name']);
}

Call only one function at a time

I am creating a login and register example function using php OOP method with ajax.
When i click on login button it automatically fires the register function as well and when click on register fires login function. I know the issue is when i create an object and calls both the functions below class. I want to know is there any way that i can call only one function at one time. Here is the code:
Ajax
function login() {
jQuery('#loginform').on('submit', (function(e) {
e.preventDefault();
jQuery.ajax({
url: 'scripts/controller.php/login',
type: 'POST',
data: new FormData(this),
processData: false,
contentType: false,
cache: false,
beforeSend: function() {
jQuery('#btn-login').html('<i class="fa fa-spinner fa-spin fa-fw"></i>');
},
success: function(data) {
if(data == 'Logged in') {
jQuery('.result').show();
jQuery('.result').html(data);
jQuery('#btn-login').html('Login');
}
else {
jQuery('.result').html(data);
jQuery('.result').show();
jQuery('#btn-login').html('Login');
}
}
});
}));
}
function register() {
jQuery('#signupform').on('submit', (function(e) {
e.preventDefault();
jQuery.ajax({
url: 'scripts/controller.php/register',
type: 'POST',
data: new FormData(this),
processData: false,
contentType: false,
cache: false,
beforeSend: function() {
jQuery('#btn-signup').html('<i class="fa fa-spinner fa-spin fa-fw"></i>');
},
success: function(data) {
if(data === 'An email has been sent. Please verify your account with in 3 days.') {
jQuery('.result').show();
jQuery('.result').fadeOut(5000);
jQuery('.result').html(data);
jQuery('#btn-signup').html('Sign Up');
jQuery('.result').html(data);
jQuery('#signupform')[0].reset();
}
else {
jQuery('.result').show();
jQuery('.result').html(data);
jQuery('#btn-signup').html('Sign Up');
}
}
});
}));
}
PHP Code
<?php
require('model.php');
class curd {
/************************************************/
/*** LOGIN **/
/************************************************/
public function login() {
$restricted = array('--', '#', "'--", '/*', '*/', '/**/', '/*', '1/0', '*/ 1', "'", ';', '1=1','true','false', 'BEGIN', '+', '||', '|', "' or 1=1/*", "') or '1'='1--", "') or ('1'='1--", '*', 'drop' );
$userEmail = strip_tags(stripcslashes(htmlspecialchars($_POST['email'])));
$password = strip_tags(stripcslashes(htmlspecialchars($_POST['password'])));
if(in_array($userEmail, $restricted) or in_array($password, $restricted)) {
echo 'Avoid SQL injection attacks.';
}
else if(!filter_var($userEmail, FILTER_VALIDATE_EMAIL)) {
echo 'Invalid email address.';
}
else if(strlen(trim($userEmail)) < 5) {
echo 'Minimum characters in email are 5.';
}
else if(strlen(trim($password)) < 5) {
echo 'Minimum characters in password are 5.';
}
else {
$model = new curd_model();
echo $model -> login($userEmail, md5(sha1($password)));
}
}
/************************************************/
/*** REGISTER **/
/************************************************/
public function register() {
$restricted = array('--', '#', "'--", '/*', '*/', '/**/', '/*', '1/0', '*/ 1', "'", ';', '1=1','true','false', 'BEGIN', '+', '||', '|', "' or 1=1/*", "') or '1'='1--", "') or ('1'='1--", '*', 'drop' );
$username = strip_tags(stripcslashes(htmlspecialchars($_POST['username'])));
$userEmail = strip_tags(stripcslashes(htmlspecialchars($_POST['email'])));
$password = strip_tags(stripcslashes(htmlspecialchars($_POST['password'])));
$question = strip_tags(stripcslashes(htmlspecialchars($_POST['question'])));
$answer = strip_tags(stripcslashes(htmlspecialchars($_POST['answer'])));
if(in_array($userEmail, $restricted) or in_array($password, $restricted) or in_array($userEmail, $restricted) or in_array($question, $restricted) or in_array($answer, $restricted)) {
echo 'Avoid SQL injection attacks.';
}
else if(!filter_var($userEmail, FILTER_VALIDATE_EMAIL)) {
echo 'Invalid email address.';
}
else if(strlen(trim($userEmail)) < 5) {
echo 'Minimum characters in email are 5.';
}
else if(strlen(trim($password)) < 5) {
echo 'Minimum characters in password are 5.';
}
else {
$model = new curd_model();
echo $model -> register($username, $userEmail, md5(sha1($password)), $question, $answer);
}
}
}
$object = new curd();
$object -> login();
$object -> register();
?>
Anytime you'll load the file the following lines would run:
$object = new curd();
$object -> login();
$object -> register();
And therefore, both of the login and register functions would run.
You have 2 options:
Split those functions into 2 different files.
In your Ajax, add a parameter which would tell this file which function to run.
In MVC you might have a Routing mechanism (for instance: /user/login -> Controller User -> Method login)
In case you don't, you can simply use a query string, like: /scripts/controller.php?do=login and in your php file have a condition:
$object = new curd();
$do = $_GET['do'];
if($do == 'login'){
$object -> login();
} else {
$object -> register();
}
and in your ajax, update the request url:
jQuery.ajax({
url: 'scripts/controller.php?do=register',
(for login request as well .. ?do=login)

How to trigger Alert after Server Error Response with Dropzone.js

I want to trigger a javascript alert from dropzone.js when the server returns an error. (in json).
Here is my function/method. It seems to be working fine.
public function file_upload($account_id,$bid_id) {
$path = FMREPO . "/account-" . $account_id . "/bid-project-" .$bid_id . "/";
if (file_exists ( $path )){
if (!empty($_FILES)) {
$tempFile = $_FILES['file']['tmp_name'];
$fileName = $_FILES['file']['name'];
$targetPath = $path . "diagram-" . $bid_id . "-";
$targetFile = $targetPath . $fileName ;
move_uploaded_file($tempFile, $targetFile);
// $this->load->database(); // load database
// $this->db->insert('file_table',array('file_name' => $fileName));
}
} else{
header('HTTP/1.1 500 Internal Server Directory Not Found');
header('Content-Type: application/json; charset=UTF-8');
die(json_encode(array('error' => 'File Could Not Be Saved')));
}
}
Here is my Dropzone options. This is the part I don't know how to do or make it work. The "error:" is what I added but it always triggers an alert, even when the file upload was successfull. What do I need to do here?
Dropzone.options.diagramDropzone = {
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 6, // MB
maxFiles: 2,
thumbnailWidth: 100,
thumbnailHeight: 100,
error: function(){
alert('error');
},
init: function() {
this.on("maxfilesexceeded", function(file){
alert("No more files please!");
console.log(file);
this.removeFile(file);
});
}
}
Edit: I just realized this
error: function(){
//alert here
},
should be
error: function(response){
//alert here
},
so now that is working! But the with alert(response) I get [object]. So now the question is how do I alert my string?
You can set up you alert inside the init option like this:
init: function() {
this.on("maxfilesexceeded", function(file){
alert("No more files please!");
console.log(file);
this.removeFile(file);
}),
this.on("error", function(file, errorMessage, xhr) {
alert(errorMessage);
])
}

File upload via Ajax in Laravel

I'm trying to upload a file through ajax in Laravel.
$("#stepbutton2").click(function(){
var uploadFile = document.getElementById("largeImage");
if( ""==uploadFile.value){
}
else{
var fd = new FormData();
fd.append( "fileInput", $("#largeImage")[0].files[0]);
$.ajax({
url: '/nominations/upload/image',
data: fd,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
if(data.uploaded==true){
alert(data.url);
}
},
error: function(err){
alert(err);
}
});
}
});
I'm passing the file input to the php script.
public function image(){
$file = Input::file('fileInput');
$ext = $file->getClientOriginalExtension();
$fileName = md5(time()).".$ext";
$destinationPath = "uploads/".date('Y').'/'.date('m').'/';
$file->move($destinationPath, $fileName);
$path = $file->getRealPath();
return Response::json(["success"=>true,"uploaded"=>true, "url"=>$path]);
}
I'm getting a the response as
{"success":true,"uploaded":true,"url":false}
The request Payload is
------WebKitFormBoundary30GMDJXOsygjL0ZS
Content-Disposition: form-data; name="fileInput"; filename="DSC06065 copy.jpg"
Content-Type: image/jpeg
Why this is happening?
Found the answer:
public function image(){
$file = Input::file('fileInput');
$ext = $file->getClientOriginalExtension();
$fileName = md5(time()).".$ext";
$destinationPath = "uploads/".date('Y').'/'.date('m').'/';
$moved_file = $file->move($destinationPath, $fileName);
$path = $moved_file->getRealPath();
return Response::json(["success"=>true,"uploaded"=>true, "url"=>$path]);
}
Get the path after assigning it to a new variable.

Categories

Resources