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

Commit 26bac6f

Browse files
authored
Merge pull request #2754 from magento-panda/PANDA-PR-2.3
Fixed issues: - MAGETWO-89238: [Sales email] Disabled invoice emails produce performance issue - MAGETWO-75530: Deadlock when 'Asynchronous indexing' is enabled (insert from select on sales_order_grid).
2 parents 01103d9 + 4353482 commit 26bac6f

File tree

43 files changed

+648
-166
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+648
-166
lines changed

app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStorePost.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ public function execute()
3737
try {
3838
$model->delete();
3939

40-
$this->_eventManager->dispatch('store_delete', ['store' => $model]);
41-
4240
$this->messageManager->addSuccess(__('You deleted the store view.'));
4341
return $redirectResult->setPath('adminhtml/*/');
4442
} catch (\Magento\Framework\Exception\LocalizedException $e) {

app/code/Magento/Backend/Controller/Adminhtml/System/Store/Save.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ private function processWebsiteSave($postData)
4646
*/
4747
private function processStoreSave($postData)
4848
{
49-
$eventName = 'store_edit';
5049
/** @var \Magento\Store\Model\Store $storeModel */
5150
$storeModel = $this->_objectManager->create(\Magento\Store\Model\Store::class);
5251
$postData['store']['name'] = $this->filterManager->removeTags($postData['store']['name']);
@@ -56,7 +55,6 @@ private function processStoreSave($postData)
5655
$storeModel->setData($postData['store']);
5756
if ($postData['store']['store_id'] == '') {
5857
$storeModel->setId(null);
59-
$eventName = 'store_add';
6058
}
6159
$groupModel = $this->_objectManager->create(
6260
\Magento\Store\Model\Group::class
@@ -70,8 +68,6 @@ private function processStoreSave($postData)
7068
);
7169
}
7270
$storeModel->save();
73-
$this->_objectManager->get(\Magento\Store\Model\StoreManager::class)->reinitStores();
74-
$this->_eventManager->dispatch($eventName, ['store' => $storeModel]);
7571
$this->messageManager->addSuccess(__('You saved the store view.'));
7672

7773
return $postData;
@@ -102,7 +98,6 @@ private function processGroupSave($postData)
10298
);
10399
}
104100
$groupModel->save();
105-
$this->_eventManager->dispatch('store_group_save', ['group' => $groupModel]);
106101
$this->messageManager->addSuccess(__('You saved the store.'));
107102

108103
return $postData;

app/code/Magento/Sales/Model/EmailSenderHandler.php

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
namespace Magento\Sales\Model;
77

8+
use Magento\Sales\Model\Order\Email\Container\IdentityInterface;
9+
810
/**
911
* Sales emails sending
1012
*
@@ -41,22 +43,42 @@ class EmailSenderHandler
4143
*/
4244
protected $globalConfig;
4345

46+
/**
47+
* @var IdentityInterface
48+
*/
49+
private $identityContainer;
50+
51+
/**
52+
* @var \Magento\Store\Model\StoreManagerInterface
53+
*/
54+
private $storeManager;
55+
4456
/**
4557
* @param \Magento\Sales\Model\Order\Email\Sender $emailSender
4658
* @param \Magento\Sales\Model\ResourceModel\EntityAbstract $entityResource
4759
* @param \Magento\Sales\Model\ResourceModel\Collection\AbstractCollection $entityCollection
4860
* @param \Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
61+
* @param IdentityInterface|null $identityContainer
62+
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
63+
* @throws \InvalidArgumentException
4964
*/
5065
public function __construct(
5166
\Magento\Sales\Model\Order\Email\Sender $emailSender,
5267
\Magento\Sales\Model\ResourceModel\EntityAbstract $entityResource,
5368
\Magento\Sales\Model\ResourceModel\Collection\AbstractCollection $entityCollection,
54-
\Magento\Framework\App\Config\ScopeConfigInterface $globalConfig
69+
\Magento\Framework\App\Config\ScopeConfigInterface $globalConfig,
70+
IdentityInterface $identityContainer = null,
71+
\Magento\Store\Model\StoreManagerInterface $storeManager = null
5572
) {
5673
$this->emailSender = $emailSender;
5774
$this->entityResource = $entityResource;
5875
$this->entityCollection = $entityCollection;
5976
$this->globalConfig = $globalConfig;
77+
78+
$this->identityContainer = $identityContainer ?: \Magento\Framework\App\ObjectManager::getInstance()
79+
->get(\Magento\Sales\Model\Order\Email\Container\NullIdentity::class);
80+
$this->storeManager = $storeManager ?: \Magento\Framework\App\ObjectManager::getInstance()
81+
->get(\Magento\Store\Model\StoreManagerInterface::class);
6082
}
6183

