diff --git a/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php b/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php index 57ece517195..e9096645385 100644 --- a/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php +++ b/lib/Cake/Test/Case/View/Helper/HtmlHelperTest.php @@ -553,6 +553,40 @@ public function testImageTagWithTheme() { } } +/** + * testBase64ImageTag method + * + * @return void + */ + public function testBase64ImageTag() { + $this->Html->request->webroot = ''; + + $result = $this->Html->image('cake.icon.png', array('base64' => true)); + $this->assertTags($result, array( + 'img' => array( + 'src' => 'preg:/data:image\/png;base64,(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})/', + 'alt' => '' + ))); + + $result = $this->Html->image('/img/cake.icon.png', array('base64' => true)); + $this->assertTags($result, array( + 'img' => array( + 'src' => 'preg:/data:image\/png;base64,(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})/', + 'alt' => '' + ))); + } + +/** + * testLoadConfigWrongFile method + * + * @return void + * @expectedException InvalidArgumentException + */ + public function testBase64InvalidArgumentException() { + $this->Html->request->webroot = ''; + $this->Html->image('non-existent-image.png', array('base64' => true)); + } + /** * test theme assets in main webroot path * diff --git a/lib/Cake/View/Helper/HtmlHelper.php b/lib/Cake/View/Helper/HtmlHelper.php index e18967e4aef..548c61e6bae 100644 --- a/lib/Cake/View/Helper/HtmlHelper.php +++ b/lib/Cake/View/Helper/HtmlHelper.php @@ -20,6 +20,7 @@ App::uses('AppHelper', 'View/Helper'); App::uses('CakeResponse', 'Network'); +App::uses('File', 'Utility'); /** * Html Helper class for easy use of HTML widgets. @@ -809,10 +810,13 @@ protected function _prepareCrumbs($startText, $escape = true) { * `$options['url']`. * - `fullBase` If true the src attribute will get a full address for the image file. * - `plugin` False value will prevent parsing path as a plugin + * - `base64` If true the src attribute will instead be a base64 data URI of the image file. + * Can not be used with external links. * * @param string $path Path to the image file, relative to the app/webroot/img/ directory. * @param array $options Array of HTML attributes. See above for special options. * @return string completed img tag + * @throws InvalidArgumentException - if the image isn't on disk and you have requested the base64 output * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#HtmlHelper::image */ public function image($path, $options = array()) { @@ -829,6 +833,19 @@ public function image($path, $options = array()) { unset($options['url']); } + if (!empty($options['base64']) && !$url) { + $fullPath = WWW_ROOT . $path; + $file = new File($fullPath, false); + if (!$file->exists() || !$file->readable()) { + throw new InvalidArgumentException(__d('cake', 'Unable to find the requested image to output as base64!')); + } + + $base64 = base64_encode($file->read()); + $type = $file->mime(); + unset($options['base64']); + $path = sprintf('data:%s;base64,%s', $type, $base64); + } + $image = sprintf($this->_tags['image'], $path, $this->_parseAttributes($options)); if ($url) {