Skip to content

Commit

Permalink
Inject js (#65)
Browse files Browse the repository at this point in the history
* Added Exception Classes
URL validation moved into separate class

* Added local path validation
Added facebook utility scripts to inject

* Fixed exception namespace

* Image format refactored

* Added js injection

* Added docs

* Nitpick-CI fixes

* Added Exception Classes
URL validation moved into separate class

* Added local path validation
Added facebook utility scripts to inject

* Fixed exception namespace

* Image format refactored

* Added js injection

* Added docs

* Nitpick-CI fixes

* Changed timeout naming
Added timeout value validation
  • Loading branch information
MASNathan committed Aug 15, 2016
1 parent 851c949 commit 57db948
Show file tree
Hide file tree
Showing 23 changed files with 507 additions and 69 deletions.
43 changes: 38 additions & 5 deletions README.md
Expand Up @@ -60,19 +60,52 @@ You can also set the User Agent
$screenCapture->setUserAgentString('Some User Agent String');
```

And the resulted image format
And the resulted image type
``` php
// allowed formats are 'jpg' and 'png', default is 'jpg'.
$screenCapture->setFormat('png');
// allowed types are 'jpg' and 'png', default is 'jpg'.
$screenCapture->setImageType(Screen\Image\Types\Png::FORMAT);
// or
$screenCapture->setImageType('png');
```
* If the format is ```jpg``` and the background color is not set, the default value will be ```#FFFFFF```, if ```png``` the default background color will be transparent.

And most importantly, save the result
``` php
$fileLocation = '/some/dir/test.' . $screen->getFormat();
$screen->save($fileLocation);
$fileLocation = '/some/dir/test.' . $screen->getImageType()->getFormat();
$screenCapture->save($fileLocation);

// you don't need to set the file extension
$fileLocation = '/some/dir/test';
$screenCapture->save($fileLocation); // Will automatically determine the extension type

echo $screenCapture->getImageLocation(); // --> /some/dir/test.png
```

##Injection your own JS into the web page

You can also run your own JS scripts or snippets before the screenshot.

For that we have the method ```includeJs```, here are some usage examples:

``` php
// Including a remote file
$jQueryUrl = 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js';
$screenCapture->includeJs(new \Screen\Injection\Url($jQUeryUrl));

// Including a local file
$localFilePath = 'path/to/my/script.js';
$screenCapture->includeJs(new \Screen\Injection\LocalPath($localFilePath));

// Using the scripts included on the library
$screen->includeJs(new \Screen\Injection\Scripts\FacebookHideCookiesPolicy());
$screen->includeJs(new \Screen\Injection\Scripts\FacebookHideSignUp());

// Using a js snippet
$screen->includeJs("console.log('This is supa cool!');");
```

Just use this method before calling ```save(...)```

##Other configurations
Additionally to the basic usage, you can set so extra configurations.

Expand Down
10 changes: 5 additions & 5 deletions demo/shot.php
Expand Up @@ -35,12 +35,12 @@
}

if (isset($_GET['format'])) { // Format
$screen->setFormat($_GET['format']);
$screen->setImageType($_GET['format']);
}

$fileLocation = 'test.' . $screen->getFormat();
$fileLocation = 'test';
$screen->save($fileLocation);

header('Content-Type:' . $screen->getMimeType());
header('Content-Length: ' . filesize($fileLocation));
readfile($fileLocation);
header('Content-Type:' . $screen->getImageType()->getMimeType());
header('Content-Length: ' . filesize($screen->getImageLocation()));
readfile($screen->getImageLocation());
3 changes: 3 additions & 0 deletions scripts/facebook-hide-cookies-policy.js
@@ -0,0 +1,3 @@
(function () {
document.getElementsByClassName('fbPageBanner')[0].getElementsByTagName('button')[0].click();
})();
6 changes: 6 additions & 0 deletions scripts/facebook-hide-login.js
@@ -0,0 +1,6 @@
(function () {
var loginForm = document.getElementsByClassName('menu_login_container');
if (loginForm[0]) {
loginForm[0].style.display = 'none';
}
})();
19 changes: 19 additions & 0 deletions scripts/facebook-hide-signup.js
@@ -0,0 +1,19 @@
/* User Page */
(function () {
var uiBoxOverlay = document.getElementsByClassName('uiBoxOverlay');
if (uiBoxOverlay[0]) {
uiBoxOverlay[0].style.display = 'none';
}
var timelineLoggedOutSignUp = document.getElementsByClassName('timelineLoggedOutSignUp');
if (timelineLoggedOutSignUp[0]) {
timelineLoggedOutSignUp[0].style.display = 'none';
}
})();