6284
/**
@@ -69,14 +91,50 @@ public function sendEmails()
6991
$this->entityCollection->addFieldToFilter('send_email', ['eq' => 1]);
7092
$this->entityCollection->addFieldToFilter('email_sent', ['null' => true]);
7193

72-
/** @var \Magento\Sales\Model\AbstractModel $item */
73-
foreach ($this->entityCollection->getItems() as $item) {
74-
if ($this->emailSender->send($item, true)) {
75-
$this->entityResource->save(
76-
$item->setEmailSent(true)
77-
);
94+
/** @var \Magento\Store\Api\Data\StoreInterface[] $stores */
95+
$stores = $this->getStores(clone $this->entityCollection);
96+
97+
/** @var \Magento\Store\Model\Store $store */
98+
foreach ($stores as $store) {
99+
$this->identityContainer->setStore($store);
100+
if (!$this->identityContainer->isEnabled()) {
101+
continue;
102+
}
103+
$entityCollection = clone $this->entityCollection;
104+
$entityCollection->addFieldToFilter('store_id', $store->getId());
105+
106+
/** @var \Magento\Sales\Model\AbstractModel $item */
107+
foreach ($entityCollection->getItems() as $item) {
108+
if ($this->emailSender->send($item, true)) {
109+
$this->entityResource->save(
110+
$item->setEmailSent(true)
111+
);
112+
}
78113
}
79114
}
80115
}
81116
}
117+
118+
/**
119+
* Get stores for given entities.
120+
*
121+
* @param ResourceModel\Collection\AbstractCollection $entityCollection
122+
* @return \Magento\Store\Api\Data\StoreInterface[]
123+
* @throws \Magento\Framework\Exception\NoSuchEntityException
124+
*/
125+
private function getStores(
126+
\Magento\Sales\Model\ResourceModel\Collection\AbstractCollection $entityCollection
127+
): array {
128+
$stores = [];
129+
130+
$entityCollection->addAttributeToSelect('store_id')->getSelect()->group('store_id');
131+
/** @var \Magento\Sales\Model\EntityInterface $item */
132+
foreach ($entityCollection->getItems() as $item) {
133+
/** @var \Magento\Store\Model\StoreManagerInterface $store */
134+
$store = $this->storeManager->getStore($item->getStoreId());
135+
$stores[$item->getStoreId()] = $store;
136+
}
137+
138+
return $stores;
139+
}
82140
}

app/code/Magento/Sales/Model/Order/Email/Container/IdentityInterface.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6-
namespace Magento\Sales\Model\Order\Email\Container;
6+
7+
namespace Magento\Sales\Model\Order\Email\Container;
78

89
use Magento\Store\Model\Store;
910

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Sales\Model\Order\Email\Container;
9+
10+
class NullIdentity extends Container implements IdentityInterface
11+
{
12+
/**
13+
* @inheritdoc
14+
*/
15+
public function isEnabled()
16+
{
17+
return true;
18+
}
19+
20+
/**
21+
* @inheritdoc
22+
*/
23+
public function getEmailCopyTo()
24+
{
25+
return false;
26+
}
27+
28+
/**
29+
* @inheritdoc
30+
*/
31+
public function getCopyMethod()
32+
{
33+
return '';
34+
}
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
public function getGuestTemplateId()
40+
{
41+
return null;
42+
}
43+
44+
/**
45+
* @inheritdoc
46+
*/
47+
public function getTemplateId()
48+
{
49+
return null;
50+
}
51+
52+
/**
53+
* @inheritdoc
54+
*/
55+
public function getEmailIdentity()
56+
{
57+
return '';
58+
}
59+
}

app/code/Magento/Sales/Model/ResourceModel/Grid.php

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ class Grid extends AbstractGrid
4545
*/
4646
private $notSyncedDataProvider;
4747

48+
/**
49+
* Order grid rows batch size
50+
*/
51+
const BATCH_SIZE = 100;
52+
4853
/**
4954
* @param Context $context
5055
* @param string $mainTableName
@@ -104,25 +109,20 @@ public function refresh($value, $field = null)
104109
*
105110
* Only orders created/updated since the last method call will be added.
106111
*
107-
* @return \Zend_Db_Statement_Interface
112+
* @return void
108113
*/
109114
public function refreshBySchedule()
110115
{
111-
$select = $this->getGridOriginSelect()
112-
->where(
113-
$this->mainTableName . '.entity_id IN (?)',
114-
$this->notSyncedDataProvider->getIds($this->mainTableName, $this->gridTableName)
116+
$notSyncedIds = $this->notSyncedDataProvider->getIds($this->mainTableName, $this->gridTableName);
117+
foreach (array_chunk($notSyncedIds, self::BATCH_SIZE) as $bunch) {
118+
$select = $this->getGridOriginSelect()->where($this->mainTableName . '.entity_id IN (?)', $bunch);
119+
$fetchResult = $this->getConnection()->fetchAll($select);
120+
$this->getConnection()->insertOnDuplicate(
121+
$this->getTable($this->gridTableName),
122+
$fetchResult,
123+
array_keys($this->columns)
115124
);
116-
117-
return $this->getConnection()->query(
118-
$this->getConnection()
119-
->insertFromSelect(
120-
$select,
121-
$this->getTable($this->gridTableName),
122-
array_keys($this->columns),
123-
AdapterInterface::INSERT_ON_DUPLICATE
124-
)
125-
);
125+
}
126126
}
127127

128128
/**

app/code/Magento/Sales/Model/ResourceModel/GridInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function refresh($value, $field = null);
2929
*
3030
* Only rows created/updated since the last method call should be added.
3131
*
32-
* @return \Zend_Db_Statement_Interface
32+
* @return void
3333
*/
3434
public function refreshBySchedule();
3535

0 commit comments

Comments
 (0)