PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / trunk
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress vtrunk
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
acymailing / back / Helpers / MailboxHelper.php

MailboxHelper.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress trunk, at back/Helpers/MailboxHelper.php

301 lines 10.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace AcyMailing\Helpers;
4
5 use AcyMailing\Classes\UserClass;
6
7 class MailboxHelper extends BounceHelper
8 {
9 private array $mailboxConfig = [];
10 public $conditions;
11
12 public function buildConfigFromMailbox(): bool
13 {
14 $this->mailboxConfig = [
15 'server' => $this->action->server,
16 'username' => $this->action->username,
17 'password' => $this->action->password,
18 'port' => $this->action->port,
19 'connect_method' => $this->action->connection_method,
20 'secure_method' => $this->action->secure_method,
21 'self_signed' => $this->action->self_signed,
22 'timeout' => 10,
23 'bounce_access_token' => empty($this->action->bounce_access_token) ? '' : $this->action->bounce_access_token,
24 ];
25
26 return $this->isConfigurationValid();
27 }
28
29 private function isConfigurationValid(): bool
30 {
31 $keyShouldNotBeEmpty = in_array($this->mailboxConfig['server'], self::HOSTS_NEEDING_OAUTH) ? 'bounce_access_token' : 'password';
32
33 $error = false;
34 foreach ($this->mailboxConfig as $key => $oneConfig) {
35 if (empty($oneConfig) && $key === $keyShouldNotBeEmpty) {
36 $error = true;
37 break;
38 }
39 }
40
41 return !$error;
42 }
43
44 public function isConnectionValid(object $mailbox, bool $close = true): bool
45 {
46 $this->action = $mailbox;
47 if (!$this->buildConfigFromMailbox()) {
48 return false;
49 }
50
51 if (!$this->init($this->mailboxConfig) || !$this->connect()) {
52 return false;
53 }
54
55 if ($close) {
56 $this->close();
57 }
58
59 return true;
60 }
61
62 private function senderConditionPass(): bool
63 {
64 $conditions = $this->action->conditions;
65 $fromEmail = $this->_message->header->from_email;
66
67 if ($conditions['sender'] === 'specific') {
68 $allowedSenders = explode(',', $conditions['specific']);
69 if (empty($allowedSenders) || !in_array($fromEmail, $allowedSenders)) {
70 $this->display(acym_translationSprintf('ACYM_SENDER_NOT_ALLOWED_X', $fromEmail), self::MESSAGE_TYPE_INFO);
71
72 return false;
73 }
74 }
75
76 if ($conditions['sender'] === 'groups') {
77 $cmsUserId = acym_getCmsUserIdByEmail($fromEmail);
78 if (empty($cmsUserId)) {
79 $this->display(acym_translationSprintf('ACYM_SENDER_NOT_ALLOWED_X_CMS', $fromEmail, ACYM_CMS_TITLE), self::MESSAGE_TYPE_INFO);
80
81 return false;
82 }
83
84 $groups = acym_getGroupsByUser($cmsUserId, false);
85
86 if (empty(array_intersect((array)$conditions['groups'], $groups))) {
87 $this->display(acym_translationSprintf('ACYM_SENDER_NOT_ALLOWED_X_GROUP', $fromEmail, implode(', ', $conditions['groups'])), self::MESSAGE_TYPE_INFO);
88
89 return false;
90 }
91 }
92
93 if ($conditions['sender'] == 'lists' && !empty($conditions['lists'])) {
94 $userClass = new UserClass();
95 $user = $userClass->getOneByEmail($fromEmail);
96
97 if (empty($user)) {
98 $this->display(acym_translationSprintf('ACYM_SENDER_NOT_ALLOWED_X_NOT_EXISTS', $fromEmail), self::MESSAGE_TYPE_INFO);
99
100 return false;
101 }
102
103 $subscriptions = $userClass->getSubscriptionStatus($user->id, $conditions['lists'], 1);
104
105 if (empty($subscriptions)) {
106 $this->display(acym_translationSprintf('ACYM_SENDER_NOT_ALLOWED_X_LIST', $fromEmail), self::MESSAGE_TYPE_INFO);
107
108 return false;
109 }
110 }
111
112 return true;
113 }
114
115 private function subjectConditionPass(): bool
116 {
117 $conditions = $this->action->conditions;
118 $subject = $this->_message->subject;
119
120 $passSubject = true;
121 if (empty($subject)) {
122 $passSubject = false;
123 } elseif ($conditions['subject'] == 'begins' && strpos($subject, $conditions['subject_text']) !== 0) {
124 $passSubject = false;
125 } elseif ($conditions['subject'] == 'ends' && strpos($subject, $conditions['subject_text']) !== strlen($subject) - strlen($conditions['subject_text'])) {
126 $passSubject = false;
127 } elseif ($conditions['subject'] == 'contains' && strpos($subject, $conditions['subject_text']) === false) {
128 $passSubject = false;
129 } elseif ($conditions['subject'] == 'regex' && !preg_match($conditions['subject_regex'], $subject)) {
130 $passSubject = false;
131 }
132
133 if (!$passSubject) {
134 $this->display(acym_translation('ACYM_SUBJECT_DOESNT_MATCH'), self::MESSAGE_TYPE_INFO);
135
136 return false;
137 }
138
139 return true;
140 }
141
142 public function conditionsPass(): bool
143 {
144 if (!empty($this->action->conditions['sender']) && !$this->senderConditionPass()) {
145 return false;
146 }
147
148 if (!empty($this->action->conditions['subject']) && !$this->subjectConditionPass()) {
149 return false;
150 }
151
152 return true;
153 }
154
155 public function handleAction(): void
156 {
157 if (empty($this->action)) {
158 return;
159 }
160
161 $maxMessages = min($this->nbMessages, 100);
162
163 if ($this->report) {
164 if (function_exists('apache_get_modules')) {
165 $modules = apache_get_modules();
166 $this->mod_security2 = in_array('mod_security2', $modules);
167 }
168
169 /*This is to avoid the blank page... and it apparently works! ;) */
170 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Disabled to prevent blank output pages.
171 @ini_set('output_buffering', 'off');
172 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Disabled to prevent blank output pages.
173 @ini_set('zlib.output_compression', 0);
174
175 if (!headers_sent()) {
176 while (ob_get_level() > 0 && $this->obend++ < 3) {
177 @ob_end_flush();
178 }
179 }
180 ?>
181 <div style="position:fixed; top:3px; left:3px; background-color: white; border: 1px solid grey; padding: 3px; font-size:14px">
182 <?php echo esc_html(acym_translation('ACYM_MAILBOX_ACTIONS')); ?> : <span id="counter">0</span> / <?php echo esc_attr($maxMessages); ?>
183 </div>
184 <script type="text/javascript" language="javascript">
185 function setCounter(val) {
186 document.getElementById('counter').innerHTML = val;
187 }
188 </script>
189 <?php
190 if (function_exists('ob_flush')) {
191 @ob_flush();
192 }
193
194 if (!$this->mod_security2) {
195 @flush();
196 }
197 }
198
199 $msgNB = $maxMessages;
200
201 while (($msgNB > 0) && ($this->_message = $this->getMessage($msgNB))) {
202 if ($this->report) {
203 echo '<script type="text/javascript" language="javascript">setCounter('.esc_html($maxMessages - $msgNB + 1).')</script>';
204 if (function_exists('ob_flush')) {
205 @ob_flush();
206 }
207 if (!$this->mod_security2) {
208 @flush();
209 }
210 }
211 $this->_message->messageNB = $msgNB;
212 $msgNB--;
213
214 if (empty($this->_message->subject)) {
215 $this->_message->subject = '';
216 }
217
218 //We could not retrieve the message... we continue with the next message
219 if (!$this->decodeMessage()) {
220 $this->display(acym_translation('ACYM_ERROR_RETRIEVING_MESSAGE'), self::MESSAGE_TYPE_ERROR, $maxMessages - $this->_message->messageNB + 1);
221 continue;
222 }
223
224 if (empty($this->_message->html)) {
225 $this->_message->html = nl2br($this->_message->text);
226 }
227 $stripedHtml = acym_stripTags($this->_message->html);
228
229 if (strlen($stripedHtml) < 3) {
230 $this->display(acym_translation('ACYM_EMPTY_EMAIL_X', esc_html($this->_message->subject)), self::MESSAGE_TYPE_ERROR);
231 if ($this->action->delete_wrong_emails) {
232 $this->deleteMessage($this->_message->messageNB);
233 }
234 continue;
235 }
236
237 if (!$this->conditionsPass()) {
238 $this->display(acym_translation('ACYM_INVALID_EMAIL', $this->_message->subject), self::MESSAGE_TYPE_ERROR);
239 if ($this->action->delete_wrong_emails) {
240 $this->deleteMessage($this->_message->messageNB);
241 }
242 continue;
243 }
244
245 if ($this->executeActions()) {
246 $this->display(acym_translation('ACYM_MESSAGE_DELETED'));
247 $this->deleteMessage($this->_message->messageNB);
248 }
249
250 //We don't have time to finish the process? Ok, we stop it now!
251 if (!empty($this->stoptime) && time() > $this->stoptime) {
252 break;
253 }
254 }
255 }
256
257 public function executeActions(): bool
258 {
259 $executedActions = [];
260
261 foreach ($this->action->actions as $actionKey => $oneAction) {
262 $this->display('<strong>'.acym_translationSprintf('ACYM_ACTION_X', intval($actionKey) + 1).'</strong>');
263
264 $actionId = array_keys($oneAction)[0];
265
266 if (empty($actionId)) {
267 continue;
268 }
269 $executedActions[$actionKey] = true;
270
271 $reportMessages = [];
272 acym_trigger('onAcymMailboxAction_'.$actionId, [&$oneAction[$actionId], &$reportMessages, &$executedActions[$actionKey], $this]);
273
274 foreach ($reportMessages as $reportMessage) {
275 $this->display($reportMessage['message'], $reportMessage['success'] ? self::MESSAGE_TYPE_SUCCESS : self::MESSAGE_TYPE_ERROR);
276 }
277
278 $this->attachments = [];
279 }
280
281 $allActionsExecuted = true;
282 foreach ($executedActions as $oneActionExecuted) {
283 $allActionsExecuted = $allActionsExecuted && $oneActionExecuted;
284 }
285
286 // If false one or more actions were not executed
287 return $allActionsExecuted;
288 }
289
290 public function getAttachments(): string
291 {
292 $newAttachments = [];
293 foreach ($this->attachments as $attachment) {
294 unset($attachment->size);
295 $newAttachments[] = $attachment;
296 }
297
298 return json_encode($newAttachments);
299 }
300 }
301