PluginProbe ʕ •ᴥ•ʔ
WP Mail SMTP by WPForms – The Most Popular SMTP and Email Log Plugin / 4.7.0
WP Mail SMTP by WPForms – The Most Popular SMTP and Email Log Plugin v4.7.0
0.9.6 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.2 1.7.0 1.7.1 1.8.0 1.8.1 1.9.0 2.0.0 2.0.1 2.1.1 2.2.1 2.3.1 2.4.0 2.5.0 2.5.1 2.6.0 2.7.0 2.8.0 2.9.0 3.0.1 3.0.2 3.0.3 3.1.0 3.10.0 3.11.0 3.11.1 3.2.0 3.2.1 3.3.0 3.4.0 3.5.0 3.5.1 3.5.2 3.6.1 3.7.0 3.8.0 3.8.2 3.9.0 4.0.1 4.1.0 4.1.1 4.2.0 4.3.0 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.8.0 trunk 0.10.0 0.10.1 0.11.1 0.11.2 0.3.1 0.3.2 0.4 0.4.1 0.4.2 0.5.0 0.5.1 0.5.2 0.6 0.7 0.8 0.8.2 0.8.3 0.8.4 0.8.5 0.8.6 0.8.7 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5
wp-mail-smtp / src / Options.php
wp-mail-smtp / src Last commit date
Admin 6 months ago Compatibility 6 months ago Helpers 6 months ago Providers 6 months ago Queue 6 months ago Reports 6 months ago Tasks 6 months ago UsageTracking 6 months ago AbstractConnection.php 6 months ago Conflicts.php 6 months ago Connect.php 6 months ago Connection.php 6 months ago ConnectionInterface.php 6 months ago ConnectionsManager.php 6 months ago Core.php 6 months ago DBRepair.php 6 months ago Debug.php 6 months ago Geo.php 6 months ago MailCatcher.php 6 months ago MailCatcherInterface.php 6 months ago MailCatcherTrait.php 6 months ago MailCatcherV6.php 6 months ago Migration.php 6 months ago MigrationAbstract.php 6 months ago Migrations.php 6 months ago OptimizedEmailSending.php 6 months ago Options.php 6 months ago Processor.php 6 months ago SiteHealth.php 6 months ago Upgrade.php 6 months ago Uploads.php 6 months ago WP.php 6 months ago WPMailArgs.php 6 months ago WPMailInitiator.php 6 months ago
Options.php
1816 lines
1 <?php
2
3 namespace WPMailSMTP;
4
5 use WPMailSMTP\Helpers\Crypto;
6 use WPMailSMTP\Reports\Emails\Summary as SummaryReportEmail;
7 use WPMailSMTP\UsageTracking\UsageTracking;
8
9 /**
10 * Class Options to handle all options management.
11 * WordPress does all the heavy work for caching get_option() data,
12 * so we don't have to do that. But we want to minimize cyclomatic complexity
13 * of calling a bunch of WP functions, thus we will cache them in a class as well.
14 *
15 * @since 1.0.0
16 */
17 class Options {
18
19 /**
20 * All the options keys.
21 *
22 * @since 1.3.0
23 * @since 1.4.0 Added Mailgun:region.
24 * @since 1.5.0 Added Outlook/AmazonSES.
25 * @since 1.8.0 Added Pepipost API.
26 * @since 2.0.0 Added SMTP.com API.
27 *
28 * @var array Map of all the default options of the plugin.
29 */
30 private static $map = [
31 'mail' => [
32 'from_name',
33 'from_email',
34 'mailer',
35 'return_path',
36 'from_name_force',
37 'from_email_force',
38 ],
39 'smtp' => [
40 'host',
41 'port',
42 'encryption',
43 'autotls',
44 'auth',
45 'user',
46 'pass',
47 ],
48 'gmail' => [
49 'one_click_setup_enabled',
50 'client_id',
51 'client_secret',
52 ],
53 'outlook' => [
54 'one_click_setup_enabled',
55 'client_id',
56 'client_secret',
57 ],
58 'zoho' => [
59 'domain',
60 'client_id',
61 'client_secret',
62 ],
63 'amazonses' => [
64 'client_id',
65 'client_secret',
66 'region',
67 ],
68 'mailgun' => [
69 'api_key',
70 'domain',
71 'region',
72 ],
73 'mailjet' => [
74 'api_key',
75 'secret_key',
76 ],
77 'mailersend' => [
78 'api_key',
79 'has_pro_plan',
80 ],
81 'mandrill' => [
82 'api_key',
83 ],
84 'sendgrid' => [
85 'api_key',
86 'domain',
87 ],
88 'sparkpost' => [
89 'api_key',
90 'region',
91 ],
92 'postmark' => [
93 'server_api_token',
94 'message_stream',
95 ],
96 'smtpcom' => [
97 'api_key',
98 'channel',
99 ],
100 'sendinblue' => [
101 'api_key',
102 'domain',
103 ],
104 'sendlayer' => [
105 'api_key',
106 ],
107 'elasticemail' => [
108 'api_key',
109 ],
110 'smtp2go' => [
111 'api_key',
112 ],
113 'resend' => [
114 'api_key',
115 ],
116 'pepipostapi' => [
117 'api_key',
118 ],
119 'pepipost' => [
120 'host',
121 'port',
122 'encryption',
123 'auth',
124 'user',
125 'pass',
126 ],
127 'license' => [
128 'key',
129 ],
130 'alert_email' => [
131 'enabled',
132 'connections',
133 ],
134 'alert_slack_webhook' => [
135 'enabled',
136 'connections',
137 ],
138 'alert_discord_webhook' => [
139 'enabled',
140 'connections',
141 ],
142 'alert_twilio_sms' => [
143 'enabled',
144 'connections',
145 ],
146 'alert_custom_webhook' => [
147 'enabled',
148 'connections',
149 ],
150 'alert_push_notifications' => [
151 'enabled',
152 'connections',
153 ],
154 'alert_whatsapp' => [
155 'enabled',
156 'connections',
157 ],
158 'alert_events' => [
159 'email_hard_bounced',
160 ],
161 ];
162
163 /**
164 * List of all mailers (except PHP default mailer 'mail').
165 *
166 * @since 3.3.0
167 *
168 * @var string[]
169 */
170 public static $mailers = [
171 'sendlayer',
172 'smtpcom',
173 'sendinblue',
174 'amazonses',
175 'gmail',
176 'mailgun',
177 'mailjet',
178 'mailersend',
179 'mandrill',
180 'outlook',
181 'postmark',
182 'resend',
183 'sendgrid',
184 'sparkpost',
185 'zoho',
186 'elasticemail',
187 'smtp2go',
188 'smtp',
189 'pepipost',
190 'pepipostapi',
191 ];
192
193 /**
194 * That's where plugin options are saved in wp_options table.
195 *
196 * @since 1.0.0
197 *
198 * @var string
199 */
200 const META_KEY = 'wp_mail_smtp';
201
202 /**
203 * All instances of Options class that should be notified about options update.
204 *
205 * @since 3.7.0
206 *
207 * @var Options[]
208 */
209 protected static $update_observers;
210
211 /**
212 * Options data.
213 *
214 * @since 3.7.0
215 *
216 * @var array
217 */
218 protected $options = [];
219
220 /**
221 * Init the Options class.
222 * TODO: add a flag to process without retrieving const values.
223 *
224 * @since 1.0.0
225 * @since 3.3.0 Deprecated instantiation via new keyword. `Options::init()` must be used.
226 */
227 public function __construct() {
228
229 // Store all class instances that will be notified about options update.
230 static::$update_observers[] = $this;
231
232 $this->populate_options();
233 }
234
235 /**
236 * Initialize all the options.
237 *
238 * @since 1.0.0
239 *
240 * @return Options
241 */
242 public static function init() {
243
244 static $instance;
245
246 if ( ! $instance ) {
247 $instance = new self();
248 }
249
250 return $instance;
251 }
252
253 /**
254 * Whether current class is a main options.
255 *
256 * @since 3.7.0
257 *
258 * @var bool
259 */
260 protected function is_main_options() {
261
262 return true;
263 }
264
265 /**
266 * Default options that are saved on plugin activation.
267 *
268 * @since 1.3.0
269 * @since 2.1.0 Set the Force from email to "on" by default.
270 *
271 * @return array
272 */
273 public static function get_defaults() {
274
275 $defaults = [
276 'mail' => [
277 'from_email' => get_option( 'admin_email' ),
278 'from_name' => get_bloginfo( 'name' ),
279 'mailer' => 'mail',
280 'return_path' => false,
281 'from_email_force' => true,
282 'from_name_force' => false,
283 ],
284 'smtp' => [
285 'autotls' => true,
286 'auth' => true,
287 ],
288 'general' => [
289 SummaryReportEmail::SETTINGS_SLUG => ! is_multisite() ? false : true,
290 ],
291 ];
292
293 /**
294 * Filters the default options.
295 *
296 * @since 3.11.0
297 *
298 * @param array $defaults Default options.
299 */
300 return apply_filters( 'wp_mail_smtp_options_get_defaults', $defaults );
301 }
302
303 /**
304 * Retrieve all options of the plugin.
305 *
306 * @since 1.0.0
307 * @since 2.2.0 Added the filter.
308 */
309 protected function populate_options() {
310
311 $this->options = apply_filters( 'wp_mail_smtp_populate_options', get_option( static::META_KEY, [] ) );
312 }
313
314 /**
315 * Get all the options.
316 *
317 * Options::init()->get_all();
318 *
319 * @since 1.0.0
320 *
321 * @return array
322 */
323 public function get_all() {
324
325 $options = $this->options;
326
327 foreach ( $options as $group => $g_value ) {
328 foreach ( $g_value as $key => $value ) {
329 $options[ $group ][ $key ] = $this->get( $group, $key );
330 }
331 }
332
333 return $this->is_main_options() ? apply_filters( 'wp_mail_smtp_options_get_all', $options ) : $options;
334 }
335
336 /**
337 * Get all the options for a group.
338 *
339 * Options::init()->get_group('smtp') - will return the array of options for the group, including defaults and constants.
340 *
341 * @since 1.0.0
342 * @since 1.5.0 Process values through the get() method which is aware of constants.
343 *
344 * @param string $group
345 *
346 * @return array
347 */
348 public function get_group( $group ) {
349
350 // Just to feel safe.
351 $group = sanitize_key( $group );
352
353 /*
354 * Get the values saved in DB.
355 * If plugin is configured with constants right from the start - this will not have all the values.
356 */
357 $options = isset( $this->options[ $group ] ) ? $this->options[ $group ] : [];
358
359 // We need to process certain constants-aware options through actual constants.
360 if ( isset( self::$map[ $group ] ) ) {
361 foreach ( self::$map[ $group ] as $key ) {
362 $options[ $key ] = $this->get( $group, $key );
363 }
364 }
365
366 return $this->is_main_options() ? apply_filters( 'wp_mail_smtp_options_get_group', $options, $group ) : $options;
367 }
368
369 /**
370 * Get options by a group and a key.
371 *
372 * Options::init()->get( 'smtp', 'host' ) - will return only SMTP 'host' option.
373 *
374 * @since 1.0.0
375 * @since 2.5.0 Added $strip_slashes method parameter.
376 *
377 * @param string $group The option group.
378 * @param string $key The option key.
379 * @param bool $strip_slashes If the slashes should be stripped from string values.
380 *
381 * @return mixed|null Null if value doesn't exist anywhere: in constants, in DB, in a map. So it's completely custom or a typo.
382 */
383 public function get( $group, $key, $strip_slashes = true ) {
384
385 // Just to feel safe.
386 $group = sanitize_key( $group );
387 $key = sanitize_key( $key );
388 $value = null;
389
390 // Get the const value if we have one.
391 $value = $this->get_const_value( $group, $key, $value );
392
393 // We don't have a const value.
394 if ( $value === null ) {
395 // Ordinary database or default values.
396 if ( isset( $this->options[ $group ] ) ) {
397 // Get the options key of a group.
398 if ( isset( $this->options[ $group ][ $key ] ) ) {
399 $value = $this->get_existing_option_value( $group, $key );
400 } else {
401 $value = $this->postprocess_key_defaults( $group, $key );
402 }
403 } else {
404 /*
405 * Fallback to default if it doesn't exist in a map.
406 * Allow to retrieve only values from a map.
407 */
408 if (
409 isset( self::$map[ $group ] ) &&
410 in_array( $key, self::$map[ $group ], true )
411 ) {
412 $value = $this->postprocess_key_defaults( $group, $key );
413 }
414 }
415 }
416
417 // Conditionally strip slashes only from values saved in DB. Constants should be processed as is.
418 if ( $strip_slashes && is_string( $value ) && ! $this->is_const_defined( $group, $key ) ) {
419 $value = stripslashes( $value );
420 }
421
422 return $this->is_main_options() ? apply_filters( 'wp_mail_smtp_options_get', $value, $group, $key ) : $value;
423 }
424
425 /**
426 * Get the existing cached option value.
427 *
428 * @since 2.5.0
429 *
430 * @param string $group The options group.
431 * @param string $key The options key.
432 *
433 * @return mixed
434 */
435 private function get_existing_option_value( $group, $key ) {
436
437 if ( $group === 'smtp' && $key === 'pass' ) {
438 try {
439 return Crypto::decrypt( $this->options[ $group ][ $key ] );
440 } catch ( \Exception $e ) {
441 return $this->options[ $group ][ $key ];
442 }
443 }
444
445 return $this->options[ $group ][ $key ];
446 }
447
448 /**
449 * Some options may be non-empty by default,
450 * so we need to postprocess them to convert.
451 *
452 * @since 1.0.0
453 * @since 1.4.0 Added Mailgun:region.
454 * @since 1.5.0 Added Outlook/AmazonSES, license key support.
455 *
456 * @param string $group
457 * @param string $key
458 *
459 * @return mixed
460 */
461 protected function postprocess_key_defaults( $group, $key ) {
462
463 $value = '';
464
465 switch ( $key ) {
466 case 'from_email_force':
467 case 'from_name_force':
468 case 'return_path':
469 $value = $group === 'mail' ? false : true;
470 break;
471
472 case 'mailer':
473 $value = 'mail';
474 break;
475
476 case 'encryption':
477 $value = in_array( $group, [ 'smtp', 'pepipost' ], true ) ? 'none' : $value;
478 break;
479
480 case 'region':
481 $value = $group === 'mailgun' || $group === 'sparkpost' ? 'US' : $value;
482 break;
483
484 case 'auth':
485 case 'autotls':
486 $value = in_array( $group, [ 'smtp', 'pepipost' ], true ) ? false : true;
487 break;
488
489 case 'pass':
490 $value = $this->get_const_value( $group, $key, $value );
491 break;
492
493 case 'type':
494 $value = $group === 'license' ? 'lite' : '';
495 break;
496 }
497
498 return apply_filters( 'wp_mail_smtp_options_postprocess_key_defaults', $value, $group, $key );
499 }
500
501 /**
502 * Process the options values through the constants check.
503 * If we have defined associated constant - use it instead of a DB value.
504 * Backward compatibility is hard.
505 * General section of options won't have constants, so we are omitting those checks and just return default value.
506 *
507 * @since 1.0.0
508 * @since 1.4.0 Added WPMS_MAILGUN_REGION.
509 * @since 1.5.0 Added Outlook/AmazonSES, license key support.
510 * @since 1.6.0 Added Sendinblue.
511 * @since 1.7.0 Added Do Not Send.
512 * @since 1.8.0 Added Pepipost API.
513 * @since 3.6.0 Added Debug Events Retention Period.
514 *
515 * @param string $group
516 * @param string $key
517 * @param mixed $value
518 *
519 * @return mixed
520 */
521 protected function get_const_value( $group, $key, $value ) {
522
523 if ( ! $this->is_const_enabled() ) {
524 return $value;
525 }
526
527 $return = null;
528
529 // phpcs:disable WPForms.Formatting.Switch.AddEmptyLineBefore, WPForms.Formatting.Switch.RemoveEmptyLineBefore
530 switch ( $group ) {
531 case 'mail':
532 switch ( $key ) {
533 case 'from_name':
534 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
535 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAIL_FROM_NAME : $value;
536 break;
537 case 'from_email':
538 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
539 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAIL_FROM : $value;
540 break;
541 case 'mailer':
542 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
543 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILER : $value;
544 break;
545 case 'return_path':
546 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
547 $return = $this->is_const_defined( $group, $key ) ? WPMS_SET_RETURN_PATH : $value;
548 break;
549 case 'from_name_force':
550 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
551 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAIL_FROM_NAME_FORCE : $value;
552 break;
553 case 'from_email_force':
554 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
555 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAIL_FROM_FORCE : $value;
556 break;
557 }
558
559 break;
560
561 case 'smtp':
562 switch ( $key ) {
563 case 'host':
564 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
565 $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_HOST : $value;
566 break;
567 case 'port':
568 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
569 $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_PORT : $value;
570 break;
571 case 'encryption':
572 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
573 $return = $this->is_const_defined( $group, $key ) ? ( WPMS_SSL === '' ? 'none' : WPMS_SSL ) : $value;
574 break;
575 case 'auth':
576 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
577 $return = $this->is_const_defined( $group, $key ) ? (bool) WPMS_SMTP_AUTH : $value;
578 break;
579 case 'autotls':
580 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
581 $return = $this->is_const_defined( $group, $key ) ? (bool) WPMS_SMTP_AUTOTLS : $value;
582 break;
583 case 'user':
584 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
585 $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_USER : $value;
586 break;
587 case 'pass':
588 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
589 $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP_PASS : $value;
590 break;
591 }
592
593 break;
594
595 case 'sendlayer':
596 switch ( $key ) {
597 case 'api_key':
598 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
599 $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDLAYER_API_KEY : $value;
600 break;
601 }
602
603 break;
604
605 case 'gmail':
606 switch ( $key ) {
607 case 'client_id':
608 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
609 $return = $this->is_const_defined( $group, $key ) ? WPMS_GMAIL_CLIENT_ID : $value;
610 break;
611 case 'client_secret':
612 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
613 $return = $this->is_const_defined( $group, $key ) ? WPMS_GMAIL_CLIENT_SECRET : $value;
614 break;
615 }
616
617 break;
618
619 case 'outlook':
620 switch ( $key ) {
621 case 'client_id':
622 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
623 $return = $this->is_const_defined( $group, $key ) ? WPMS_OUTLOOK_CLIENT_ID : $value;
624 break;
625 case 'client_secret':
626 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
627 $return = $this->is_const_defined( $group, $key ) ? WPMS_OUTLOOK_CLIENT_SECRET : $value;
628 break;
629 }
630
631 break;
632
633 case 'zoho':
634 switch ( $key ) {
635 case 'domain':
636 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
637 $return = $this->is_const_defined( $group, $key ) ? WPMS_ZOHO_DOMAIN : $value;
638 break;
639 case 'client_id':
640 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
641 $return = $this->is_const_defined( $group, $key ) ? WPMS_ZOHO_CLIENT_ID : $value;
642 break;
643 case 'client_secret':
644 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
645 $return = $this->is_const_defined( $group, $key ) ? WPMS_ZOHO_CLIENT_SECRET : $value;
646 break;
647 }
648
649 break;
650
651 case 'amazonses':
652 switch ( $key ) {
653 case 'client_id':
654 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
655 $return = $this->is_const_defined( $group, $key ) ? WPMS_AMAZONSES_CLIENT_ID : $value;
656 break;
657 case 'client_secret':
658 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
659 $return = $this->is_const_defined( $group, $key ) ? WPMS_AMAZONSES_CLIENT_SECRET : $value;
660 break;
661 case 'region':
662 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
663 $return = $this->is_const_defined( $group, $key ) ? WPMS_AMAZONSES_REGION : $value;
664 break;
665 }
666
667 break;
668
669 case 'mailgun':
670 switch ( $key ) {
671 case 'api_key':
672 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
673 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILGUN_API_KEY : $value;
674 break;
675 case 'domain':
676 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
677 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILGUN_DOMAIN : $value;
678 break;
679 case 'region':
680 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
681 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILGUN_REGION : $value;
682 break;
683 }
684
685 break;
686
687 case 'mailjet':
688 switch ( $key ) {
689 case 'api_key':
690 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
691 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILJET_API_KEY : $value;
692 break;
693 case 'secret_key':
694 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
695 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILJET_SECRET_KEY : $value;
696 break;
697 }
698
699 break;
700
701 case 'sendgrid':
702 switch ( $key ) {
703 case 'api_key':
704 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
705 $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDGRID_API_KEY : $value;
706 break;
707 case 'domain':
708 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
709 $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDGRID_DOMAIN : $value;
710 break;
711 }
712
713 break;
714
715 case 'sparkpost':
716 switch ( $key ) {
717 case 'api_key':
718 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
719 $return = $this->is_const_defined( $group, $key ) ? WPMS_SPARKPOST_API_KEY : $value;
720 break;
721 case 'region':
722 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
723 $return = $this->is_const_defined( $group, $key ) ? WPMS_SPARKPOST_REGION : $value;
724 break;
725 }
726
727 break;
728
729 case 'postmark':
730 switch ( $key ) {
731 case 'server_api_token':
732 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
733 $return = $this->is_const_defined( $group, $key ) ? WPMS_POSTMARK_SERVER_API_TOKEN : $value;
734 break;
735 case 'message_stream':
736 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
737 $return = $this->is_const_defined( $group, $key ) ? WPMS_POSTMARK_MESSAGE_STREAM : $value;
738 break;
739 }
740
741 break;
742
743 case 'smtpcom':
744 switch ( $key ) {
745 case 'api_key':
746 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
747 $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTPCOM_API_KEY : $value;
748 break;
749 case 'channel':
750 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
751 $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTPCOM_CHANNEL : $value;
752 break;
753 }
754
755 break;
756
757 case 'sendinblue':
758 switch ( $key ) {
759 case 'api_key':
760 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
761 $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDINBLUE_API_KEY : $value;
762 break;
763 case 'domain':
764 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
765 $return = $this->is_const_defined( $group, $key ) ? WPMS_SENDINBLUE_DOMAIN : $value;
766 break;
767 }
768
769 break;
770
771 case 'elasticemail':
772 switch ( $key ) {
773 case 'api_key':
774 $return = $this->is_const_defined( $group, $key ) ? WPMS_ELASTICEMAIL_API_KEY : $value;
775 break;
776 }
777
778 break;
779
780 case 'smtp2go':
781 switch ( $key ) {
782 case 'api_key':
783 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
784 $return = $this->is_const_defined( $group, $key ) ? WPMS_SMTP2GO_API_KEY : $value;
785 break;
786 }
787
788 break;
789
790 case 'resend':
791 switch ( $key ) {
792 case 'api_key':
793 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
794 $return = $this->is_const_defined( $group, $key ) ? WPMS_RESEND_API_KEY : $value;
795 break;
796 }
797
798 break;
799
800 case 'pepipostapi':
801 switch ( $key ) {
802 case 'api_key':
803 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
804 $return = $this->is_const_defined( $group, $key ) ? WPMS_PEPIPOST_API_KEY : $value;
805 break;
806 }
807
808 break;
809
810 case 'alert_email':
811 switch ( $key ) {
812 case 'connections':
813 $return = $this->is_const_defined( $group, $key ) ? [ [ 'send_to' => WPMS_ALERT_EMAIL_SEND_TO ] ] : $value;
814 break;
815 }
816
817 break;
818
819 case 'alert_slack_webhook':
820 switch ( $key ) {
821 case 'connections':
822 $return = $this->is_const_defined( $group, $key ) ? [ [ 'webhook_url' => WPMS_ALERT_SLACK_WEBHOOK_URL ] ] : $value;
823 break;
824 }
825
826 break;
827
828 case 'alert_discord_webhook':
829 switch ( $key ) {
830 case 'connections':
831 $return = $this->is_const_defined( $group, $key ) ? [ [ 'webhook_url' => WPMS_ALERT_DISCORD_WEBHOOK_URL ] ] : $value;
832 break;
833 }
834
835 break;
836
837 case 'alert_teams_webhook':
838 switch ( $key ) {
839 case 'connections':
840 $return = $this->is_const_defined( $group, $key ) ? [ [ 'webhook_url' => WPMS_ALERT_TEAMS_WEBHOOK_URL ] ] : $value;
841 break;
842 }
843
844 break;
845
846 case 'alert_twilio_sms':
847 switch ( $key ) {
848 case 'connections':
849 if ( $this->is_const_defined( $group, $key ) ) {
850 $return = [
851 [
852 'account_sid' => WPMS_ALERT_TWILIO_SMS_ACCOUNT_SID,
853 'auth_token' => WPMS_ALERT_TWILIO_SMS_AUTH_TOKEN,
854 'from_phone_number' => WPMS_ALERT_TWILIO_SMS_FROM_PHONE_NUMBER,
855 'to_phone_number' => WPMS_ALERT_TWILIO_SMS_TO_PHONE_NUMBER,
856 ],
857 ];
858 } else {
859 $return = $value;
860 }
861 break;
862 }
863
864 break;
865
866 case 'alert_custom_webhook':
867 switch ( $key ) {
868 case 'connections':
869 $return = $this->is_const_defined( $group, $key ) ? [ [ 'webhook_url' => WPMS_ALERT_CUSTOM_WEBHOOK_URL ] ] : $value;
870 break;
871 }
872
873 break;
874
875 case 'license':
876 switch ( $key ) {
877 case 'key':
878 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
879 $return = $this->is_const_defined( $group, $key ) ? WPMS_LICENSE_KEY : $value;
880 break;
881 }
882
883 break;
884
885 case 'general':
886 switch ( $key ) {
887 case 'do_not_send':
888 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
889 $return = $this->is_const_defined( $group, $key ) ? WPMS_DO_NOT_SEND : $value;
890 break;
891
892 case SummaryReportEmail::SETTINGS_SLUG:
893 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
894 $return = $this->is_const_defined( $group, $key ) ?
895 $this->parse_boolean( WPMS_SUMMARY_REPORT_EMAIL_DISABLED ) :
896 $value;
897 break;
898
899 case OptimizedEmailSending::SETTINGS_SLUG:
900 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
901 $return = $this->is_const_defined( $group, $key ) ?
902 $this->parse_boolean( WPMS_OPTIMIZED_EMAIL_SENDING_ENABLED ) :
903 $value;
904 break;
905 }
906
907 break;
908
909 case 'debug_events':
910 switch ( $key ) {
911 case 'retention_period':
912 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
913 $return = $this->is_const_defined( $group, $key ) ? intval( WPMS_DEBUG_EVENTS_RETENTION_PERIOD ) : $value;
914 break;
915 }
916
917 break;
918
919 case 'mailersend':
920 switch ( $key ) {
921 case 'api_key':
922 $return = $this->is_const_defined( $group, $key ) ? WPMS_MAILERSEND_API_KEY : $value;
923 break;
924
925 case 'has_pro_plan':
926 $return = $this->is_const_defined( $group, $key ) ? $this->parse_boolean( WPMS_MAILERSEND_HAS_PRO_PLAN ) : $value;
927 break;
928 }
929 break;
930
931 case 'mandrill':
932 if ( $key === 'api_key' ) {
933 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
934 $return = $this->is_const_defined( $group, $key ) ? WPMS_MANDRILL_API_KEY : $value;
935 }
936
937 break;
938
939 case 'alert_whatsapp':
940 switch ( $key ) {
941 case 'connections':
942 if ( $this->is_const_defined( $group, $key ) ) {
943 $return = [
944 [
945 'access_token' => WPMS_ALERT_WHATSAPP_ACCESS_TOKEN,
946 'whatsapp_business_id' => WPMS_ALERT_WHATSAPP_BUSINESS_ID,
947 'phone_number_id' => WPMS_ALERT_WHATSAPP_PHONE_NUMBER_ID,
948 'to_phone_number' => WPMS_ALERT_WHATSAPP_TO_PHONE_NUMBER,
949 'template_language' => WPMS_ALERT_WHATSAPP_TEMPLATE_LANGUAGE,
950 ],
951 ];
952 } else {
953 $return = $value;
954 }
955 break;
956 }
957
958 break;
959
960 default:
961 // Always return the default value if nothing from above matches the request.
962 $return = $value;
963 }
964
965 // phpcs:enable WPForms.Formatting.Switch.AddEmptyLineBefore, WPForms.Formatting.Switch.RemoveEmptyLineBefore
966
967 return apply_filters( 'wp_mail_smtp_options_get_const_value', $return, $group, $key, $value );
968 }
969
970 /**
971 * Whether constants redefinition is enabled or not.
972 *
973 * @since 1.0.0
974 * @since 1.5.0 Added filter to redefine the value.
975 *
976 * @return bool
977 */
978 public function is_const_enabled() {
979
980 $return = defined( 'WPMS_ON' ) && WPMS_ON === true;
981
982 return apply_filters( 'wp_mail_smtp_options_is_const_enabled', $return );
983 }
984
985 /**
986 * We need this check to reuse later in admin area,
987 * to distinguish settings fields that were redefined,
988 * and display them differently.
989 *
990 * @since 1.0.0
991 * @since 1.5.0 Added a filter, Outlook/AmazonSES, license key support.
992 * @since 1.6.0 Added Sendinblue.
993 * @since 1.7.0 Added Do Not Send.
994 * @since 1.8.0 Added Pepipost API.
995 *
996 * @param string $group
997 * @param string $key
998 *
999 * @return bool
1000 */
1001 public function is_const_defined( $group, $key ) {
1002
1003 if ( ! $this->is_const_enabled() ) {
1004 return false;
1005 }
1006
1007 // Just to feel safe.
1008 $group = sanitize_key( $group );
1009 $key = sanitize_key( $key );
1010 $return = false;
1011
1012 // phpcs:disable WPForms.Formatting.Switch.AddEmptyLineBefore, WPForms.Formatting.Switch.RemoveEmptyLineBefore
1013 switch ( $group ) {
1014 case 'mail':
1015 switch ( $key ) {
1016 case 'from_name':
1017 $return = defined( 'WPMS_MAIL_FROM_NAME' ) && WPMS_MAIL_FROM_NAME;
1018 break;
1019 case 'from_email':
1020 $return = defined( 'WPMS_MAIL_FROM' ) && WPMS_MAIL_FROM;
1021 break;
1022 case 'mailer':
1023 $return = defined( 'WPMS_MAILER' ) && WPMS_MAILER;
1024 break;
1025 case 'return_path':
1026 $return = defined( 'WPMS_SET_RETURN_PATH' ) && ( WPMS_SET_RETURN_PATH === 'true' || WPMS_SET_RETURN_PATH === true );
1027 break;
1028 case 'from_name_force':
1029 $return = defined( 'WPMS_MAIL_FROM_NAME_FORCE' ) && ( WPMS_MAIL_FROM_NAME_FORCE === 'true' || WPMS_MAIL_FROM_NAME_FORCE === true );
1030 break;
1031 case 'from_email_force':
1032 $return = defined( 'WPMS_MAIL_FROM_FORCE' ) && ( WPMS_MAIL_FROM_FORCE === 'true' || WPMS_MAIL_FROM_FORCE === true );
1033 break;
1034 }
1035
1036 break;
1037
1038 case 'smtp':
1039 switch ( $key ) {
1040 case 'host':
1041 $return = defined( 'WPMS_SMTP_HOST' ) && WPMS_SMTP_HOST;
1042 break;
1043 case 'port':
1044 $return = defined( 'WPMS_SMTP_PORT' ) && WPMS_SMTP_PORT;
1045 break;
1046 case 'encryption':
1047 $return = defined( 'WPMS_SSL' );
1048 break;
1049 case 'auth':
1050 $return = defined( 'WPMS_SMTP_AUTH' );
1051 break;
1052 case 'autotls':
1053 $return = defined( 'WPMS_SMTP_AUTOTLS' );
1054 break;
1055 case 'user':
1056 $return = defined( 'WPMS_SMTP_USER' ) && WPMS_SMTP_USER;
1057 break;
1058 case 'pass':
1059 $return = defined( 'WPMS_SMTP_PASS' ) && WPMS_SMTP_PASS;
1060 break;
1061 }
1062
1063 break;
1064
1065 case 'sendlayer':
1066 switch ( $key ) {
1067 case 'api_key':
1068 $return = defined( 'WPMS_SENDLAYER_API_KEY' ) && WPMS_SENDLAYER_API_KEY;
1069 break;
1070 }
1071
1072 break;
1073
1074 case 'gmail':
1075 switch ( $key ) {
1076 case 'client_id':
1077 $return = defined( 'WPMS_GMAIL_CLIENT_ID' ) && WPMS_GMAIL_CLIENT_ID;
1078 break;
1079 case 'client_secret':
1080 $return = defined( 'WPMS_GMAIL_CLIENT_SECRET' ) && WPMS_GMAIL_CLIENT_SECRET;
1081 break;
1082 }
1083
1084 break;
1085
1086 case 'outlook':
1087 switch ( $key ) {
1088 case 'client_id':
1089 $return = defined( 'WPMS_OUTLOOK_CLIENT_ID' ) && WPMS_OUTLOOK_CLIENT_ID;
1090 break;
1091 case 'client_secret':
1092 $return = defined( 'WPMS_OUTLOOK_CLIENT_SECRET' ) && WPMS_OUTLOOK_CLIENT_SECRET;
1093 break;
1094 }
1095
1096 break;
1097
1098 case 'zoho':
1099 switch ( $key ) {
1100 case 'domain':
1101 $return = defined( 'WPMS_ZOHO_DOMAIN' ) && WPMS_ZOHO_DOMAIN;
1102 break;
1103 case 'client_id':
1104 $return = defined( 'WPMS_ZOHO_CLIENT_ID' ) && WPMS_ZOHO_CLIENT_ID;
1105 break;
1106 case 'client_secret':
1107 $return = defined( 'WPMS_ZOHO_CLIENT_SECRET' ) && WPMS_ZOHO_CLIENT_SECRET;
1108 break;
1109 }
1110
1111 break;
1112
1113 case 'amazonses':
1114 switch ( $key ) {
1115 case 'client_id':
1116 $return = defined( 'WPMS_AMAZONSES_CLIENT_ID' ) && WPMS_AMAZONSES_CLIENT_ID;
1117 break;
1118 case 'client_secret':
1119 $return = defined( 'WPMS_AMAZONSES_CLIENT_SECRET' ) && WPMS_AMAZONSES_CLIENT_SECRET;
1120 break;
1121 case 'region':
1122 $return = defined( 'WPMS_AMAZONSES_REGION' ) && WPMS_AMAZONSES_REGION;
1123 break;
1124 }
1125
1126 break;
1127
1128 case 'mailgun':
1129 switch ( $key ) {
1130 case 'api_key':
1131 $return = defined( 'WPMS_MAILGUN_API_KEY' ) && WPMS_MAILGUN_API_KEY;
1132 break;
1133 case 'domain':
1134 $return = defined( 'WPMS_MAILGUN_DOMAIN' ) && WPMS_MAILGUN_DOMAIN;
1135 break;
1136 case 'region':
1137 $return = defined( 'WPMS_MAILGUN_REGION' ) && WPMS_MAILGUN_REGION;
1138 break;
1139 }
1140
1141 break;
1142
1143 case 'mailjet':
1144 switch ( $key ) {
1145 case 'api_key':
1146 $return = defined( 'WPMS_MAILJET_API_KEY' ) && WPMS_MAILJET_API_KEY;
1147 break;
1148 case 'secret_key':
1149 $return = defined( 'WPMS_MAILJET_SECRET_KEY' ) && WPMS_MAILJET_SECRET_KEY;
1150 break;
1151 }
1152
1153 break;
1154
1155 case 'sendgrid':
1156 switch ( $key ) {
1157 case 'api_key':
1158 $return = defined( 'WPMS_SENDGRID_API_KEY' ) && WPMS_SENDGRID_API_KEY;
1159 break;
1160 case 'domain':
1161 $return = defined( 'WPMS_SENDGRID_DOMAIN' ) && WPMS_SENDGRID_DOMAIN;
1162 break;
1163 }
1164
1165 break;
1166
1167 case 'sparkpost':
1168 switch ( $key ) {
1169 case 'api_key':
1170 $return = defined( 'WPMS_SPARKPOST_API_KEY' ) && WPMS_SPARKPOST_API_KEY;
1171 break;
1172 case 'region':
1173 $return = defined( 'WPMS_SPARKPOST_REGION' ) && WPMS_SPARKPOST_REGION;
1174 break;
1175 }
1176
1177 break;
1178
1179 case 'postmark':
1180 switch ( $key ) {
1181 case 'server_api_token':
1182 $return = defined( 'WPMS_POSTMARK_SERVER_API_TOKEN' ) && WPMS_POSTMARK_SERVER_API_TOKEN;
1183 break;
1184 case 'message_stream':
1185 $return = defined( 'WPMS_POSTMARK_MESSAGE_STREAM' ) && WPMS_POSTMARK_MESSAGE_STREAM;
1186 break;
1187 }
1188
1189 break;
1190
1191 case 'smtpcom':
1192 switch ( $key ) {
1193 case 'api_key':
1194 $return = defined( 'WPMS_SMTPCOM_API_KEY' ) && WPMS_SMTPCOM_API_KEY;
1195 break;
1196 case 'channel':
1197 $return = defined( 'WPMS_SMTPCOM_CHANNEL' ) && WPMS_SMTPCOM_CHANNEL;
1198 break;
1199 }
1200
1201 break;
1202
1203 case 'sendinblue':
1204 switch ( $key ) {
1205 case 'api_key':
1206 $return = defined( 'WPMS_SENDINBLUE_API_KEY' ) && WPMS_SENDINBLUE_API_KEY;
1207 break;
1208 case 'domain':
1209 $return = defined( 'WPMS_SENDINBLUE_DOMAIN' ) && WPMS_SENDINBLUE_DOMAIN;
1210 break;
1211 }
1212
1213 break;
1214
1215 case 'elasticemail':
1216 switch ( $key ) {
1217 case 'api_key':
1218 $return = defined( 'WPMS_ELASTICEMAIL_API_KEY' ) && WPMS_ELASTICEMAIL_API_KEY;
1219 break;
1220 }
1221
1222 break;
1223
1224 case 'smtp2go':
1225 switch ( $key ) {
1226 case 'api_key':
1227 $return = defined( 'WPMS_SMTP2GO_API_KEY' ) && WPMS_SMTP2GO_API_KEY;
1228 break;
1229 }
1230
1231 break;
1232
1233 case 'resend':
1234 switch ( $key ) {
1235 case 'api_key':
1236 $return = defined( 'WPMS_RESEND_API_KEY' ) && WPMS_RESEND_API_KEY;
1237 break;
1238 }
1239
1240 break;
1241
1242 case 'pepipostapi':
1243 switch ( $key ) {
1244 case 'api_key':
1245 $return = defined( 'WPMS_PEPIPOST_API_KEY' ) && WPMS_PEPIPOST_API_KEY;
1246 break;
1247 }
1248
1249 break;
1250
1251 case 'alert_email':
1252 switch ( $key ) {
1253 case 'connections':
1254 $return = defined( 'WPMS_ALERT_EMAIL_SEND_TO' ) && WPMS_ALERT_EMAIL_SEND_TO;
1255 break;
1256 }
1257
1258 break;
1259
1260 case 'alert_slack_webhook':
1261 switch ( $key ) {
1262 case 'connections':
1263 $return = defined( 'WPMS_ALERT_SLACK_WEBHOOK_URL' ) && WPMS_ALERT_SLACK_WEBHOOK_URL;
1264 break;
1265 }
1266
1267 break;
1268
1269 case 'alert_discord_webhook':
1270 switch ( $key ) {
1271 case 'connections':
1272 $return = defined( 'WPMS_ALERT_DISCORD_WEBHOOK_URL' ) && WPMS_ALERT_DISCORD_WEBHOOK_URL;
1273 break;
1274 }
1275
1276 break;
1277
1278 case 'alert_teams_webhook':
1279 switch ( $key ) {
1280 case 'connections':
1281 $return = defined( 'WPMS_ALERT_TEAMS_WEBHOOK_URL' ) && WPMS_ALERT_TEAMS_WEBHOOK_URL;
1282 break;
1283 }
1284
1285 break;
1286
1287 case 'alert_twilio_sms':
1288 switch ( $key ) {
1289 case 'connections':
1290 $return = defined( 'WPMS_ALERT_TWILIO_SMS_ACCOUNT_SID' ) && WPMS_ALERT_TWILIO_SMS_ACCOUNT_SID &&
1291 defined( 'WPMS_ALERT_TWILIO_SMS_AUTH_TOKEN' ) && WPMS_ALERT_TWILIO_SMS_AUTH_TOKEN &&
1292 defined( 'WPMS_ALERT_TWILIO_SMS_FROM_PHONE_NUMBER' ) && WPMS_ALERT_TWILIO_SMS_FROM_PHONE_NUMBER &&
1293 defined( 'WPMS_ALERT_TWILIO_SMS_TO_PHONE_NUMBER' ) && WPMS_ALERT_TWILIO_SMS_TO_PHONE_NUMBER;
1294 break;
1295 }
1296
1297 break;
1298
1299 case 'alert_custom_webhook':
1300 switch ( $key ) {
1301 case 'connections':
1302 $return = defined( 'WPMS_ALERT_CUSTOM_WEBHOOK_URL' ) && WPMS_ALERT_CUSTOM_WEBHOOK_URL;
1303 break;
1304 }
1305
1306 break;
1307
1308 case 'alert_whatsapp':
1309 switch ( $key ) {
1310 case 'connections':
1311 $return = defined( 'WPMS_ALERT_WHATSAPP_ACCESS_TOKEN' ) && WPMS_ALERT_WHATSAPP_ACCESS_TOKEN &&
1312 defined( 'WPMS_ALERT_WHATSAPP_BUSINESS_ID' ) && WPMS_ALERT_WHATSAPP_BUSINESS_ID &&
1313 defined( 'WPMS_ALERT_WHATSAPP_PHONE_NUMBER_ID' ) && WPMS_ALERT_WHATSAPP_PHONE_NUMBER_ID &&
1314 defined( 'WPMS_ALERT_WHATSAPP_TO_PHONE_NUMBER' ) && WPMS_ALERT_WHATSAPP_TO_PHONE_NUMBER &&
1315 defined( 'WPMS_ALERT_WHATSAPP_TEMPLATE_LANGUAGE' ) && WPMS_ALERT_WHATSAPP_TEMPLATE_LANGUAGE;
1316 break;
1317 }
1318
1319 break;
1320
1321 case 'license':
1322 switch ( $key ) {
1323 case 'key':
1324 $return = defined( 'WPMS_LICENSE_KEY' ) && WPMS_LICENSE_KEY;
1325 break;
1326 }
1327
1328 break;
1329
1330 case 'general':
1331 switch ( $key ) {
1332 case 'do_not_send':
1333 /** No inspection comment @noinspection PhpUndefinedConstantInspection */
1334 $return = defined( 'WPMS_DO_NOT_SEND' ) && WPMS_DO_NOT_SEND;
1335 break;
1336
1337 case SummaryReportEmail::SETTINGS_SLUG:
1338 $return = defined( 'WPMS_SUMMARY_REPORT_EMAIL_DISABLED' );
1339 break;
1340
1341 case OptimizedEmailSending::SETTINGS_SLUG:
1342 $return = defined( 'WPMS_OPTIMIZED_EMAIL_SENDING_ENABLED' );
1343 break;
1344 }
1345
1346 break;
1347
1348 case 'debug_events':
1349 switch ( $key ) {
1350 case 'retention_period':
1351 $return = defined( 'WPMS_DEBUG_EVENTS_RETENTION_PERIOD' );
1352 break;
1353 }
1354
1355 break;
1356
1357 case 'mailersend':
1358 switch ( $key ) {
1359 case 'api_key':
1360 $return = defined( 'WPMS_MAILERSEND_API_KEY' ) && WPMS_MAILERSEND_API_KEY;
1361 break;
1362
1363 case 'has_pro_plan':
1364 $return = defined( 'WPMS_MAILERSEND_HAS_PRO_PLAN' );
1365 break;
1366 }
1367 break;
1368
1369 case 'mandrill': // phpcs:ignore PSR2.ControlStructures.SwitchDeclaration.BodyOnNextLineCASE
1370
1371 switch ( $key ) {
1372 case 'api_key':
1373 $return = defined( 'WPMS_MANDRILL_API_KEY' ) && WPMS_MANDRILL_API_KEY;
1374 break;
1375 }
1376
1377 break;
1378 }
1379
1380 // phpcs:enable WPForms.Formatting.Switch.AddEmptyLineBefore, WPForms.Formatting.Switch.RemoveEmptyLineBefore
1381
1382 return apply_filters( 'wp_mail_smtp_options_is_const_defined', $return, $group, $key );
1383 }
1384
1385 /**
1386 * Set plugin options, all at once.
1387 *
1388 * @since 1.0.0
1389 * @since 1.3.0 Added $once argument to save options only if they don't exist already.
1390 * @since 1.4.0 Added Mailgun:region.
1391 * @since 1.5.0 Added Outlook/AmazonSES, Email Log. Stop saving const values into DB.
1392 * @since 2.5.0 Added $overwrite_existing method parameter.
1393 *
1394 * @param array $options Plugin options to save.
1395 * @param bool $once Whether to update existing options or to add these options only once.
1396 * @param bool $overwrite_existing Whether to overwrite existing settings or merge these passed options with existing ones.
1397 */
1398 public function set( $options, $once = false, $overwrite_existing = true ) {
1399
1400 // Merge existing settings with new values.
1401 if ( ! $overwrite_existing ) {
1402 $options = self::array_merge_recursive( $this->get_all_raw(), $options );
1403 }
1404
1405 $options = $this->process_generic_options( $options );
1406 $options = $this->process_mailer_specific_options( $options );
1407 $options = apply_filters( 'wp_mail_smtp_options_set', $options );
1408
1409 $this->save_options( $options, $once );
1410
1411 do_action( 'wp_mail_smtp_options_set_after', $options );
1412 }
1413
1414 /**
1415 * Save options to DB.
1416 *
1417 * @since 3.7.0
1418 *
1419 * @param array $options Options to save.
1420 * @param bool $once Whether to update existing options or to add these options only once.
1421 */
1422 protected function save_options( $options, $once ) {
1423
1424 // Whether to update existing options or to add these options only once if they don't exist yet.
1425 if ( $once ) {
1426 add_option( static::META_KEY, $options, '', 'no' ); // Do not autoload these options.
1427 } else {
1428 if ( is_multisite() && WP::use_global_plugin_settings() ) {
1429 update_blog_option( get_main_site_id(), static::META_KEY, $options );
1430 } else {
1431 update_option( static::META_KEY, $options, 'no' );
1432 }
1433 }
1434
1435 // Now we need to re-cache values of all instances.
1436 foreach ( static::$update_observers as $observer ) {
1437 $observer->populate_options();
1438 }
1439 }
1440
1441 /**
1442 * Process the generic plugin options.
1443 *
1444 * @since 2.5.0
1445 *
1446 * @param array $options The options array.
1447 *
1448 * @return array
1449 */
1450 protected function process_generic_options( $options ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.NestingLevel.MaxExceeded
1451
1452 foreach ( (array) $options as $group => $keys ) {
1453 foreach ( $keys as $option_name => $option_value ) {
1454 switch ( $group ) {
1455 case 'mail':
1456 switch ( $option_name ) {
1457 case 'from_name':
1458 $options[ $group ][ $option_name ] = sanitize_text_field( $option_value );
1459 break;
1460 case 'mailer':
1461 $mailer = sanitize_text_field( $option_value );
1462
1463 $mailer = in_array( $mailer, self::$mailers, true ) ? $mailer : 'mail';
1464
1465 $options[ $group ][ $option_name ] = $mailer;
1466 break;
1467 case 'from_email':
1468 if ( filter_var( $option_value, FILTER_VALIDATE_EMAIL ) ) {
1469 $options[ $group ][ $option_name ] = sanitize_email( $option_value );
1470 } else {
1471 $options[ $group ][ $option_name ] = sanitize_email(
1472 wp_mail_smtp()->get_processor()->get_default_email()
1473 );
1474 }
1475 break;
1476 case 'return_path':
1477 case 'from_name_force':
1478 case 'from_email_force':
1479 $options[ $group ][ $option_name ] = (bool) $option_value;
1480 break;
1481 }
1482 break;
1483
1484 case 'general':
1485 switch ( $option_name ) {
1486 case 'do_not_send':
1487 case 'am_notifications_hidden':
1488 case 'email_delivery_errors_hidden':
1489 case 'dashboard_widget_hidden':
1490 case 'uninstall':
1491 case UsageTracking::SETTINGS_SLUG:
1492 case SummaryReportEmail::SETTINGS_SLUG:
1493 case OptimizedEmailSending::SETTINGS_SLUG:
1494 $options[ $group ][ $option_name ] = (bool) $option_value;
1495 break;
1496 }
1497
1498 case 'debug_events':
1499 switch ( $option_name ) {
1500 case 'email_debug':
1501 $options[ $group ][ $option_name ] = (bool) $option_value;
1502 break;
1503 case 'retention_period':
1504 $options[ $group ][ $option_name ] = (int) $option_value;
1505 break;
1506 }
1507 }
1508 }
1509 }
1510
1511 return $options;
1512 }
1513
1514 /**
1515 * Process mailers-specific plugin options.
1516 *
1517 * @since 2.5.0
1518 *
1519 * @param array $options The options array.
1520 *
1521 * @return array
1522 */
1523 protected function process_mailer_specific_options( $options ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.NestingLevel.MaxExceeded
1524
1525 if (
1526 ! empty( $options['mail']['mailer'] ) &&
1527 isset( $options[ $options['mail']['mailer'] ] ) &&
1528 in_array( $options['mail']['mailer'], self::$mailers, true )
1529 ) {
1530
1531 $mailer = $options['mail']['mailer'];
1532
1533 foreach ( $options[ $mailer ] as $option_name => $option_value ) {
1534 switch ( $option_name ) {
1535 case 'host': // smtp.
1536 case 'user': // smtp.
1537 case 'encryption': // smtp.
1538 case 'region': // mailgun/amazonses/sparkpost.
1539 $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : sanitize_text_field( $option_value );
1540 break; // smtp.
1541 case 'port':
1542 $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? 25 : (int) $option_value;
1543 break;
1544 case 'auth': // smtp.
1545 case 'autotls': // smtp.
1546 $option_value = (bool) $option_value;
1547
1548 $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? false : $option_value;
1549 break;
1550
1551 case 'pass': // smtp.
1552 // Do not process as they may contain certain special characters, but allow to be overwritten using constants.
1553 $option_value = trim( (string) $option_value );
1554 $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : $option_value;
1555
1556 if ( $mailer === 'smtp' && ! $this->is_const_defined( 'smtp', 'pass' ) ) {
1557 try {
1558 $options[ $mailer ][ $option_name ] = Crypto::encrypt( $option_value );
1559 } catch ( \Exception $e ) {
1560 } // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch, Squiz.Commenting.EmptyCatchComment.Missing, Squiz.ControlStructures.ControlSignature.NewlineAfterOpenBrace
1561 }
1562 break;
1563
1564 case 'api_key': // mailgun/sendgrid/sendinblue/pepipostapi/smtpcom/sparkpost/sendlayer/smtp2go/mailjet/elasticemail/resend.
1565 case 'secret_key': // mailjet.
1566 case 'domain': // mailgun/zoho/sendgrid/sendinblue.
1567 case 'client_id': // gmail/outlook/amazonses/zoho.
1568 case 'client_secret': // gmail/outlook/amazonses/zoho.
1569 case 'auth_code': // gmail/outlook.
1570 case 'channel': // smtpcom.
1571 case 'server_api_token': // postmark.
1572 case 'message_stream': // postmark.
1573 $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? '' : sanitize_text_field( $option_value );
1574 break;
1575
1576 case 'has_pro_plan': // mailersend.
1577 $options[ $mailer ][ $option_name ] = $this->is_const_defined( $mailer, $option_name ) ? false : (bool) $option_value;
1578 break;
1579
1580 case 'access_token': // gmail/outlook/zoho, is an array.
1581 case 'user_details': // outlook/zoho, is an array.
1582 // These options don't support constants.
1583 $options[ $mailer ][ $option_name ] = $option_value;
1584 break;
1585 }
1586 }
1587 }
1588
1589 return $options;
1590 }
1591
1592 /**
1593 * Merge recursively, including a proper substitution of values in sub-arrays when keys are the same.
1594 * It's more like array_merge() and array_merge_recursive() combined.
1595 *
1596 * @since 1.0.0
1597 *
1598 * @return array
1599 */
1600 public static function array_merge_recursive() {
1601
1602 $arrays = func_get_args();
1603
1604 if ( count( $arrays ) < 2 ) {
1605 return isset( $arrays[0] ) ? $arrays[0] : [];
1606 }
1607
1608 $merged = [];
1609
1610 while ( $arrays ) {
1611 $array = array_shift( $arrays );
1612
1613 if ( ! is_array( $array ) ) {
1614 return [];
1615 }
1616
1617 if ( empty( $array ) ) {
1618 continue;
1619 }
1620
1621 foreach ( $array as $key => $value ) {
1622 if ( is_string( $key ) ) {
1623 if (
1624 is_array( $value ) &&
1625 array_key_exists( $key, $merged ) &&
1626 is_array( $merged[ $key ] )
1627 ) {
1628 $merged[ $key ] = call_user_func( __METHOD__, $merged[ $key ], $value );
1629 } else {
1630 $merged[ $key ] = $value;
1631 }
1632 } else {
1633 $merged[] = $value;
1634 }
1635 }
1636 }
1637
1638 return $merged;
1639 }
1640
1641 /**
1642 * Check whether the site is using Pepipost SMTP or not.
1643 *
1644 * @since 1.0.0
1645 *
1646 * @return bool
1647 */
1648 public function is_pepipost_active() {
1649
1650 _deprecated_function(
1651 __METHOD__,
1652 '2.4.0',
1653 'WPMailSMTP\Options::is_mailer_active()'
1654 );
1655
1656 return apply_filters( 'wp_mail_smtp_options_is_pepipost_active', $this->is_mailer_active( 'pepipost' ) );
1657 }
1658
1659 /**
1660 * Check whether the site is using provided mailer or not.
1661 *
1662 * @since 2.3.0
1663 *
1664 * @param string $mailer The mailer slug.
1665 *
1666 * @return bool
1667 */
1668 public function is_mailer_active( $mailer ) {
1669
1670 $mailer = sanitize_key( $mailer );
1671
1672 return apply_filters(
1673 "wp_mail_smtp_options_is_mailer_active_{$mailer}",
1674 $this->get( 'mail', 'mailer' ) === $mailer
1675 );
1676 }
1677
1678 /**
1679 * Check whether the site is using Pepipost/SMTP as a mailer or not.
1680 *
1681 * @since 1.1.0
1682 *
1683 * @return bool
1684 */
1685 public function is_mailer_smtp() {
1686
1687 return apply_filters( 'wp_mail_smtp_options_is_mailer_smtp', in_array( $this->get( 'mail', 'mailer' ), [ 'pepipost', 'smtp' ], true ) );
1688 }
1689
1690 /**
1691 * Get all the options, but without stripping the slashes.
1692 *
1693 * @since 2.5.0
1694 *
1695 * @return array
1696 */
1697 public function get_all_raw() {
1698
1699 $options = $this->options;
1700
1701 foreach ( $options as $group => $g_value ) {
1702 foreach ( $g_value as $key => $value ) {
1703 $options[ $group ][ $key ] = $this->get( $group, $key, false );
1704 }
1705 }
1706
1707 return $options;
1708 }
1709
1710 /**
1711 * Parse boolean value from string.
1712 *
1713 * @since 2.8.0
1714 *
1715 * @param string|boolean $value String or boolean value.
1716 *
1717 * @return boolean
1718 */
1719 public function parse_boolean( $value ) {
1720
1721 // Return early if it's boolean.
1722 if ( is_bool( $value ) ) {
1723 return $value;
1724 }
1725
1726 $value = trim( $value );
1727
1728 return $value === 'true';
1729 }
1730
1731 /**
1732 * Get a message of a constant that was set inside wp-config.php file.
1733 *
1734 * @since 2.8.0
1735 *
1736 * @param string $constant Constant name.
1737 *
1738 * @return string
1739 */
1740 public function get_const_set_message( $constant ) {
1741
1742 return sprintf( /* translators: %1$s - constant that was used; %2$s - file where it was used. */
1743 esc_html__( 'The value of this field was set using a constant %1$s most likely inside %2$s of your WordPress installation.', 'wp-mail-smtp' ),
1744 '<code>' . esc_html( $constant ) . '</code>',
1745 '<code>wp-config.php</code>'
1746 );
1747 }
1748
1749 /**
1750 * Whether option was changed.
1751 * Can be used only before option save to DB.
1752 *
1753 * @since 3.0.0
1754 *
1755 * @param string $new_value Submitted value (e.g from $_POST).
1756 * @param string $group Group key.
1757 * @param string $key Option key.
1758 *
1759 * @return bool
1760 */
1761 public function is_option_changed( $new_value, $group, $key ) {
1762
1763 $old_value = $this->get( $group, $key );
1764
1765 return $old_value !== $new_value;
1766 }
1767
1768 /**
1769 * Whether constant was changed.
1770 * Can be used only for insecure options.
1771 *
1772 * @since 3.0.0
1773 *
1774 * @param string $group Group key.
1775 * @param string $key Option key.
1776 *
1777 * @return bool
1778 */
1779 public function is_const_changed( $group, $key ) {
1780
1781 if ( ! $this->is_const_defined( $group, $key ) ) {
1782 return false;
1783 }
1784
1785 // Prevent double options update on multiple function call for same option.
1786 static $cache = [];
1787
1788 $cache_key = $group . '_' . $key;
1789
1790 if ( isset( $cache[ $cache_key ] ) ) {
1791 return $cache[ $cache_key ];
1792 }
1793
1794 $value = $this->get( $group, $key );
1795
1796 // Get old value from DB.
1797 add_filter( 'wp_mail_smtp_options_is_const_enabled', '__return_false', PHP_INT_MAX );
1798 $old_value = $this->get( $group, $key );
1799 remove_filter( 'wp_mail_smtp_options_is_const_enabled', '__return_false', PHP_INT_MAX );
1800
1801 $changed = $value !== $old_value;
1802
1803 // Save new constant value to DB.
1804 if ( $changed ) {
1805 $old_opt = $this->get_all_raw();
1806
1807 $old_opt[ $group ][ $key ] = $value;
1808 $this->set( $old_opt );
1809 }
1810
1811 $cache[ $cache_key ] = $changed;
1812
1813 return $changed;
1814 }
1815 }
1816