Skip to content

Commit

Permalink
rewrite options passing
Browse files Browse the repository at this point in the history
  • Loading branch information
andrej-griniuk committed Apr 21, 2018
1 parent bd33039 commit d0a9439
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 85 deletions.
1 change: 1 addition & 0 deletions config/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ function (Event $event) {
$controller = $event->getSubject();
if ($controller->components()->has('RequestHandler')) {
$controller->RequestHandler->setConfig('viewClassMap.jpg', 'HtmlToImageView.HtmlToImage');
$controller->RequestHandler->setConfig('viewClassMap.png', 'HtmlToImageView.HtmlToImage');
}
}
);
54 changes: 28 additions & 26 deletions src/View/HtmlToImageView.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace HtmlToImageView\View;

use Cake\Core\Configure;
use Cake\Core\Exception\Exception;
use Cake\Event\EventManager;
use Cake\Http\Response;
Expand All @@ -23,6 +24,13 @@ class HtmlToImageView extends View
*/
protected $_binary = '/usr/bin/wkhtmltoimage';

/**
* List of allowed options for wkhtmltoimage command
*
* @var array
*/
protected $_allowedImageOptions = ['crop-w', 'crop-h', 'crop-x', 'crop-y', 'width', 'height', 'format', 'quality', 'zoom'];

/**
* Flag to indicate if the environment is windows
*
Expand All @@ -31,35 +39,33 @@ class HtmlToImageView extends View
protected $_windowsEnvironment;

/**
* The subdirectory. Image views are always in img.
* The subdirectory for image views
*
* @var string|null
*/
public $subDir = 'img';

/**
* The name of the layouts sub folder containing layouts for this View.
* The name of the layouts sub folder containing layouts for this View
*
* @var string|null
*/
public $layoutPath = 'img';

/**
* List of image config collected from the associated controller.
* List of image options
*
* @var array
*/
public $imageConfig = [];
public $imageOptions = [];