/* Product Page */
(function () {
var footerBox = document.getElementsByClassName('_5hn6');
if (footerBox[0]) {
footerBox[0].style.display = 'none';
}
})();
6 changes: 6 additions & 0 deletions scripts/facebook-hide-top-bar.js
@@ -0,0 +1,6 @@
(function () {
var topBar = document.getElementById('pagelet_bluebar');
if (topBar) {
topBar.style.display = 'none';
}
})();
158 changes: 104 additions & 54 deletions src/Capture.php
Expand Up @@ -2,6 +2,12 @@

namespace Screen;

use Screen\Exceptions\InvalidArgumentException;
use Screen\Exceptions\TemplateNotFoundException;
use Screen\Image\Types;
use Screen\Image\Types\Type;
use Screen\Injection\LocalPath;
use Screen\Injection\Url;
use Screen\Location\Jobs;
use Screen\Location\Output;

Expand Down Expand Up @@ -57,11 +63,11 @@ class Capture
protected $backgroundColor = '';

/**
* Image format
* Image Type, default is jpeg
*
* @var string
* @var Type
*/
protected $format = 'jpg';
protected $imageType;

/**
* User Agent String used on the page request
Expand All @@ -72,9 +78,10 @@ class Capture

/**
* Sets the timeout period
*
* @var int
*/
protected $resourceTimeout = 0;
protected $timeout = 0;

/**
* Bin directory, should contain the phantomjs file, otherwise it won't work
Expand Down Expand Up @@ -104,6 +111,27 @@ class Capture
*/
public $output;

/**
* Location where the file was written to
*
* @var string
*/
protected $imageLocation;

/**
* List of included JS scripts
*
* @var array
*/
protected $includedJsScripts = array();

/**
* List of included JS snippets
*
* @var array
*/
protected $includedJsSnippets = array();

/**
* Capture constructor.
*/
Expand All @@ -118,18 +146,31 @@ public function __construct($url = null)

$this->jobs = new Jobs();
$this->output = new Output();

$this->setImageType(Types\Jpg::FORMAT);
}

