diff --git a/app/code/Magento/Catalog/Block/Product/View/Gallery.php b/app/code/Magento/Catalog/Block/Product/View/Gallery.php index 0edeba7d807ac8e4c1be154d236bbff7c93a87b5..97909ffaa889f283d8a07c3f87be508f0c855c0a 100644 --- a/app/code/Magento/Catalog/Block/Product/View/Gallery.php +++ b/app/code/Magento/Catalog/Block/Product/View/Gallery.php @@ -63,15 +63,13 @@ class Gallery extends \Magento\Catalog\Block\Product\View\AbstractView ); $image->setData( 'medium_image_url', - $this->_imageHelper->init($product, 'product_page_image_medium') - ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false) + $this->_imageHelper->init($product, 'product_page_image_medium_no_frame') ->setImageFile($image->getFile()) ->getUrl() ); $image->setData( 'large_image_url', - $this->_imageHelper->init($product, 'product_page_image_large') - ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false) + $this->_imageHelper->init($product, 'product_page_image_large_no_frame') ->setImageFile($image->getFile()) ->getUrl() ); diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php index eb5e7142d3094f5457fde615bc4987a8df912ab1..6f13e9077f4732af3714ae2af50ca804a22f0aa2 100644 --- a/app/code/Magento/Catalog/Helper/Image.php +++ b/app/code/Magento/Catalog/Helper/Image.php @@ -195,7 +195,6 @@ class Image extends AbstractHelper protected function setImageProperties() { $this->_getModel()->setDestinationSubdir($this->getType()); - $this->_getModel()->setWidth($this->getWidth()); $this->_getModel()->setHeight($this->getHeight()); @@ -241,25 +240,25 @@ class Image extends AbstractHelper { $this->setWatermark( $this->scopeConfig->getValue( - "design/watermark/{$this->_getModel()->getDestinationSubdir()}_image", + "design/watermark/{$this->getType()}_image", \Magento\Store\Model\ScopeInterface::SCOPE_STORE ) ); $this->setWatermarkImageOpacity( $this->scopeConfig->getValue( - "design/watermark/{$this->_getModel()->getDestinationSubdir()}_imageOpacity", + "design/watermark/{$this->getType()}_imageOpacity", \Magento\Store\Model\ScopeInterface::SCOPE_STORE ) ); $this->setWatermarkPosition( $this->scopeConfig->getValue( - "design/watermark/{$this->_getModel()->getDestinationSubdir()}_position", + "design/watermark/{$this->getType()}_position", \Magento\Store\Model\ScopeInterface::SCOPE_STORE ) ); $this->setWatermarkSize( $this->scopeConfig->getValue( - "design/watermark/{$this->_getModel()->getDestinationSubdir()}_size", + "design/watermark/{$this->getType()}_size", \Magento\Store\Model\ScopeInterface::SCOPE_STORE ) ); @@ -500,10 +499,7 @@ class Image extends AbstractHelper protected function isScheduledActionsAllowed() { $model = $this->_getModel(); - if ($model->isBaseFilePlaceholder() - && $model->getNewFile() === true - || $model->isCached() - ) { + if ($model->isBaseFilePlaceholder() || $model->isCached()) { return false; } return true; diff --git a/app/code/Magento/Catalog/Model/Product/Image.php b/app/code/Magento/Catalog/Model/Product/Image.php index 34e1ad30ad434add33508bb63c7b8b1a78ddc9fb..769faa682f422b569dd6673df819f05d7371aeb8 100644 --- a/app/code/Magento/Catalog/Model/Product/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Image.php @@ -12,8 +12,8 @@ namespace Magento\Catalog\Model\Product; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Image as MagentoImage; -use Magento\Store\Model\Store; /** * @SuppressWarnings(PHPMD.TooManyFields) @@ -170,6 +170,21 @@ class Image extends \Magento\Framework\Model\AbstractModel */ protected $_storeManager; + /** + * @var \Magento\Catalog\Model\View\Asset\ImageFactory + */ + private $viewAssetImageFactory; + + /** + * @var \Magento\Catalog\Model\View\Asset\PlaceholderFactory + */ + private $viewAssetPlaceholderFactory; + + /** + * @var \Magento\Framework\View\Asset\LocalInterface + */ + private $imageAsset; + /** * @param \Magento\Framework\Model\Context $context * @param \Magento\Framework\Registry $registry @@ -207,7 +222,6 @@ class Image extends \Magento\Framework\Model\AbstractModel $this->_coreFileStorageDatabase = $coreFileStorageDatabase; parent::__construct($context, $registry, $resource, $resourceCollection, $data); $this->_mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA); - $result = $this->_mediaDirectory->create($this->_catalogProductMediaConfig->getBaseMediaPath()); $this->_imageFactory = $imageFactory; $this->_assetRepo = $assetRepo; $this->_viewFileSystem = $viewFileSystem; @@ -450,85 +464,29 @@ class Image extends \Magento\Framework\Model\AbstractModel * @param string $file * @return $this * @throws \Exception - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - * @SuppressWarnings(PHPMD.NPathComplexity) */ public function setBaseFile($file) { $this->_isBaseFilePlaceholder = false; - if ($file && 0 !== strpos($file, '/', 0)) { - $file = '/' . $file; - } - $baseDir = $this->_catalogProductMediaConfig->getBaseMediaPath(); - - if ('/no_selection' == $file) { - $file = null; - } - if ($file) { - if (!$this->_fileExists($baseDir . $file) || !$this->_checkMemory($baseDir . $file)) { - $file = null; - } - } - if (!$file) { + $this->imageAsset = $this->getViewAssetImageFactory()->create( + [ + 'miscParams' => $this->getMiscParams(), + 'filePath' => $file, + ] + ); + if ($file == 'no_selection' || !$this->_fileExists($this->imageAsset->getSourceFile()) + || !$this->_checkMemory($this->imageAsset->getSourceFile()) + ) { $this->_isBaseFilePlaceholder = true; - // check if placeholder defined in config - $isConfigPlaceholder = $this->_scopeConfig->getValue( - "catalog/placeholder/{$this->getDestinationSubdir()}_placeholder", - \Magento\Store\Model\ScopeInterface::SCOPE_STORE + $this->imageAsset = $this->getViewAssetPlaceholderFactory()->create( + [ + 'type' => $this->getDestinationSubdir(), + ] ); - $configPlaceholder = '/placeholder/' . $isConfigPlaceholder; - if (!empty($isConfigPlaceholder) && $this->_fileExists($baseDir . $configPlaceholder)) { - $file = $configPlaceholder; - } else { - $this->_newFile = true; - return $this; - } - } - - $baseFile = $baseDir . $file; - - if (!$file || !$this->_mediaDirectory->isFile($baseFile)) { - throw new \Exception(__('We can\'t find the image file.')); } - $this->_baseFile = $baseFile; - - // build new filename (most important params) - $path = [ - $this->_catalogProductMediaConfig->getBaseMediaPath(), - 'cache', - $this->getDestinationSubdir(), - ]; - if (!empty($this->_width) || !empty($this->_height)) { - $path[] = "{$this->_width}x{$this->_height}"; - } - - // add misk params as a hash - $miscParams = [ - ($this->_keepAspectRatio ? '' : 'non') . 'proportional', - ($this->_keepFrame ? '' : 'no') . 'frame', - ($this->_keepTransparency ? '' : 'no') . 'transparency', - ($this->_constrainOnly ? 'do' : 'not') . 'constrainonly', - $this->_rgbToString($this->_backgroundColor), - 'angle' . $this->_angle, - 'quality' . $this->_quality, - ]; - - // if has watermark add watermark params to hash - if ($this->getWatermarkFile()) { - $miscParams[] = $this->getWatermarkFile(); - $miscParams[] = $this->getWatermarkImageOpacity(); - $miscParams[] = $this->getWatermarkPosition(); - $miscParams[] = $this->getWatermarkWidth(); - $miscParams[] = $this->getWatermarkHeight(); - } - - $path[] = md5(implode('_', $miscParams)); - - // append prepared filename - $this->_newFile = implode('/', $path) . $file; - // the $file contains heading slash + $this->_baseFile = $this->imageAsset->getSourceFile(); return $this; } @@ -542,6 +500,7 @@ class Image extends \Magento\Framework\Model\AbstractModel } /** + * @deprecated * @return bool|string */ public function getNewFile() @@ -690,10 +649,10 @@ class Image extends \Magento\Framework\Model\AbstractModel */ public function saveFile() { - if ($this->_isBaseFilePlaceholder && $this->_newFile === true) { + if ($this->_isBaseFilePlaceholder) { return $this; } - $filename = $this->_mediaDirectory->getAbsolutePath($this->getNewFile()); + $filename = $this->getBaseFile() ? $this->imageAsset->getPath() : null; $this->getImageProcessor()->save($filename); $this->_coreFileStorageDatabase->saveFile($filename); return $this; @@ -704,17 +663,7 @@ class Image extends \Magento\Framework\Model\AbstractModel */ public function getUrl() { - if ($this->_newFile === true) { - $url = $this->_assetRepo->getUrl( - "Magento_Catalog::images/product/placeholder/{$this->getDestinationSubdir()}.jpg" - ); - } else { - $url = $this->_storeManager->getStore()->getBaseUrl( - \Magento\Framework\UrlInterface::URL_TYPE_MEDIA - ) . $this->_newFile; - } - - return $url; + return $this->imageAsset->getUrl(); } /** @@ -740,9 +689,7 @@ class Image extends \Magento\Framework\Model\AbstractModel */ public function isCached() { - if (is_string($this->_newFile)) { - return $this->_fileExists($this->_newFile); - } + return file_exists($this->imageAsset->getPath()); } /** @@ -939,18 +886,72 @@ class Image extends \Magento\Framework\Model\AbstractModel */ public function getResizedImageInfo() { - $fileInfo = null; - if ($this->_newFile === true) { - $asset = $this->_assetRepo->createAsset( - "Magento_Catalog::images/product/placeholder/{$this->getDestinationSubdir()}.jpg" - ); - $img = $asset->getSourceFile(); - $fileInfo = getimagesize($img); + if ($this->isBaseFilePlaceholder() == true) { + $image = $this->imageAsset->getSourceFile(); } else { - if ($this->_mediaDirectory->isFile($this->_mediaDirectory->getAbsolutePath($this->_newFile))) { - $fileInfo = getimagesize($this->_mediaDirectory->getAbsolutePath($this->_newFile)); - } + $image = $this->imageAsset->getPath(); } - return $fileInfo; + return getimagesize($image); + } + + /** + * @return \Magento\Catalog\Model\View\Asset\ImageFactory + */ + private function getViewAssetImageFactory() + { + if ($this->viewAssetImageFactory == null) { + $this->viewAssetImageFactory = ObjectManager::getInstance()->get( + \Magento\Catalog\Model\View\Asset\ImageFactory::class + ); + } + + return $this->viewAssetImageFactory; + } + + /** + * @return \Magento\Catalog\Model\View\Asset\PlaceholderFactory + */ + private function getViewAssetPlaceholderFactory() + { + if ($this->viewAssetPlaceholderFactory == null) { + $this->viewAssetPlaceholderFactory = ObjectManager::getInstance()->get( + \Magento\Catalog\Model\View\Asset\PlaceholderFactory::class + ); + } + + return $this->viewAssetPlaceholderFactory; + } + + /** + * Retrieve misc params based on all image attributes + * + * @return array + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + private function getMiscParams() + { + $miscParams = [ + 'image_type' => $this->getDestinationSubdir(), + 'image_height' => $this->getHeight(), + 'image_width' => $this->getWidth(), + 'keep_aspect_ratio' => ($this->_keepAspectRatio ? '' : 'non') . 'proportional', + 'keep_frame' => ($this->_keepFrame ? '' : 'no') . 'frame', + 'keep_transparency' => ($this->_keepTransparency ? '' : 'no') . 'transparency', + 'constrain_only' => ($this->_constrainOnly ? 'do' : 'not') . 'constrainonly', + 'background' => $this->_rgbToString($this->_backgroundColor), + 'angle' => $this->_angle, + 'quality' => $this->_quality, + ]; + + // if has watermark add watermark params to hash + if ($this->getWatermarkFile()) { + $miscParams['watermark_file'] = $this->getWatermarkFile(); + $miscParams['watermark_image_opacity'] = $this->getWatermarkImageOpacity(); + $miscParams['watermark_position'] = $this->getWatermarkPosition(); + $miscParams['watermark_width'] = $this->getWatermarkWidth(); + $miscParams['watermark_height'] = $this->getWatermarkHeight(); + } + + return $miscParams; } } diff --git a/app/code/Magento/Catalog/Model/View/Asset/Image.php b/app/code/Magento/Catalog/Model/View/Asset/Image.php new file mode 100644 index 0000000000000000000000000000000000000000..31129d7d892d2a3737b4263beb127a37c6e0217b --- /dev/null +++ b/app/code/Magento/Catalog/Model/View/Asset/Image.php @@ -0,0 +1,191 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Model\View\Asset; + +use Magento\Catalog\Model\Product\Media\ConfigInterface; +use Magento\Framework\Encryption\Encryptor; +use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Framework\View\Asset\ContextInterface; +use Magento\Framework\View\Asset\LocalInterface; + +/** + * A locally available image file asset that can be referred with a file path + * + * This class is a value object with lazy loading of some of its data (content, physical file path) + */ +class Image implements LocalInterface +{ + /** + * @var string + */ + private $filePath; + + /** + * @var string + */ + private $contentType = 'image'; + + /** + * @var ContextInterface + */ + private $context; + + /** + * Misc image params depend on size, transparency, quality, watermark etc. + * + * @var array + */ + private $miscParams; + + /** + * @var ConfigInterface + */ + private $mediaConfig; + + /** + * @var EncryptorInterface + */ + private $encryptor; + + /** + * Image constructor. + * + * @param ConfigInterface $mediaConfig + * @param ContextInterface $context + * @param EncryptorInterface $encryptor + * @param string $filePath + * @param array $miscParams + */ + public function __construct( + ConfigInterface $mediaConfig, + ContextInterface $context, + EncryptorInterface $encryptor, + $filePath, + array $miscParams = [] + ) { + $this->mediaConfig = $mediaConfig; + $this->context = $context; + $this->filePath = $filePath; + $this->miscParams = $miscParams; + $this->encryptor = $encryptor; + } + + /** + * {@inheritdoc} + */ + public function getUrl() + { + return $this->context->getBaseUrl() . $this->getRelativePath(DIRECTORY_SEPARATOR); + } + + /** + * {@inheritdoc} + */ + public function getContentType() + { + return $this->contentType; + } + + /** + * {@inheritdoc} + */ + public function getPath() + { + return $this->getRelativePath($this->context->getPath()); + } + + /** + * Subroutine for building path + * + * @param string $path + * @param string $item + * @return string + */ + private function join($path, $item) + { + return trim( + $path . ($item ? DIRECTORY_SEPARATOR . ltrim($item, DIRECTORY_SEPARATOR) : ''), + DIRECTORY_SEPARATOR + ); + } + + /** + * {@inheritdoc} + */ + public function getSourceFile() + { + return $this->mediaConfig->getBaseMediaPath() + . DIRECTORY_SEPARATOR . ltrim($this->filePath, DIRECTORY_SEPARATOR); + } + + /** + * Get source content type + * + * @return string + */ + public function getSourceContentType() + { + return $this->contentType; + } + + /** + * {@inheritdoc} + */ + public function getContent() + { + return null; + } + + /** + * {@inheritdoc} + */ + public function getFilePath() + { + return $this->filePath; + } + + /** + * {@inheritdoc} + * @return ContextInterface + */ + public function getContext() + { + return $this->context; + } + + /** + * {@inheritdoc} + */ + public function getModule() + { + return 'cache'; + } + + /** + * Retrieve part of path based on misc params + * + * @return string + */ + private function getMiscPath() + { + return $this->encryptor->hash(implode('_', $this->miscParams), Encryptor::HASH_VERSION_MD5); + } + + /** + * Generate relative path + * + * @param string $result + * @return string + */ + private function getRelativePath($result) + { + $result = $this->join($result, $this->getModule()); + $result = $this->join($result, $this->getMiscPath()); + $result = $this->join($result, $this->getFilePath()); + return DIRECTORY_SEPARATOR . $result; + } +} diff --git a/app/code/Magento/Catalog/Model/View/Asset/Image/Context.php b/app/code/Magento/Catalog/Model/View/Asset/Image/Context.php new file mode 100644 index 0000000000000000000000000000000000000000..33f0adb70c94113f51321ecce40cdffdee1ef769 --- /dev/null +++ b/app/code/Magento/Catalog/Model/View/Asset/Image/Context.php @@ -0,0 +1,59 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Model\View\Asset\Image; + +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\View\Asset\ContextInterface; + +/** + * A basic path context for assets that includes a directory path + */ +class Context implements ContextInterface +{ + /** + * @var \Magento\Framework\Filesystem\Directory\WriteInterface + */ + private $mediaDirectory; + + /** + * @var \Magento\Catalog\Model\Product\Media\ConfigInterface + */ + private $mediaConfig; + + /** + * @var \Magento\Framework\Filesystem + */ + private $filesystem; + + /** + */ + public function __construct( + \Magento\Catalog\Model\Product\Media\ConfigInterface $mediaConfig, + \Magento\Framework\Filesystem $filesystem + ) { + $this->mediaConfig = $mediaConfig; + $this->filesystem = $filesystem; + $this->mediaDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::MEDIA); + $this->mediaDirectory->create($this->mediaConfig->getBaseMediaPath()); + } + + /** + * {@inheritdoc} + */ + public function getPath() + { + return $this->mediaDirectory->getAbsolutePath($this->mediaConfig->getBaseMediaPath()); + } + + /** + * {@inheritdoc} + */ + public function getBaseUrl() + { + return $this->mediaConfig->getBaseMediaUrl(); + } +} diff --git a/app/code/Magento/Catalog/Model/View/Asset/Placeholder.php b/app/code/Magento/Catalog/Model/View/Asset/Placeholder.php new file mode 100644 index 0000000000000000000000000000000000000000..fd7dcd1c4692ec76af97bdfb782e756345985d4b --- /dev/null +++ b/app/code/Magento/Catalog/Model/View/Asset/Placeholder.php @@ -0,0 +1,181 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\Catalog\Model\View\Asset; + +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Framework\View\Asset\ContextInterface; +use Magento\Framework\View\Asset\File\NotFoundException; +use Magento\Framework\View\Asset\LocalInterface; +use Magento\Framework\View\Asset\Repository; + +/** + * A locally available image placeholder file asset that can be referred with a file type + */ +class Placeholder implements LocalInterface +{ + /** + * Type of placeholder + * + * @var string + */ + private $type; + + /** + * Filevpath of placeholder + * + * @var string + */ + private $filePath; + + /** + * @var string + */ + private $contentType = 'image'; + + /** + * @var ContextInterface + */ + private $context; + + /** + * @var Repository + */ + private $assetRepo; + + /** + * Core store config + * + * @var ScopeConfigInterface + */ + private $scopeConfig; + + /** + * Placeholder constructor. + * + * @param ContextInterface $context + * @param ScopeConfigInterface $scopeConfig + * @param Repository $assetRepo + * @param string $type + */ + public function __construct( + ContextInterface $context, + ScopeConfigInterface $scopeConfig, + Repository $assetRepo, + $type + ) { + $this->context = $context; + $this->scopeConfig = $scopeConfig; + $this->assetRepo = $assetRepo; + $this->type = $type; + } + + /** + * {@inheritdoc} + */ + public function getUrl() + { + if ($this->getFilePath() !== null) { + $result = $this->context->getBaseUrl() . '/' . $this->getModule() . '/' . $this->getFilePath(); + } else { + $result = $this->assetRepo->getUrl("Magento_Catalog::images/product/placeholder/{$this->type}.jpg"); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function getContentType() + { + return $this->contentType; + } + + /** + * {@inheritdoc} + */ + public function getPath() + { + if ($this->getFilePath() !== null) { + $result = $this->getContext()->getPath() + . DIRECTORY_SEPARATOR . $this->getModule() + . DIRECTORY_SEPARATOR . $this->getFilePath(); + } else { + $defaultPlaceholder = $this->assetRepo->createAsset( + "Magento_Catalog::images/product/placeholder/{$this->type}.jpg" + ); + try { + $result = $defaultPlaceholder->getSourceFile(); + } catch (NotFoundException $e) { + $result = null; + } + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function getSourceFile() + { + return $this->getPath(); + } + + /** + * Get source content type + * + * @return string + */ + public function getSourceContentType() + { + return $this->contentType; + } + + /** + * {@inheritdoc} + */ + public function getContent() + { + return null; + } + + /** + * {@inheritdoc} + */ + public function getFilePath() + { + if ($this->filePath !== null) { + return $this->filePath; + } + // check if placeholder defined in config + $isConfigPlaceholder = $this->scopeConfig->getValue( + "catalog/placeholder/{$this->type}_placeholder", + \Magento\Store\Model\ScopeInterface::SCOPE_STORE + ); + $this->filePath = $isConfigPlaceholder; + + return $this->filePath; + } + + /** + * {@inheritdoc} + * @return ContextInterface + */ + public function getContext() + { + return $this->context; + } + + /** + * {@inheritdoc} + */ + public function getModule() + { + return 'placeholder'; + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/GalleryTest.php b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/GalleryTest.php index 2e3a896d956d9cdd1dd82ccee58873bcf6131460..3aee622b5e3b3a48910318157a33faf8498cfd37 100644 --- a/app/code/Magento/Catalog/Test/Unit/Block/Product/View/GalleryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Block/Product/View/GalleryTest.php @@ -111,8 +111,8 @@ class GalleryTest extends \PHPUnit_Framework_TestCase ->method('init') ->willReturnMap([ [$productMock, 'product_page_image_small', [], $this->imageHelper], - [$productMock, 'product_page_image_medium', [], $this->imageHelper], - [$productMock, 'product_page_image_large', [], $this->imageHelper], + [$productMock, 'product_page_image_medium_no_frame', [], $this->imageHelper], + [$productMock, 'product_page_image_large_no_frame', [], $this->imageHelper], ]) ->willReturnSelf(); $this->imageHelper->expects($this->exactly(3)) @@ -129,19 +129,6 @@ class GalleryTest extends \PHPUnit_Framework_TestCase ->method('getUrl') ->willReturn('product_page_image_large_url'); - $this->imageHelper->expects($this->exactly(2)) - ->method('constrainOnly') - ->with(true) - ->willReturnSelf(); - $this->imageHelper->expects($this->exactly(2)) - ->method('keepAspectRatio') - ->with(true) - ->willReturnSelf(); - $this->imageHelper->expects($this->exactly(2)) - ->method('keepFrame') - ->with(false) - ->willReturnSelf(); - $images = $this->model->getGalleryImages(); $this->assertInstanceOf(\Magento\Framework\Data\Collection::class, $images); } diff --git a/app/code/Magento/Catalog/Test/Unit/Helper/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Helper/ImageTest.php index 206f20bc98179db80af5fb45014b061149dec8d7..4ed3495f9e34812788baf408632e5af29d521044 100644 --- a/app/code/Magento/Catalog/Test/Unit/Helper/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Helper/ImageTest.php @@ -424,7 +424,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase * @param string $imageId * @param string $imageFile * @param string $baseFile - * @param string $newFile * @param string $destination * @param boolean $setImageFile * @param boolean $isCached @@ -436,7 +435,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase $imageId, $imageFile, $baseFile, - $newFile, $destination, $setImageFile, $isCached, @@ -477,9 +475,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase $this->image->expects($this->any()) ->method('isBaseFilePlaceholder') ->willReturn($isBaseFilePlaceholder); - $this->image->expects($this->any()) - ->method('getNewFile') - ->willReturn($newFile); $this->prepareAttributes([], $imageId); @@ -502,7 +497,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase 'image_id' => 'test_image_id', 'image_file' => '/path/to/test_image_id.png', 'base_file' => '/path/to/base_image.png', - 'new_file' => '/path/to/base_image.png', 'destination' => 'small_image', 'set_image_file' => true, 'is_cached' => false, @@ -516,7 +510,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase 'image_id' => 'test_image_id', 'image_file' => '/path/to/test_image_id.png', 'base_file' => null, - 'new_file' => true, 'destination' => 'small_image', 'set_image_file' => false, 'is_cached' => false, @@ -530,7 +523,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase 'image_id' => 'test_image_id', 'image_file' => '/path/to/test_image_id.png', 'base_file' => null, - 'new_file' => false, 'destination' => 'small_image', 'set_image_file' => true, 'is_cached' => false, @@ -544,7 +536,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase 'image_id' => 'test_image_id', 'image_file' => '/path/to/test_image_id.png', 'base_file' => null, - 'new_file' => true, 'destination' => 'small_image', 'set_image_file' => true, 'is_cached' => false, @@ -558,7 +549,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase 'image_id' => 'test_image_id', 'image_file' => '/path/to/test_image_id.png', 'base_file' => null, - 'new_file' => '/path/to/test_image_id.png', 'destination' => 'small_image', 'set_image_file' => true, 'is_cached' => false, diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php index 44f7f87cc2c62afc2c09d262bbd2721683fcfea3..8ee875dad17b1c8fb09a99449c039825f9e1344c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/ImageTest.php @@ -6,12 +6,17 @@ namespace Magento\Catalog\Test\Unit\Model\Product; +use Magento\Catalog\Model\View\Asset\Image\ContextFactory; +use Magento\Catalog\Model\View\Asset\ImageFactory; +use Magento\Catalog\Model\View\Asset\PlaceholderFactory; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\View\Asset\ContextInterface; /** * Class ImageTest * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + * @SuppressWarnings(PHPMD.TooManyFields) */ class ImageTest extends \PHPUnit_Framework_TestCase { @@ -75,6 +80,21 @@ class ImageTest extends \PHPUnit_Framework_TestCase */ protected $mediaDirectory; + /** + * @var \Magento\Framework\View\Asset\LocalInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $imageAsset; + + /** + * @var ImageFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $viewAssetImageFactory; + + /** + * @var PlaceholderFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $viewAssetPlaceholderFactory; + protected function setUp() { $this->context = $this->getMock(\Magento\Framework\Model\Context::class, [], [], '', false); @@ -99,7 +119,6 @@ class ImageTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->setMethods(['create', 'isFile', 'isExist', 'getAbsolutePath']) ->getMock(); - $this->mediaDirectory->expects($this->once())->method('create')->will($this->returnValue(true)); $this->filesystem = $this->getMock(\Magento\Framework\Filesystem::class, [], [], '', false); $this->filesystem->expects($this->once())->method('getDirectoryWrite') @@ -110,20 +129,49 @@ class ImageTest extends \PHPUnit_Framework_TestCase $this->fileSystem = $this->getMock(\Magento\Framework\View\FileSystem::class, [], [], '', false); $this->scopeConfigInterface = $this->getMock(\Magento\Framework\App\Config\ScopeConfigInterface::class); + $context = $this->getMockBuilder(\Magento\Framework\Model\Context::class) + ->disableOriginalConstructor() + ->getMock(); + $this->image = new \Magento\Catalog\Model\Product\Image( + $context, + $this->registry, + $this->storeManager, + $this->config, + $this->coreFileHelper, + $this->filesystem, + $this->factory, + $this->repository, + $this->fileSystem, + $this->scopeConfigInterface + ); + //Settings for backward compatible property $objectManagerHelper = new ObjectManagerHelper($this); - $this->image = $objectManagerHelper->getObject( - \Magento\Catalog\Model\Product\Image::class, - [ - 'registry' => $this->registry, - 'storeManager' => $this->storeManager, - 'catalogProductMediaConfig' => $this->config, - 'coreFileStorageDatabase' => $this->coreFileHelper, - 'filesystem' => $this->filesystem, - 'imageFactory' => $this->factory, - 'assetRepo' => $this->repository, - 'viewFileSystem' => $this->fileSystem, - 'scopeConfig' => $this->scopeConfigInterface - ] + $this->imageAsset = $this->getMockBuilder(\Magento\Framework\View\Asset\LocalInterface::class) + ->getMockForAbstractClass(); + $objectManagerHelper->setBackwardCompatibleProperty( + $this->image, + 'imageAsset', + $this->imageAsset + ); + + $this->viewAssetImageFactory = $this->getMockBuilder(ImageFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $objectManagerHelper->setBackwardCompatibleProperty( + $this->image, + 'viewAssetImageFactory', + $this->viewAssetImageFactory + ); + + $this->viewAssetPlaceholderFactory = $this->getMockBuilder(PlaceholderFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $objectManagerHelper->setBackwardCompatibleProperty( + $this->image, + 'viewAssetPlaceholderFactory', + $this->viewAssetPlaceholderFactory ); } @@ -177,18 +225,39 @@ class ImageTest extends \PHPUnit_Framework_TestCase $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/somefile.png'; $this->mediaDirectory->expects($this->any())->method('getAbsolutePath') ->will($this->returnValue($absolutePath)); + $this->viewAssetImageFactory->expects($this->any()) + ->method('create') + ->with( + [ + 'miscParams' => [ + 'image_type' => null, + 'image_height' => null, + 'image_width' => null, + 'keep_aspect_ratio' => 'proportional', + 'keep_frame' => 'frame', + 'keep_transparency' => 'transparency', + 'constrain_only' => 'doconstrainonly', + 'background' => 'ffffff', + 'angle' => null, + 'quality' => 80, + ], + 'filePath' => '/somefile.png', + ] + ) + ->willReturn($this->imageAsset); + $this->viewAssetPlaceholderFactory->expects($this->never())->method('create'); + + $this->imageAsset->expects($this->any())->method('getSourceFile')->willReturn('catalog/product/somefile.png'); $this->image->setBaseFile('/somefile.png'); $this->assertEquals('catalog/product/somefile.png', $this->image->getBaseFile()); - $this->assertEquals( - 'catalog/product/cache//beff4985b56e3afdbeabfc89641a4582/somefile.png', - $this->image->getNewFile() - ); } public function testSetBaseNoSelectionFile() { - $this->image->setBaseFile('/no_selection'); - $this->assertTrue($this->image->getNewFile()); + $this->viewAssetPlaceholderFactory->expects($this->once())->method('create')->willReturn($this->imageAsset); + $this->imageAsset->expects($this->any())->method('getSourceFile')->willReturn('Default Placeholder Path'); + $this->image->setBaseFile('no_selection'); + $this->assertEquals('Default Placeholder Path', $this->image->getBaseFile()); } public function testSetGetImageProcessor() @@ -284,45 +353,45 @@ class ImageTest extends \PHPUnit_Framework_TestCase )->disableOriginalConstructor()->getMock(); $this->image->setImageProcessor($imageProcessor); $this->coreFileHelper->expects($this->once())->method('saveFile')->will($this->returnValue(true)); - $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/somefile.png'; - $this->mediaDirectory->expects($this->once())->method('getAbsolutePath') - ->will($this->returnValue($absolutePath)); $this->image->saveFile(); } public function testSaveFileNoSelection() { - $this->testSetBaseNoSelectionFile(); + $imageProcessor = $this->getMockBuilder( + \Magento\Framework\Image::class + )->disableOriginalConstructor()->getMock(); + $this->image->setImageProcessor($imageProcessor); $this->assertSame($this->image, $this->image->saveFile()); } public function testGetUrl() { $this->testSetGetBaseFile(); - $url = $this->image->getUrl(); - $this->assertEquals( - 'http://magento.com/media/catalog/product/cache//beff4985b56e3afdbeabfc89641a4582/somefile.png', - $url - ); + $this->imageAsset->expects($this->any())->method('getUrl')->will($this->returnValue('url of exist image')); + $this->assertEquals('url of exist image', $this->image->getUrl()); } public function testGetUrlNoSelection() { - $this->testSetBaseNoSelectionFile(); - $this->repository->expects($this->once())->method('getUrl')->will($this->returnValue('someurl')); - $this->assertEquals('someurl', $this->image->getUrl()); + $this->viewAssetPlaceholderFactory->expects($this->once())->method('create')->willReturn($this->imageAsset); + $this->imageAsset->expects($this->any())->method('getUrl')->will($this->returnValue('Default Placeholder URL')); + $this->image->setBaseFile('no_selection'); + $this->assertEquals('Default Placeholder URL', $this->image->getUrl()); } public function testSetGetDestinationSubdir() { - $this->image->setDestinationSubdir('somesubdir'); - $this->assertEquals('somesubdir', $this->image->getDestinationSubdir()); + $this->image->setDestinationSubdir('image_type'); + $this->assertEquals('image_type', $this->image->getDestinationSubdir()); } public function testIsCached() { $this->testSetGetBaseFile(); + $absolutePath = dirname(dirname(__DIR__)) . '/_files/catalog/product/watermark/somefile.png'; + $this->imageAsset->expects($this->any())->method('getPath')->willReturn($absolutePath); $this->assertTrue($this->image->isCached()); } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/Image/ContextTest.php b/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/Image/ContextTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cdc1296486eef202a6410b6a3fd3a1d738ca60f9 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/Image/ContextTest.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Test\Unit\Model\View\Asset\Image; + +use Magento\Catalog\Model\Product\Media\ConfigInterface; +use Magento\Catalog\Model\View\Asset\Image\Context; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem; +use Magento\Framework\Filesystem\Directory\WriteInterface; + +/** + * Class ContextTest + */ +class ContextTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Context + */ + protected $model; + + /** + * @var WriteInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $mediaDirectory; + + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $mediaConfig; + + /** + * @var Filesystem|\PHPUnit_Framework_MockObject_MockObject + */ + protected $filesystem; + + protected function setUp() + { + $this->mediaConfig = $this->getMockBuilder(ConfigInterface::class)->getMockForAbstractClass(); + $this->mediaConfig->expects($this->any())->method('getBaseMediaPath')->willReturn('catalog/product'); + $this->mediaDirectory = $this->getMockBuilder(WriteInterface::class)->getMockForAbstractClass(); + $this->mediaDirectory->expects($this->once())->method('create')->with('catalog/product'); + $this->filesystem = $this->getMockBuilder(Filesystem::class) + ->disableOriginalConstructor() + ->getMock(); + $this->filesystem->expects($this->once()) + ->method('getDirectoryWrite') + ->with(DirectoryList::MEDIA) + ->willReturn($this->mediaDirectory); + $this->model = new Context( + $this->mediaConfig, + $this->filesystem + ); + } + + public function testGetPath() + { + $path = '/var/www/html/magento2ce/pub/media/catalog/product'; + $this->mediaDirectory->expects($this->once()) + ->method('getAbsolutePath') + ->with('catalog/product') + ->willReturn($path); + + $this->assertEquals($path, $this->model->getPath()); + } + + public function testGetUrl() + { + $baseUrl = 'http://localhost/pub/media/catalog/product'; + $this->mediaConfig->expects($this->once())->method('getBaseMediaUrl')->willReturn($baseUrl); + + $this->assertEquals($baseUrl, $this->model->getBaseUrl()); + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/ImageTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5e96cdb1c3395182049e78ae29cd3b44bd0baf17 --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/ImageTest.php @@ -0,0 +1,148 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Test\Unit\Model\View\Asset; + +use Magento\Catalog\Model\Product\Media\ConfigInterface; +use Magento\Catalog\Model\View\Asset\Image; +use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Framework\View\Asset\ContextInterface; + +/** + * Class ImageTest + */ +class ImageTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\View\Asset\Image + */ + protected $model; + + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $mediaConfig; + + /** + * @var EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $encryptor; + + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $imageContext; + + protected function setUp() + { + $this->mediaConfig = $this->getMockBuilder(ConfigInterface::class)->getMockForAbstractClass(); + $this->encryptor = $this->getMockBuilder(EncryptorInterface::class)->getMockForAbstractClass(); + $this->imageContext = $this->getMockBuilder(ContextInterface::class)->getMockForAbstractClass(); + $this->model = new Image( + $this->mediaConfig, + $this->imageContext, + $this->encryptor, + '/somefile.png' + ); + } + + public function testModuleAndContentAndContentType() + { + $contentType = 'image'; + $this->assertEquals($contentType, $this->model->getContentType()); + $this->assertEquals($contentType, $this->model->getSourceContentType()); + $this->assertNull($this->model->getContent()); + $this->assertEquals('cache', $this->model->getModule()); + } + + public function testGetFilePath() + { + $this->assertEquals('/somefile.png', $this->model->getFilePath()); + } + + public function testGetSoureFile() + { + $this->mediaConfig->expects($this->once())->method('getBaseMediaPath')->willReturn('catalog/product'); + $this->assertEquals('catalog/product/somefile.png', $this->model->getSourceFile()); + } + + public function testGetContext() + { + $this->assertInstanceOf(ContextInterface::class, $this->model->getContext()); + } + + /** + * @param string $filePath + * @param array $miscParams + * @dataProvider getPathDataProvider + */ + public function testGetPath($filePath, $miscParams) + { + $imageModel = new Image( + $this->mediaConfig, + $this->imageContext, + $this->encryptor, + $filePath, + $miscParams + ); + $absolutePath = '/var/www/html/magento2ce/pub/media/catalog/product'; + $hashPath = md5(implode('_', $miscParams)); + $this->imageContext->expects($this->once())->method('getPath')->willReturn($absolutePath); + $this->encryptor->expects($this->once())->method('hash')->willReturn($hashPath); + $this->assertEquals( + $absolutePath . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . $hashPath . $filePath, + $imageModel->getPath() + ); + } + + /** + * @param string $filePath + * @param array $miscParams + * @dataProvider getPathDataProvider + */ + public function testGetUrl($filePath, $miscParams) + { + $imageModel = new Image( + $this->mediaConfig, + $this->imageContext, + $this->encryptor, + $filePath, + $miscParams + ); + $absolutePath = 'http://localhost/pub/media/catalog/product'; + $hashPath = md5(implode('_', $miscParams)); + $this->imageContext->expects($this->once())->method('getBaseUrl')->willReturn($absolutePath); + $this->encryptor->expects($this->once())->method('hash')->willReturn($hashPath); + $this->assertEquals( + $absolutePath . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . $hashPath . $filePath, + $imageModel->getUrl() + ); + } + + public function getPathDataProvider() + { + return [ + [ + '/some_file.png', + [], //default value for miscParams + ], + [ + '/some_file_2.png', + [ + 'image_type' => 'thumbnail', + 'image_height' => 75, + 'image_width' => 75, + 'keep_aspect_ratio' => 'proportional', + 'keep_frame' => 'frame', + 'keep_transparency' => 'transparency', + 'constrain_only' => 'doconstrainonly', + 'background' => 'ffffff', + 'angle' => null, + 'quality' => 80, + ], + ] + ]; + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/PlaceholderTest.php b/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/PlaceholderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..38d5ceb16e6b5b17e8e7cbaa1171513d68027e3c --- /dev/null +++ b/app/code/Magento/Catalog/Test/Unit/Model/View/Asset/PlaceholderTest.php @@ -0,0 +1,163 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Test\Unit\Model\View\Asset; + +use Magento\Framework\App\Config\ScopeConfigInterface; +use Magento\Catalog\Model\View\Asset\Placeholder; +use Magento\Framework\View\Asset\ContextInterface; +use Magento\Framework\View\Asset\Repository; + +/** + * Class PlaceholderTest + */ +class PlaceholderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\Catalog\Model\View\Asset\Placeholder + */ + protected $model; + + /** + * @var ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $scopeConfig; + + /** + * @var Repository|\PHPUnit_Framework_MockObject_MockObject + */ + protected $repository; + + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $imageContext; + + protected function setUp() + { + $this->scopeConfig = $this->getMockBuilder(ScopeConfigInterface::class)->getMockForAbstractClass(); + $this->imageContext = $this->getMockBuilder(ContextInterface::class)->getMockForAbstractClass(); + $this->repository = $this->getMockBuilder(Repository::class)->disableOriginalConstructor()->getMock(); + $this->model = new Placeholder( + $this->imageContext, + $this->scopeConfig, + $this->repository, + 'thumbnail' + ); + } + + public function testModuleAndContentAndContentType() + { + $contentType = 'image'; + $this->assertEquals($contentType, $this->model->getContentType()); + $this->assertEquals($contentType, $this->model->getSourceContentType()); + $this->assertNull($this->model->getContent()); + $this->assertEquals('placeholder', $this->model->getModule()); + } + + public function testGetFilePath() + { + $this->assertNull($this->model->getFilePath()); + $this->scopeConfig->expects($this->once())->method('getValue')->willReturn('default/thumbnail.jpg'); + $this->assertEquals('default/thumbnail.jpg', $this->model->getFilePath()); + } + + public function testGetContext() + { + $this->assertInstanceOf(ContextInterface::class, $this->model->getContext()); + } + + /** + * @param string $imageType + * @param string $placeholderPath + * @dataProvider getPathDataProvider + */ + public function testGetPathAndGetSourceFile($imageType, $placeholderPath) + { + $imageModel = new Placeholder( + $this->imageContext, + $this->scopeConfig, + $this->repository, + $imageType + ); + $absolutePath = '/var/www/html/magento2ce/pub/media/catalog/product'; + + $this->scopeConfig->expects($this->any()) + ->method('getValue') + ->with( + "catalog/placeholder/{$imageType}_placeholder", + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + null + )->willReturn($placeholderPath); + + if ($placeholderPath == null) { + $this->imageContext->expects($this->never())->method('getPath'); + $assetMock = $this->getMockBuilder(\Magento\Framework\View\Asset\MergeableInterface::class) + ->getMockForAbstractClass(); + $expectedResult = 'path/to_default/placeholder/by_type'; + $assetMock->expects($this->any())->method('getSourceFile')->willReturn($expectedResult); + $this->repository->expects($this->any())->method('createAsset')->willReturn($assetMock); + } else { + $this->imageContext->expects($this->any())->method('getPath')->willReturn($absolutePath); + $expectedResult = $absolutePath + . DIRECTORY_SEPARATOR . $imageModel->getModule() + . DIRECTORY_SEPARATOR . $placeholderPath; + } + + $this->assertEquals($expectedResult, $imageModel->getPath()); + $this->assertEquals($expectedResult, $imageModel->getSourceFile()); + } + + /** + * @param string $imageType + * @param string $placeholderPath + * @dataProvider getPathDataProvider + */ + public function testGetUrl($imageType, $placeholderPath) + { + $imageModel = new Placeholder( + $this->imageContext, + $this->scopeConfig, + $this->repository, + $imageType + ); + + $this->scopeConfig->expects($this->any()) + ->method('getValue') + ->with( + "catalog/placeholder/{$imageType}_placeholder", + \Magento\Store\Model\ScopeInterface::SCOPE_STORE, + null + )->willReturn($placeholderPath); + + if ($placeholderPath == null) { + $this->imageContext->expects($this->never())->method('getBaseUrl'); + $expectedResult = 'http://localhost/pub/media/catalog/product/to_default/placeholder/by_type'; + $this->repository->expects($this->any())->method('getUrl')->willReturn($expectedResult); + } else { + $baseUrl = 'http://localhost/pub/media/catalog/product'; + $this->imageContext->expects($this->any())->method('getBaseUrl')->willReturn($baseUrl); + $expectedResult = $baseUrl + . DIRECTORY_SEPARATOR . $imageModel->getModule() + . DIRECTORY_SEPARATOR . $placeholderPath; + } + + $this->assertEquals($expectedResult, $imageModel->getUrl()); + } + + public function getPathDataProvider() + { + return [ + [ + 'thumbnail', + 'default/thumbnail.jpg', + ], + [ + 'non_exist', + null, + ], + ]; + } +} diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 6b39520ae021e9eb3bfafa20bda03e42c7db907a..27c3a0a2f14c80714bf934c167bd8337477cc06a 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -48,6 +48,8 @@ <preference for="Magento\Catalog\Api\Data\CategorySearchResultsInterface" type="Magento\Framework\Api\SearchResults" /> <preference for="Magento\Catalog\Model\Config\Source\ProductPriceOptionsInterface" type="Magento\Catalog\Model\Config\Source\Product\Options\Price"/> <preference for="Magento\Catalog\Model\Indexer\Product\Flat\Table\BuilderInterface" type="Magento\Catalog\Model\Indexer\Product\Flat\Table\Builder"/> + <preference for="Magento\Catalog\Model\Product\Media\ConfigInterface" type="Magento\Catalog\Model\Product\Media\Config"/> + <preference for="Magento\Framework\View\Asset\ContextInterface" type="Magento\Catalog\Model\View\Asset\Image\Context"/> <type name="Magento\Customer\Model\ResourceModel\Visitor"> <plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" /> </type> diff --git a/app/code/Magento/ConfigurableProduct/Helper/Data.php b/app/code/Magento/ConfigurableProduct/Helper/Data.php index 079aee7b23750bbb08d01ecae4c672c50bf1eeb2..4c1370b1a0d7aed1c786d318c3c65382277e2afe 100644 --- a/app/code/Magento/ConfigurableProduct/Helper/Data.php +++ b/app/code/Magento/ConfigurableProduct/Helper/Data.php @@ -50,15 +50,13 @@ class Data ); $image->setData( 'medium_image_url', - $this->imageHelper->init($product, 'product_page_image_medium') - ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false) + $this->imageHelper->init($product, 'product_page_image_medium_no_frame') ->setImageFile($image->getFile()) ->getUrl() ); $image->setData( 'large_image_url', - $this->imageHelper->init($product, 'product_page_image_large') - ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false) + $this->imageHelper->init($product, 'product_page_image_large_no_frame') ->setImageFile($image->getFile()) ->getUrl() ); diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Helper/DataTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Helper/DataTest.php index be1f4c76a4f45e3051c4d39f87c4619ffac1de3a..efb11e6b13a1d63d4fb9fbb37b5d5a89f5a8f511 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Helper/DataTest.php @@ -35,7 +35,7 @@ class DataTest extends \PHPUnit_Framework_TestCase public function testGetAllowAttributes() { - $typeInstanceMock = $this->getMock( + $typeInstanceMock = $this->getMock( \Magento\ConfigurableProduct\Model\Product\Type\Configurable::class, [], [], '', false ); $typeInstanceMock->expects($this->once()) @@ -91,7 +91,7 @@ class DataTest extends \PHPUnit_Framework_TestCase */ public function getOptionsDataProvider() { - $currentProductMock = $this->getMock( + $currentProductMock = $this->getMock( \Magento\Catalog\Model\Product::class, ['getTypeInstance', '__wakeup'], [], '', false ); $provider = []; @@ -106,10 +106,10 @@ class DataTest extends \PHPUnit_Framework_TestCase $attributesCount = 3; $attributes = []; for ($i = 1; $i < $attributesCount; $i++) { - $attribute = $this->getMock( + $attribute = $this->getMock( \Magento\Framework\DataObject::class, ['getProductAttribute'], [], '', false ); - $productAttribute = $this->getMock( + $productAttribute = $this->getMock( \Magento\Framework\DataObject::class, ['getId', 'getAttributeCode'], [], @@ -127,7 +127,7 @@ class DataTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($productAttribute)); $attributes[] = $attribute; } - $typeInstanceMock = $this->getMock( + $typeInstanceMock = $this->getMock( \Magento\ConfigurableProduct\Model\Product\Type\Configurable::class, [], [], '', false ); $typeInstanceMock->expects($this->any()) @@ -138,7 +138,7 @@ class DataTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue($typeInstanceMock)); $allowedProducts = []; for ($i = 1; $i <= 2; $i++) { - $productMock = $this->getMock( + $productMock = $this->getMock( \Magento\Catalog\Model\Product::class, ['getData', 'getImage', 'getId', '__wakeup', 'getMediaGalleryImages'], [], '', false ); $productMock->expects($this->any()) @@ -195,4 +195,64 @@ class DataTest extends \PHPUnit_Framework_TestCase } return $map[$key]; } + + public function testGetGalleryImages() + { + $productMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class) + ->setMethods(['getMediaGalleryImages']) + ->getMockForAbstractClass(); + $productMock->expects($this->once()) + ->method('getMediaGalleryImages') + ->willReturn($this->getImagesCollection()); + + $this->_imageHelperMock->expects($this->exactly(3)) + ->method('init') + ->willReturnMap([ + [$productMock, 'product_page_image_small', [], $this->_imageHelperMock], + [$productMock, 'product_page_image_medium_no_frame', [], $this->_imageHelperMock], + [$productMock, 'product_page_image_large_no_frame', [], $this->_imageHelperMock], + ]) + ->willReturnSelf(); + $this->_imageHelperMock->expects($this->exactly(3)) + ->method('setImageFile') + ->with('test_file') + ->willReturnSelf(); + $this->_imageHelperMock->expects($this->at(0)) + ->method('getUrl') + ->willReturn('product_page_image_small_url'); + $this->_imageHelperMock->expects($this->at(1)) + ->method('getUrl') + ->willReturn('product_page_image_medium_url'); + $this->_imageHelperMock->expects($this->at(2)) + ->method('getUrl') + ->willReturn('product_page_image_large_url'); + + $this->assertInstanceOf( + \Magento\Framework\Data\Collection::class, + $this->_model->getGalleryImages($productMock) + ); + + } + + /** + * @return \Magento\Framework\Data\Collection + */ + private function getImagesCollection() + { + $collectionMock = $this->getMockBuilder(\Magento\Framework\Data\Collection::class) + ->disableOriginalConstructor() + ->getMock(); + + $items = [ + new \Magento\Framework\DataObject([ + 'file' => 'test_file' + ]), + ]; + + $collectionMock->expects($this->any()) + ->method('getIterator') + ->willReturn(new \ArrayIterator($items)); + + return $collectionMock; + } } diff --git a/app/code/Magento/Swatches/Helper/Data.php b/app/code/Magento/Swatches/Helper/Data.php index a973a822c4101671faa0fe57925a0e9b0c5b2f2a..d80aaaf73ccf016bc1d571254cfc90a7f0452c3d 100644 --- a/app/code/Magento/Swatches/Helper/Data.php +++ b/app/code/Magento/Swatches/Helper/Data.php @@ -328,12 +328,10 @@ class Data private function getAllSizeImages(ModelProduct $product, $imageFile) { return [ - 'large' => $this->imageHelper->init($product, 'product_page_image_large') - ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false) + 'large' => $this->imageHelper->init($product, 'product_page_image_large_no_frame') ->setImageFile($imageFile) ->getUrl(), - 'medium' => $this->imageHelper->init($product, 'product_page_image_medium') - ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false) + 'medium' => $this->imageHelper->init($product, 'product_page_image_medium_no_frame') ->setImageFile($imageFile) ->getUrl(), 'small' => $this->imageHelper->init($product, 'product_page_image_small') diff --git a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php index e5f2f887836eff5ad73ca95602d4d7aec411150e..10f26acfc2594499adb80cd6df5bfee1fc277f88 100644 --- a/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php +++ b/app/code/Magento/Swatches/Test/Unit/Helper/DataTest.php @@ -340,8 +340,8 @@ class DataTest extends \PHPUnit_Framework_TestCase $this->imageHelperMock->expects($this->any()) ->method('init') ->willReturnMap([ - [$this->productMock, 'product_page_image_large', [], $this->imageHelperMock], - [$this->productMock, 'product_page_image_medium', [], $this->imageHelperMock], + [$this->productMock, 'product_page_image_large_no_frame', [], $this->imageHelperMock], + [$this->productMock, 'product_page_image_medium_no_frame', [], $this->imageHelperMock], [$this->productMock, 'product_page_image_small', [], $this->imageHelperMock], ]); @@ -349,15 +349,6 @@ class DataTest extends \PHPUnit_Framework_TestCase ->method('setImageFile') ->with($image) ->willReturnSelf(); - $this->imageHelperMock->expects($this->any()) - ->method('constrainOnly') - ->willReturnSelf(); - $this->imageHelperMock->expects($this->any()) - ->method('keepAspectRatio') - ->willReturnSelf(); - $this->imageHelperMock->expects($this->any()) - ->method('keepFrame') - ->willReturnSelf(); $this->imageHelperMock->expects($this->any()) ->method('getUrl') ->willReturn('http://full_path_to_image/magento1.png'); diff --git a/app/design/frontend/Magento/blank/etc/view.xml b/app/design/frontend/Magento/blank/etc/view.xml index 6c53a8613f09ca1f91c9e024b8e2cec723f0b309..3bf5fc6fc77af5a67becb60920343c6f6ce48db8 100644 --- a/app/design/frontend/Magento/blank/etc/view.xml +++ b/app/design/frontend/Magento/blank/etc/view.xml @@ -73,10 +73,18 @@ <height>140</height> </image> <image id="product_page_image_large" type="image"/> + <image id="product_page_image_large_no_frame" type="image"> + <frame>false</frame> + </image> <image id="product_page_image_medium" type="image"> <width>700</width> <height>700</height> </image> + <image id="product_page_image_medium_no_frame" type="image"> + <width>700</width> + <height>700</height> + <frame>false</frame> + </image> <image id="product_page_image_small" type="thumbnail"> <width>90</width> <height>90</height> diff --git a/app/design/frontend/Magento/luma/etc/view.xml b/app/design/frontend/Magento/luma/etc/view.xml index 12a51ee065edba43c9afde39ce31c2aace3d00a8..33fc64af977c557f17fd7e9db0779a881fa77e08 100644 --- a/app/design/frontend/Magento/luma/etc/view.xml +++ b/app/design/frontend/Magento/luma/etc/view.xml @@ -77,10 +77,18 @@ <height>140</height> </image> <image id="product_page_image_large" type="image"/> + <image id="product_page_image_large_no_frame" type="image"> + <frame>false</frame> + </image> <image id="product_page_image_medium" type="image"> <width>700</width> <height>560</height> </image> + <image id="product_page_image_medium_no_frame" type="image"> + <width>700</width> + <height>700</height> + <frame>false</frame> + </image> <image id="product_page_image_small" type="thumbnail"> <width>88</width> <height>110</height> diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/ImageTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/ImageTest.php index 88fd7797e768fb5fb227a8fc888ad481794d4347..8b0d1b393f467641bd87bc65fb425dbe8000bff6 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/ImageTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Product/ImageTest.php @@ -23,8 +23,15 @@ class ImageTest extends \PHPUnit_Framework_TestCase $model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( \Magento\Catalog\Model\Product\Image::class ); - $model->setDestinationSubdir('image')->setBaseFile(''); - $this->assertEmpty($model->getBaseFile()); + /** @var \Magento\Catalog\Model\View\Asset\Placeholder $defualtPlaceholder */ + $defualtPlaceholder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager() + ->create(\Magento\Catalog\Model\View\Asset\Placeholder::class, + ['type' => 'image'] + ); + + $model->setDestinationSubdir('image'); + $model->setBaseFile(''); + $this->assertEquals($defualtPlaceholder->getSourceFile(), $model->getBaseFile()); return $model; }