Yii 1.1: phantomjs-takescreenshot-action

A web service which is implemented as an action to take screenshot of a website using phantomjs
4 followers

This is a web service which is implemented as an action to take screenshot of a website & return the file content to web service consumer.

For those of you who do not know how to use phantomjs to take screenshot of a web page dynamically, please refer to this article (the "Rendering" example).

Let's assume you have phantomjs installed on server A to take screenshot of a web site. Now you are implementing 2 web applications that need the functionality that server A does. These 2 applications are going to be deployed on server B & C. So, instead of installing phantomjs on server B & C again, a web service is implemented on server A so that you can use this functionality from anywhere. This web service is implemented as a Yii action and will return the content of the screenshot which then can be saved as a jpg image. This web service is going to be called using curl.

Requirements

Yii 1.1 or above

Usage

Copy & paste the extension into protected/extension. Then create an action to set up the web service & another action to call this web service. I implement these 2 actions in 1 controller for simplicity.

<?php
class TestPhantomController extends CController {
    public function actions(){
        return array(
            "takeScreenshot" => array(
                "class" => "ext.phantomjs.EWebScreenshotAction",
                "username" => "username", // username to use this web service
                "password" => "password", // password to use this web service
                "allowedIps" => array(), // restricted to some IPs only, leave blank for any IP
            )
        );
    }
 
    public function actionTestScreenshot() {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->createAbsoluteUrl("/test/takeScreenshot"));
        $fields = array(
            "username" => "username",
            "password" => "password",
            "webUrl" => "http://www.google.com",
        );
        curl_setopt($ch, CURLOPT_POST, count($fields));
        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
 
        $result = curl_exec($ch);
        $httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
 
        if ($httpStatus == 200 && ! empty($result)) {
            file_put_contents("C:/test.jpg", $result);
        } else { // Error occurred
            echo $result;
        }
    }
}
?>

Glandore Systems

Total 4 comments

#12351 report it
luckas at 2013/03/15 09:09am
Reply: Reliability in Production?

Hi w00tw00t111, we are using the class into production environment, the software is not public, but i can say that's working great, with the example that i have wrote you can convert any html (with img, flash, svg) into pdf, we have have some problems with the height of the page, but it's a problem of webkit engine that we are using, the server it's a windows server 2008. if you have any problem post it and we can help you

Bye

#12225 report it
w00tw00t111 at 2013/03/07 11:05am
Reliability in Production?

Luckas, Thanks for your post! Has this been deployed in a production environment? We are needing to do exactly what you are doing, with a few charting/graphing libraries. Have you experienced and reliability problems using this method?

#11392 report it
luckas at 2013/01/10 12:10pm
Great Extensión, i give my experience

We are running a project in a Linux Server we have some problems using the Web Service solution, and we don't have time to fix this probem, meanwhile we created a Class into the Extension

//*****
/ Put this class into the phantomjs extension directory
//*****
<?php
    class PDFmaker
    {
        // The command to run phantomjs
        public $phantomjsCommand = "phantomjs";
 
        /**
         * Make a PDF from URL of File Path
         * @param string $webUrl URL or File Path
         * @return string PDF File Content
         */
        public function saveFromPath($webUrl)
        {
            $tempFolder = Yii::getPathOfAlias("application"). "/runtime";
 
            $screenshotFileName = $tempFolder . "/" . uniqid() . ".pdf";
            $phantomjsCommand = $this->phantomjsCommand . " " . dirname(__FILE__) . "/js/rasterize.js " . $webUrl . " " . $screenshotFileName;
 
            exec($phantomjsCommand);
 
            $status = false;
            $fileContent = "";
            if (file_exists($screenshotFileName)) {
                $status = true;
                $fileContent = file_get_contents($screenshotFileName);
 
                // Remove file
                unlink($screenshotFileName);
            }
            return $fileContent;
        }
 
        /**
         * Make a PDF from String Content
         * @param string $htmlContent URL or File Path
         * @return string PDF File Content
         */
        public function saveFromContent($htmlContent)
        {
            $tempFolder = Yii::getPathOfAlias("application"). "/runtime";
 
            $screenshotFileName = $tempFolder . "/" . uniqid() . ".pdf";
 
            $tempContentFile = $tempFolder . "/" . uniqid() . ".tmp";
            $fh = fopen($tempContentFile, 'w') or die("can't open file");
            fwrite($fh, $htmlContent);
            fclose($fh);
 
            $phantomjsCommand = $this->phantomjsCommand . " " . dirname(__FILE__) . "/js/rasterize.js " . $tempContentFile . " " . $screenshotFileName;
 
            exec($phantomjsCommand);
 
            $status = false;
            $fileContent = "";
            if (file_exists($screenshotFileName)) {
                $status = true;
                $fileContent = file_get_contents($screenshotFileName);
 
                // Remove file
                unlink($tempContentFile);
                unlink($screenshotFileName);
            }
            return $fileContent;
        }
    }
?>
 
 
/*****
/Register the class into the project (protect/main.php)
-- Section "import"
 
        'import'=>array(
                'OTHER FILES YYY',
                'OTHER FILES ZZZ',
                'ext.phantomjs.PDFmaker'
        ),
 
 
//*****
 
 
//****************
//Example of usage
//****************
 
public funtion actionExport()
{
        $htmlContent = '<p>Hello World</p>';
        $pdf = new PDFmaker();
 
        $str = $pdf->saveFromContent($htmlContent);
 
        $outputFileName =  'pairwise_comparison_'.date('YmdH').'.pdf';
 
        header('Content-Type: application/pdf');
        header('Content-Length: '.strlen($str));
        header('Content-Disposition: inline; filename="'.$outputFileName.'"');
        header('Cache-Control: private, max-age=0, must-revalidate');
        header('Pragma: public');
        ini_set('zlib.output_compression','0');
        die($str);
}

Bye

#7839 report it
Mariusz W. at 2012/04/22 01:54am
Nice feature

Good to know there is phantomjs library! I have never heard about this....

Leave a comment

Please to leave your comment.

Create extension