diff --git a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php index d8ac9fdf9131d8dbab66cde7181dfa23b28ec63c..0ec9ddf3298f9daec7ab9dfec22765ad95521919 100644 --- a/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php +++ b/app/code/Magento/Bundle/Ui/DataProvider/Product/Form/Modifier/BundlePanel.php @@ -458,7 +458,8 @@ class BundlePanel extends AbstractModifier 'component' => 'Magento_Bundle/js/components/bundle-input-type', 'parentContainer' => 'product_bundle_container', 'selections' => 'bundle_selections', - 'targetIndex' => 'is_default', + 'isDefaultIndex' => 'is_default', + 'userDefinedIndex' => 'selection_can_change_qty', 'dataScope' => 'type', 'label' => __('Input Type'), 'sortOrder' => 20, diff --git a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-input-type.js b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-input-type.js index e52856e53891c64981c9e617afb01c77b453363a..14dd426ed02aa7f144c109a0ac17016be2d56329 100644 --- a/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-input-type.js +++ b/app/code/Magento/Bundle/view/adminhtml/web/js/components/bundle-input-type.js @@ -26,36 +26,42 @@ define([ if (type !== this.previousType) { this.previousType = type; - - if (type === 'radio') { - this.clearValues(); - } + this.processSelections(type === 'radio'); } this._super(); }, /** - * Clears values in components like this. + * Toggle 'User Defined' column and clears values + * @param {Boolean} isRadio */ - clearValues: function () { + processSelections: function (isRadio) { var records = registry.get(this.retrieveParentName(this.parentContainer) + '.' + this.selections), checkedFound = false; records.elems.each(function (record) { record.elems.filter(function (comp) { - return comp.index === this.targetIndex; + return comp.index === this.userDefinedIndex; }, this).each(function (comp) { - if (comp.checked()) { - if (checkedFound) { - comp.clearing = true; - comp.clear(); - comp.clearing = false; - } - - checkedFound = true; - } + comp.visible(isRadio); }); + + if (isRadio) { + record.elems.filter(function (comp) { + return comp.index === this.isDefaultIndex; + }, this).each(function (comp) { + if (comp.checked()) { + if (checkedFound) { + comp.clearing = true; + comp.clear(); + comp.clearing = false; + } + + checkedFound = true; + } + }); + } }, this); }, diff --git a/app/code/Magento/CacheInvalidate/etc/events.xml b/app/code/Magento/CacheInvalidate/etc/events.xml index 47d27f98f1e796419333e74dc467a4a7628468b6..58ddeb64c9257d70788d9c63dbfbbc77099dea4f 100644 --- a/app/code/Magento/CacheInvalidate/etc/events.xml +++ b/app/code/Magento/CacheInvalidate/etc/events.xml @@ -48,4 +48,7 @@ <event name="controller_action_postdispatch_adminhtml_system_currencysymbol_save"> <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Observer\InvalidateVarnishObserver"/> </event> + <event name="clean_cache_after_reindex"> + <observer name="flush_varnish_pagecache" instance="Magento\CacheInvalidate\Observer\InvalidateVarnishObserver"/> + </event> </config> \ No newline at end of file diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/AffectCache.php b/app/code/Magento/Catalog/Model/Indexer/Category/AffectCache.php deleted file mode 100644 index 098e636b8655cd07053490f3b454c1507ef73f17..0000000000000000000000000000000000000000 --- a/app/code/Magento/Catalog/Model/Indexer/Category/AffectCache.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Catalog\Model\Indexer\Category; - -/** - * Class AffectCache - */ -class AffectCache -{ - /** - * @var \Magento\Framework\Indexer\CacheContext - */ - protected $context; - - /** - * @param \Magento\Framework\Indexer\CacheContext $context - */ - public function __construct( - \Magento\Framework\Indexer\CacheContext $context - ) { - $this->context = $context; - } - - /** - * @param \Magento\Framework\Indexer\ActionInterface $subject - * @param array $ids - * @return array - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function beforeExecute(\Magento\Framework\Indexer\ActionInterface $subject, $ids) - { - $this->context->registerEntities(\Magento\Catalog\Model\Category::CACHE_TAG, $ids); - return [$ids]; - } -} diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat.php index 2338a72c1aa7891d76daf25eaa507c8c7074dbb8..280f53fe70186970b6fb98e9cda4b18eb5f588d0 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model\Indexer\Category; +use Magento\Framework\Indexer\CacheContext; + class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface { /** @@ -17,9 +19,16 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame */ protected $rowsActionFactory; - /** @var \Magento\Framework\Indexer\IndexerRegistry */ + /** + * @var \Magento\Framework\Indexer\IndexerRegistry + */ protected $indexerRegistry; + /** + * @var \Magento\Framework\Indexer\CacheContext + */ + private $cacheContext; + /** * @param Flat\Action\FullFactory $fullActionFactory * @param Flat\Action\RowsFactory $rowsActionFactory @@ -54,6 +63,7 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame $action->reindex($ids, true); } $action->reindex($ids); + $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Category::CACHE_TAG, $ids); } /** @@ -64,6 +74,7 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame public function executeFull() { $this->fullActionFactory->create()->reindexAll(); + $this->getCacheContext()->registerTags([\Magento\Catalog\Model\Category::CACHE_TAG]); } /** @@ -87,4 +98,19 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame { $this->execute([$id]); } + + /** + * Get cache context + * + * @return \Magento\Framework\Indexer\CacheContext + * @deprecated + */ + protected function getCacheContext() + { + if (!($this->cacheContext instanceof CacheContext)) { + return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class); + } else { + return $this->cacheContext; + } + } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product.php index 44a24f4623d7fa008247246577548e182513da64..ffcca0d3dfb7a7b1fdb80cca772cacc8c3aba895 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model\Indexer\Category; +use Magento\Framework\Indexer\CacheContext; + class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface { /** @@ -22,9 +24,16 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr */ protected $rowsActionFactory; - /** @var \Magento\Framework\Indexer\IndexerRegistry */ + /** + * @var \Magento\Framework\Indexer\IndexerRegistry + */ protected $indexerRegistry; + /** + * @var \Magento\Framework\Indexer\CacheContext + */ + protected $cacheContext; + /** * @param Product\Action\FullFactory $fullActionFactory * @param Product\Action\RowsFactory $rowsActionFactory @@ -49,6 +58,18 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr public function execute($ids) { $this->executeAction($ids); + $this->registerEntities($ids); + } + + /** + * Add entities to cache context + * + * @param int[] $ids + * @return void + */ + protected function registerEntities($ids) + { + $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Category::CACHE_TAG, $ids); } /** @@ -59,6 +80,17 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr public function executeFull() { $this->fullActionFactory->create()->execute(); + $this->registerTags(); + } + + /** + * Add tags to cache context + * + * @return void + */ + protected function registerTags() + { + $this->getCacheContext()->registerTags([\Magento\Catalog\Model\Category::CACHE_TAG]); } /** @@ -103,4 +135,19 @@ class Product implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fr return $this; } + + /** + * Get cache context + * + * @return \Magento\Framework\Indexer\CacheContext + * @deprecated + */ + protected function getCacheContext() + { + if (!($this->cacheContext instanceof CacheContext)) { + return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class); + } else { + return $this->cacheContext; + } + } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/AffectCache.php b/app/code/Magento/Catalog/Model/Indexer/Product/AffectCache.php deleted file mode 100644 index 44a00e41e75459ff91be930671164083cedc1048..0000000000000000000000000000000000000000 --- a/app/code/Magento/Catalog/Model/Indexer/Product/AffectCache.php +++ /dev/null @@ -1,39 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -namespace Magento\Catalog\Model\Indexer\Product; - -/** - * Class AffectCache - */ -class AffectCache -{ - /** - * @var \Magento\Framework\Indexer\CacheContext $context - */ - protected $context; - - /** - * @param \Magento\Framework\Indexer\CacheContext $context - */ - public function __construct( - \Magento\Framework\Indexer\CacheContext $context - ) { - $this->context = $context; - } - - /** - * @param \Magento\Framework\Indexer\ActionInterface $subject - * @param array $ids - * @return array - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ - public function beforeExecute(\Magento\Framework\Indexer\ActionInterface $subject, $ids) - { - $this->context->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); - return [$ids]; - } -} diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Category.php b/app/code/Magento/Catalog/Model/Indexer/Product/Category.php index 282591ba26b2ac17600cfa2a5dc5f222f66c3dd1..b272870b9f770e5de82cbb04d21d6c2320b7a8eb 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Category.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Category.php @@ -24,4 +24,30 @@ class Category extends \Magento\Catalog\Model\Indexer\Category\Product ) { parent::__construct($fullActionFactory, $rowsActionFactory, $indexerRegistry); } + + /** + * Add tags to cache context + * + * @return void + */ + protected function registerTags() + { + $this->getCacheContext()->registerTags( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ] + ); + } + + /** + * Add entities to cache context + * + * @param int[] $ids + * @return void + */ + protected function registerEntities($ids) + { + $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); + } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php index a66637e8b3a88dd3ce05378cf7e689f9b932ee1d..0b3ccf1cc4c886bf40cd23c0013e2bb9dea77289 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model\Indexer\Product; +use Magento\Framework\Indexer\CacheContext; + class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface { /** @@ -22,6 +24,11 @@ class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framew */ protected $_productEavIndexerFull; + /** + * @var \Magento\Framework\Indexer\CacheContext + */ + private $cacheContext; + /** * @param Eav\Action\Row $productEavIndexerRow * @param Eav\Action\Rows $productEavIndexerRows @@ -46,6 +53,7 @@ class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framew public function execute($ids) { $this->_productEavIndexerRows->execute($ids); + $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); } /** @@ -56,6 +64,12 @@ class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framew public function executeFull() { $this->_productEavIndexerFull->execute(); + $this->getCacheContext()->registerTags( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ] + ); } /** @@ -79,4 +93,19 @@ class Eav implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framew { $this->_productEavIndexerRow->execute($id); } + + /** + * Get cache context + * + * @return \Magento\Framework\Indexer\CacheContext + * @deprecated + */ + protected function getCacheContext() + { + if (!($this->cacheContext instanceof CacheContext)) { + return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class); + } else { + return $this->cacheContext; + } + } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat.php index 47d525ede8c1f142c192fe270fb6a87057133639..e423d9553bcb39e3adb6bd8328311428297817e8 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model\Indexer\Product; +use Magento\Framework\Indexer\CacheContext; + class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface { /** @@ -22,6 +24,11 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame */ protected $_productFlatIndexerFull; + /** + * @var \Magento\Framework\Indexer\CacheContext + */ + private $cacheContext; + /** * @param Flat\Action\Row $productFlatIndexerRow * @param Flat\Action\Rows $productFlatIndexerRows @@ -46,6 +53,7 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame public function execute($ids) { $this->_productFlatIndexerRows->execute($ids); + $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); } /** @@ -56,6 +64,12 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame public function executeFull() { $this->_productFlatIndexerFull->execute(); + $this->getCacheContext()->registerTags( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ] + ); } /** @@ -79,4 +93,19 @@ class Flat implements \Magento\Framework\Indexer\ActionInterface, \Magento\Frame { $this->_productFlatIndexerRow->execute($id); } + + /** + * Get cache context + * + * @return \Magento\Framework\Indexer\CacheContext + * @deprecated + */ + protected function getCacheContext() + { + if (!($this->cacheContext instanceof CacheContext)) { + return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class); + } else { + return $this->cacheContext; + } + } } diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Price.php b/app/code/Magento/Catalog/Model/Indexer/Product/Price.php index ea763354a70d7a24cc5c77403f6028563dc82159..f8ed6cb6d2fe4ce43b646e48fcee628c41e4f3ec 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Product/Price.php +++ b/app/code/Magento/Catalog/Model/Indexer/Product/Price.php @@ -5,6 +5,8 @@ */ namespace Magento\Catalog\Model\Indexer\Product; +use Magento\Framework\Indexer\CacheContext; + class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface { /** @@ -22,6 +24,11 @@ class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram */ protected $_productPriceIndexerFull; + /** + * @var \Magento\Framework\Indexer\CacheContext + */ + private $cacheContext; + /** * @param Price\Action\Row $productPriceIndexerRow * @param Price\Action\Rows $productPriceIndexerRows @@ -46,6 +53,7 @@ class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram public function execute($ids) { $this->_productPriceIndexerRows->execute($ids); + $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); } /** @@ -56,6 +64,12 @@ class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram public function executeFull() { $this->_productPriceIndexerFull->execute(); + $this->getCacheContext()->registerTags( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ] + ); } /** @@ -79,4 +93,19 @@ class Price implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram { $this->_productPriceIndexerRow->execute($id); } + + /** + * Get cache context + * + * @return \Magento\Framework\Indexer\CacheContext + * @deprecated + */ + protected function getCacheContext() + { + if (!($this->cacheContext instanceof CacheContext)) { + return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class); + } else { + return $this->cacheContext; + } + } } diff --git a/app/code/Magento/Catalog/Setup/UpgradeData.php b/app/code/Magento/Catalog/Setup/UpgradeData.php index 2e05d5b0ac770bdeaacd056a52819a0c582ca1e5..542fea6770fab226e2bb7d22643d0dc74f66218e 100644 --- a/app/code/Magento/Catalog/Setup/UpgradeData.php +++ b/app/code/Magento/Catalog/Setup/UpgradeData.php @@ -257,6 +257,12 @@ class UpgradeData implements UpgradeDataInterface 'frontend_label', 'Small' ); + $categorySetup->updateAttribute( + ProductAttributeInterface::ENTITY_TYPE_CODE, + 'image', + 'frontend_input_renderer', + null + ); //Design tab $categorySetup->updateAttribute( diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/AffectCacheTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/AffectCacheTest.php deleted file mode 100644 index d0d3cb3d2fa18f2d329437202eb99f2e88db97db..0000000000000000000000000000000000000000 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/AffectCacheTest.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -namespace Magento\Catalog\Test\Unit\Model\Indexer\Category; - -class AffectCacheTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \Magento\Catalog\Model\Indexer\Category\AffectCache - */ - protected $plugin; - - /** - * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var \Magento\Framework\Indexer\ActionInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $subjectMock; - - /** - * Set up - */ - protected function setUp() - { - $this->subjectMock = $this->getMockForAbstractClass('Magento\Framework\Indexer\ActionInterface', - [], '', false, true, true, []); - $this->contextMock = $this->getMock('Magento\Framework\Indexer\CacheContext', - [], [], '', false); - $this->plugin = new \Magento\Catalog\Model\Indexer\Category\AffectCache($this->contextMock); - } - - /** - * test beforeExecute - */ - public function testBeforeExecute() - { - $expectedIds = [5, 6, 7]; - $this->contextMock->expects($this->once()) - ->method('registerEntities') - ->with($this->equalTo(\Magento\Catalog\Model\Category::ENTITY), - $this->equalTo($expectedIds)) - ->will($this->returnValue($this->contextMock)); - $actualIds = $this->plugin->beforeExecute($this->subjectMock, $expectedIds); - $this->assertEquals([$expectedIds], $actualIds); - } -} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/FlatTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/FlatTest.php index 1f7edb65e9432ef02500ece8a2f4b57fb6da2718..0be219fdecd91f9b51436a06ca0bc1c990b8fb63 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/FlatTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/FlatTest.php @@ -32,6 +32,11 @@ class FlatTest extends \PHPUnit_Framework_TestCase */ protected $indexerRegistryMock; + /** + * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject + */ + protected $cacheContextMock; + protected function setUp() { $this->fullMock = $this->getMock( @@ -73,6 +78,15 @@ class FlatTest extends \PHPUnit_Framework_TestCase $this->rowsMock, $this->indexerRegistryMock ); + + $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false); + + $cacheContextProperty = new \ReflectionProperty( + \Magento\Catalog\Model\Indexer\Category\Flat::class, + 'cacheContext' + ); + $cacheContextProperty->setAccessible(true); + $cacheContextProperty->setValue($this->model, $this->cacheContextMock); } public function testExecuteWithIndexerInvalid() @@ -105,6 +119,10 @@ class FlatTest extends \PHPUnit_Framework_TestCase $this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock)); + $this->cacheContextMock->expects($this->once()) + ->method('registerEntities') + ->with(\Magento\Catalog\Model\Category::CACHE_TAG, $ids); + $this->model->execute($ids); } @@ -127,6 +145,10 @@ class FlatTest extends \PHPUnit_Framework_TestCase $this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock)); + $this->cacheContextMock->expects($this->once()) + ->method('registerEntities') + ->with(\Magento\Catalog\Model\Category::CACHE_TAG, $ids); + $this->model->execute($ids); } @@ -137,4 +159,25 @@ class FlatTest extends \PHPUnit_Framework_TestCase ->with(\Magento\Catalog\Model\Indexer\Category\Flat\State::INDEXER_ID) ->will($this->returnValue($this->indexerMock)); } + + public function testExecuteFull() + { + /** @var \Magento\Catalog\Model\Indexer\Category\Flat\Action\Full $categoryIndexerFlatFull */ + $categoryIndexerFlatFull = $this->getMock( + \Magento\Catalog\Model\Indexer\Category\Flat\Action\Full::class, + [], + [], + '', + false + ); + $this->fullMock->expects($this->once()) + ->method('create') + ->willReturn($categoryIndexerFlatFull); + $categoryIndexerFlatFull->expects($this->once()) + ->method('reindexAll'); + $this->cacheContextMock->expects($this->once()) + ->method('registerTags') + ->with([\Magento\Catalog\Model\Category::CACHE_TAG]); + $this->model->executeFull(); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php index 72f53360b9a17279b83b2cac8c39112d46713511..2dd1d30500cd5c302b45f57432bf9ddf25dcd713 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Category/ProductTest.php @@ -32,6 +32,11 @@ class ProductTest extends \PHPUnit_Framework_TestCase */ protected $indexerRegistryMock; + /** + * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject + */ + protected $cacheContextMock; + protected function setUp() { $this->fullMock = $this->getMock( @@ -73,6 +78,15 @@ class ProductTest extends \PHPUnit_Framework_TestCase $this->rowsMock, $this->indexerRegistryMock ); + + $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false); + + $cacheContextProperty = new \ReflectionProperty( + \Magento\Catalog\Model\Indexer\Category\Product::class, + 'cacheContext' + ); + $cacheContextProperty->setAccessible(true); + $cacheContextProperty->setValue($this->model, $this->cacheContextMock); } public function testExecuteWithIndexerWorking() @@ -115,6 +129,10 @@ class ProductTest extends \PHPUnit_Framework_TestCase $this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock)); + $this->cacheContextMock->expects($this->once()) + ->method('registerEntities') + ->with(\Magento\Catalog\Model\Category::CACHE_TAG, $ids); + $this->model->execute($ids); } @@ -125,4 +143,25 @@ class ProductTest extends \PHPUnit_Framework_TestCase ->with(\Magento\Catalog\Model\Indexer\Category\Product::INDEXER_ID) ->will($this->returnValue($this->indexerMock)); } + + public function testExecuteFull() + { + /** @var \Magento\Catalog\Model\Indexer\Category\Product\Action\Full $productIndexerFlatFull */ + $productIndexerFlatFull = $this->getMock( + \Magento\Catalog\Model\Indexer\Category\Product\Action\Full::class, + [], + [], + '', + false + ); + $this->fullMock->expects($this->once()) + ->method('create') + ->willReturn($productIndexerFlatFull); + $productIndexerFlatFull->expects($this->once()) + ->method('execute'); + $this->cacheContextMock->expects($this->once()) + ->method('registerTags') + ->with([\Magento\Catalog\Model\Category::CACHE_TAG]); + $this->model->executeFull(); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/AffectCacheTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/AffectCacheTest.php deleted file mode 100644 index a69eb70638a41b8e4c4fa1eeeaa081c3e7d01ac6..0000000000000000000000000000000000000000 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/AffectCacheTest.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ - -// @codingStandardsIgnoreFile - -namespace Magento\Catalog\Test\Unit\Model\Indexer\Product; - -class AffectCacheTest extends \PHPUnit_Framework_TestCase -{ - /** - * @var \Magento\PageCache\Model\Indexer\Product\RefreshPlugin - */ - protected $plugin; - - /** - * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject - */ - protected $contextMock; - - /** - * @var \Magento\Framework\Indexer\ActionInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $subjectMock; - - /** - * Set up - */ - protected function setUp() - { - $this->subjectMock = $this->getMockForAbstractClass('Magento\Framework\Indexer\ActionInterface', - [], '', false, true, true, []); - $this->contextMock = $this->getMock('Magento\Framework\Indexer\CacheContext', - [], [], '', false); - $this->plugin = new \Magento\Catalog\Model\Indexer\Product\AffectCache($this->contextMock); - } - - /** - * test beforeExecute - */ - public function testBeforeExecute() - { - $expectedIds = [1, 2, 3]; - $this->contextMock->expects($this->once()) - ->method('registerEntities') - ->with($this->equalTo(\Magento\Catalog\Model\Product::ENTITY), - $this->equalTo($expectedIds)) - ->will($this->returnValue($this->contextMock)); - $actualIds = $this->plugin->beforeExecute($this->subjectMock, $expectedIds); - $this->assertEquals([$expectedIds], $actualIds); - } -} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/CategoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/CategoryTest.php index 0b80262ef9223acaee11274839f3f9fdd2eb2c0c..9910ca7f06ba635c560436139461a2c259c6b8a8 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/CategoryTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/CategoryTest.php @@ -32,6 +32,11 @@ class CategoryTest extends \PHPUnit_Framework_TestCase */ protected $indexerRegistryMock; + /** + * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject + */ + protected $cacheContextMock; + protected function setUp() { $this->fullMock = $this->getMock( @@ -73,6 +78,15 @@ class CategoryTest extends \PHPUnit_Framework_TestCase $this->rowsMock, $this->indexerRegistryMock ); + + $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false); + + $cacheContextProperty = new \ReflectionProperty( + \Magento\Catalog\Model\Indexer\Category\Product::class, + 'cacheContext' + ); + $cacheContextProperty->setAccessible(true); + $cacheContextProperty->setValue($this->model, $this->cacheContextMock); } public function testExecuteWithIndexerWorking() @@ -115,6 +129,10 @@ class CategoryTest extends \PHPUnit_Framework_TestCase $this->rowsMock->expects($this->once())->method('create')->will($this->returnValue($rowMock)); + $this->cacheContextMock->expects($this->once()) + ->method('registerEntities') + ->with(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); + $this->model->execute($ids); } @@ -125,4 +143,30 @@ class CategoryTest extends \PHPUnit_Framework_TestCase ->with(\Magento\Catalog\Model\Indexer\Product\Category::INDEXER_ID) ->will($this->returnValue($this->indexerMock)); } + + public function testExecuteFull() + { + /** @var \Magento\Catalog\Model\Indexer\Category\Product\Action\Full $productIndexerFlatFull */ + $productIndexerFlatFull = $this->getMock( + \Magento\Catalog\Model\Indexer\Category\Product\Action\Full::class, + [], + [], + '', + false + ); + $this->fullMock->expects($this->once()) + ->method('create') + ->willReturn($productIndexerFlatFull); + $productIndexerFlatFull->expects($this->once()) + ->method('execute'); + $this->cacheContextMock->expects($this->once()) + ->method('registerTags') + ->with( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ] + ); + $this->model->executeFull(); + } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/EavTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/EavTest.php index 34801d07e557b0fad7d4e2409e923f05fb489925..446fde618b8c96fec75393950d112d7f7c39acf6 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/EavTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/EavTest.php @@ -27,6 +27,11 @@ class EavTest extends \PHPUnit_Framework_TestCase */ protected $_productEavIndexerFull; + /** + * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject + */ + protected $cacheContextMock; + protected function setUp() { $this->_productEavIndexerRow = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Eav\Action\Row') @@ -41,22 +46,44 @@ class EavTest extends \PHPUnit_Framework_TestCase ->disableOriginalConstructor() ->getMock(); - $this->_model = new \Magento\Catalog\Model\Indexer\Product\Eav( + $this->model = new \Magento\Catalog\Model\Indexer\Product\Eav( $this->_productEavIndexerRow, $this->_productEavIndexerRows, $this->_productEavIndexerFull ); + + $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false); + + $cacheContextProperty = new \ReflectionProperty( + \Magento\Catalog\Model\Indexer\Product\Eav::class, + 'cacheContext' + ); + $cacheContextProperty->setAccessible(true); + $cacheContextProperty->setValue($this->model, $this->cacheContextMock); + } + + public function testExecute() + { + $ids = [1, 2, 3]; + $this->_productEavIndexerRow->expects($this->any()) + ->method('execute') + ->with($ids); + + $this->cacheContextMock->expects($this->once()) + ->method('registerEntities') + ->with(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); + + $this->model->execute($ids); } - public function testExecuteAndExecuteList() + public function testExecuteList() { $ids = [1, 2, 3]; $this->_productEavIndexerRow->expects($this->any()) ->method('execute') ->with($ids); - $this->_model->execute($ids); - $this->_model->executeList($ids); + $this->model->executeList($ids); } public function testExecuteFull() @@ -64,7 +91,16 @@ class EavTest extends \PHPUnit_Framework_TestCase $this->_productEavIndexerFull->expects($this->once()) ->method('execute'); - $this->_model->executeFull(); + $this->cacheContextMock->expects($this->once()) + ->method('registerTags') + ->with( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ] + ); + + $this->model->executeFull(); } public function testExecuteRow() @@ -74,6 +110,6 @@ class EavTest extends \PHPUnit_Framework_TestCase ->method('execute') ->with($id); - $this->_model->executeRow($id); + $this->model->executeRow($id); } } diff --git a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/FlatTest.php b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/FlatTest.php index cb4d485cfd1ac0d417ab6d828673cda0858c69d9..f9eb1b1d29099c4a902c7babec37cd5cc12b0436 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/FlatTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/Indexer/Product/FlatTest.php @@ -29,6 +29,11 @@ class FlatTest extends \PHPUnit_Framework_TestCase */ private $productFlatIndexerFull; + /** + * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject + */ + protected $cacheContextMock; + protected function setUp() { $this->productFlatIndexerRow = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Flat\Action\Row') @@ -52,21 +57,50 @@ class FlatTest extends \PHPUnit_Framework_TestCase 'productFlatIndexerFull' => $this->productFlatIndexerFull ] ); + + $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false); + + $cacheContextProperty = new \ReflectionProperty( + \Magento\Catalog\Model\Indexer\Product\Flat::class, + 'cacheContext' + ); + $cacheContextProperty->setAccessible(true); + $cacheContextProperty->setValue($this->model, $this->cacheContextMock); } - public function testExecuteAndExecuteList() + public function testExecute() { - $except = ['test']; - $this->productFlatIndexerRows->expects($this->any())->method('execute')->with($this->equalTo($except)); + $ids = [1, 2, 3]; + $this->productFlatIndexerRows->expects($this->any())->method('execute')->with($this->equalTo($ids)); - $this->model->execute($except); - $this->model->executeList($except); + $this->cacheContextMock->expects($this->once()) + ->method('registerEntities') + ->with(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); + + $this->model->execute($ids); + } + + public function testExecuteList() + { + $ids = [1, 2, 3]; + $this->productFlatIndexerRows->expects($this->any())->method('execute')->with($this->equalTo($ids)); + + $this->model->executeList($ids); } public function testExecuteFull() { $this->productFlatIndexerFull->expects($this->any())->method('execute'); + $this->cacheContextMock->expects($this->once()) + ->method('registerTags') + ->with( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ] + ); + $this->model->executeFull(); } diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php index 473d1d423067478ea94d0c8b5afcc88c68de40c2..61141072f7725e165cb29938e7878b6b240ef6a6 100644 --- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php +++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/CustomOptions.php @@ -319,8 +319,7 @@ class CustomOptions extends AbstractModifier 'sortOrder' => 20, 'actions' => [ [ - 'targetName' => static::FORM_NAME . '.' . static::FORM_NAME . '.' - . static::GROUP_CUSTOM_OPTIONS_NAME . '.' . static::GRID_OPTIONS_NAME, + 'targetName' => 'ns = ${ $.ns }, index = ' . static::GRID_OPTIONS_NAME, 'actionName' => 'addChild', ] ] diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 65e14be97edd1e665caa49615319724f8b62fecf..19a4f22a3c8e9425d474873f321f08baf062113c 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -194,10 +194,6 @@ <plugin name="indexerCategoryFlatConfigGet" type="Magento\Catalog\Model\Indexer\Category\Flat\Plugin\IndexerConfigData" /> <plugin name="indexerProductFlatConfigGet" type="Magento\Catalog\Model\Indexer\Product\Flat\Plugin\IndexerConfigData" /> </type> - <type name="Magento\Catalog\Model\Indexer\Category\Flat"> - <plugin name="page-cache-indexer-reindex-category-flat" - type="Magento\Catalog\Model\Indexer\Category\AffectCache" sortOrder="10"/> - </type> <type name="Magento\Catalog\Model\Indexer\Product\Price\AbstractAction"> <arguments> <argument name="defaultPriceIndexer" xsi:type="object">Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice</argument> @@ -213,14 +209,6 @@ </argument> </arguments> </type> - <type name="Magento\Catalog\Model\Indexer\Category\Product"> - <plugin name="page-cache-indexer-reindex-category-product" - type="Magento\Catalog\Model\Indexer\Product\AffectCache" sortOrder="10"/> - </type> - <type name="Magento\Catalog\Model\Indexer\Product\Category"> - <plugin name="page-cache-indexer-reindex-product-category" - type="Magento\Catalog\Model\Indexer\Category\AffectCache" sortOrder="10"/> - </type> <type name="Magento\Catalog\Model\Product\LinkTypeProvider"> <arguments> <argument name="linkTypes" xsi:type="array"> @@ -285,10 +273,6 @@ <argument name="indexer" xsi:type="object" shared="false">Magento\Framework\Indexer\IndexerInterface</argument> </arguments> </type> - <type name="Magento\Catalog\Model\Indexer\Product\Flat"> - <plugin name="page-cache-indexer-reindex-product-flat" - type="Magento\Catalog\Model\Indexer\Product\AffectCache" sortOrder="10"/> - </type> <type name="Magento\Framework\Model\ActionValidator\RemoveAction"> <arguments> <argument name="protectedModels" xsi:type="array"> diff --git a/app/code/Magento/Catalog/view/base/web/js/price-box.js b/app/code/Magento/Catalog/view/base/web/js/price-box.js index ff06f34db85c69a978fccd1f472702f13b749f50..b095d24cf481067fd6edce586f8a9131dbcde3be 100644 --- a/app/code/Magento/Catalog/view/base/web/js/price-box.js +++ b/app/code/Magento/Catalog/view/base/web/js/price-box.js @@ -184,7 +184,7 @@ define([ var type = $(element).data('priceType'), amount = parseFloat($(element).data('priceAmount')); - if (type && amount) { + if (type && !_.isNaN(amount)) { prices[type] = { amount: amount }; diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php index 2fc215cb2e9766953431e42ebf5ffc14d7cac262..0e86e0ac793ac55f9c7771c3b8d37a3ba2da0f05 100644 --- a/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php @@ -1,13 +1,12 @@ <?php /** - * @category Magento - * @package Magento_CatalogInventory * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\CatalogInventory\Model\Indexer; +use Magento\Framework\Indexer\CacheContext; + class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface { /** @@ -25,6 +24,11 @@ class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram */ protected $_productStockIndexerFull; + /** + * @var \Magento\Framework\Indexer\CacheContext + */ + private $cacheContext; + /** * @param Stock\Action\Row $productStockIndexerRow * @param Stock\Action\Rows $productStockIndexerRows @@ -50,6 +54,7 @@ class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram public function execute($ids) { $this->_productStockIndexerRows->execute($ids); + $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); } /** @@ -60,6 +65,12 @@ class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram public function executeFull() { $this->_productStockIndexerFull->execute(); + $this->getCacheContext()->registerTags( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG + ] + ); } /** @@ -85,4 +96,19 @@ class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Fram { $this->_productStockIndexerRow->execute($id); } + + /** + * Get cache context + * + * @return \Magento\Framework\Indexer\CacheContext + * @deprecated + */ + protected function getCacheContext() + { + if (!($this->cacheContext instanceof CacheContext)) { + return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class); + } else { + return $this->cacheContext; + } + } } diff --git a/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php b/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php index 7571b3e9a9facba4bd8e45feee10dbe73df21676..73d1f23582ce537a3aaa62f25a467393ab76b464 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/AbstractIndexer.php @@ -7,7 +7,8 @@ namespace Magento\CatalogRule\Model\Indexer; use Magento\Framework\Mview\ActionInterface as MviewActionInterface; use Magento\Framework\Indexer\ActionInterface as IndexerActionInterface; -use Magento\Framework\DataObject\IdentityInterface as IdentityInterface; +use Magento\Framework\DataObject\IdentityInterface; +use Magento\Framework\Indexer\CacheContext; abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInterface, IdentityInterface { @@ -28,6 +29,11 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt */ private $cacheManager; + /** + * @var \Magento\Framework\Indexer\CacheContext + */ + protected $cacheContext; + /** * @param IndexBuilder $indexBuilder * @param \Magento\Framework\Event\ManagerInterface $eventManager @@ -60,7 +66,7 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt { $this->indexBuilder->reindexFull(); $this->_eventManager->dispatch('clean_cache_by_tags', ['object' => $this]); - //TODO: remove after fix fpc. MAGETWO-49121 + //TODO: remove after fix fpc. MAGETWO-50668 $this->getCacheManager()->clean($this->getIdentities()); } @@ -144,4 +150,19 @@ abstract class AbstractIndexer implements IndexerActionInterface, MviewActionInt } return $this->cacheManager; } + + /** + * Get cache context + * + * @return \Magento\Framework\Indexer\CacheContext + * @deprecated + */ + protected function getCacheContext() + { + if (!($this->cacheContext instanceof CacheContext)) { + return \Magento\Framework\App\ObjectManager::getInstance()->get(CacheContext::class); + } else { + return $this->cacheContext; + } + } } diff --git a/app/code/Magento/CatalogRule/Model/Indexer/Product/ProductRuleIndexer.php b/app/code/Magento/CatalogRule/Model/Indexer/Product/ProductRuleIndexer.php index 08b35927226503fbc1b404500cc733a0a7d090b5..696f3c6ec803d0a69d68a9c840395abf2f2a3a34 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/Product/ProductRuleIndexer.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/Product/ProductRuleIndexer.php @@ -15,6 +15,7 @@ class ProductRuleIndexer extends AbstractIndexer protected function doExecuteList($ids) { $this->indexBuilder->reindexByIds(array_unique($ids)); + $this->getCacheContext()->registerEntities(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); } /** diff --git a/app/code/Magento/CatalogRule/Model/Indexer/Rule/RuleProductIndexer.php b/app/code/Magento/CatalogRule/Model/Indexer/Rule/RuleProductIndexer.php index 8d627bc80d313d1adfe27ca10f535b5a7c664e02..b5125501571e0817af278803845e37022efa633c 100644 --- a/app/code/Magento/CatalogRule/Model/Indexer/Rule/RuleProductIndexer.php +++ b/app/code/Magento/CatalogRule/Model/Indexer/Rule/RuleProductIndexer.php @@ -17,6 +17,7 @@ class RuleProductIndexer extends AbstractIndexer protected function doExecuteList($ids) { $this->indexBuilder->reindexFull(); + $this->getCacheContext()->registerTags($this->getIdentities()); } /** diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Product/ProductRuleIndexerTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Product/ProductRuleIndexerTest.php index cd503d22c66f05e0dbb8b637ba26332051700379..c0d76d027f034b903cc4b26d982e5b48b21c9d1e 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Product/ProductRuleIndexerTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Product/ProductRuleIndexerTest.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\CatalogRule\Test\Unit\Model\Indexer\Product; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; @@ -20,6 +19,11 @@ class ProductRuleIndexerTest extends \PHPUnit_Framework_TestCase */ protected $indexer; + /** + * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject + */ + protected $cacheContextMock; + protected function setUp() { $this->indexBuilder = $this->getMock('Magento\CatalogRule\Model\Indexer\IndexBuilder', [], [], '', false); @@ -30,7 +34,17 @@ class ProductRuleIndexerTest extends \PHPUnit_Framework_TestCase 'indexBuilder' => $this->indexBuilder, ] ); + + $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false); + + $cacheContextProperty = new \ReflectionProperty( + \Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer::class, + 'cacheContext' + ); + $cacheContextProperty->setAccessible(true); + $cacheContextProperty->setValue($this->indexer, $this->cacheContextMock); } + /** * @param array $ids * @param array $idsForIndexer @@ -38,8 +52,12 @@ class ProductRuleIndexerTest extends \PHPUnit_Framework_TestCase */ public function testDoExecuteList($ids, $idsForIndexer) { - $this->indexBuilder->expects($this->once())->method('reindexByIds')->with($idsForIndexer); - + $this->indexBuilder->expects($this->once()) + ->method('reindexByIds') + ->with($idsForIndexer); + $this->cacheContextMock->expects($this->once()) + ->method('registerEntities') + ->with(\Magento\Catalog\Model\Product::CACHE_TAG, $ids); $this->indexer->executeList($ids); } diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Rule/RuleProductIndexerTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Rule/RuleProductIndexerTest.php index 3af9eaff625d3f72813f4e330c52bac5aeb00da0..7522e34924284cd24d18c98e5850a4ff7844442c 100644 --- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Rule/RuleProductIndexerTest.php +++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/Rule/RuleProductIndexerTest.php @@ -20,6 +20,11 @@ class RuleProductIndexerTest extends \PHPUnit_Framework_TestCase */ protected $indexer; + /** + * @var \Magento\Framework\Indexer\CacheContext|\PHPUnit_Framework_MockObject_MockObject + */ + protected $cacheContextMock; + protected function setUp() { $this->indexBuilder = $this->getMock('Magento\CatalogRule\Model\Indexer\IndexBuilder', [], [], '', false); @@ -30,13 +35,31 @@ class RuleProductIndexerTest extends \PHPUnit_Framework_TestCase 'indexBuilder' => $this->indexBuilder, ] ); + + $this->cacheContextMock = $this->getMock(\Magento\Framework\Indexer\CacheContext::class, [], [], '', false); + + $cacheContextProperty = new \ReflectionProperty( + \Magento\CatalogRule\Model\Indexer\Rule\RuleProductIndexer::class, + 'cacheContext' + ); + $cacheContextProperty->setAccessible(true); + $cacheContextProperty->setValue($this->indexer, $this->cacheContextMock); } public function testDoExecuteList() { + $ids = [1, 2, 5]; $this->indexBuilder->expects($this->once())->method('reindexFull'); - - $this->indexer->executeList([1, 2, 5]); + $this->cacheContextMock->expects($this->once()) + ->method('registerTags') + ->with( + [ + \Magento\Catalog\Model\Category::CACHE_TAG, + \Magento\Catalog\Model\Product::CACHE_TAG, + \Magento\Framework\App\Cache\Type\Block::CACHE_TAG + ] + ); + $this->indexer->executeList($ids); } public function testDoExecuteRow() diff --git a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml index dbc98c4b59d52a82d3af8c01851f7ac9625e6f22..2b57747de4fcaee6268c3e77d800f45df7a95549 100644 --- a/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml +++ b/app/code/Magento/Cms/view/adminhtml/layout/cms_page_edit.xml @@ -6,7 +6,6 @@ */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> - <update handle="styles"/> <body> <referenceContainer name="content"> <uiComponent name="cms_page_form"/> diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php index 2fc849be10f10988356b977298168173a18a4f7b..fc496b83febb52d1ce0eaaa400e0d1faf65c8d8a 100644 --- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php +++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php @@ -509,8 +509,8 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType ->addAttributeToSelect('name') ->addAttributeToSelect('price') ->addAttributeToSelect('weight') -// ->addAttributeToSelect('msrp') -// ->addAttributeToSelect('media_gallery') + ->addAttributeToSelect('image') + ->addAttributeToSelect('status') ->addFilterByRequiredOptions() ->setStoreId($product->getStoreId()); diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php index ee8fa65e2a3dd91bcd749ebc7837ada0a2ea4efd..17139915dd8fed0ed9c657f5210e8c5749d76a24 100644 --- a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php +++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php @@ -48,9 +48,9 @@ class ConfigurablePriceResolver implements PriceResolverInterface $productPrice = $this->priceResolver->resolvePrice($subProduct); $price = $price ? min($price, $productPrice) : $productPrice; } - if (!$price) { + if ($price === null) { throw new \Magento\Framework\Exception\LocalizedException( - __('Configurable product "%1" do not have sub-products', $product->getName()) + __('Configurable product "%1" does not have sub-products', $product->getName()) ); } return (float)$price; diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php index 5ada8354ef0aa20987b733b7d49bbc8c9162ee65..d37335e7a0842f8418308ca8d915376f0ae50ffd 100644 --- a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Quote/Item/CartItemProcessorTest.php @@ -65,10 +65,15 @@ class CartItemProcessorTest extends \PHPUnit_Framework_TestCase false ); - $this->productOptionExtensionAttributes = $this->getMockBuilder(ProductOptionExtensionAttributes::class) - ->disableOriginalConstructor() - ->setMethods(['setConfigurableItemOptions']) - ->getMock(); + $this->productOptionExtensionAttributes = $this->getMockForAbstractClass( + ProductOptionExtensionAttributes::class, + [], + '', + false, + true, + true, + ['setConfigurableItemOptions'] + ); $this->model = new \Magento\ConfigurableProduct\Model\Quote\Item\CartItemProcessor( $this->objectFactoryMock, diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cb13fcf140c49dc687dcf6568e9a64fb369c71c2 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Pricing/Price/ConfigurablePriceResolverTest.php @@ -0,0 +1,104 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\ConfigurableProduct\Test\Unit\Pricing\Price; + +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; + +class ConfigurablePriceResolverTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver + */ + protected $resolver; + + /** + * @var PHPUnit_Framework_MockObject_MockObject | \Magento\ConfigurableProduct\Model\Product\Type\Configurable + */ + protected $configurable; + + /** + * @var PHPUnit_Framework_MockObject_MockObject | \Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface + */ + protected $priceResolver; + + protected function setUp() + { + $className = 'Magento\ConfigurableProduct\Model\Product\Type\Configurable'; + $this->configurable = $this->getMock($className, ['getUsedProducts'], [], '', false); + + $className = 'Magento\ConfigurableProduct\Pricing\Price\PriceResolverInterface'; + $this->priceResolver = $this->getMockForAbstractClass($className, [], '', false, true, true, ['resolvePrice']); + + $objectManager = new ObjectManager($this); + $this->resolver = $objectManager->getObject( + 'Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver', + [ + 'priceResolver' => $this->priceResolver, + 'configurable' => $this->configurable, + ] + ); + } + + /** + * situation: There are no used products, thus there are no prices + * + * @expectedException \Magento\Framework\Exception\LocalizedException + */ + public function testResolvePriceWithNoPrices() + { + $product = $this->getMockForAbstractClass( + 'Magento\Framework\Pricing\SaleableInterface', + [], + '', + false, + true, + true, + ['getName'] + ); + $product->expects($this->once())->method('getName')->willReturn('Kiwi'); + + $this->configurable->expects($this->once())->method('getUsedProducts')->willReturn([]); + + $this->resolver->resolvePrice($product); + } + + /** + * situation: one product is supplying the price, which could be a price of zero (0) + * + * @dataProvider testResolvePriceDataProvider + */ + public function testResolvePrice($expectedValue) + { + $price = $expectedValue; + + $product = $this->getMockForAbstractClass( + 'Magento\Framework\Pricing\SaleableInterface', + [], + '', + false, + true, + true, + ['getName'] + ); + $product->expects($this->never())->method('getName'); + + $this->configurable->expects($this->once())->method('getUsedProducts')->willReturn([$product]); + $this->priceResolver->expects($this->atLeastOnce())->method('resolvePrice')->willReturn($price); + + $this->assertEquals($expectedValue, $this->resolver->resolvePrice($product)); + } + + /** + * @return array + */ + public function testResolvePriceDataProvider() + { + return [ + 'price of zero' => [0.00], + 'price of five' => [5], + ]; + } +} diff --git a/app/code/Magento/ConfigurableProduct/i18n/en_US.csv b/app/code/Magento/ConfigurableProduct/i18n/en_US.csv index ec07c74c8868b7ff8906f3cdf68327e8e26eab7b..59ae9a201670772f1fe3220bbb27adb99e1d3876 100644 --- a/app/code/Magento/ConfigurableProduct/i18n/en_US.csv +++ b/app/code/Magento/ConfigurableProduct/i18n/en_US.csv @@ -30,7 +30,7 @@ Summary,Summary "You need to choose options for your item.","You need to choose options for your item." "Some product variations fields are not valid.","Some product variations fields are not valid." "Configuration must have specified attributes","Configuration must have specified attributes" -"Configurable product ""%1"" do not have sub-products","Configurable product ""%1"" do not have sub-products" +"Configurable product ""%1"" does not have sub-products","Configurable product ""%1"" does not have sub-products" "This group contains attributes used in configurable products. Please move these attributes to another group and try again.","This group contains attributes used in configurable products. Please move these attributes to another group and try again." "This attribute is used in configurable products. You cannot remove it from the attribute set.","This attribute is used in configurable products. You cannot remove it from the attribute set." "Associated Products","Associated Products" diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index 5fafc70d1a74118863273a27dd154a733d33991c..d38e2760f1dc7fc6d31772481ab9cc64b757413e 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -23,7 +23,7 @@ define([ state: {}, priceFormat: {}, optionTemplate: '<%- data.label %>' + - '<% if (data.finalPrice.value) { %>' + + "<% if (typeof data.finalPrice.value !== 'undefined') { %>" + ' <%- data.finalPrice.formatted %>' + '<% } %>', mediaGallerySelector: '[data-gallery-role=gallery-placeholder]', diff --git a/app/code/Magento/Downloadable/view/adminhtml/web/js/components/is-downloadable-handler.js b/app/code/Magento/Downloadable/view/adminhtml/web/js/components/is-downloadable-handler.js index 5e619b76c7ecd8ba22fd1e8ff3f25786ac93d33e..8fc6508cd877d752eb94640abeebbc895ec1a716 100644 --- a/app/code/Magento/Downloadable/view/adminhtml/web/js/components/is-downloadable-handler.js +++ b/app/code/Magento/Downloadable/view/adminhtml/web/js/components/is-downloadable-handler.js @@ -22,7 +22,7 @@ define([ * Change visibility for samplesFieldset & linksFieldset based on current statuses of checkbox. */ changeVisibility: function () { - if (this.samplesFieldset && this.linksFieldset) { + if (this.samplesFieldset() && this.linksFieldset()) { if (this.checked() && !this.disabled()) { this.samplesFieldset().visible(true); this.linksFieldset().visible(true); diff --git a/app/code/Magento/Indexer/Model/Processor/InvalidateCache.php b/app/code/Magento/Indexer/Model/Processor/CleanCache.php similarity index 64% rename from app/code/Magento/Indexer/Model/Processor/InvalidateCache.php rename to app/code/Magento/Indexer/Model/Processor/CleanCache.php index d4cc663612845011019d7832736b5ca0041dd53b..b5dec17899819a074ecf5f6ae1dba30f12c44ebc 100644 --- a/app/code/Magento/Indexer/Model/Processor/InvalidateCache.php +++ b/app/code/Magento/Indexer/Model/Processor/CleanCache.php @@ -3,13 +3,9 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Indexer\Model\Processor; -/** - * Class InvalidateCache - */ -class InvalidateCache +class CleanCache { /** * @var \Magento\Framework\Indexer\CacheContext @@ -21,24 +17,16 @@ class InvalidateCache */ protected $eventManager; - /** - * @var \Magento\Framework\Module\Manager - */ - protected $moduleManager; - /** * @param \Magento\Framework\Indexer\CacheContext $context * @param \Magento\Framework\Event\Manager $eventManager - * @param \Magento\Framework\Module\Manager $moduleManager */ public function __construct( \Magento\Framework\Indexer\CacheContext $context, - \Magento\Framework\Event\Manager $eventManager, - \Magento\Framework\Module\Manager $moduleManager + \Magento\Framework\Event\Manager $eventManager ) { $this->context = $context; $this->eventManager = $eventManager; - $this->moduleManager = $moduleManager; } /** @@ -50,8 +38,18 @@ class InvalidateCache */ public function afterUpdateMview(\Magento\Indexer\Model\Processor $subject) { - if ($this->moduleManager->isEnabled('Magento_PageCache')) { - $this->eventManager->dispatch('clean_cache_after_reindex', ['object' => $this->context]); - } + $this->eventManager->dispatch('clean_cache_after_reindex', ['object' => $this->context]); + } + + /** + * Clear cache after reindex all + * + * @param \Magento\Indexer\Model\Processor $subject + * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function afterReindexAllInvalid(\Magento\Indexer\Model\Processor $subject) + { + $this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->context]); } } diff --git a/app/code/Magento/Indexer/Test/Unit/Model/Processor/InvalidateCacheTest.php b/app/code/Magento/Indexer/Test/Unit/Model/Processor/CleanCacheTest.php similarity index 54% rename from app/code/Magento/Indexer/Test/Unit/Model/Processor/InvalidateCacheTest.php rename to app/code/Magento/Indexer/Test/Unit/Model/Processor/CleanCacheTest.php index 0a9ad31ba273a50773a8c6189ebd6a441aa2a610..511eb798e55289b8d94e576ffe326a929ddf63b3 100644 --- a/app/code/Magento/Indexer/Test/Unit/Model/Processor/InvalidateCacheTest.php +++ b/app/code/Magento/Indexer/Test/Unit/Model/Processor/CleanCacheTest.php @@ -3,10 +3,9 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Indexer\Test\Unit\Model\Processor; -class InvalidateCacheTest extends \PHPUnit_Framework_TestCase +class CleanCacheTest extends \PHPUnit_Framework_TestCase { /** * Tested plugin @@ -36,13 +35,6 @@ class InvalidateCacheTest extends \PHPUnit_Framework_TestCase */ protected $eventManagerMock; - /** - * Module manager mock - * - * @var \Magento\Framework\Module\Manager|\PHPUnit_Framework_MockObject_MockObject - */ - protected $moduleManager; - /** * Set up */ @@ -51,25 +43,19 @@ class InvalidateCacheTest extends \PHPUnit_Framework_TestCase $this->subjectMock = $this->getMock('Magento\Indexer\Model\Processor', [], [], '', false); $this->contextMock = $this->getMock('Magento\Framework\Indexer\CacheContext', [], [], '', false); $this->eventManagerMock = $this->getMock('Magento\Framework\Event\Manager', [], [], '', false); - $this->moduleManager = $this->getMock('Magento\Framework\Module\Manager', [], [], '', false); - $this->plugin = new \Magento\Indexer\Model\Processor\InvalidateCache( + $this->plugin = new \Magento\Indexer\Model\Processor\CleanCache( $this->contextMock, - $this->eventManagerMock, - $this->moduleManager + $this->eventManagerMock ); } /** - * Test afterUpdateMview with enabled PageCache module + * Test afterUpdateMview * * @return void */ - public function testAfterUpdateMviewPageCacheEnabled() + public function testAfterUpdateMview() { - $this->moduleManager->expects($this->once()) - ->method('isEnabled') - ->with($this->equalTo('Magento_PageCache')) - ->will($this->returnValue(true)); $this->eventManagerMock->expects($this->once()) ->method('dispatch') ->with( @@ -78,20 +64,4 @@ class InvalidateCacheTest extends \PHPUnit_Framework_TestCase ); $this->plugin->afterUpdateMview($this->subjectMock); } - - /** - * Test afterUpdateMview with disabled PageCache module - * - * @return void - */ - public function testAfterUpdateMviewPageCacheDisabled() - { - $this->moduleManager->expects($this->once()) - ->method('isEnabled') - ->with($this->equalTo('Magento_PageCache')) - ->will($this->returnValue(false)); - $this->eventManagerMock->expects($this->never()) - ->method('dispatch'); - $this->plugin->afterUpdateMview($this->subjectMock); - } } diff --git a/app/code/Magento/Indexer/composer.json b/app/code/Magento/Indexer/composer.json index e70c92907e7aee19d7de54688b4696ae89df57c4..2c374d77111510c9d14a5ed3f846e09be67d3891 100644 --- a/app/code/Magento/Indexer/composer.json +++ b/app/code/Magento/Indexer/composer.json @@ -4,7 +4,6 @@ "require": { "php": "~5.5.22|~5.6.0|~7.0.0", "magento/module-backend": "100.0.*", - "magento/module-page-cache": "100.0.*", "magento/framework": "100.0.*" }, "type": "magento2-module", diff --git a/app/code/Magento/Indexer/etc/di.xml b/app/code/Magento/Indexer/etc/di.xml index 87a99325e4ae60d9bee2056a988064848ff4a322..019dad475a5531e87f14c8e4f52d8456bb0a49b7 100644 --- a/app/code/Magento/Indexer/etc/di.xml +++ b/app/code/Magento/Indexer/etc/di.xml @@ -39,8 +39,8 @@ </arguments> </type> <type name="Magento\Indexer\Model\Processor"> - <plugin name="page-cache-indexer-reindex-invalidate" - type="Magento\Indexer\Model\Processor\InvalidateCache" sortOrder="10"/> + <plugin name="page-cache-indexer-reindex-clean-cache" + type="Magento\Indexer\Model\Processor\CleanCache" sortOrder="10"/> </type> <type name="Magento\Framework\Console\CommandList"> diff --git a/app/code/Magento/PageCache/Observer/InvalidateCacheIfChanged.php b/app/code/Magento/PageCache/Observer/InvalidateCacheIfChanged.php deleted file mode 100644 index c8f2d0e23f20d3da3ff7aa291ca5067e11e1133e..0000000000000000000000000000000000000000 --- a/app/code/Magento/PageCache/Observer/InvalidateCacheIfChanged.php +++ /dev/null @@ -1,56 +0,0 @@ -<?php -/** - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\PageCache\Observer; - -use Magento\Framework\Event\ObserverInterface; - -/** - * An observer to invalidate full page cache when the content given is changed - */ -class InvalidateCacheIfChanged implements ObserverInterface -{ - /** - * @var \Magento\Framework\App\Cache\TypeListInterface - */ - protected $typeList; - - /** - * Application config object - * - * @var \Magento\PageCache\Model\Config - */ - protected $config; - - /** - * @param \Magento\PageCache\Model\Config $config - * @param \Magento\Framework\App\Cache\TypeListInterface $typeList - */ - public function __construct( - \Magento\PageCache\Model\Config $config, - \Magento\Framework\App\Cache\TypeListInterface $typeList - ) { - $this->config = $config; - $this->typeList = $typeList; - } - - /** - * Invalidate full page cache if content is changed - * - * @param \Magento\Framework\Event\Observer $observer - * @return void - */ - public function execute(\Magento\Framework\Event\Observer $observer) - { - if ($this->config->isEnabled()) { - $object = $observer->getEvent()->getObject(); - if ($object instanceof \Magento\Framework\DataObject\IdentityInterface) { - if ($object->getIdentities()) { - $this->typeList->invalidate('full_page'); - } - } - } - } -} diff --git a/app/code/Magento/PageCache/Test/Unit/Observer/InvalidateCacheIfChangedTest.php b/app/code/Magento/PageCache/Test/Unit/Observer/InvalidateCacheIfChangedTest.php deleted file mode 100644 index 9e6af22857295967436f6ce7d944b8aeb6d42040..0000000000000000000000000000000000000000 --- a/app/code/Magento/PageCache/Test/Unit/Observer/InvalidateCacheIfChangedTest.php +++ /dev/null @@ -1,91 +0,0 @@ -<?php -/** - * - * Copyright © 2016 Magento. All rights reserved. - * See COPYING.txt for license details. - */ -namespace Magento\PageCache\Test\Unit\Observer; - -class InvalidateCacheIfChangedTest extends \PHPUnit_Framework_TestCase -{ - /** @var \Magento\PageCache\Observer\InvalidateCacheIfChanged */ - protected $model; - - /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\PageCache\Model\Config */ - protected $configMock; - - /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\Cache\TypeListInterface */ - protected $typeListMock; - - /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Event\Observer */ - protected $observerMock; - - /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\DataObject\IdentityInterface */ - protected $objectMock; - - /** - * Set up all mocks and data for test - */ - protected function setUp() - { - $this->configMock = $this->getMock( - 'Magento\PageCache\Model\Config', - ['getType', 'isEnabled'], - [], - '', - false - ); - $this->typeListMock = $this->getMock('Magento\Framework\App\Cache\TypeList', [], [], '', false); - - $this->model = new \Magento\PageCache\Observer\InvalidateCacheIfChanged( - $this->configMock, - $this->typeListMock - ); - - $this->observerMock = $this->getMock('Magento\Framework\Event\Observer', [], [], '', false); - $eventMock = $this->getMock('Magento\Framework\Event', ['getObject'], [], '', false); - $this->objectMock = $this->getMockForAbstractClass( - 'Magento\Framework\DataObject\IdentityInterface', - [], - '', - false - ); - $eventMock->expects($this->any())->method('getObject')->willReturn($this->objectMock); - $this->observerMock->expects($this->any())->method('getEvent')->willReturn($eventMock); - } - - /** - * @dataProvider invalidateCacheDataProvider - * @param bool $cacheState - */ - public function testExecuteChanged($cacheState) - { - $this->configMock->expects($this->once())->method('isEnabled')->will($this->returnValue($cacheState)); - - if ($cacheState) { - $this->typeListMock->expects($this->once())->method('invalidate')->with($this->equalTo('full_page')); - $this->objectMock->expects($this->once())->method('getIdentities')->will($this->returnValue(['tag_1'])); - } - $this->model->execute($this->observerMock); - } - - /** - * @dataProvider invalidateCacheDataProvider - * @param bool $cacheState - */ - public function testExecuteNoChanged($cacheState) - { - $this->configMock->expects($this->once())->method('isEnabled')->will($this->returnValue($cacheState)); - $this->typeListMock->expects($this->never())->method('invalidate'); - - if ($cacheState) { - $this->objectMock->expects($this->once())->method('getIdentities')->will($this->returnValue([])); - } - $this->model->execute($this->observerMock); - } - - public function invalidateCacheDataProvider() - { - return [[true], [false]]; - } -} diff --git a/app/code/Magento/PageCache/etc/events.xml b/app/code/Magento/PageCache/etc/events.xml index 617709c400a1500c59bafa3f0b11ded2ddbcdf06..7ac67a931c7ac8bbbe3b5e397a7ade7b3a039633 100644 --- a/app/code/Magento/PageCache/etc/events.xml +++ b/app/code/Magento/PageCache/etc/events.xml @@ -13,7 +13,7 @@ <observer name="invalidate_builtin" instance="Magento\PageCache\Observer\FlushCacheByTags" /> </event> <event name="clean_cache_after_reindex"> - <observer name="reindex_cache_flush" instance="Magento\PageCache\Observer\InvalidateCacheIfChanged" /> + <observer name="reindex_cache_flush" instance="Magento\PageCache\Observer\FlushCacheByTags" /> </event> <event name="adminhtml_cache_flush_system"> <observer name="flush_system_pagecache" instance="Magento\PageCache\Observer\FlushAllCache" /> diff --git a/app/code/Magento/Quote/Model/Quote/Address/Total.php b/app/code/Magento/Quote/Model/Quote/Address/Total.php index e841d9b7d76150499cfcc15ab41668468fbb4458..aeaa71fb8daad7c4fa8d832e66cad83dadb45f34 100644 --- a/app/code/Magento/Quote/Model/Quote/Address/Total.php +++ b/app/code/Magento/Quote/Model/Quote/Address/Total.php @@ -114,6 +114,7 @@ class Total extends \Magento\Framework\DataObject } //@codeCoverageIgnoreStart + /** * Get all total amount values * @@ -133,4 +134,33 @@ class Total extends \Magento\Framework\DataObject { return $this->baseTotalAmounts; } + + //@codeCoverageIgnoreEnd + + /** + * Set the full info, which is used to capture tax related information. + * If a string is used, it is assumed to be serialized. + * + * @param array|string $info + * @return $this + */ + public function setFullInfo($info) + { + $this->setData('full_info', $info); + return $this; + } + + /** + * Returns the full info, which is used to capture tax related information. + * + * @return array + */ + public function getFullInfo() + { + $fullInfo = $this->getData('full_info'); + if (is_string($fullInfo)) { + $fullInfo = unserialize($fullInfo); + } + return $fullInfo; + } } diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/TotalTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/TotalTest.php index 00f653922db5c4c89e173a32fd9ce29bd34b5ece..efe6a81ce9242f510561f54cd6b484a336b37dbf 100644 --- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/TotalTest.php +++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Address/TotalTest.php @@ -167,4 +167,48 @@ class TotalTest extends \PHPUnit_Framework_TestCase { $this->assertEquals(0, $this->model->getBaseTotalAmount('great')); } + + /** + * Verify handling of serialized, non-serialized input into and out of getFullInfo() + * + * @param $input + * @param $expected + * @dataProvider getFullInfoDataProvider + */ + public function testGetFullInfo($input, $expected) + { + $this->model->setFullInfo($input); + $this->assertEquals($expected, $this->model->getFullInfo()); + } + + /** + * @return array + */ + public function getFullInfoDataProvider() + { + $myArray = ['team' => 'kiwis']; + $serializedInput = serialize($myArray); + + return [ + 'simple array' => [ + $myArray, + $myArray, + ], + + 'serialized array' => [ + $serializedInput, + $myArray, + ], + + 'null input/output' => [ + null, + null, + ], + + 'float input' => [ + 1.23, + 1.23, + ], + ]; + } } diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals/tax.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals/tax.phtml index ad0e314930e095aa0cdeca00280924c35b525342..acf10ccbaa08726485065b67733c2cd52263c477 100755 --- a/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals/tax.phtml +++ b/app/code/Magento/Sales/view/adminhtml/templates/order/create/totals/tax.phtml @@ -11,11 +11,11 @@ $taxAmount = $block->getTotal()->getValue(); <?php if (($taxAmount == 0 && $this->helper('Magento\Tax\Helper\Data')->displayZeroTax()) || ($taxAmount > 0)): ?> <?php global $taxIter; $taxIter++; ?> <?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary()): ?> -<?php $isTop = 1; ?> - <?php foreach ($block->getTotal()->getFullInfo() as $info): ?> + <?php $isTop = 1; ?> + <?php foreach ($block->getTotal()->getFullInfo() as $info): ?> <?php if (isset($info['hidden']) && $info['hidden']) { - continue; -} ?> + continue; + } ?> <?php $percent = $info['percent']; ?> <?php $amount = $info['amount']; ?> <?php $rates = $info['rates']; ?> @@ -39,7 +39,7 @@ $taxAmount = $block->getTotal()->getValue(); <?php $isFirst = 0; ?> <?php $isTop = 0; ?> <?php endforeach; ?> - <?php endforeach; ?> + <?php endforeach; ?> <?php endif;?> <?php $class = "{$block->getTotal()->getCode()} " . ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() ? 'summary-total' : ''); ?> <tr<?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary()): ?> onclick="expandDetails(this, '.summary-details-<?php /* @escapeNotVerified */ echo $taxIter;?>')"<?php endif; ?> class="<?php /* @escapeNotVerified */ echo $class;?> row-totals"> diff --git a/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php b/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php index 93c628c9a2e2603e3deecadc37a00eafcd419e3f..09f925f4f6ecdbf6d6c857e3529605c5cf74250a 100644 --- a/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php +++ b/app/code/Magento/SalesRule/Model/Rule/Metadata/ValueProvider.php @@ -78,7 +78,7 @@ class ValueProvider $applyOptions = [ ['label' => __('Percent of product price discount'), 'value' => Rule::BY_PERCENT_ACTION], ['label' => __('Fixed amount discount'), 'value' => Rule::BY_FIXED_ACTION], - ['label' => __('Fixed amount discount for whole cart'), 'value' => Rule::BY_PERCENT_ACTION], + ['label' => __('Fixed amount discount for whole cart'), 'value' => Rule::CART_FIXED_ACTION], ['label' => __('Buy X get Y free (discount amount is Y)'), 'value' => Rule::BUY_X_GET_Y_ACTION] ]; diff --git a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/_files/MetaData.php b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/_files/MetaData.php index d93c504af9e71c7490c304f6b5fd43e87c335daa..ec3d3c86d7288b7292fe630478812669286bbc8e 100644 --- a/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/_files/MetaData.php +++ b/app/code/Magento/SalesRule/Test/Unit/Model/Rule/Metadata/_files/MetaData.php @@ -1,4 +1,9 @@ <?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ + return [ 'rule_information' => [ @@ -101,7 +106,7 @@ return [ ], [ 'label' => __('Fixed amount discount for whole cart'), - 'value' => 'by_percent', + 'value' => 'cart_fixed', ], [ 'label' => __( diff --git a/app/code/Magento/Security/Model/ResourceModel/AdminSessionInfo/Collection.php b/app/code/Magento/Security/Model/ResourceModel/AdminSessionInfo/Collection.php index f85e2d308d7d1205110833074e33a864267745a9..5c6537030396357851e4b73984e5302119d64bde 100644 --- a/app/code/Magento/Security/Model/ResourceModel/AdminSessionInfo/Collection.php +++ b/app/code/Magento/Security/Model/ResourceModel/AdminSessionInfo/Collection.php @@ -16,7 +16,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab protected $_idFieldName = 'id'; /** - * @var \Magento\Framework\Stdlib\DateTime + * @var \Magento\Framework\Stdlib\DateTime\DateTime */ protected $dateTime; @@ -25,7 +25,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Framework\Stdlib\DateTime $dateTime + * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource */ @@ -34,7 +34,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Framework\Stdlib\DateTime $dateTime, + \Magento\Framework\Stdlib\DateTime\DateTime $dateTime, \Magento\Framework\DB\Adapter\AdapterInterface $connection = null, \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null ) { @@ -108,9 +108,11 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab */ public function filterExpiredSessions($sessionLifeTime) { + $connection = $this->getConnection(); + $gmtTimestamp = $this->dateTime->gmtTimestamp(); $this->addFieldToFilter( 'updated_at', - ['gt' => $this->dateTime->formatDate($this->dateTime->gmDate('U', null) - $sessionLifeTime)] + ['gt' => $connection->formatDate($gmtTimestamp - $sessionLifeTime)] ); return $this; } diff --git a/app/code/Magento/Security/Model/ResourceModel/PasswordResetRequestEvent/Collection.php b/app/code/Magento/Security/Model/ResourceModel/PasswordResetRequestEvent/Collection.php index f1c1a867717d1d778570708a05be21ba3d40cc3c..5b455f8c686e3a6e76e065a03ee34c45a44160ce 100644 --- a/app/code/Magento/Security/Model/ResourceModel/PasswordResetRequestEvent/Collection.php +++ b/app/code/Magento/Security/Model/ResourceModel/PasswordResetRequestEvent/Collection.php @@ -16,7 +16,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab protected $_idFieldName = 'id'; /** - * @var \Magento\Framework\Stdlib\DateTime + * @var \Magento\Framework\Stdlib\DateTime\DateTime */ protected $dateTime; @@ -25,7 +25,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Framework\Stdlib\DateTime $dateTime + * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection * @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource */ @@ -34,7 +34,7 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab \Psr\Log\LoggerInterface $logger, \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy, \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Framework\Stdlib\DateTime $dateTime, + \Magento\Framework\Stdlib\DateTime\DateTime $dateTime, \Magento\Framework\DB\Adapter\AdapterInterface $connection = null, \Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null ) { @@ -102,9 +102,11 @@ class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\Ab */ public function filterByLifetime($lifetime) { + $connection = $this->getConnection(); + $gmtTimestamp = $this->dateTime->gmtTimestamp(); $this->addFieldToFilter( 'created_at', - ['gt' => $this->dateTime->formatDate($this->dateTime->gmDate('U', null) - $lifetime)] + ['gt' => $connection->formatDate($gmtTimestamp - $lifetime)] ); return $this; diff --git a/app/code/Magento/Security/Setup/InstallSchema.php b/app/code/Magento/Security/Setup/InstallSchema.php index 02143411a5d50c0e78311b6dfe42578a25cf7a93..db090066d9cbd054989d6b2c87dfffc74e94e622 100644 --- a/app/code/Magento/Security/Setup/InstallSchema.php +++ b/app/code/Magento/Security/Setup/InstallSchema.php @@ -88,9 +88,9 @@ class InstallSchema implements InstallSchemaInterface ) ->addColumn( 'ip', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - null, - ['unsigned' => true, 'nullable' => false], + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 15, + ['nullable' => false], 'Remote user IP' ) ->addIndex( @@ -151,9 +151,9 @@ class InstallSchema implements InstallSchemaInterface ) ->addColumn( 'ip', - \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER, - null, - ['unsigned' => true, 'nullable' => false], + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 15, + ['nullable' => false], 'Remote user IP' ) ->addIndex( diff --git a/app/code/Magento/Security/Setup/UpgradeSchema.php b/app/code/Magento/Security/Setup/UpgradeSchema.php new file mode 100644 index 0000000000000000000000000000000000000000..f17f0f496024832f0abb52de893a20adf9e2978c --- /dev/null +++ b/app/code/Magento/Security/Setup/UpgradeSchema.php @@ -0,0 +1,52 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Security\Setup; + +use Magento\Framework\Setup\UpgradeSchemaInterface; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\SchemaSetupInterface; + +/** + * Upgrade the Catalog module DB scheme + */ +class UpgradeSchema implements UpgradeSchemaInterface +{ + /** + * {@inheritdoc} + */ + public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context) + { + $setup->startSetup(); + + if (version_compare($context->getVersion(), '2.0.1', '<')) { + $setup->getConnection()->changeColumn( + $setup->getTable(\Magento\Security\Setup\InstallSchema::ADMIN_SESSIONS_DB_TABLE_NAME), + 'ip', + 'ip', + [ + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 'length' => 15, + 'nullable' => false, + 'comment' => 'Remote user IP' + ] + ); + + $setup->getConnection()->changeColumn( + $setup->getTable(\Magento\Security\Setup\InstallSchema::PASSWORD_RESET_REQUEST_EVENT_DB_TABLE_NAME), + 'ip', + 'ip', + [ + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 'length' => 15, + 'nullable' => false, + 'comment' => 'Remote user IP' + ] + ); + } + + $setup->endSetup(); + } +} diff --git a/app/code/Magento/Security/Test/Unit/Model/ResourceModel/AdminSessionInfo/CollectionTest.php b/app/code/Magento/Security/Test/Unit/Model/ResourceModel/AdminSessionInfo/CollectionTest.php index 633ab04dd03b5802440b9d0342a415784df9c9ba..c5229e573d08e6446bae09e647b85fc69f2d2134 100644 --- a/app/code/Magento/Security/Test/Unit/Model/ResourceModel/AdminSessionInfo/CollectionTest.php +++ b/app/code/Magento/Security/Test/Unit/Model/ResourceModel/AdminSessionInfo/CollectionTest.php @@ -6,8 +6,6 @@ namespace Magento\Security\Test\Unit\Model\ResourceModel\AdminSessionInfo; -use Magento\Security\Model\ConfigInterface; - /** * Test class for \Magento\Security\Model\ResourceModel\AdminSessionInfo\Collection testing */ @@ -16,7 +14,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Security\Model\ResourceModel\AdminSessionInfo\Collection */ protected $collectionMock; - /** @var \Magento\Framework\Stdlib\DateTime */ + /** @var \Magento\Framework\Stdlib\DateTime\DateTime */ protected $dateTimeMock; /** @var \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ @@ -29,7 +27,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase protected function setUp() { $this->dateTimeMock = $this->getMock( - '\Magento\Framework\Stdlib\DateTime', + \Magento\Framework\Stdlib\DateTime\DateTime::class, [], [], '', @@ -136,14 +134,14 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $timestamp = time(); $this->dateTimeMock->expects($this->once()) - ->method('gmDate') + ->method('gmtTimestamp') ->willReturn($timestamp); $this->collectionMock->expects($this->once()) ->method('addFieldToFilter') ->with( 'updated_at', - ['gt' => $this->dateTimeMock->formatDate($timestamp - $sessionLifeTime)] + ['gt' => $this->collectionMock->getConnection()->formatDate($timestamp - $sessionLifeTime)] ) ->willReturnSelf(); diff --git a/app/code/Magento/Security/Test/Unit/Model/ResourceModel/PasswordResetRequestEvent/CollectionTest.php b/app/code/Magento/Security/Test/Unit/Model/ResourceModel/PasswordResetRequestEvent/CollectionTest.php index 4492326851582eef1b340f1bef52026a09a8ee35..6f9664031bbf70bb1033be719b7ad5322a6914ba 100644 --- a/app/code/Magento/Security/Test/Unit/Model/ResourceModel/PasswordResetRequestEvent/CollectionTest.php +++ b/app/code/Magento/Security/Test/Unit/Model/ResourceModel/PasswordResetRequestEvent/CollectionTest.php @@ -6,8 +6,6 @@ namespace Magento\Security\Test\Unit\Model\ResourceModel\PasswordResetRequestEvent; -use Magento\Security\Model\ConfigInterface; - /** * Test class for \Magento\Security\Model\ResourceModel\AdminSessionInfo\Collection testing */ @@ -16,7 +14,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Security\Model\ResourceModel\PasswordResetRequestEvent\Collection */ protected $collectionMock; - /** @var \Magento\Framework\Stdlib\DateTime */ + /** @var \Magento\Framework\Stdlib\DateTime\DateTime */ protected $dateTimeMock; /** @var \Magento\Framework\DB\Select */ @@ -61,7 +59,7 @@ class CollectionTest extends \PHPUnit_Framework_TestCase ); $this->dateTimeMock = $this->getMock( - '\Magento\Framework\Stdlib\DateTime', + '\Magento\Framework\Stdlib\DateTime\DateTime', [], [], '', @@ -175,14 +173,14 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $timestamp = time(); $this->dateTimeMock->expects($this->once()) - ->method('gmDate') + ->method('gmtTimestamp') ->willReturn($timestamp); $this->collectionMock->expects($this->once()) ->method('addFieldToFilter') ->with( 'created_at', - ['gt' => $this->dateTimeMock->formatDate($timestamp - $lifetime)] + ['gt' => $this->collectionMock->getConnection()->formatDate($timestamp - $lifetime)] ) ->willReturnSelf(); diff --git a/app/code/Magento/Security/etc/module.xml b/app/code/Magento/Security/etc/module.xml index d0bdba4a6f79cbf0bfe0cff841ef91d0c3faaa0a..85ad00b5c0729e90016f938afeef49e9ddf32f44 100644 --- a/app/code/Magento/Security/etc/module.xml +++ b/app/code/Magento/Security/etc/module.xml @@ -6,7 +6,7 @@ */ --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> - <module name="Magento_Security" setup_version="2.0.0"> + <module name="Magento_Security" setup_version="2.0.1"> <sequence> <module name="Magento_Backend"/> <module name="Magento_Store"/> diff --git a/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml b/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml index 92d0b199ae7071b6f482aa9d153a68362d6e1f0c..4cdfbac691e6aadf18530ac41203b7790788bc39 100644 --- a/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml +++ b/app/code/Magento/Tax/view/frontend/templates/checkout/tax.phtml @@ -39,10 +39,10 @@ <?php if ($this->helper('Magento\Tax\Helper\Data')->displayFullSummary() && $_value != 0): ?> <?php $isTop = 1; ?> - <?php foreach (unserialize($block->getTotal()->getFullInfo()) as $info): ?> + <?php foreach ($block->getTotal()->getFullInfo() as $info): ?> <?php if (isset($info['hidden']) && $info['hidden']) { - continue; -} ?> + continue; + } ?> <?php $percent = $info['percent']; ?> <?php $amount = $info['amount']; ?> <?php $rates = $info['rates']; ?> diff --git a/app/code/Magento/Ui/view/base/templates/stepswizard.phtml b/app/code/Magento/Ui/view/base/templates/stepswizard.phtml index b6f74dda267eb9dcbf30932a6659989a934b8046..82cc34b42b12088f781629fac0a8a53948437d0e 100644 --- a/app/code/Magento/Ui/view/base/templates/stepswizard.phtml +++ b/app/code/Magento/Ui/view/base/templates/stepswizard.phtml @@ -64,7 +64,7 @@ "component": "Magento_Ui/js/lib/step-wizard", "initData": <?= /* @escapeNotVerified */ $this->helper("Magento\Framework\Json\Helper\Data")->jsonEncode($block->getInitData()) ?>, "stepsNames": <?= /* @escapeNotVerified */ $this->helper("Magento\Framework\Json\Helper\Data")->jsonEncode($block->getStepComponents()) ?>, - "modalClass": "<?= /* @noEscape */ $block->getData('config/modal')?>" + "modalClass": "<?= /* @noEscape */ $block->getData('config/dataScope')?>" } } } diff --git a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php index efcfda9cb67bbc8c76d3775d4ba8f3fe4ac2882d..d91faf2da5dd699989cc87cd7794b1a395516598 100644 --- a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php +++ b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php @@ -6,6 +6,8 @@ */ namespace Magento\User\Controller\Adminhtml\Auth; +use Magento\Security\Model\SecurityManager; + class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth { /** @@ -31,12 +33,15 @@ class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth * Forgot administrator password action * * @return void + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function execute() { $email = (string)$this->getRequest()->getParam('email'); $params = $this->getRequest()->getParams(); + /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */ + $resultRedirect = $this->resultRedirectFactory->create(); if (!empty($email) && !empty($params)) { // Validate received data to be an email address if (\Zend_Validate::is($email, 'EmailAddress')) { @@ -47,7 +52,6 @@ class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth ); } catch (\Magento\Framework\Exception\SecurityViolationException $exception) { $this->messageManager->addErrorMessage($exception->getMessage()); - $resultRedirect = $this->resultRedirectFactory->create(); return $resultRedirect->setPath('admin'); } $collection = $this->_objectManager->get('Magento\User\Model\ResourceModel\User\Collection'); @@ -55,20 +59,28 @@ class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth $collection->addFieldToFilter('email', $email); $collection->load(false); - if ($collection->getSize() > 0) { - foreach ($collection as $item) { - /** @var \Magento\User\Model\User $user */ - $user = $this->_userFactory->create()->load($item->getId()); - if ($user->getId()) { - $newPassResetToken = $this->_objectManager->get( - 'Magento\User\Helper\Data' - )->generateResetPasswordLinkToken(); - $user->changeResetPasswordLinkToken($newPassResetToken); - $user->save(); - $user->sendPasswordResetConfirmationEmail(); + try { + if ($collection->getSize() > 0) { + foreach ($collection as $item) { + /** @var \Magento\User\Model\User $user */ + $user = $this->_userFactory->create()->load($item->getId()); + if ($user->getId()) { + $newPassResetToken = $this->_objectManager->get( + 'Magento\User\Helper\Data' + )->generateResetPasswordLinkToken(); + $user->changeResetPasswordLinkToken($newPassResetToken); + $user->save(); + $user->sendPasswordResetConfirmationEmail(); + } + break; } - break; } + } catch (\Exception $exception) { + $this->messageManager->addExceptionMessage( + $exception, + __('We\'re unable to send the password reset email.') + ); + return $resultRedirect->setPath('admin'); } // @codingStandardsIgnoreStart $this->messageManager->addSuccess(__('We\'ll email you a link to reset your password.')); diff --git a/app/code/Magento/Widget/Model/Widget.php b/app/code/Magento/Widget/Model/Widget.php index fbf2485d37542a489d3a8e6b8bf447a6d94e81c5..2235df9aff0772f05eb7ea71d0ebf60010893570 100644 --- a/app/code/Magento/Widget/Model/Widget.php +++ b/app/code/Magento/Widget/Model/Widget.php @@ -309,7 +309,7 @@ class Widget } elseif (trim($value) == '') { $widget = $this->getConfigAsObject($type); $parameters = $widget->getParameters(); - if (is_object($parameters[$name])) { + if (isset($parameters[$name]) && is_object($parameters[$name])) { $value = $parameters[$name]->getValue(); } } diff --git a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php index 44eedd2c9fc40de783f778ccfa7568531db64907..90de5d2832b53cbaef102f2dd818032bba614aae 100644 --- a/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php +++ b/lib/internal/Magento/Framework/Code/Minifier/Adapter/Css/CSSmin.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Framework\Code\Minifier\Adapter\Css; use CSSmin as CssMinLibrary; @@ -26,10 +25,24 @@ class CSSmin implements AdapterInterface /** * @param CssMinLibrary $cssMinifier + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function __construct(CssMinLibrary $cssMinifier) { - $this->cssMinifier = $cssMinifier; + // TODO: set $cssMinifier in constructor once MAGETWO-51176 is resolved. + } + + /** + * Get CSS Minifier + * + * @return \CSSMin + */ + private function getCssMin() + { + if (!($this->cssMinifier instanceof \CSSMin)) { + $this->cssMinifier = new \CSSmin(false); + } + return $this->cssMinifier; } /** @@ -42,7 +55,7 @@ class CSSmin implements AdapterInterface { $pcreRecursionLimit = ini_get('pcre.recursion_limit'); ini_set('pcre.recursion_limit', self::PCRE_RECURSION_LIMIT); - $result = $this->cssMinifier->run($content); + $result = $this->getCssMin()->run($content); ini_set('pcre.recursion_limit', $pcreRecursionLimit); return $result; } diff --git a/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Css/CssMinTest.php b/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Css/CssMinTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f6cc3c489206be68d5809017b01e6b727fa8462a --- /dev/null +++ b/lib/internal/Magento/Framework/Code/Test/Unit/Minifier/Adapter/Css/CssMinTest.php @@ -0,0 +1,24 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Code\Test\Unit\Minifier\Adapter\Css; + +class CssMinTest extends \PHPUnit_Framework_TestCase +{ + public function testMinify() + { + $cssMinMock = $this->getMockBuilder(\CSSmin::class) + ->disableOriginalConstructor() + ->getMock(); + $cssMinAdapter = new \Magento\Framework\Code\Minifier\Adapter\Css\CSSmin($cssMinMock); + $property = new \ReflectionProperty(\Magento\Framework\Code\Minifier\Adapter\Css\CSSmin::class, 'cssMinifier'); + $property->setAccessible(true); + $property->setValue($cssMinAdapter, $cssMinMock); + + $expectedResult = 'minified content'; + $cssMinMock->expects($this->once())->method('run')->willReturn($expectedResult); + $this->assertEquals($expectedResult, $cssMinAdapter->minify('not minified')); + } +} diff --git a/lib/internal/Magento/Framework/Console/Cli.php b/lib/internal/Magento/Framework/Console/Cli.php index 6e9110de1ab75200dc859f39018b7010deeb8423..9742acbbd237cdce6f379f2fbb218526d3f60f62 100644 --- a/lib/internal/Magento/Framework/Console/Cli.php +++ b/lib/internal/Magento/Framework/Console/Cli.php @@ -3,22 +3,23 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Framework\Console; -use Magento\Framework\Filesystem\Driver\File; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\ConsoleOutput; +use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Application as SymfonyApplication; use Magento\Framework\App\Bootstrap; +use Magento\Framework\Filesystem\Driver\File; use Magento\Framework\Shell\ComplexParameter; -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; -use Magento\Framework\Setup\FilePermissions; +use Magento\Setup\Console\CompilerPreparation; /** - * Magento2 CLI Application. This is the hood for all command line tools supported by Magento. + * Magento 2 CLI Application. This is the hood for all command line tools supported by Magento * * {@inheritdoc} + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class Cli extends SymfonyApplication { @@ -27,7 +28,9 @@ class Cli extends SymfonyApplication */ const INPUT_KEY_BOOTSTRAP = 'bootstrap'; - /** @var \Zend\ServiceManager\ServiceManager */ + /** + * @var \Zend\ServiceManager\ServiceManager + */ private $serviceManager; /** @@ -47,23 +50,6 @@ class Cli extends SymfonyApplication */ public function doRun(InputInterface $input, OutputInterface $output) { - // Check to make sure var/generation/Magento folder dir have read/execute permission for the current user - /** @var \Magento\Setup\Model\ObjectManagerProvider $omProvider */ - $omProvider = $this->serviceManager->get('Magento\Setup\Model\ObjectManagerProvider'); - /** @var \Magento\Framework\ObjectManagerInterface $objectManager */ - $objectManager = $omProvider->get(); - /** @var \Magento\Framework\Setup\Filepermissions $filePermissions */ - $filePermissions = $objectManager->get('Magento\Framework\Setup\FilePermissions'); - if ($filePermissions->checkDirectoryPermissionForCLIUser() === false) { - $output->writeln( - "<error>Command line user (" - . get_current_user() - . ") may not have proper read+execute permissions for directories under \"var/generation/\" . " - . "Please address this issue before using Magento command line." - ); - return 0; - } - $exitCode = parent::doRun($input, $output); if ($this->initException) { $output->writeln( @@ -76,21 +62,31 @@ class Cli extends SymfonyApplication } /** - * @param string $name The name of the application - * @param string $version The version of the application + * @param string $name application name + * @param string $version application version + * @SuppressWarnings(PHPMD.ExitExpression) */ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN') { $this->serviceManager = \Zend\Mvc\Application::init(require BP . '/setup/config/application.config.php') ->getServiceManager(); + $generationDirectoryAccess = new GenerationDirectoryAccess($this->serviceManager); + if (!$generationDirectoryAccess->check()) { + $output = new ConsoleOutput(); + $output->writeln( + '<error>Command line user does not have read and write permissions on var/generation directory. Please' + . ' address this issue before using Magento command line.</error>' + ); + exit(0); + } /** - * Temporary workaround until the compiler is able to clear the generation directory. (MAGETWO-44493) + * Temporary workaround until the compiler is able to clear the generation directory + * @todo remove after MAGETWO-44493 resolved */ - if (class_exists('Magento\Setup\Console\CompilerPreparation')) { - (new \Magento\Setup\Console\CompilerPreparation($this->serviceManager, new ArgvInput(), new File())) - ->handleCompilerEnvironment(); + if (class_exists(CompilerPreparation::class)) { + $compilerPreparation = new CompilerPreparation($this->serviceManager, new ArgvInput(), new File()); + $compilerPreparation->handleCompilerEnvironment(); } - parent::__construct($name, $version); } diff --git a/lib/internal/Magento/Framework/Console/GenerationDirectoryAccess.php b/lib/internal/Magento/Framework/Console/GenerationDirectoryAccess.php new file mode 100644 index 0000000000000000000000000000000000000000..873669bcf8fff35aeac7874e922ad73943853953 --- /dev/null +++ b/lib/internal/Magento/Framework/Console/GenerationDirectoryAccess.php @@ -0,0 +1,76 @@ +<?php +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Console; + +use Magento\Framework\App\Bootstrap; +use Magento\Framework\App\Filesystem\DirectoryList; +use Magento\Framework\Filesystem\DriverPool; +use Magento\Framework\Filesystem\File\WriteFactory; +use Magento\Framework\Filesystem\Directory\Write; +use Zend\ServiceManager\ServiceManager; +use Magento\Setup\Mvc\Bootstrap\InitParamListener; + +/** + * Check var/generation read and write access + */ +class GenerationDirectoryAccess +{ + /** + * @var ServiceManager + */ + private $serviceManager; + + /** + * @param ServiceManager $serviceManager + */ + public function __construct( + ServiceManager $serviceManager + ) { + $this->serviceManager = $serviceManager; + } + + /** + * Check var/generation read and write access + * + * @return bool + */ + public function check() + { + $initParams = $this->serviceManager->get(InitParamListener::BOOTSTRAP_PARAM); + $filesystemDirPaths = isset($initParams[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS]) + ? $initParams[Bootstrap::INIT_PARAM_FILESYSTEM_DIR_PATHS] + : []; + $directoryList = new DirectoryList(BP, $filesystemDirPaths); + $generationDirectoryPath = $directoryList->getPath(DirectoryList::GENERATION); + $driverPool = new DriverPool(); + $fileWriteFactory = new WriteFactory($driverPool); + /** @var \Magento\Framework\Filesystem\DriverInterface $driver */ + $driver = $driverPool->getDriver(DriverPool::FILE); + $directoryWrite = new Write($fileWriteFactory, $driver, $generationDirectoryPath); + if ($directoryWrite->isExist()) { + if ($directoryWrite->isDirectory() + || $directoryWrite->isReadable() + ) { + try { + $probeFilePath = $generationDirectoryPath . DIRECTORY_SEPARATOR . time(); + $fileWriteFactory->create($probeFilePath, DriverPool::FILE, 'w'); + $directoryWrite->delete($probeFilePath); + } catch (\Exception $e) { + return false; + } + } else { + return false; + } + } else { + try { + $directoryWrite->create(); + } catch (\Exception $e) { + return false; + } + } + return true; + } +} diff --git a/lib/internal/Magento/Framework/Indexer/CacheContext.php b/lib/internal/Magento/Framework/Indexer/CacheContext.php index cf4c4bc5ee2334b64bc668af495e9b083e5b87f4..230adc543d4371a203fcf330c5a8de403e2a2150 100644 --- a/lib/internal/Magento/Framework/Indexer/CacheContext.php +++ b/lib/internal/Magento/Framework/Indexer/CacheContext.php @@ -15,6 +15,11 @@ class CacheContext implements \Magento\Framework\DataObject\IdentityInterface */ protected $entities = []; + /** + * @var array + */ + private $tags = []; + /** * Register entity Ids * @@ -29,6 +34,18 @@ class CacheContext implements \Magento\Framework\DataObject\IdentityInterface return $this; } + /** + * Register entity tags + * + * @param string $cacheTag + * @return $this + */ + public function registerTags($cacheTags) + { + $this->tags = array_merge($this->tags, $cacheTags); + return $this; + } + /** * Returns registered entities * @@ -57,6 +74,6 @@ class CacheContext implements \Magento\Framework\DataObject\IdentityInterface $identities[] = $cacheTag . '_' . $id; } } - return $identities; + return array_merge($identities, array_unique($this->tags)); } } diff --git a/lib/internal/Magento/Framework/Setup/FilePermissions.php b/lib/internal/Magento/Framework/Setup/FilePermissions.php index df65ae89296fc685d3fa240720a6ea3463307670..4bb0816a34752969ae843d791e8823512f88610c 100644 --- a/lib/internal/Magento/Framework/Setup/FilePermissions.php +++ b/lib/internal/Magento/Framework/Setup/FilePermissions.php @@ -3,15 +3,12 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Framework\Setup; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Backup\Filesystem\Iterator\Filter; use Magento\Framework\Filesystem\Filter\ExcludeFilter; use Magento\Framework\Filesystem; -use Magento\Framework\Filesystem\Driver\File; -use Magento\Framework\OsInfo; class FilePermissions { @@ -25,11 +22,6 @@ class FilePermissions */ protected $directoryList; - /** - * @var File - */ - protected $driverFile; - /** * List of required writable directories for installation * @@ -65,27 +57,16 @@ class FilePermissions */ protected $nonWritablePathsInDirectories = []; - /** - * @var \Magento\Framework\OsInfo - */ - protected $osInfo; - /** * @param Filesystem $filesystem * @param DirectoryList $directoryList - * @param File $driverFile - * @param OsInfo $osInfo */ public function __construct( Filesystem $filesystem, - DirectoryList $directoryList, - File $driverFile, - OsInfo $osInfo + DirectoryList $directoryList ) { $this->filesystem = $filesystem; $this->directoryList = $directoryList; - $this->driverFile = $driverFile; - $this->osInfo = $osInfo; } /** @@ -230,25 +211,6 @@ class FilePermissions return $this->isReadableDirectory($directory) && !$directory->isWritable(); } - /** - * Checks if var/generation/* has read and execute permissions - * - * @return bool - */ - public function checkDirectoryPermissionForCLIUser() - { - $varGenerationDir = $this->directoryList->getPath(DirectoryList::GENERATION); - $dirs = $this->driverFile->readDirectory($varGenerationDir); - array_unshift($dirs, $varGenerationDir); - - foreach ($dirs as $dir) { - if (!$this->directoryPermissionForCLIUserValid($dir)) { - return false; - } - } - return true; - } - /** * Checks if directory exists and is readable * @@ -308,16 +270,4 @@ class FilePermissions $current = $this->getApplicationCurrentNonWritableDirectories(); return array_diff($required, $current); } - - /** - * Checks if directory has permissions needed for CLI user (valid directory, readable, and executable.) - * Ignores executable permission for Windows. - * - * @param string $dir - * @return bool - */ - private function directoryPermissionForCLIUserValid($dir) - { - return (is_dir($dir) && is_readable($dir) && (is_executable($dir) || $this->osInfo->isWindows())); - } } diff --git a/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php b/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php index 3788a1ede33cfef1b935159fa8c74eeac7d8fadb..cff6323802083c6000f009833415562eee6c3957 100644 --- a/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php +++ b/lib/internal/Magento/Framework/Setup/Test/Unit/FilePermissionsTest.php @@ -3,7 +3,6 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ - namespace Magento\Framework\Setup\Test\Unit; use \Magento\Framework\Setup\FilePermissions; @@ -26,16 +25,6 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase */ private $directoryListMock; - /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Filesystem\Driver\File - */ - private $driverFileMock; - - /** - * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\OsInfo - */ - private $osInfoMock; - /** * @var FilePermissions */ @@ -45,8 +34,6 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase { $this->directoryWriteMock = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false); $this->filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false); - $this->driverFileMock = $this->getMock('Magento\Framework\Filesystem\Driver\File', [], [], '', false); - $this->osInfoMock = $this->getMock('Magento\Framework\OsInfo', [], [], '', false); $this->filesystemMock ->expects($this->any()) @@ -56,9 +43,7 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase $this->filePermissions = new FilePermissions( $this->filesystemMock, - $this->directoryListMock, - $this->driverFileMock, - $this->osInfoMock + $this->directoryListMock ); } @@ -212,55 +197,6 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase ]; } - /** - * Directories have executable permission, not Windows - */ - public function testCheckDirectoryPermissionForCLIUser() - { - $this->directoryListMock->expects($this->once())->method('getPath')->willReturn('/var/generation'); - $this->driverFileMock->expects($this->once()) - ->method('readDirectory') - ->willReturn(['/var/generation/Composer', '/var/gen/Magento']); - // Should never check for OS if executable - $this->osInfoMock->expects($this->never())->method('isWindows'); - $this->assertTrue($this->filePermissions->checkDirectoryPermissionForCLIUser()); - } - - /** - * Directories do not have executable permissions, is Windows - */ - public function testCheckDirectoryPermissionForCLIUserWin() - { - $this->directoryListMock->expects($this->once())->method('getPath')->willReturn('/var/generationNotExec'); - $this->driverFileMock->expects($this->once()) - ->method('readDirectory') - ->willReturn(['/var/generation/ComposerNotExec', '/var/generation/MagentoNotExec']); - // Contains a 'NotExec', so is_executable will return false, isWindows should be called once for each - // directory (including parent) and return true - $this->osInfoMock->expects($this->exactly(3))->method('isWindows')->willReturn(true); - $this->assertTrue($this->filePermissions->checkDirectoryPermissionForCLIUser()); - } - - /** - * One directory does not have executable permission, is not Windows - */ - public function testCheckDirectoryPermissionForCLIUserNotExecutable() - { - $this->directoryListMock->expects($this->once())->method('getPath')->willReturn('/var/generation'); - $this->driverFileMock->expects($this->once()) - ->method('readDirectory') - ->willReturn(['/var/generation/ComposerNotExec', '/var/gen/Magento']); - // Contains a 'NotExec', so is_executable will return false, isWindows should be called and return false - $this->osInfoMock->expects($this->once())->method('isWindows')->willReturn(false); - $this->assertFalse($this->filePermissions->checkDirectoryPermissionForCLIUser()); - } - - /* - * exec directory, unix - * non-exec directory, windows - * non-exec directory, unix - */ - public function setUpDirectoryListInstallation() { $this->directoryListMock @@ -340,46 +276,3 @@ class FilePermissionsTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(false)); } } - -namespace Magento\Framework\Setup; - -/** - * Overriding the built-in PHP function is_dir, always returns true, - * allows unit test of this code without having to setup special directories. - * - * @param string $filename - * @return true - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ -function is_dir($filename) -{ - return true; -} - -/** - * Overriding the built-in PHP function is_readable, always returns true, - * allows unit test of this code without having to setup special directories. - * - * @param string $filename - * @return true - * @SuppressWarnings(PHPMD.UnusedFormalParameter) - */ -function is_readable($filename) -{ - return true; -} - -/** - * Overriding the built-in PHP function is_executable, will return false if directory name contains 'NotExec' - * Allows unit test of this code without having to setup a special directory with non-executable permission. - * - * @param string $filename - * @return bool - */ -function is_executable($filename) -{ - if (strpos($filename, 'NotExec') !== false) { - return false; - } - return true; -}