React native upload image or file via php - php

i am using document picker to upload an image via php.
this is my js code:
const [singleFile, setSingleFile] = useState(null);
const uploadImage = async () => {
// Check if any file is selected or not
if (singleFile != null) {
// If file selected then create FormData
const fileToUpload = singleFile;
const data = new FormData();
data.append('name', 'imgup');
data.append('attachement_file', fileToUpload);
axios.post(''+ALL.API_URL+'/sellwithus/upload.php', data, {
headers: {
'Content-Type': 'multipart/form-data; ',
}
})
.then((response) => {
console.log(response);
})
} else {
// If no file selected the show alert
alert('Please Select File first');
}
};
the select code:
const selectFile = async () => {
// Opening Document Picker to select one file
try {
const res = await DocumentPicker.pick({
// Provide which type of file you want user to pick
type: [DocumentPicker.types.images],
// There can me more options as well
// DocumentPicker.types.allFiles
// DocumentPicker.types.images
// DocumentPicker.types.plainText
// DocumentPicker.types.audio
// DocumentPicker.types.pdf
});
// Printing the log realted to the file
console.log('res : ' + JSON.stringify(res));
// Setting the state to show single file attributes
setSingleFile(res);
} catch (err) {
setSingleFile(null);
// Handling any exception (If any)
if (DocumentPicker.isCancel(err)) {
// If user canceled the document selection
alert('Canceled');
} else {
// For Unknown Error
alert('Unknown Error: ' + JSON.stringify(err));
throw err;
}
}
};
this is the res result:
console.log(JSON.stringify(res));
res
:[{"size":1454366,"fileCopyUri":null,"name":"D0BED0E3-4567-41DA-9B21-8C409E355A87.JPG","uri":"file:///Users/saeedmatar/Library/Developer/CoreSimulator/Devices/098A7371-530E-4667-AAAF-80EAE97F9A9E/data/Containers/Data/Application/06A2878B-D812-4B3C-BEF0-2E40DBFE9A27/tmp/org.reactjs.native.example.JelApp-Inbox/D0BED0E3-4567-41DA-9B21-8C409E355A87.JPG"}]
this is my php code:
$_POST = json_decode(file_get_contents("php://input"),true);
$imageData=$_POST["_parts"][1][1][0];
file_put_contents('uploads/image.JPG', $imageData["uri"]);
the image that uploaded is 0 mb and not appearing.
how can i use uri to upload the image?

File uri returned by react-native-document-picker is a reference in the device app local cache and can't be used to upload data.
Fetch and upload document BLOB data.
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", [DOCUMENT_PATH_URI_HERE], true);
xhr.send(null);
});
// code to submit blob data
// We're done with the blob, close and release it
blob.close();

Related

How to download image using vue js and laravel

