Skip to content

Commit bc6ea8c

Browse files
Merge pull request #1796 from magento-engcom/develop-prs
[EngCom] Public Pull Requests - develop - MAGETWO-83289: [Backport 2.3] #11825: Generate new FormKey and replace for oldRequestParams Wishlist #12042 - MAGETWO-84529: [2.3] Correct flat indexing with staging and > 500 cats #12345
2 parents 6c3edb1 + 9179379 commit bc6ea8c

File tree

6 files changed

+214
-12
lines changed

6 files changed

+214
-12
lines changed

app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,22 +369,55 @@ protected function getAttributeValues($entityIds, $storeId)
369369
}
370370
$values = [];
371371

372+
$linkIds = $this->getLinkIds($entityIds);
373+
foreach ($linkIds as $linkId) {
374+
$values[$linkId] = [];
375+
}
376+
372377
$attributes = $this->getAttributes();
373378
$attributesType = ['varchar', 'int', 'decimal', 'text', 'datetime'];
379+
$linkField = $this->getCategoryMetadata()->getLinkField();
374380
foreach ($attributesType as $type) {
375381
foreach ($this->getAttributeTypeValues($type, $entityIds, $storeId) as $row) {
376-
if (isset($row['entity_id']) && isset($row['attribute_id'])) {
382+
if (isset($row[$linkField]) && isset($row['attribute_id'])) {
377383
$attributeId = $row['attribute_id'];
378384
if (isset($attributes[$attributeId])) {
379385
$attributeCode = $attributes[$attributeId]['attribute_code'];
380-
$values[$row['entity_id']][$attributeCode] = $row['value'];
386+
$values[$row[$linkField]][$attributeCode] = $row['value'];
381387
}
382388
}
383389
}
384390
}
391+
385392
return $values;
386393
}
387394

