function wptuts_register_pointer_testing($p)
 {
     // only do this for administrators
     if (PostmanUtils::isAdmin()) {
         $p['postman16_log'] = array('target' => '.configure_manually', 'options' => array('content' => sprintf('<h3> %s </h3> <p> %s </p>', __('New for v1.6! Email Log', 'postman-smtp'), __('Enable to save a copy of all your emails. Great for troubleshooting or as a backup for messages that get lost. <b>Access the Email Log in the Tools menu.</b>', 'postman-smtp')), 'position' => array('edge' => 'top', 'align' => 'left')));
         return $p;
     }
 }
 function wptuts_register_pointer_testing($p)
 {
     // only do this for administrators
     if (PostmanUtils::isAdmin() && false) {
         $p['postman16_log'] = array('target' => '.configure_manually', 'options' => array('content' => '', 'position' => array('edge' => 'top', 'align' => 'left')));
         return $p;
     }
 }
function check($ipAddress, $expectedresult)
{
    $result = PostmanUtils::isHostAddressNotADomainName($ipAddress);
    $displaySuccess = 'fail';
    if ($result == $expectedresult) {
        $displaySuccess = 'pass';
    }
    print sprintf("%s: %s=%s\n", $displaySuccess, $ipAddress, $result);
}
 /**
  * Validate the email address
  *
  * @throws Exception
  */
 public function validate()
 {
     if (!PostmanUtils::validateEmail($this->email)) {
         $message = 'Invalid e-mail address: ' . $this->email;
         $logger = new PostmanLogger(get_class($this));
         $logger->warn($message);
         throw new Exception($message);
     }
 }
 /**
  * Validate the email address
  *
  * @throws Exception
  */
 public function validate($desc = '')
 {
     if (!PostmanUtils::validateEmail($this->email)) {
         if (empty($desc)) {
             /* Translators: Where %s is the email address */
             $message = sprintf('Invalid e-mail address "%s"', $this->email);
         } else {
             /* Translators: Where (1) is the header name (eg. To) and (2) is the email address */
             $message = sprintf('Invalid "%1$s" e-mail address "%2$s"', $desc, $this->email);
         }
         $logger = new PostmanLogger(get_class($this));
         $logger->warn($message);
         throw new Exception($message);
     }
 }
 /**
  * **********************************************
  * If we have a code back from the OAuth 2.0 flow,
  * we need to exchange that for an access token.
  * We store the resultant access token
  * bundle in the session, and redirect to ourself.
  * **********************************************
  */
 public function processAuthorizationGrantCode($transactionId)
 {
     if (isset($_GET['code'])) {
         $code = $_GET['code'];
         $this->getLogger()->debug('Found authorization code in request header');
         $postvals = array('client_id' => $this->getClientId(), 'client_secret' => $this->getClientSecret(), 'grant_type' => 'authorization_code', 'redirect_uri' => $this->getCallbackUri(), 'code' => $code);
         $response = PostmanUtils::remotePostGetBodyOnly($this->getTokenUrl(), $postvals);
         $this->processResponse($response);
         $this->getAuthorizationToken()->setVendorName(self::VENDOR_NAME);
         return true;
     } else {
         $this->getLogger()->debug('Expected code in the request header but found none - user probably denied request');
         return false;
     }
 }
 /**
  * Register and add settings
  */
 private function registerSettings()
 {
     // only administrators should be able to trigger this
     if (PostmanUtils::isAdmin()) {
         //
         $sanitizer = new PostmanInputSanitizer();
         register_setting(PostmanAdminController::SETTINGS_GROUP_NAME, PostmanOptions::POSTMAN_OPTIONS, array($sanitizer, 'sanitize'));
         // Sanitize
         add_settings_section('transport_section', __('Transport', Postman::TEXT_DOMAIN), array($this, 'printTransportSectionInfo'), 'transport_options');
         add_settings_field(PostmanOptions::TRANSPORT_TYPE, _x('Type', '(i.e.) What kind is it?', Postman::TEXT_DOMAIN), array($this, 'transport_type_callback'), 'transport_options', 'transport_section');
         // the Message From section
         add_settings_section(PostmanAdminController::MESSAGE_FROM_SECTION, _x('From Address', 'The Message Sender Email Address', Postman::TEXT_DOMAIN), array($this, 'printMessageFromSectionInfo'), PostmanAdminController::MESSAGE_FROM_OPTIONS);
         add_settings_field(PostmanOptions::MESSAGE_SENDER_EMAIL, __('Email Address', Postman::TEXT_DOMAIN), array($this, 'from_email_callback'), PostmanAdminController::MESSAGE_FROM_OPTIONS, PostmanAdminController::MESSAGE_FROM_SECTION);
         add_settings_field(PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE, '', array($this, 'prevent_from_email_override_callback'), PostmanAdminController::MESSAGE_FROM_OPTIONS, PostmanAdminController::MESSAGE_FROM_SECTION);
         add_settings_field(PostmanOptions::MESSAGE_SENDER_NAME, __('Name', Postman::TEXT_DOMAIN), array($this, 'sender_name_callback'), PostmanAdminController::MESSAGE_FROM_OPTIONS, PostmanAdminController::MESSAGE_FROM_SECTION);
         add_settings_field(PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE, '', array($this, 'prevent_from_name_override_callback'), PostmanAdminController::MESSAGE_FROM_OPTIONS, PostmanAdminController::MESSAGE_FROM_SECTION);
         // the Additional Addresses section
         add_settings_section(PostmanAdminController::MESSAGE_SECTION, __('Additional Email Addresses', Postman::TEXT_DOMAIN), array($this, 'printMessageSectionInfo'), PostmanAdminController::MESSAGE_OPTIONS);
         add_settings_field(PostmanOptions::REPLY_TO, __('Reply-To', Postman::TEXT_DOMAIN), array($this, 'reply_to_callback'), PostmanAdminController::MESSAGE_OPTIONS, PostmanAdminController::MESSAGE_SECTION);
         add_settings_field(PostmanOptions::FORCED_TO_RECIPIENTS, __('To Recipient(s)', Postman::TEXT_DOMAIN), array($this, 'to_callback'), PostmanAdminController::MESSAGE_OPTIONS, PostmanAdminController::MESSAGE_SECTION);
         add_settings_field(PostmanOptions::FORCED_CC_RECIPIENTS, __('Carbon Copy Recipient(s)', Postman::TEXT_DOMAIN), array($this, 'cc_callback'), PostmanAdminController::MESSAGE_OPTIONS, PostmanAdminController::MESSAGE_SECTION);
         add_settings_field(PostmanOptions::FORCED_BCC_RECIPIENTS, __('Blind Carbon Copy Recipient(s)', Postman::TEXT_DOMAIN), array($this, 'bcc_callback'), PostmanAdminController::MESSAGE_OPTIONS, PostmanAdminController::MESSAGE_SECTION);
         // the Additional Headers section
         add_settings_section(PostmanAdminController::MESSAGE_HEADERS_SECTION, __('Additional Headers', Postman::TEXT_DOMAIN), array($this, 'printAdditionalHeadersSectionInfo'), PostmanAdminController::MESSAGE_HEADERS_OPTIONS);
         add_settings_field(PostmanOptions::ADDITIONAL_HEADERS, __('Custom Headers', Postman::TEXT_DOMAIN), array($this, 'headers_callback'), PostmanAdminController::MESSAGE_HEADERS_OPTIONS, PostmanAdminController::MESSAGE_HEADERS_SECTION);
         // the Email Validation section
         add_settings_section(PostmanAdminController::EMAIL_VALIDATION_SECTION, __('Validation', Postman::TEXT_DOMAIN), array($this, 'printEmailValidationSectionInfo'), PostmanAdminController::EMAIL_VALIDATION_OPTIONS);
         add_settings_field(PostmanOptions::ENVELOPE_SENDER, __('Email Address', Postman::TEXT_DOMAIN), array($this, 'disable_email_validation_callback'), PostmanAdminController::EMAIL_VALIDATION_OPTIONS, PostmanAdminController::EMAIL_VALIDATION_SECTION);
         // the Logging section
         add_settings_section(PostmanAdminController::LOGGING_SECTION, __('Email Log Settings', Postman::TEXT_DOMAIN), array($this, 'printLoggingSectionInfo'), PostmanAdminController::LOGGING_OPTIONS);
         add_settings_field('logging_status', __('Enable Logging', Postman::TEXT_DOMAIN), array($this, 'loggingStatusInputField'), PostmanAdminController::LOGGING_OPTIONS, PostmanAdminController::LOGGING_SECTION);
         add_settings_field('logging_max_entries', __('Maximum Log Entries', 'Configuration Input Field', Postman::TEXT_DOMAIN), array($this, 'loggingMaxEntriesInputField'), PostmanAdminController::LOGGING_OPTIONS, PostmanAdminController::LOGGING_SECTION);
         add_settings_field(PostmanOptions::TRANSCRIPT_SIZE, __('Maximum Transcript Size', Postman::TEXT_DOMAIN), array($this, 'transcriptSizeInputField'), PostmanAdminController::LOGGING_OPTIONS, PostmanAdminController::LOGGING_SECTION);
         // the Network section
         add_settings_section(PostmanAdminController::NETWORK_SECTION, __('Network Settings', Postman::TEXT_DOMAIN), array($this, 'printNetworkSectionInfo'), PostmanAdminController::NETWORK_OPTIONS);
         add_settings_field('connection_timeout', _x('TCP Connection Timeout (sec)', 'Configuration Input Field', Postman::TEXT_DOMAIN), array($this, 'connection_timeout_callback'), PostmanAdminController::NETWORK_OPTIONS, PostmanAdminController::NETWORK_SECTION);
         add_settings_field('read_timeout', _x('TCP Read Timeout (sec)', 'Configuration Input Field', Postman::TEXT_DOMAIN), array($this, 'read_timeout_callback'), PostmanAdminController::NETWORK_OPTIONS, PostmanAdminController::NETWORK_SECTION);
         // the Advanced section
         add_settings_section(PostmanAdminController::ADVANCED_SECTION, _x('Miscellaneous Settings', 'Configuration Section Title', Postman::TEXT_DOMAIN), array($this, 'printAdvancedSectionInfo'), PostmanAdminController::ADVANCED_OPTIONS);
         add_settings_field(PostmanOptions::LOG_LEVEL, _x('PHP Log Level', 'Configuration Input Field', Postman::TEXT_DOMAIN), array($this, 'log_level_callback'), PostmanAdminController::ADVANCED_OPTIONS, PostmanAdminController::ADVANCED_SECTION);
         add_settings_field(PostmanOptions::RUN_MODE, _x('Delivery Mode', 'Configuration Input Field', Postman::TEXT_DOMAIN), array($this, 'runModeCallback'), PostmanAdminController::ADVANCED_OPTIONS, PostmanAdminController::ADVANCED_SECTION);
         add_settings_field(PostmanOptions::STEALTH_MODE, _x('Stealth Mode', 'This mode removes the Postman X-Mailer signature from emails', Postman::TEXT_DOMAIN), array($this, 'stealthModeCallback'), PostmanAdminController::ADVANCED_OPTIONS, PostmanAdminController::ADVANCED_SECTION);
         add_settings_field(PostmanOptions::TEMPORARY_DIRECTORY, __('Temporary Directory', Postman::TEXT_DOMAIN), array($this, 'temporaryDirectoryCallback'), PostmanAdminController::ADVANCED_OPTIONS, PostmanAdminController::ADVANCED_SECTION);
     }
 }
 /**
  * After receiving the authorization code, your application can exchange the code
  * (along with a client ID and client secret) for an access token and, in some cases,
  * a refresh token.
  *
  * This code is identical for Google and Hotmail
  *
  * @see PostmanAuthenticationManager::processAuthorizationGrantCode()
  */
 public function processAuthorizationGrantCode($transactionId)
 {
     if (isset($_GET['code'])) {
         $this->getLogger()->debug('Found authorization code in request header');
         $code = $_GET['code'];
         if (isset($_GET['state']) && $_GET['state'] == $transactionId) {
             $this->getLogger()->debug('Found valid state in request header');
         } else {
             $this->getLogger()->error('The grant code from Google had no accompanying state and may be a forgery');
             throw new PostmanStateIdMissingException();
         }
         $postvals = array('client_id' => $this->getClientId(), 'client_secret' => $this->getClientSecret(), 'grant_type' => 'authorization_code', 'redirect_uri' => $this->getCallbackUri(), 'code' => $code);
         $response = PostmanUtils::remotePostGetBodyOnly($this->getTokenUrl(), $postvals);
         $this->processResponse($response);
         $this->getAuthorizationToken()->setVendorName(self::VENDOR_NAME);
         return true;
     } else {
         $this->getLogger()->debug('Expected code in the request header but found none - user probably denied request');
         return false;
     }
 }
 /**
  *
  * @param unknown $queryHostData        	
  */
 function __construct($queryHostData)
 {
     $this->hostname = $queryHostData['hostname'];
     $this->hostnameDomainOnly = $queryHostData['hostname_domain_only'];
     $this->port = $queryHostData['port'];
     $this->protocol = $queryHostData['protocol'];
     $this->secure = PostmanUtils::parseBoolean($queryHostData['secure']);
     $this->mitm = PostmanUtils::parseBoolean($queryHostData['mitm']);
     $this->reportedHostname = $queryHostData['reported_hostname'];
     $this->reportedHostnameDomainOnly = $queryHostData['reported_hostname_domain_only'];
     $this->message = $queryHostData['message'];
     $this->startTls = PostmanUtils::parseBoolean($queryHostData['start_tls']);
     $this->authPlain = PostmanUtils::parseBoolean($queryHostData['auth_plain']);
     $this->auth_login = PostmanUtils::parseBoolean($queryHostData['auth_login']);
     $this->auth_crammd5 = PostmanUtils::parseBoolean($queryHostData['auth_crammd5']);
     $this->auth_xoauth = PostmanUtils::parseBoolean($queryHostData['auth_xoauth']);
     $this->auth_none = PostmanUtils::parseBoolean($queryHostData['auth_none']);
     $this->try_smtps = PostmanUtils::parseBoolean($queryHostData['try_smtps']);
     $this->success = PostmanUtils::parseBoolean($queryHostData['success']);
     $this->transport = $queryHostData['transport'];
     assert(!empty($this->transport));
     $this->id = sprintf('%s_%s', $this->hostname, $this->port);
 }
 /**
  * Functions to execute on the admin_init event
  *
  * "Runs at the beginning of every admin page before the page is rendered."
  * ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_an_Admin_Page_Request
  */
 public function on_admin_init()
 {
     // only administrators should be able to trigger this
     if (PostmanUtils::isAdmin()) {
         $this->registerStylesAndScripts();
     }
 }
 /**
  *
  * @param unknown $email        	
  * @return Ambigous <number, boolean>
  */
 private function validateEmail($email)
 {
     return PostmanUtils::validateEmail($email);
 }