I have a hyperlink button on click of this, i want to fetch image from database and get it downloaded on user side with use of laravel and vue js. Below is my code for script file
getImage: function() {
axios.get('/getImage/' + this.form.cashout_id )
.then(function (r)
{
const url = window.URL.createObjectURL(new Blob([r.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.'+r.headers.ext); //or any other extension
document.body.appendChild(link);
link.click();
//hide loader
i.loader = false
})
.catch(function (error) {
alert('Error');
});
},
and now this is my controller code where image is being fetched.
public function getimage($id)
{
$cashout = CashOutDetail::findorfail($id);
$storage_date = Carbon::parse($cashout['recorded_date']);
return response()->download(
storage_path('app/cashoutdetails/'. $storage_date->year .'/' . $storage_date->format('M') . '/'. $cashout->bank_receipt),
'filename.jpg',
['Content-Type' => 'image/jpg']
);
}
Issue is that my image is being fetched and displayed in console window but unable to download. Can anybody help?
You should try:
axios({
method: 'GET',
url: '/getImage/123.jpg',
responseType: 'blob', // <-<<<<<<<<<<
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', '123.jpg');
document.body.appendChild(link);
link.click();
});

Laravel How to create and download PDF from view on same route

I have a laravel-application where I want to generate a PDF from the values, the user has entered in some input fields. So when the user has entered the data, he clicks a button which generates the PDF and downloads it immediately afterwards automatically. All this should happen on the same route/view. The PDF should not be stored somewhere.
So right now, when I click the button, the entered Data gets through, e.g. stored in the DB, and it seems that a PDF is created, but I can't see or find it, and my browser does not inform me that there is a PDF available for download.
Before I started, I installed the laravel-dompdf-plugin, and followed the instructions.
So my route look like this
Route::view('formpage', 'app.statement')->name('statement'); // The blade view with the Form
Route::post('statement', 'MyController#generatePDF')->name('generatePDF'); // this is where I post the form
This is my controller
use PDF;
class MyController extends Controller {
public function generatePDF(Request $request){
$statement = Statement::create([
'name' => $validated['name'],
'email' => $validated['email'],
'phone' => $validated['phone'],
'declaration_date' => $validated['declaration_date'],
]);
$pdf = PDF::loadView('pdf.statement', $statement);
return $pdf->download('File__'.$statement->name.'.pdf');
}
}
I posting the form with javascript by using axios by simply doing this:
$('#submitBtn').click(function(e) {
const formData = new FormData();
formData.append(
"name",
$("#statement")
.find('input[name="name"]')
.val()
);
...etc with all other fields
axios.post($("#statement form").attr("action"), formData)
.then(response => {
$('#submitBtn')
.attr("disabled", "disabled")
.addClass("disabled")
.html('<i class="fas fa-fw fa-check"></i> Success'); */
$("#statement form")[0].reset();
})
.catch(error => {
console.log("ERR: ", error); // DEBUG
$("#statement .text-danger").show();
$('#sworn-statement button[type="submit"]')
.removeAttr("disabled")
.removeClass("disabled")
.html("Send");
});
}
What am I doing wrong?
UPDATE
I tried to do this:
const FileDownload = require("js-file-download");
axios.post($("#statement form").attr("action"), formData)
.then(response => {
FileDownload(response.data,"File.pdf");
}).catch(error => {
console.log('error:', error);
});
which gives me a blank page.
So as I said in the comments your problem is that the file is in the response you get from the axios POST request. If you don't handle the filedownload after you get the response nothing will happen.
You can use the js-file-download module. After you've installed this module you can modify your code to something like this:
const FileDownload = require('js-file-download');
axios.get(YOUR_URL)
.then((response) => {
FileDownload(response.data, YOUR_FILE_NAME);
});
There's also an another solution with JQuery which I got from that answer:
$.ajax({
type: "POST",
url: url,
data: params,
success: function(response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
}
});
Just replace the url and params attributes with your stuff. This creates also a POST request and handles the incomming PDF file as filedownload after the response arrives.

Trying to upload image with formdata and fetch api in reactnative but when trying to print formdata in php file no image data is there why?

In the PHP file, image details are not displaying. but in js file formdata is consoled proper.
How to pass image details to php file using fetch and formdata?
I have run this in macOS.
This is Demo.js file for uploading image in folder and store name in phpmyadmin.
import * as React from "react";
import { Button, Image, View } from "react-native";
import * as ImagePicker from "expo-image-picker";
import * as Permissions from "expo-permissions";
import Constants from "expo-constants";
import { ROOT_URL } from "../../get_connection";
export default class Demo extends React.Component {
state = {
image: null,
Image_TAG: ""
};
render() {
let { image } = this.state;
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Button
title="Pick an image from camera roll"
onPress={this._pickImage}
/>
{image && (
<Image source={{ uri: image }} style={{ width: 200, height: 200 }} />
)}
</View>
);
}
componentDidMount() {
this.getPermissionAsync();
}
getPermissionAsync = async () => {
if (Constants.platform.ios) {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (status !== "granted") {
alert("Sorry, we need camera roll permissions to make this work!");
}
}
};
_pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3]
});
console.log(result);
if (result.cancelled) {
return;
}
if (!result.cancelled) {
this.setState({
image: result.uri
});
}
// ImagePicker saves the taken photo to disk and returns a local URI to it
let localUri = result.uri;
let filename = localUri.split("/").pop();
// Infer the type of the image
let match = /\.(\w+)$/.exec(filename);
let type = match ? `image/${match[1]}` : `image`;
var data = new FormData();
data.append("photo", {
image: localUri, // your file path string
image_tag: filename,
type
});
data.append("hh", "bb");
console.log(data);
fetch(`${ROOT_URL}/uploadImage.php`, {
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data"
},
method: "POST",
body: data
})
.then(response => response.text())
.then(responseJson => {
console.log(responseJson);
alert(responseJson);
})
.catch(error => {
console.error(error);
});
};
}
**This is php servlet file.**
<?php
// Importing DBConfig.php file.
include 'DBConfig.php';
// Creating connection.
$con = mysqli_connect($HostName,$HostUser,$HostPass,$DatabaseName);
//$json = file_get_contents('php://input');
// $obj = json_decode($json,true);
// Image uploading folder.
$target_dir = "uploads";
print_r($_POST);
exit;
// Generating random image name each time so image name will not be same .
$target_dir = $target_dir . "/" .rand() . "_" . time() . ".jpeg";
// Receiving image tag sent from application.
$img_tag = $_POST["photo"]["image_tag"];
if($image_tag!=""){
// Receiving image sent from Application
if(move_uploaded_file($_FILES['image']['tmp_name'], $target_dir)){
// Adding domain name with image random name.
$target_dir = $domain_name . $target_dir ;
// Inserting data into MySQL database.
//mysqli_query("insert into image_upload_table (image_tag, image_path) VALUES('$img_tag' , '$target_dir')");
$add = mysqli_query($con,"insert into image_upload_table (image_tag, image_path) VALUES('$img_tag' , '$target_dir')");
if($add){
echo json_encode("Image Uploaded Successfully."); // alert msg in react native
}
else{
echo json_encode('check internet connection'); // our query fail
}
}
}
?>
I expect form data with image details but this is what I got.
enter image description here
enter image description here

