5
5
*/
6
6
namespace Magento \Sales \Model ;
7
7
8
+ use Magento \Framework \App \Config \ScopeConfigInterface ;
8
9
use Magento \Framework \App \Config \ValueFactory ;
9
10
use Magento \Framework \App \Config \ValueInterface ;
10
11
use Magento \Framework \App \ObjectManager ;
11
12
use Magento \Sales \Model \Order \Email \Container \IdentityInterface ;
13
+ use Magento \Sales \Model \Order \Email \Sender ;
12
14
use Magento \Sales \Model \ResourceModel \Collection \AbstractCollection ;
15
+ use Magento \Sales \Model \ResourceModel \EntityAbstract ;
16
+ use Magento \Store \Model \StoreManagerInterface ;
13
17
14
18
/**
15
19
* Sales emails sending
19
23
*/
20
24
class EmailSenderHandler
21
25
{
26
+ /**
27
+ * Configuration path for defining asynchronous email sending attempts
28
+ */
29
+ public const XML_PATH_ASYNC_SENDING_ATTEMPTS = 'sales_email/general/async_sending_attempts ' ;
30
+
22
31
/**
23
32
* Email sender model.
24
33
*
25
- * @var \Magento\Sales\Model\Order\Email\ Sender
34
+ * @var Sender
26
35
*/
27
36
protected $ emailSender ;
28
37
29
38
/**
30
39
* Entity resource model.
31
40
*
32
- * @var \Magento\Sales\Model\ResourceModel\ EntityAbstract
41
+ * @var EntityAbstract
33
42
*/
34
43
protected $ entityResource ;
35
44
@@ -43,7 +52,7 @@ class EmailSenderHandler
43
52
/**
44
53
* Global configuration storage.
45
54
*
46
- * @var \Magento\Framework\App\Config\ ScopeConfigInterface
55
+ * @var ScopeConfigInterface
47
56
*/
48
57
protected $ globalConfig ;
49
58
@@ -53,7 +62,7 @@ class EmailSenderHandler
53
62
private $ identityContainer ;
54
63
55
64
/**
56
- * @var \Magento\Store\Model\ StoreManagerInterface
65
+ * @var StoreManagerInterface
57
66
*/
58
67
private $ storeManager ;
59
68
@@ -70,24 +79,24 @@ class EmailSenderHandler
70
79
private $ modifyStartFromDate ;
71
80
72
81
/**
73
- * @param \Magento\Sales\Model\Order\Email\ Sender $emailSender
74
- * @param \Magento\Sales\Model\ResourceModel\ EntityAbstract $entityResource
82
+ * @param Sender $emailSender
83
+ * @param EntityAbstract $entityResource
75
84
* @param AbstractCollection $entityCollection
76
- * @param \Magento\Framework\App\Config\ ScopeConfigInterface $globalConfig
85
+ * @param ScopeConfigInterface $globalConfig
77
86
* @param IdentityInterface|null $identityContainer
78
- * @param \Magento\Store\Model\ StoreManagerInterface|null $storeManager
87
+ * @param StoreManagerInterface|null $storeManager
79
88
* @param ValueFactory|null $configValueFactory
80
89
* @param string|null $modifyStartFromDate
81
90
*/
82
91
public function __construct (
83
- \ Magento \ Sales \ Model \ Order \ Email \ Sender $ emailSender ,
84
- \ Magento \ Sales \ Model \ ResourceModel \ EntityAbstract $ entityResource ,
92
+ Sender $ emailSender ,
93
+ EntityAbstract $ entityResource ,
85
94
AbstractCollection $ entityCollection ,
86
- \ Magento \ Framework \ App \ Config \ ScopeConfigInterface $ globalConfig ,
95
+ ScopeConfigInterface $ globalConfig ,
87
96
IdentityInterface $ identityContainer = null ,
88
- \ Magento \ Store \ Model \ StoreManagerInterface $ storeManager = null ,
97
+ StoreManagerInterface $ storeManager = null ,
89
98
?ValueFactory $ configValueFactory = null ,
90
- ?string $ modifyStartFromDate = null
99
+ ?string $ modifyStartFromDate = null ,
91
100
) {
92
101
$ this ->emailSender = $ emailSender ;
93
102
$ this ->entityResource = $ entityResource ;
@@ -97,21 +106,28 @@ public function __construct(
97
106
$ this ->identityContainer = $ identityContainer ?: ObjectManager::getInstance ()
98
107
->get (\Magento \Sales \Model \Order \Email \Container \NullIdentity::class);
99
108
$ this ->storeManager = $ storeManager ?: ObjectManager::getInstance ()
100
- ->get (\ Magento \ Store \ Model \ StoreManagerInterface::class);
109
+ ->get (StoreManagerInterface::class);
101
110
102
111
$ this ->configValueFactory = $ configValueFactory ?: ObjectManager::getInstance ()->get (ValueFactory::class);
103
112
$ this ->modifyStartFromDate = $ modifyStartFromDate ?: $ this ->modifyStartFromDate ;
104
113
}
105
114
106
115
/**
107
116
* Handles asynchronous email sending
117
+ *
108
118
* @return void
109
119
*/
110
120
public function sendEmails ()
111
121
{
112
122
if ($ this ->globalConfig ->getValue ('sales_email/general/async_sending ' )) {
113
123
$ this ->entityCollection ->addFieldToFilter ('send_email ' , ['eq ' => 1 ]);
114
- $ this ->entityCollection ->addFieldToFilter ('email_sent ' , ['null ' => true ]);
124
+ $ this ->entityCollection ->addFieldToFilter (
125
+ 'email_sent ' ,
126
+ [
127
+ ['null ' => true ],
128
+ ['lteq ' => -1 ]
129
+ ]
130
+ );
115
131
$ this ->filterCollectionByStartFromDate ($ this ->entityCollection );
116
132
$ this ->entityCollection ->setPageSize (
117
133
$ this ->globalConfig ->getValue ('sales_email/general/sending_limit ' )
@@ -120,6 +136,8 @@ public function sendEmails()
120
136
/** @var \Magento\Store\Api\Data\StoreInterface[] $stores */
121
137
$ stores = $ this ->getStores (clone $ this ->entityCollection );
122
138
139
+ $ maxSendAttempts = $ this ->globalConfig ->getValue (self ::XML_PATH_ASYNC_SENDING_ATTEMPTS );
140
+
123
141
/** @var \Magento\Store\Model\Store $store */
124
142
foreach ($ stores as $ store ) {
125
143
$ this ->identityContainer ->setStore ($ store );
@@ -131,12 +149,19 @@ public function sendEmails()
131
149
132
150
/** @var \Magento\Sales\Model\AbstractModel $item */
133
151
foreach ($ entityCollection ->getItems () as $ item ) {
134
- if ($ this ->emailSender ->send ($ item , true )) {
135
- $ this ->entityResource ->saveAttribute (
136
- $ item ->setEmailSent (true ),
137
- 'email_sent '
138
- );
152
+ $ sendAttempts = $ item ->getEmailSent () ?? -$ maxSendAttempts ;
153
+ $ isEmailSent = $ this ->emailSender ->send ($ item , true );
154
+
155
+ if ($ isEmailSent ) {
156
+ $ sendAttempts = 1 ;
157
+ } else {
158
+ $ sendAttempts ++;
139
159
}
160
+
161
+ $ this ->entityResource ->saveAttribute (
162
+ $ item ->setEmailSent ($ sendAttempts ),
163
+ 'email_sent '
164
+ );
140
165
}
141
166
}
142
167
}
@@ -157,7 +182,7 @@ private function getStores(
157
182
$ entityCollection ->addAttributeToSelect ('store_id ' )->getSelect ()->group ('store_id ' );
158
183
/** @var \Magento\Sales\Model\EntityInterface $item */
159
184
foreach ($ entityCollection ->getItems () as $ item ) {
160
- /** @var \Magento\Store\Model\ StoreManagerInterface $store */
185
+ /** @var StoreManagerInterface $store */
161
186
$ store = $ this ->storeManager ->getStore ($ item ->getStoreId ());
162
187
$ stores [$ item ->getStoreId ()] = $ store ;
163
188
}
0 commit comments