Action doesn't execute after ajax post - php

I'm trying to generate a pdf file with an image and a highcharts image in it.
This is what I do when I click on a button:
('#button').click(function() {
var quizid = <?php echo json_encode($quizid); ?>;
var chart = Highcharts.charts[0];
canvg(document.getElementById('canvas'), chart.getSVG())
var canvas = document.getElementById("canvas");
var img = canvas.toDataURL("image/png");
//document.write('<img src="'+img+'"/>');
// AJAX CALL TO ACTION
$.ajax({
url: '/results/savepdf',
type:"POST",
data: {quizid: quizid, image: img},
success: function(data) {
console.log("ajax call succces");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
});
In my action I have:
public function savepdfAction(){
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
if(isset($_POST['quizid']))
$quizid = $_POST['quizid'];
if(isset($_POST['image']))
$image = $_POST['image'];
// SAVE THE PDF OR WORD
// INCLUDE TCPDF LIBRARY
require_once 'tcpdf/tcpdf.php';
try {
// create new PDF document
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Nicola Asuni');
$pdf->SetTitle('TCPDF Example 009');
$pdf->SetSubject('TCPDF Tutorial');
$pdf->SetKeywords('TCPDF, PDF, example, test, guide');
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE.' 009', PDF_HEADER_STRING);
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
$pdf->AddPage();
$pdf->setJPEGQuality(75);
$imgdata = base64_decode('iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABlBMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDrEX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg==');
$pdf->Image('#'.$imgdata);
$pdf->Image('/images/logo.png', 25, 40, 154, 25, 'PNG', 'http://www.surveyanyplace.com', '', true, 150, '', false, false, 1, false, false, false);
$horizontal_alignments = array('L', 'C', 'R');
$vertical_alignments = array('T', 'M', 'B');
$pdf->Output('example_009.pdf', 'I');
}
catch (Exception $e) {
die ('Application error: ' . $e->getMessage());
}
}
As you can see I just want to show a pdf file without the parameters that were sent (Just to test).
This doesn't work ....
When I try this without the ajax call it works fine ...
I got this response:
TCPDF ERROR: Some data has already been output, can't send PDF file
I searched for the error and read that you have can fix this by putting ob_end_clean(); before your $pdf->Output('example_009.pdf', 'I');. And when I did that I got another reponse that you can watch here.

Since a .pdf file is binary data, you shouldn't use an Ajax request. After a quick search I found this jQuery plugin:
jQuery Plugin for Requesting Ajax-like File Downloads
It's a very small function and it generates a temporary form with hidden fields that it submits. Maybe not the most beautiful solution, but it should work. Haven't tested it though...

Related

Image background does not appear on pdf - TCPDF Laravel 8

I have a problem, I can't show the background image on the pdf, the output is only white blank pdf. I've checked the path to the background image and it's accessible. However, when you want to use it as a background, the image will not appear in the pdf.
I'm using laravel 8 with tcpdf ^^ Please help
public function savePDF($id)
{
$dokumen = Sertifikat::where('id',$id)->first();
$path = Storage::url('dokumen/').$dokumen->image;
PDF::SetTitle("Certificate");
PDF::AddPage('L','A4');
PDF::setImageScale(1);
PDF::SetAutoPageBreak(false, 0);
PDF::Image($path, 0, 0, 210, 297, '', '', '', false, 300, '', false, false, 0);
$view = \View::make('sertifikat.view', ['sertifikat'=>$dokumen]);
$html_content = $view->render();
PDF::writeHTML($html_content, true, false, true, false, '');
// D is the change of these two functions. Including D parameter will avoid
// loading PDF in browser and allows downloading directly
PDF::Output('Certificate.pdf');
}
Controller
https://pastebin.com/8RhNB5LF
View
https://pastebin.com/gPFMUGJi
Error section on the website
https://afgalaxy.com/sertifikat

Download generated pdf after ajax post

I'm working with Wordpress and I'm trying to generate a PDF in php after ajax post. I need to open my generated file in another window. I'm using this functions :
$('#my_button').on('click' , function(e){
e.preventDefault();
array = [];
jQuery.post( filter_params.ajaxurl, {
'action': 'create_pdf',
'array': array,
},
function(response){
//$('#w').empty();
//$('#w').append(response);
window.open("data:application/pdf," + response);
})
.success(function(data){
});
});
add_action( 'wp_ajax_create_pdf', 'create_pdf' );
add_action( 'wp_ajax_nopriv_create_pdf', 'create_pdf' );
function create_pdf() {
$array = $_POST['array'];
$pdf = new myPDF();
$pdf->AliasNbPages();
$pdf->AddPage('L', 'A4', 0);
$pdf->headerTable();
$pdf->viewTable( $array);
$pdf->Output();
die();
}
to make that we should store the generated pdf temporarily and open a new tab in the success function with the path of the generated pdf file.
function create_pdf() {
$array = $_POST['array'];
$pdf = new myPDF();
$pdf->AliasNbPages();
$pdf->AddPage('L', 'A4', 0);
$pdf->headerTable();
$pdf->viewTable( $array);
$pdf->Output('output.pdf','F');
die();
}

AJAX - PHP - FFMPEG - Execution not completing

Here is a slightly tricky situation:
I am using ajax to call a function that uses FFMpeg to convert a video.
The code all works fine EXCEPT:
The execution is cut short so I end up with a video of 2 frames.
I assume this is ajax causing the problem because as far as its concerned, its called the function and returned a success output to my php page.
In other words, the ffmpeg script cuts off when the ajax has completed.
Is there a way I can tell ajax to wait for the ffmpeg function to finish or do i need to set up a cron job for it to run in the background?
EDIT:
Heres the code:
AJAX:
// watermark($thevideo)
var ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
var formData = new FormData();
formData.append('thevideo', thevideo);
formData.append('action', "watermark");
$.ajax({
url: ajaxurl,
type: "POST",
data:formData,cache: false,
processData: false, // Don't process the files
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success:function(data) {
alert(data);
}
});
PHP FFMPEG Function:
// Watermark ***************
// IMPORTANT!
// This action & function can be called by ajax but requires absolute file paths!
add_action( 'wp_ajax_watermark', 'do_watermark' );
add_action( 'wp_ajax_nopriv_watermark', 'do_watermark' );
function getabspath( $file_url ){
return realpath($_SERVER['DOCUMENT_ROOT'] . parse_url( $file_url, PHP_URL_PATH ));
}
function do_watermark() {
session_start();
ini_set('display_errors', 1);
error_reporting(E_ALL);
// $thevideo = $_POST['thevideo'];
$thevideo = getabspath($_POST['thevideo']);
$newvideo = getabspath('./wp-content/uploads') . '/test.mp4';
$thewatermark = getabspath('./wp-content/uploads/mefbpic.png');
// For some reason we have to OMIT THE DRIVE LETTER from the watermark image path
// AND the backslashes need to be turned forward even tho its an absolute path!?!
$thewatermark = substr($thewatermark,2); // Cuts off the first 2 chars. - (C:)
$thewatermark = str_replace('\\','/',$thewatermark);
// require_once('./vendor/autoload.php');
require_once(getabspath('./vendor/autoload.php'));
$ffmpeg = FFMpeg\FFMpeg::create(array(
'ffmpeg.binaries' => getabspath('./FFMpeg/bin/ffmpeg.exe'),
'ffprobe.binaries' => getabspath('./FFMpeg/bin/ffprobe.exe'),
'timeout' => 3600, // The timeout for the underlying process
'ffmpeg.threads' => 12, // The number of threads that FFMpeg should use
));
$video = $ffmpeg->open($thevideo);
$video
->filters()
->resize(new \FFMpeg\Coordinate\Dimension(640, 360))
->watermark($thewatermark, [
'position' => 'relative',
'bottom' => 50,
'right' => 50,
])
->synchronize();
//$video
// ->save(new \FFMpeg\Format\Video\X264(), $thevideo);
$format = new \FFMpeg\Format\Video\X264();
$format->setAdditionalParameters(array('-y'));
$video->save($format, $newvideo);
echo 'done!';
}
Fixed it!
Just had to add
async: false,
to the ajax request!
Cheers ;)

How do you save a PDF with FDPF using parameters?

I have this button, that is tied to this function:
$('#genPDF').click(function () {
var str = "hText=something" +
"&cText=also something";
$.ajax({
url: "/wp-content/themes/mytheme/indexpdf.php",
data: str,
cache: false,
success: function (result) {
console.log("Success!");
$("#pdfobject").attr("src", "/wp-content/themes/mytheme/flyer.pdf");
var container = document.getElementById("pdfContainer");
var content = container.innerHTML;
container.innerHTML = content;
}
});
});
To explain what the successful ajax code does, first outputs "success!" in the console, which the browser does, then replaces a certain div on the page with a revised link (refreshing a certain part of the page).
This above code works, and makes it's way over to indexpdf.php, which is:
<?php
$hText = trim(isset($_GET['hText']) ? $_GET['hText'] : '');
$cText = trim(isset($_GET['cText']) ? $_GET['cText'] : '');
require_once('fpdf.php');
require_once('fpdi.php');
// initiate FPDI
$pdf = new FPDI();
$pdf->AddPage();
$pdf->setSourceFile("TestFlyer.pdf");
$tplIdx = $pdf->importPage(1);
$pdf->useTemplate($tplIdx, 10, 10, 100);
$pdf->SetFont('Helvetica');
$pdf->SetTextColor(255, 0, 0);
$pdf->SetXY(30, 30);
$pdf->Write(0, $hText.$cText);
$pdf->Output("D","flyer.pdf");
?>
The problem is, it's supposed to take testflyer.pdf, load it's first page and write my passed in arguments into it. THEN, save itself as flyer.pdf.
It's not saving, I don't know what's doing on or what the problem is.
All PDF's and PHP files above are in the /mytheme/ folder.
If you want to save the PDF, set the dest parameter as F:
So,
$pdf->Output("D","flyer.pdf");
must be:
$pdf->Output("F","flyer.pdf");
And reformat your write line as:
$pdf->Write(0, "$hText $cText");
According to the documentation, destination where to send the document. It can be one of the following:
I: send the file inline to the browser. The PDF viewer is used if available.
D: send to the browser and force a file download with the name given by name.
F: save to a local file with the name given by name (may include a path).
S: return the document as a string.
The default value is I.

How to set landscape orientation using HTML2PDF

How to change the page orientation of pdf file generated via HTML2PDF to landscape...?
By default, it is opening as Portrait format. I have changed it in html2pdf.class, but nothing changed.Please help me..
This is the php code:
require('../../includes/html2pdf/html2fpdf.php');
$pdf=new HTML2FPDF('L','mm','A3');
$pdf->AddPage();
$pdf->setFont("arial",'',8);
$pdf->WriteHTML($data);
$pdf->Output("outstanding.pdf","I");
Using L as the constructor parameter should work just fine. Don't mess with the class internals.
This is my only code and it works fine. Try using the newest release: HTML2PDF.
// convert to PDF
require_once('../../vendor/html2pdf_v4.03/html2pdf.class.php');
try
{
$html2pdf = new HTML2PDF('L', 'A4', 'en');
$html2pdf->setDefaultFont('Arial');
$html2pdf->writeHTML($html, false);
$html2pdf->Output('output.pdf', 'D');
}
catch(HTML2PDF_exception $e) {
echo $e;
exit;
}
Or you can add orientation on tag.
<page orientation="landscape" format="A5" > Landscape </page>
Check out http://demo.html2pdf.fr/examples/pdf/exemple04.pdf for more example.
This solution also is very good and it's in the documentation:
var element = document.getElementById('element-to-print');
var opt = {
margin: 1,
filename: 'myfile.pdf',
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2 },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
// New Promise-based usage:
html2pdf().set(opt).from(element).save();
// Old monolithic-style usage:
html2pdf(element, opt);

Categories