Skip to content

Commit 57db948

Browse files
authored
Inject js (#65)
* 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
1 parent 851c949 commit 57db948

23 files changed

+507
-69
lines changed

README.md

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,52 @@ You can also set the User Agent
6060
$screenCapture->setUserAgentString('Some User Agent String');
6161
```
6262

63-
And the resulted image format
63+
And the resulted image type
6464
``` php
65-
// allowed formats are 'jpg' and 'png', default is 'jpg'.
66-
$screenCapture->setFormat('png');
65+
// allowed types are 'jpg' and 'png', default is 'jpg'.
66+
$screenCapture->setImageType(Screen\Image\Types\Png::FORMAT);
67+
// or
68+
$screenCapture->setImageType('png');
6769
```
6870
* 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.
6971

7072
And most importantly, save the result
7173
``` php
72-
$fileLocation = '/some/dir/test.' . $screen->getFormat();
73-
$screen->save($fileLocation);
74+
$fileLocation = '/some/dir/test.' . $screen->getImageType()->getFormat();
75+
$screenCapture->save($fileLocation);
76+
77+
// you don't need to set the file extension
78+
$fileLocation = '/some/dir/test';
79+
$screenCapture->save($fileLocation); // Will automatically determine the extension type
80+
81+
echo $screenCapture->getImageLocation(); // --> /some/dir/test.png
7482
```
7583

84+
##Injection your own JS into the web page
85+
86+
You can also run your own JS scripts or snippets before the screenshot.
87+
88+
For that we have the method ```includeJs```, here are some usage examples:
89+
90+
``` php
91+
// Including a remote file
92+
$jQueryUrl = 'https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js';
93+
$screenCapture->includeJs(new \Screen\Injection\Url($jQUeryUrl));
94+
95+
// Including a local file
96+
$localFilePath = 'path/to/my/script.js';
97+
$screenCapture->includeJs(new \Screen\Injection\LocalPath($localFilePath));
98+
99+
// Using the scripts included on the library
100+
$screen->includeJs(new \Screen\Injection\Scripts\FacebookHideCookiesPolicy());
101+
$screen->includeJs(new \Screen\Injection\Scripts\FacebookHideSignUp());
102+
103+
// Using a js snippet
104+
$screen->includeJs("console.log('This is supa cool!');");
105+
```
106+
107+
Just use this method before calling ```save(...)```
108+
76109
##Other configurations
77110
Additionally to the basic usage, you can set so extra configurations.
78111

demo/shot.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@
3535
}
3636

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

41-
$fileLocation = 'test.' . $screen->getFormat();
41+
$fileLocation = 'test';
4242
$screen->save($fileLocation);
4343

44-
header('Content-Type:' . $screen->getMimeType());
45-
header('Content-Length: ' . filesize($fileLocation));
46-
readfile($fileLocation);
44+
header('Content-Type:' . $screen->getImageType()->getMimeType());
45+
header('Content-Length: ' . filesize($screen->getImageLocation()));
46+
readfile($screen->getImageLocation());
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(function () {
2+
document.getElementsByClassName('fbPageBanner')[0].getElementsByTagName('button')[0].click();
3+
})();

scripts/facebook-hide-login.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(function () {
2+
var loginForm = document.getElementsByClassName('menu_login_container');
3+
if (loginForm[0]) {
4+
loginForm[0].style.display = 'none';
5+
}
6+
})();

scripts/facebook-hide-signup.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* User Page */
2+
(function () {
3+
var uiBoxOverlay = document.getElementsByClassName('uiBoxOverlay');
4+
if (uiBoxOverlay[0]) {
5+
uiBoxOverlay[0].style.display = 'none';
6+
}
7+
var timelineLoggedOutSignUp = document.getElementsByClassName('timelineLoggedOutSignUp');
8+
if (timelineLoggedOutSignUp[0]) {
9+
timelineLoggedOutSignUp[0].style.display = 'none';
10+
}
11+
})();
12+
13+
/* Product Page */
14+
(function () {
15+
var footerBox = document.getElementsByClassName('_5hn6');
16+
if (footerBox[0]) {
17+
footerBox[0].style.display = 'none';
18+
}
19+
})();

scripts/facebook-hide-top-bar.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(function () {
2+
var topBar = document.getElementById('pagelet_bluebar');
3+
if (topBar) {
4+
topBar.style.display = 'none';
5+
}
6+
})();

src/Capture.php

Lines changed: 104 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
namespace Screen;
44

5+
use Screen\Exceptions\InvalidArgumentException;
6+
use Screen\Exceptions\TemplateNotFoundException;
7+
use Screen\Image\Types;
8+
use Screen\Image\Types\Type;
9+
use Screen\Injection\LocalPath;
10+
use Screen\Injection\Url;
511
use Screen\Location\Jobs;
612
use Screen\Location\Output;
713

@@ -57,11 +63,11 @@ class Capture
5763
protected $backgroundColor = '';
5864

5965
/**
60-
* Image format
66+
* Image Type, default is jpeg
6167
*
62-
* @var string
68+
* @var Type
6369
*/
64-
protected $format = 'jpg';
70+
protected $imageType;
6571

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

7379
/**
7480
* Sets the timeout period
81+
*
7582
* @var int
7683
*/
77-
protected $resourceTimeout = 0;
84+
protected $timeout = 0;
7885

7986
/**
8087
* Bin directory, should contain the phantomjs file, otherwise it won't work
@@ -104,6 +111,27 @@ class Capture
104111
*/
105112
public $output;
106113

114+
/**
115+
* Location where the file was written to
116+
*
117+
* @var string
118+
*/
119+
protected $imageLocation;
120+
121+
/**
122+
* List of included JS scripts
123+
*
124+
* @var array
125+
*/
126+
protected $includedJsScripts = array();
127+
128+
/**
129+
* List of included JS snippets
130+
*
131+
* @var array
132+
*/
133+
protected $includedJsSnippets = array();
134+
107135
/**
108136
* Capture constructor.
109137
*/
@@ -118,18 +146,31 @@ public function __construct($url = null)
118146

119147
$this->jobs = new Jobs();
120148
$this->output = new Output();
149+
150+
$this->setImageType(Types\Jpg::FORMAT);
121151
}
122152

153+
/**
154+
* Saves the screenshot to the requested location
155+
*
156+
* @param string $imageLocation Image Location
157+
* @param bool $deleteFileIfExists True to delete the file if it exists
158+
*
159+
* @return bool
160+
*/
123161
public function save($imageLocation, $deleteFileIfExists = true)
124162
{
125-
$outputPath = $this->output->getLocation() . $imageLocation;
163+
$this->imageLocation = $this->output->getLocation() . $imageLocation;
164+
165+
if (!pathinfo($this->imageLocation, PATHINFO_EXTENSION)) {
166+
$this->imageLocation .= '.' . $this->getImageType()->getFormat();
167+
}
126168

127169
$data = array(
128170
'url' => $this->url,
129171
'width' => $this->width,
130172
'height' => $this->height,
131-
// If used on windows the \ char needs to be handled to be used on a js string
132-
'imageLocation' => str_replace("\\", "\\\\", $outputPath),
173+
'imageLocation' => LocalPath::sanitize($this->imageLocation),
133174
);
134175

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

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

154-
if ($this->resourceTimeout) {
155-
$data['resourceTimeout'] = $this->resourceTimeout;
195+
if ($this->timeout) {
196+
$data['timeout'] = $this->timeout;
197+
}
198+
199+
if ($this->includedJsScripts) {
200+
$data['includedJsScripts'] = $this->includedJsScripts;
201+
}
202+
203+
if ($this->includedJsSnippets) {
204+
$data['includedJsSnippets'] = $this->includedJsSnippets;
156205
}
157206

158-
if ($deleteFileIfExists && file_exists($outputPath) && is_writable($outputPath)) {
159-
unlink($outputPath);
207+
if ($deleteFileIfExists && file_exists($this->imageLocation) && is_writable($this->imageLocation)) {
208+
unlink($this->imageLocation);
160209
}
161210

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

174-
return file_exists($outputPath);
223+
return file_exists($this->imageLocation);
175224
}
176225

177226
private function getTemplateResult($templateName, array $args)
178227
{
179228
$templatePath = $this->templatePath . DIRECTORY_SEPARATOR . $templateName . '.php';
180229
if (!file_exists($templatePath)) {
181-
throw new \Exception("The template {$templateName} does not exist!");
230+
throw new TemplateNotFoundException($templateName);
182231
}
183232
ob_start();
184233
extract($args);
@@ -210,19 +259,7 @@ public function setBinPath($binPath)
210259
*/
211260
public function setUrl($url)
212261
{
213-
// Prepend http:// if the url doesn't contain it
214-
if (!stristr($url, 'http://') && !stristr($url, 'https://')) {
215-
$url = 'http://' . $url;
216-
}
217-
218-
if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
219-
throw new \Exception("Invalid URL");
220-
}
221-
222-
$url = str_replace(array(';', '"', '<?'), '', strip_tags($url));
223-
$url = str_replace(array('\077', '\''), array(' ', '/'), $url);
224-
225-
$this->url = $url;
262+
$this->url = new Url($url);
226263
}
227264

228265
/**
@@ -296,49 +333,37 @@ public function setBackgroundColor($backgroundColor)
296333
}
297334

298335
/**
299-
* Sets the image format
336+
* Sets the image type
300337
*
301-
* @param string $format 'jpg' | 'png'
338+
* @param string $type 'jpg', 'png', etc...
302339
*
303340
* @return Capture
304341
*/
305-
public function setFormat($format)
342+
public function setImageType($type)
306343
{
307-
$format = strtolower($format);
308-
if (!in_array($format, ['jpg', 'png'])) {
309-
throw new Exception(
310-
"Invalid image format '{$format}'. " .
311-
"Allowed formats are 'jpg' and 'png'"
312-
);
313-
}
314-
315-
$this->format = $format;
344+
$this->imageType = Types::getClass($type);
316345

317346
return $this;
318347
}
319348

320349
/**
321-
* Gets the image format
350+
* Returns the image type instance
322351
*
323-
* @return string
352+
* @return Type
324353
*/
325-
public function getFormat()
354+
public function getImageType()
326355
{
327-
return $this->format;
356+
return $this->imageType;
328357
}
329358

330359
/**
331-
* Gets the MIME type of resulted image
360+
* Returns the location where the screenshot file was written
332361
*
333362
* @return string
334363
*/
335-
public function getMimeType()
364+
public function getImageLocation()
336365
{
337-
if ($this->format === 'png') {
338-
return 'image/png';
339-
}
340-
341-
return 'image/jpeg';
366+
return $this->imageLocation;
342367
}
343368

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

358383
/**
359384
* Sets the timeout period
360-
* @param int $timeout
361-
* @return $this
385+
*
386+
* @param int $timeout Timeout period
387+
*
388+
* @return Capture
389+
* @throws InvalidArgumentException
362390
*/
363-
public function setResourceTimeout($timeout = 30000)
391+
public function setTimeout($timeout)
364392
{
365-
$this->resourceTimeout = $timeout;
393+
if (!is_numeric($timeout)) {
394+
throw new InvalidArgumentException('The timeout value must be a number.');
395+
}
396+
$this->timeout = $timeout;
397+
398+
return $this;
399+
}
400+
401+
/**
402+
* Adds a JS script or snippet to the screen shot script
403+
*
404+
* @param string|URL $script Script to include
405+
*
406+
* @return Capture
407+
*/
408+
public function includeJs($script)
409+
{
410+
if (is_a($script, Url::class)) {
411+
$this->includedJsScripts[] = $script;
412+
} else {
413+
$this->includedJsSnippets[] = $script;
414+
}
415+
366416
return $this;
367417
}
368418
}

0 commit comments

Comments
 (0)