I posted about this issue not that long ago, and I thought I had figured it out but nothing is happening.
Issue: I am trying to generate a PDF file that captures the signature of a client. Essentially they type in their name in a box and that name gets displayed in the pdf.php file along with all the other information(e.g. date, terms & conditions etc..).
I created a class that extends from FPDF and though JavaScript I am sending the name that gets filled and it gets processed through that pdf.php file and should return a "signed" pdf file.
However my pdf file is not downloading, saving or any of the options (I, D, F, S).
Below is a snippet of that section in my code.
pdf.php
$tempDir = "C:/PHP/temp/";
$thisaction = filter_input(INPUT_POST, 'action', FILTER_SANITIZE_STRING);
$answers = filter_input(INPUT_POST, 'encFormData');
$decFD = json_decode($answers);
$pdf = new WaiverFPDF();
// Pull values from array
$returnVals = array();
$returnVals['result'];
$returnVals['html'] = '';
$returnVals['errorMsg'] = '';
//the name of the person who signed the waiver
$name = $decFD->signWaiver;
$today = date('m/d/Y');
if($thisaction == 'waiverName'){
// Generate a new PDF
$pdf = new WaiverFPDF();
$pdf->AddPage()
$pdfFile = "Waiver". $name . ".pdf";
....
// Output form
$pdf->Write(8, 'I HEREBY ASSUME ALL OF THE RISKS...');
// Line Break
$pdf-> all other info...
$outFile = $tempDir . $pdfFile;
//output pdf
$pdf->Output('D', $pdfFile);
$returnVals['result'] = true;
}
else{
$returnVals['errorMsg'] = "There was an error in waiver.php";
$returnVals['result'] = false;
}
echo json_encode($returnVals);
?>
.js file (JSON)
function sendWaiver(){
var formHash = new Hash();
formHash.signWaiver = $('signWaiver').get('value');
console.log ("name being encoded");
waiverNameRequest.setOptions({
data : {
'encFormData' : JSON.encode(formHash)
}
}).send();
return true;
}
waiverNameRequest = new Request.JSON({
method : 'post',
async : false,
url : 'pdf.php',
data : {
'action' : 'waiverName',
'encFormData' : ''
},
onRequest : function() {
// $('messageDiv').set('html', 'processing...');
console.log("waiver onRequest");
},
onSuccess : function(response) {
$('messageDiv').set('html', 'PDF has been downloaded');
if (response.result == true) {
console.log('OnSuccess PDF created');
} else {
$('messageDiv').set('html', response.errorMsg);
console.log('PDF error');
}
}
});
I know my error handling is very simple, but all I am getting is success messages, but no generated pdf file... I'm not sure what i am doing wrong. I also made sure the file (when i save to a file) is writable.
class_WaiverFPDF.php
class WaiverFPDF extends FPDF
{
// Page header
function Header()
{
// Arial bold 15
$this->SetFont('Arial','B',12);
// Position XY X=20, Y=25
$this->SetXY(15,25);
// Title
$this->Cell(179,10, 'Accident Waiver ','B','C');
// Line break
$this->Ln(11);
}
// Page footer
function Footer()
{
// Position from bottom
$this->SetY(-21);
// Arial italic 8
$this->SetFont('Arial','I',8);
$this->Ln();
// Current date
$this->SetFont('Arial','I',8);
// $this->Cell(179,10,$today,0,1,'R',false);
// $today= date('m/d/Y');
$this->Cell(115,10,' Participant Name',0,0,'C');
$this->Cell(150,10,'Date',0,'C',false);
// Page number
//$this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');
}
}
Related
I have an HMTL form with 3 fields on it, Firstname, Lastname and image upload file. When submit is pressed it calls the following JS script.
//main function to be called on submit
function processData() {
var firstName = document.querySelector('#first-name'),
lastName = document.querySelector('#last-name'),
imageUser = document.querySelector('#image-user');
var formSubmitData = {
'firstName': firstName.value,
'lastName': lastName.value,
'imageUser': imageUser.value
};
var dataString = JSON.stringify(formSubmitData);
if (navigator.onLine) {
sendDataToServer(dataString);
} else {
saveDataLocally(dataString);
}
firstName.value = '';
lastName.value = '';
imageUser.value = '';
}
//called on submit if device is online from processData()
function sendDataToServer(dataString) {
var myRequest = new XMLHttpRequest();
//new code added so data is sent to server
//displays popup message - data sent to server
myRequest.onreadystatechange = function() {
if (myRequest.readyState == 4 && myRequest.status == 200) {
console.log('Sent to server: ' + dataString + '');
window.localStorage.removeItem(dataString);
} else if (myRequest.readyState == 4 && myRequest.status != 200) {
console.log('Server request could not be completed');
saveDataLocally(dataString);
}
}
myRequest.open("POST", "write_test.php", true);
//Send the proper header information along with the request
myRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
myRequest.send(dataString);
alert('Sent: ' + dataString + ''); //remove this line as only for example
}
As you will see it sends a POST request to the php page. The "datastring" is encoded as JSON.
I use the following PHP code to send the data to the SQL server, but all it does is create a blank record with no data but it does create a new record.
<?php
//TRYING NEW CODE TO EXTRACT DATA FROM dataString
$json = json_decode(file_get_contents("php://input"), true);
$data = json_decode($json, true);
echo '<pre>' . print_r($data, true) . '</pre>';
// INSERT into your contact table.
$sql="INSERT INTO contacts (firstName, lastName)VALUES('$firstName','$lastName')";
How do I get it to create records in SQL with data that has been submitted from the form??
I have no final solution as I don't have the form code. Hope you are ready to learn.
I'm worried about user image - don't send any image for testing, but a string (like path) or nothing, please.
js - change for double quotes:
var formSubmitData = {
"firstName" : firstName.value,
"lastName" : lastName.value,
"imageUser" : imageUser.value
};
php - leave only this
<?php
$data = json_decode(file_get_contents("php://input")); // test only version
print_r($data); // test only version
/*
and close the rest as a comment - SQL is fine, don't worry
$data = json_decode(file_get_contents("php://input",true)); // final ver
echo print_r($data, true); // final ver
...
*/
If you receive the right output, delete the trial version and good luck.
If not - go back to var formSubmitData to the values on the right - they are so naked ... without any quotes
And of course, take care of security (injection) and order, set the required at the inputs - you don't need empty submits
Good Day. Please, I need your assistance. Building a laravel website in which tinymce is/was implemented in a some textareas. The challenge is that if images are uploaded in the editor, they are stored as base64 encoding. This slows down the server. I had to change my data type to longtext in my database. How do I store the images instead of base64? And how do I read the stored images.
My codes are shown below
My Controller
public function create(Request $request){
$categories = BlogCategory::all();
$tags = Tag::all();
if($request->isMethod('post')){
//dd($request);
$data = $request->except('name');
$post = new Post;
//Title
$post->title = $request->title;
//Slug
$post->publish_date = new Carbon;
$slug = $this->createSlug($request->title);
$post->slug = $slug;
//Category
if($request->category_id == "Choose Category")
{
Session::flash('failure','Please Select A Category To Proceed!');
return redirect()->back();
}else{
$post->category_id = $request->category_id;
}
//Body
$post->body = $request->body;
//Author
if(isset($request->author)){
$post->author = $request->author;
$post->author_slug = Str::slug($post->author,'-');
}else{
$post->author = "";
$post->author_slug = "";
}
//User ID
$post->user_id = Auth::user()->id;
//Keywords
if(isset($request->keywords)){
$post->keywords = $request->keywords;
}else{
$post->keywords = "";
}
//Description
if(isset($request->description)){
$post->description = $request->description;
}else{
$post->description = "";
}
//Publish
if(isset($request->publish)){
if($request->publish == 'draft'){
$post->publish = 0;
}elseif($request->publish == 'publish'){
$post->publish = 1;
$post->publish_date = new Carbon;
}
}
//Comment
if(isset($request->comments)){
if($request->comments = "on"){
$post->comment = 1;
}
}
//Image
if($request->hasFile('image')){
$img_temp = $request->file('image');
if($img_temp->isValid()){
$extension = $img_temp->getClientOriginalExtension();
$filename = 'mohvisuals'.rand(111,9999).'.'.$extension;
$large_image_path = 'images/backend_images/posts/large/'.$filename;
$medium_image_path = 'images/backend_images/posts/medium/'.$filename;
//Resize Images
Image::make($img_temp)->save($large_image_path);
Image::make($img_temp)->fit(500,400)->save($medium_image_path);
//Store Images
$post->image =$filename;
}
}
$post->save();
$post->tags()->sync($request->tags,false);
Session::flash('success',' Post Created Successfully!');
return redirect()->back();
}
return view('back_end.blog.posts.create')->with(compact('categories','tags'));
}
Your title/description says something, but your code says something else.
To store the file in database, the column type must be BINARY/BLOB.
To store the filename in database and the file on disk, colum type should be VARCHAR relative to the maximum filename length.
Do not convert files to base64 unless they're small, as their size will increase around x3 times.
To store file in database you can use this code. Inside your controller:
if ($request->hasFile('file'))
{
// If you want to resize the image, use the following method to get temporary file's path.
$request->file('file')->getPathName();
// `get()` retrieves file's content in binary mode
$post->image = request->file('file')->get();
}
I am uploading a csv file and sending it to page to process using the js fetch api. I have session included using my init file and all works well accept for the page that should process to file info. Without including the session it works fine and I can process the file, when including it, I can see al the session info, but $_FILES just stops working, I can't see any of the info for some reason.
I really hope this is something stupid
Some code if needed
The init file
<?php
//define Site Root and Includes Path
defined('DS') ? null : define('DS', DIRECTORY_SEPARATOR);
defined('SITE_ROOT') ? null : define('SITE_ROOT', __DIR__ . DS );
defined('INCLUDES_PATH') ? null : define('INCLUDES_PATH', SITE_ROOT);
//get class files
include(INCLUDES_PATH.DS."Session.php");
require_once(INCLUDES_PATH.DS."functions.php");
require_once(INCLUDES_PATH.DS."DB.php");
require_once(INCLUDES_PATH.DS."Validation.php");
require_once(INCLUDES_PATH.DS."User.php");
require_once(INCLUDES_PATH.DS."Swp.php");
require_once(INCLUDES_PATH.DS."Incident.php");
require_once(INCLUDES_PATH.DS."Hira.php");
require_once(INCLUDES_PATH.DS."Mail.php");
The Session.php page
<?php
class Session
{
private $logged_in;
public $user_id;
function __construct()
{
session_start();
$this->check_login();
}
public function is_logged_in() {
return $this->logged_in;
}
private function check_login() {
if (isset($_SESSION['UserID'])) {
$this->user_id = $_SESSION['UserID'];
$this->logged_in = true;
} else {
unset($this->user_id);
$this->logged_in = false;
}
}
}
$session = new Session();
The form page
<?php
//get all the includes
require_once("../php_functions/_init.php");
print_r($_FILES);
//all rows from csv file
$rows = array_map('str_getcsv', file($_FILES['file']['tmp_name'][0]));
//get only the headers
$header = array_shift($rows);
//declare the array
$csv = array();
//create associative array using array_combine
foreach ($rows as $row) {
$csv[] = array_combine($header, $row);
}
print_r($csv);
like I mentioned if I removed the require once from this page it works as expected. Any ideas would help
Just in case you need it here is the js for uploading the file
document.querySelector("#upload_file").addEventListener("click", function () {
const url = 'php/employee/upload_employee_csv_form.php';
const files = document.querySelector('[type=file]').files;
const formData = new FormData();
for (let i = 0; i < files.length; i++) {
let file = files[i];
formData.append('file[]', file);
}
console.log(formData);
fetch(url, {
method: 'POST',
body: formData
}).then(response => {
console.log(response);
});
});
I actually figured it out. So my session was being included before I actually added it, to fix this instead of just saying session_start I check to see if the session is there and then only start if necessary.
The code
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
Bonus tip :-)
The above code will work for php 5.4 and up if you are running something lower than 5.4 you can do the following:
if(session_id() == '') {
session_start();
}
Hope this helps
Alright, So I have this script that uploads a file on drag and drop from the browser using HTML5.
$(function(){
var dropbox = $('#dropbox'),
message = $('.message', dropbox);
dropbox.filedrop({
// The name of the $_FILES entry:
paramname:'pic',
maxfiles: 50,
maxfilesize: 50,
url: 'post_file.php',
uploadFinished:function(i,file,response){
$.data(file).addClass('done');
// response is the JSON object that post_file.php returns
},
error: function(err, file) {
switch(err) {
case 'BrowserNotSupported':
showMessage('Your browser does not support HTML5 file uploads!');
break;
case 'TooManyFiles':
alert('Too many files! Please select 20 at most! (configurable)');
break;
case 'FileTooLarge':
alert(file.name+' is too large! Please upload files up to 10mb (configurable).');
break;
default:
break;
}
},
//// Called before each upload is started
// beforeEach: function(file){
// if(!file.type.match(/^image\//)){
// alert('Only images are allowed!');
//
// // Returning false will cause the
// // file to be rejected
// return false;
// }
// },
uploadStarted:function(i, file, len){
createImage(file);
},
progressUpdated: function(i, file, progress) {
$.data(file).find('.progress').width(progress);
}
});
var template = '<div class="preview">'+
'<span class="imageHolder">'+
'<img />'+
'<span class="uploaded"></span>'+
'</span>'+
'<div class="progressHolder">'+
'<div class="progress"></div>'+
'</div>'+
'</div>';
function createImage(file){
var preview = $(template),
image = $('img', preview);
var reader = new FileReader();
image.width = 100;
image.height = 100;
reader.onload = function(e){
// e.target.result holds the DataURL which
// can be used as a source of the image:
image.attr('src',e.target.result);
};
// Reading the file as a DataURL. When finished,
// this will trigger the onload function above:
reader.readAsDataURL(file);
message.hide();
preview.appendTo(dropbox);
// Associating a preview container
// with the file, using jQuery's $.data():
$.data(file,preview);
}
function showMessage(msg){
message.html(msg);
}
});
It runs on with the following post_file.php
<?php
// If you want to ignore the uploaded files,
// set $demo_mode to true;
$demo_mode = false;
$upload_dir = 'uploads/';
//$allowed_ext = array('jpg','jpeg','png','gif','doc','docx','pdf','xls','xlsx','pptx','ppt','rtf','txt','mp4','css','rar','zip','exe','mp3','wav');
if(strtolower($_SERVER['REQUEST_METHOD']) != 'post'){
exit_status('Error! Wrong HTTP method!');
}
if(array_key_exists('pic',$_FILES) && $_FILES['pic']['error'] == 0 ){
$pic = $_FILES['pic'];
//if(!in_array(get_extension($pic['name']),$allowed_ext)){
// exit_status('Only '.implode(',',$allowed_ext).' files are allowed!');
//}
if($demo_mode){
// File uploads are ignored. We only log them.
$line = implode(' ', array( date('r'), $_SERVER['REMOTE_ADDR'], $pic['size'], $pic['name']));
file_put_contents('log.txt', $line.PHP_EOL, FILE_APPEND);
exit_status('Uploads are ignored in demo mode.');
}
// Move the uploaded file from the temporary
// directory to the uploads folder:
if(move_uploaded_file($pic['tmp_name'], $upload_dir.$pic['name'])){
exit_status('File was uploaded successfuly!');
}
}
exit_status('Something went wrong with your upload!');
// Helper functions
function exit_status($str){
echo json_encode(array('status'=>$str));
exit;
}
function get_extension($file_name){
$ext = explode('.', $file_name);
$ext = array_pop($ext);
return strtolower($ext);
}
?>
Now the problem is I have a certain JSON url that when I open it sends a text message to a certain number. I'm trying to append that URL somewhere in the script so that it runs that url everytime an upload is made.
Any ideas?
$URL = "http://www.api.com/api.php?data=mydata";
$data = file_get_contents($URL);
This solves it.
My goal is to upload some images to a server and provide them with a description.
On clicking an upload button, this is what I want to happen:
1) a javascript function dynamically adds a form to get a description
of the images.
2) on submitting the form:
a) the description entered in the form must be available $_POST['description'] at server side.
b) the images are sent to the server using an XMLHttpRequest
In the code I wrote the description is not available $_POST['description'].
When i remove the check if(!isset($_POST['description'])), the imagefiles are perfectly uploaded.
This is my code:
javascript code
upload.onclick = uploadPrompt;
// dynamically add a form
function uploadPrompt () {
// fileQueue is an array containing all images that need to be uploaded
if (fileQueue.length < 1) {
alert("There are no images available for uploading.");
} else {
var inputDescription = document.createElement("input");
inputDescription.className = "promptInput";
inputDescription.type = "text";
inputDescription.name = "description";
var inputButton = document.createElement("button");
inputButton.id = "promptInputButton";
inputButton.type = "submit";
inputButton.innerHTML = "Start uploading";
var promptForm = document.createElement("form");
promptForm.method = "post";
promptForm.action = "upload.php";
promptForm.onsubmit = uploadQueue;
promptForm.id = "promptForm";
promptForm.appendChild(inputDescription);
promptForm.appendChild(inputButton);
document.body.appendChild(promptForm);
}
}
function uploadQueue(ev) {
ev.preventDefault();
elementToBeRemoved = document.getElementById("promptForm");
elementToBeRemoved.parentElement.removeChild(elementToBeRemoved);
while (fileQueue.length > 0) {
var item = fileQueue.pop();
// item.file is the actual image data
uploadFile(item.file);
}
}
function uploadFile (file) {
if (file) {
var xhr = new XMLHttpRequest();
var fd = new FormData();
fd.append('image',file);
xhr.upload.addEventListener("error", function (ev) {
console.log(ev);
}, false);
xhr.open("POST", "upload.php");
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", file.name);
xhr.send(fd);
}
}
php code upload.php
<?php
session_start();
if (!isset($_POST['description'])) {
echo "upload:fail\n";
echo "message:No scene was specified";
exit();
}
if (isset($_FILES['image'])) {
if(!move_uploaded_file($_FILES['image']['tmp_name'], "uploads/" . $_POST['description'] . "/" . $_FILES['image']['name'])) {
echo "upload:fail\n";
}
else {
echo "upload:succes\n";
}
exit();
}
exit();
?>
I'd really advise against creating your own asynchronous file upload functionality when there is a plethora of developers who have already programmed the same thing better. Check out these options:
Blueimp's jQuery file uploader
Uploadifive (Uploadify's HTML5 implementation)
I've used these two before and they work very well. For BlueImp, you can use this option to send additional form data:
$('#fileupload').fileupload({
formData: $('.some_form').serialize()
});
The above captures a form and serializes its inputs. Alternatively, you can populate an array or object using specific values (i.e. from specific elements in your DOM):
var array = new Array();
$('.description').each(function() {
array[this.id] = this.value;
});
You'd use IDs to link your files and descriptions.