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