Input Image File in VueJs + SlimPHP - javascript

I am new in VueJs, I want to input image file and some text using vuejs for creating new user. So far, I already make the base64 image, but I don't know how to pass this base64 image to the slim code in the server.
Here is my vue code:
Input File
<input class="file-input" type="file" name="userPhoto" #change="uploadPhoto">
Method :
uploadPhoto: function(e){
var reader = new FileReader()
reader.readAsDataURL(e.target.files[0])
reader.onload = (e) => {
this.usr.user_photo = e.target.result
}
}
Post :
console.log(this.usr);
this.$http.post('MyAPI', this.usr)
.then(function(response){
this.$router.push({path: '/'});
}
console.log output this object :
Image
and here is my code in slim post request
$app->post('/api/user/add', function(Request $request, Response $response){
//Upload Files
$directory = $this->get('upload_directory');
$uploadFiles = $request->getUploadedFiles();
$uploadedFile = $uploadFiles['userPhoto'];
if($uploadedFile->getError() === UPLOAD_ERR_OK){
$filename = moveUploadedFile($directory,$uploadedFile);
$response->write('Uploaded '.$filename.'<br/>');
}
function moveUploadedFile($directory, UploadedFile $uploadedFile){
$extension = pathinfo($uploadedFile->getClientFilename());
$basename = bin2hex(random_bytes(8));
$filename = sprinf('%s.%0.8s',$basename, $extension);
$uploadedFile->moveTo($directory.'/'.$filename);
return $filename;
}
$user_id = $request->getParam('user_id');
$password = $request->getParam('password');
$name = $request->getParam('name');
$status = $request->getParam('status');
$prodi = $request->getParam('prodi');
$social_link = $request->getParam('social_link');
$sql = "INSERT INTO user
VALUES (:user_id,:password,:name,:status,:prodi,CURRENT_TIMESTAMP(),'$filename',:social_link)";
try{
// Get DB Object
$db = new db();
// Connect
$db = $db->connect();
$stmt = $db->prepare($sql);
$stmt->bindParam(':user_id', $user_id);
$stmt->bindParam(':password', $password);
$stmt->bindParam(':name', $name);
$stmt->bindParam(':status', $status);
$stmt->bindParam(':prodi', $prodi);
$stmt->bindParam(':social_link', $social_link);
$stmt->execute();
echo '{"notice" : {"text": "User Added"}}';
} catch(PDOException $e){
echo '{"Error": {"text": }'.$e->getMessage().'}';
}
});
I already try using resteasy and copy paste all object inside the "usr", but i got this error :
500 Internal Server Error
Can someone tell me how to do this? thanks

Your ajax request contains the image data within a json encoded attribute "user_photo" in form of a Data URI scheme.
This is not a "classic" file upload, so this code won't work like expected.
$uploadFiles = $request->getUploadedFiles();
Instead you may try to read the data URI from the json data.
$userPhoto = $request->getParam('user_photo');
Then try to decode the data URI string and save it as file.
$userPhoto = str_replace("\n", "", $userPhoto);
$userPhotoData = substr($userPhoto, strpos($userPhoto, ',') + 1);
// Decode the base64 string
$userPhotoData = base64_decode($userPhotoData);
// Save the file
file_put_contents('filename.jpg', $userPhotoData);
Notice: Never use echo in Slim. Use the response object instead.
$result = [
'notice' => [
'text' => 'User Added'
]
];
return $response->withJson($result);

Related

Imagick format conversion

I am trying to create thumbnails from pdf uploads using Imagick. I wrote a script that's supposed to do it, but, it only uploads the file without creating a thumbnail.
This will certainly make some of you roll your eyes, but, PHP is completely uncharted territory to me. Could anyone help me out? Thanks!
<?php
include 'includes/session.php';
include 'includes/slugify.php';
if(isset($_POST['add'])){
$name = $_POST['name'];
$slug = slugify($name);
$category = $_POST['category'];
$price = $_POST['price'];
$description = $_POST['description'];
$filename = $_FILES['photo']['name'];
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
$allowed = array('pdf', 'doc', 'docx', 'odc', 'jpg');
$conn = $pdo->open();
$stmt = $conn->prepare("SELECT *, COUNT(*) AS numrows FROM products WHERE slug=:slug");
$stmt->execute(['slug'=>$slug]);
$row = $stmt->fetch();
if($row['numrows'] > 0){
$_SESSION['error'] = 'document already exists';
}
else{
if(!in_array($ext, $allowed)) {
$_SESSION['error'] = 'Filetype not allowed';
}
else{
if(!empty($filename)){
$new_filename = $slug.'.'.$ext;
copy($_FILES['photo']['tmp_name'], '../documents/'.$new_filename);
}
else{
$new_filename = '';
creating a thumbnail
$img = new Imagick($filename[0]);
$img-> setImageFormat('jpg');
$convert = $slug. '.' .$jpg;
$img-> writeImages($_FILES['photo']['tmp_name'], '../images/'.$convert);
}
try{
$stmt = $conn->prepare("INSERT INTO products (category_id, name, description,
slug, price, photo) VALUES (:category, :name, :description, :slug, :price, :
photo)");
$stmt->execute(['category'=>$category, 'name'=>$name,
'description'=>$description,
'slug'=>$slug, 'price'=>$price, 'photo'=>$new_filename]);
$_SESSION['success'] = 'document added successfully';
}
catch(PDOException $e){
$_SESSION['error'] = $e->getMessage();
}
}
}
$pdo->close();
}
else{
$_SESSION['error'] = 'Fill up product form first';
}
header('location: documents.php');
?>
It looks like your call to $img->writeImages($_FILES['photo']['tmp_name'], '../images/'.$convert) is incorrect: you're passing two strings (the filename of an uploaded image and what looks like a destination filename) but the Imagick documentation indicates you should be passing only a destination filename (along with an optional Boolean).
So this:
$img-> writeImages($_FILES['photo']['tmp_name'], '../images/'.$convert);
Should probably be:
$img-> writeImages('../images/'.$convert);
Also, it's hard to tell whether the two chunks of PHP that you posted come one after the other, but if they do, then your logic for when to create the images looks faulty:
if(!empty($filename)){
// Do some stuff
} else {
// Write the images
}
The problem here is that the block of code that writes the images only executes when $filename is empty. Shouldn't it write the images if $filename is not empty?
Last but not least, the Imagick writeImages() function returns a Boolean indicating whether it was successful. You should store this result and log it to see what the result is. You should also confirm that your destination filename ('../images/'.$convert) is correct, and that the path exists and is writable.

How to save PDF from base64 in database with url?

I'm generating PDF of html table. I want to save pdf in database. This script is downloading pdf. I want to send pdf file to controller side then save in database. I'm getting base64 string in controller now how i can save and retrieve with url?
var doc = new jsPDF({
unit: 'px',
format: 'a4'
});
doc.fromHTML($('#revision_table').get(0), 2, 2);
doc.save('scdedule_revision.pdf');
var pdf = doc.output();
axios.post(this.$path + 'api/savePdf', null,
{
params: {'pdf_file': doc.output('datauri')}
}
).then(({data}) => (
console.log(data)
))
.catch(error => console.log(error));
Controller:
public function savePdf(Request $request)
{
$destinationPath = 'users/pdf';
$fileuploadedpath = '';
$pdf = $request->get('pdf_file');
if ($pdf != '') {
$extension = $pdf->getClientOriginalExtension();
$fileName = rand(11111, 99999) . '.' . $extension;
$success[0] = $pdf->move($destinationPath, $fileName);
$fileuploadedpath = url($destinationPath . "/" . $fileName);
}
dd($fileuploadedpath);
}
Try this
$data = file_get_contents('string path file');
$content = base64_decode($data);
for storing the base64 into the database you need to simply store the base64 string to database column form controller
$b64Doc = base64_encode(file_get_contents($this->pdfdoc));
Now for decoding the file use the file all you need to fetch the base64 data form table and then use code below to get the PDF again
// a route is created.
$route = "pdf/".$name;
// decode base64
$pdf_b64 = base64_decode($base_64);
// you record the file in existing folder
if(file_put_contents($route, $pdf_b64)){
//just to force download by the browser
header("Content-type: application/pdf");
//print base64 decoded
echo $pdf_b64;
}

Uploading Picture Is Corrupted

I am trying to allow users to upload a new profile pic by clicking on the old one.
I am using ajax and a file reader to do so
$('#profileImage').click(function(){ $('#image-file').trigger('click'); });
$('#image-file').on('change',function(){
if (this.files && this.files[0]) {
var FR= new FileReader();
FR.readAsDataURL(this.files[0]);
FR.addEventListener("load", function(e) {
document.getElementById("profileImage").src = e.target.result;
imgData = e.target.result;
var formData = {
'name' : localStorage.getItem('email'),
'image' : imgData
};
console.log("image data: " + imgData);
$.ajax({
type : 'POST',
url : '/uploadprofile.php',
data : formData,
dataType: 'text',
encode : true
}).done(function(data) {
console.log(data);
});
});
}
});
The new image is loaded onto the old picture and the console tracks the image data sent through.
The only issue is that the newly updated picture is not visible to the container. It shows an icon of a broken picture.
This is my php file that handles the insertion
$json = json_decode(file_get_contents('php://input'),true);
if ($json == "") {
$name = $_POST['name'];
$image = $_POST['image'];
} else {
$name = $json["name"]; //within square bracket should be same as Utils.imageName & Utils.image
$image = $json["image"];
}
$response = array();
$decodedImage = base64_decode("$image");
//unlink old picture
// unlink($name.".jpg");
$oldName = $name;
$name .= date("D M d Y G:i");
$name = str_replace(' ', '', $name);
$fullPath = "http://www.mywebsite.com/uploads/".$name.".jpg";
$return = file_put_contents("uploads/".$name.".jpg", $decodedImage);
if($return !== false){
$response['email'] = $oldName;
$response['image'] = $image;
$response['success'] = 1;
$response['message'] = "Image Uploaded Successfully";
$sql = "UPDATE Users SET PicLocation = '$fullPath' WHERE Email = '$oldName'";
$result = $conn->query($sql);
}else{
$response['success'] = 0;
$response['message'] = "Image Uploaded Failed";
}
echo json_encode($response);
The value for $response['image'] that gets printed out is correct but it doesn't seem to show the picture. The data is corrupted somehow. Is there something I should do to get the correct data?
Additionally, sometimes I get the error:
jquery.min.js:2 POST http://tanglecollege.com/uploadprofile.php 406 (Not Acceptable)
I don't know what it means and there doesn't seem to be a good explanation.
Also, the file that gets saved to the server is corrupted in some way. I can track the base64 data being passed along from js to php but when it is saved as a file, that file is corrupted and the image can not be read from the filepath.

Slim 3 returns array(0) for getUploadedFiles() when trying to perform POST request from web page

I am trying to perform a Post request to store some dummy data to my database. The data set consist of three text fields and a file.
Following the Slim 3 File Upload Documentation I created my service which works perfectly.
Here's my service code:
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
use Slim\Http\UploadedFile;
$container = $app->getContainer();
$container['upload_directory'] = __DIR__ . '/uploads/';
$app->post('/np/register',function(Request $request, Response $response){
$np_name = $request->getParam('np_name');
$np_language = $request->getParam('np_language');
$uploadedFiles = $request->getUploadedFiles();
$upload_folder = '/uploads/';
$directory = $this->get('upload_directory');
$np_image_path = $uploadedFiles['np_image_path'];
$np_active_status = $request->getParam('np_active_status');
$register_date = date('Y/m/d H:i:s');
//Getting the server ip
$server_ip = gethostbyname(gethostname());
try
{
$np_name_check = preg_match('~^[A-Za-z ]{3,20}$~i', $np_name);
$np_language_check = preg_match('~^[A-Za-z_]{3,20}$~i', $np_language);
$np_active_status_check = preg_match('/^[0-1]{1}$/', $np_active_status);
if($np_name_check>0 && $np_language_check>0 && $np_active_status_check>0 && isset($np_name) && isset($np_language) &&
isset($np_active_status) && isset($np_image_path))
{
$get_filename = moveUploadedFile($directory, $np_image_path);
$ServerURL = 'http://'.$server_ip.'/np_console/src/routes'.$upload_folder.$get_filename;
$np_image_path = $ServerURL;
$sql = "INSERT INTO np_registration (np_name,np_language,np_image_path,np_active_status,np_register_date) VALUES (:np_name,:np_language,:np_image_path,:np_active_status,:register_date)";
try
{
//Get DB Object
$db = new db();
//Connect to database
$db = $db->connect();
$stmt = $db->prepare($sql);
$stmt->bindParam(':np_name', $np_name);
$stmt->bindParam(':np_language', $np_language);
$stmt->bindParam(':np_image_path', $np_image_path);
$stmt->bindParam(':np_active_status', $np_active_status);
$stmt->bindParam(':register_date', $register_date);
$stmt->execute();
echo '{"notice":{"respnse":"NetPicks Added Successfully"}';
}
catch(PDOException $e)
{
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
}
else{
echo '{"error":{"respnse":"\nInvalid Data Entry"}';
}
}
catch(PDOException $e) {
echo '{"error":{"text":'. $e->getMessage() .'}}';
}
});
function moveUploadedFile($directory, UploadedFile $uploadedFile)
{
$extension = pathinfo($uploadedFile->getClientFilename(), PATHINFO_EXTENSION);
$basename = bin2hex(random_bytes(8));
$filename = sprintf('%s.%0.8s', $basename, $extension);
$uploadedFile->moveTo($directory . DIRECTORY_SEPARATOR . $filename);
return $filename;
}
?>
My Post request via Postman works as required and I am able to insert values to my db.
Postman Response
But when I try to perform the POST request from my web page it fails. On using the var_dump I found out that $uploadedFiles always returns array(0).
Post Service call:
export default function NP_Registration_Service(type, np_name, np_language, np_image_path, np_active_status){
let BaseUrl = 'http://localhost/np_console/public/index.php';
let formData = new FormData();
formData.append('np_name', np_name);
formData.append('np_language', np_language);
formData.append('np_image_path', np_image_path);
formData.append('np_active_status', np_active_status);
return new Promise((resolve,reject) => {
fetch(BaseUrl+type,{
method: 'POST',
body: formData
})
.then((response) => {
var resText = response.text();
console.log("The resText");
console.log(resText);
})
.catch((error) => {
reject(error);
});
});
}
Here's the response with var_dump($uploadedFiles) which returns array(0).
Console Output
I have looked into this but it didn't provide any help.
So am I making a mistake with the service call?
As suggested by Karol Samborski adding
var fileField = document.querySelector("input[type='file']");
formData.append('np_image_path', fileField.files[0]);
to the Post service call(fetch request) resolved the issue.

using phpfile output inside js file file as variable

Recently I am learning single page application, but I got a problem, the project I am working on is inside a folder that contain many folders, php js are folders in side the main folder, and each contain its type of files, the problem is that one of the php file called getmax.php gives me the maximum id ,I want to use this max(id) in a js file called module.js in order to give the new module the next id , the module.js should gives this id to another php file called insert.php ,the connection between the module.js and insert.php is working properly if I set the id manually . but I could not figure out how can I make it use the max(id) from the getmax.php file.
note: I noticed lately I'm using MySQL and I should used mysqli I will fix it later.
the getmax.php is:
<?php
// alle relevanten Tabellen abfragen und als json zurückgeben.
$json["status"] = "running";
$details[] = "started get_tables ";
// Include confi.php
include_once('confi.php');
//var_dump($_POST);
$request_body = file_get_contents('php://input');
// first store the given set of data to keep it for future analysis
$statement = "INSERT INTO tbl_archive (content) VALUES ('$request_body' );";
mysql_query($statement);
$input = json_decode($request_body, true);
// now check if valid user
$user = $input["user"];
$username = $user["username"];
$password = $user["password"];
if($password and $username){
$mySQLstring = "SELECT username, password, id, create_user FROM tbl_user where username = '$username' ;";
$json["statement"][] = $mySQLstring;
$qur = mysql_query($mySQLstring);
//var_dump ( $qur );
if ($qur){
$max = mysql_fetch_assoc($qur);
}
if ($max){
$json["max"] = $max;
if ($max["password"] == $password){
$json["username"] = $username;
$json["id"] = $max["id"];
$json["create_user"] = $max["create_user"];
$json["status"] = "ok";
$tables = array("class", "class_user", "module", "module_class", "module_user", "rating", "student", "student_class");
//$tables = array("class");
foreach($tables as $table){
if ( $table == 'module' ){
$statement ='SELECT create_user, MAX(id) FROM tbl_'.$table;
//$statement .= ' GROUP BY create_user' ;
$statement .= ' WHERE create_user = 19 ' ;
$qur = mysql_query($statement);
if ($qur){
while($r = mysql_fetch_array($qur, MYSQL_ASSOC)){
//var_dump($r);
//echo (json_encode($r));
$result[$table][] = $r;
}
}
}
}
$json = array("status" => "ok", "data" => $result);
}
}
}
#mysql_close($conn);
/* Output header */
header('Content-type: application/json');
echo json_encode($json);
?>
PHP and JS are run on the server and client respectively, and as such you cannot call methods/functions of one from the other. AJAX exists to pass values between JS and serverside code.

Categories

Resources