From 7d993d8736a73a71891e401ff706d70985587118 Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Tue, 9 Apr 2024 12:11:18 +0100 Subject: [PATCH 1/8] feat: Add screenshot support --- src/Browserless.php | 94 ++---------------------- src/Browserless/Client.php | 108 ++++++++++++++++++++++++++++ src/Browserless/Screenshot.php | 35 +++++++++ test/Browserless/ScreenshotTest.php | 36 ++++++++++ test/BrowserlessTest.php | 2 - 5 files changed, 184 insertions(+), 91 deletions(-) create mode 100644 src/Browserless/Client.php create mode 100644 src/Browserless/Screenshot.php create mode 100644 test/Browserless/ScreenshotTest.php diff --git a/src/Browserless.php b/src/Browserless.php index 304ab04..9c6df62 100644 --- a/src/Browserless.php +++ b/src/Browserless.php @@ -2,29 +2,20 @@ namespace SynergiTech\ChromePDF; -use GuzzleHttp\Psr7\StreamWrapper; +use SynergiTech\ChromePDF\Browserless\Client; /** * Driver to render PDFs remotely using browserless.io */ class Browserless extends AbstractPDF { - /** - * @var string|null - */ - private $apiKey; - /** - * @var string - */ - private $apiUrl = 'https://chrome.browserless.io'; + use Client; + /** * @var string */ private $pdfEndpoint = '/pdf'; - /** - * @var \GuzzleHttp\Client - */ - private $client; + /** * @var bool */ @@ -38,25 +29,6 @@ class Browserless extends AbstractPDF */ private $timeout; - /** - * @param string $apiKey api key from browserless.io - * @param \GuzzleHttp\Client $client custom Guzzle client - */ - public function __construct(string $apiKey = null, $client = null) - { - if ($client === null) { - // @codeCoverageIgnoreStart - $client = new \GuzzleHttp\Client([ - 'base_uri' => $this->apiUrl, - ]); - // @codeCoverageIgnoreEnd - } - $this->client = $client; - if ($apiKey !== null) { - $this->setApiKey($apiKey); - } - } - /** * Sets the PDF documents rotation * @@ -69,18 +41,6 @@ public function setRotation(int $rotation = null): self return $this; } - /** - * Sets the browserless API key - * - * @param string $apiKey - * @return self - */ - public function setApiKey(string $apiKey): self - { - $this->apiKey = $apiKey; - return $this; - } - /** * Sets whether or not to ask Browserless to attempt to render the document in safe mode * @@ -116,16 +76,6 @@ public function getTimeout(): ?int return $this->timeout; } - /** - * Retrieves the browserless.io API key - * - * @return string|null - */ - public function getApiKey(): ?string - { - return $this->apiKey; - } - /** * Whether the document will be rendered in safe mode or not * @@ -232,41 +182,7 @@ public function getFormattedOptions(): array */ private function render(array $options) { - try { - $response = $this->client->post($this->pdfEndpoint, [ - 'query' => [ - 'token' => $this->getApiKey(), - ], - 'json' => $options, - ]); - } catch (\GuzzleHttp\Exception\ClientException $e) { - $message = 'No response'; - - $response = $e->getResponse(); - - /** - * You could use $e->hasResponse() but that is not accurate enough, - * as phpstan will be analysing against method signatures from guzzle 6 & 7 - */ - if ($response !== null) { - $message = $response->getBody(); - - $json = json_decode($message); - if (json_last_error() === JSON_ERROR_NONE) { - $messages = []; - foreach ($json as $error) { - $messages[] = $error->message; - } - $message = implode(', ', $messages); - } - } - - throw new Browserless\APIException("Failed to render PDF: {$message}", $e->getCode(), $e); - } catch (\Exception $e) { - throw new Browserless\APIException("Failed to render PDF: {$e->getMessage()}", $e->getCode(), $e); - } - - return StreamWrapper::getResource($response->getBody()); + return $this->request($this->pdfEndpoint, $options); } /** diff --git a/src/Browserless/Client.php b/src/Browserless/Client.php new file mode 100644 index 0000000..e408985 --- /dev/null +++ b/src/Browserless/Client.php @@ -0,0 +1,108 @@ + $this->apiUrl, + ]); + // @codeCoverageIgnoreEnd + } + $this->client = $client; + if ($apiKey !== null) { + $this->setApiKey($apiKey); + } + } + + /** + * Retrieves the browserless.io API key + * + * @return string|null + */ + public function getApiKey(): ?string + { + return $this->apiKey; + } + + /** + * @param array $json + * + * @return resource + */ + protected function request(string $endpoint, array $json) + { + try { + $response = $this->client->post($endpoint, [ + 'query' => [ + 'token' => $this->getApiKey(), + ], + 'json' => $json, + ]); + } catch (\GuzzleHttp\Exception\ClientException $e) { + $message = 'No response'; + + $response = $e->getResponse(); + + /** + * You could use $e->hasResponse() but that is not accurate enough, + * as phpstan will be analysing against method signatures from guzzle 6 & 7 + */ + if ($response !== null) { + $message = $response->getBody(); + + $json = json_decode($message); + if (json_last_error() === JSON_ERROR_NONE) { + $messages = []; + foreach ($json as $error) { + $messages[] = $error->message; + } + $message = implode(', ', $messages); + } + } + + throw new APIException("Failed to render PDF: {$message}", $e->getCode(), $e); + } catch (\Exception $e) { + throw new APIException("Failed to render PDF: {$e->getMessage()}", $e->getCode(), $e); + } + + return StreamWrapper::getResource($response->getBody()); + } + + /** + * Sets the browserless API key + * + * @param string $apiKey + * @return self + */ + private function setApiKey(string $apiKey): self + { + $this->apiKey = $apiKey; + return $this; + } +} diff --git a/src/Browserless/Screenshot.php b/src/Browserless/Screenshot.php new file mode 100644 index 0000000..0dcf9b1 --- /dev/null +++ b/src/Browserless/Screenshot.php @@ -0,0 +1,35 @@ + $options see https://www.browserless.io/docs/screenshot#custom-options + * + * @return resource + */ + public function render(string $url, array $options = []) + { + $options = array_merge([ + 'quality' => 75, + 'type' => 'jpeg', + 'fullPage' => false, + ], $options); + + return $this->request( + endpoint: '/screenshot', + json: [ + 'url' => $url, + 'options' => $options, + ] + ); + } +} diff --git a/test/Browserless/ScreenshotTest.php b/test/Browserless/ScreenshotTest.php new file mode 100644 index 0000000..4373676 --- /dev/null +++ b/test/Browserless/ScreenshotTest.php @@ -0,0 +1,36 @@ +getMockBuilder(Chrome::class) + ->setMethods(['post']) + ->getMock(); + } + + public function test_render() + { + $client = $this->getMockedClient(); + + $client->expects($this->once()) + ->method('post') + ->with($this->anything(), $this->hasKeyValue(['json', 'url'], $this->identicalTo('test'))) + ->willReturn(new Response(200, [], 'screenshot')); + + $bl = new Screenshot('', $client); + $stream = $bl->render('test'); + + $this->assertIsResource($stream); + $this->assertSame('screenshot', fgets($stream)); + } +} diff --git a/test/BrowserlessTest.php b/test/BrowserlessTest.php index a874461..449077f 100644 --- a/test/BrowserlessTest.php +++ b/test/BrowserlessTest.php @@ -15,8 +15,6 @@ use SynergiTech\ChromePDF\Chrome; use SynergiTech\ChromePDF\Test\TestCase; -use PHPUnit\Framework\Constraint\ArraySubset; - class BrowserlessTest extends TestCase { private function getMockedClient() From f708e95daef49a6afca5363b1ac180646c331330 Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Tue, 9 Apr 2024 13:29:31 +0100 Subject: [PATCH 2/8] Make some final changes to tidy up the code --- src/Browserless/Client.php | 4 ++++ src/Browserless/Screenshot.php | 4 +++- test/Browserless/ScreenshotTest.php | 7 ------- test/BrowserlessTest.php | 7 ------- test/TestCase.php | 8 ++++++++ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Browserless/Client.php b/src/Browserless/Client.php index e408985..6b44123 100644 --- a/src/Browserless/Client.php +++ b/src/Browserless/Client.php @@ -21,6 +21,10 @@ trait Client */ private $apiUrl = 'https://chrome.browserless.io'; + public const EUROPE_REGION_URL = 'production-lon.browserless.io'; + + public const US_REGION_URL = 'production-sfo.browserless.io'; + /** * @param string $apiKey api key from browserless.io * @param \GuzzleHttp\Client $client custom Guzzle client diff --git a/src/Browserless/Screenshot.php b/src/Browserless/Screenshot.php index 0dcf9b1..7675a46 100644 --- a/src/Browserless/Screenshot.php +++ b/src/Browserless/Screenshot.php @@ -19,10 +19,12 @@ class Screenshot public function render(string $url, array $options = []) { $options = array_merge([ - 'quality' => 75, 'type' => 'jpeg', 'fullPage' => false, ], $options); + if ($options['type'] === 'jpeg' && ! isset($options['quality'])) { + $options['quality'] = 75; + } return $this->request( endpoint: '/screenshot', diff --git a/test/Browserless/ScreenshotTest.php b/test/Browserless/ScreenshotTest.php index 4373676..e498a8a 100644 --- a/test/Browserless/ScreenshotTest.php +++ b/test/Browserless/ScreenshotTest.php @@ -11,13 +11,6 @@ class ScreenshotTest extends TestCase { - private function getMockedClient() - { - return $this->getMockBuilder(Chrome::class) - ->setMethods(['post']) - ->getMock(); - } - public function test_render() { $client = $this->getMockedClient(); diff --git a/test/BrowserlessTest.php b/test/BrowserlessTest.php index 449077f..ba7d589 100644 --- a/test/BrowserlessTest.php +++ b/test/BrowserlessTest.php @@ -17,13 +17,6 @@ class BrowserlessTest extends TestCase { - private function getMockedClient() - { - return $this->getMockBuilder(Chrome::class) - ->setMethods(['post']) - ->getMock(); - } - public function test_rotation() { $client = $this->getMockedClient(); diff --git a/test/TestCase.php b/test/TestCase.php index 1ee7add..97786c0 100644 --- a/test/TestCase.php +++ b/test/TestCase.php @@ -3,6 +3,7 @@ namespace SynergiTech\ChromePDF\Test; use PHPUnit\Framework\TestCase as PHPUnitTestCase; +use SynergiTech\ChromePDF\Chrome; class TestCase extends PHPUnitTestCase { @@ -10,4 +11,11 @@ public function hasKeyValue($key, $constraint = null) { return new Constraint\ArrayHasKeyValue($key, $constraint); } + + protected function getMockedClient() + { + return $this->getMockBuilder(Chrome::class) + ->setMethods(['post']) + ->getMock(); + } } From 2b8d038bb0f79cc7d1f1d0e7fff7c9a3d28e1a8a Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Tue, 9 Apr 2024 13:31:31 +0100 Subject: [PATCH 3/8] Drop support for php 7.x --- .github/workflows/main.yml | 12 ++---------- composer.json | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d60e03c..98dbd17 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,17 +8,9 @@ jobs: strategy: fail-fast: false matrix: - php: [7.3, 7.4, "8.0", 8.1, 8.2, 8.3] - symfony_process: [4, 5, 6, 7] + php: ["8.0", 8.1, 8.2, 8.3] + symfony_process: [7] exclude: - - php: 7.3 - symfony_process: 6 - - php: 7.4 - symfony_process: 6 - - php: 7.3 - symfony_process: 7 - - php: 7.4 - symfony_process: 7 - php: "8.0" symfony_process: 7 - php: 8.1 diff --git a/composer.json b/composer.json index 56ce567..6dc4ae3 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": "^7.3|^8.0|^8.1", + "php": "^8.0|^8.1", "symfony/process": "~4.0 || ~5.0 || ~6.0 || ~7.0", "guzzlehttp/guzzle": "^6.3 || ^7.0" }, From bc0b0acb8d449447a6027827c35066e0c7ff7293 Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Tue, 9 Apr 2024 13:34:52 +0100 Subject: [PATCH 4/8] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 466ce7b..d1c5c86 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ composer require synergitech/chrome-pdf-php If you are planning to use the [`chrome-pdf`](https://github.com/SynergiTech/chrome-pdf) driver to render PDFs locally, you should also make sure to install this from npm. ### browserless -If you are planning to use the [browserless](https://www.browserless.io/) driver to render PDFs remotely, you should register for an API key. Remember that local assets cannot be rendered by browserless. +If you are planning to use the [browserless](https://www.browserless.io/) driver to render PDFs remotely or take screenshots, you should register for an API key. Remember that local assets cannot be rendered by browserless. ## Usage A common interface is provided via AbstractPDF. The options presented via this class will be available from all drivers. @@ -25,12 +25,22 @@ You should instantiate one of the available drivers, potentially passing options ```php use SynergiTech\ChromePDF\Chrome; use SynergiTech\ChromePDF\Browserless; +use SynergiTech\ChromePDF\Browserless\Screenshot; $pdf = new Chrome('path-to-chrome-pdf'); $pdf->renderContent('

test

'); $pdf = new Browserless('your-api-key'); $pdf->renderContent('

test

'); + +// For information on options, see https://www.browserless.io/docs/screenshot#custom-options. +// `render()` defaults to using jpeg with a quality of 75 and fullPage set to false. +$file = new Screenshot('your-api-key'); +$file->render('https://example.com'); +$file->render('https://example.com', [ + 'fullPage' => true, + 'type' => 'png', +]); ``` ## Examples From 15d895d7dbf3d6486aaef4f1d568a432abaf6b1e Mon Sep 17 00:00:00 2001 From: Edward Bebbington Date: Wed, 10 Apr 2024 09:22:32 +0100 Subject: [PATCH 5/8] update readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d1c5c86..f5eaa74 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ # PHP ChromePDF Renderer -![Unit tests](https://github.com/SynergiTech/chrome-pdf-php/workflows/Unit%20tests/badge.svg) [![Tests](https://github.com/SynergiTech/chrome-pdf-php/actions/workflows/main.yml/badge.svg)](https://github.com/SynergiTech/chrome-pdf-php/actions/workflows/main.yml) _For pre-V1 documentation [click here](https://github.com/SynergiTech/chrome-pdf-php/blob/v0/README.md)_ @@ -8,6 +7,8 @@ This is a library for creating PDFs from HTML rendered with the SkPDF backend vi * [SynergiTech/chrome-pdf](https://github.com/SynergiTech/chrome-pdf) * [browserless](https://www.browserless.io/) +Currently supports PHP ^8 + ## Installation ``` composer require synergitech/chrome-pdf-php From dc6e37e44af7a877945631139cc37747523dc2d0 Mon Sep 17 00:00:00 2001 From: William Hall Date: Wed, 10 Apr 2024 13:15:08 +0100 Subject: [PATCH 6/8] =?UTF-8?q?=F0=9F=9A=A7=20what=20if=20we=20dropped=208?= =?UTF-8?q?.0=20to=20get=20enums?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/main.yml | 12 +++++------- Dockerfile | 2 +- composer.json | 2 +- src/Browserless/Client.php | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 98dbd17..bc08f5c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,13 +8,11 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.0", 8.1, 8.2, 8.3] - symfony_process: [7] - exclude: - - php: "8.0" - symfony_process: 7 - - php: 8.1 - symfony_process: 7 + php: [8.1, 8.2, 8.3] + symfony_process: [4, 5, 6, 7] + # exclude: + # - php: 8.1 + # symfony_process: 7 steps: - uses: actions/checkout@v4 diff --git a/Dockerfile b/Dockerfile index e80f648..9394d4f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG PHP_VERSION=8.0 +ARG PHP_VERSION=8.1 FROM php:$PHP_VERSION-cli-alpine RUN apk add git zip unzip autoconf make g++ diff --git a/composer.json b/composer.json index 6dc4ae3..969044c 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": "^8.0|^8.1", + "php": "^8.1", "symfony/process": "~4.0 || ~5.0 || ~6.0 || ~7.0", "guzzlehttp/guzzle": "^6.3 || ^7.0" }, diff --git a/src/Browserless/Client.php b/src/Browserless/Client.php index 6b44123..78dc455 100644 --- a/src/Browserless/Client.php +++ b/src/Browserless/Client.php @@ -21,9 +21,9 @@ trait Client */ private $apiUrl = 'https://chrome.browserless.io'; - public const EUROPE_REGION_URL = 'production-lon.browserless.io'; + // public const EUROPE_REGION_URL = 'production-lon.browserless.io'; - public const US_REGION_URL = 'production-sfo.browserless.io'; + // public const US_REGION_URL = 'production-sfo.browserless.io'; /** * @param string $apiKey api key from browserless.io From dc551ae558706f7a069299d8746d1014e2cac389 Mon Sep 17 00:00:00 2001 From: William Hall Date: Wed, 10 Apr 2024 13:57:19 +0100 Subject: [PATCH 7/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20use=20enums=20for=20en?= =?UTF-8?q?dpoints=20and=20wrap=20it=20all=20up?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/main.yml | 6 ++-- README.md | 29 +++++++++++++----- src/Browserless.php | 2 +- src/Browserless/Client.php | 23 +++++---------- src/Browserless/EndpointsEnum.php | 10 +++++++ src/Browserless/Screenshot.php | 10 ++----- test/Browserless/ScreenshotTest.php | 5 +--- test/BrowserlessTest.php | 46 ++++++++++++++--------------- 8 files changed, 71 insertions(+), 60 deletions(-) create mode 100644 src/Browserless/EndpointsEnum.php diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bc08f5c..9b11f5d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,9 +10,9 @@ jobs: matrix: php: [8.1, 8.2, 8.3] symfony_process: [4, 5, 6, 7] - # exclude: - # - php: 8.1 - # symfony_process: 7 + exclude: + - php: 8.1 + symfony_process: 7 steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index f5eaa74..f53efb2 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ _For pre-V1 documentation [click here](https://github.com/SynergiTech/chrome-pdf-php/blob/v0/README.md)_ +_For pre-V3 documentation [click here](https://github.com/SynergiTech/chrome-pdf-php/blob/v2/README.md)_ + This is a library for creating PDFs from HTML rendered with the SkPDF backend via Chrome. In order to do this, you can opt to use one of the supported drivers: * [SynergiTech/chrome-pdf](https://github.com/SynergiTech/chrome-pdf) -* [browserless](https://www.browserless.io/) - -Currently supports PHP ^8 +* [Browserless](https://www.browserless.io/) ## Installation ``` @@ -16,8 +16,8 @@ composer require synergitech/chrome-pdf-php ### chrome-pdf If you are planning to use the [`chrome-pdf`](https://github.com/SynergiTech/chrome-pdf) driver to render PDFs locally, you should also make sure to install this from npm. -### browserless -If you are planning to use the [browserless](https://www.browserless.io/) driver to render PDFs remotely or take screenshots, you should register for an API key. Remember that local assets cannot be rendered by browserless. +### Browserless +If you are planning to use the [Browserless](https://www.browserless.io/) driver to render PDFs remotely or take screenshots, you should register for an API key. Remember that local assets cannot be rendered by Browserless. ## Usage A common interface is provided via AbstractPDF. The options presented via this class will be available from all drivers. @@ -26,17 +26,32 @@ You should instantiate one of the available drivers, potentially passing options ```php use SynergiTech\ChromePDF\Chrome; use SynergiTech\ChromePDF\Browserless; -use SynergiTech\ChromePDF\Browserless\Screenshot; $pdf = new Chrome('path-to-chrome-pdf'); $pdf->renderContent('

test

'); $pdf = new Browserless('your-api-key'); $pdf->renderContent('

test

'); +``` + +### Advanced Browserless Usage + +You can optionally use specific endpoints when you create a client. + +```php +use SynergiTech\ChromePDF\Browserless; + +$pdf = new Browserless('your-api-key', Browserless\EndpointsEnum::London); +``` + +As this library essentially functions as an API client for Browserless, we have also implemented the screenshot API. + +```php +use SynergiTech\ChromePDF\Browserless; // For information on options, see https://www.browserless.io/docs/screenshot#custom-options. // `render()` defaults to using jpeg with a quality of 75 and fullPage set to false. -$file = new Screenshot('your-api-key'); +$file = new Browserless\Screenshot('your-api-key'); $file->render('https://example.com'); $file->render('https://example.com', [ 'fullPage' => true, diff --git a/src/Browserless.php b/src/Browserless.php index 9c6df62..e09fad2 100644 --- a/src/Browserless.php +++ b/src/Browserless.php @@ -182,7 +182,7 @@ public function getFormattedOptions(): array */ private function render(array $options) { - return $this->request($this->pdfEndpoint, $options); + return $this->request($this->pdfEndpoint, $options); } /** diff --git a/src/Browserless/Client.php b/src/Browserless/Client.php index 78dc455..a7fb539 100644 --- a/src/Browserless/Client.php +++ b/src/Browserless/Client.php @@ -17,24 +17,17 @@ trait Client private $apiKey; /** - * @var string - */ - private $apiUrl = 'https://chrome.browserless.io'; - - // public const EUROPE_REGION_URL = 'production-lon.browserless.io'; - - // public const US_REGION_URL = 'production-sfo.browserless.io'; - - /** - * @param string $apiKey api key from browserless.io * @param \GuzzleHttp\Client $client custom Guzzle client */ - public function __construct(string $apiKey = null, $client = null) - { + public function __construct( + string $apiKey = null, + EndpointsEnum|string $endpoint = EndpointsEnum::Default, + $client = null + ) { if ($client === null) { // @codeCoverageIgnoreStart $client = new \GuzzleHttp\Client([ - 'base_uri' => $this->apiUrl, + 'base_uri' => ($endpoint instanceof EndpointsEnum) ? $endpoint->value : $endpoint, ]); // @codeCoverageIgnoreEnd } @@ -90,9 +83,9 @@ protected function request(string $endpoint, array $json) } } - throw new APIException("Failed to render PDF: {$message}", $e->getCode(), $e); + throw new APIException("Failed to render from Browserless: {$message}", $e->getCode(), $e); } catch (\Exception $e) { - throw new APIException("Failed to render PDF: {$e->getMessage()}", $e->getCode(), $e); + throw new APIException("Failed to render from Browserless: {$e->getMessage()}", $e->getCode(), $e); } return StreamWrapper::getResource($response->getBody()); diff --git a/src/Browserless/EndpointsEnum.php b/src/Browserless/EndpointsEnum.php new file mode 100644 index 0000000..b1b7713 --- /dev/null +++ b/src/Browserless/EndpointsEnum.php @@ -0,0 +1,10 @@ + $options see https://www.browserless.io/docs/screenshot#custom-options + * @param array $options see https://www.browserless.io/docs/screenshot#custom-options * * @return resource */ @@ -22,6 +17,7 @@ public function render(string $url, array $options = []) 'type' => 'jpeg', 'fullPage' => false, ], $options); + if ($options['type'] === 'jpeg' && ! isset($options['quality'])) { $options['quality'] = 75; } @@ -31,7 +27,7 @@ public function render(string $url, array $options = []) json: [ 'url' => $url, 'options' => $options, - ] + ], ); } } diff --git a/test/Browserless/ScreenshotTest.php b/test/Browserless/ScreenshotTest.php index e498a8a..2f634c3 100644 --- a/test/Browserless/ScreenshotTest.php +++ b/test/Browserless/ScreenshotTest.php @@ -3,10 +3,7 @@ namespace SynergiTech\ChromePDF\Test\Browserless; use GuzzleHttp\Psr7\Response; - -use SynergiTech\ChromePDF\Browserless; use SynergiTech\ChromePDF\Browserless\Screenshot; -use SynergiTech\ChromePDF\Chrome; use SynergiTech\ChromePDF\Test\TestCase; class ScreenshotTest extends TestCase @@ -20,7 +17,7 @@ public function test_render() ->with($this->anything(), $this->hasKeyValue(['json', 'url'], $this->identicalTo('test'))) ->willReturn(new Response(200, [], 'screenshot')); - $bl = new Screenshot('', $client); + $bl = new Screenshot(client: $client); $stream = $bl->render('test'); $this->assertIsResource($stream); diff --git a/test/BrowserlessTest.php b/test/BrowserlessTest.php index ba7d589..d7f8893 100644 --- a/test/BrowserlessTest.php +++ b/test/BrowserlessTest.php @@ -29,7 +29,7 @@ public function test_rotation() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $this->assertNull($bl->getRotation()); @@ -54,7 +54,7 @@ public function test_safeMode() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $this->assertFalse($bl->getSafeMode()); @@ -74,7 +74,7 @@ public function test_timeout() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $this->assertNull($bl->getTimeout()); @@ -117,7 +117,7 @@ public function test_displayHeaderFooter() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setDisplayHeaderFooter(true); @@ -155,7 +155,7 @@ public function test_header() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setHeader('header-test'); @@ -180,7 +180,7 @@ public function test_footer() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setFooter('footer-test'); @@ -205,7 +205,7 @@ public function test_format() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setFormat('Letter'); @@ -234,7 +234,7 @@ public function test_width() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setWidth('100px'); @@ -266,7 +266,7 @@ public function test_height() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setHeight('100px'); @@ -298,7 +298,7 @@ public function test_landscape() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setLandscape(true); @@ -374,7 +374,7 @@ public function test_margin() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setMargin('20px'); @@ -415,7 +415,7 @@ public function test_pageRanges() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setPageRanges('2,5-7'); @@ -451,7 +451,7 @@ public function test_preferCSSPageSize() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setPreferCSSPageSize(true); @@ -486,7 +486,7 @@ public function test_printBackground() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setPrintBackground(true); @@ -518,7 +518,7 @@ public function test_scale() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setScale(2); @@ -550,7 +550,7 @@ public function test_waitUntil() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setWaitUntil('domcontentloaded'); @@ -582,7 +582,7 @@ public function test_mediaEmulation() ) ->willReturn(new Response()); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $bl->renderContent('test'); $bl->setMediaEmulation('screen'); @@ -601,7 +601,7 @@ public function test_renderContent() ->with($this->anything(), $this->hasKeyValue(['json', 'html'], $this->identicalTo('test'))) ->willReturn(new Response(200, [], 'rendered-pdf')); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $stream = $bl->renderContent('test'); $this->assertIsResource($stream); @@ -617,7 +617,7 @@ public function test_renderURL() ->with($this->anything(), $this->hasKeyValue(['json', 'url'], $this->identicalTo('https://bbc.co.uk'))) ->willReturn(new Response(200, [], 'rendered-pdf')); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $stream = $bl->renderURL('https://bbc.co.uk'); $this->assertIsResource($stream); @@ -637,7 +637,7 @@ public function test_renderFile() fwrite($tmpfile, 'test file'); $path = stream_get_meta_data($tmpfile)['uri']; - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); $stream = $bl->renderFile($path); $this->assertIsResource($stream); @@ -658,7 +658,7 @@ public function test_plainError() $handler = HandlerStack::create($mock); $client = new Client(['handler' => $handler]); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); try { $stream = $bl->renderContent(''); } catch (APIException $e) { @@ -681,7 +681,7 @@ public function test_jsonError() $handler = HandlerStack::create($mock); $client = new Client(['handler' => $handler]); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); try { $stream = $bl->renderContent(''); } catch (APIException $e) { @@ -705,7 +705,7 @@ public function test_miscError() $handler = HandlerStack::create($mock); $client = new Client(['handler' => $handler]); - $bl = new Browserless('', $client); + $bl = new Browserless(client: $client); try { $stream = $bl->renderContent(''); } catch (APIException $e) { From 8a1b00a1944e749a78604676efb07d8f386d818d Mon Sep 17 00:00:00 2001 From: William Hall Date: Wed, 10 Apr 2024 14:16:01 +0100 Subject: [PATCH 8/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20nobody=20likes=20jpeg?= =?UTF-8?q?=20screenshots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +++-- src/Browserless/Screenshot.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f53efb2..cd7e4c7 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,13 @@ As this library essentially functions as an API client for Browserless, we have use SynergiTech\ChromePDF\Browserless; // For information on options, see https://www.browserless.io/docs/screenshot#custom-options. -// `render()` defaults to using jpeg with a quality of 75 and fullPage set to false. +// `render()` defaults to using png and fullPage set to false +// but jpegs will get a quality of 75 set if you don't set one $file = new Browserless\Screenshot('your-api-key'); $file->render('https://example.com'); $file->render('https://example.com', [ 'fullPage' => true, - 'type' => 'png', + 'type' => 'jpeg', ]); ``` diff --git a/src/Browserless/Screenshot.php b/src/Browserless/Screenshot.php index 9721bde..d1144be 100644 --- a/src/Browserless/Screenshot.php +++ b/src/Browserless/Screenshot.php @@ -14,7 +14,7 @@ class Screenshot public function render(string $url, array $options = []) { $options = array_merge([ - 'type' => 'jpeg', + 'type' => 'png', 'fullPage' => false, ], $options);