Skip to content

Commit 04fa524

Browse files
authored
MAGETWO-66755: Fix Framework\Data\Collection::each() method #7330
2 parents d48e68a + b8846a7 commit 04fa524

File tree

2 files changed

+99
-4
lines changed

2 files changed

+99
-4
lines changed

lib/internal/Magento/Framework/Data/Collection.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -514,17 +514,29 @@ public function walk($callback, array $args = [])
514514
}
515515

516516
/**
517-
* @param string|array $objMethod
517+
* Call method or callback on each item in the collection.
518+
*
519+
* @param string|array|\Closure $objMethod
518520
* @param array $args
519521
* @return void
520522
*/
521523
public function each($objMethod, $args = [])
522524
{
523-
foreach ($args->_items as $k => $item) {
524-
$args->_items[$k] = call_user_func($objMethod, $item);
525+
if ($objMethod instanceof \Closure) {
526+
foreach ($this->getItems() as $item) {
527+
$objMethod($item, ...$args);
528+
}
529+
} elseif (is_array($objMethod)) {
530+
foreach ($this->getItems() as $item) {
531+
call_user_func($objMethod, $item, ...$args);
532+
}
533+
} else {
534+
foreach ($this->getItems() as $item) {
535+
$item->$objMethod(...$args);
536+
}
525537
}
526538
}
527-
539+
528540
/**
529541
* Setting data for all collection items
530542
*

lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Framework\Data\Test\Unit;
77

8+
// @codingStandardsIgnoreFile
9+
810
class CollectionTest extends \PHPUnit_Framework_TestCase
911
{
1012
/**
@@ -173,4 +175,85 @@ public function testPossibleFlowWithItem()
173175
$this->_model->removeAllItems();
174176
$this->assertEquals([], $this->_model->getItems());
175177
}
178+
179+
public function testEachCallsMethodOnEachItemWithNoArgs()
180+
{
181+
for ($i = 0; $i < 3; $i++) {
182+
$item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']);
183+
$item->expects($this->once())->method('testCallback')->with();
184+
$this->_model->addItem($item);
185+
}
186+
$this->_model->each('testCallback');
187+
}
188+
189+
public function testEachCallsMethodOnEachItemWithArgs()
190+
{
191+
for ($i = 0; $i < 3; $i++) {
192+
$item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']);
193+
$item->expects($this->once())->method('testCallback')->with('a', 'b', 'c');
194+
$this->_model->addItem($item);
195+
}
196+
$this->_model->each('testCallback', ['a', 'b', 'c']);
197+
}
198+
199+
public function testCallsClosureWithEachItemAndNoArgs()
200+
{
201+
for ($i = 0; $i < 3; $i++) {
202+
$item = $this->getMock(\Magento\Framework\DataObject::class, ['testCallback']);
203+
$item->expects($this->once())->method('testCallback')->with();
204+
$this->_model->addItem($item);
205+
}
206+
$this->_model->each(function ($item) {
207+
$item->testCallback();
208+
});
209+
}
210+
211+
public function testCallsClosureWithEachItemAndArgs()
212+
{
213+
for ($i = 0; $i < 3; $i++) {
214+
$item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']);
215+
$item->expects($this->once())->method('testItemCallback')->with('a', 'b', 'c');
216+
$this->_model->addItem($item);
217+
}
218+
$this->_model->each(function ($item, ...$args) {
219+
$item->testItemCallback(...$args);
220+
}, ['a', 'b', 'c']);
221+
}
222+
223+
public function testCallsCallableArrayWithEachItemNoArgs()
224+
{
225+
$mockCallbackObject = $this->getMockBuilder('DummyEachCallbackInstance')
226+
->setMethods(['testObjCallback'])
227+
->getMock();
228+
$mockCallbackObject->method('testObjCallback')->willReturnCallback(function ($item, ...$args) {
229+
$item->testItemCallback(...$args);
230+
});
231+
232+
for ($i = 0; $i < 3; $i++) {
233+
$item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']);
234+
$item->expects($this->once())->method('testItemCallback')->with();
235+
$this->_model->addItem($item);
236+
}
237+
238+
$this->_model->each([$mockCallbackObject, 'testObjCallback']);
239+
}
240+
241+
public function testCallsCallableArrayWithEachItemAndArgs()
242+
{
243+
$mockCallbackObject = $this->getMockBuilder('DummyEachCallbackInstance')
244+
->setMethods(['testObjCallback'])
245+
->getMock();
246+
$mockCallbackObject->method('testObjCallback')->willReturnCallback(function ($item, ...$args) {
247+
$item->testItemCallback(...$args);
248+
});
249+
250+
for ($i = 0; $i < 3; $i++) {
251+
$item = $this->getMock(\Magento\Framework\DataObject::class, ['testItemCallback']);
252+
$item->expects($this->once())->method('testItemCallback')->with('a', 'b', 'c');
253+
$this->_model->addItem($item);
254+
}
255+
256+
$callback = [$mockCallbackObject, 'testObjCallback'];
257+
$this->_model->each($callback, ['a', 'b', 'c']);
258+
}
176259
}

0 commit comments

Comments
 (0)