/**
* Saves the screenshot to the requested location
*
* @param string $imageLocation Image Location
* @param bool $deleteFileIfExists True to delete the file if it exists
*
* @return bool
*/
public function save($imageLocation, $deleteFileIfExists = true)
{
$outputPath = $this->output->getLocation() . $imageLocation;
$this->imageLocation = $this->output->getLocation() . $imageLocation;

if (!pathinfo($this->imageLocation, PATHINFO_EXTENSION)) {
$this->imageLocation .= '.' . $this->getImageType()->getFormat();
}

$data = array(
'url' => $this->url,
'width' => $this->width,
'height' => $this->height,
// If used on windows the \ char needs to be handled to be used on a js string
'imageLocation' => str_replace("\\", "\\\\", $outputPath),
'imageLocation' => LocalPath::sanitize($this->imageLocation),
);

if ($this->clipWidth && $this->clipHeight) {
Expand All @@ -141,7 +182,7 @@ public function save($imageLocation, $deleteFileIfExists = true)

if ($this->backgroundColor) {
$data['backgroundColor'] = $this->backgroundColor;
} elseif ($this->getFormat() == 'jpg') {
} elseif ($this->getImageType()->getFormat() == Types\Jpg::FORMAT) {
// If there is no background color set, and it's a jpeg
// we need to set a bg color, otherwise the background will be black
$data['backgroundColor'] = '#FFFFFF';
Expand All @@ -151,12 +192,20 @@ public function save($imageLocation, $deleteFileIfExists = true)
$data['userAgent'] = $this->userAgentString;
}

if ($this->resourceTimeout) {
$data['resourceTimeout'] = $this->resourceTimeout;
if ($this->timeout) {
$data['timeout'] = $this->timeout;
}

if ($this->includedJsScripts) {
$data['includedJsScripts'] = $this->includedJsScripts;
}

if ($this->includedJsSnippets) {
$data['includedJsSnippets'] = $this->includedJsSnippets;
}

if ($deleteFileIfExists && file_exists($outputPath) && is_writable($outputPath)) {
unlink($outputPath);
if ($deleteFileIfExists && file_exists($this->imageLocation) && is_writable($this->imageLocation)) {
unlink($this->imageLocation);
}

$jobName = md5(json_encode($data));
Expand All @@ -171,14 +220,14 @@ public function save($imageLocation, $deleteFileIfExists = true)
$command = sprintf("%sphantomjs %s", $this->binPath, $jobPath);
$result = exec(escapeshellcmd($command));

return file_exists($outputPath);
return file_exists($this->imageLocation);
}

private function getTemplateResult($templateName, array $args)
{
$templatePath = $this->templatePath . DIRECTORY_SEPARATOR . $templateName . '.php';
if (!file_exists($templatePath)) {
throw new \Exception("The template {$templateName} does not exist!");
throw new TemplateNotFoundException($templateName);
}
ob_start();
extract($args);
Expand Down Expand Up @@ -210,19 +259,7 @@ public function setBinPath($binPath)
*/
public function setUrl($url)
{
// Prepend http:// if the url doesn't contain it
if (!stristr($url, 'http://') && !stristr($url, 'https://')) {
$url = 'http://' . $url;
}

if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
throw new \Exception("Invalid URL");
}

$url = str_replace(array(';', '"', '<?'), '', strip_tags($url));
$url = str_replace(array('\077', '\''), array(' ', '/'), $url);

$this->url = $url;
$this->url = new Url($url);
}

/**
Expand Down Expand Up @@ -296,49 +333,37 @@ public function setBackgroundColor($backgroundColor)
}

/**
* Sets the image format
* Sets the image type
*
* @param string $format 'jpg' | 'png'
* @param string $type 'jpg', 'png', etc...
*
* @return Capture
*/
public function setFormat($format)
public function setImageType($type)
{
$format = strtolower($format);
if (!in_array($format, ['jpg', 'png'])) {
throw new Exception(
"Invalid image format '{$format}'. " .
"Allowed formats are 'jpg' and 'png'"
);
}

$this->format = $format;
$this->imageType = Types::getClass($type);

return $this;
}

/**
* Gets the image format
* Returns the image type instance
*
* @return string
* @return Type
*/
public function getFormat()
public function getImageType()
{
return $this->format;
return $this->imageType;
}

/**
* Gets the MIME type of resulted image
* Returns the location where the screenshot file was written
*
* @return string
*/
public function getMimeType()
public function getImageLocation()
{
if ($this->format === 'png') {
return 'image/png';
}

return 'image/jpeg';
return $this->imageLocation;
}

/**
Expand All @@ -357,12 +382,37 @@ public function setUserAgentString($userAgentString)

/**
* Sets the timeout period
* @param int $timeout
* @return $this
*
* @param int $timeout Timeout period
*
* @return Capture
* @throws InvalidArgumentException
*/
public function setResourceTimeout($timeout = 30000)
public function setTimeout($timeout)
{
$this->resourceTimeout = $timeout;
if (!is_numeric($timeout)) {
throw new InvalidArgumentException('The timeout value must be a number.');
}
$this->timeout = $timeout;

return $this;
}

/**
* Adds a JS script or snippet to the screen shot script
*
* @param string|URL $script Script to include
*
* @return Capture
*/
public function includeJs($script)
{
if (is_a($script, Url::class)) {
$this->includedJsScripts[] = $script;
} else {
$this->includedJsSnippets[] = $script;
}

return $this;
}
}

0 comments on commit 57db948

Please sign in to comment.