Skip to content

Commit bbcb564

Browse files
committed
ACP2E-1476: [Magento Cloud] - Cannot export customer from customer grid admin
1 parent 5844ade commit bbcb564

File tree

8 files changed

+242
-36
lines changed

8 files changed

+242
-36
lines changed

app/code/Magento/Customer/Test/Unit/Ui/Component/DataProvider/DocumentTest.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,33 @@ public function testGetGroupAttribute()
157157
$this->storeManager->expects(static::never())
158158
->method('getWebsites');
159159

160-
$group = $this->getMockForAbstractClass(GroupInterface::class);
160+
$group1 = $this->getMockForAbstractClass(GroupInterface::class);
161+
$group2 = $this->getMockForAbstractClass(GroupInterface::class);
161162

162-
$this->groupRepository->expects(static::once())
163+
$this->groupRepository->expects(static::exactly(2))
163164
->method('getById')
164-
->willReturn($group);
165+
->willReturnMap([[1, $group1], [2, $group2]]);
165166

166-
$group->expects(static::once())
167+
$group1->expects(static::once())
167168
->method('getCode')
168169
->willReturn('General');
169170

171+
$group2->expects(static::once())
172+
->method('getCode')
173+
->willReturn('Wholesale');
174+
175+
$attribute = $this->document->getCustomAttribute('group_id');
176+
static::assertEquals('General', $attribute->getValue());
177+
178+
// Check that the group code is resolved from cache
179+
$this->document->setData('group_id', 1);
170180
$attribute = $this->document->getCustomAttribute('group_id');
171181
static::assertEquals('General', $attribute->getValue());
182+
183+
// Check that the group code is resolved from repository if missing in the cache
184+
$this->document->setData('group_id', 2);
185+
$attribute = $this->document->getCustomAttribute('group_id');
186+
static::assertEquals('Wholesale', $attribute->getValue());
172187
}
173188

174189
/**

app/code/Magento/Customer/Ui/Component/DataProvider/Document.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ class Document extends \Magento\Framework\View\Element\UiComponent\DataProvider\
5555
*/
5656
private static $accountLockAttributeCode = 'lock_expires';
5757