Angular/PHP: upload file data in $_POST, not $_FILES

I'm using AngularJS v1.6.1, Apache 2.4.10 on Debian with PHP 5.6.24 and I'm trying to upload a file to my server using $http POST service.
On my php.ini, max file size is set to 8Mo, max post size too, upload file is on, and memory size limit is set to 128Mo.
Form:
<input type="file" accept="application/pdf" id="uploadOT" max-files="1" ng-model="uploadOT" name="uploadOT" valid-file required ng-class="{'md-input-invalid':uploadForm.uploadOT.$error.validFile}" />
Angular directive: (when input content change, get a FileReader object and send file)
myModule.directive('validFile', function() {
return {
require: 'ngModel',
link: function(scope, elt, attrs, ctrl) {
ctrl.$setValidity('validFile', elt.val() !== '');
elt.bind('change', function() {
var file = document.getElementById('uploadOT').files;
var reader = new FileReader();
reader.onload = function(e) {
scope.sendFile(reader, scope.id);
};
scope.showUploadProgress = true;
scope.filename = file[0].name;
reader.readAsBinaryString(file[0]);
ctrl.$setValidity('validFile', elt.val() !== '');
scope.$apply(function() {
ctrl.$setViewValue(elt.val());
ctrl.$render();
});
});
}
};
});
Inside controller:
$scope.sendFile = function(reader, id) {
var fd = new FormData();
fd.append('id', id);
fd.append('file', reader.result);
fd.append('MAX_FILE_SIZE', 8 * 1024 * 1024);
$http.post('api/upload.php', fd, {
headers: {'Content-Type' : undefined },
transformRequest: angular.identity
}).then(function() {
alert('upload success');
}, function() {
$scope.showUploadError = true;
$scope.showUploadProgress = false;
$scope.postError = 'Une erreur inconnue est survenue !';
});
};
On server side (file api/upload.php), I print variables $_POST and $_FILES with print_r().
Why is $_FILES always empty, and my file data is in $_POST['file']?
I can create file from $_POST['file'] data with php function file_put_contents() but I cannot make verifications that I can make with $_FILES. Is it really important (security issues)?
If I change my POST Content-Type to multipart/form-data, the same thing happend.
I presume it's because you forgot to specify the encoding type of your form element.
enctype="multipart/form-data"
So, by default - the browser will assume that the form encoding type is "application/x-www-form-urlencoded" which does not support files in this way. You can still securely send file binary data with the stock encoding method however, this might be where performance and functionality are determining factors to which you choose. I recommend running some tests to confirm which is the fastest. In some cases, the difference will be negligible and will likely be for sake of consistency.
Skip the FileReader API and use the file object directly:
<input type=file files-input ng-model="files" ng-change="upload()" />
The filesInput Directive
angular.module("myApp").directive("filesInput", function() {
return {
require: 'ngModel',
link: function linkFn (scope, elem, attrs, ngModel) {
elem.on("change", function (e) {
ngModel.$setViewValue(elem[0].files, "change");
});
},
};
});
The upload() function
vm.upload = function() {
//var formData = new $window.FormData();
//formData.append("file-0", vm.files[0]);
var config = { headers: { "Content-Type": undefined } };
$http.post(url, vm.files[0], config)
.then(function(response) {
vm.result = "SUCCESS";
}).catch(function(response) {
vm.result = "ERROR "+response.status;
});
};
The XHR API send() method can post either a file object or a FormData object. It is more efficient to send the file object directly as the XHR API uses base64 encoding for the FormData object which has a 33% overhead.
The DEMO on PLNKR.
To make it works, I had to do these modifications:
Directive:
myModule.directive('validFile', function() {
return {
require: 'ngModel',
link: function(scope, elt, attrs, ctrl) {
ctrl.$setValidity('validFile', elt.val() !== '');
elt.bind('change', function() {
var file = document.getElementById('uploadOT').files;
var reader = new FileReader();
reader.onload = function(e) {
scope.sendFile(file[0], scope.OT); ////CHANGE HERE
};
scope.showUploadProgress = true;
scope.filename = file[0].name;
reader.readAsArrayBuffer(file[0]); ////CHANGE HERE
ctrl.$setValidity('validFile', elt.val() !== '');
scope.$apply(function() {
ctrl.$setViewValue(elt.val());
ctrl.$render();
});
});
}
};
});
Inside Controller
$scope.sendFile = function(file, id) {
var fd = new FormData();
fd.append('id', id);
fd.append('file', file);
fd.append('MAX_FILE_SIZE', 8 * 1024 * 1024);
$http({
method: 'POST',
url: 'upload.php',
data: fd,
headers: {'Content-Type': undefined, 'Process-Data': false},
transformRequest: angular.identity
}).then( function() {
console.log('success');
}, function() {
console.log('failure');
});
};

