ruạṛ
<?php use FluentMail\App\Services\Mailer\Manager; use FluentMail\App\Services\Mailer\Providers\Factory; use FluentMail\App\Services\Mailer\Providers\AmazonSes\SimpleEmailService; if (!function_exists('fluentMail')) { function fluentMail($module = null) { return FluentMail\App\App::getInstance($module); } } if (!function_exists('fluentMailMix')) { function fluentMailMix($path, $manifestDirectory = '') { return fluentMail('url.assets') . ltrim($path, '/'); } } if (!function_exists('fluentMailAssetUrl')) { function fluentMailAssetUrl($path = null) { $assetUrl = fluentMail('url.assets'); return $path ? ($assetUrl . $path) : $assetUrl; } } if (!function_exists('fluentMailIsListedSenderEmail')) { function fluentMailIsListedSenderEmail($email) { static $settings; if (!$settings) { $settings = fluentMailGetSettings(); } if (!$settings) { return false; } return !empty($settings['mappings'][$email]); } } if (!function_exists('fluentMailDefaultConnection')) { function fluentMailDefaultConnection() { static $defaultConnection; if ($defaultConnection) { return $defaultConnection; } $settings = fluentMailGetSettings(); if (!$settings) { return []; } if ( isset($settings['misc']['default_connection']) && isset($settings['connections'][$settings['misc']['default_connection']]) ) { $default = $settings['misc']['default_connection']; $defaultConnection = $settings['connections'][$default]['provider_settings']; } else if (count($settings['connections'])) { $connection = reset($settings['connections']); $defaultConnection = $connection['provider_settings']; } else { $defaultConnection = []; } return $defaultConnection; } } if (!function_exists('fluentMailgetConnection')) { function fluentMailgetConnection($email) { $factory = fluentMail(Factory::class); if (!($connection = $factory->get($email))) { $connection = fluentMailDefaultConnection(); } return $connection; } } if (!function_exists('fluentMailGetProvider')) { function fluentMailGetProvider($fromEmail, $cacheClear = false) { static $providers = []; if (isset($providers[$fromEmail]) && !$cacheClear) { return $providers[$fromEmail]; } $manager = fluentMail(Manager::class); $misc = $manager->getSettings('misc'); if ((!empty($misc['simulate_emails']) && $misc['simulate_emails'] == 'yes') || (defined('FLUENTMAIL_SIMULATE_EMAILS') && FLUENTMAIL_SIMULATE_EMAILS)) { $providers[$fromEmail] = new FluentMail\App\Services\Mailer\Providers\Simulator\Handler(); return $providers[$fromEmail]; } $mappings = $manager->getSettings('mappings'); $connection = false; if (isset($mappings[$fromEmail])) { $connectionId = $mappings[$fromEmail]; $connections = $manager->getSettings('connections'); if (isset($connections[$connectionId])) { $connection = $connections[$connectionId]['provider_settings']; } } if (!$connection) { $connection = fluentMailDefaultConnection(); if ($connection && \FluentMail\Includes\Support\Arr::get($connection, 'force_from_email') != 'no') { $connection['force_from_email_id'] = $connection['sender_email']; } } if ($connection) { $factory = fluentMail(Factory::class); $driver = $factory->make($connection['provider']); $driver->setSettings($connection); $providers[$fromEmail] = $driver; } else { $providers[$fromEmail] = false; } return $providers[$fromEmail]; } } if (!function_exists('fluentMailSesConnection')) { function fluentMailSesConnection($connection) { static $drivers = []; if (isset($drivers[$connection['sender_email']])) { return $drivers[$connection['sender_email']]; } $region = 'email.' . $connection['region'] . '.amazonaws.com'; $ses = new SimpleEmailService( $connection['access_key'], $connection['secret_key'], $region, false ); $drivers[$connection['sender_email']] = $ses; return $drivers[$connection['sender_email']]; } } if (!function_exists('fluentMailSend')) { function fluentMailSend($to, $subject, $message, $headers = '', $attachments = array()) { // Compact the input, apply the filters, and extract them back out. /** * Filters the wp_mail() arguments. * * @param array $args A compacted array of wp_mail() arguments, including the "to" email, * subject, message, headers, and attachments values. * @since 2.2.0 * */ $atts = apply_filters( 'wp_mail', compact('to', 'subject', 'message', 'headers', 'attachments') ); /** * Filters whether to preempt sending an email. * * Returning a non-null value will short-circuit {@see wp_mail()}, returning * that value instead. A boolean return value should be used to indicate whether * the email was successfully sent. * * @param null|bool $return Short-circuit return value. * @param array $atts { * Array of the `wp_mail()` arguments. * * @type string|string[] $to Array or comma-separated list of email addresses to send message. * @type string $subject Email subject. * @type string $message Message contents. * @type string|string[] $headers Additional headers. * @type string|string[] $attachments Paths to files to attach. * } * @since 5.7.0 * */ $pre_wp_mail = apply_filters('pre_wp_mail', null, $atts); if (null !== $pre_wp_mail) { return $pre_wp_mail; } if (isset($atts['to'])) { $to = $atts['to']; } if (!is_array($to)) { $to = explode(',', $to); } if (isset($atts['subject'])) { $subject = $atts['subject']; } if (isset($atts['message'])) { $message = $atts['message']; } if (isset($atts['headers'])) { $headers = $atts['headers']; } if (isset($atts['attachments'])) { $attachments = $atts['attachments']; } if (!is_array($attachments)) { $attachments = explode("\n", str_replace("\r\n", "\n", $attachments)); } global $phpmailer; // (Re)create it, if it's gone missing. if (!($phpmailer instanceof PHPMailer\PHPMailer\PHPMailer)) { require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php'; require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php'; require_once ABSPATH . WPINC . '/PHPMailer/Exception.php'; $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true); $phpmailer::$validator = static function ($email) { return (bool)is_email($email); }; } // Headers. $cc = array(); $bcc = array(); $reply_to = array(); if (empty($headers)) { $headers = array(); } else { if (!is_array($headers)) { // Explode the headers out, so this function can take // both string headers and an array of headers. $tempheaders = explode("\n", str_replace("\r\n", "\n", $headers)); } else { $tempheaders = $headers; } $headers = array(); // If it's actually got contents. if (!empty($tempheaders)) { // Iterate through the raw headers. foreach ((array)$tempheaders as $header) { if (strpos($header, ':') === false) { if (false !== stripos($header, 'boundary=')) { $parts = preg_split('/boundary=/i', trim($header)); $boundary = trim(str_replace(array("'", '"'), '', $parts[1])); } continue; } // Explode them out. list($name, $content) = explode(':', trim($header), 2); // Cleanup crew. $name = trim($name); $content = trim($content); switch (strtolower($name)) { // Mainly for legacy -- process a "From:" header if it's there. case 'from': $bracket_pos = strpos($content, '<'); if (false !== $bracket_pos) { // Text before the bracketed email is the "From" name. if ($bracket_pos > 0) { $from_name = substr($content, 0, $bracket_pos - 1); $from_name = str_replace('"', '', $from_name); $from_name = trim($from_name); } $from_email = substr($content, $bracket_pos + 1); $from_email = str_replace('>', '', $from_email); $from_email = trim($from_email); // Avoid setting an empty $from_email. } elseif ('' !== trim($content)) { $from_email = trim($content); } break; case 'content-type': if (strpos($content, ';') !== false) { list($type, $charset_content) = explode(';', $content); $content_type = trim($type); if (false !== stripos($charset_content, 'charset=')) { $charset = trim(str_replace(array('charset=', '"'), '', $charset_content)); } elseif (false !== stripos($charset_content, 'boundary=')) { $boundary = trim(str_replace(array('BOUNDARY=', 'boundary=', '"'), '', $charset_content)); $charset = ''; } // Avoid setting an empty $content_type. } elseif ('' !== trim($content)) { $content_type = trim($content); } break; case 'cc': $cc = array_merge((array)$cc, explode(',', $content)); break; case 'bcc': $bcc = array_merge((array)$bcc, explode(',', $content)); break; case 'reply-to': $reply_to = array_merge((array)$reply_to, explode(',', $content)); break; default: // Add it to our grand headers array. $headers[trim($name)] = trim($content); break; } } } } // Empty out the values that may be set. $phpmailer->clearAllRecipients(); $phpmailer->clearAttachments(); $phpmailer->clearCustomHeaders(); $phpmailer->clearReplyTos(); $phpmailer->Body = ''; $phpmailer->AltBody = ''; /* * If we don't have an email from the input headers, default to wordpress@$sitename * Some hosts will block outgoing mail from this address if it doesn't exist, * but there's no easy alternative. Defaulting to admin_email might appear to be * another option, but some hosts may refuse to relay mail from an unknown domain. * See https://core.trac.wordpress.org/ticket/5007. */ $defaultConnection = false; if (!isset($from_email)) { $defaultConnection = fluentMailDefaultConnection(); if (!empty($defaultConnection['sender_email'])) { $from_email = $defaultConnection['sender_email']; } else { // Get the site domain and get rid of www. $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST); if ('www.' === substr($sitename, 0, 4)) { $sitename = substr($sitename, 4); } $from_email = 'wordpress@' . $sitename; } } // Set "From" name and email. // If we don't have a name from the input headers. if (!isset($from_name)) { if ($defaultConnection && !empty($defaultConnection['sender_name'])) { $from_name = $defaultConnection['sender_name']; } else { $provider = fluentMailGetProvider($from_email); if ($provider && !empty($provider->getSetting('sender_name'))) { $from_name = $provider->getSetting('sender_name'); } else { $from_name = 'WordPress'; } } } if (!apply_filters('fluentsmtp_disable_from_name_email', false)) { /** * Filters the email address to send from. * * @param string $from_email Email address to send from. * @since 2.2.0 * */ $from_email = apply_filters('wp_mail_from', $from_email); } /** * Filters the name to associate with the "from" email address. * * @param string $from_name Name associated with the "from" email address. * @since 2.3.0 * */ $from_name = apply_filters('wp_mail_from_name', $from_name); try { $phpmailer->setFrom($from_email, $from_name, false); } catch (PHPMailer\PHPMailer\Exception $e) { $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments'); $mail_error_data['phpmailer_exception_code'] = $e->getCode(); /** This filter is documented in wp-includes/pluggable.php */ do_action( 'wp_mail_failed', new WP_Error( 'wp_mail_failed', $e->getMessage(), $mail_error_data ) ); return false; } // Set mail's subject and body. $phpmailer->Subject = $subject; $phpmailer->Body = $message; // Set destination addresses, using appropriate methods for handling addresses. $address_headers = compact('to', 'cc', 'bcc', 'reply_to'); foreach ($address_headers as $address_header => $addresses) { if (empty($addresses)) { continue; } foreach ((array)$addresses as $address) { try { // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>". $recipient_name = ''; if (preg_match('/(.*)<(.+)>/', $address, $matches)) { if (count($matches) == 3) { $recipient_name = $matches[1]; $address = $matches[2]; } } switch ($address_header) { case 'to': $phpmailer->addAddress($address, $recipient_name); break; case 'cc': $phpmailer->addCc($address, $recipient_name); break; case 'bcc': $phpmailer->addBcc($address, $recipient_name); break; case 'reply_to': $phpmailer->addReplyTo($address, $recipient_name); break; } } catch (PHPMailer\PHPMailer\Exception $e) { continue; } } } // Set to use PHP's mail(). $phpmailer->isMail(); // Set Content-Type and charset. // If we don't have a content-type from the input headers. if (!isset($content_type)) { $content_type = 'text/plain'; } /** * Filters the wp_mail() content type. * * @param string $content_type Default wp_mail() content type. * @since 2.3.0 * */ $content_type = apply_filters('wp_mail_content_type', $content_type); $phpmailer->ContentType = $content_type; // Set whether it's plaintext, depending on $content_type. if ('text/html' === $content_type) { $phpmailer->isHTML(true); } // If we don't have a charset from the input headers. if (!isset($charset)) { $charset = get_bloginfo('charset'); } /** * Filters the default wp_mail() charset. * * @param string $charset Default email charset. * @since 2.3.0 * */ $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset); // Set custom headers. if (!empty($headers)) { foreach ((array)$headers as $name => $content) { // Only add custom headers not added automatically by PHPMailer. if (!in_array($name, array('MIME-Version', 'X-Mailer'), true)) { try { $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content)); } catch (PHPMailer\PHPMailer\Exception $e) { continue; } } } if (false !== stripos($content_type, 'multipart') && !empty($boundary)) { $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary)); } } if (!empty($attachments)) { foreach ($attachments as $attachment) { try { $phpmailer->addAttachment($attachment); } catch (PHPMailer\PHPMailer\Exception $e) { continue; } } } /** * Fires after PHPMailer is initialized. * * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference). * @since 2.2.0 * */ do_action_ref_array('phpmailer_init', array(&$phpmailer)); $mail_data = compact('to', 'subject', 'message', 'headers', 'attachments'); // Send! try { // Trap the fluentSMTPMail mailer here $phpmailer = new FluentMail\App\Services\Mailer\FluentPHPMailer($phpmailer); $send = $phpmailer->send(); do_action('wp_mail_succeeded', $mail_data); return $send; } catch (PHPMailer\PHPMailer\Exception $e) { $mail_data['phpmailer_exception_code'] = $e->getCode(); /** * Fires after a PHPMailer\PHPMailer\Exception is caught. * * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array * containing the mail recipient, subject, message, headers, and attachments. * @since 4.4.0 * */ do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_data)); return false; } } } if (!function_exists('fluentMailGetSettings')) { function fluentMailGetSettings($defaults = [], $cached = true) { static $cachedSettings; if ($cached && $cachedSettings) { return $cachedSettings; } $settings = get_option('fluentmail-settings'); if (!$settings) { return $defaults; } if (!empty($settings['use_encrypt'])) { $providerKeyMaps = [ 'smtp' => 'password', 'ses' => 'secret_key', 'mailgun' => 'api_key', 'sendgrid' => 'api_key', 'sendinblue' => 'api_key', 'sparkpost' => 'api_key', 'pepipost' => 'api_key', 'postmark' => 'api_key', 'elasticmail' => 'api_key', 'gmail' => 'client_secret', 'outlook' => 'client_secret', ]; if (!empty($settings['connections']) && is_array($settings['connections'])) { foreach ($settings['connections'] as $key => $connection) { $providerKey = $connection['provider_settings']['provider']; if (empty($providerKeyMaps[$providerKey])) { continue; } $secretFieldKey = $providerKeyMaps[$providerKey]; if (empty($connection['provider_settings'][$secretFieldKey])) { continue; } $settings['connections'][$key]['provider_settings'][$secretFieldKey] = fluentMailEncryptDecrypt($connection['provider_settings'][$secretFieldKey], 'd'); } } } $cachedSettings = $settings; return $settings; } } if (!function_exists('fluentMailSetSettings')) { function fluentMailSetSettings($settings) { $settings['use_encrypt'] = apply_filters('fluentsmtp_use_encrypt', 'yes'); $hasSecretField = false; if (!empty($settings['use_encrypt'])) { $providerKeyMaps = [ 'smtp' => 'password', 'ses' => 'secret_key', 'mailgun' => 'api_key', 'sendgrid' => 'api_key', 'sendinblue' => 'api_key', 'sparkpost' => 'api_key', 'pepipost' => 'api_key', 'postmark' => 'api_key', 'elasticmail' => 'api_key', 'gmail' => 'client_secret', 'outlook' => 'client_secret', ]; if (!empty($settings['connections']) && is_array($settings['connections'])) { foreach ($settings['connections'] as $key => $connection) { $providerKey = $connection['provider_settings']['provider']; if (empty($providerKeyMaps[$providerKey])) { continue; } $secretFieldKey = $providerKeyMaps[$providerKey]; if (empty($connection['provider_settings'][$secretFieldKey])) { continue; } $hasSecretField = true; $settings['connections'][$key]['provider_settings'][$secretFieldKey] = fluentMailEncryptDecrypt($connection['provider_settings'][$secretFieldKey], 'e'); } } } if ($hasSecretField) { $settings['test'] = fluentMailEncryptDecrypt('test', 'e'); } else { $settings['test'] = ''; $settings['use_encrypt'] = ''; } $result = update_option('fluentmail-settings', $settings); fluentMailGetSettings([], false); return $result; } } if (!function_exists('fluentMailEncryptDecrypt')) { function fluentMailEncryptDecrypt($value, $type = 'e') { if (!$value) { return $value; } if (!extension_loaded('openssl')) { return $value; } if (defined('FLUENTMAIL_ENCRYPT_SALT')) { $salt = FLUENTMAIL_ENCRYPT_SALT; } else { $salt = (defined('LOGGED_IN_SALT') && '' !== LOGGED_IN_SALT) ? LOGGED_IN_SALT : 'this-is-a-fallback-salt-but-not-secure'; } if (defined('FLUENTMAIL_ENCRYPT_KEY')) { $key = FLUENTMAIL_ENCRYPT_KEY; } else { $key = (defined('LOGGED_IN_KEY') && '' !== LOGGED_IN_KEY) ? LOGGED_IN_KEY : 'this-is-a-fallback-key-but-not-secure'; } if ($type == 'e') { $method = 'aes-256-ctr'; $ivlen = openssl_cipher_iv_length($method); $iv = openssl_random_pseudo_bytes($ivlen); $raw_value = openssl_encrypt($value . $salt, $method, $key, 0, $iv); if (!$raw_value) { return false; } return base64_encode($iv . $raw_value); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode } $raw_value = base64_decode($value, true); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode $method = 'aes-256-ctr'; $ivlen = openssl_cipher_iv_length($method); $iv = substr($raw_value, 0, $ivlen); $raw_value = substr($raw_value, $ivlen); $newValue = openssl_decrypt($raw_value, $method, $key, 0, $iv); if (!$newValue || substr($newValue, -strlen($salt)) !== $salt) { return false; } return substr($newValue, 0, -strlen($salt)); } } function fluentMailDb() { if (function_exists('FluentSmtpDb')) { return FluentSmtpDb(); } require_once(FLUENTMAIL_PLUGIN_PATH . 'app/Services/DB/wpfluent.php'); return FluentSmtpDb(); } function fluentMailFuncCouldNotBeLoadedRecheckPluginsLoad() { add_action('admin_notices', function () { if (!current_user_can('manage_options')) { return; } $details = new ReflectionFunction('wp_mail'); $hints = $details->getFileName() . ':' . $details->getStartLine(); ?> <div class="notice notice-warning fluentsmtp_urgent is-dismissible"> <p> <?php echo sprintf( __('The <strong>FluentSMTP</strong> plugin depends on <a target="_blank" href="%1s">wp_mail</a> pluggable function and plugin is not able to extend it. Please check if another plugin is using this and disable it for <strong>FluentSMTP</strong> to work!', 'fluent-smtp'), 'https://developer.wordpress.org/reference/functions/wp_mail/' ); ?> </p> <p style="color: red;"><?php _e('Possible Conflict: ', 'fluent-smtp'); ?><?php echo $hints; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></p> </div> <?php }); $activePlugins = get_option('active_plugins'); $index = array_search('fluent-smtp/fluent-smtp.php', $activePlugins); if ($index !== false) { if ($index === 0) { return; } unset($activePlugins[$index]); array_unshift($activePlugins, 'fluent-smtp/fluent-smtp.php'); update_option('active_plugins', $activePlugins, true); } }
cải xoăn