58+
/**
59+
* @var array
60+
*/
61+
private static $customerGroupCodeById = [];
62+
5863
/**
5964
* @var CustomerMetadataInterface
6065
*/
@@ -164,8 +169,11 @@ private function setCustomerGroupValue()
164169
{
165170
$value = $this->getData(self::$groupAttributeCode);
166171
try {
167-
$group = $this->groupRepository->getById($value);
168-
$this->setCustomAttribute(self::$groupAttributeCode, $group->getCode());
172+
if (!isset(static::$customerGroupCodeById[$value])) {
173+
static::$customerGroupCodeById[$value] = $this->groupRepository->getById($value)->getCode();
174+
}
175+
$this->setCustomAttribute(self::$groupAttributeCode, static::$customerGroupCodeById[$value]);
176+
169177
} catch (NoSuchEntityException $e) {
170178
$this->setCustomAttribute(self::$groupAttributeCode, 'N/A');
171179
}

app/code/Magento/Ui/Model/Export/ConvertToCsv.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
use Magento\Framework\Filesystem;
1212
use Magento\Ui\Component\MassAction\Filter;
1313

14-
/**
15-
* Class ConvertToCsv
16-
*/
1714
class ConvertToCsv
1815
{
1916
/**
@@ -85,14 +82,17 @@ public function getCsvFile()
8582
->setCurrentPage($i)
8683
->setPageSize($this->pageSize);
8784
$totalCount = (int) $dataProvider->getSearchResult()->getTotalCount();
88-
while ($totalCount > 0) {
89-
$items = $dataProvider->getSearchResult()->getItems();
85+
$totalPagesCount = (int) ceil($totalCount / $this->pageSize);
86+
while ($i <= $totalPagesCount) {
87+
// setTotalCount to prevent total count from being calculated in loop
88+
$searchResult = $dataProvider->getSearchResult();
89+
$searchResult->setTotalCount($totalCount);
90+
$items = $searchResult->getItems();
9091
foreach ($items as $item) {
9192
$this->metadataProvider->convertDate($item, $component->getName());
9293
$stream->writeCsv($this->metadataProvider->getRowData($item, $fields, $options));
9394
}
9495
$searchCriteria->setCurrentPage(++$i);
95-
$totalCount = $totalCount - $this->pageSize;
9696
}
9797
$stream->unlock();
9898
$stream->close();

app/code/Magento/Ui/Test/Unit/Model/Export/ConvertToCsvTest.php

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,13 @@ public function testGetCsvFile()
107107
$componentName = 'component_name';
108108
$data = ['data_value'];
109109

110-
$document = $this->getMockBuilder(DocumentInterface::class)
110+
$document1 = $this->getMockBuilder(DocumentInterface::class)
111111
->getMockForAbstractClass();
112112

113-
$this->mockComponent($componentName, [$document]);
113+
$document2 = $this->getMockBuilder(DocumentInterface::class)
114+
->getMockForAbstractClass();
115+
116+
$this->mockComponent($componentName, [$document1], [$document2]);
114117
$this->mockFilter();
115118
$this->mockDirectory();
116119

@@ -139,13 +142,13 @@ public function testGetCsvFile()
139142
->method('getFields')
140143
->with($this->component)
141144
->willReturn([]);
142-
$this->metadataProvider->expects($this->once())
145+
$this->metadataProvider->expects($this->exactly(2))
143146
->method('getRowData')
144-
->with($document, [], [])
147+
->withConsecutive([$document1, [], []], [$document2, [], []])
145148
->willReturn($data);
146-
$this->metadataProvider->expects($this->once())
149+
$this->metadataProvider->expects($this->exactly(2))
147150
->method('convertDate')
148-
->with($document, $componentName);
151+
->withConsecutive([$document1, $componentName], [$document2, $componentName]);
149152

150153
$result = $this->model->getCsvFile();
151154
$this->assertIsArray($result);
@@ -186,9 +189,10 @@ protected function mockStream($expected)
186189

187190
/**
188191
* @param string $componentName
189-
* @param array $items
192+
* @param array $page1Items
193+
* @param array $page2Items
190194
*/
191-
protected function mockComponent($componentName, $items)
195+
private function mockComponent(string $componentName, array $page1Items, array $page2Items): void
192196
{
193197
$context = $this->getMockBuilder(ContextInterface::class)
194198
->setMethods(['getDataProvider'])
@@ -200,7 +204,15 @@ protected function mockComponent($componentName, $items)
200204
->setMethods(['getSearchResult'])
201205
->getMockForAbstractClass();
202206

203-
$searchResult = $this->getMockBuilder(SearchResultInterface::class)
207+
$searchResult0 = $this->getMockBuilder(SearchResultInterface::class)
208+
->setMethods(['getItems'])
209+
->getMockForAbstractClass();
210+
211+
$searchResult1 = $this->getMockBuilder(SearchResultInterface::class)
212+
->setMethods(['getItems'])
213+
->getMockForAbstractClass();
214+
215+
$searchResult2 = $this->getMockBuilder(SearchResultInterface::class)
204216
->setMethods(['getItems'])
205217
->getMockForAbstractClass();
206218

@@ -218,24 +230,35 @@ protected function mockComponent($componentName, $items)
218230
->method('getDataProvider')
219231
->willReturn($dataProvider);
220232

221-
$dataProvider->expects($this->exactly(2))
233+
$dataProvider->expects($this->exactly(3))
222234
->method('getSearchResult')
223-
->willReturn($searchResult);
235+
->willReturnOnConsecutiveCalls($searchResult0, $searchResult1, $searchResult2);
224236

225237
$dataProvider->expects($this->once())
226238
->method('getSearchCriteria')
227239
->willReturn($searchCriteria);
228240

229-
$searchResult->expects($this->once())
241+
$searchResult1->expects($this->once())
242+
->method('setTotalCount');
243+
244+
$searchResult2->expects($this->once())
245+
->method('setTotalCount');
246+
247+
$searchResult1->expects($this->once())
248+
->method('getItems')
249+
->willReturn($page1Items);
250+
251+
$searchResult2->expects($this->once())
230252
->method('getItems')
231-
->willReturn($items);
253+
->willReturn($page2Items);
232254

233-
$searchResult->expects($this->once())
255+
$searchResult0->expects($this->once())
234256
->method('getTotalCount')
235-
->willReturn(1);
257+
->willReturn(201);
236258

237-
$searchCriteria->expects($this->any())
259+
$searchCriteria->expects($this->exactly(3))
238260
->method('setCurrentPage')
261+
->withConsecutive([1], [2], [3])
239262
->willReturnSelf();
240263

241264
$searchCriteria->expects($this->once())

lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/Document.php

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
*/
66
namespace Magento\Framework\View\Element\UiComponent\DataProvider;
77

8+
use Magento\Framework\Api\AttributeInterface;
89
use Magento\Framework\Api\Search\DocumentInterface;
910
use Magento\Framework\DataObject;
1011
use Magento\Framework\Api\AttributeValueFactory;
12+
use Magento\Framework\Profiler;
1113

1214
/**
1315
* The document data provider
@@ -24,6 +26,11 @@ class Document extends DataObject implements DocumentInterface
2426
*/
2527
protected $attributeValueFactory;
2628

29+
/**
30+
* @var \Magento\Framework\Api\AttributeValue
31+
*/
32+
private $attributeValuePrototype;
33+
2734
/**
2835
* @param AttributeValueFactory $attributeValueFactory
2936
*/
@@ -62,12 +69,11 @@ public function setId($id)
6269
* Get an attribute value.
6370
*
6471
* @param string $attributeCode
65-
* @return \Magento\Framework\Api\AttributeInterface|null
72+
* @return AttributeInterface|null
6673
*/
6774
public function getCustomAttribute($attributeCode)
6875
{
69-
/** @var \Magento\Framework\Api\AttributeInterface $attributeValue */
70-
$attributeValue = $this->attributeValueFactory->create();
76+
$attributeValue = $this->getNewEmptyAttributeValue();
7177
$attributeValue->setAttributeCode($attributeCode);
7278
$attributeValue->setValue($this->getData($attributeCode));
7379
return $attributeValue;
@@ -89,13 +95,13 @@ public function setCustomAttribute($attributeCode, $attributeValue)
8995
/**
9096
* Retrieve custom attributes values.
9197
*
92-
* @return \Magento\Framework\Api\AttributeInterface[]|null
98+
* @return AttributeInterface[]|null
9399
*/
94100
public function getCustomAttributes()
95101
{
96102
$output = [];
97103
foreach ($this->getData() as $key => $value) {
98-
$attribute = $this->attributeValueFactory->create();
104+
$attribute = $this->getNewEmptyAttributeValue();
99105
$output[] = $attribute->setAttributeCode($key)->setValue($value);
100106
}
101107
return $output;
@@ -104,13 +110,13 @@ public function getCustomAttributes()
104110
/**
105111
* Set array of custom attributes
106112
*
107-
* @param \Magento\Framework\Api\AttributeInterface[] $attributes
113+
* @param AttributeInterface[] $attributes
108114
* @return $this
109115
* @throws \LogicException
110116
*/
111117
public function setCustomAttributes(array $attributes)
112118
{
113-
/** @var \Magento\Framework\Api\AttributeInterface $attribute */
119+
/** @var AttributeInterface $attribute */
114120
foreach ($attributes as $attribute) {
115121
$this->setData(
116122
$attribute->getAttributeCode(),
@@ -119,4 +125,17 @@ public function setCustomAttributes(array $attributes)
119125
}
120126
return $this;
121127
}
128+
129+
/**
130+
* Returns new instance of attribute value
131+
*
132+
* @return AttributeInterface
133+
*/
134+
private function getNewEmptyAttributeValue(): AttributeInterface
135+
{
136+
if ($this->attributeValuePrototype === null) {
137+
$this->attributeValuePrototype = $this->attributeValueFactory->create();
138+
}
139+
return clone $this->attributeValuePrototype;
140+
}
122141
}

lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/SearchResult.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
use Magento\Framework\App\ObjectManager;
1818

1919
/**
20-
* Class SearchResult
2120
* Generic Search Result
21+
*
2222
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2323
* @api
2424
*/
@@ -97,7 +97,10 @@ public function __construct(
9797
}
9898

9999
/**
100+
* Returns resource connection
101+
*
100102
* @deprecated 101.0.0
103+
* @see Dependencies MUST be explicitly declared in the constructor
101104
* @return ResourceConnection
102105
*/
103106
private function getResourceConnection()
@@ -109,6 +112,8 @@ private function getResourceConnection()
109112
}
110113

111114
/**
115+
* Returns search aggregations
116+
*
112117
* @return \Magento\Framework\Api\Search\AggregationInterface
113118
*/
114119
public function getAggregations()
@@ -130,6 +135,8 @@ public function getResource()
130135
}
131136

132137
/**
138+
* Set search aggregations
139+
*
133140
* @param \Magento\Framework\Api\Search\AggregationInterface $aggregations
134141
* @return void
135142
*/
@@ -139,6 +146,8 @@ public function setAggregations($aggregations)
139146
}
140147

141148
/**
149+
* Returns the search criteria or NULL if not defined
150+
*
142151
* @return \Magento\Framework\Api\Search\SearchCriteriaInterface|null
143152
*/
144153
public function getSearchCriteria()
@@ -147,6 +156,8 @@ public function getSearchCriteria()
147156
}
148157

149158
/**
159+
* Set the search criteria.
160+
*
150161
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
151162
* @return $this
152163
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
@@ -158,6 +169,8 @@ public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface
158169
}
159170

160171
/**
172+
* Returns total items count
173+
*
161174
* @return int
162175
*/
163176
public function getTotalCount()
@@ -169,12 +182,15 @@ public function getTotalCount()
169182
}
170183

171184
/**
185+
* Set total items count
186+
*
172187
* @param int $totalCount
173188
* @return $this
174189
*/
175190
public function setTotalCount($totalCount)
176191
{
177192
$this->totalCount = $totalCount;
193+
$this->_totalRecords = $totalCount;
178194
return $this;
179195
}
180196

@@ -191,6 +207,7 @@ public function setItems(array $items = null)
191207
$this->addItem($item);
192208
}
193209
unset($this->totalCount);
210+
unset($this->_totalRecords);
194211
}
195212
return $this;
196213
}

0 commit comments

Comments
 (0)