diff --git a/app/code/Magento/Cms/Block/Page.php b/app/code/Magento/Cms/Block/Page.php index 3a63f5b4b941c80a6a1ecfe9f5afb94223e56935..adbb1251c2d4c42e83811155cfd441ddf1c781ed 100644 --- a/app/code/Magento/Cms/Block/Page.php +++ b/app/code/Magento/Cms/Block/Page.php @@ -126,16 +126,26 @@ class Page extends \Magento\Framework\View\Element\AbstractBlock implements */ protected function _addBreadcrumbs(\Magento\Cms\Model\Page $page) { + $homePageIdentifier = $this->_scopeConfig->getValue( + 'web/default/cms_home_page', + ScopeInterface::SCOPE_STORE + ); + $homePageDelimiterPosition = strrpos($homePageIdentifier, '|'); + if ($homePageDelimiterPosition) { + $homePageIdentifier = substr($homePageIdentifier, 0, $homePageDelimiterPosition); + } + $noRouteIdentifier = $this->_scopeConfig->getValue( + 'web/default/cms_no_route', + ScopeInterface::SCOPE_STORE + ); + $noRouteDelimiterPosition = strrpos($noRouteIdentifier, '|'); + if ($noRouteDelimiterPosition) { + $noRouteIdentifier = substr($noRouteIdentifier, 0, $noRouteDelimiterPosition); + } if ($this->_scopeConfig->getValue('web/default/show_cms_breadcrumbs', ScopeInterface::SCOPE_STORE) && ($breadcrumbsBlock = $this->getLayout()->getBlock('breadcrumbs')) - && $page->getIdentifier() !== $this->_scopeConfig->getValue( - 'web/default/cms_home_page', - ScopeInterface::SCOPE_STORE - ) - && $page->getIdentifier() !== $this->_scopeConfig->getValue( - 'web/default/cms_no_route', - ScopeInterface::SCOPE_STORE - ) + && $page->getIdentifier() !== $homePageIdentifier + && $page->getIdentifier() !== $noRouteIdentifier ) { $breadcrumbsBlock->addCrumb( 'home', diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 245e7fc8a41a47602df47911d871858e79a219e0..7ffec9083aec015e76ff86c4574515f5c52e6c07 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -344,7 +344,6 @@ define([ _determineProductData: function () { // Check if product is in a list of products. var productId, - product, isInProductView = false; productId = this.element.parents('.product-item-details') @@ -352,8 +351,7 @@ define([ if (!productId) { // Check individual product. - product = document.getElementsByName('product')[0]; - productId = product ? product.value : undefined; + productId = $('[name=product]').val(); isInProductView = productId > 0; } diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php index 92ae78f26d0919c1ea7340d667f0ca708ebdc69e..d8d09efb5d66fc8be254938d7d5113bda9746ca6 100644 --- a/lib/internal/Magento/Framework/Data/Collection.php +++ b/lib/internal/Magento/Framework/Data/Collection.php @@ -514,17 +514,29 @@ class Collection implements \IteratorAggregate, \Countable, ArrayInterface, Coll } /** - * @param string|array $objMethod + * Call method or callback on each item in the collection. + * + * @param string|array|\Closure $objMethod * @param array $args * @return void */ public function each($objMethod, $args = []) { - foreach ($args->_items as $k => $item) { - $args->_items[$k] = call_user_func($objMethod, $item); + if ($objMethod instanceof \Closure) { + foreach ($this->getItems() as $item) { + $objMethod($item, ...$args); + } + } elseif (is_array($objMethod)) { + foreach ($this->getItems() as $item) { + call_user_func($objMethod, $item, ...$args); + } + } else { + foreach ($this->getItems() as $item) { + $item->$objMethod(...$args); + } } } - + /** * Setting data for all collection items * diff --git a/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php b/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php index 90f0ac2be6d0f15c4a6917875c5451e36514945d..b54374ad10a8380a2d47aa2af8ed2a3da8a72524 100644 --- a/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php +++ b/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php @@ -5,6 +5,8 @@ */ namespace Magento\Framework\Data\Test\Unit; +// @codingStandardsIgnoreFile + class CollectionTest extends \PHPUnit_Framework_TestCase { /** @@ -173,4 +175,85 @@ class CollectionTest extends \PHPUnit_Framework_TestCase $this->_model->removeAllItems(); $this->assertEquals([], $this->_model->getItems()); } + + public function testEachCallsMethodOnEachItemWithNoArgs() + { + for ($i = 0; $i < 3; $i++) { + $item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']); + $item->expects($this->once())->method('testCallback')->with(); + $this->_model->addItem($item); + } + $this->_model->each('testCallback'); + } + + public function testEachCallsMethodOnEachItemWithArgs() + { + for ($i = 0; $i < 3; $i++) { + $item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']); + $item->expects($this->once())->method('testCallback')->with('a', 'b', 'c'); + $this->_model->addItem($item); + } + $this->_model->each('testCallback', ['a', 'b', 'c']); + } + + public function testCallsClosureWithEachItemAndNoArgs() + { + for ($i = 0; $i < 3; $i++) { + $item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']); + $item->expects($this->once())->method('testCallback')->with(); + $this->_model->addItem($item); + } + $this->_model->each(function ($item) { + $item->testCallback(); + }); + } + + public function testCallsClosureWithEachItemAndArgs() + { + for ($i = 0; $i < 3; $i++) { + $item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']); + $item->expects($this->once())->method('testItemCallback')->with('a', 'b', 'c'); + $this->_model->addItem($item); + } + $this->_model->each(function ($item, ...$args) { + $item->testItemCallback(...$args); + }, ['a', 'b', 'c']); + } + + public function testCallsCallableArrayWithEachItemNoArgs() + { + $mockCallbackObject = $this->getMockBuilder('DummyEachCallbackInstance') + ->setMethods(['testObjCallback']) + ->getMock(); + $mockCallbackObject->method('testObjCallback')->willReturnCallback(function ($item, ...$args) { + $item->testItemCallback(...$args); + }); + + for ($i = 0; $i < 3; $i++) { + $item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']); + $item->expects($this->once())->method('testItemCallback')->with(); + $this->_model->addItem($item); + } + + $this->_model->each([$mockCallbackObject, 'testObjCallback']); + } + + public function testCallsCallableArrayWithEachItemAndArgs() + { + $mockCallbackObject = $this->getMockBuilder('DummyEachCallbackInstance') + ->setMethods(['testObjCallback']) + ->getMock(); + $mockCallbackObject->method('testObjCallback')->willReturnCallback(function ($item, ...$args) { + $item->testItemCallback(...$args); + }); + + for ($i = 0; $i < 3; $i++) { + $item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']); + $item->expects($this->once())->method('testItemCallback')->with('a', 'b', 'c'); + $this->_model->addItem($item); + } + + $callback = [$mockCallbackObject, 'testObjCallback']; + $this->_model->each($callback, ['a', 'b', 'c']); + } } diff --git a/lib/internal/Magento/Framework/Session/SaveHandlerInterface.php b/lib/internal/Magento/Framework/Session/SaveHandlerInterface.php index a2d7e486e66ee29749b013535be5945d72152c33..0b3650c28fd720321733e278a3a226b700dd10e4 100644 --- a/lib/internal/Magento/Framework/Session/SaveHandlerInterface.php +++ b/lib/internal/Magento/Framework/Session/SaveHandlerInterface.php @@ -7,7 +7,7 @@ */ namespace Magento\Framework\Session; -interface SaveHandlerInterface extends \Zend_Session_SaveHandler_Interface +interface SaveHandlerInterface extends \SessionHandlerInterface { /** * Default session save handler