I need create a PDF from an HTML view rendering with Javascript Apis
This is my code in PHP Laravel 4
$con = Contrato::find($id);
$html = (string) View::make('contratos.contratopdf')->with('con',$con)->render();
return PDF::load(utf8_decode($html), 'A5', 'landscape')->show();
In the view I have this script
<script src="http://test.rentacar.cl/js/lib/jquery.signaturepad.min.js"></script>
This js change the Dom in a normal HTML but when I show in PDF don't work.
Thanks!!
PhantomJS works nicely, take a look at this package: https://github.com/jonnnnyw/php-phantomjs
Full documentation here: http://jonnnnyw.github.io/php-phantomjs/
Example:
<?php
use JonnyW\PhantomJs\Client;
$client = Client::getInstance();
$request = $client->getMessageFactory()->createCaptureRequest('http://google.com');
$response = $client->getMessageFactory()->createResponse();
$file = '/path/to/save/your/screen/capture/file.jpg';
$request->setCaptureFile($file);
$client->send($request, $response);
From my experience of dompdf(very famous pdf library),those library don't support JS interpreting(because the php don't have the power to interpret the javascript),here are two workaound I think you can try.
1.Server side rendering html,move your dom manipulation to php in order to create the dom element.(Recommended)
2.Use php and phantomJS.The php call phantomJS to capture the screen of html and saved the screenshot to pdf.
Related
I'm looking to run this bit of PHP within a text/javascript environment. The point is to display a description for certain media files within the Jplayer Playlister. So how can I run this within a text/javascript environment? If you need an example of the Playerlister working fine, and then breaking upon implementation of the PHP, I can provide that.
Here's the PHP:
// CONFIGURE THESE VARIABLES:
// actual place where your mp3s live on your server's filesystem. TRAILING SLASH REQ'D.
$musicDirectory="myServerPathHere";
// corresponding web URL for accessing the music directory. TRAILING SLASH REQ'D.
$musicURL="myURLhere";
// step through each item...
$fileDir = opendir($musicDirectory) or die ($php_errormsg);
while (false !== ($thisFile = readdir($fileDir))) // step through music directory
{
$thisFilePath = $musicDirectory . $thisFile;
if (is_file($thisFilePath) && strrchr ($thisFilePath, '.') == ".mp3") // not . or .., ends in .mp3
{
// only include files that have a corresponding .txt file
$thisTextPath = substr_replace($thisFilePath, ".txt", (strlen($thisFilePath) - 4));
if (is_file($thisTextPath))
{
$myFullURL=$musicURL . $thisFile;
$myFileSize=filesize($thisFilePath);
$textContents = file($thisTextPath);
foreach ($textContents as $thisLine) echo htmlspecialchars($thisLine) . "\n";
}
}
}
closedir($fileDir);
It's possible I don't fully understand what you're asking, so forgive me if that is the case, but what you seem to be asking is how to run PHP client side.
The simple answer is you can't.
PHP is a server-side language. To accomplish what you're trying to do you need to pass some data from PHP to your javascript.
This has always been a bit of a tricky thing to do for me. I usually resort to setting my variables via an on-page <script> tag like this:
<script>
var myJSVar = <?= $myPHPVar ?>
</script>
I've also used a simple JS object to configure a later script using this same method. There are also some neat tools that enable you to create JSON objects from your PHP objects and pass that to the client side. This makes things pretty smooth, and I recommend you check it out on your own.
I'd like to scrape the actual the dynamically created URLs in this web page's menu using PHP:
http://groceries.iceland.co.uk/
I have previously used something like this:
<?php
$baseurls = array("http://groceries.iceland.co.uk/");
foreach ($baseurls as $source)
{
$html = file_get_contents($source);
$start = strpos($html,'<nav id="mainNavigation"');
$end = strpos($html,'</nav>',$start);
$mainarea = substr($html,$start,$end-$start);
$dom = new DOMDocument();
#$dom->loadHTML($mainarea);
// grab all the urls on the page
$xpath = new DOMXPath($dom);
$hrefs = $xpath->evaluate("/html/body//a");
for ($i = 0; $i < $hrefs->length; $i++)
{
$href = $hrefs->item($i);
$url = $href->getAttribute('href');
}
}
?>
but it's not doing the job for this particular page. For example, my code returns a url such as:
groceries.iceland.co.uk//frozen-chips-and-potato-products
but I want it to give me:
groceries.iceland.co.uk//frozen/chips-and-potato-products/c/FRZCAP?q=:relevance&view=list
The browser adds "/c/FRZCAP?q=:relevance&view=list" to the end and this is what I want.
Hope you can help
Thanks
Edit: Just to confirm, I had at look at the website you're trying to scrape with JavaScript turned off and it appears that the Mainnav urls are generated using JavaScript, so you will be unable to scrape the page without using a headless browser.
Per #Sam and #halfer's comments, if you need to scrape a site that has dynamic URLs generated by JavaScript then you will need to use a scraper that supports JavaScript.
If you want to do the bulk of your development in PHP, then I recommend not trying to use a headless browser via PHP and instead relying on a service that can scrape a JavaScript rendered page and return the contents for you.
The best one that I've found, and one that we use in our projects, is https://phantomjscloud.com/
I am currently working on a project where i wanna implement jQuery to cakephp 2.0.
I have followed the guide at:
http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html
i.e. I have downloaded jquery-1.8.1.js (also tried the .min.js file) and put it in app/webroot/js.
In the default layout file i have added
echo $this->Html->script('jquery');
and just before the end of the body tag i have added
echo $this->Js->writeBuffer();
In my controller i have added
public $helpers = array('Js' => array('Jquery'));
When i reload my page and check the source code I see that the link to the jQuery file works correctly.
But when I try to add a simple script (just adding an alert) like this (in the view file):
$alert = $this->Js->alert('Hey there');
nothing happens...
Any kind person out there that might have any suggestion to what I do wrong?
I have spent hours looking looking at the internet and following different guides but still can get a simple thing as an alert working.
According to CakePHP 2.0 documentation: "by default, alert does not buffer, and returns the script snippet."
So by default:
echo $this->Js->alert('Hey there'); // outputs alert("Hey there");
To override this behaviour and add the script to the buffer:
echo $this->Js->alert('Hey there', true);
To write the buffer (commonly right before </body>):
echo $this->Js->writeBuffer();
As an alternative you can use scriptBlock:
$jscript = "alert('Hey there!');";
echo $this->Html->scriptBlock($jscript, array('inline'=>false));
I have a server-side script but now I want it run on client-side, so I want to convert from php to javascript. I am really not good at js so, please help.
Php code here:
function getAlexaRank($theUrl)
{
$alexa_url = "http://data.alexa.com/data?cli=10&dat=snbamz&url=" . $theUrl;
$doc = new DOMDocument();
$doc->load($alexa_url);
$popularities = $doc->getElementsByTagName("POPULARITY");
foreach($popularities as $popularity)
{
return $popularity->getAttribute('TEXT');
}
return "-1";
}
Refer to the following link to acheive it using js
http://www.hiteshagrawal.com/javascript/javascript-parsing-xml-in-javascript
CSS and Javascript files don't change very often, so I want them to be cached by the web browser. But I also want the web browser to see changes made to these files without requiring the user to clear their browser cache. Also want a solution that works well with a version control system such as Subversion.
Some solutions I have seen involve adding a version number to the end of the file in the form of a query string.
Could use the SVN revision number to automate this for you: ASP.NET Display SVN Revision Number
Can you specify how you include the Revision variable of another file? That is in the HTML file I can include the Revision number in the URL to the CSS or Javascript file.
In the Subversion book it says about Revision: "This keyword describes the last known revision in which this file changed in the repository".
Firefox also allows pressing CTRL+R to reload everything on a particular page.
To clarify I am looking for solutions that don't require the user to do anything on their part.
I found that if you append the last modified timestamp of the file onto the end of the URL the browser will request the files when it is modified. For example in PHP:
function urlmtime($url) {
$parsed_url = parse_url($url);
$path = $parsed_url['path'];
if ($path[0] == "/") {
$filename = $_SERVER['DOCUMENT_ROOT'] . "/" . $path;
} else {
$filename = $path;
}
if (!file_exists($filename)) {
// If not a file then use the current time
$lastModified = date('YmdHis');
} else {
$lastModified = date('YmdHis', filemtime($filename));
}
if (strpos($url, '?') === false) {
$url .= '?ts=' . $lastModified;
} else {
$url .= '&ts=' . $lastModified;
}
return $url;
}
function include_css($css_url, $media='all') {
// According to Yahoo, using link allows for progressive
// rendering in IE where as #import url($css_url) does not
echo '<link rel="stylesheet" type="text/css" media="' .
$media . '" href="' . urlmtime($css_url) . '">'."\n";
}
function include_javascript($javascript_url) {
echo '<script type="text/javascript" src="' . urlmtime($javascript_url) .
'"></script>'."\n";
}
Some solutions I have seen involve adding a version number to the end of the file in the form of a query string.
<script type="text/javascript" src="funkycode.js?v1">
You could use the SVN revision number to automate this for you by including the word LastChangedRevision in your html file after where v1 appears above. You must also setup your repository to do this.
I hope this further clarifies my answer?
Firefox also allows pressing CTRL + R to reload everything on a particular page.
In my opinion, it is better to make the version number part of the file itself e.g. myscript.1.2.3.js. You can set your webserver to cache this file forever, and just add a new js file when you have a new version.
When you release a new version of your CSS or JS libraries, cause the following to occur:
modify the filename to include a unique version string
modify the HTML files which reference the library to point at the versioned file
(this is usually a pretty simple matter for a release script)
Now you can set the Expires for the CSS/JS to be years in the future. Whenever you change the content, if the referencing HTML points to a new URI, browsers will no longer use the old cached copy.
This causes the caching behavior you want without requiring anything of the user.
I was also wondering how to do this, when I found grom's answer. Thanks for the code.
I struggled with understanding how the code was supposed to be used. (I don't use a version control system.) In summary, you include the timestamp (ts) when you call the stylesheet. You're not planning on changing the stylesheet often:
<?php
include ('grom_file.php');
// timestamp on the filename has to be updated manually
include_css('_stylesheets/style.css?ts=20080912162813', 'all');
?>