Example #12
0
/**
 * Create the main Postman class to start Postman
 */
function postman_start($startingMemory)
{
    postman_setupPostman();
    PostmanUtils::logMemoryUse($startingMemory, 'Postman');
}
 /**
  * Get the settings option array and print one of its values
  */
 public function basic_auth_password_callback()
 {
     print '<input tabindex="99" id="fake_password" name="fake[password]" style="position:absolute; top:-500px;" type="password" value="Safari Autofill Me">';
     printf('<input type="password" id="input_basic_auth_password" name="postman_options[basic_auth_password]" value="%s" size="40" class="required" placeholder="Required"/>', null !== $this->options->getPassword() ? esc_attr(PostmanUtils::obfuscatePassword($this->options->getPassword())) : '');
     print ' <input type="button" id="togglePasswordField" value="Show Password" class="button button-secondary" style="visibility:hidden" />';
 }
 /**
  * This Ajax function retrieves whether a TCP port is open or not
  */
 function runSmtpsTest()
 {
     $hostname = trim(PostmanUtils::getRequestParameter('hostname'));
     $port = intval(PostmanUtils::getRequestParameter('port'));
     $transport = trim(PostmanUtils::getRequestParameter('transport'));
     $transportName = trim(PostmanUtils::getRequestParameter('transport_name'));
     $this->logger->debug(sprintf('testing SMTPS socket %s:%s (%s)', $hostname, $port, $transport));
     $portTest = new PostmanPortTest($hostname, $port);
     $portTest->transportName = $transportName;
     $success = $portTest->testSmtpsPorts();
     $this->buildResponse($hostname, $port, $portTest, $success, $transport);
 }
