Skip to content

Commit d661e48

Browse files
authored
Inject js (#63)
* 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
1 parent ce9a5d8 commit d661e48

22 files changed

+478
-60
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: 88 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
namespace Screen;
44

5+
use Screen\Exceptions\TemplateNotFoundException;
6+
use Screen\Image\Types;
7+
use Screen\Image\Types\Type;
8+
use Screen\Injection\LocalPath;
9+
use Screen\Injection\Url;
510
use Screen\Location\Jobs;
611
use Screen\Location\Output;
712

@@ -57,11 +62,11 @@ class Capture
5762
protected $backgroundColor = '';
5863

5964
/**
60-
* Image format
65+
* Image Type, default is jpeg
6166
*
62-
* @var string
67+
* @var Type
6368
*/
64-
protected $format = 'jpg';
69+
protected $imageType;
6570

6671
/**
6772
* User Agent String used on the page request
@@ -98,6 +103,27 @@ class Capture
98103
*/
99104
public $output;
100105

106+
/**
107+
* Location where the file was written to
108+
*
109+
* @var string
110+
*/
111+
protected $imageLocation;
112+
113+
/**
114+
* List of included JS scripts
115+
*
116+
* @var array
117+
*/
118+
protected $includedJsScripts = array();
119+
120+
/**
121+
* List of included JS snippets
122+
*
123+
* @var array
124+
*/
125+
protected $includedJsSnippets = array();
126+
101127
/**
102128
* Capture constructor.
103129
*/
@@ -112,18 +138,31 @@ public function __construct($url = null)
112138

113139
$this->jobs = new Jobs();
114140
$this->output = new Output();
141+
142+
$this->setImageType(Types\Jpg::FORMAT);
115143
}
116144

