Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 7e76ff5

Browse files
RuslanKostiv1duhon
authored andcommitted
MAGETWO-72472: Impossible to perform mass update on product with 60+ attributes in system
1 parent 3aa0a16 commit 7e76ff5

File tree

2 files changed

+171
-11
lines changed

2 files changed

+171
-11
lines changed

app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Collection.php

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,19 @@ public function setAttributeSetsFilter(array $setIds)
210210
*/
211211
public function setInAllAttributeSetsFilter(array $setIds)
212212
{
213-
foreach ($setIds as $setId) {
214-
$setId = (int)$setId;
215-
if (!$setId) {
216-
continue;
217-
}
218-
$alias = sprintf('entity_attribute_%d', $setId);
219-
$joinCondition = $this->getConnection()->quoteInto(
220-
"{$alias}.attribute_id = main_table.attribute_id AND {$alias}.attribute_set_id =?",
221-
$setId
222-
);
223-
$this->join([$alias => 'eav_entity_attribute'], $joinCondition, 'attribute_id');
213+
if (!empty($setIds)) {
214+
$this->getSelect()
215+
->join(
216+
['entity_attribute' => $this->getTable('eav_entity_attribute')],
217+
'entity_attribute.attribute_id = main_table.attribute_id',
218+
['count' => new \Zend_Db_Expr('COUNT(*)')]
219+
)
220+
->where(
221+
'entity_attribute.attribute_set_id IN (?)',
222+
$setIds
223+
)
224+
->group('entity_attribute.attribute_id')
225+
->having('count = ' . count($setIds));
224226
}
225227

226228
//$this->getSelect()->distinct(true);
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Eav\Test\Unit\Model\ResourceModel\Entity\Attribute;
8+
9+
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
10+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
11+
12+
/**
13+
* Test for \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection class.
14+
*
15+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
16+
*/
17+
class CollectionTest extends \PHPUnit\Framework\TestCase
18+
{
19+
/**
20+
* @var \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection
21+
*/
22+
private $model;
23+
24+
/**
25+
* @var \Magento\Framework\Data\Collection\EntityFactory|\PHPUnit_Framework_MockObject_MockObject
26+
*/
27+
private $entityFactoryMock;
28+
29+
/**
30+
* @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject
31+
*/
32+
private $loggerMock;
33+
34+
/**
35+
* @var \Magento\Framework\Data\Collection\Db\FetchStrategyInterface|\PHPUnit_Framework_MockObject_MockObject
36+
*/
37+
private $fetchStrategyMock;
38+
39+
/**
40+
* @var \Magento\Framework\Data\Collection\EntityFactory|\PHPUnit_Framework_MockObject_MockObject
41+
*/
42+
private $eventManagerMock;
43+
44+
/**
45+
* @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject
46+
*/
47+
private $eavConfigMock;
48+
49+
/**
50+
* @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
51+
*/
52+
private $storeManagerMock;
53+
54+
/**
55+
* @var \Magento\Framework\DB\Adapter\AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
56+
*/
57+
private $connectionMock;
58+
59+
/**
60+
* @var \Magento\Framework\Model\ResourceModel\Db\AbstractDb|\PHPUnit_Framework_MockObject_MockObject
61+
*/
62+
private $resourceMock;
63+
64+
/**
65+
* @var \Magento\Framework\DB\Select|\PHPUnit_Framework_MockObject_MockObject
66+
*/
67+
private $selectMock;
68+
69+
/**
70+
* {@inheritdoc}
71+
*/
72+
protected function setUp()
73+
{
74+
$this->entityFactoryMock = $this->getMockBuilder(\Magento\Framework\Data\Collection\EntityFactory::class)
75+
->disableOriginalConstructor()
76+
->getMock();
77+
78+
$this->loggerMock = $this->getMockBuilder(\Psr\Log\LoggerInterface::class)
79+
->disableOriginalConstructor()
80+
->getMock();
81+
82+
$this->fetchStrategyMock = $this->getMockBuilder(FetchStrategyInterface::class)
83+
->disableOriginalConstructor()
84+
->getMock();
85+
86+
$this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class)
87+
->disableOriginalConstructor()
88+
->getMock();
89+
90+
$this->eavConfigMock = $this->getMockBuilder(\Magento\Eav\Model\Config::class)
91+
->disableOriginalConstructor()
92+
->getMock();
93+
94+
$this->connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\Pdo\Mysql::class)
95+
->disableOriginalConstructor()
96+
->getMock();
97+
98+
$this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class)
99+
->disableOriginalConstructor()
100+
->getMock();
101+
102+
$this->resourceMock = $this->getMockBuilder(\Magento\Framework\Model\ResourceModel\Db\AbstractDb::class)
103+
->setMethods(['__wakeup', 'getConnection', 'getMainTable', 'getTable'])
104+
->disableOriginalConstructor()
105+
->getMockForAbstractClass();
106+
107+
$this->resourceMock->expects($this->any())->method('getConnection')->willReturn($this->connectionMock);
108+
$this->resourceMock->expects($this->any())->method('getMainTable')->willReturn('eav_entity_attribute');
109+
110+
$this->selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
111+
->disableOriginalConstructor()
112+
->getMock();
113+
114+
$this->connectionMock->expects($this->any())->method('select')->willReturn($this->selectMock);
115+
116+
$objectManager = new ObjectManager($this);
117+
$this->model = $objectManager->getObject(
118+
\Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection::class,
119+
[
120+
'entityFactory' => $this->entityFactoryMock,
121+
'logger' => $this->loggerMock,
122+
'fetchStrategy' => $this->fetchStrategyMock,
123+
'eventManager' => $this->eventManagerMock,
124+
'eavConfig' => $this->eavConfigMock,
125+
'connection' => $this->connectionMock,
126+
'resource' => $this->resourceMock,
127+
]
128+
);
129+
}
130+
131+
/**
132+
* Test method \Magento\Eav\Model\ResourceModel\Entity\Attribute\Collection::setInAllAttributeSetsFilter
133+
*
134+
* @return void
135+
*/
136+
public function testSetInAllAttributeSetsFilter()
137+
{
138+
$setIds = [1, 2, 3];
139+
140+
$this->selectMock->expects($this->atLeastOnce())
141+
->method('where')
142+
->with('entity_attribute.attribute_set_id IN (?)', $setIds)
143+
->willReturnSelf();
144+
$this->selectMock->expects($this->atLeastOnce())->method('join')->with(
145+
['entity_attribute' => $this->model->getTable('eav_entity_attribute')],
146+
'entity_attribute.attribute_id = main_table.attribute_id',
147+
['count' => new \Zend_Db_Expr('COUNT(*)')]
148+
)->willReturnSelf();
149+
150+
$this->selectMock->expects($this->atLeastOnce())->method('group')->with('entity_attribute.attribute_id')
151+
->willReturnSelf();
152+
153+
$this->selectMock->expects($this->atLeastOnce())->method('having')->with('count = ' . count($setIds))
154+
->willReturnSelf();
155+
156+
$this->model->setInAllAttributeSetsFilter($setIds);
157+
}
158+
}

0 commit comments

Comments
 (0)