I'm trying to upload image to storage. I'm currently got this object but seems unfortunate to save on app/storage
Illuminate\Http\UploadedFile Object
(
[test:Symfony\Component\HttpFoundation\File\UploadedFile:private] =>
[originalName:Symfony\Component\HttpFoundation\File\UploadedFile:private] => lamborghini_veneno_art_minimalism_99945_1366x768.jpg
[mimeType:Symfony\Component\HttpFoundation\File\UploadedFile:private] => image/jpeg
[size:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 117303
[error:Symfony\Component\HttpFoundation\File\UploadedFile:private] => 0
[hashName:protected] =>
[pathName:SplFileInfo:private] => C:\xampp\tmp\php82F7.tmp
[fileName:SplFileInfo:private] => php82F7.tmp
)
Here is my code.
In profile.vue I have click event from input file.
onFilePicked(event){
const files = event.target.files
const data = new FormData();
data.append('avatar', files[0]);
this.$store.dispatch('uploadImage_profile',data)
.then(response=>{
})
.catch(error=>{
})
}
Then send using axios
axios({
url: '/prod/api/uploadImage_profile',
method: 'post',
data: obj
})
.then(response=>{
if(response.status == 200){
resolve(response.data)
}
})
.catch(error=>{
if(error.response){
reject(error.response.data);
}
})
And my Controller.php
public function uploadImage_profile(Request $request){
$response = [];
//var_dump($request->file('avatar'));
//$path = $request->file('avatar')->store('avatars');
if($request->hasFile('avatar')){
$file = $request->file('avatar');
Storage::put('file.jpg', $file);
}
return response()->json($response);
}
You need to set Content-Type as multipart/form-data in your axios post request:
axios({
url: '/prod/api/uploadImage_profile',
method: 'post',
data: obj,
headers: {
'Content-Type': 'multipart/form-data'
}
})
Try this way:
$file = $request->file('avatar');
$destinationPath = storage_path() . '/folder'; // directory under which you want to store the file
if( $file ->move( $destinationPath, $file ) )
{
// image moved successfuly
}
else
{
// fail to move image
}
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'm trying to save image to php application (made with laravel 6.0) using React Native. Here is my react native image picker
var ImagePicker = NativeModules.ImageCropPicker;
here is my image save function
addImages = async () => {
const { image, images } = this.state
const access_token = await AsyncStorage.getItem('access_token')
try {
let data = new FormData();
images.map((image, i) => {
data.append('id', id);
data.append('uri', image.uri);
data.append('type', image.mime);
data.append('name', 'test.jpg');
});
fetch(apiConfig.apiUrl + '/api/save-image', {
method: 'POST',
headers: {
'Content-Type' : 'multipart/form-data',
'Authorization': 'Bearer ' + access_token,
},
body:data
})
.then(function (response) {
return response.json();
})
.then(function (data) {
try {
console.log(data);
} catch (error) {
console.log(error);
}
}.bind(this))
.catch((error) => {
console.log(error)
});
}catch (error) {
console.log(error)
}
}
Here is my php code
public function saveImage(Request $request)
{
header( "Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Origin: *");
try {
$file= array('file'=>$request->uri);
Storage::disk('public')->put($request->imgName,File::get($file->file));
return response()->json(['true'=>'Successfully Created'], 200);
} catch (\Exception $e) {
Log::info('vehicle image: ', [$e->getMessage()]);
return response()->json(['error'=>$e], 200);
}
}
When I try to save I'm getting SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data.
when I return the $request->uri I'm getting something like this file:///data/user/0/com.carup/cache/react-native-image-crop-picker/IMG_20191103_161929.jpg
How can I fix this?
How can I fix this?
You need to specify file name as the third parameter to data.append:
data.append('file', image.uri, 'test.jpg');
Finally I have fixed it with Base64 method. Here is my code.
pick images with base64
pickMultipleBase64=()=> {
ImagePicker.openPicker({
multiple: true,
width: 300,
height: 300,
includeBase64: true,
includeExif: true,
}).then(images => {
this.setState({
images: images.map(image => {
return {uri: `data:${image.mime};base64,`+ image.data, width: image.width, height: image.height,type:image.mime}
}),
});
}).catch(e => alert(e));
}
And uploaded with other details like this
addImages = async () => {
const { image, images, stockNo } = this.state
const access_token = await AsyncStorage.getItem('access_token')
if(access_token == null) {
return(
this.gotoLogin()
)
}
this.setState({
isLoading:true,
message:'',
status:true
})
try {
let data = new FormData();
images.map((image, i) => {
data.append('id', id);
data.append('stock', stockNo);
data.append('chassis', chassis_no);
data.append('file'+i, this.state.images[i].uri);
data.append('type'+i, this.state.images[i].type);
imageCount++
});
data.append('imageCount', imageCount);
// console.log(data);
fetch(apiConfig.apiUrl + '/api/save-image', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + access_token,
},
body:data
})
.then(function (response) {
return response.json();
})
.then(function (data) {
console.log(data);
imageCount = 0
try {
this.setState({
isLoading: false,
message:data.true ? data.true:data.error,
messageColor:data.true ? CarColors.success : CarColors.error,
btnStatus:true
// chassis:''
})
if(data.true){
this.setState({
image:null,
images: null,
})
}
} catch (error) {
this.removeToken();
console.log('1 '+error);
}
}.bind(this))
.catch((error) => {
this.setState({
isLoading: false,
message:'error',
messageColor:CarColors.error,
})
console.log(error)
});
}catch (error) {
console.log(error)
}
And my php(laravel) code is like this. Here I have created a new folder (with vehicle id) in storage and save images to separate folders.
public static function saveImage($request)
{
$dir = "./storage/vehicle/" . $request->id;
if (is_dir($dir) === false) {
mkdir($dir);
}
DB::beginTransaction();
try {
for ($i = 0; $i < $request->imageCount; $i++) {
$type = [];
$file = 'file' . $i;
$mime = 'type' . $i;
$data = $request->$file;
$type = explode('/', $request->$mime);
$extension = $type[1];
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$data = base64_decode($data);
$Imgdata =Images::create([
'vehicle_id' => $request->id,
'img_name' => $i.'.'.$extension,
'img_ext' => $extension,
'img_order' => '0',
]);
Storage::disk('vehicle')->put($request->id . '/' . $i . '.' . $extension, $data);
}
//Update Vehicle table ImageStatus
$Vehicle = Vehicle::where('id',$request->id)->update([
'img_status' => '1',
]);
return response()->json(['true' => 'Successfully Uploaded'], 200);
} catch (\Exception $e) {
DB::rollback();
Log::info('vehicle image name save issue: ', [$e->getMessage()]);
return 'false';
}
}
Hope this will help others who are going to upload multiple images with react native
I want to send a docx file to the client in the response of a get request:
Here's the Laravel controller code:
public function file($id)
{
$dlink = resource_path('temp/' . $id . '.docx');
$headers = [
'Content-Type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
];
return response()->download($dlink, $id . '.docx', $headers);
}
VueJS code:
axios.get(`${location.protocol}//${location.host}/api/download/${response.data}`,
{ responseType: "arraybuffer" }
)
.then(response => {
this.downloadFile(response);
})
.catch(err => alert(err));
downloadFile(response) {
var newBlob = new Blob([response.body], {
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
const data = window.URL.createObjectURL(newBlob);
var link = document.createElement("a");
link.href = data;
link.download = "resume.docx";
link.click();
setTimeout(function() {
window.URL.revokeObjectURL(data);
}, 100);
}
It doesn't show any error. but downloads a corrupted 9bytes docx file.
changing response.body to response.data did the job.
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()
Like the title says, I'm trying to do an image upload from VueJs to a Laravel endpoint. I discovered that the only way(if there is another please tell me) is to send the base64 of the image through the request. On the Vue side I think everything is covered.
However, on the Laravel side is where it gets complicated. I can't decode the base64 string that gets passed, and when I try to store the image in my AWS S3 bucket, it doesn't store properly. Here is the code:
VueJS
<template>
<input type="file" name="image" class="form-control" #change="imagePreview($event)">
</template>
methods: {
submitForm(){
axios.defaults.headers.post['Content-Type'] = 'multipart/form-data';
axios.post(this.$apiUrl + '/article', {
image: this.image
}).then(response => {
flash(response.data.message, 'success');
}).catch(e => {
console.log(e);
})
},
imagePreview(event) {
let input = event.target;
if (input.files && input.files[0]) {
var reader = new FileReader();
let vm = this;
reader.onload = e => {
this.previewImageUrl = e.target.result;
vm.image = e.target.result;
}
reader.readAsDataURL(input.files[0]);
}
}
}
Laravel:
$this->validate($request, [
'image' => 'required',
]);
// return response()->json(base64_decode($request->image));
$timestampName = microtime(true) . '.jpg';
$url = env('AWS_URL') . '/article_images/' .$timestampName;
Storage::disk('s3')->put($timestampName, base64_decode($request->image));
If I add the image validation rule, it says it's not an image..
I would also like to retrieve the extension if possible.
you can do it using FormData in JS part and use getClientOriginalExtension() on the file to get the extension in Laravel.
VueJS
imagePreview(event) {
let selectedFile = event.target.files[0];
vm.image = selectedFile;
}
submitForm(){
let fomrData = new FormData();
formData.append('image', vm.image);
axios.post(this.$apiUrl + '/article', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
flash(response.data.message, 'success');
})
.catch(e => {
console.log(e);
});
}
Laravel
$this->validate($request, [
'image' => 'required',
]);
$image = $request->file('image');
$extension = $image->getClientOriginalExtension(); // Get the extension
$timestampName = microtime(true) . '.' . $extension;
$url = env('AWS_URL') . '/article_images/' .$timestampName;
Storage::disk('s3')->put($url, file_get_contents($image));
Here is a link that might be useful
Hope that it helps.