I am sending formdata from Angular 2 to Laravel API to save the recorded voice from RecordRTC js. Checked the filename, filetype and blob file on console. it is showing. but not able to retrieve on Laravel backend code.
public uploadToServer() {
let blob = this.recordRTC instanceof Blob ? this.recordRTC : this.recordRTC.blob;
let fileType = blob.type.split('/')[0] || 'audio';
let fileName = (Math.random() * 1000).toString().replace('.', '');
if (fileType === 'audio') {
fileName += '.' + (!!navigator.mozGetUserMedia ? 'ogg' : 'wav');
} else {
fileName += '.webm';
}
// create FormData
var formData: FormData = new FormData();
console.log(fileName);
console.log(blob);
console.log(fileType);
formData.append(fileType + '-filename', fileName);
formData.append(fileType + '-blob', blob);
console.log(formData);
this.recordingService.saveRecording(formData).subscribe(
data => this.saveRecordingSuccess(data),
error => this.saveRecordingFail(error)
);
}
Laravel Code:-
public function saveRecording(Request $request)
{
$fileName = '';
$tempName = '';
$file_idx = '';
if (!empty($_FILES['audio-blob'])) {
$file_idx = 'audio-blob';
$fileName = $_POST['audio-filename'];
$tempName = $_FILES[$file_idx]['tmp_name'];
}
if (empty($fileName) || empty($tempName)) {
if(empty($tempName)) {
echo 'Invalid temp_name: '.$tempName;
return;
}
echo 'Invalid file name: '.$fileName;
return;
}
$filePath = public_path('voiceRecording/' . $fileName);
// make sure that one can upload only allowed audio/video files
$allowed = array(
'webm',
'wav'
);
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
if (!$extension || empty($extension) || !in_array($extension, $allowed)) {
echo 'Invalid file extension: '.$extension;
return;
}
if (!move_uploaded_file($tempName, $filePath)) {
// error code
return;
}
}
In laravel code I have not receiving any files and post data.
You have to put on your form the mime type, like in JQuery Ajax, have the property
mimeType: "multipart/form-data"
Related
I want to be able to have a user drag and drop a pdf file and have a modal appear for the user to quickly fill out a form about the file. When the user clicks submit, the file and the form data are passed using Ajax to a php file to then have the file upload and the data processed into a DB.
script.js
// On drop calls uploadFile Function and appends to formData object
$("#dropzone").on ('drop', function (e) {
e.preventDefault();
$(this).removeClass('dropzone dragover').addClass('dropzone');
$("#myModal").removeClass("hidden").addClass("visible");
var file = e.originalEvent.dataTransfer.files;
uploadFile(file);
});
var uploadFile = function(files){
formData = new FormData();
formData.append("file", files);
var x;
for (x = 0; x < files.length; x = x + 1){
let file = files[x];
formData.append('files[]', file);
}
};
// On Form submit all data is saved to values and Ajax call to users.php
$("form").on('submit', function(e) {
// e.preventDefault();
var values = $(this).serialize();
$("#myModal").removeClass("visible").addClass("hidden");
url = 'app/forms/users.php'
$.ajax({
type: 'POST',
url: 'app/forms/users.php',
processData: false,
contentType: false,
cache: false,
data: { formData, values },
dataType: 'json',
success: console.log("Done")
});
});
This is where I run into issues. I am able to
console.log(Array.from(formData)) at all points of interaction before the user hits submit. But when the user submits the form it seems the formData vanishes from existence.
users.php
} else if ($_POST['dispatch'] == 'file_upload') {
// Upload File
var_dump($_FILES);
var_dump($_POST);
$errors = [];
$target_dir = 'F:\wamp64\www\blank\dev\uploads/';
$extensions = ['pdf', 'PDF'];
$all_files = count($_FILES['file']['tmp_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];
$tmp = explode('.', $_FILES['file']['name'][$i]);
$file_ext = strtolower(end($tmp));
$file = $target_dir . date('U')."-".basename($file_Name);
if (!in_array($file_ext, $extensions)) {
$errors[] = 'Extension not allowed: ' . $file_Name . ' ' . $file_Type;
}
if ($file_Size > 9000000000000000000) {
$errors[] = 'File size exceeds limit: ' . $file_Name . ' ' . $file_Type;
}
move_uploaded_file($file_Tmp, $file);
if ($errors) print_r($errors);
}
// Process to DB
Currently, the only data I can find is the formData from the form itself. If there is any information that I missed that could be helpful just let me know. Either I need to go about this a different way or I'm just missing something.
Any help is appreciated. Thank you.
Am trying to update user image database column using dropzone plugin in one request but when i set uploadMultiple to true is not working no image move to folder neither database. But when i set it to false only last image name move to user image column but all images move to folder.
Thanks in advance
Here is my code
Dropzone.options.mydropzone =
{
autoProcessQueue: false,
addRemoveLinks: true,
dictMaxFilesExceeded: "Maximum upload limit reached",
dictInvalidFileType: "upload only JPG/PNG/JPEG/GIF/BMP",
acceptedFiles: '.png,.jpg,.jpeg,.gif,.bmp',
parallelUploads: 10,
// uploadMultiple: true,
init: function ()
{
var submitButton = document.querySelector('#letupload');
myDropzone = this;
submitButton.addEventListener("click", function(){
myDropzone.processQueue();
});
this.on("complete", function(){
if (this.getQueuedFiles().length == 0 && this.getUploadingFiles().length == 0)
{
var _this = this;
_this.removeAllFiles();
}
//console.log(this.getUploadingFiles());
});
},
};
Server Side
if (!empty($_FILES)) {
$temp_file = $_FILES['file']['tmp_name'];
$targetDir = '../../user_images/';
$filename = rand().$_FILES['file']['name'];
$targetFile = $targetDir.$filename;
if (move_uploaded_file($temp_file, $targetFile)) {
$sql="UPDATE img SET Image='$filename' WHERE User_id = '$memberid' ";//
if(!$qsql=mysqli_query($con,$sql))
{
echo mysqli_error($con);
}
}
}
After follow Mohammed link every images to to destination folder but only last image save into that database Below is my new server side code
if (!empty($_FILES)) {
foreach($_FILES['file']['tmp_name'] as $key => $value) {
$temp_file = $_FILES['file']['tmp_name'][$key];
$targetDir = '../../user_images/';
$filename = rand().$_FILES['file']['name'][$key];
$targetFile = $targetDir.$filename;
if (move_uploaded_file($temp_file,$targetFile)) {
$sql="UPDATE img SET Image='$filename' WHERE User_id = '$memberid' ";//
if(!$qsql=mysqli_query($con,$sql))
{
echo mysqli_error($con);
}
}
}
}
You are updating at each iteration , so the value at the end of script will be the name of the last image uploaded , so there is a way to solve this issue trying this snippet of code :
Insert into an array (i nammed id $images) the file name of uploaded
files.
convert array into spring separated by comma , using implode
function .(i used the same variable $images).
update the row with images name .
Code example :
if (!empty($_FILES)) {
$images=array[];
foreach($_FILES['file']['tmp_name'] as $key => $value) {
$temp_file = $_FILES['file']['tmp_name'][$key];
$targetDir = '../../user_images/';
$filename = rand().$_FILES['file']['name'][$key];
$targetFile = $targetDir.$filename;
if (move_uploaded_file($temp_file,$targetFile)) {
$images[]= $filename;
}
}
$images = implode(',',$images);
$sql="UPDATE img SET Image='$images' WHERE User_id = '$memberid' ";//
if(!$qsql=mysqli_query($con,$sql)){
echo mysqli_error($con);
}
}
Hope this help you .
Thanks to #Mohammed after I try your code, the problem of saving images name into database still persist, I now discover that you declare empty array inside the foreach so below is the working code
Dropzone Js
Dropzone.options.mydropzone =
{
autoProcessQueue: false,
addRemoveLinks: true,
dictMaxFilesExceeded: "Maximum upload limit reached",
dictInvalidFileType: "upload only JPG/PNG/JPEG/GIF/BMP",
acceptedFiles: '.png,.jpg,.jpeg,.gif,.bmp',
parallelUploads: 10,
uploadMultiple: true,
init: function ()
{
var submitButton = document.querySelector('#letupload');
myDropzone = this;
submitButton.addEventListener("click", function(){
myDropzone.processQueue();
});
this.on("complete", function(file, response){
if (this.getQueuedFiles().length == 0 && this.getUploadingFiles().length == 0)
{
var _this = this;
_this.removeAllFiles();
}
console.log(this.getUploadingFiles());
});
},
};
Server Side
if (!empty($_FILES)) {
$empty_img_arr=array();
foreach($_FILES['file']['tmp_name'] as $key => $value) {
$temp_file = $_FILES['file']['tmp_name'][$key];
$targetDir = '../../user_images/';
$filename = rand().$_FILES['file']['name'][$key];
$targetFile = $targetDir.$filename;
if (move_uploaded_file($temp_file,$targetFile)) {
$empty_img_arr[]= $filename;
$image = implode(',',$empty_img_arr);
$sql="UPDATE img SET Image='$image' WHERE User_id = '$memberid' ";//
if(!$qsql=mysqli_query($con,$sql))
{
echo mysqli_error($con);
}
}
}
}
Thanks so much really appreciate
I'm creating an image optimiser using gulp and PHP for the Upload.
I want to be able to output the file path url of the uploaded file into index.php what is the best way to do it..
i've tried mimicking the output of the file path using the below, but didn't work..
-: print 'https://footpatrol.s3.amazonaws.com/images/'.date('Y').'/'. date('d-m').'/'.$newfilename.'';
PHP Code.
<?php
$files = glob('images/*'); // get all file names
foreach($files as $file){ // iterate files
if(is_file($file))
unlink($file); // delete file
}
foreach($_FILES['file']['name'] as $index=>$name){
$filename = $name;
if(!file_exists("images/".$filename)){
$file_basename = substr($filename, 0, strripos($filename, '.')); // get file extention
$file_ext = substr($filename, strripos($filename, '.')); // get file name
$newfilename = md5($file_basename) . $file_ext;
move_uploaded_file($_FILES["file"]["tmp_name"][$index],"images/" . $newfilename);
if( move_uploaded_file($_FILES["file"]["tmp_name"][$index],"images/" . $newfilename)){
print '<div class="img">https://footpatrol.s3.amazonaws.com/images/'.date('Y').'/'. date('d-m').'/'.$newfilename.'</div>';
}
}
}
?>
Gulp Code..
var gulp = require('gulp');
var imagemin = require('gulp-imagemin');
var clean = require('gulp-clean');
var s3 = require('gulp-s3');
var AWS = require('aws-sdk');
var fs = require('fs')
var pngquant = require('imagemin-pngquant');
var jpegrecompress = require('imagemin-jpeg-recompress');
var moment = require('moment');
var runSequence = require('run-sequence');
// Delete files in image folder
gulp.task('cleanTemp', function(cb) {
return gulp.src('dist/images/*', { read: false }).pipe(clean());
cb(err)
});
// Delete files in image folder
gulp.task('delete', ['image'], function() {
return gulp.src('./images/*', { read: false })
.pipe(clean());
});
var year = moment().format('YYYY');
var today = moment().format('MM-DD');
// // Image Optimisation
//console.log('dist/images/'+year+'/'+today)
gulp.task('image',['cleanTemp'], function() {
return gulp.src('images/*')
.pipe(imagemin([
imagemin.gifsicle({ interlaced: true }),
jpegrecompress({
progressive: true,
max: 70,
min: 55
}),
pngquant({ quality: '70-80' })
]))
.pipe(gulp.dest('dist/images/' + year + '/' + today + ''));
});
aws = JSON.parse(fs.readFileSync('./aws.json'));
// // UPLOAD
gulp.task('upload', function() {
return gulp.src('./dist/**')
.pipe(s3(aws))
});
// Watch Image files
gulp.task('watch', function() {
gulp.watch('images/*', function(event) {
runSequence('cleanTemp', ['image','upload']);
});
});
// Default Task
gulp.task('default', ['cleanTemp','image', 'upload']);
I am using Laravel 5.0, for image uploading I am using dropzone.js. Actually file uploading to folder and database but it is throwing error like
Call to a member function getClientOriginalName() on a non-object
on post method.
Where have I gone wrong?
View File,
<form method="POST" class="dropzone dz-clickable" id="productDropzone" action="{{url()}}/cms/website/pages/upload_files" enctype="multipart/form-data">
<div class="dz-default dz-message">
<span>Drop files here to upload</span>
</div>
<input name="_token" type="hidden" value="{{ csrf_token() }}">
<input type="submit" value="Upload" id="submit_all"/>
</form>
Below is my js,
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone("form#productDropzone", {
paramName : 'file',
maxFilesize: 3, // MB
maxFiles: 3,
autoProcessQueue: false,
addRemoveLinks: true,
init: function() {
this.on("addedfile", function(file) { fileupload_flag = 1; });
this.on("complete", function(file) { fileupload_flag = 0; });
},
accept: function(file, done)
{
var re = /(?:\.([^.]+))?$/;
var ext = re.exec(file.name)[1];
ext = ext.toUpperCase();
if ( ext == "JPG" || ext == "JPEG" || ext == "PNG" || ext == "GIF" || ext == "BMP")
{
done();
}else {
done("Please select only supported picture files.");
}
},
success: function( file, response ) {
obj = JSON.parse(response);
file.previewElement.querySelector("file").src = obj.src;
// alert(obj.src);return false;
}
});
$('#submit_all').click(function(){
myDropzone.processQueue();
});
Controller function,
$com_id = Auth::user()->company_id;
$file = Request::file('file');
$destinationPath = public_path() . '/images/section/';
$filename = strtolower($file->getClientOriginalName());
$upload_success = $file->move($destinationPath, $filename);
if ($upload_success) {
$upload = new Cms_banner_master();
$upload->product_banner = json_encode($filename);
$upload->company_id = $com_id;
$upload->home_banner ="1";
$upload->save();
return Response::json(array($fileName));
} else
{
return Response::json('error', 400);
}
If you want to prevent the error from happening, you can add some validity checks on the file first.
For example with the isValid method
Update: I added the hasFile method too.
if(Request::hasFile('file') {
$file = Request::file('file');
if($file->isValid()) {
$destinationPath = public_path() . '/images/section/';
$filename = strtolower($file->getClientOriginalName());
$upload_success = $file->move($destinationPath, $filename);
if ($upload_success) {
...
}
}
} else {
return Response::json('No file uploaded', 409);
}
And I would also generate a new name for the uploaded file, this way you don't need the getClientOriginalName:
$filename = $com_id.'_'.date('YmdHis')'.'.$file->guessExtension();
In the spirit of "never trust the users" and not letting them 'choose' a file name from a file that you will be saving on your server.
I'm trying to upload files using php and I am copying and renaming files from other instances that are actually working (uploading pics). But for some reason the form is not passing (POST) any file that is NOT an image :-/
So, in resume, I am getting this (Google) 'request payload' for an image file:
------WebKitFormBoundaryrHOYostaC2KnUDlD
Content-Disposition: form-data; name="uploaded_file[]"; filename="image.jpg"
Content-Type: image/jpeg
------WebKitFormBoundaryrHOYostaC2KnUDlD--
But this for txt or pdf files:
------WebKitFormBoundaryc1RJOtSOpYKAZiBz--
Here is the form and script (functions are to avoid the user to click 'Submit', those work good):
echo '
<script language="JavaScript" type="text/javascript">
function HandleBrowseClick()
{
var fileinput = document.getElementById("uploaded_file");
fileinput.click();
}
function Handlechange()
{
var fileinput = document.getElementById("uploaded_file");
var textinput = document.getElementById("filename");
textinput.value = fileinput.value;
}
</script>';
echo '
<form enctype="multipart/form-data" target="_blank" name="send_file" id="send_file" method="post" action="file_upload.php">
<input type="file" class="hide button" id="uploaded_file" name="uploaded_file" onChange="Handlechange();"/>
<button type="submit" id="btn">Upload!</button>
</form>';
echo '
<div onclick="HandleBrowseClick();" id="fakeBrowse" >Load a file</div>
<input type="text" id="filename" size="50" readonly="true" />
';
So, since it's not passing anything, in my file_upload.php I get the "ERROR: Please browse for a file before clicking the upload button." or "Invalid argument supplied for foreach()" (if I expect an array) error.
I tried using application/x-www-form-urlencoded allowing the same result. Now for those who get mad if there is no question marks: Why the form works fine with images but not so with other kind of files? What am I dong wrong?
Here is the first few lines of file_upload.php (I don't think it's necessary but you never know):
$target = "../files/temp/";
foreach ($_FILES["uploaded_file"]["error"] as $key => $error) {
if ($error != UPLOAD_ERR_OK) { echo "error"; die;}
$fileName = $target . $_FILES["uploaded_file"]["name"][$key]; // The file name
$fileTmpLoc = $_FILES["uploaded_file"]["tmp_name"][$key]; // File in the PHP tmp folder
$fileType = $_FILES["uploaded_file"]["type"][$key]; // The type of file it is
$fileSize = $_FILES["uploaded_file"]["size"][$key]; // File size in bytes
$fileErrorMsg = $_FILES["uploaded_file"]["error"][$key]; // 0 for false... and 1 for true last $key!!!
$fileName = preg_replace('#[^a-z.0-9]#i', '', $fileName); // filter the $filename
$fileName = strtolower($fileName);
$kaboom = explode(".", $fileName); // Split file name into an array using the dot
$fileExt = end($kaboom); // Now target the last array element to get the file extension
if (!$fileTmpLoc) { // if file not chosen
echo "ERROR: Please browse for a file before clicking the upload button.";
exit();
}
else if ($fileErrorMsg == 1) { // if file upload error key is equal to 1
echo "ERROR: An error occurred while processing the file. Try again.";
exit();
}
Finally, some more js:
if (window.FormData) {
formdata = new FormData();
document.getElementById("btn").style.display = "none";
}
input.addEventListener("change", function (evt) {
document.getElementById("response").innerHTML = "Loading . . ."
var i = 0, len = this.files.length, img, reader, file;
for ( ; i < len; i++ ) {
file = this.files[i];
if (!!file.type.match(/image.*/)) {
if (formdata) {
formdata.append("uploaded_file[]", file);
}
}
}
if (formdata) {
$.ajax({
url: "file_upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false
}).done(function (res) {
document.getElementById("response").innerHTML = res;
if ( window.FileReader ) {
reader = new FileReader();
reader.onloadend = function (e) {
showUploadedItem(e.target.result, file.fileName);
};
reader.readAsDataURL(file);
}
});
}
}, false);
where changing contentType doesn't make any diference
THANKS!!!
You have to define the MIME types for your files. For example
.pdf application/pdf
.doc application/msword
Okay, my bad. The js file has an image filter. It started working right away after I removed it.