Save HTML as PDF and email using MPDF - javascript

I need to be able to send a PDF version of a PHP page's HTML (with CSS styles intact as some tags are set to display: none in a #media print{} clause) as an email.
I found mpdf which looks relatively easy and seems like a solid solution. The class offers the ability to email a PDF file on the fly. This is great.
My dilemma is as follows:
I want to send page_1.php's contents to send_email.php as a url variable to use as the PDF content.
To store this variable I have tried:
ob_start(); // at the top of the page
// THE DYNAMICALLY GENERATED PAGE CONTENT
$html = ob_get_contents(); // I put the page contents into a variable
ob_end_clean();
For some reason this does not let the page load in it's entirety. Only a few tags show up. The ob_get_contents(); and ob_end_clean(); are sitting before the end </html> tag. Is this a potential cause?
I need to use these functions before the end of the page to utilize the variable higher up at the actual 'email link' I created.
I have also tried:
$page_url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; // to grab the current url
$html = file_get_contents($page_url); // place contents in a variable
For some reason, this does not allow any page on the site to load. All one gets is a spinning wheel in the browser url input.
Even if I can get the page's content into a variable and parse it to send_email.php, how would I retain the CSS properties when creating the PDF?
Would a javascript alternative be more viable?
Any help would be outstanding!

I've had success posting the html to the php file:
$html = $_POST['html'];
$head.= '<link rel="stylesheet" type="text/css" href="/app/css/app.css" /> ';
$head.= '<link rel="stylesheet" type="text/css" href="/app/css/pdf_style.css" /> ';
require_once 'mpdf/mpdf.php';
$mpdf = new mPDF('', 'Letter', 0, '', 12.7, 12.7, 12.7, 12.7, 0, 0);
$mpdf->WriteHTML($head.$html,0);

Related

Does end of script tag take priority than backtick?

