Plugin Directory

Changeset 3136968


Ignore:
Timestamp:
08/17/2024 08:26:17 AM (20 months ago)
Author:
omykhailenko
Message:

Updating trunk

Location:
mailgun/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • mailgun/trunk/CHANGELOG.md

    r3126570 r3136968  
    11Changelog
    22=========
     3
     42.1.1 (2024-08-17)
     5- Added fallback to regular mail in case or error during sending email vua API
    36
    472.1.0 (2024-07-27)
  • mailgun/trunk/includes/wp-mail-api.php

    r3126570 r3136968  
    450450
    451451        $endpoint = mg_api_get_region($region);
    452         $endpoint = ($endpoint) ? $endpoint : 'https://api.mailgun.net/v3/';
     452        $endpoint = ($endpoint) ?: 'https://api.mailgun.net/v3/';
    453453        $url = $endpoint . "{$domain}/messages";
    454454
    455         // TODO: Mailgun only supports 1000 recipients per request, since we are
    456         // overriding this function, let's add looping here to handle that
    457         $response = wp_remote_post($url, $data);
    458         if (is_wp_error($response)) {
    459             // Store WP error in last error.
    460             mg_api_last_error($response->get_error_message());
    461 
    462             return false;
    463         }
    464 
    465         $response_code = wp_remote_retrieve_response_code($response);
    466         $response_body = json_decode(wp_remote_retrieve_body($response));
    467 
    468         // Mailgun API should *always* return a `message` field, even when
    469         // $response_code != 200, so a lack of `message` indicates something
    470         // is broken.
    471         if ((int)$response_code != 200 || !isset($response_body->message)) {
    472             // Store response code and HTTP response message in last error.
    473             $response_message = wp_remote_retrieve_response_message($response);
    474             $errmsg = "$response_code - $response_message";
    475             mg_api_last_error($errmsg);
    476 
    477             return false;
    478         }
    479 
    480         // Not sure there is any additional checking that needs to be done here, but why not?
    481         if ($response_body->message !== 'Queued. Thank you.') {
    482             mg_api_last_error($response_body->message);
    483 
    484             return false;
     455        $isFallbackNeeded = false;
     456        try {
     457            $response = wp_remote_post($url, $data);
     458            if (is_wp_error($response)) {
     459                // Store WP error in last error.
     460                mg_api_last_error($response->get_error_message());
     461
     462                $isFallbackNeeded = true;
     463            }
     464
     465            $response_code = wp_remote_retrieve_response_code($response);
     466            $response_body = json_decode(wp_remote_retrieve_body($response));
     467
     468            if ((int)$response_code !== 200 || !isset($response_body->message)) {
     469                // Store response code and HTTP response message in last error.
     470                $response_message = wp_remote_retrieve_response_message($response);
     471                $errmsg = "$response_code - $response_message";
     472                mg_api_last_error($errmsg);
     473
     474                $isFallbackNeeded = true;
     475            }
     476            if ($response_body->message !== 'Queued. Thank you.') {
     477                mg_api_last_error($response_body->message);
     478
     479                $isFallbackNeeded = true;
     480            }
     481        } catch (Throwable $throwable) {
     482            $isFallbackNeeded = true;
     483        }
     484
     485        //Email Fallback
     486
     487        if ($isFallbackNeeded) {
     488            global $phpmailer;
     489
     490            // (Re)create it, if it's gone missing.
     491            if (!($phpmailer instanceof PHPMailer\PHPMailer\PHPMailer)) {
     492                require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
     493                require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
     494                require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
     495                $phpmailer = new PHPMailer\PHPMailer\PHPMailer(true);
     496
     497                $phpmailer::$validator = static function ($email) {
     498                    return (bool)is_email($email);
     499                };
     500            }
     501
     502            // Empty out the values that may be set.
     503            $phpmailer->clearAllRecipients();
     504            $phpmailer->clearAttachments();
     505            $phpmailer->clearCustomHeaders();
     506            $phpmailer->clearReplyTos();
     507            $phpmailer->Body = '';
     508            $phpmailer->AltBody = '';
     509
     510            // Set "From" name and email.
     511
     512            // If we don't have a name from the input headers.
     513            if (!isset($from_name)) {
     514                $from_name = 'WordPress';
     515            }
     516
     517            /*
     518             * If we don't have an email from the input headers, default to wordpress@$sitename
     519             * Some hosts will block outgoing mail from this address if it doesn't exist,
     520             * but there's no easy alternative. Defaulting to admin_email might appear to be
     521             * another option, but some hosts may refuse to relay mail from an unknown domain.
     522             * See https://core.trac.wordpress.org/ticket/5007.
     523             */
     524            if (!isset($from_email)) {
     525                // Get the site domain and get rid of www.
     526                $sitename = wp_parse_url(network_home_url(), PHP_URL_HOST);
     527                $from_email = 'wordpress@';
     528
     529                if (null !== $sitename) {
     530                    if (str_starts_with($sitename, 'www.')) {
     531                        $sitename = substr($sitename, 4);
     532                    }
     533
     534                    $from_email .= $sitename;
     535                }
     536            }
     537
     538            /**
     539             * Filters the email address to send from.
     540             * @param string $from_email Email address to send from.
     541             * @since 2.2.0
     542             */
     543            $from_email = apply_filters('wp_mail_from', $from_email);
     544
     545            /**
     546             * Filters the name to associate with the "from" email address.
     547             * @param string $from_name Name associated with the "from" email address.
     548             * @since 2.3.0
     549             */
     550            $from_name = apply_filters('wp_mail_from_name', $from_name);
     551
     552            try {
     553                $phpmailer->setFrom($from_email, $from_name, false);
     554            } catch (PHPMailer\PHPMailer\Exception $e) {
     555                $mail_error_data = compact('to', 'subject', 'message', 'headers', 'attachments');
     556                $mail_error_data['phpmailer_exception_code'] = $e->getCode();
     557
     558                /** This filter is documented in wp-includes/pluggable.php */
     559                do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_error_data));
     560
     561                return false;
     562            }
     563
     564            // Set mail's subject and body.
     565            $phpmailer->Subject = $subject;
     566            $phpmailer->Body = $message;
     567
     568            // Set destination addresses, using appropriate methods for handling addresses.
     569            $address_headers = compact('to', 'cc', 'bcc', 'replyTo');
     570
     571            foreach ($address_headers as $address_header => $addresses) {
     572                if (empty($addresses)) {
     573                    continue;
     574                }
     575
     576                foreach ((array)$addresses as $address) {
     577                    try {
     578                        // Break $recipient into name and address parts if in the format "Foo <bar@baz.com>".
     579                        $recipient_name = '';
     580
     581                        if (preg_match('/(.*)<(.+)>/', $address, $matches)) {
     582                            if (count($matches) === 3) {
     583                                $recipient_name = $matches[1];
     584                                $address = $matches[2];
     585                            }
     586                        }
     587
     588                        switch ($address_header) {
     589                            case 'to':
     590                                $phpmailer->addAddress($address, $recipient_name);
     591                                break;
     592                            case 'cc':
     593                                $phpmailer->addCc($address, $recipient_name);
     594                                break;
     595                            case 'bcc':
     596                                $phpmailer->addBcc($address, $recipient_name);
     597                                break;
     598                            case 'reply_to':
     599                                $phpmailer->addReplyTo($address, $recipient_name);
     600                                break;
     601                        }
     602                    } catch (PHPMailer\PHPMailer\Exception $e) {
     603                        continue;
     604                    }
     605                }
     606            }
     607
     608            // Set to use PHP's mail().
     609            $phpmailer->isMail();
     610
     611            // Set Content-Type and charset.
     612
     613            // If we don't have a Content-Type from the input headers.
     614            if (!isset($content_type)) {
     615                $content_type = 'text/plain';
     616            }
     617
     618            /**
     619             * Filters the wp_mail() content type.
     620             * @param string $content_type Default wp_mail() content type.
     621             * @since 2.3.0
     622             */
     623            $content_type = apply_filters('wp_mail_content_type', $content_type);
     624
     625            $phpmailer->ContentType = $content_type;
     626
     627            // Set whether it's plaintext, depending on $content_type.
     628            if ('text/html' === $content_type) {
     629                $phpmailer->isHTML(true);
     630            }
     631
     632            // If we don't have a charset from the input headers.
     633            if (!isset($charset)) {
     634                $charset = get_bloginfo('charset');
     635            }
     636
     637            /**
     638             * Filters the default wp_mail() charset.
     639             * @param string $charset Default email charset.
     640             * @since 2.3.0
     641             */
     642            $phpmailer->CharSet = apply_filters('wp_mail_charset', $charset);
     643
     644            // Set custom headers.
     645            if (!empty($headers)) {
     646                foreach ((array)$headers as $name => $content) {
     647                    // Only add custom headers not added automatically by PHPMailer.
     648                    if (!in_array($name, ['MIME-Version', 'X-Mailer'], true)) {
     649                        try {
     650                            $phpmailer->addCustomHeader(sprintf('%1$s: %2$s', $name, $content));
     651                        } catch (PHPMailer\PHPMailer\Exception $e) {
     652                            continue;
     653                        }
     654                    }
     655                }
     656
     657                if (false !== stripos($content_type, 'multipart') && !empty($boundary)) {
     658                    $phpmailer->addCustomHeader(sprintf('Content-Type: %s; boundary="%s"', $content_type, $boundary));
     659                }
     660            }
     661
     662            if (!empty($attachments)) {
     663                foreach ($attachments as $filename => $attachment) {
     664                    $filename = is_string($filename) ? $filename : '';
     665
     666                    try {
     667                        $phpmailer->addAttachment($attachment, $filename);
     668                    } catch (PHPMailer\PHPMailer\Exception $e) {
     669                        continue;
     670                    }
     671                }
     672            }
     673
     674            /**
     675             * Fires after PHPMailer is initialized.
     676             * @param PHPMailer $phpmailer The PHPMailer instance (passed by reference).
     677             * @since 2.2.0
     678             */
     679            do_action_ref_array('phpmailer_init', [&$phpmailer]);
     680
     681            $mail_data = compact('to', 'subject', 'message', 'headers', 'attachments');
     682
     683            // Send!
     684            try {
     685                $send = $phpmailer->send();
     686
     687                /**
     688                 * Fires after PHPMailer has successfully sent an email.
     689                 * The firing of this action does not necessarily mean that the recipient(s) received the
     690                 * email successfully. It only means that the `send` method above was able to
     691                 * process the request without any errors.
     692                 * @param array $mail_data {
     693                 *     An array containing the email recipient(s), subject, message, headers, and attachments.
     694                 * @type string[] $to Email addresses to send message.
     695                 * @type string $subject Email subject.
     696                 * @type string $message Message contents.
     697                 * @type string[] $headers Additional headers.
     698                 * @type string[] $attachments Paths to files to attach.
     699                 * }
     700                 * @since 5.9.0
     701                 */
     702                do_action('wp_mail_succeeded', $mail_data);
     703
     704                return $send;
     705            } catch (PHPMailer\PHPMailer\Exception $e) {
     706                $mail_data['phpmailer_exception_code'] = $e->getCode();
     707
     708                /**
     709                 * Fires after a PHPMailer\PHPMailer\Exception is caught.
     710                 * @param WP_Error $error A WP_Error object with the PHPMailer\PHPMailer\Exception message, and an array
     711                 *                        containing the mail recipient, subject, message, headers, and attachments.
     712                 * @since 4.4.0
     713                 */
     714                do_action('wp_mail_failed', new WP_Error('wp_mail_failed', $e->getMessage(), $mail_data));
     715
     716                return false;
     717            }
    485718        }
    486719
  • mailgun/trunk/includes/wp-mail-smtp.php

    r2777895 r3136968  
    8181        mg_smtp_last_error($error->get_error_message());
    8282    } else {
    83         mg_smtp_last_error($error->__toString());
     83        if (method_exists($error, '__toString')) {
     84            mg_smtp_last_error($error->__toString());
     85        }
    8486    }
    8587}
  • mailgun/trunk/mailgun.php

    r3126570 r3136968  
    44 * Plugin URI:   http://wordpress.org/extend/plugins/mailgun/
    55 * Description:  Mailgun integration for WordPress
    6  * Version:      2.1.0
     6 * Version:      2.1.1
    77 * Requires PHP: 7.4
    88 * Requires at least: 4.4
     
    8787                    $this->deactivate_and_die(__DIR__ . '/includes/wp-mail-api.php');
    8888                }
     89            }
     90
     91            if (!function_exists('mg_api_get_region') && !in_array(__DIR__ . '/includes/mg-api.php', get_included_files())) {
     92                include __DIR__ . '/includes/mg-api.php';
    8993            }
    9094        } else {
  • mailgun/trunk/readme.md

    r3126570 r3136968  
    55Tags: mailgun, smtp, http, api, mail, email
    66Tested up to: 6.6.1
    7 Stable tag: 2.1.0
     7Stable tag: 2.1.1
    88License: GPLv2 or later
    99
     
    133133== Changelog ==
    134134
     135= 2.1.1 (2024-08-17): =
     136- Added fallback to regular mail in case or error during sending email vua API
     137
    135138= 2.1.0 (2024-07-27): =
    136139- Added ability to suppress Track Clicks when we send Reset Password email (it was an issue with domain url in the email)
  • mailgun/trunk/readme.txt

    r3126570 r3136968  
    1271276. Subscription Form Seen By Site Visitors
    128128
    129 
    130129== Changelog ==
     130
     131= 2.1.1 (2024-08-17): =
     132- Added fallback to regular mail in case or error during sending email vua API
    131133
    132134= 2.1.0 (2024-07-27): =
Note: See TracChangeset for help on using the changeset viewer.