PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 11.1.0
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v11.1.0
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 / dynamics / outlook / plugin.php

plugin.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 11.1.0, at back/dynamics/outlook/plugin.php

297 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use AcyMailing\Core\AcymPlugin;
4 use AcyMailing\Helpers\MailerHelper;
5
6 class plgAcymOutlook extends AcymPlugin
7 {
8 const SENDING_METHOD_ID = 'outlook';
9 const SENDING_METHOD_NAME = 'Outlook';
10 const SCOPE_SMTP = 'openid offline_access https://outlook.office.com/SMTP.Send';
11 const SCOPE_IMAP = 'openid offline_access https://outlook.office.com/IMAP.AccessAsUser.All';
12
13 public function __construct()
14 {
15 parent::__construct();
16 $this->pluginDescription->name = acym_translation('ACYM_OUTLOOK');
17 }
18
19 public function onAcymGetSendingMethods(&$data, $isMailer = false)
20 {
21 if ($isMailer) {
22 return;
23 }
24
25 $data['sendingMethods'][self::SENDING_METHOD_ID] = [
26 'name' => $this->pluginDescription->name,
27 'image' => ACYM_IMAGES.'mailers/outlook.svg',
28 ];
29 }
30
31 public function onAcymGetSendingMethodsHtmlSetting(&$data)
32 {
33 $username = $this->config->get('outlook_username', $this->config->get('from_email'));
34 $setupDocumentation = ACYM_DOCUMENTATION.'setup/configuration/mail-configuration/set-up-oauth-2.0';
35 $redirectUrl = trim($this->config->get('outlook_redirect_url', acym_baseURI()));
36
37 $refreshToken = $this->config->get('outlook_refresh_token');
38 $refreshTokenExpiration = $this->config->get('outlook_refresh_token_expiration');
39 $mustAuthenticate = empty($refreshToken) || (!empty($refreshTokenExpiration) && $refreshTokenExpiration < time());
40 ?>
41 <div class="send_settings grid-x cell large-6 xlarge-5 xxlarge-4 margin-auto" id="<?php echo esc_attr(self::SENDING_METHOD_ID); ?>_settings">
42 <div class="acym_port_465_closed is-hidden">
43 <?php acym_display(acym_translation('ACYM_PORT_NEEDED'), 'error', false); ?>
44 </div>
45 <div class="cell grid-x acym_vcenter acym__sending__methods__one__settings">
46 <label for="outlook_username" class="cell">
47 <?php echo esc_html(acym_translation('ACYM_SMTP_USERNAME'));
48 acym_info(['textShownInTooltip' => 'ACYM_SMTP_USERNAME_DESC']); ?>
49 </label>
50 <input id="outlook_username"
51 class="cell"
52 type="text"
53 name="config[outlook_username]"
54 value="<?php echo esc_attr($username); ?>">
55 </div>
56 <div class="cell grid-x acym_vcenter acym__sending__methods__one__settings">
57 <label for="outlook_tenant" class="cell"><?php acym_externalLink('ACYM_TENANT', $setupDocumentation, false); ?></label>
58 <?php
59 $value = $this->config->get('outlook_tenant');
60 acym_select(
61 [
62 'common' => 'ACYM_ANY_ACCOUNT_TYPE',
63 'consumers' => 'ACYM_MICROSOFT_ACCOUNTS',
64 'organizations' => 'ACYM_ORGANIZATIONS',
65 ],
66 'config[outlook_tenant]',
67 empty($value) ? 'consumers' : $value,
68 [
69 'class' => 'acym__select',
70 ],
71 '',
72 '',
73 '',
74 true,
75 true
76 );
77 ?>
78 </div>
79 <div class="cell grid-x acym_vcenter acym__sending__methods__one__settings">
80 <label for="outlook_client_id" class="cell"><?php acym_externalLink('ACYM_SMTP_CLIENT_ID', $setupDocumentation, false); ?></label>
81 <input id="outlook_client_id"
82 class="cell"
83 type="text"
84 name="config[outlook_client_id]"
85 value="<?php echo esc_attr($this->config->get('outlook_client_id')); ?>">
86 </div>
87 <div class="cell grid-x acym_vcenter acym__sending__methods__one__settings">
88 <label for="outlook_client_secret" class="cell"><?php acym_externalLink('ACYM_SMTP_CLIENT_SECRET', $setupDocumentation, false); ?></label>
89 <input id="outlook_client_secret"
90 class="cell"
91 type="text"
92 name="config[outlook_client_secret]"
93 value="<?php echo esc_attr($this->config->get('outlook_client_secret')); ?>">
94 </div>
95 <div class="cell grid-x acym_vcenter acym__sending__methods__one__settings">
96 <label for="outlook_redirect_url" class="cell"><?php echo esc_html(acym_translation('ACYM_SMTP_REDIRECT_URL')); ?></label>
97 <input id="outlook_redirect_url"
98 class="cell"
99 type="text"
100 name="config[outlook_redirect_url]"
101 value="<?php echo esc_attr($redirectUrl); ?>">
102 </div>
103 <div class="cell grid-x acym_vcenter acym__sending__methods__one__settings">
104 <?php if ($mustAuthenticate) { ?>
105 <button data-before-action="configSave"
106 data-task="loginForOAuth2Smtp"
107 class="button acy_button_submit margin-next-1">
108 <?php echo esc_html(acym_translation('ACYM_AUTHENTICATE')); ?>
109 </button>
110 <?php $this->getCopySettingsButton($data, self::SENDING_METHOD_ID, 'wp_mail_smtp', false); ?>
111 <?php } else { ?>
112 <button data-before-action="configSave"
113 data-task="logoutForOAuth2Smtp"
114 class="button acy_button_submit button-secondary margin-bottom-1">
115 <?php echo esc_html(acym_translation('ACYM_REVOKE_PERMISSIONS')); ?>
116 </button>
117 <?php
118 if (!empty($refreshTokenExpiration)) {
119 echo esc_html(acym_translationSprintf('ACYM_AUTHENTICATION_WILL_EXPIRE', acym_date($refreshTokenExpiration, 'ACYM_DATE_FORMAT_LC2')));
120 }
121 ?>
122 <?php } ?>
123 </div>
124 </div>
125 <?php
126 }
127
128 public function onAcymGetSettingsSendingMethodFromPlugin(&$data, $plugin, $method)
129 {
130 if ($method !== self::SENDING_METHOD_ID) {
131 return;
132 }
133
134 if (ACYM_CMS === 'wordpress' && $plugin === 'wp_mail_smtp') {
135 $wpMailSmtpSetting = get_option('wp_mail_smtp', '');
136
137 if (empty($wpMailSmtpSetting['outlook'])) {
138 return;
139 }
140
141 $data['outlook_client_id'] = $wpMailSmtpSetting['outlook']['client_id'] ?? '';
142 $data['outlook_client_secret'] = $wpMailSmtpSetting['outlook']['client_secret'] ?? '';
143 }
144 }
145
146 /**
147 * Doc: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#request-an-authorization-code
148 */
149 public function onAcymOauthAuthenticate(string &$consentUrl, bool $isSmtp): void
150 {
151 if ($isSmtp) {
152 if ($this->config->get('mailer_method') !== self::SENDING_METHOD_ID) {
153 return;
154 }
155
156 $clientId = $this->config->get('outlook_client_id');
157 $clientSecret = $this->config->get('outlook_client_secret');
158 $tenant = $this->config->get('outlook_tenant');
159 $redirectUrl = $this->config->get('outlook_redirect_url');
160 $scope = self::SCOPE_SMTP;
161 } else {
162 if ($this->config->get('bounce_server') !== 'outlook.office365.com') {
163 return;
164 }
165
166 $clientId = $this->config->get('bounce_client_id');
167 $clientSecret = $this->config->get('bounce_client_secret');
168 $tenant = $this->config->get('bounce_tenant');
169 $redirectUrl = acym_baseURI();
170 $scope = self::SCOPE_IMAP;
171 }
172
173 if (empty($clientId) || empty($clientSecret) || empty($redirectUrl)) {
174 acym_enqueueMessage(acym_translation('ACYM_PLEASE_FILL_CLIENT_ID_SECRET'), 'error', false);
175
176 return;
177 }
178
179 $consentUrl = 'https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/authorize';
180 $consentUrl .= '?response_mode=query';
181 $consentUrl .= '&client_id='.urlencode($clientId);
182 $consentUrl .= '&prompt=consent';
183 $consentUrl .= '&response_type=code';
184 $consentUrl .= '&redirect_uri='.urlencode($redirectUrl);
185 $consentUrl .= '&scope='.urlencode($scope);
186 $consentUrl .= '&state=acymailing'.($isSmtp ? 'smtp' : 'bounce');
187 }
188
189 /**
190 * Doc: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow#redeem-a-code-for-an-access-token
191 */
192 public function onAcymOauthCredentialsCreation(bool $isSmtp, string $code): void
193 {
194 if ($isSmtp) {
195 if ($this->config->get('mailer_method') !== self::SENDING_METHOD_ID) {
196 return;
197 }
198
199 $clientId = trim($this->config->get('outlook_client_id'));
200 $clientSecret = trim($this->config->get('outlook_client_secret'));
201 $tenant = trim($this->config->get('outlook_tenant', 'consumers'));
202 $redirectUrl = trim($this->config->get('outlook_redirect_url', acym_baseURI()));
203 $scope = self::SCOPE_SMTP;
204 } else {
205 if ($this->config->get('bounce_server') !== 'outlook.office365.com') {
206 return;
207 }
208
209 $clientId = trim($this->config->get('bounce_client_id'));
210 $clientSecret = trim($this->config->get('bounce_client_secret'));
211 $tenant = trim($this->config->get('bounce_tenant', 'consumers'));
212 $redirectUrl = acym_baseURI();
213 $scope = self::SCOPE_IMAP;
214 }
215
216 if (empty($clientId) || empty($clientSecret)) {
217 acym_enqueueMessage(acym_translation('ACYM_PLEASE_FILL_CLIENT_ID_SECRET'), 'error', false);
218
219 return;
220 }
221
222 $response = acym_makeCurlCall(
223 'https://login.microsoftonline.com/'.$tenant.'/oauth2/v2.0/token',
224 [
225 'method' => 'POST',
226 'data' => [
227 'grant_type' => 'authorization_code',
228 'code' => $code,
229 'client_id' => $clientId,
230 'client_secret' => $clientSecret,
231 'redirect_uri' => $redirectUrl,
232 'scope' => $scope,
233 ],
234 ]
235 );
236
237 acym_logError('Response from OAuth call: '.json_encode($response), self::SENDING_METHOD_ID);
238
239 if (!empty($response['error'])) {
240 acym_enqueueMessage(acym_translationSprintf('ACYM_SMTP_OAUTH_ERROR', $response['error']), 'error', false);
241
242 return;
243 }
244
245 $expiringTime = time() + (int)$response['expires_in'];
246
247 if (!empty($response['refresh_token_expires_in'])) {
248 $refreshExpiringTime = time() + (int)$response['refresh_token_expires_in'];
249
250 acym_enqueueMessage(
251 acym_translationSprintf(
252 'ACYM_OAUTH_TEMPORARY',
253 acym_date($refreshExpiringTime, 'ACYM_DATE_FORMAT_LC2')
254 ),
255 'info',
256 false
257 );
258 } else {
259 $refreshExpiringTime = 0;
260 acym_enqueueMessage(acym_translation('ACYM_SMTP_OAUTH_OK'), 'info');
261 }
262
263 if ($isSmtp) {
264 $newConfig = [
265 'outlook_access_token' => $response['access_token'],
266 'outlook_access_token_expiration' => $expiringTime,
267 'outlook_refresh_token' => $response['refresh_token'],
268 'outlook_refresh_token_expiration' => $refreshExpiringTime,
269 ];
270 } else {
271 $newConfig = [
272 'bounce_access_token' => $response['access_token'],
273 'bounce_access_token_expiration' => $expiringTime,
274 'bounce_refresh_token' => $response['refresh_token'],
275 'bounce_refresh_token_expiration' => $refreshExpiringTime,
276 ];
277 }
278
279 $this->config->saveConfig($newConfig);
280 acym_config(true);
281 }
282
283 public function onAcymOauthRevoke(): void
284 {
285 if ($this->config->get('mailer_method') !== self::SENDING_METHOD_ID) {
286 return;
287 }
288
289 $this->config->saveConfig(
290 [
291 'outlook_refresh_token' => '',
292 'outlook_refresh_token_expiration' => '',
293 ]
294 );
295 }
296 }
297