395+
/**
396+
* Translate entity ids into link ids
397+
*
398+
* Used for rows with no EAV attributes set.
399+
*
400+
* @param array $entityIds
401+
* @return array
402+
*/
403+
private function getLinkIds(array $entityIds)
404+
{
405+
$linkField = $this->getCategoryMetadata()->getLinkField();
406+
if ($linkField === 'entity_id') {
407+
return $entityIds;
408+
}
409+
410+
$select = $this->connection->select()->from(
411+
['e' => $this->connection->getTableName($this->getTableName('catalog_category_entity'))],
412+
[$linkField]
413+
)->where(
414+
'e.entity_id IN (?)',
415+
$entityIds
416+
);
417+
418+
return $this->connection->fetchCol($select);
419+
}
420+
388421
/**
389422
* Return attribute values for given entities and store of specific attribute type
390423
*

app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,22 @@ protected function populateFlatTables(array $stores)
6464
}
6565
/** @TODO Do something with chunks */
6666
$categoriesIdsChunks = array_chunk($categoriesIds[$store->getRootCategoryId()], 500);
67+
6768
foreach ($categoriesIdsChunks as $categoriesIdsChunk) {
6869
$attributesData = $this->getAttributeValues($categoriesIdsChunk, $store->getId());
70+
$linkField = $this->categoryMetadata->getLinkField();
71+
6972
$data = [];
7073
foreach ($categories[$store->getRootCategoryId()] as $category) {
71-
if (!isset($attributesData[$category[$this->categoryMetadata->getLinkField()]])) {
74+
if (!isset($attributesData[$category[$linkField]])) {
7275
continue;
7376
}
7477
$category['store_id'] = $store->getId();
7578
$data[] = $this->prepareValuesToInsert(
76-
array_merge($category, $attributesData[$category[$this->categoryMetadata->getLinkField()]])
79+
array_merge($category, $attributesData[$category[$linkField]])
7780
);
7881
}
82+
7983
$this->connection->insertMultiple(
8084
$this->addTemporaryTableSuffix($this->getMainStoreTable($store->getId())),
8185
$data

app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,16 +164,22 @@ private function reindexStore(Store $store, array $entityIds, $useTempTable)
164164
*/
165165
private function buildIndexData(Store $store, $categoriesIdsChunk, $attributesData)
166166
{
167+
$linkField = $this->categoryMetadata->getLinkField();
168+
167169
$data = [];
168170
foreach ($categoriesIdsChunk as $categoryId) {
169171
try {
172+
$category = $this->categoryRepository->get($categoryId);
173+
$categoryData = $category->getData();
174+
$linkId = $categoryData[$linkField];
175+
170176
$categoryAttributesData = [];
171-
if (isset($attributesData[$categoryId]) && is_array($attributesData[$categoryId])) {
172-
$categoryAttributesData = $attributesData[$categoryId];
177+
if (isset($attributesData[$linkId]) && is_array($attributesData[$linkId])) {
178+
$categoryAttributesData = $attributesData[$linkId];
173179
}
174180
$categoryIndexData = $this->buildCategoryIndexData(
175181
$store,
176-
$categoryId,
182+
$categoryData,
177183
$categoryAttributesData
178184
);
179185
$data[] = $categoryIndexData;
@@ -186,18 +192,16 @@ private function buildIndexData(Store $store, $categoriesIdsChunk, $attributesDa
186192

187193
/**
188194
* @param Store $store
189-
* @param int $categoryId
195+
* @param array $categoryData
190196
* @param array $categoryAttributesData
191197
* @return array
192198
* @throws NoSuchEntityException
193199
*/
194-
private function buildCategoryIndexData(Store $store, $categoryId, array $categoryAttributesData)
200+
private function buildCategoryIndexData(Store $store, array $categoryData, array $categoryAttributesData)
195201
{
196-
$category = $this->categoryRepository->get($categoryId);
197-
$categoryAttributesData = [];
198202
$data = $this->prepareValuesToInsert(
199203
array_merge(
200-
$category->getData(),
204+
$categoryData,
201205
$categoryAttributesData,
202206
['store_id' => $store->getId()]
203207
)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Customer\Model\Plugin;
8+
9+
use Magento\Customer\Model\Session;
10+
use Magento\Framework\Data\Form\FormKey as DataFormKey;
11+
use Magento\PageCache\Observer\FlushFormKey;
12+
13+
class CustomerFlushFormKey
14+
{
15+
/**
16+
* @var Session
17+
*/
18+
private $session;
19+
20+
/**
21+
* @var DataFormKey
22+
*/
23+
private $dataFormKey;
24+
25+
/**
26+
* Initialize dependencies.
27+
*
28+
* @param Session $session
29+
* @param DataFormKey $dataFormKey
30+
*/
31+
public function __construct(Session $session, DataFormKey $dataFormKey)
32+
{
33+
$this->session = $session;
34+
$this->dataFormKey = $dataFormKey;
35+
}
36+
37+
/**
38+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
39+
* @param FlushFormKey $subject
40+
* @param callable $proceed
41+
* @param $args
42+
*/
43+
public function aroundExecute(FlushFormKey $subject, callable $proceed, ...$args)
44+
{
45+
$currentFormKey = $this->dataFormKey->getFormKey();
46+
$proceed(...$args);
47+
$beforeParams = $this->session->getBeforeRequestParams();
48+
if ($beforeParams['form_key'] == $currentFormKey) {
49+
$beforeParams['form_key'] = $this->dataFormKey->getFormKey();
50+
$this->session->setBeforeRequestParams($beforeParams);
51+
}
52+
}
53+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Customer\Test\Unit\Model\Plugin;
7+
8+
use Magento\Customer\Model\Plugin\CustomerFlushFormKey;
9+
use Magento\Customer\Model\Session;
10+
use Magento\Framework\App\PageCache\FormKey as CookieFormKey;
11+
use Magento\Framework\Data\Form\FormKey as DataFormKey;
12+
use Magento\Framework\Event\Observer;
13+
use Magento\PageCache\Observer\FlushFormKey;
14+
use PHPUnit\Framework\TestCase;
15+
use PHPUnit_Framework_MockObject_MockObject as MockObject;
16+
17+
class CustomerFlushFormKeyTest extends TestCase
18+
{
19+
/**
20+
* @var CookieFormKey | MockObject
21+
*/
22+
private $cookieFormKey;
23+
24+
/**
25+
* @var Session | MockObject
26+
*/
27+
private $customerSession;
28+
29+
/**
30+
* @var DataFormKey | MockObject
31+
*/
32+
private $dataFormKey;
33+
34+
protected function setUp()
35+
{
36+
37+
/** @var CookieFormKey | MockObject */
38+
$this->cookieFormKey = $this->getMockBuilder(CookieFormKey::class)
39+
->disableOriginalConstructor()
40+
->getMock();
41+
42+
/** @var DataFormKey | MockObject */
43+
$this->dataFormKey = $this->getMockBuilder(DataFormKey::class)
44+
->disableOriginalConstructor()
45+
->getMock();
46+
47+
/** @var Session | MockObject */
48+
$this->customerSession = $this->getMockBuilder(Session::class)
49+
->disableOriginalConstructor()
50+
->setMethods(['getBeforeRequestParams', 'setBeforeRequestParams'])
51+
->getMock();
52+
}
53+
54+
/**
55+
* @dataProvider aroundFlushFormKeyProvider
56+
* @param $beforeFormKey
57+
* @param $currentFormKey
58+
* @param $getFormKeyTimes
59+
* @param $setBeforeParamsTimes
60+
*/
61+
public function testAroundFlushFormKey(
62+
$beforeFormKey,
63+
$currentFormKey,
64+
$getFormKeyTimes,
65+
$setBeforeParamsTimes
66+
) {
67+
$observerDto = new Observer();
68+
$observer = new FlushFormKey($this->cookieFormKey, $this->dataFormKey);
69+
$plugin = new CustomerFlushFormKey($this->customerSession, $this->dataFormKey);
70+
71+
$beforeParams['form_key'] = $beforeFormKey;
72+
73+
$this->dataFormKey->expects($this->exactly($getFormKeyTimes))
74+
->method('getFormKey')
75+
->willReturn($currentFormKey);
76+
77+
$this->customerSession->expects($this->once())
78+
->method('getBeforeRequestParams')
79+
->willReturn($beforeParams);
80+
81+
$this->customerSession->expects($this->exactly($setBeforeParamsTimes))
82+
->method('setBeforeRequestParams')
83+
->with($beforeParams);
84+
85+
$proceed = function ($observerDto) use ($observer) {
86+
return $observer->execute($observerDto);
87+
};
88+
89+
$plugin->aroundExecute($observer, $proceed, $observerDto);
90+
}
91+
92+
/**
93+
* Data provider for testAroundFlushFormKey
94+
*
95+
* @return array
96+
*/
97+
public function aroundFlushFormKeyProvider()
98+
{
99+
return [
100+
['form_key_value', 'form_key_value', 2, 1],
101+
['form_old_key_value', 'form_key_value', 1, 0],
102+
[null, 'form_key_value', 1, 0]
103+
];
104+
}
105+
}

app/code/Magento/Customer/etc/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@
323323
<type name="Magento\Framework\App\Action\AbstractAction">
324324
<plugin name="customerNotification" type="Magento\Customer\Model\Plugin\CustomerNotification"/>
325325
</type>
326+
<type name="Magento\PageCache\Observer\FlushFormKey">
327+
<plugin name="customerFlushFormKey" type="Magento\Customer\Model\Plugin\CustomerFlushFormKey"/>
328+
</type>
326329
<type name="Magento\Customer\Model\Customer\NotificationStorage">
327330
<arguments>
328331
<argument name="cache" xsi:type="object">Magento\Customer\Model\Cache\Type\Notification</argument>

0 commit comments

Comments
 (0)