Uploading camera image to server using phonegap/cordova and access the data returned by server

I am new to phone gap/cordova and PHP. I created a phone gap/cordova application to upload camera taken image to server.The server uniquely renames the image according to some timestamp code and it has to return that image name back to the app.I have pretty well uploaded the image but I need to retrieve back that image name data echoed back by the server.On success upload, when I tried to alert the data that is returned back by the server, it is alerting [object object].I need to retrieve the value.How can it be possible.My code at the client side is given below.
var pictureSource; // picture source
var destinationType; // sets the format of returned value
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
function clearCache() {
navigator.camera.cleanup();
}
var retries = 0;
function onCapturePhoto(fileURI) {
var win = function (r) {
clearCache();
retries = 0;
alert('Done! message returned back is '+r);
}
var fail = function (error) {
if (retries == 0) {
retries ++
setTimeout(function() {
onCapturePhoto(fileURI)
}, 1000)
} else {
retries = 0;
clearCache();
alert('Ups. Something wrong happens!');
}
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
var params=new param();
param.client_device_id=device.uuid;
options.params = params; // if we need to send parameters to the server request
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://host/upload.php"), win, fail, options);
}
function capturePhoto() {
navigator.camera.getPicture(onCapturePhoto, onFail, {
quality: 100,
destinationType: destinationType.FILE_URI
});
}
function onFail(message) {
alert('Failed because: ' + message);
}
The code for the upload.php is given below
<?php
if (!file_exists($_POST["client_device_id"])) {
mkdir($_POST["client_device_id"], 0777, true);
}
$date = new DateTime();
$timeStamp=$date->getTimestamp() -1435930688;
move_uploaded_file($_FILES["file"]["tmp_name"], 'f:\\xampp\\htdocs\\FileUpload\\'.$_POST["client_device_id"]."\\".$timeStamp.'.jpg');
echo $timeStamp.".jpg";
?>
The problem is that after successful upload in the device it is alerting 'Done! message returned back is [object object]'.I need to get the value.Please help me on it.
I figured out the answer myself.Just want to share with you all.I used alert(JSON.stringify(r)).Now I know the format of the returned json object .Knowing that I have easily printed out the image name.r.response helped me retrieve the generated image name.

Categories