Example #15
0
 /**
  * Given a hostname, test if it has open ports
  *
  * @param string $hostname        	
  */
 private function talkToMailServer($connectionString)
 {
     $this->logger->trace('talkToMailServer()');
     $stream = $this->createStream($connectionString, $this->connectionTimeout);
     if ($stream) {
         $serverName = PostmanUtils::postmanGetServerName();
         @stream_set_timeout($stream, $this->readTimeout);
         // see http://php.net/manual/en/transports.inet.php#113244
         // see http://php.net/stream_socket_enable_crypto
         $result = $this->readSmtpResponse($stream);
         if ($result) {
             $this->reportedHostname = $result;
             $this->reportedHostnameDomainOnly = $this->getRegisteredDomain($this->reportedHostname);
             $this->logger->trace(sprintf('comparing %s with %s', $this->reportedHostnameDomainOnly, $this->hostnameDomainOnly));
             $this->mitm = true;
             // MITM exceptions
             if ($this->reportedHostnameDomainOnly == 'google.com' && $this->hostnameDomainOnly == 'gmail.com') {
                 $this->mitm = false;
             } elseif ($this->reportedHostnameDomainOnly == 'hotmail.com' && $this->hostnameDomainOnly == 'live.com') {
                 $this->mitm = false;
             } elseif ($this->reportedHostnameDomainOnly == $this->hostnameDomainOnly) {
                 $this->mitm = false;
             }
             $this->debug(sprintf('domain name: %s (%s)', $this->reportedHostname, $this->reportedHostnameDomainOnly));
             $this->sendSmtpCommand($stream, sprintf('EHLO %s', $serverName));
             $this->readSmtpResponse($stream);
             if ($this->checkStartTls) {
                 $this->sendSmtpCommand($stream, 'STARTTLS');
                 $this->readSmtpResponse($stream);
                 $starttlsSuccess = @stream_socket_enable_crypto($stream, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
                 if ($starttlsSuccess) {
                     $this->startTls = true;
                     $this->secure = true;
                     $this->sendSmtpCommand($stream, sprintf('EHLO %s', $serverName));
                     $this->readSmtpResponse($stream);
                 } else {
                     $this->error('starttls failed');
                 }
             }
             fclose($stream);
             $this->debug('return true');
             return true;
         } else {
             fclose($stream);
             $this->debug('return false');
             return false;
         }
     } else {
         return false;
     }
 }
 /**
  * Step 5: Exchange refresh token for new access token
  * After the access token expires, you can use the refresh token, which has a long lifetime, to get a new access token.
  */
 public function refreshToken()
 {
     $this->getLogger()->debug('Refreshing Token');
     $refreshUrl = $this->getTokenUrl();
     $callbackUrl = $this->getCallbackUri();
     assert(!empty($refreshUrl));
     assert(!empty($callbackUrl));
     $headers = array('Authorization' => sprintf("Basic %s", base64_encode($this->getClientId() . ':' . $this->getClientSecret())));
     $postvals = array('redirect_uri' => $callbackUrl, 'grant_type' => 'refresh_token', 'refresh_token' => $this->getAuthorizationToken()->getRefreshToken());
     $response = PostmanUtils::remotePostGetBodyOnly($this->getTokenUrl(), $postvals, $headers);
     $this->processResponse($response);
 }
 /**
  */
 public function mandrill_api_key_callback()
 {
     printf('<input type="password" autocomplete="off" id="mandrill_api_key" name="postman_options[mandrill_api_key]" value="%s" size="60" class="required" placeholder="%s"/>', null !== $this->options->getMandrillApiKey() ? esc_attr(PostmanUtils::obfuscatePassword($this->options->getMandrillApiKey())) : '', __('Required', Postman::TEXT_DOMAIN));
     print ' <input type="button" id="toggleMandrillApiKey" value="Show Password" class="button button-secondary" style="visibility:hidden" />';
 }
Example #18
0
 /**
  * This is the general message that Postman requires configuration, to warn users who think
  * the plugin is ready-to-go as soon as it is activated.
  * This message only goes away once
  * the plugin is configured.
  */
 public function display_configuration_required_warning()
 {
     $this->logger->debug('Displaying configuration required warning');
     $message = sprintf(__('WordPress is still handling email delivery, <em>not</em> Postman.', 'postman-smtp'));
     $message .= ' ';
     /* translators: where %s is the URL to the Postman Setup page */
     $message .= sprintf(__('<a href="%s">Configure</a> the plugin.', 'postman-smtp'), PostmanUtils::getSettingsPageUrl());
     $this->messageHandler->printMessage($message, PostmanMessageHandler::WARNING_CLASS);
 }
 /**
  * Constructor
  *
  * @param PostmanOptions $options        	
  */
 function __construct()
 {
     $this->options = PostmanOptions::getInstance();
     $this->authorizationToken = PostmanOAuthToken::getInstance();
     $this->diagnostics = '';
     PostmanUtils::registerAjaxHandler('postman_diagnostics', $this, 'getDiagnostics');
 }
 /**
  * Handles the authorization grant
  */
 function handleAuthorizationGrant()
 {
     $logger = $this->logger;
     $options = $this->options;
     $authorizationToken = $this->authorizationToken;
     $logger->debug('Authorization in progress');
     $transactionId = PostmanSession::getInstance()->getOauthInProgress();
     // begin transaction
     PostmanUtils::lock();
     $authenticationManager = PostmanAuthenticationManagerFactory::getInstance()->createAuthenticationManager();
     try {
         if ($authenticationManager->processAuthorizationGrantCode($transactionId)) {
             $logger->debug('Authorization successful');
             // save to database
             $authorizationToken->save();
             $this->messageHandler->addMessage(__('The OAuth 2.0 authorization was successful. Ready to send e-mail.', Postman::TEXT_DOMAIN));
         } else {
             $this->messageHandler->addError(__('Your email provider did not grant Postman permission. Try again.', Postman::TEXT_DOMAIN));
         }
     } catch (PostmanStateIdMissingException $e) {
         $this->messageHandler->addError(__('The grant code from Google had no accompanying state and may be a forgery', Postman::TEXT_DOMAIN));
     } catch (Exception $e) {
         $logger->error('Error: ' . get_class($e) . ' code=' . $e->getCode() . ' message=' . $e->getMessage());
         /* translators: %s is the error message */
         $this->messageHandler->addError(sprintf(__('Error authenticating with this Client ID. [%s]', Postman::TEXT_DOMAIN), '<em>' . $e->getMessage() . '</em>'));
     }
     // clean-up
     PostmanUtils::unlock();
     PostmanSession::getInstance()->unsetOauthInProgress();
     // redirect home
     PostmanUtils::redirect(PostmanUtils::POSTMAN_HOME_PAGE_RELATIVE_URL);
 }
Example #21
0
 /**
  * This is the general message that Postman requires configuration, to warn users who think
  * the plugin is ready-to-go as soon as it is activated.
  * This message only goes away once the plugin is configured.
  */
 public function display_configuration_required_warning()
 {
     if (PostmanUtils::isAdmin()) {
         if ($this->logger->isDebug()) {
             $this->logger->debug('Displaying configuration required warning');
         }
         $message = sprintf(PostmanTransportRegistry::getInstance()->getReadyMessage());
         $goToSettings = sprintf('<a href="%s">%s</a>', PostmanUtils::getSettingsPageUrl(), __('Settings', Postman::TEXT_DOMAIN));
         $goToEmailLog = sprintf('%s', _x('Email Log', 'The log of Emails that have been delivered', Postman::TEXT_DOMAIN));
         if (PostmanOptions::getInstance()->isMailLoggingEnabled()) {
             $goToEmailLog = sprintf('<a href="%s">%s</a>', PostmanUtils::getEmailLogPageUrl(), $goToEmailLog);
         }
         $message .= sprintf(' %s | %s', $goToEmailLog, $goToSettings);
         $this->messageHandler->printMessage($message, PostmanMessageHandler::WARNING_CLASS);
     }
 }
Example #22
0
 /**
  * Handle activation of plugin
  */
 private function handleOptionUpdates()
 {
     $this->logger->debug("Activating plugin");
     // prior to version 0.2.5, $authOptions did not exist
     $authOptions = get_option('postman_auth_token');
     $options = get_option('postman_options');
     $postmanState = get_option('postman_state');
     if (empty($authOptions) && !empty($options) && !empty($options['access_token'])) {
         $this->logger->debug("Upgrading database: copying Authorization token from postman_options to postman_auth_token");
         // copy the variables from $options to $authToken
         $authOptions['access_token'] = $options['access_token'];
         $authOptions['refresh_token'] = $options['refresh_token'];
         // there was a bug where we weren't setting the expiry time
         if (!empty($options['auth_token_expires'])) {
             $authOptions['auth_token_expires'] = $options['auth_token_expires'];
         }
         update_option('postman_auth_token', $authOptions);
     }
     if (!isset($options['authorization_type']) && !isset($options['auth_type'])) {
         // prior to 1.0.0, access tokens were saved in authOptions without an auth type
         // prior to 0.2.5, access tokens were save in options without an auth type
         // either way, only oauth2 was supported
         if (isset($authOptions['access_token']) || isset($options['access_token'])) {
             $this->logger->debug("Upgrading database: setting authorization_type to 'oauth2'");
             $options['authorization_type'] = 'oauth2';
             update_option('postman_options', $options);
         }
     }
     if (!isset($options['enc_type'])) {
         // prior to 1.3, encryption type was combined with authentication type
         if (isset($options['authorization_type'])) {
             $this->logger->debug("Upgrading database: creating auth_type and enc_type from authorization_type");
             $authType = $options['authorization_type'];
             switch ($authType) {
                 case 'none':
                     $options['auth_type'] = 'none';
                     $options['enc_type'] = 'none';
                     break;
                 case 'basic-ssl':
                     $options['auth_type'] = 'login';
                     $options['enc_type'] = 'ssl';
                     break;
                 case 'basic-tls':
                     $options['auth_type'] = 'login';
                     $options['enc_type'] = 'tls';
                     break;
                 case 'oauth2':
                     $options['auth_type'] = 'oauth2';
                     $options['enc_type'] = 'ssl';
                     break;
                 default:
             }
             update_option('postman_options', $options);
         }
     }
     // prior to 1.3.3, the version identifier was not stored and the passwords were plaintext
     if (isset($options['enc_type']) && !(isset($options['version']) || isset($postmanState['version']))) {
         $this->logger->debug("Upgrading database: added plugin version and encoding password");
         $options['version'] = '1.3.3';
         if (isset($options['basic_auth_password'])) {
             $options['basic_auth_password'] = base64_encode($options['basic_auth_password']);
         }
         update_option('postman_options', $options);
     }
     // prior to 1.4.2, the transport was not identified and the auth token had no vendor
     if (isset($options['auth_type']) && !isset($options['transport_type'])) {
         $this->logger->debug("Upgrading database: added transport_type and vendor_name");
         $options['transport_type'] = 'smtp';
         update_option('postman_options', $options);
         if (isset($authOptions['access_token']) && isset($options['oauth_client_id'])) {
             // if there is a stored token..
             if (PostmanUtils::endsWith($options['oauth_client_id'], 'googleusercontent.com')) {
                 $authOptions['vendor_name'] = 'google';
             } else {
                 if (strlen($options['oauth_client_id'] < strlen($options['oauth_client_secret']))) {
                     $authOptions['vendor_name'] = 'microsoft';
                 } else {
                     $authOptions['vendor_name'] = 'yahoo';
                 }
             }
             update_option('postman_auth_token', $authOptions);
         }
     }
     // for version 1.6.18, the envelope from was introduced
     if (!empty($options['sender_email']) && empty($options['envelope_sender'])) {
         $this->logger->debug("Upgrading database: adding envelope_sender");
         $options['envelope_sender'] = $options['sender_email'];
         update_option('postman_options', $options);
     }
     if (isset($postmanState['version']) && version_compare($postmanState['version'], '1.7.0', '<')) {
         if ($options['mail_log_max_entries'] == 10) {
             $options['mail_log_max_entries'] = 250;
         }
         $postmanStats = get_option('postman_stats');
         $stateCleared = false;
         if (!isset($postmanState['delivery_success_total']) && isset($postmanStats['delivery_success_total'])) {
             $postmanState['delivery_success_total'] = $postmanStats['delivery_success_total'];
             $stateCleared = true;
         }
         if (!isset($postmanState['delivery_fail_total']) && isset($postmanStats['delivery_fail_total'])) {
             $postmanState['delivery_fail_total'] = $postmanStats['delivery_fail_total'];
             $stateCleared = true;
         }
         if ($stateCleared) {
             delete_option('postman_stats');
         }
     }
     // can we create a tmp file? - this code is duplicated in InputSanitizer
     PostmanUtils::deleteLockFile();
     $lockSuccess = PostmanUtils::createLockFile();
     // &= does not work as expected in my PHP
     $lockSuccess = $lockSuccess && PostmanUtils::deleteLockFile();
     $postmanState['locking_enabled'] = $lockSuccess;
     // always update the version number
     if (!isset($postmanState['install_date'])) {
         $this->logger->debug("Upgrading database: adding install_date");
         $postmanState['install_date'] = time();
     }
     $pluginData = apply_filters('postman_get_plugin_metadata', null);
     $postmanState['version'] = $pluginData['version'];
     update_option('postman_state', $postmanState);
     //
     delete_option('postman_session');
     // reload options
     PostmanState::getInstance()->reload();
     PostmanOptions::getInstance()->reload();
 }
 /**
  * From http://www.hughlashbrooke.com/2014/02/wordpress-add-items-glance-widget/
  * http://coffeecupweb.com/how-to-add-custom-post-types-to-at-a-glance-dashboard-widget-in-wordpress/
  *
  * @param unknown $items        	
  * @return string
  */
 function customizeAtAGlanceDashboardWidget($items = array())
 {
     // only modify the At-a-Glance for administrators
     if (PostmanUtils::isAdmin()) {
         $post_types = array(PostmanEmailLogPostType::POSTMAN_CUSTOM_POST_TYPE_SLUG);
         foreach ($post_types as $type) {
             if (!post_type_exists($type)) {
                 continue;
             }
             $num_posts = wp_count_posts($type);
             if ($num_posts) {
                 $published = intval($num_posts->publish);
                 $privated = intval($num_posts->private);
                 $post_type = get_post_type_object($type);
                 $text = _n('%s ' . $post_type->labels->singular_name, '%s ' . $post_type->labels->name, $privated, Postman::TEXT_DOMAIN);
                 $text = sprintf($text, number_format_i18n($privated));
                 $items[] = sprintf('<a class="%1$s-count" href="%3$s">%2$s</a>', $type, $text, PostmanUtils::getEmailLogPageUrl()) . "\n";
             }
         }
         return $items;
     }
 }
Example #24
0
 /**
  * Clean up after sending the mail
  *
  * @param PostmanZendMailEngine $engine        	
  * @param unknown $startTime        	
  */
 private function postSend(PostmanMailEngine $engine, $startTime, PostmanOptions $options, PostmanModuleTransport $transport)
 {
     // save the transcript
     $this->transcript = $engine->getTranscript();
     // log the transcript
     if ($this->logger->isTrace()) {
         $this->logger->trace('Transcript:');
         $this->logger->trace($this->transcript);
     }
     // delete the semaphore
     if ($transport->isLockingRequired()) {
         PostmanUtils::unlock();
     }
     // stop the clock
     $endTime = microtime(true) * 1000;
     $this->totalTime = $endTime - $startTime;
 }
 /**
  * Sanitize each setting field as needed
  *
  * @param array $input
  *        	Contains all settings fields as array keys
  */
 public function sanitize($input)
 {
     $this->logger->debug("Sanitizing data before storage");
     $new_input = array();
     $success = true;
     $this->sanitizeString('Encryption Type', PostmanOptions::SECURITY_TYPE, $input, $new_input);
     $this->sanitizeString('Hostname', PostmanOptions::HOSTNAME, $input, $new_input);
     if (!empty($input[PostmanOptions::PORT])) {
         $port = absint($input[PostmanOptions::PORT]);
         if ($port > 0) {
             $this->sanitizeInt('Port', PostmanOptions::PORT, $input, $new_input);
         } else {
             $new_input[PostmanOptions::PORT] = $this->options->getPort();
             add_settings_error(PostmanOptions::PORT, PostmanOptions::PORT, 'Invalid TCP Port', 'error');
             $success = false;
         }
     }
     // check the auth type AFTER the hostname because we reset the hostname if auth is bad
     $this->sanitizeString('From Email', PostmanOptions::MESSAGE_SENDER_EMAIL, $input, $new_input);
     // the wizard doesn't set an envelope sender, so we'll default it to From Email
     $new_input[PostmanOptions::ENVELOPE_SENDER] = $new_input[PostmanOptions::MESSAGE_SENDER_EMAIL];
     $this->sanitizeString('Sender Email', PostmanOptions::ENVELOPE_SENDER, $input, $new_input);
     $this->sanitizeString('Transport Type', PostmanOptions::TRANSPORT_TYPE, $input, $new_input);
     $this->sanitizeString('Authorization Type', PostmanOptions::AUTHENTICATION_TYPE, $input, $new_input);
     $this->sanitizeString('From Name', PostmanOptions::MESSAGE_SENDER_NAME, $input, $new_input);
     $this->sanitizeString('Client ID', PostmanOptions::CLIENT_ID, $input, $new_input);
     $this->sanitizeString('Client Secret', PostmanOptions::CLIENT_SECRET, $input, $new_input);
     $this->sanitizeString('Username', PostmanOptions::BASIC_AUTH_USERNAME, $input, $new_input);
     $this->sanitizePassword('Password', PostmanOptions::BASIC_AUTH_PASSWORD, $input, $new_input, $this->options->getPassword());
     $this->sanitizePassword('Mandrill API Key', PostmanOptions::MANDRILL_API_KEY, $input, $new_input, $this->options->getMandrillApiKey());
     $this->sanitizePassword('SendGrid API Key', PostmanOptions::SENDGRID_API_KEY, $input, $new_input, $this->options->getSendGridApiKey());
     $this->sanitizeString('Reply-To', PostmanOptions::REPLY_TO, $input, $new_input);
     $this->sanitizeString('From Name Override', PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE, $input, $new_input);
     $this->sanitizeString('From Email Override', PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE, $input, $new_input);
     $this->sanitizeString('Disable Email Validation', PostmanOptions::DISABLE_EMAIL_VALIDAITON, $input, $new_input);
     $this->sanitizeString('Forced To Recipients', PostmanOptions::FORCED_TO_RECIPIENTS, $input, $new_input);
     $this->sanitizeString('Forced CC Recipients', PostmanOptions::FORCED_CC_RECIPIENTS, $input, $new_input);
     $this->sanitizeString('Forced BCC Recipients', PostmanOptions::FORCED_BCC_RECIPIENTS, $input, $new_input);
     $this->sanitizeString('Additional Headers', PostmanOptions::ADDITIONAL_HEADERS, $input, $new_input);
     $this->sanitizeInt('Read Timeout', PostmanOptions::READ_TIMEOUT, $input, $new_input);
     $this->sanitizeInt('Conenction Timeout', PostmanOptions::CONNECTION_TIMEOUT, $input, $new_input);
     $this->sanitizeInt('Log Level', PostmanOptions::LOG_LEVEL, $input, $new_input);
     $this->sanitizeString('Email Log Enabled', PostmanOptions::MAIL_LOG_ENABLED_OPTION, $input, $new_input);
     $this->sanitizeLogMax('Email Log Max Entries', PostmanOptions::MAIL_LOG_MAX_ENTRIES, $input, $new_input);
     $this->sanitizeString('Run Mode', PostmanOptions::RUN_MODE, $input, $new_input);
     $this->sanitizeString('Stealth Mode', PostmanOptions::STEALTH_MODE, $input, $new_input);
     $this->sanitizeInt('Transcript Size', PostmanOptions::TRANSCRIPT_SIZE, $input, $new_input);
     $this->sanitizeString('Temporary Directory', PostmanOptions::TEMPORARY_DIRECTORY, $input, $new_input);
     if ($new_input[PostmanOptions::CLIENT_ID] != $this->options->getClientId() || $new_input[PostmanOptions::CLIENT_SECRET] != $this->options->getClientSecret() || $new_input[PostmanOptions::HOSTNAME] != $this->options->getHostname()) {
         $this->logger->debug("Recognized new Client ID");
         // the user entered a new client id and we should destroy the stored auth token
         delete_option(PostmanOAuthToken::OPTIONS_NAME);
     }
     // can we create a tmp file? - this code is duplicated in ActivationHandler
     PostmanUtils::deleteLockFile($new_input[PostmanOptions::TEMPORARY_DIRECTORY]);
     $lockSuccess = PostmanUtils::createLockFile($new_input[PostmanOptions::TEMPORARY_DIRECTORY]);
     // &= does not work as expected in my PHP
     $lockSuccess = $lockSuccess && PostmanUtils::deleteLockFile($new_input[PostmanOptions::TEMPORARY_DIRECTORY]);
     $this->logger->debug('FileLocking=' . $lockSuccess);
     PostmanState::getInstance()->setFileLockingEnabled($lockSuccess);
     if ($success) {
         PostmanSession::getInstance()->setAction(self::VALIDATION_SUCCESS);
     } else {
         PostmanSession::getInstance()->setAction(self::VALIDATION_FAILED);
     }
     return $new_input;
 }
 /**
  * (non-PHPdoc)
  *
  * @see PostmanSmtpEngine::send()
  */
 public function send(PostmanMessage $message)
 {
     $this->logger->debug("Prepping Zend");
     $envelopeFrom = new PostmanEmailAddress($this->transport->getEnvelopeFromEmailAddress());
     if ($this->transport->isEnvelopeFromValidationSupported()) {
         // validate the envelope from since we didn't do it in the Message
         $envelopeFrom->validate('Envelope From');
     }
     // create the Message
     $charset = $message->getCharset();
     $this->logger->debug('Building Postman_Zend_Mail with charset=' . $charset);
     $mail = new Postman_Zend_Mail($charset);
     // add the Postman signature - append it to whatever the user may have set
     if (!PostmanOptions::getInstance()->isStealthModeEnabled()) {
         $pluginData = apply_filters('postman_get_plugin_metadata', null);
         $mail->addHeader('X-Mailer', sprintf('Postman SMTP %s for WordPress (%s)', $pluginData['version'], 'https://wordpress.org/plugins/postman-smtp/'));
     }
     // add the headers - see http://framework.zend.com/manual/1.12/en/zend.mail.additional-headers.html
     foreach ((array) $message->getHeaders() as $header) {
         $this->logger->debug(sprintf('Adding user header %s=%s', $header['name'], $header['content']));
         $mail->addHeader($header['name'], $header['content'], true);
     }
     // if the caller set a Content-Type header, use it
     $contentType = $message->getContentType();
     if (!empty($contentType)) {
         $mail->addHeader('Content-Type', $contentType, false);
         $this->logger->debug('Adding content-type ' . $contentType);
     }
     // add the From Header
     $fromHeader = $this->addFrom($message, $mail);
     $fromHeader->log($this->logger, 'From');
     // add the Sender Header, overriding what the user may have set
     $mail->addHeader('Sender', $this->transport->getFromEmailAddress(), false);
     // from RFC 5321: http://tools.ietf.org/html/rfc5321#section-4.4
     // A message-originating SMTP system SHOULD NOT send a message that
     // already contains a Return-path header field.
     // I changed Zend/Mail/Mail.php to fix this
     $mail->setReturnPath($this->transport->getEnvelopeFromEmailAddress());
     // add the to recipients
     foreach ((array) $message->getToRecipients() as $recipient) {
         $recipient->log($this->logger, 'To');
         $mail->addTo($recipient->getEmail(), $recipient->getName());
     }
     // add the cc recipients
     foreach ((array) $message->getCcRecipients() as $recipient) {
         $recipient->log($this->logger, 'Cc');
         $mail->addCc($recipient->getEmail(), $recipient->getName());
     }
     // add the to recipients
     foreach ((array) $message->getBccRecipients() as $recipient) {
         $recipient->log($this->logger, 'Bcc');
         $mail->addBcc($recipient->getEmail(), $recipient->getName());
     }
     // add the reply-to
     $replyTo = $message->getReplyTo();
     // $replyTo is null or a PostmanEmailAddress object
     if (isset($replyTo)) {
         $mail->setReplyTo($replyTo->getEmail(), $replyTo->getName());
     }
     // add the date
     $date = $message->getDate();
     if (!empty($date)) {
         $mail->setDate($date);
     }
     // add the messageId
     $messageId = $message->getMessageId();
     if (!empty($messageId)) {
         $mail->setMessageId($messageId);
     }
     // add the subject
     if (null !== $message->getSubject()) {
         $mail->setSubject($message->getSubject());
     }
     $textPart = $message->getBodyTextPart();
     if (!empty($textPart)) {
         $this->logger->debug('Adding body as text');
         $mail->setBodyText($textPart);
     }
     $htmlPart = $message->getBodyHtmlPart();
     if (!empty($htmlPart)) {
         $this->logger->debug('Adding body as html');
         $mail->setBodyHtml($htmlPart);
     }
     // add attachments
     $this->logger->debug("Adding attachments");
     $message->addAttachmentsToMail($mail);
     // create the SMTP transport
     $this->logger->debug("Create the Zend_Mail transport");
     $zendTransport = $this->transport->createZendMailTransport($this->transport->getHostname(), array());
     try {
         // send the message
         $this->logger->debug("Sending mail");
         $mail->send($zendTransport);
         if ($this->logger->isInfo()) {
             $this->logger->info(sprintf('Message %d accepted for delivery', PostmanState::getInstance()->getSuccessfulDeliveries() + 1));
         }
         // finally not supported??
         if ($zendTransport->getConnection() && !PostmanUtils::isEmpty($zendTransport->getConnection()->getLog())) {
             $this->transcript = $zendTransport->getConnection()->getLog();
         } else {
             if (method_exists($zendTransport, 'getTranscript') && !PostmanUtils::isEmpty($zendTransport->getTranscript())) {
                 // then use the API response
                 $this->transcript = $zendTransport->getTranscript();
             } else {
                 if (method_exists($zendTransport, 'getMessage') && !PostmanUtils::isEmpty($zendTransport->getMessage())) {
                     // then use the Raw Message as the Transcript
                     $this->transcript = $zendTransport->getMessage();
                 }
             }
         }
     } catch (Exception $e) {
         // finally not supported??
         if ($zendTransport->getConnection() && !PostmanUtils::isEmpty($zendTransport->getConnection()->getLog())) {
             $this->transcript = $zendTransport->getConnection()->getLog();
         } else {
             if (method_exists($zendTransport, 'getTranscript') && !PostmanUtils::isEmpty($zendTransport->getTranscript())) {
                 // then use the API response
                 $this->transcript = $zendTransport->getTranscript();
             } else {
                 if (method_exists($zendTransport, 'getMessage') && !PostmanUtils::isEmpty($zendTransport->getMessage())) {
                     // then use the Raw Message as the Transcript
                     $this->transcript = $zendTransport->getMessage();
                 }
             }
         }
         // get the current exception message
         $message = $e->getMessage();
         if ($e->getCode() == 334) {
             // replace the unusable Google message with a better one in the case of code 334
             $message = sprintf(__('Communication Error [334] - make sure the Envelope From email is the same account used to create the Client ID.', Postman::TEXT_DOMAIN));
         }
         // create a new exception
         $newException = new Exception($message, $e->getCode());
         // throw the new exception after handling
         throw $newException;
     }
 }
Example #27
0
 /**
  * Does this hostname belong to Google?
  *
  * @param unknown $hostname        	
  * @return boolean
  */
 static function isGoogle($hostname)
 {
     return PostmanUtils::endsWith($hostname, 'gmail.com') || PostmanUtils::endsWith($hostname, 'googleapis.com');
 }
 /**
  */
 public function outputTestEmailWizardContent()
 {
     print '<div class="wrap">';
     $this->outputChildPageHeader(__('Send a Test Email', 'postman-smtp'));
     printf('<form id="postman_test_email_wizard" method="post" action="%s">', PostmanUtils::getSettingsPageUrl());
     // Step 1
     printf('<h5>%s</h5>', __('Specify the Recipient', 'postman-smtp'));
     print '<fieldset>';
     printf('<legend>%s</legend>', __('Who is this message going to?', 'postman-smtp'));
     printf('<p>%s', __('This utility allows you to send an email message for testing.', 'postman-smtp'));
     print ' ';
     /* translators: where %d is an amount of time, in seconds */
     printf('%s</p>', sprintf(_n('If there is a problem, Postman will give up after %d second.', 'If there is a problem, Postman will give up after %d seconds.', $this->options->getReadTimeout(), 'postman-smtp'), $this->options->getReadTimeout()));
     printf('<label for="postman_test_options[test_email]">%s</label>', _x('Recipient Email Address', 'Configuration Input Field', 'postman-smtp'));
     print $this->adminController->test_email_callback();
     print '</fieldset>';
     // Step 2
     printf('<h5>%s</h5>', __('Send The Message', 'postman-smtp'));
     print '<fieldset>';
     print '<legend>';
     print __('Sending the message:', 'postman-smtp');
     printf(' <span id="postman_test_message_status">%s</span>', _x('In Outbox', 'Email Test Status', 'postman-smtp'));
     print '</legend>';
     print '<section>';
     printf('<p><label>%s</label></p>', _x('Status', 'Was sending this email successful or not?', 'postman-smtp'));
     print '<textarea id="postman_test_message_error_message" readonly="readonly" cols="65" rows="4"></textarea>';
     print '</section>';
     print '</fieldset>';
     // Step 3
     printf('<h5>%s</h5>', __('Session Transcript', 'postman-smtp'));
     print '<fieldset>';
     printf('<legend>%s</legend>', __('Examine the SMTP Session Transcript if you need to.', 'postman-smtp'));
     printf('<p>%s</p>', __('This is the conversation between Postman and your SMTP server. It can be useful for diagnosing problems. <b>DO NOT</b> post it on-line, it may contain your account password.', 'postman-smtp'));
     print '<section>';
     printf('<p><label for="postman_test_message_transcript">%s</label></p>', __('SMTP Session Transcript', 'postman-smtp'));
     print '<textarea readonly="readonly" id="postman_test_message_transcript" cols="65" rows="8"></textarea>';
     print '</section>';
     print '</fieldset>';
     print '</form>';
     print '</div>';
 }
 public function isYahoo()
 {
     return PostmanUtils::endsWith($this->hostname, 'yahoo.com');
 }
 /**
  * (non-PHPdoc)
  *
  * @see PostmanSmtpEngine::send()
  */
 public function send(PostmanMessage $message, $hostname)
 {
     $options = PostmanOptions::getInstance();
     // create the Message
     $charset = $message->getCharset();
     $this->logger->debug('Building Postman_Zend_Mail with charset=' . $charset);
     $mail = new Postman_Zend_Mail($charset);
     // add the Postman signature - append it to whatever the user may have set
     if (!$options->isStealthModeEnabled()) {
         $pluginData = apply_filters('postman_get_plugin_metadata', null);
         $mail->addHeader('X-Mailer', sprintf('Postman SMTP %s for WordPress (%s)', $pluginData['version'], 'https://wordpress.org/plugins/postman-smtp/'));
     }
     // add the headers - see http://framework.zend.com/manual/1.12/en/zend.mail.additional-headers.html
     foreach ((array) $message->getHeaders() as $header) {
         $this->logger->debug(sprintf('Adding user header %s=%s', $header['name'], $header['content']));
         $mail->addHeader($header['name'], $header['content'], true);
     }
     // modify the content-type to include the boundary
     $contentType = $message->getContentType();
     if (false !== stripos($contentType, 'multipart') && !empty($this->boundary)) {
         // Lines in email are terminated by CRLF ("\r\n") according to RFC2821
         $contentType = sprintf("%s;\r\n\t boundary=\"%s\"", $contentType, $message->getBoundary());
     }
     // if the caller set a Content-Type header, push it into the $mail object
     if (!empty($contentType)) {
         $mail->addHeader('Content-Type', $contentType, false);
         $this->logger->debug('Adding content-type ' . $contentType);
     }
     // add the From Header
     $fromHeader = $this->addFrom($message, $mail);
     $fromHeader->log($this->logger, 'From');
     // add the Sender Header, overriding what the user may have set
     $mail->addHeader('Sender', $options->getEnvelopeSender(), false);
     // from RFC 5321: http://tools.ietf.org/html/rfc5321#section-4.4
     // A message-originating SMTP system SHOULD NOT send a message that
     // already contains a Return-path header field.
     // I changed Zend/Mail/Mail.php to fix this
     $mail->setReturnPath($options->getEnvelopeSender());
     // add the to recipients
     foreach ((array) $message->getToRecipients() as $recipient) {
         $recipient->log($this->logger, 'To');
         $mail->addTo($recipient->getEmail(), $recipient->getName());
     }
     // add the cc recipients
     foreach ((array) $message->getCcRecipients() as $recipient) {
         $recipient->log($this->logger, 'Cc');
         $mail->addCc($recipient->getEmail(), $recipient->getName());
     }
     // add the to recipients
     foreach ((array) $message->getBccRecipients() as $recipient) {
         $recipient->log($this->logger, 'Bcc');
         $mail->addBcc($recipient->getEmail(), $recipient->getName());
     }
     // add the reply-to
     $replyTo = $message->getReplyTo();
     // $replyTo is null or a PostmanEmailAddress object
     if (isset($replyTo)) {
         $mail->setReplyTo($replyTo->getEmail(), $replyTo->getName());
     }
     // add the date
     $date = $message->getDate();
     if (!empty($date)) {
         $mail->setDate($date);
     }
     // add the messageId
     $messageId = $message->getMessageId();
     if (!empty($messageId)) {
         $mail->setMessageId($messageId);
     }
     // add the subject
     if (null !== $message->getSubject()) {
         $mail->setSubject($message->getSubject());
     }
     // add the message content as either text or html
     $bodyTextPart = $message->getBodyTextPart();
     $bodyHtmlPart = $message->getBodyHtmlPart();
     if (!empty($bodyTextPart) && empty($bodyHtmlPart)) {
         $this->logger->debug('Adding body as text');
         $mail->setBodyText($message->getBody());
     } else {
         if (empty($bodyTextPart) && !empty($bodyHtmlPart)) {
             $this->logger->debug('Adding body as html');
             $mail->setBodyHtml($message->getBody());
         } else {
             if (!empty($bodyTextPart) && !empty($bodyHtmlPart)) {
                 $this->logger->debug('Adding body as text and html');
                 $mail->setBodyHtml($message->getBodyHtmlPart());
                 $mail->setBodyText($message->getBodyTextPart());
             } else {
                 if (empty($contentType) || substr($contentType, 0, 10) === 'text/plain') {
                     $this->logger->debug('Adding body as text');
                     $mail->setBodyText($message->getBody());
                 } else {
                     if (substr($contentType, 0, 9) === 'text/html') {
                         $this->logger->debug('Adding body as html');
                         $mail->setBodyHtml($message->getBody());
                     } else {
                         if (substr($contentType, 0, 21) === 'multipart/alternative') {
                             $this->logger->debug('Adding body as multipart/alternative');
                             $arr = explode(PHP_EOL, $message->getBody());
                             $textBody = '';
                             $htmlBody = '';
                             $mode = '';
                             foreach ($arr as $s) {
                                 if (substr($s, 0, 25) === "Content-Type: text/plain;") {
                                     $mode = 'foundText';
                                 } else {
                                     if (substr($s, 0, 24) === "Content-Type: text/html;") {
                                         $mode = 'foundHtml';
                                     } else {
                                         if ($mode == 'textReading') {
                                             $textBody .= $s;
                                         } else {
                                             if ($mode == 'htmlReading') {
                                                 $htmlBody .= $s;
                                             } else {
                                                 if ($mode == 'foundText') {
                                                     if ($s == '') {
                                                         $mode = 'textReading';
                                                     }
                                                 } else {
                                                     if ($mode == 'foundHtml') {
                                                         if ($s == '') {
                                                             $mode = 'htmlReading';
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                             $mail->setBodyHtml($htmlBody);
                             $mail->setBodyText($textBody);
                         } else {
                             $this->logger->error('Unknown content-type: ' . $contentType);
                             $mail->setBodyText($message->getBody());
                         }
                     }
                 }
             }
         }
     }
     // add attachments
     $this->logger->debug("Adding attachments");
     $message->addAttachmentsToMail($mail);
     // get the transport configuration
     $this->logger->debug("Create the Zend_Mail transport configuration array");
     $config = $this->authenticator->createConfig($this->transport);
     assert(!empty($config));
     // create the SMTP transport
     $this->logger->debug("Create the Zend_Mail transport configuration");
     $zendTransport = $this->transport->createZendMailTransport($hostname, $config);
     assert(!empty($zendTransport));
     try {
         // send the message
         $this->logger->debug("Sending mail");
         $mail->send($zendTransport);
         // finally not supported??
         if ($zendTransport->getConnection() && !PostmanUtils::isEmpty($zendTransport->getConnection()->getLog())) {
             $this->transcript = $zendTransport->getConnection()->getLog();
             $this->logger->trace($this->transcript);
         } else {
             if (method_exists($zendTransport, 'getMessage') && !PostmanUtils::isEmpty($zendTransport->getMessage())) {
                 // then use the Raw Message as the Transcript
                 $this->transcript = $zendTransport->getMessage();
                 $this->logger->trace($this->transcript);
             }
         }
     } catch (Exception $e) {
         // finally not supported??
         if ($zendTransport->getConnection() && !PostmanUtils::isEmpty($zendTransport->getConnection()->getLog())) {
             $this->transcript = $zendTransport->getConnection()->getLog();
             $this->logger->trace($this->transcript);
         } else {
             if (method_exists($zendTransport, 'getMessage') && !PostmanUtils::isEmpty($zendTransport->getMessage())) {
                 // then use the Raw Message as the Transcript
                 $this->transcript = $zendTransport->getMessage();
                 $this->logger->trace($this->transcript);
             }
         }
         // get the current exception message
         $message = $e->getMessage();
         if ($e->getCode() == 334) {
             // replace the unusable Google message with a better one in the case of code 334
             $message = sprintf(__('Communication Error [334] - make sure the Envelope From email is the same account used to create the Client ID.', 'postman-smtp'));
         }
         // create a new exception
         $newException = new Exception($message, $e->getCode());
         // throw the new exception after handling
         throw $newException;
     }
 }