diff --git a/VERSIONS_HOTLINE/76959 b/VERSIONS_HOTLINE/76959 new file mode 100644 index 0000000000000000000000000000000000000000..df4b01fbffc4305b4240872e96739e9622239e9c --- /dev/null +++ b/VERSIONS_HOTLINE/76959 @@ -0,0 +1,2 @@ + - ticket #76959 : Ressources numériques : correction du vignettage des images. + \ No newline at end of file diff --git a/application/modules/admin/controllers/FileManagerController.php b/application/modules/admin/controllers/FileManagerController.php index a1304b07524a7d579fef4924c4d57373e2f0af14..bd115c9e017cd3aef594eb2e31d01c0f4f103c89 100644 --- a/application/modules/admin/controllers/FileManagerController.php +++ b/application/modules/admin/controllers/FileManagerController.php @@ -245,7 +245,7 @@ class Admin_FileManagerController extends ZendAfi_Controller_Action { return $this->_redirectWithMessage($this->_('Dimensions "%s" invalident. Les dimensions valident sont : %s .', $dimensions, $available_dimensions)); list($width, $height) = explode('x', $dimensions); - $message = (new Class_Notice_Thumbnail_ResizeImage)->resize($item->getRealpath(), $width, $height, null, true) + $message = (new Class_Notice_Thumbnail_ResizeImage($item))->resize($width, $height) ? $this->_('L\'image "%s" a été redimensionnée.', $item->getId()) : $this->_('Erreur. L\'image "%s" n\'a pas été redimensionnée.', $item->getId()); @@ -257,7 +257,7 @@ class Admin_FileManagerController extends ZendAfi_Controller_Action { $item = $this->_findItemFromParams(); list($width, $height) = explode('x', $item->getDimensions()); - $message = (new Class_Notice_Thumbnail_ResizeImage)->resize($item->getRealpath(), $width, $height, null, true) + $message = (new Class_Notice_Thumbnail_ResizeImage($item))->resize($width, $height) ? $this->_('L\'image "%s" a été compressée.', $item->getId()) : $this->_('Erreur. L\'image "%s" n\'a pas été compressée.', $item->getId()); diff --git a/application/modules/admin/controllers/RecordsController.php b/application/modules/admin/controllers/RecordsController.php index e96e98d516c36bdce0f553659c5e5b28144d3400..9c92ea3ef035cab68d69781f1373c8856bcb968b 100644 --- a/application/modules/admin/controllers/RecordsController.php +++ b/application/modules/admin/controllers/RecordsController.php @@ -27,6 +27,17 @@ class Admin_RecordsController extends ZendAfi_Controller_Action { return $this->_redirectToReferer(); } + if ($album = $record->getAlbum()){ + $album->createThumbnail(); + $url_vignette = $album->getThumbnailUrl(); + + $record->setUrlVignette($url_vignette); + $record->setUrlImage(($poster = $album->getPoster()) ? $poster : $url_vignette); + $record->save(); + + $this->_helper->notify($this->_('Vignette réinitialisée pour "%s"', $record->getTitrePrincipal())); + return $this->_redirectToReferer(); + } $record ->setUrlImage('') diff --git a/library/Class/Album.php b/library/Class/Album.php index a327e18ca146cf59e64325d7eb8026e3ab95ddc4..7e8f2dacb0c08bf3a53a1692812ac2329df80757 100644 --- a/library/Class/Album.php +++ b/library/Class/Album.php @@ -685,8 +685,8 @@ class Class_Album extends Storm_Model_Abstract { $on_update = function($old_file, $new_file) use ($to_delete) { if ($old_file && $old_file != $new_file) - foreach($to_delete as $item) - $this->getFileSystem()->unlink($item); + foreach($to_delete as $item) + $this->getFileSystem()->unlink($item); $this->createThumbnail(); @@ -723,6 +723,9 @@ class Class_Album extends Storm_Model_Abstract { if (!$this->hasFichier()) return true; + if ($this->getFileSystem()->file_exists($this->getThumbnailPath())) + return true; + try { $image = new Imagick($this->getVignettePath()); $image->thumbnailImage(160, 0); diff --git a/library/Class/FileManager.php b/library/Class/FileManager.php index 060eb15fff711c035913f03225d14abee7213d5d..f0214ce526100f72dca8e9d56343d0489d6b7d32 100644 --- a/library/Class/FileManager.php +++ b/library/Class/FileManager.php @@ -148,25 +148,43 @@ class Class_FileManager extends Class_Entity { protected static function _findPathIn($url_or_path) { - if(!$url_or_path) + if (!$url_or_path) return; - if(!is_string($url_or_path)) + if (!is_string($url_or_path)) return; - if(!Class_Url::isAnUrl($url_or_path)) - return $url_or_path; + return static::_isPath($url_or_path) + ? static::_formatFromPath($url_or_path) + : static::_formatFromUrl($url_or_path); + } + + + protected static function _formatFromPath($path) { + $path = str_replace(ROOT_PATH, '', $path); + + return ('/' === substr($path, 0, 1)) + ? substr_replace($path, '', 0, 1) + : $path; + } - if(!$url = Class_Url::absolute($url_or_path)) + + protected static function _formatFromUrl($url) { + if (!$url = Class_Url::absolute($url)) return; - if(!$absolute = Class_Url::absolute('/')) + if (!$absolute = Class_Url::absolute('/')) return; return str_replace($absolute , '', $url); } + protected static function _isPath($url_or_path) { + return !Class_Url::isAnUrl($url_or_path); + } + + public static function delete($item) { if (!$item) return true; diff --git a/library/Class/FileManager/FileSystem.php b/library/Class/FileManager/FileSystem.php index 275a3bb4dfcd408880a21a5fe4395c225d176dee..33339fdfa2b2d374fc9fc99da57c4871a75d245b 100644 --- a/library/Class/FileManager/FileSystem.php +++ b/library/Class/FileManager/FileSystem.php @@ -231,8 +231,9 @@ class Class_FileManager_FileSystem { $path = $root->getRealpath(); $total = Class_AdminVar::get('ALLOWED_DISK_SPACE') * 1024 * 1024; $used = exec(sprintf('du -0sb %s', $path)); - $used = filter_var($used, FILTER_SANITIZE_NUMBER_INT); - $free = $total >= $used ? $total - $used : 0; + $parts = explode("\t", $used); + $used = (int)$parts[0]; + $free = ($total >= $used) ? ($total - $used) : 0; $used_percent = sprintf('%.2f',($used / $total) * 100) . '%'; diff --git a/library/Class/FileWriter.php b/library/Class/FileWriter.php index 0e9e77ab7c958c0810c19fa686300cd844b23779..222ab7004379a3346d0a09968b2ea9f2d355081d 100644 --- a/library/Class/FileWriter.php +++ b/library/Class/FileWriter.php @@ -43,7 +43,6 @@ class Class_FileWriter { public function mkdir($directory_name) { return mkdir($directory_name,0777,true); - } @@ -56,6 +55,8 @@ class Class_FileWriter { return move_uploaded_file($source,$destination); } -} -?> \ No newline at end of file + public function unlink($path) { + return unlink($path); + } +} \ No newline at end of file diff --git a/library/Class/Indexation/PseudoNotice.php b/library/Class/Indexation/PseudoNotice.php index 6ecd6d4d581f1c725a6b7f7e78ff653829cd8e5a..16f58ab1afb965985e0037199e278cdb6a3d4ed9 100644 --- a/library/Class/Indexation/PseudoNotice.php +++ b/library/Class/Indexation/PseudoNotice.php @@ -441,6 +441,7 @@ class Class_Indexation_PseudoNotice_Album extends Class_Indexation_PseudoNotice{ protected function _index() { + $this->_model->createThumbnail(); $url_vignette = $this->_model->getThumbnailUrl(); $this->_notice->setUrlVignette($url_vignette); $this->_notice->setUrlImage($url_vignette); diff --git a/library/Class/Notice/Thumbnail/ResizeImage.php b/library/Class/Notice/Thumbnail/ResizeImage.php index 4fa3d3dd485a55228ca09858b48986482f776357..7e3812e80654c635e30dd56cc508447f252cb206 100644 --- a/library/Class/Notice/Thumbnail/ResizeImage.php +++ b/library/Class/Notice/Thumbnail/ResizeImage.php @@ -21,7 +21,10 @@ class Class_Notice_Thumbnail_ResizeImage { + use Trait_StaticFileWriter, Trait_Translator; + protected static $_default_image_factory; + protected $_image; public static function setDefaultImageFactory($factory) { @@ -36,27 +39,64 @@ class Class_Notice_Thumbnail_ResizeImage { } - public function resize($source, $width, $height, $into = '', $unlink = false, $bestfit = true) { + public static function reset() { + static::setDefaultImageFactory(null); + } + + + public function __construct($image) { + $this->_image = $image; + } + + + public function resize($width, $height, $unlink = false, $bestfit = true) { + if (!$this->_image || !$this->_image->isImage()) + return new Class_Entity(); + + $pattern = 'temp/thumbnails/file-manager/%sx%s'; + + $thumb_path_pattern = sprintf($pattern, $width, $height); + $thumb_path = str_replace($this->_image->getParentPath(), + $thumb_path_pattern, + $this->_image->getPath()); + + $thumb_parent_path = explode('/', $thumb_path); + array_pop($thumb_parent_path); + $thumb_parent_path = implode('/', $thumb_parent_path); + + $thumb_url = Class_Url::absolute(sprintf($pattern . '/%s', + $width, + $height, + $this->_image->getName())); + + if (@$this->getFileWriter()->fileExists($thumb_path)) + return new Class_Entity(['Url' => $thumb_url, + 'Alt' => $this->_('Vignette de l\'image "%s"', $this->_image->getName())]); + + if (!@$this->getFileWriter()->fileExists($thumb_parent_path)) + @$this->getFileWriter()->mkdir($thumb_parent_path, 0755, true); + try { - $image = static::getImageFactory($source); + $image = static::getImageFactory($this->_image->getPath()); $image->scaleImage($width, $height, $bestfit); $image->setImageBackgroundColor('none'); $image->setImageCompressionQuality(Class_AdminVar::get('IMAGICK_IMAGE_COMPRESSION_QUALITY')); $image->setSamplingFactors(explode(';', Class_AdminVar::get('IMAGICK_SAMPLING_FACTORS'))); - $into = $into - ? $into - : $source; + $into = $thumb_path; if($unlink) - @unlink($into); + @$this->getFileWriter()->unlink($into); $image->writeImage($into); $image->destroy(); + } catch(Exception $e) { - return false; + return new Class_Entity(['Title' => $this->_('Erreur lors du vignettage de l\'image "%s". %s', $this->_image->getName(), + $e->getMessage())]); } - return true; + return new Class_Entity(['Url' => $thumb_url, + 'Title' => $this->_('Vignette de l\'image "%s"', $this->_image->getName())]); } } \ No newline at end of file diff --git a/library/Class/Url.php b/library/Class/Url.php index ddd9e6d8029b3bfd148f8c0f33d3a7389fcb3b2d..2263fa4f022f5efd9ec5cab2c73477eee7bc5516 100644 --- a/library/Class/Url.php +++ b/library/Class/Url.php @@ -88,16 +88,8 @@ class Class_Url { public static function isAnUrl($string) { - if(!$string) - return false; - - if(!is_string($string)) - return false; - - if('/' === substr($string, 0, 1)) - return true; - - return 'http' === substr($string, 0, 4); + return static::absolute($string) === $string + || static::relative($string) === $string; } diff --git a/library/ZendAfi/Controller/Plugin/Manager/FileManager.php b/library/ZendAfi/Controller/Plugin/Manager/FileManager.php index 3e438c55af1ff979fc51e40cdc9c32be241474a6..c65def555f3af358dd673c4e5f3547869f21c2ac 100644 --- a/library/ZendAfi/Controller/Plugin/Manager/FileManager.php +++ b/library/ZendAfi/Controller/Plugin/Manager/FileManager.php @@ -25,11 +25,10 @@ class ZendAfi_Controller_Plugin_Manager_FileManager extends ZendAfi_Controller_P public function getActions($model) { return [['url' => $this->_getBrowseUrl($model), 'icon' => '', - 'caption' => function($model) { - return - (($img = $this->_view->thumbnail($model)) ? $img : $this->_view->tag('i', '', ['class' => $model->getFontAwesome()])) . - $model->getName();}, - + 'caption' => function($model) + { + return $this->_view->thumbnail($model) . $model->getName(); + }, 'label' => $this->_('Voir le contenu de "%s"', $model->getPath()), 'anchorOptions' => array_filter(['title' => $this->_('Voir le contenu de "%s"', $model->getId()), 'data-path' => $model->getPath(), diff --git a/library/ZendAfi/View/Helper/Thumbnail.php b/library/ZendAfi/View/Helper/Thumbnail.php index 3681ae424579b4fca9aa03515618316247f328f4..469d27502fef2b9eb85b8c90baaeecdda9642fca 100644 --- a/library/ZendAfi/View/Helper/Thumbnail.php +++ b/library/ZendAfi/View/Helper/Thumbnail.php @@ -21,39 +21,15 @@ class ZendAfi_View_Helper_Thumbnail extends ZendAfi_View_Helper_BaseHelper { - use Trait_StaticFileWriter; public function thumbnail($instance, $width = 160, $height = 150) { - if(!$instance->isImage()) - return ''; - - try { - $thumb_path_pattern = sprintf('temp/thumbnails/file-manager/%sx%s', $width, $height); - $thumb_path = str_replace($instance->getParentPath(), - $thumb_path_pattern, - $instance->getRealpath()); - - $thumb_parent_path = explode('/', $thumb_path); - array_pop($thumb_parent_path); - $thumb_parent_path = implode('/', $thumb_parent_path); - - $thumb_url = Class_Url::absolute(str_replace($instance->getParentPath(), - $thumb_path_pattern, - $instance->getId())); - - if($this->getFileWriter()->fileExists($thumb_path)) - return $this->view->tagImg($thumb_url); - - if(!$this->getFileWriter()->fileExists($thumb_parent_path)) - $this->getFileWriter()->mkdir($thumb_parent_path, 0755, true); - - if(!(new Class_Notice_Thumbnail_ResizeImage)->resize($instance->getRealpath(), $width, $height, $thumb_path)) - return ''; - - return $this->view->tagImg($thumb_url); - } catch (Exception $e) { - return ''; - } + $resized_image = (new Class_Notice_Thumbnail_ResizeImage($instance)) + ->resize($width, $height); + + return ($url = $resized_image->getUrl()) + ? $this->view->tagImg($url, ['title' => $resized_image->getTitle(), + 'alt' => $resized_image->getAlt()]) + : $this->_tag('i', '', ['title' => $resized_image->getTitle(), + 'class' => $instance->getFontAwesome()]); } -} -?> \ No newline at end of file +} \ No newline at end of file diff --git a/tests/application/modules/AbstractControllerTestCase.php b/tests/application/modules/AbstractControllerTestCase.php index f9542cea09b4020e1695b06717dba743dd7fb406..7343f543762f1d1bd241dde38de2f937b39e782c 100644 --- a/tests/application/modules/AbstractControllerTestCase.php +++ b/tests/application/modules/AbstractControllerTestCase.php @@ -18,6 +18,8 @@ * along with BOKEH; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + + abstract class AbstractControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase { use Storm_Test_THelpers; @@ -196,10 +198,12 @@ abstract class AbstractControllerTestCase extends Zend_Test_PHPUnit_ControllerTe Class_AdminVar::set('NOM_DOMAINE', ''); Class_Log::resetInstance(); Class_WebService_BibNumerique_Vignette::resetInstance(); + Class_Notice_Thumbnail_ResizeImage::reset(); Class_FileManager::reset(); Class_Notice_Xsl::reset(); Class_CommSigb::setInstance(null); ZendAfi_Acl_AdminControllerGroup::setAcl(null); + Class_Album::setFileSystem(null); } diff --git a/tests/application/modules/admin/controllers/FileManagerControllerTest.php b/tests/application/modules/admin/controllers/FileManagerControllerTest.php index 0652c019bab6eea28f669f993c1d2b42e5978094..edffe8b85056188fe58d207e6242ec657a22735a 100644 --- a/tests/application/modules/admin/controllers/FileManagerControllerTest.php +++ b/tests/application/modules/admin/controllers/FileManagerControllerTest.php @@ -695,7 +695,7 @@ class FileManagerControllerWallDispatchTest extends FileManagerControllerTestCas /** @test */ public function thumbnailShouldBePresent() { - $this->assertXPath('//div//a[contains(@href, "&display_mode_browser=wall")][contains(@href, "?browser=userfiles%2Fimage.png")]//i'); + $this->assertXPath('//div//a[contains(@href, "&display_mode_browser=wall")][contains(@href, "?browser=userfiles%2Fimage.png")]//i[contains(@title, "Erreur lors du vignettage de l\'image")]'); } @@ -1663,6 +1663,7 @@ class FileManagerControllerRigthsOnPathTest extends ModelTestCase { class FileManagerControllerFindTest extends ModelTestCase { + protected $old_server_name, $_storm_default_to_volatile = true; @@ -1701,7 +1702,9 @@ class FileManagerControllerFindTest extends ModelTestCase { [['module' => 'admin', 'controller' => 'index', 'action' => 'index', - 'userfiles' => 'image'], null] + 'userfiles' => 'image'], null], + [ROOT_PATH . 'userfiles', 'userfiles'], + [ROOT_PATH . 'userfiles/image', 'userfiles/image'] ]; } @@ -1717,7 +1720,7 @@ class FileManagerControllerFindTest extends ModelTestCase { return $this->assertTrue(true); if(!$file) - $this->fail('no file find @ ' . $path_or_url . '. Path expected : ' . $file_path); + $this->fail('no file find @ ' . $path_or_url . '. Expected path : ' . $file_path); $this->assertEquals($file_path, $file->getPath()); } diff --git a/tests/application/modules/admin/controllers/RecordsControllerTest.php b/tests/application/modules/admin/controllers/RecordsControllerTest.php index 10637e8e9a7b82036f0caf4edf41f002587e39e8..526b154471e2ffc4ce83daf10dce23ce4ed6bbdd 100644 --- a/tests/application/modules/admin/controllers/RecordsControllerTest.php +++ b/tests/application/modules/admin/controllers/RecordsControllerTest.php @@ -96,6 +96,58 @@ class RecordsControllerResetThumbnailTest extends RecordsControllerTestCase { +class RecordsControllerResetAlbumThumbnailTest extends RecordsControllerTestCase { + public function setUp() { + parent::setUp(); + + $album = $this->fixture('Class_Album', + ['id' => 5, + 'visible' => 1, + 'status' => 3, + 'titre' => 'Potter', + 'fichier' => 'potter.png']); + + $album->setFileSystem($this->mock() + ->whenCalled('file_exists') + ->with('./userfiles/album/5/thumb_potter.png') + ->answers(true)); + + $album->index(); + $id = $album->getNoticeId(); + + $this->dispatch('/admin/records/reset-thumbnail/id/12345', true); + + Class_Notice::clearCache(); + $this->_notice = Class_Notice::find($id); + } + + + /** @test */ + public function urlImageShouldPotter() { + $this->assertContains('/userfiles/album/5/thumb_potter.png', $this->_notice->getUrlImage()); + } + + + /** @test */ + public function urlThumbnailShouldBePotter() { + $this->assertContains('/userfiles/album/5/thumb_potter.png', $this->_notice->getUrlVignette()); + } + + + /** @test */ + public function actionShouldRedirect() { + $this->assertRedirect(); + } + + + /** @test */ + public function responseShouldNotifyRecordUpdated() { + $this->assertFlashMessengerContentContains('Vignette réinitialisée pour "Harry Potter"'); + } +} + + + class RecordsControllerResetThumbnailUnknowRecordTest extends RecordsControllerTestCase { public function setUp() { parent::setUp(); diff --git a/tests/library/Class/Indexation/PseudoNoticeTest.php b/tests/library/Class/Indexation/PseudoNoticeTest.php index a06bd2ef0b3987651556544cb463bd128eb016e0..00fa1a412047f3e17c8079b9ccbc46bf34e0090e 100644 --- a/tests/library/Class/Indexation/PseudoNoticeTest.php +++ b/tests/library/Class/Indexation/PseudoNoticeTest.php @@ -19,11 +19,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + abstract class Class_Indexation_PseudoNoticeTestCase extends ModelTestCase { protected $_storm_default_to_volatile = true; } + class Class_Indexation_PseudoNoticeAlbumTest extends Class_Indexation_PseudoNoticeTestCase { public function setUp() { parent::setUp(); diff --git a/tests/library/Class/ModelTestCase.php b/tests/library/Class/ModelTestCase.php index 8ceda4ff8320031645dc93717bef3fd451bbb495..edd782f15f347d04afb9fe17d06efd2720612853 100644 --- a/tests/library/Class/ModelTestCase.php +++ b/tests/library/Class/ModelTestCase.php @@ -86,6 +86,9 @@ abstract class ModelTestCase extends Storm_Test_ModelTestCase { protected function tearDown() { Class_Url::setPhpMode(null); + Class_Notice_Thumbnail_ResizeImage::reset(); + Class_ALbum::setFileSystem(null); + Class_FileManager::reset(); Class_AdminVar::set('NOM_DOMAINE', ''); if($this->_storm_default_to_volatile) { diff --git a/tests/library/ZendAfi/View/Helper/ThumnailTest.php b/tests/library/ZendAfi/View/Helper/ThumnailTest.php new file mode 100644 index 0000000000000000000000000000000000000000..717f6d34095a861c63e234264dccbb4491fe5199 --- /dev/null +++ b/tests/library/ZendAfi/View/Helper/ThumnailTest.php @@ -0,0 +1,40 @@ +<?php +/** + * Copyright (c) 2012-2017, Agence Française Informatique (AFI). All rights reserved. + * + * BOKEH is free software; you can redistribute it and/or modify + * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by + * the Free Software Foundation. + * + * There are special exceptions to the terms and conditions of the AGPL as it + * is applied to this software (see README file). + * + * BOKEH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE + * along with BOKEH; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +class ZendAfi_View_HelperThumbnailImageTest extends ViewHelperTestCase { + + public function setUp() { + parent::setUp(); + $this->_helper = new ZendAfi_View_Helper_Thumbnail(); + $this->_helper->setView($this->view); + + Class_FileManager::beOpenBar(); + $image = Class_FileManager::find(__DIR__ . '/image.png'); + $this->_html = $this->_helper->thumbnail($image); + } + + + /** @test */ + public function htmlShouldContainsTagImgWithTempUrl() { + $this->assertXpath($this->_html, '//img[contains(@src, "/temp/thumbnails/file-manager/160x150/image.png")]', $this->_html); + } +} \ No newline at end of file diff --git a/tests/library/ZendAfi/View/Helper/ViewHelperTestCase.php b/tests/library/ZendAfi/View/Helper/ViewHelperTestCase.php index fc6b81337d9a900375dc5067b6d6b8c8155b063c..0a5cb41260f102ff88de9083c21ad83713301a37 100644 --- a/tests/library/ZendAfi/View/Helper/ViewHelperTestCase.php +++ b/tests/library/ZendAfi/View/Helper/ViewHelperTestCase.php @@ -18,11 +18,15 @@ * along with BOKEH; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + + abstract class ViewHelperTestCase extends ModelTestCase { + use Storm_Test_THelpers; - protected - $_storm_default_to_volatile = false; + + protected $_storm_default_to_volatile = false; + public function assertQueryContentContains() { call_user_func_array(array(new Storm_Test_XPath(), __FUNCTION__), @@ -148,6 +152,7 @@ abstract class ViewHelperTestCase extends ModelTestCase { ZendAfi_Auth::getInstance()->clearIdentity(); } + public function login($role) { $account = new stdClass(); $account->username = 'AutoTest' . time(); diff --git a/tests/library/ZendAfi/View/Helper/image.png b/tests/library/ZendAfi/View/Helper/image.png new file mode 100644 index 0000000000000000000000000000000000000000..005be664397530788419a40b6a73dd184d1c4ee4 Binary files /dev/null and b/tests/library/ZendAfi/View/Helper/image.png differ