145+
/**
146+
* Saves the screenshot to the requested location
147+
*
148+
* @param string $imageLocation Image Location
149+
* @param bool $deleteFileIfExists True to delete the file if it exists
150+
*
151+
* @return bool
152+
*/
117153
public function save($imageLocation, $deleteFileIfExists = true)
118154
{
119-
$outputPath = $this->output->getLocation() . $imageLocation;
155+
$this->imageLocation = $this->output->getLocation() . $imageLocation;
156+
157+
if (!pathinfo($this->imageLocation, PATHINFO_EXTENSION)) {
158+
$this->imageLocation .= '.' . $this->getImageType()->getFormat();
159+
}
120160

121161
$data = array(
122162
'url' => $this->url,
123163
'width' => $this->width,
124164
'height' => $this->height,
125-
// If used on windows the \ char needs to be handled to be used on a js string
126-
'imageLocation' => str_replace("\\", "\\\\", $outputPath),
165+
'imageLocation' => LocalPath::sanitize($this->imageLocation),
127166
);
128167

129168
if ($this->clipWidth && $this->clipHeight) {
@@ -135,7 +174,7 @@ public function save($imageLocation, $deleteFileIfExists = true)
135174

136175
if ($this->backgroundColor) {
137176
$data['backgroundColor'] = $this->backgroundColor;
138-
} elseif ($this->getFormat() == 'jpg') {
177+
} elseif ($this->getImageType()->getFormat() == Types\Jpg::FORMAT) {
139178
// If there is no background color set, and it's a jpeg
140179
// we need to set a bg color, otherwise the background will be black
141180
$data['backgroundColor'] = '#FFFFFF';
@@ -145,8 +184,16 @@ public function save($imageLocation, $deleteFileIfExists = true)
145184
$data['userAgent'] = $this->userAgentString;
146185
}
147186

148-
if ($deleteFileIfExists && file_exists($outputPath) && is_writable($outputPath)) {
149-
unlink($outputPath);
187+
if ($this->includedJsScripts) {
188+
$data['includedJsScripts'] = $this->includedJsScripts;
189+
}
190+
191+
if ($this->includedJsSnippets) {
192+
$data['includedJsSnippets'] = $this->includedJsSnippets;
193+
}
194+
195+
if ($deleteFileIfExists && file_exists($this->imageLocation) && is_writable($this->imageLocation)) {
196+
unlink($this->imageLocation);
150197
}
151198

152199
$jobName = md5(json_encode($data));
@@ -161,14 +208,14 @@ public function save($imageLocation, $deleteFileIfExists = true)
161208
$command = sprintf("%sphantomjs %s", $this->binPath, $jobPath);
162209
$result = exec(escapeshellcmd($command));
163210

164-
return file_exists($outputPath);
211+
return file_exists($this->imageLocation);
165212
}
166213

167214
private function getTemplateResult($templateName, array $args)
168215
{
169216
$templatePath = $this->templatePath . DIRECTORY_SEPARATOR . $templateName . '.php';
170217
if (!file_exists($templatePath)) {
171-
throw new \Exception("The template {$templateName} does not exist!");
218+
throw new TemplateNotFoundException($templateName);
172219
}
173220
ob_start();
174221
extract($args);
@@ -200,19 +247,7 @@ public function setBinPath($binPath)
200247
*/
201248
public function setUrl($url)
202249
{
203-
// Prepend http:// if the url doesn't contain it
204-
if (!stristr($url, 'http://') && !stristr($url, 'https://')) {
205-
$url = 'http://' . $url;
206-
}
207-
208-
if (!$url || !filter_var($url, FILTER_VALIDATE_URL)) {
209-
throw new \Exception("Invalid URL");
210-
}
211-
212-
$url = str_replace(array(';', '"', '<?'), '', strip_tags($url));
213-
$url = str_replace(array('\077', '\''), array(' ', '/'), $url);
214-
215-
$this->url = $url;
250+
$this->url = new Url($url);
216251
}
217252

218253
/**
@@ -286,49 +321,37 @@ public function setBackgroundColor($backgroundColor)
286321
}
287322

288323
/**
289-
* Sets the image format
324+
* Sets the image type
290325
*
291-
* @param string $format 'jpg' | 'png'
326+
* @param string $type 'jpg', 'png', etc...
292327
*
293328
* @return Capture
294329
*/
295-
public function setFormat($format)
330+
public function setImageType($type)
296331
{
297-
$format = strtolower($format);
298-
if (!in_array($format, ['jpg', 'png'])) {
299-
throw new Exception(
300-
"Invalid image format '{$format}'. " .
301-
"Allowed formats are 'jpg' and 'png'"
302-
);
303-
}
304-
305-
$this->format = $format;
332+
$this->imageType = Types::getClass($type);
306333

307334
return $this;
308335
}
309336

310337
/**
311-
* Gets the image format
338+
* Returns the image type instance
312339
*
313-
* @return string
340+
* @return Type
314341
*/
315-
public function getFormat()
342+
public function getImageType()
316343
{
317-
return $this->format;
344+
return $this->imageType;
318345
}
319346

320347
/**
321-
* Gets the MIME type of resulted image
348+
* Returns the location where the screenshot file was written
322349
*
323350
* @return string
324351
*/
325-
public function getMimeType()
352+
public function getImageLocation()
326353
{
327-
if ($this->format === 'png') {
328-
return 'image/png';
329-
}
330-
331-
return 'image/jpeg';
354+
return $this->imageLocation;
332355
}
333356

334357
/**
@@ -344,4 +367,22 @@ public function setUserAgentString($userAgentString)
344367

345368
return $this;
346369
}
370+
371+
/**
372+
* Adds a JS script or snippet to the screen shot script
373+
*
374+
* @param string|URL $script Script to include
375+
*
376+
* @return Capture
377+
*/
378+
public function includeJs($script)
379+
{
380+
if (is_a($script, Url::class)) {
381+
$this->includedJsScripts[] = $script;
382+
} else {
383+
$this->includedJsSnippets[] = $script;
384+
}
385+
386+
return $this;
387+
}
347388
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Screen\Exceptions;
4+
5+
class FileNotFoundException extends ScreenException
6+
{
7+
public function __construct($path, $code = 0, Exception $previous = null)
8+
{
9+
$message = sprintf("The file was not found at '%s'.", $path);
10+
11+
parent::__construct($message, $code, $previous);
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Screen\Exceptions;
4+
5+
class InvalidUrlException extends ScreenException
6+
{
7+
public function __construct($url, $code = 0, Exception $previous = null)
8+
{
9+
$message = sprintf("The url '%s' is not valid.", $url);
10+
11+
parent::__construct($message, $code, $previous);
12+
}
13+
}

src/Exceptions/ScreenException.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Screen\Exceptions;
4+
5+
class ScreenException extends \Exception
6+
{
7+
}

0 commit comments

Comments
 (0)