I am developing page builder widget. I have to save entire html of edited page to local storage and database. PHP script will load saved html from database, and javascript would save it to local storage, and page builder widget script will parse html saved in local storage.
The problem is that when the html includes <script></script> tag, it won't load successfully. For example, the following script will show error, if html includes script tag.
<script>
<?php $html = $db->getPageHtml();?>
window.localStorage.setItem('pb_html', `<?php echo $html?>`);
</script>
For example, if $html is set as </script> the following script will show error:
<script>
window.localStorage.setItem('test', `</script>`);
</script>
The other html tags are successfully rendered. I think </script> take priority than ` (backtick) when javascript is parsed by browser.
PHP function htmlspecialchar won't solve this problem because it converts < and > to < and >. And page builder javascript don't understand it. Do you have any suggestion?
Browsers generally don't parse the script when looking for the </script> tag. First they extract everything between <script> and </script>, then this is parsed as JavaScript. It doesn't matter what type of quotes are used around the tag, since it isn't parsed at that point.
The usual way to avoid problems when you have a literal string containing </script> is to split it up.
window.localStorage.setItem('test', `</sc` + `ript>`);
See Why split the <script> tag when writing it with document.write()?

Is there any way to make Javascript work in DOMPDF-generated PDFs?

I am currently testing DOMPDF and got it working quite nice for my purposes, including CSS styling, displaying content fetched from a mysql database etc.
Now I tried to use some Javascript, but it doesn't work. I used a very simple script for testing:
HTML somewhere on the page:
<div id='mydiv1' style='width: 100%;height:20px;background:#ddd;'></div>
The JS (just above the closing </body> tag (but I also tried it right after the opening <body> tag):
<script>
document.getElementById('mydiv1').innerHTML = 'this is a test';
</script>
When I echo this page in the browser (I am echoing a variable which contains the complete HTML/PHP page), that text appears in the DIV. When I put the same variable in DOMPDF's loadHtml and then render and output it, the script-generated text doesn't appear in the PDF (the rest of the page does).
So my question is: Is there any way to make Javascript work in DOMPDF-generated PDFs?
Unfortunately, DOMPDF doesn't support javascript. You may consider looking at something like phantomjs, which can be used to save pdf files, as well.
There is a DomPDF option to turn on inline javascript:
$isJavascriptEnabled = true;
Heres an example of how to use the DomPDF options:
$HTML = <<<HTML
!DOCTYPE html>
<html>
<head>
<body>
some html
</body>
<script> somejs </script>
</head>
</html>
HTML;
require_once "sites/all/libraries/dompdf/autoload.inc.php";
use Dompdf\Dompdf;
use Dompdf\Options;
$options = new Options();
$options->set('isJavascriptEnabled', TRUE);
$dompdf = new Dompdf($options);
$dompdf->load_html($HTML);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
$dompdf->stream('blah.pdf');
I took this from DomPDF's options page: https://github.com/dompdf/dompdf/blob/master/src/Options.php

HTML in new Browser Tab or WIndow

In my PHP file, I have a string variable that contains complete HTML code.
$content = '<html>
<head>
<script>--Some javascript and libraries included--</script>
<title></title>
</head>
<body>
<style>--Some Styling--</style>
</body>
</html>';
I get this in a loop and now I want this HTML to open in new tab or window of browser. With every iteration, there would be a new Tab or Window. I don't think it is possible on server side so may be some JavaScript need to be concatenated to it.
In loop, I've created the URL to hit the controller and set the parameters with it and then simple use the following statement.
echo '<script type="text/javascript"> window.open("'. $url .'"); </script>';
and In the $url variable, I created the URL and post data in it. That's how, the new tab will open that hits the url and result will be my complete HTML.

automatically css/js content in 1 file

I separate many CSS/JS so it's easier to work in and look over.
But when the website loads, it has to load all those JS and CSS files and that will extend the loading times more and more.
So I was trying to put a simple php script in my website that takes all the CSS content and put it in 1 file. Same goes for the JS content.
It looks like this ($data['js'] and $data['css'] are arrays with all the files):
<?php
$jsData = "";
$cssData = "";
foreach($data['js'] as $js) {
$jsData .= file_get_contents($js);
}
foreach($data['css'] as $css) {
$cssData .= file_get_contents($css);
}
file_put_contents('static/js/javascript.js', $jsData);
file_put_contents('static/css/style.css', $cssData);
?>
<script type="text/javascript" src="static/js/javascript.js"></script>
<link href="static/css/style.css" rel="stylesheet" type="text/css">
As I'm still a beginner I wanted to ask you for tips/suggestions,
What do you guys think?
Thank you
Use this CssJsBundler
The above is on github, and opensource and it does what you have requested !
And also check out http://www.subchild.com/2008/08/07/simple-javascript-and-css-file-bundler/
which tells you how to configure the options.

Redirect IF referrer matches destination

I would like to redirect to a different page if the referrer matches the loaded website. I want to do this because I run a php rotator script running simultaneously on several websites. But IF I have site A being advertised on sites A B C D, I would like site A to show only if the referrer matches site B C or D or not to show if referrer matches site A. This is to prevent showing the same website on itself.
The script is a php script loaded in an iframe. It doesn't have referrer cloaking or anything like that. I can include any javascript or php in the rotator script.
Any ideas or pointers would be appreciated. Thank you!
sorry, this is a little long, but I want to make sure this is well answered.
Let's be clear and use consistent terminology to make sure we're on the same page here:
redirect means to capture the request for the current page and point it at a different page.
For example:
typing "http://gooogle.com" into your address bar will perform a redirect to "http://google.com"
There are multiple kinds of redirects, we'll not got into them here.
referer indicates the URI that linked to the page being requested, as pulled from the HTTP headers
For example:
You're on the page "http://slate.com"
You click a link that leads you to "http://newsweek.com"
your referer is "http://slate.com" in this case.
A redirect may modify the value of the referer, depending on the type of redirect.
In order to accomplish what you wish: to not display an ad in an iframe for the page you are currently on, you are not actually concerned about either of these. You don't need any redirection, and you don't need to be concerned about who linked to the current page.
Consider how your page works:
There is a javascript that executes on page load that inserts an iframe into your document.
That iframe, in turn, loads the PHP file on the server, which displays the ad.
So you have an HTML page that looks something like this:
index.html
<!doctype HTML>
<html>
<head><title>Server A Index</title></head>
<body>
<header>
<section id="top_banner_ad">
<script src="./js/adrotator.js"></script>
</section>
</header>
<!-- Some content... -->
</body>
</html>
Which calls a JavaScript that looks something like this:
/js/adrotator.js
var holder = document.getElementById("top_banner_ad");
var iframe = document.createElement("iframe");
iframe.src = "http://example.com/inc/adrotators.php";
holder.appendChild(iframe);
Which calls, finally, a PHP script that looks something like this:
/inc/adrotators.php
<!doctype HTML>
<html>
<head><title></title></head>
<body>
<?php $advert = get_advert(); ?>
<a href="<?php echo $advert['url']; ?>">
<img src="<?php echo $advert['imgsrc']; ?>">
</a>
</body>
</html>
I'm not sure what you have access to in this scenario, but I'm going to assume you have access to all of these: the page hosting the script (index.html), the javascript that creates the iframe (/js/adrotator.js), and the php script that is called by the iframe (/inc/adrotator.php).
You have at least 2 solutions:
You can either have /js/adrotator.js find out from index.html and tell the /inc/adrotator.php who it is, or you can have /inc/adrotator.php find out who it's parent frame is.
So, the iframe has knowledge of its parent frame (though they can only actually communicate under certain circumstances)
If your iframe loads a page that is on the same domain (subdomains matter), one solution would be to have a javascript in the iframe (in the HTML generated by the PHP) check its parent, like so:
parent.document.location.href
And then request a new ad if the target domain matches the parent.
(preferred) If you can modify the javascript that creates the iframe in your page, then you could have the javascript check the url and add it as a url parameter to the src attribute of the iframe it calls.
For example:
var host_url = window.location.href;
var iframe = document.createElement("iframe");
iframe.src = "http://example.com/ad_rotator.php?host="+ host_url;
document.body.appendChild(iframe);
And then your PHP script would not serve an ad whose target matches $_GET["host"]
<?php
$advert = get_advert();
while ($advert['url'] == $_GET['host']) {
$advert = get_advert();
}
?>
<a href="<?php echo $advert['url']; ?>">
<img src="<?php echo $advert['imgsrc']; ?>">
</a>
all the code here is untested pseudo-code, you will definitely need to modify this, it's just a starter
If you can't modify the PHP that loads the ad, nor can you modify the script that injects the iframe, you're pretty much hosed.

Categories

Resources