I'm trying to implement dropzonejs file upload on my website, but I'm getting this error
{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"Call to a member function isValid() on a non-object","file":"C:\\Users\\Username\\Desktop\\localhost\\Project\\app\\controllers\\FileController.php","line":147}}
I have this inside the head tag. I check if the file is an Image and then check the dimensions before sending the file in to the controller. If the file is not an image I send it straight to the controller.
<script type="text/javascript">
$(function() {
Dropzone.options.createFile = {
accept: function(file, done) {
// checking if the filetype is an image to check the dimensions
if ((/\.(gif|jpg|jpeg|tiff|png)$/i).test(file.name)) {
var pixels = 0;
var reader = new FileReader();
reader.onload = (function(file) {
var image = new Image();
image.src = file.target.result;
image.onload = function() {
width = this.width;
height = this.height;
if(width < 800 || height < 300) {
done('image is not 800x300 pixels!');
} else {
done();
}
};
});
reader.readAsDataURL(file);
} else {
// if the file is not an image
done();
}
},
url: '/process/create-file',
previewsContainer: ".dropzone-previews",
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
}
});
</script>
This is the stripped controller, I removed a chunk of the code to make it shorter. Because the error is right at the top.
public function postCreateFile()
{
if(!Input::hasFile('file'))
return Response::json('Where is the file?', 400);
$file = Input::file('file');
if($file->isValid()){
// do stuff
}
}
if I add return var_dump($file) before the $file->isValid() line I get this response
array (size=2) '_token' => string 'BtN7aFkEUQvXlaJDzxx28e4WMI08h5bl3VqrEaHR' (length=40) 'file' => array (size=1) 0 => object(Symfony\Component\HttpFoundation\File\UploadedFile)[9] private 'test' => boolean false private 'originalName' => string '65VWl.jpg' (length=9) private 'mimeType' => string 'image/jpeg' (length=10) private 'size' => int 260740 private 'error' => int 0
And here is the form. I have enctype and files set to true, but still I get an error with a message "non-object" as described above.
{{ Form::open(array('class' => 'dropzone', 'id' => 'create-file', 'url' => 'process/create-file', 'enctype' => 'multipart/form-data', 'files' => true)) }}
<div class="dropzone-previews" id="giga-drop">
<div class="fallback">
{{ Form::file('file') }}
</div>
</div>
{{ Form::close() }}
Any ideas why am I getting this error?
Thanks for #Maerlyn for pointing out it was an array.
Also I found this link that I didn't notice when searching before Laravel and Dropzonejs, files are not uploaded correctly
I had to modify my $file variable to this:
$file = Input::file('file'); // didn't work
$file = Input::file('file')[0]; // works
Related
Language used : js with react - redux-toolkit and php with laravel
I'm trying to save my file in my mongodb database
first of all, here my input file and axios function to post from client (react) to server(laravel) . (it's working, i received the data in php)
import React from 'react';
export const Attach = ({ register, setValue }) => {
const handleFile = (e) => {
setValue('Attachment', e.target.files[0]);
};
return (
<div >
<label >Insert a file </label>
<input type="file" name="file" onChange={(e) => handleFile(e)} />
</div>
);
};
and my axios post function
export const postOffers = (data) => (dispatch) => {
axios({
method: 'post',
url: `${process.env.REACT_APP_API_URL}offer`,
data: {
Type: Type,
UserName: data.UserName,
Object: data.Object,
Address: data.Address,
Comment: data.Comment,
Attachment: data.Attachment,
},
}).then((res) => {
if (!res.data) {
console.log('error form');
} else {
console.log(data.Attachment);
}
});
};
-> console.log(data.Attachment);
then in my php controller :
public function createOffers(Request $request)
{
if ($request) {
//what i have tried
//upload file
$bucket = InternOffer::getMongoDB()->selectGridFSBucket();
$file = $request->file('Attachment');
$resource = fopen($file, "a+");
$file_id = $bucket->uploadFromStream($file, $resource);
$InternOffer = InternOffer::create([
'Type' => $request->get('Type'),
"UserName" => $request->get('UserName'),
'Object' => $request->get('Object'),
'Address' => $request->get('Address'),
'Comment' => $request->get('Comment'),
// 'Attachment' => $file_id, (working if i don't pass the attachment)
]);
if ($InternOffer) {
$InternOffer->save();
return ["result" => "Offers has been successfully created"];
} else {
return ["result" => "failed"];
}
}
}
I have a problem, and I can't fix it. I read a lots of forum and issues, but it don't resolve.
The problem is that
$photos = $request->file('file');
return var_dump($photos);
bring NULL. I tried to find the error, but I can't
I want store images on server and in a table, then it connecting to an another products table,
First write in the inputs some data ex. Name,Category, after an other tab upload the images with Dropzone, and save it in one time together.
I am use rowanwins dropzone.
My ... .blade.php
<form method="POST" enctype="multipart/form-data" action="{{ route('product.createnew') }}">
// Other Products inputs ..
//Uploads
<vue-dropzone
ref="myVueDropzone"
id="dropzone"
:options="dropzoneOptions">
</vue-dropzone>
// / form and scripts section
<script>
var url = "{{ route('product.createnew') }}";
console.log(url);
var app = new Vue({
el: '#app',
data: function () {
return {
dropzoneOptions: {
url: url,
thumbnailWidth: 150,
maxFilesize: 2,
maxFiles: 2,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
autoDiscover : true,
clickable : true,
uploadMultiple :true,
addRemoveLinks:true,
headers: {
"X-CSRF-TOKEN": document.head.querySelector("[name=csrf-token]").content
},
},
radioButton: '0',
}
},
methods: {
deleteDropFile(index) {
this.dropFiles.splice(index, 1)
},
}
});
My Create Controller
public function create(Request $request)
{
$validator = Validator::make($request->all(), [
//Other products input
'file' => 'nullable|mimes:jpeg,jpg,png,gif|max:2048',
]);
//$products = new Products
//$products->save();
$photos = $request->file('file');
return var_dump($photos);
if (!is_array($photos)) {
$photos = [$photos];
}
for ($i = 0; $i < count($photos); $i++) {
$photo = $photos[$i];
$savename = sha1(time() . '.' . $request->get('name'))."_$i";
$images = new ProductImages ([
'name' => $request->get('name'),
'post_id'=> $products->id,
'path'=> public_path('uploads') . '/' . $savename,
'main'=> 0,
]);
$images->save();
Image::make($photo)
->resize(250, null, function ($constraints) {
$constraints->aspectRatio();
})
->save(public_path('uploads'). '/' . $savename);
$photo->move(public_path('uploads'), $savename);
}
return redirect()->back();
}
My routes
Route::group(['prefix' => 'product'], function () {
Route::get('/create', 'ProductController#index')->name('product.create'); //View
Route::post('/createnew', 'ProductController#create')->name('product.createnew'); //Post
});
After all I found what is wrong.
It is the validation
'file' => 'nullable|mimes:jpeg,jpg,png,gif|max:2048',
throw the error.
Thanks
I am using jQuery file uploader to upload a resized image, convert it to blob and save it as blob into a DB.
For the database I also need to save the mimeType, which I see in the request, which I receive, but I dont understand how to get the mimeType value.
The code to send the image:
var formData = new FormData();
formData.append("_token", $('meta[name="csrf-token"]').attr('content'));
formData.append("user_id_val", $('.user-general-i').data('userid'));
// HTML file input, chosen by user
formData.append("userfile", data.files[0]);
var request = new XMLHttpRequest();
request.open("POST", "http://localhost.eu/home/create_comment_images");
request.onload = function(oEvent) {
if (request.status == 200) {
console.log('success');
} else {
console.log(request.status);
}
};
request.send(formData);
Code on the server:
public function create_comment_images(Request $data) {
\Log::info($data);
try {
$path = $data->userfile;
$logo = file_get_contents($path);
$base64 = base64_encode($logo);
return ['success' => true];
} catch (\Exception $e) {
return ['success' => false, 'message' => $e->getMessage()];
}
return ['success' => false, 'message' => 'Something went wrong'];
}
The log info shows me this:
array (
'_token' => 'QxOqetFU2Re6fwe442vksGNnvV0C88v8dcrFpAp',
'user_id_val' => '568092',
'userfile' =>
Illuminate\Http\UploadedFile::__set_state(array(
'test' => false,
'originalName' => 'Unbenannt.png',
'mimeType' => 'image/png',
'error' => 0,
'hashName' => NULL,
)),
)
I am almost there, I need the get the mimeType information from the array.
I tried:
$data->userfile->mime_content_type
$data->userfile->mimeType
$data->userfile['mimeType']
$data->userfile[0]['mimeType']
Nothing works. Any ideas how to extract that information?
On Laravel you can use the intervention library. This library is very powerfull you can change the format, resize and do all kind of stuff.
Here a basic example..
// read image from temporary file
$img = Image::make($_FILES['image']['tmp_name']);
// get or sets the mime type.
$mimeType = $img::mime();
// save image
$img->save('foo/bar.jpg');
// Get image as string.
$string = base64_encode($img->encode('jpg'));
Intervention Reference
To get the mimetype from the uploaded file header, you can call getMimeType() on the \Illuminate\Http\UploadedFile class.
$uploadedFile = $data->file('userfile');// or
$mimeType = $uploadedFile->getMimeType()
I'm using laravel 4.2 and currently I don't how to save a csv file into public\csv\ directory using AJAX. I'm still finding some answers. Maybe someone can help me with this.
Here's my code:
In blade view:
{{Form::open(['route' => 'file_upload', 'files' => true, 'id' => 'upload_form', 'method' => 'POST'])}}
{{Form::file('csv_upload', ['id' => 'uploaded_file', 'accept' => 'text/csv'])}}
{{Form::submit('submit', ['class' => 'btn btn-primary btn-xs', 'id' => 'upload'])}}
{{Form::close()}}
Javascript Ajax:
var ajax_ready = 1
var token = {{Session::get('_token')}}
if($.type(originalOptions.data) === 'string') {
options.data = originalOptions.data+"&_token="+token;
}else if($.type(originalOptions.data) === 'object') {
//Here I got a new error
}else{
options.data = $.param(($.extend(originalOptions.data, {'_token':mmad_token})));
}
options.url = originalOptions.url.slice(0,originalOptions.url.indexOf("?_token="));
if (ajax_ready!=1){
jqXHR.abort();
}
ajax_ready = 0;
});
$('form#upload_form').on('submit', function(e){
e.preventDefault();
var uploadFile = $('#uploaded_file');
var ext = $("input#uploaded_file").val().split(".").pop().toLowerCase();
var file = $('input[name="csv_upload"]').val();
if($.inArray(ext, ["csv"]) === -1) {
alert("Please upload a .csv file!");
return false;
}
var csv = uploadFile[0].files;
var form = new FormData(this);
var csvFile = {lastModifed: csv[0].lastModified, fileName: csv[0].name, size: csv[0].size, fileType: csv[0].type};
$.post('{{ URL::route("file_upload") }}?_token={{Session::token()}}',{
data: form
}).done(function(response){
});
});
PHP:
public function upload_csv()
{
$inputs = Input::all();
$csvFile = $inputs['data']['fileName'];
$path = public_path().DIRECTORY_SEPARATOR.'csv'.DIRECTORY_SEPARATOR;
$path2 = public_path('csv/');
if(is_dir($path2))
{
#move_uploaded_file($csvFile, $path2.$csvFile); //This line can't move the uploaded files in my desired directory
}
return json_encode(['success' => 1, 'description' => 'Successfully Upload File']);
}
This code below does work when not using AJAX:
if(Input::hasFile('csv_upload'))
{
$file = Input::file('csv_upload');
$originalFilename = $file->getClientOriginalName();
$rules = ['csv_upload' => 'required|file:csv'];
$validate = Validator::make(['csv_upload' => $file], $rules);
if($validate->fails())
{
return json_encode(['error' => 1, 'description' => 'File must be in .csv format']);
}
$path = public_path('/csv/');
if(!file_exists($path))
{
mkdir($path);
}
}
Console.log of csv
You can not move file because when you submit form with ajax file is not being sent with ajax,For sending file you have to send file with FormData() javascript Object.
If you check in upload_csv controller by putting print_r($_FILES); you will get empty array.
So use FormData on client side for appending file, then try agian.
You aren't getting error beacuse you have used php Error Control Operators likes#move_uploaded_file($csvFile, $path2.$csvFile);.
if you need working example then tell me i will give it to you.
Code For Your Help:
1. In blade view:
<script type="text/javascript">
$('form#upload_form').on('submit', function(e){
e.preventDefault();
var uploadFile = $('#uploaded_file');
var ext = $("input#uploaded_file").val().split(".").pop().toLowerCase();
var file = $('input[name="mmad_csv_upload"]').val();
if($.inArray(ext, ["csv"]) === -1) {
alert("Please upload a .csv file!");
return false;
}
var csv = uploadFile[0].files;
var formData = new FormData($(this)[0]);
formData.append('uploaded_file', $("#uploaded_file")[0].files[0]);
formData.append('lastModifed', csv[0].lastModified);
formData.append('fileName', csv[0].name);
console.log(formData);
$.ajax({
url: '{{ URL::route("file_upload") }}',
type: 'POST',
data: formData,
async: true,
cache: false,
contentType: false,
processData: false,
success: function (returndata) { //alert(returndata); return false;
}
});
});
</script>
2.Controller
public function file_upload(Request $request)
{
$inputs = Input::all();
$csvFile = $inputs['fileName'];
$path = public_path().DIRECTORY_SEPARATOR.'csv'.DIRECTORY_SEPARATOR;
$path2 = public_path('/csv/');
if(is_dir($path2))
{
$success = $request->file('uploaded_file')->move($path2, $csvFile);
}
return json_encode(['success' => 1, 'description' => 'Successfully Upload File']);
}
To move the uploaded file to a new location, you should use the move method. This method will move the file from its temporary upload location (as determined by your PHP configuration) to a more permanent destination of your choosing:
Input::file('fileName')->move($destinationPath, $fileName);
If you need additional validations, you can check it at http://laravel.com/docs/5.1/requests#files
Default AJAX POST does not support file uploads. Use jQuery Form to upload files successfully. Full documentation of file upload at http://malsup.com/jquery/form/#file-upload
Below my example of a recentlty build script... My Controller uploads the files to S3, but is easy to be implemented with local storage.
var progress = function(event, position, total, percent) {
$(".progress-bar").width(percent + '%');
$(".progress-bar").html(percent + '%');
if(percent > 50) {
$(".progress-bar").css('color','#fff');
}
if(percent == 100) {
setTimeout(function(){
$(".progress").html('<span class="processing-msg">Processing... Please be patient!</span>');
$(".processing-msg").fadeIn('slow');
}, 1000);
}
}
var success = function(data) {
var obj = $.parseJSON(data);
$("#"+obj.hidden, parent.document).val(obj.filename);
var src = 'https://s3.amazonaws.com/spincms'+obj.path+'thumb_'+obj.filename;
$("#uploaded-"+obj.hidden, parent.document).html('<img class="img-circle uploaded-img" src="' + src + '">');
$(".progress").html('<span class="processing-msg-next">File has been uploaded and processed. Do not forget to submit the form!</span>');
}
var options = {
target: '#output',
uploadProgress: progress,
success: success,
resetForm: true
};
$(document).on('click', "#upload-now", function(e) {
$(".progress").html('<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100"></div>');
if($("#upload-form input[type=file]")[0].files.length == 0) {
$(".progress").html('<span class="processing-msg-next">No file selected!</span>');
return false;
} else {
var name = $("#upload-form input[name='name']").val();
var token = $("#upload-form input[name='_token']").val();
var file_name = $("#upload-form input[type=file]")[0].files[0].name;
$("#upload-form").ajaxSubmit(options);
}
}
});
Since you are using jQuery you can use the form plugin as it will make things much more easier for you to work with for example , this is the jquery part that you will use :
$(document).ready(function() {
// bind 'myForm' and provide a simple callback function
$('#upload_form').ajaxForm(function() {
alert("Your file has been uploaded, thanks");
});
});
and in your controller you can code it like :
pubilc function postUpload()
{
$success = false;
if(Request::ajax())
{
if(Input::hasFile('csv_upload'))
{
$file = Input::file('csv_upload');
if(!File::isDirectory(storage_path('csv'))) {
File::createDirectory(storage_path('csv'));
}
$file->move(storage_path('csv'), $file->getClientOriginalName());
// now your file is on app/storage/csv folder
$filePath = storage_path('csv/'.$file->getClientOriginalName());
$success = true;
}
}
return Response::json(['success'=>$success]);
}
i am using the jQuery-File-Upload jquery plugin to upload some files
i am uploading the pictures from one domain (client side) to another one (server side) through an api.
the image seems to upload fine int he tmp directory on the server side but the $_FILE var doesn't contain the image type or size
array (size=1)
'files' =>
array (size=5)
'name' =>
array (size=1)
0 => string '3.jpg' (length=5)
'type' =>
array (size=1)
0 => null
'tmp_name' =>
array (size=1)
0 => string '/tmp/phpXyHG5T' (length=14)
'error' =>
array (size=1)
0 => int 0
'size' =>
array (size=1)
0 => null
the js is simple
$('#fileupload').fileupload({
dataType: 'json',
url : 'http://server_side.com/requests/index/image-upload/',
add: function (e, data) {
data.context = $('#upload_button')
.click(function () {
data.context = $('#upload_button').text('Uploading...');
data.submit();
});
},
done: function (e, data) {
console.log(data);
}
}).on('fileuploaddone', function (e, data) {
console.log(data);
}).on('fileuploadsubmit', function (e, data) {
console.log(data);
});
the php side
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender(TRUE);
// initialize the upload
$uploadHandler = new Api_Model_UploadHandler();
$uploadHandler->initialize();
any ideas?
i figure it out.
I'm using Zend Framework.
the issue is that the $_FILE looses the size and type if you ask for it after the Api_Model_UploadHandler initialization because the tmp image gets removed.
so by asking for the image before seems to work ok.
no need to check if the file exists
public function imageUploadAction()
{
// in case some other crap goes wrong on the website, i want a clean json response
error_reporting(0);
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender(TRUE);
// get the request
$request = $this->getRequest();
// get other params if you sent any
$fileName = !empty($_FILES) ? $_FILES["files"]["name"][0] : '_';
if (file_exists('tmp/' . $fileName)) {
$upload = new Zend_File_Transfer_Adapter_Http();
if (is_null($files)) {
$files = $upload->getFileInfo();
}
// ... do a regular zend image upload
}
// initialize the upload
$uploadHandler = new Api_Model_UploadHandler();
$uploadHandler->initialize();
return json_encode(array());
}