diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Frontend/Image.php b/app/code/Magento/Catalog/Model/Product/Attribute/Frontend/Image.php index 6173a76eca421..cdd6da7019da5 100644 --- a/app/code/Magento/Catalog/Model/Product/Attribute/Frontend/Image.php +++ b/app/code/Magento/Catalog/Model/Product/Attribute/Frontend/Image.php @@ -9,23 +9,28 @@ * * @author Magento Core Team */ + namespace Magento\Catalog\Model\Product\Attribute\Frontend; -class Image extends \Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend +use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend; +use Magento\Framework\UrlInterface; +use Magento\Store\Model\StoreManagerInterface; + +class Image extends AbstractFrontend { /** * Store manager * - * @var \Magento\Store\Model\StoreManagerInterface + * @var StoreManagerInterface */ protected $_storeManager; /** * Construct * - * @param \Magento\Store\Model\StoreManagerInterface $storeManager + * @param StoreManagerInterface $storeManager */ - public function __construct(\Magento\Store\Model\StoreManagerInterface $storeManager) + public function __construct(StoreManagerInterface $storeManager) { $this->_storeManager = $storeManager; } @@ -42,9 +47,9 @@ public function getUrl($product) $image = $product->getData($this->getAttribute()->getAttributeCode()); $url = false; if (!empty($image)) { - $url = $this->_storeManager->getStore($product->getStore()) - ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) - . 'catalog/product/' . $image; + $url = $this->_storeManager + ->getStore($product->getStore()) + ->getBaseUrl(UrlInterface::URL_TYPE_MEDIA) . 'catalog/product/' . ltrim($image, '/'); } return $url; } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/Frontend/ImageTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/Frontend/ImageTest.php index 115a333a38b5b..3ceedddc2b713 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/Frontend/ImageTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Product/Attribute/Frontend/ImageTest.php @@ -3,45 +3,71 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ + namespace Magento\Catalog\Test\Unit\Model\Product\Attribute\Frontend; +use Magento\Catalog\Model\Product; +use Magento\Catalog\Model\Product\Attribute\Frontend\Image; +use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Store\Model\Store; +use Magento\Store\Model\StoreManagerInterface; +use PHPUnit\Framework\TestCase; -class ImageTest extends \PHPUnit\Framework\TestCase +class ImageTest extends TestCase { /** - * @var \Magento\Catalog\Model\Product\Attribute\Frontend\Image + * @var Image */ private $model; - public function testGetUrl() + /** + * @dataProvider getUrlDataProvider + * @param string $expectedImage + * @param string $productImage + */ + public function testGetUrl(string $expectedImage, string $productImage) + { + $this->assertEquals($expectedImage, $this->model->getUrl($this->getMockedProduct($productImage))); + } + + /** + * Data provider for testGetUrl + * + * @return array + */ + public function getUrlDataProvider(): array { - $this->assertEquals('catalog/product/img.jpg', $this->model->getUrl($this->getMockedProduct())); + return [ + ['catalog/product/img.jpg', 'img.jpg'], + ['catalog/product/img.jpg', '/img.jpg'], + ]; } protected function setUp() { $helper = new ObjectManager($this); $this->model = $helper->getObject( - \Magento\Catalog\Model\Product\Attribute\Frontend\Image::class, + Image::class, ['storeManager' => $this->getMockedStoreManager()] ); $this->model->setAttribute($this->getMockedAttribute()); } /** - * @return \Magento\Catalog\Model\Product + * @param string $productImage + * @return Product */ - private function getMockedProduct() + private function getMockedProduct(string $productImage): Product { - $mockBuilder = $this->getMockBuilder(\Magento\Catalog\Model\Product::class); + $mockBuilder = $this->getMockBuilder(Product::class); $mock = $mockBuilder->setMethods(['getData', 'getStore', '__wakeup']) ->disableOriginalConstructor() ->getMock(); $mock->expects($this->any()) ->method('getData') - ->will($this->returnValue('img.jpg')); + ->will($this->returnValue($productImage)); $mock->expects($this->any()) ->method('getStore'); @@ -50,13 +76,13 @@ private function getMockedProduct() } /** - * @return \Magento\Store\Model\StoreManagerInterface + * @return StoreManagerInterface */ - private function getMockedStoreManager() + private function getMockedStoreManager(): StoreManagerInterface { $mockedStore = $this->getMockedStore(); - $mockBuilder = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class); + $mockBuilder = $this->getMockBuilder(StoreManagerInterface::class); $mock = $mockBuilder->setMethods(['getStore']) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -69,11 +95,11 @@ private function getMockedStoreManager() } /** - * @return \Magento\Store\Model\Store + * @return Store */ - private function getMockedStore() + private function getMockedStore(): Store { - $mockBuilder = $this->getMockBuilder(\Magento\Store\Model\Store::class); + $mockBuilder = $this->getMockBuilder(Store::class); $mock = $mockBuilder->setMethods(['getBaseUrl', '__wakeup']) ->disableOriginalConstructor() ->getMockForAbstractClass(); @@ -86,11 +112,11 @@ private function getMockedStore() } /** - * @return \Magento\Eav\Model\Entity\Attribute\AbstractAttribute + * @return AbstractAttribute */ - private function getMockedAttribute() + private function getMockedAttribute(): AbstractAttribute { - $mockBuilder = $this->getMockBuilder(\Magento\Eav\Model\Entity\Attribute\AbstractAttribute::class); + $mockBuilder = $this->getMockBuilder(AbstractAttribute::class); $mockBuilder->setMethods(['getAttributeCode', '__wakeup']); $mockBuilder->disableOriginalConstructor(); $mock = $mockBuilder->getMockForAbstractClass(); diff --git a/app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php b/app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php index e473f714bd21d..cea19c098b928 100644 --- a/app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php +++ b/app/code/Magento/CatalogInventory/Observer/ProcessInventoryDataObserver.php @@ -97,7 +97,7 @@ private function prepareQuantityAndStockStatus(StockItemInterface $stockItem, ar ) { unset($quantityAndStockStatus['is_in_stock']); } - if (isset($quantityAndStockStatus['qty']) + if (array_key_exists('qty', $quantityAndStockStatus) && $stockItem->getQty() == $quantityAndStockStatus['qty'] ) { unset($quantityAndStockStatus['qty']); diff --git a/composer.json b/composer.json index fbc378d01a5cd..96f37a91a71dd 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "composer/composer": "1.4.1", "monolog/monolog": "^1.17", "oyejorge/less.php": "~1.7.0", - "pelago/emogrifier": "1.2.0", + "pelago/emogrifier": "^2.0.0", "tubalmartin/cssmin": "4.1.0", "magento/magento-composer-installer": ">=0.1.11", "braintree/braintree_php": "3.25.0", diff --git a/composer.lock b/composer.lock index 2f9c7d47e323b..5f534ede5b5f9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "009029e4e58a3802cc9ad92333fad729", + "content-hash": "9203f9f6b859a7748f08eb1100f9e97e", "packages": [ { "name": "braintree/braintree_php", @@ -956,29 +956,29 @@ }, { "name": "pelago/emogrifier", - "version": "V1.2.0", + "version": "v2.0.0", "source": { "type": "git", - "url": "https://github.com/jjriv/emogrifier.git", - "reference": "a1db453bb504597d821efcc04b21c79a6021e00c" + "url": "https://github.com/MyIntervals/emogrifier.git", + "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jjriv/emogrifier/zipball/a1db453bb504597d821efcc04b21c79a6021e00c", - "reference": "a1db453bb504597d821efcc04b21c79a6021e00c", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/8babf8ddbf348f26b29674e2f84db66ff7e3d95e", + "reference": "8babf8ddbf348f26b29674e2f84db66ff7e3d95e", "shasum": "" }, "require": { - "php": ">=5.4.0,<=7.1.99" + "php": "^5.5.0 || ~7.0.0 || ~7.1.0 || ~7.2.0" }, "require-dev": { - "phpunit/phpunit": "4.8.27", - "squizlabs/php_codesniffer": "2.6.0" + "phpunit/phpunit": "^4.8.0", + "squizlabs/php_codesniffer": "^3.1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.1.x-dev" } }, "autoload": { @@ -1001,18 +1001,27 @@ { "name": "Jaime Prado" }, + { + "name": "Roman Ožana", + "email": "ozana@omdesign.cz" + }, { "name": "Oliver Klee", - "email": "typo3-coding@oliverklee.de" + "email": "github@oliverklee.de" }, { - "name": "Roman Ožana", - "email": "ozana@omdesign.cz" + "name": "Zoli Szabó", + "email": "zoli.szabo+github@gmail.com" } ], "description": "Converts CSS styles into inline style attributes in your HTML code", - "homepage": "http://www.pelagodesign.com/sidecar/emogrifier/", - "time": "2017-03-02T12:51:48+00:00" + "homepage": "https://www.myintervals.com/emogrifier.php", + "keywords": [ + "css", + "email", + "pre-processing" + ], + "time": "2018-01-05T23:30:21+00:00" }, { "name": "phpseclib/phpseclib", diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php index c597741afca97..a68b0942ec090 100644 --- a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php +++ b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php @@ -352,9 +352,9 @@ public function inlinecssDirectiveDataProvider() false, true, ], - 'Production mode - File with compilation error results in unmodified markup' => [ + 'Production mode - File with compilation error results in structurally unmodified markup' => [ '

{{inlinecss file="css/file-with-error.css"}}', - '

', + '

', true, ], 'Developer mode - File with compilation error results in error message' => [ diff --git a/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/CssInliner.php b/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/CssInliner.php index 7164e68c709fb..b54761698f16c 100644 --- a/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/CssInliner.php +++ b/lib/internal/Magento/Framework/Css/PreProcessor/Adapter/CssInliner.php @@ -5,6 +5,7 @@ */ namespace Magento\Framework\Css\PreProcessor\Adapter; +use Magento\Framework\App\State; use Pelago\Emogrifier; /** @@ -17,9 +18,13 @@ class CssInliner */ private $emogrifier; - public function __construct() + /** + * @param State $appState + */ + public function __construct(State $appState) { $this->emogrifier = new Emogrifier(); + $this->emogrifier->setDebug($appState->getMode() === State::MODE_DEVELOPER); } /**