/**
* Constructor
*
* @param \Cake\Http\ServerRequest $request Request instance.
* @param \Cake\Http\Response $response Response instance.
* @param \Cake\Event\EventManager $eventManager Event manager instance.
* @param array $viewOptions View options. See View::$_passedVars for list of
* options which get set as class properties.
*
* @param array $viewOptions View options. See View::$_passedVars for list of options which get set as class properties.
* @throws \Cake\Core\Exception\Exception
*/
public function __construct(
Expand All @@ -68,27 +74,16 @@ public function __construct(
EventManager $eventManager = null,
array $viewOptions = []
) {
$this->_passedVars[] = 'imageConfig';
$this->_passedVars[] = 'imageOptions';
$this->_windowsEnvironment = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';

parent::__construct($request, $response, $eventManager, $viewOptions);

if (Hash::get($viewOptions, 'templatePath') == 'Error') {
$this->subDir = null;
$this->layoutPath = null;
$this->response = $this->response->withType('html');

return;
}

if ($binary = Hash::get($this->imageConfig, 'binary')) {
$this->_binary = $binary;
}

if (!Hash::get($this->imageConfig, 'options.format')) {
$this->imageConfig['options']['format'] = $this->request->getParam('_ext', 'jpg');
}

$this->response = $this->response->withType($this->imageConfig['options']['format']);
}

/**
Expand Down Expand Up @@ -139,7 +134,7 @@ public function output($html)
}

/**
* Execute the WkHtmlToImage command to render image
* Execute the wkhtmltoimage command to render image
*
* @param string $cmd the command to execute
* @param string $input Html to pass to wkhtmltoimage
Expand Down Expand Up @@ -172,16 +167,23 @@ protected function _exec($cmd, $input)
*/
protected function _getCommand()
{
if ($binary = Configure::read('HtmlToImageView.binary')) {
$this->_binary = $binary;
}

if (!is_executable($this->_binary)) {
throw new Exception(sprintf('wkhtmltoimage binary is not found or not executable: %s', $this->_binary));
}

$options = (array)Hash::get($this->imageConfig, 'options', []);
if ($imageOptions = (array)Hash::get($this->viewOptions(), 'imageOptions', [])) {
$this->imageOptions = array_merge($this->imageOptions, $imageOptions);
}

if (!Hash::get($this->imageOptions, 'format')) {
$this->imageOptions['format'] = $this->request->getParam('_ext', 'jpg');
}

$options = array_intersect_key(
$options,
array_flip(['crop-w', 'crop-h', 'crop-x', 'crop-y', 'width', 'height', 'format', 'quality', 'zoom'])
);
$options = array_intersect_key($this->imageOptions, array_flip($this->_allowedImageOptions));
$options['quiet'] = true;

if ($this->_windowsEnvironment) {
Expand Down
80 changes: 21 additions & 59 deletions tests/TestCase/View/HtmlToImageViewTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace ImageView\View;

use Cake\Core\Configure;
use Cake\Core\Exception\Exception;
use Cake\Http\Response;
use Cake\Http\ServerRequest;
Expand All @@ -27,6 +28,7 @@ public function setUp()
{
parent::setUp();

Configure::write('HtmlToImageView.binary', '/bin/echo');
$request = new ServerRequest();
$response = new Response();
$this->View = new HtmlToImageView($request, $response);
Expand Down Expand Up @@ -57,7 +59,7 @@ public function testConstructor()
public function testRender()
{
$request = new ServerRequest();
$response = new Response();
$response = new Response(['type' => 'image/jpeg']);
$this->View = $this->getMockBuilder('HtmlToImageView\View\HtmlToImageView')
->setConstructorArgs([$request, $response])
->setMethods(['output'])
Expand All @@ -82,16 +84,7 @@ public function testOutput()
$request = new ServerRequest();
$response = new Response();
$this->View = $this->getMockBuilder('HtmlToImageView\View\HtmlToImageView')
->setConstructorArgs([
$request,
$response,
null,
[
'imageConfig' => [
'binary' => '/bin/echo'
]
]
])
->setConstructorArgs([$request, $response])
->setMethods(['_exec'])
->getMock();

Expand All @@ -116,16 +109,7 @@ public function testOutputNoData()
$request = new ServerRequest();
$response = new Response();
$this->View = $this->getMockBuilder('HtmlToImageView\View\HtmlToImageView')
->setConstructorArgs([
$request,
$response,
null,
[
'imageConfig' => [
'binary' => '/bin/echo'
]
]
])
->setConstructorArgs([$request, $response])
->setMethods(['_exec'])
->getMock();

Expand All @@ -152,16 +136,7 @@ public function testOutputError()
$request = new ServerRequest();
$response = new Response();
$this->View = $this->getMockBuilder('HtmlToImageView\View\HtmlToImageView')
->setConstructorArgs([
$request,
$response,
null,
[
'imageConfig' => [
'binary' => '/bin/echo'
]
]
])
->setConstructorArgs([$request, $response])
->setMethods(['_exec'])
->getMock();

Expand Down Expand Up @@ -193,40 +168,31 @@ public function testGetCommand()
$method = $class->getMethod('_getCommand');
$method->setAccessible(true);

$this->View = new HtmlToImageView($request, $response, null, [
'imageConfig' => [
'binary' => '/bin/echo'
]
]);
$this->View = new HtmlToImageView($request, $response);
$result = $method->invokeArgs($this->View, []);
$expected = "/bin/echo --format 'jpg' --quiet - -";
$this->assertEquals($expected, $result);

Configure::write('HtmlToImageView.binary', '/bin/sh');
$this->View = new HtmlToImageView($request, $response, null, [
'imageConfig' => [
'binary' => '/bin/sh',
'options' => [
'crop-w' => 100,
'crop-h' => 200,
'crop-x' => 300,
'crop-y' => 400,
'width' => 500,
'height' => 600,
'format' => 'png',
'quality' => 50,
'zoom' => 1.5,
]
'imageOptions' => [
'crop-w' => 100,
'crop-h' => 200,
'crop-x' => 300,
'crop-y' => 400,
'width' => 500,
'height' => 600,
'format' => 'png',
'quality' => 50,
'zoom' => 1.5,
]
]);
$result = $method->invokeArgs($this->View, []);
$expected = "/bin/sh --crop-w '100' --crop-h '200' --crop-x '300' --crop-y '400' --width '500' --height '600' --format 'png' --quality '50' --zoom '1.5' --quiet - -";
$this->assertEquals($expected, $result);

$this->View = new HtmlToImageView($request, $response, null, [
'imageConfig' => [
'binary' => '/bin/nonexisting',
]
]);
Configure::write('HtmlToImageView.binary', '/bin/nonexisting');
$this->View = new HtmlToImageView($request, $response);
$this->expectException(Exception::class);
$this->expectExceptionMessage('wkhtmltoimage binary is not found or not executable: /bin/nonexisting');
$method->invokeArgs($this->View, []);
Expand All @@ -246,11 +212,7 @@ public function testExec()
$method = $class->getMethod('_exec');
$method->setAccessible(true);

$this->View = new HtmlToImageView($request, $response, null, [
'imageConfig' => [
'binary' => '/bin/echo'
]
]);
$this->View = new HtmlToImageView($request, $response);

$result = $method->invokeArgs($this->View, ['/bin/echo test', 'test']);
$expected = [
Expand Down

0 comments on commit d0a9439

Please sign in to comment.