Post SMTP Mailer/Email Log - Version 1.7.7

Version Description

  • 2017-10-17
  • Fixed: Error sending files with sendgrid
  • Fixed: Wrong attachments format in Mandrill
  • Fixed: Wrong Sender Header in Mandrill
Download this release

Release Info

Developer yehudah
Plugin Icon 128x128 Post SMTP Mailer/Email Log
Version 1.7.7
Comparing to
See all releases

Code changes from version 1.7.6 to 1.7.7

Postman/Postman-Configuration/PostmanConfigurationController.php CHANGED
@@ -1,48 +1,48 @@
1
  <?php
2
- require_once ('PostmanRegisterConfigurationSettings.php');
3
  class PostmanConfigurationController {
4
  const CONFIGURATION_SLUG = 'postman/configuration';
5
  const CONFIGURATION_WIZARD_SLUG = 'postman/configuration_wizard';
6
-
7
  // logging
8
  private $logger;
9
  private $options;
10
  private $settingsRegistry;
11
-
12
  // Holds the values to be used in the fields callbacks
13
  private $rootPluginFilenameAndPath;
14
-
15
  /**
16
  * Constructor
17
  *
18
- * @param unknown $rootPluginFilenameAndPath
19
  */
20
- public function __construct($rootPluginFilenameAndPath) {
21
- assert ( ! empty ( $rootPluginFilenameAndPath ) );
22
- assert ( PostmanUtils::isAdmin () );
23
- assert ( is_admin () );
24
-
25
- $this->logger = new PostmanLogger ( get_class ( $this ) );
26
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
27
- $this->options = PostmanOptions::getInstance ();
28
- $this->settingsRegistry = new PostmanSettingsRegistry ();
29
-
30
- PostmanUtils::registerAdminMenu ( $this, 'addConfigurationSubmenu' );
31
- PostmanUtils::registerAdminMenu ( $this, 'addSetupWizardSubmenu' );
32
-
33
  // hook on the init event
34
- add_action ( 'init', array (
35
  $this,
36
- 'on_init'
37
  ) );
38
-
39
  // initialize the scripts, stylesheets and form fields
40
- add_action ( 'admin_init', array (
41
  $this,
42
- 'on_admin_init'
43
  ) );
44
  }
45
-
46
  /**
47
  * Functions to execute on the init event
48
  *
@@ -51,189 +51,187 @@ class PostmanConfigurationController {
51
  */
52
  public function on_init() {
53
  // register Ajax handlers
54
- new PostmanGetHostnameByEmailAjaxController ();
55
- new PostmanManageConfigurationAjaxHandler ();
56
- new PostmanImportConfigurationAjaxController ( $this->options );
57
  }
58
-
59
  /**
60
  * Fires on the admin_init method
61
  */
62
  public function on_admin_init() {
63
- //
64
- $this->registerStylesAndScripts ();
65
- $this->settingsRegistry->on_admin_init ();
66
  }
67
-
68
  /**
69
  * Register and add settings
70
  */
71
  private function registerStylesAndScripts() {
72
- if ($this->logger->isTrace ()) {
73
- $this->logger->trace ( 'registerStylesAndScripts()' );
74
  }
75
  // register the stylesheet and javascript external resources
76
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
77
- wp_register_script ( 'postman_manual_config_script', plugins_url ( 'Postman/Postman-Configuration/postman_manual_config.js', $this->rootPluginFilenameAndPath ), array (
78
  PostmanViewController::JQUERY_SCRIPT,
79
  'jquery_validation',
80
- PostmanViewController::POSTMAN_SCRIPT
81
  ), $pluginData ['version'] );
82
- wp_register_script ( 'postman_wizard_script', plugins_url ( 'Postman/Postman-Configuration/postman_wizard.js', $this->rootPluginFilenameAndPath ), array (
83
  PostmanViewController::JQUERY_SCRIPT,
84
  'jquery_validation',
85
  'jquery_steps_script',
86
  PostmanViewController::POSTMAN_SCRIPT,
87
- 'sprintf'
88
  ), $pluginData ['version'] );
89
  }
90
-
91
  /**
92
  */
93
  private function addLocalizeScriptsToPage() {
94
- $warning = __ ( 'Warning', Postman::TEXT_DOMAIN );
95
  /* translators: where %s is the name of the SMTP server */
96
- wp_localize_script ( 'postman_wizard_script', 'postman_smtp_mitm', sprintf ( '%s: %s', $warning, __ ( 'connected to %1$s instead of %2$s.', Postman::TEXT_DOMAIN ) ) );
97
  /* translators: where %d is a port number */
98
- wp_localize_script ( 'postman_wizard_script', 'postman_wizard_bad_redirect_url', __ ( 'You are about to configure OAuth 2.0 with an IP address instead of a domain name. This is not permitted. Either assign a real domain name to your site or add a fake one in your local host file.', Postman::TEXT_DOMAIN ) );
99
-
100
  // user input
101
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_sender_email', '#input_' . PostmanOptions::MESSAGE_SENDER_EMAIL );
102
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_sender_name', '#input_' . PostmanOptions::MESSAGE_SENDER_NAME );
103
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_port_element_name', '#input_' . PostmanOptions::PORT );
104
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_hostname_element_name', '#input_' . PostmanOptions::HOSTNAME );
105
-
106
  // the enc input
107
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_enc_for_password_el', '#input_enc_type_password' );
108
  // these are the ids for the <option>s in the encryption <select>
109
-
110
  // the password inputs
111
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_basic_username', '#input_' . PostmanOptions::BASIC_AUTH_USERNAME );
112
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_basic_password', '#input_' . PostmanOptions::BASIC_AUTH_PASSWORD );
113
-
114
  // the auth input
115
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_redirect_url_el', '#input_oauth_redirect_url' );
116
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_auth_type', '#input_' . PostmanOptions::AUTHENTICATION_TYPE );
117
-
118
  // the transport modules scripts
119
- foreach ( PostmanTransportRegistry::getInstance ()->getTransports () as $transport ) {
120
- $transport->enqueueScript ();
121
  }
122
 
123
  // we need data from port test
124
- PostmanConnectivityTestController::addLocalizeScriptForPortTest ();
125
-
126
  }
127
-
128
  /**
129
  * Register the Configuration screen
130
  */
131
  public function addConfigurationSubmenu() {
132
- $page = add_submenu_page ( null, sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanConfigurationController::CONFIGURATION_SLUG, array (
133
  $this,
134
- 'outputManualConfigurationContent'
135
  ) );
136
  // When the plugin options page is loaded, also load the stylesheet
137
- add_action ( 'admin_print_styles-' . $page, array (
138
  $this,
139
- 'enqueueConfigurationResources'
140
  ) );
141
  }
142
-
143
  /**
144
  */
145
  function enqueueConfigurationResources() {
146
- $this->addLocalizeScriptsToPage ();
147
- wp_enqueue_style ( PostmanViewController::POSTMAN_STYLE );
148
- wp_enqueue_style ( 'jquery_ui_style' );
149
- wp_enqueue_script ( 'postman_manual_config_script' );
150
- wp_enqueue_script ( 'jquery-ui-tabs' );
151
  }
152
-
153
  /**
154
  * Register the Setup Wizard screen
155
  */
156
  public function addSetupWizardSubmenu() {
157
- $page = add_submenu_page ( null, sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG, array (
158
  $this,
159
- 'outputWizardContent'
160
  ) );
161
  // When the plugin options page is loaded, also load the stylesheet
162
- add_action ( 'admin_print_styles-' . $page, array (
163
  $this,
164
- 'enqueueWizardResources'
165
  ) );
166
  }
167
-
168
  /**
169
  */
170
  function enqueueWizardResources() {
171
- $this->addLocalizeScriptsToPage ();
172
- $this->importableConfiguration = new PostmanImportableConfiguration ();
173
  $startPage = 1;
174
- if ($this->importableConfiguration->isImportAvailable ()) {
175
  $startPage = 0;
176
  }
177
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_setup_wizard', array (
178
- 'start_page' => $startPage
179
  ) );
180
- wp_enqueue_style ( 'jquery_steps_style' );
181
- wp_enqueue_style ( PostmanViewController::POSTMAN_STYLE );
182
- wp_enqueue_script ( 'postman_wizard_script' );
183
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, '$jq', 'jQuery.noConflict(true)' );
184
- $shortLocale = substr ( get_locale (), 0, 2 );
185
- if ($shortLocale != 'en') {
186
- $url = plugins_url ( sprintf ( 'script/jquery-validate/localization/messages_%s.js', $shortLocale ), $this->rootPluginFilenameAndPath );
187
- wp_enqueue_script ( sprintf ( 'jquery-validation-locale-%s', $shortLocale ), $url );
188
  }
189
  }
190
-
191
  /**
192
  */
193
  public function outputManualConfigurationContent() {
194
  print '<div class="wrap">';
195
-
196
- PostmanViewController::outputChildPageHeader ( __ ( 'Settings', Postman::TEXT_DOMAIN ), 'advanced_config' );
197
  print '<div id="config_tabs"><ul>';
198
- print sprintf ( '<li><a href="#account_config">%s</a></li>', __ ( 'Account', Postman::TEXT_DOMAIN ) );
199
- print sprintf ( '<li><a href="#message_config">%s</a></li>', __ ( 'Message', Postman::TEXT_DOMAIN ) );
200
- print sprintf ( '<li><a href="#logging_config">%s</a></li>', __ ( 'Logging', Postman::TEXT_DOMAIN ) );
201
- print sprintf ( '<li><a href="#advanced_options_config">%s</a></li>', __ ( 'Advanced', Postman::TEXT_DOMAIN ) );
202
  print '</ul>';
203
  print '<form method="post" action="options.php">';
204
  // This prints out all hidden setting fields
205
- settings_fields ( PostmanAdminController::SETTINGS_GROUP_NAME );
206
  print '<section id="account_config">';
207
- if (sizeof ( PostmanTransportRegistry::getInstance ()->getTransports () ) > 1) {
208
- do_settings_sections ( 'transport_options' );
209
  } else {
210
- printf ( '<input id="input_%2$s" type="hidden" name="%1$s[%2$s]" value="%3$s"/>', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::TRANSPORT_TYPE, PostmanSmtpModuleTransport::SLUG );
211
  }
212
  print '<div id="smtp_config" class="transport_setting">';
213
- do_settings_sections ( PostmanAdminController::SMTP_OPTIONS );
214
  print '</div>';
215
  print '<div id="password_settings" class="authentication_setting non-oauth2">';
216
- do_settings_sections ( PostmanAdminController::BASIC_AUTH_OPTIONS );
217
  print '</div>';
218
  print '<div id="oauth_settings" class="authentication_setting non-basic">';
219
- do_settings_sections ( PostmanAdminController::OAUTH_AUTH_OPTIONS );
220
  print '</div>';
221
  print '<div id="mandrill_settings" class="authentication_setting non-basic non-oauth2">';
222
- do_settings_sections ( PostmanMandrillTransport::MANDRILL_AUTH_OPTIONS );
223
  print '</div>';
224
  print '<div id="sendgrid_settings" class="authentication_setting non-basic non-oauth2">';
225
- do_settings_sections ( PostmanSendGridTransport::SENDGRID_AUTH_OPTIONS );
226
  print '</div>';
227
  print '</section>';
228
  print '<section id="message_config">';
229
- do_settings_sections ( PostmanAdminController::MESSAGE_SENDER_OPTIONS );
230
- do_settings_sections ( PostmanAdminController::MESSAGE_FROM_OPTIONS );
231
- do_settings_sections ( PostmanAdminController::EMAIL_VALIDATION_OPTIONS );
232
- do_settings_sections ( PostmanAdminController::MESSAGE_OPTIONS );
233
- do_settings_sections ( PostmanAdminController::MESSAGE_HEADERS_OPTIONS );
234
  print '</section>';
235
  print '<section id="logging_config">';
236
- do_settings_sections ( PostmanAdminController::LOGGING_OPTIONS );
237
  print '</section>';
238
  /*
239
  * print '<section id="logging_config">';
@@ -241,133 +239,132 @@ class PostmanConfigurationController {
241
  * print '</section>';
242
  */
243
  print '<section id="advanced_options_config">';
244
- do_settings_sections ( PostmanAdminController::NETWORK_OPTIONS );
245
- do_settings_sections ( PostmanAdminController::ADVANCED_OPTIONS );
246
  print '</section>';
247
- submit_button ();
248
  print '</form>';
249
  print '</div>';
250
  print '</div>';
251
  }
252
-
253
  /**
254
  */
255
  public function outputWizardContent() {
256
  // Set default values for input fields
257
- $this->options->setMessageSenderEmailIfEmpty ( wp_get_current_user ()->user_email );
258
- $this->options->setMessageSenderNameIfEmpty ( wp_get_current_user ()->display_name );
259
-
260
  // construct Wizard
261
  print '<div class="wrap">';
262
-
263
- PostmanViewController::outputChildPageHeader ( __ ( 'Setup Wizard', Postman::TEXT_DOMAIN ) );
264
-
265
  print '<form id="postman_wizard" method="post" action="options.php">';
266
-
267
  // account tab
268
-
269
  // message tab
270
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE, $this->options->isPluginSenderEmailEnforced () );
271
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE, $this->options->isPluginSenderNameEnforced () );
272
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::REPLY_TO, $this->options->getReplyTo () );
273
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::FORCED_TO_RECIPIENTS, $this->options->getForcedToRecipients () );
274
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::FORCED_CC_RECIPIENTS, $this->options->getForcedCcRecipients () );
275
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::FORCED_BCC_RECIPIENTS, $this->options->getForcedBccRecipients () );
276
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::ADDITIONAL_HEADERS, $this->options->getAdditionalHeaders () );
277
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::DISABLE_EMAIL_VALIDAITON, $this->options->isEmailValidationDisabled () );
278
-
279
  // logging tab
280
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::MAIL_LOG_ENABLED_OPTION, $this->options->getMailLoggingEnabled () );
281
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::MAIL_LOG_MAX_ENTRIES, $this->options->getMailLoggingMaxEntries () );
282
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::TRANSCRIPT_SIZE, $this->options->getTranscriptSize () );
283
-
284
  // advanced tab
285
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::CONNECTION_TIMEOUT, $this->options->getConnectionTimeout () );
286
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::READ_TIMEOUT, $this->options->getReadTimeout () );
287
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::LOG_LEVEL, $this->options->getLogLevel () );
288
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::RUN_MODE, $this->options->getRunMode () );
289
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::STEALTH_MODE, $this->options->isStealthModeEnabled () );
290
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::TEMPORARY_DIRECTORY, $this->options->getTempDirectory () );
291
-
292
  // display the setting text
293
- settings_fields ( PostmanAdminController::SETTINGS_GROUP_NAME );
294
-
295
  // Wizard Step 0
296
- printf ( '<h5>%s</h5>', _x ( 'Import Configuration', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
297
  print '<fieldset>';
298
- printf ( '<legend>%s</legend>', _x ( 'Import configuration from another plugin?', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
299
- printf ( '<p>%s</p>', __ ( 'If you had a working configuration with another Plugin, the Setup Wizard can begin with those settings.', Postman::TEXT_DOMAIN ) );
300
  print '<table class="input_auth_type">';
301
- printf ( '<tr><td><input type="radio" id="import_none" name="input_plugin" value="%s" checked="checked"></input></td><td><label> %s</label></td></tr>', 'none', __ ( 'None', Postman::TEXT_DOMAIN ) );
302
-
303
- if ($this->importableConfiguration->isImportAvailable ()) {
304
- foreach ( $this->importableConfiguration->getAvailableOptions () as $options ) {
305
- printf ( '<tr><td><input type="radio" name="input_plugin" value="%s"/></td><td><label> %s</label></td></tr>', $options->getPluginSlug (), $options->getPluginName () );
306
  }
307
  }
308
  print '</table>';
309
  print '</fieldset>';
310
-
311
  // Wizard Step 1
312
- printf ( '<h5>%s</h5>', _x ( 'Sender Details', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
313
  print '<fieldset>';
314
- printf ( '<legend>%s</legend>', _x ( 'Who is the mail coming from?', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
315
- printf ( '<p>%s</p>', __ ( 'Enter the email address and name you\'d like to send mail as.', Postman::TEXT_DOMAIN ) );
316
- printf ( '<p>%s</p>', __ ( 'Please note that to prevent abuse, many email services will <em>not</em> let you send from an email address other than the one you authenticate with.', Postman::TEXT_DOMAIN ) );
317
- printf ( '<label for="postman_options[sender_email]">%s</label>', __ ( 'Email Address', Postman::TEXT_DOMAIN ) );
318
- print $this->settingsRegistry->from_email_callback ();
319
  print '<br/>';
320
- printf ( '<label for="postman_options[sender_name]">%s</label>', __ ( 'Name', Postman::TEXT_DOMAIN ) );
321
- print $this->settingsRegistry->sender_name_callback ();
322
  print '</fieldset>';
323
-
324
  // Wizard Step 2
325
- printf ( '<h5>%s</h5>', __ ( 'Outgoing Mail Server Hostname', Postman::TEXT_DOMAIN ) );
326
  print '<fieldset>';
327
- foreach ( PostmanTransportRegistry::getInstance ()->getTransports () as $transport ) {
328
- $transport->printWizardMailServerHostnameStep ();
329
  }
330
  print '</fieldset>';
331
-
332
  // Wizard Step 3
333
- printf ( '<h5>%s</h5>', __ ( 'Connectivity Test', Postman::TEXT_DOMAIN ) );
334
  print '<fieldset>';
335
- printf ( '<legend>%s</legend>', __ ( 'How will the connection to the mail server be established?', Postman::TEXT_DOMAIN ) );
336
- printf ( '<p>%s</p>', __ ( 'Your connection settings depend on what your email service provider offers, and what your WordPress host allows.', Postman::TEXT_DOMAIN ) );
337
- printf ( '<p id="connectivity_test_status">%s: <span id="port_test_status">%s</span></p>', __ ( 'Connectivity Test', Postman::TEXT_DOMAIN ), _x ( 'Ready', 'TCP Port Test Status', Postman::TEXT_DOMAIN ) );
338
- printf ( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url ( 'postman-smtp/style/ajax-loader.gif' ) );
339
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::TRANSPORT_TYPE );
340
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::PORT );
341
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::SECURITY_TYPE );
342
- printf ( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::AUTHENTICATION_TYPE );
343
  print '<p id="wizard_recommendation"></p>';
344
  /* Translators: Where %1$s is the socket identifier and %2$s is the authentication type */
345
- printf ( '<p class="user_override" style="display:none"><label><span>%s:</span></label> <table id="user_socket_override" class="user_override"></table></p>', _x ( 'Socket', 'A socket is the network term for host and port together', Postman::TEXT_DOMAIN ) );
346
- printf ( '<p class="user_override" style="display:none"><label><span>%s:</span></label> <table id="user_auth_override" class="user_override"></table></p>', __ ( 'Authentication', Postman::TEXT_DOMAIN ) );
347
  print ('<p><span id="smtp_mitm" style="display:none; background-color:yellow"></span></p>') ;
348
- $warning = __ ( 'Warning', Postman::TEXT_DOMAIN );
349
- $clearCredentialsWarning = __ ( 'This configuration option will send your authorization credentials in the clear.', Postman::TEXT_DOMAIN );
350
- printf ( '<p id="smtp_not_secure" style="display:none"><span style="background-color:yellow">%s: %s</span></p>', $warning, $clearCredentialsWarning );
351
  print '</fieldset>';
352
-
353
  // Wizard Step 4
354
- printf ( '<h5>%s</h5>', __ ( 'Authentication', Postman::TEXT_DOMAIN ) );
355
  print '<fieldset>';
356
- printf ( '<legend>%s</legend>', __ ( 'How will you prove your identity to the mail server?', Postman::TEXT_DOMAIN ) );
357
- foreach ( PostmanTransportRegistry::getInstance ()->getTransports () as $transport ) {
358
- $transport->printWizardAuthenticationStep ();
359
  }
360
  print '</fieldset>';
361
-
362
  // Wizard Step 5
363
- printf ( '<h5>%s</h5>', _x ( 'Finish', 'The final step of the Wizard', Postman::TEXT_DOMAIN ) );
364
  print '<fieldset>';
365
- printf ( '<legend>%s</legend>', _x ( 'You\'re Done!', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
366
  print '<section>';
367
- printf ( '<p>%s</p>', __ ( 'Click Finish to save these settings, then:', Postman::TEXT_DOMAIN ) );
368
  print '<ul style="margin-left: 20px">';
369
- printf ( '<li class="wizard-auth-oauth2">%s</li>', __ ( 'Grant permission with the Email Provider for Postman to send email and', Postman::TEXT_DOMAIN ) );
370
- printf ( '<li>%s</li>', __ ( 'Send yourself a Test Email to make sure everything is working!', Postman::TEXT_DOMAIN ) );
371
  print '</ul>';
372
  print '</section>';
373
  print '</fieldset>';
@@ -379,188 +376,187 @@ class PostmanConfigurationController {
379
  /**
380
  *
381
  * @author jasonhendriks
382
- *
383
  */
384
  class PostmanGetHostnameByEmailAjaxController extends PostmanAbstractAjaxHandler {
385
  const IS_GOOGLE_PARAMETER = 'is_google';
386
  function __construct() {
387
- parent::__construct ();
388
- PostmanUtils::registerAjaxHandler ( 'postman_check_email', $this, 'getAjaxHostnameByEmail' );
389
  }
390
  /**
391
  * This Ajax function retrieves the smtp hostname for a give e-mail address
392
  */
393
  function getAjaxHostnameByEmail() {
394
- $goDaddyHostDetected = $this->getBooleanRequestParameter ( 'go_daddy' );
395
- $email = $this->getRequestParameter ( 'email' );
396
- $d = new PostmanSmtpDiscovery ( $email );
397
- $smtp = $d->getSmtpServer ();
398
- $this->logger->debug ( 'given email ' . $email . ', smtp server is ' . $smtp );
399
- $this->logger->trace ( $d );
400
- if ($goDaddyHostDetected && ! $d->isGoogle) {
401
  // override with the GoDaddy SMTP server
402
  $smtp = 'relay-hosting.secureserver.net';
403
- $this->logger->debug ( 'detected GoDaddy SMTP server, smtp server is ' . $smtp );
404
  }
405
- $response = array (
406
  'hostname' => $smtp,
407
  self::IS_GOOGLE_PARAMETER => $d->isGoogle,
408
  'is_go_daddy' => $d->isGoDaddy,
409
- 'is_well_known' => $d->isWellKnownDomain
410
  );
411
- $this->logger->trace ( $response );
412
- wp_send_json_success ( $response );
413
  }
414
  }
415
  class PostmanManageConfigurationAjaxHandler extends PostmanAbstractAjaxHandler {
416
  function __construct() {
417
- parent::__construct ();
418
- PostmanUtils::registerAjaxHandler ( 'manual_config', $this, 'getManualConfigurationViaAjax' );
419
- PostmanUtils::registerAjaxHandler ( 'get_wizard_configuration_options', $this, 'getWizardConfigurationViaAjax' );
420
  }
421
-
422
  /**
423
  * Handle a Advanced Configuration request with Ajax
424
  *
425
  * @throws Exception
426
  */
427
  function getManualConfigurationViaAjax() {
428
- $queryTransportType = $this->getTransportTypeFromRequest ();
429
- $queryAuthType = $this->getAuthenticationTypeFromRequest ();
430
- $queryHostname = $this->getHostnameFromRequest ();
431
-
432
  // the outgoing server hostname is only required for the SMTP Transport
433
  // the Gmail API transport doesn't use an SMTP server
434
- $transport = PostmanTransportRegistry::getInstance ()->getTransport ( $queryTransportType );
435
- if (! $transport) {
436
- throw new Exception ( 'Unable to find transport ' . $queryTransportType );
437
  }
438
-
439
  // create the response
440
- $response = $transport->populateConfiguration ( $queryHostname );
441
  $response ['referer'] = 'manual_config';
442
-
443
  // set the display_auth to oauth2 if the transport needs it
444
- if ($transport->isOAuthUsed ( $queryAuthType )) {
445
  $response ['display_auth'] = 'oauth2';
446
- $this->logger->debug ( 'ajaxRedirectUrl answer display_auth:' . $response ['display_auth'] );
447
  }
448
- $this->logger->trace ( $response );
449
- wp_send_json_success ( $response );
450
  }
451
-
452
  /**
453
  * Once the Port Tests have run, the results are analyzed.
454
  * The Transport place bids on the sockets and highest bid becomes the recommended
455
  * The UI response is built so the user may choose a different socket with different options.
456
  */
457
  function getWizardConfigurationViaAjax() {
458
- $this->logger->debug ( 'in getWizardConfiguration' );
459
- $originalSmtpServer = $this->getRequestParameter ( 'original_smtp_server' );
460
- $queryHostData = $this->getHostDataFromRequest ();
461
- $sockets = array ();
462
  foreach ( $queryHostData as $id => $datum ) {
463
- array_push ( $sockets, new PostmanWizardSocket ( $datum ) );
464
  }
465
- $this->logger->error ( $sockets );
466
- $userPortOverride = $this->getUserPortOverride ();
467
- $userAuthOverride = $this->getUserAuthOverride ();
468
-
469
  // determine a configuration recommendation
470
- $winningRecommendation = $this->getWinningRecommendation ( $sockets, $userPortOverride, $userAuthOverride, $originalSmtpServer );
471
- if ($this->logger->isTrace ()) {
472
- $this->logger->trace ( 'winning recommendation:' );
473
- $this->logger->trace ( $winningRecommendation );
474
  }
475
-
476
  // create the reponse
477
- $response = array ();
478
- $configuration = array ();
479
  $response ['referer'] = 'wizard';
480
- if (isset ( $userPortOverride ) || isset ( $userAuthOverride )) {
481
  $configuration ['user_override'] = true;
482
  }
483
-
484
- if (isset ( $winningRecommendation )) {
485
-
486
  // create an appropriate (theoretical) transport
487
- $transport = PostmanTransportRegistry::getInstance ()->getTransport ( $winningRecommendation ['transport'] );
488
-
489
  // create user override menu
490
- $overrideMenu = $this->createOverrideMenus ( $sockets, $winningRecommendation, $userPortOverride, $userAuthOverride );
491
- if ($this->logger->isTrace ()) {
492
- $this->logger->trace ( 'override menu:' );
493
- $this->logger->trace ( $overrideMenu );
494
  }
495
-
496
  $queryHostName = $winningRecommendation ['hostname'];
497
- if ($this->logger->isDebug ()) {
498
- $this->logger->debug ( 'Getting scribe for ' . $queryHostName );
499
  }
500
- $generalConfig1 = $transport->populateConfiguration ( $queryHostName );
501
- $generalConfig2 = $transport->populateConfigurationFromRecommendation ( $winningRecommendation );
502
- $configuration = array_merge ( $configuration, $generalConfig1, $generalConfig2 );
503
  $response ['override_menu'] = $overrideMenu;
504
  $response ['configuration'] = $configuration;
505
- if ($this->logger->isTrace ()) {
506
- $this->logger->trace ( 'configuration:' );
507
- $this->logger->trace ( $configuration );
508
- $this->logger->trace ( 'response:' );
509
- $this->logger->trace ( $response );
510
  }
511
- wp_send_json_success ( $response );
512
  } else {
513
  /* translators: where %s is the URL to the Connectivity Test page */
514
- $configuration ['message'] = sprintf ( __ ( 'Postman can\'t find any way to send mail on your system. Run a <a href="%s">connectivity test</a>.', Postman::TEXT_DOMAIN ), PostmanViewController::getPageUrl ( PostmanViewController::PORT_TEST_SLUG ) );
515
  $response ['configuration'] = $configuration;
516
- if ($this->logger->isTrace ()) {
517
- $this->logger->trace ( 'configuration:' );
518
- $this->logger->trace ( $configuration );
519
  }
520
- wp_send_json_error ( $response );
521
  }
522
  }
523
-
524
  /**
525
  * // for each successful host/port combination
526
  * // ask a transport if they support it, and if they do at what priority is it
527
  * // configure for the highest priority you find
528
  *
529
- * @param unknown $queryHostData
530
  * @return unknown
531
  */
532
- private function getWinningRecommendation($sockets, $userSocketOverride, $userAuthOverride, $originalSmtpServer) {
533
  foreach ( $sockets as $socket ) {
534
- $winningRecommendation = $this->getWin ( $socket, $userSocketOverride, $userAuthOverride, $originalSmtpServer );
535
- $this->logger->error ( $socket->label );
536
  }
537
  return $winningRecommendation;
538
  }
539
-
540
  /**
541
  *
542
- * @param PostmanSocket $socket
543
- * @param unknown $userSocketOverride
544
- * @param unknown $userAuthOverride
545
- * @param unknown $originalSmtpServer
546
  * @return Ambigous <NULL, unknown, string>
547
  */
548
- private function getWin(PostmanWizardSocket $socket, $userSocketOverride, $userAuthOverride, $originalSmtpServer) {
549
  static $recommendationPriority = - 1;
550
  static $winningRecommendation = null;
551
  $available = $socket->success;
552
- if ($available) {
553
- $this->logger->debug ( sprintf ( 'Asking for judgement on %s:%s', $socket->hostname, $socket->port ) );
554
- $recommendation = PostmanTransportRegistry::getInstance ()->getRecommendation ( $socket, $userAuthOverride, $originalSmtpServer );
555
- $recommendationId = sprintf ( '%s_%s', $socket->hostname, $socket->port );
556
  $recommendation ['id'] = $recommendationId;
557
- $this->logger->debug ( sprintf ( 'Got a recommendation: [%d] %s', $recommendation ['priority'], $recommendationId ) );
558
- if (isset ( $userSocketOverride )) {
559
- if ($recommendationId == $userSocketOverride) {
560
  $winningRecommendation = $recommendation;
561
- $this->logger->debug ( sprintf ( 'User chosen socket %s is the winner', $recommendationId ) );
562
  }
563
- } elseif ($recommendation && $recommendation ['priority'] > $recommendationPriority) {
564
  $recommendationPriority = $recommendation ['priority'];
565
  $winningRecommendation = $recommendation;
566
  }
@@ -568,82 +564,82 @@ class PostmanManageConfigurationAjaxHandler extends PostmanAbstractAjaxHandler {
568
  }
569
  return $winningRecommendation;
570
  }
571
-
572
  /**
573
  *
574
- * @param unknown $queryHostData
575
  * @return multitype:
576
  */
577
- private function createOverrideMenus($sockets, $winningRecommendation, $userSocketOverride, $userAuthOverride) {
578
- $overrideMenu = array ();
579
  foreach ( $sockets as $socket ) {
580
- $overrideItem = $this->createOverrideMenu ( $socket, $winningRecommendation, $userSocketOverride, $userAuthOverride );
581
- if ($overrideItem != null) {
582
- $overrideMenu [$socket->id] = $overrideItem;
583
  }
584
  }
585
-
586
  // sort
587
- krsort ( $overrideMenu );
588
- $sortedMenu = array ();
589
  foreach ( $overrideMenu as $menu ) {
590
- array_push ( $sortedMenu, $menu );
591
  }
592
-
593
  return $sortedMenu;
594
  }
595
-
596
  /**
597
  *
598
- * @param PostmanWizardSocket $socket
599
- * @param unknown $winningRecommendation
600
- * @param unknown $userSocketOverride
601
- * @param unknown $userAuthOverride
602
  */
603
- private function createOverrideMenu(PostmanWizardSocket $socket, $winningRecommendation, $userSocketOverride, $userAuthOverride) {
604
- if ($socket->success) {
605
- $transport = PostmanTransportRegistry::getInstance ()->getTransport ( $socket->transport );
606
- $this->logger->debug ( sprintf ( 'Transport %s is building the override menu for socket', $transport->getSlug () ) );
607
- $overrideItem = $transport->createOverrideMenu ( $socket, $winningRecommendation, $userSocketOverride, $userAuthOverride );
608
  return $overrideItem;
609
  }
610
  return null;
611
  }
612
-
613
  /**
614
  */
615
  private function getTransportTypeFromRequest() {
616
- return $this->getRequestParameter ( 'transport' );
617
  }
618
-
619
  /**
620
  */
621
  private function getHostnameFromRequest() {
622
- return $this->getRequestParameter ( 'hostname' );
623
  }
624
-
625
  /**
626
  */
627
  private function getAuthenticationTypeFromRequest() {
628
- return $this->getRequestParameter ( 'auth_type' );
629
  }
630
-
631
  /**
632
  */
633
  private function getHostDataFromRequest() {
634
- return $this->getRequestParameter ( 'host_data' );
635
  }
636
-
637
  /**
638
  */
639
  private function getUserPortOverride() {
640
- return $this->getRequestParameter ( 'user_port_override' );
641
  }
642
-
643
  /**
644
  */
645
  private function getUserAuthOverride() {
646
- return $this->getRequestParameter ( 'user_auth_override' );
647
  }
648
  }
649
  class PostmanImportConfigurationAjaxController extends PostmanAbstractAjaxHandler {
@@ -651,44 +647,44 @@ class PostmanImportConfigurationAjaxController extends PostmanAbstractAjaxHandle
651
  /**
652
  * Constructor
653
  *
654
- * @param PostmanOptions $options
655
  */
656
- function __construct(PostmanOptions $options) {
657
- parent::__construct ();
658
  $this->options = $options;
659
- PostmanUtils::registerAjaxHandler ( 'import_configuration', $this, 'getConfigurationFromExternalPluginViaAjax' );
660
  }
661
-
662
  /**
663
  * This function extracts configuration details form a competing SMTP plugin
664
  * and pushes them into the Postman configuration screen.
665
  */
666
  function getConfigurationFromExternalPluginViaAjax() {
667
- $importableConfiguration = new PostmanImportableConfiguration ();
668
- $plugin = $this->getRequestParameter ( 'plugin' );
669
- $this->logger->debug ( 'Looking for config=' . $plugin );
670
- foreach ( $importableConfiguration->getAvailableOptions () as $this->options ) {
671
- if ($this->options->getPluginSlug () == $plugin) {
672
- $this->logger->debug ( 'Sending configuration response' );
673
- $response = array (
674
- PostmanOptions::MESSAGE_SENDER_EMAIL => $this->options->getMessageSenderEmail (),
675
- PostmanOptions::MESSAGE_SENDER_NAME => $this->options->getMessageSenderName (),
676
- PostmanOptions::HOSTNAME => $this->options->getHostname (),
677
- PostmanOptions::PORT => $this->options->getPort (),
678
- PostmanOptions::AUTHENTICATION_TYPE => $this->options->getAuthenticationType (),
679
- PostmanOptions::SECURITY_TYPE => $this->options->getEncryptionType (),
680
- PostmanOptions::BASIC_AUTH_USERNAME => $this->options->getUsername (),
681
- PostmanOptions::BASIC_AUTH_PASSWORD => $this->options->getPassword (),
682
- 'success' => true
683
  );
684
  break;
685
  }
686
  }
687
- if (! isset ( $response )) {
688
- $response = array (
689
- 'success' => false
690
  );
691
  }
692
- wp_send_json ( $response );
693
  }
694
  }
1
  <?php
2
+ require_once( 'PostmanRegisterConfigurationSettings.php' );
3
  class PostmanConfigurationController {
4
  const CONFIGURATION_SLUG = 'postman/configuration';
5
  const CONFIGURATION_WIZARD_SLUG = 'postman/configuration_wizard';
6
+
7
  // logging
8
  private $logger;
9
  private $options;
10
  private $settingsRegistry;
11
+
12
  // Holds the values to be used in the fields callbacks
13
  private $rootPluginFilenameAndPath;
14
+
15
  /**
16
  * Constructor
17
  *
18
+ * @param unknown $rootPluginFilenameAndPath
19
  */
20
+ public function __construct( $rootPluginFilenameAndPath ) {
21
+ assert( ! empty( $rootPluginFilenameAndPath ) );
22
+ assert( PostmanUtils::isAdmin() );
23
+ assert( is_admin() );
24
+
25
+ $this->logger = new PostmanLogger( get_class( $this ) );
26
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
27
+ $this->options = PostmanOptions::getInstance();
28
+ $this->settingsRegistry = new PostmanSettingsRegistry();
29
+
30
+ PostmanUtils::registerAdminMenu( $this, 'addConfigurationSubmenu' );
31
+ PostmanUtils::registerAdminMenu( $this, 'addSetupWizardSubmenu' );
32
+
33
  // hook on the init event
34
+ add_action( 'init', array(
35
  $this,
36
+ 'on_init',
37
  ) );
38
+
39
  // initialize the scripts, stylesheets and form fields
40
+ add_action( 'admin_init', array(
41
  $this,
42
+ 'on_admin_init',
43
  ) );
44
  }
45
+
46
  /**
47
  * Functions to execute on the init event
48
  *
51
  */
52
  public function on_init() {
53
  // register Ajax handlers
54
+ new PostmanGetHostnameByEmailAjaxController();
55
+ new PostmanManageConfigurationAjaxHandler();
56
+ new PostmanImportConfigurationAjaxController( $this->options );
57
  }
58
+
59
  /**
60
  * Fires on the admin_init method
61
  */
62
  public function on_admin_init() {
63
+ $this->registerStylesAndScripts();
64
+ $this->settingsRegistry->on_admin_init();
 
65
  }
66
+
67
  /**
68
  * Register and add settings
69
  */
70
  private function registerStylesAndScripts() {
71
+ if ( $this->logger->isTrace() ) {
72
+ $this->logger->trace( 'registerStylesAndScripts()' );
73
  }
74
  // register the stylesheet and javascript external resources
75
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
76
+ wp_register_script( 'postman_manual_config_script', plugins_url( 'Postman/Postman-Configuration/postman_manual_config.js', $this->rootPluginFilenameAndPath ), array(
77
  PostmanViewController::JQUERY_SCRIPT,
78
  'jquery_validation',
79
+ PostmanViewController::POSTMAN_SCRIPT,
80
  ), $pluginData ['version'] );
81
+ wp_register_script( 'postman_wizard_script', plugins_url( 'Postman/Postman-Configuration/postman_wizard.js', $this->rootPluginFilenameAndPath ), array(
82
  PostmanViewController::JQUERY_SCRIPT,
83
  'jquery_validation',
84
  'jquery_steps_script',
85
  PostmanViewController::POSTMAN_SCRIPT,
86
+ 'sprintf',
87
  ), $pluginData ['version'] );
88
  }
89
+
90
  /**
91
  */
92
  private function addLocalizeScriptsToPage() {
93
+ $warning = __( 'Warning', Postman::TEXT_DOMAIN );
94
  /* translators: where %s is the name of the SMTP server */
95
+ wp_localize_script( 'postman_wizard_script', 'postman_smtp_mitm', sprintf( '%s: %s', $warning, __( 'connected to %1$s instead of %2$s.', Postman::TEXT_DOMAIN ) ) );
96
  /* translators: where %d is a port number */
97
+ wp_localize_script( 'postman_wizard_script', 'postman_wizard_bad_redirect_url', __( 'You are about to configure OAuth 2.0 with an IP address instead of a domain name. This is not permitted. Either assign a real domain name to your site or add a fake one in your local host file.', Postman::TEXT_DOMAIN ) );
98
+
99
  // user input
100
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_sender_email', '#input_' . PostmanOptions::MESSAGE_SENDER_EMAIL );
101
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_sender_name', '#input_' . PostmanOptions::MESSAGE_SENDER_NAME );
102
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_port_element_name', '#input_' . PostmanOptions::PORT );
103
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_hostname_element_name', '#input_' . PostmanOptions::HOSTNAME );
104
+
105
  // the enc input
106
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_enc_for_password_el', '#input_enc_type_password' );
107
  // these are the ids for the <option>s in the encryption <select>
 
108
  // the password inputs
109
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_basic_username', '#input_' . PostmanOptions::BASIC_AUTH_USERNAME );
110
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_basic_password', '#input_' . PostmanOptions::BASIC_AUTH_PASSWORD );
111
+
112
  // the auth input
113
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_redirect_url_el', '#input_oauth_redirect_url' );
114
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_input_auth_type', '#input_' . PostmanOptions::AUTHENTICATION_TYPE );
115
+
116
  // the transport modules scripts
117
+ foreach ( PostmanTransportRegistry::getInstance()->getTransports() as $transport ) {
118
+ $transport->enqueueScript();
119
  }
120
 
121
  // we need data from port test
122
+ PostmanConnectivityTestController::addLocalizeScriptForPortTest();
123
+
124
  }
125
+
126
  /**
127
  * Register the Configuration screen
128
  */
129
  public function addConfigurationSubmenu() {
130
+ $page = add_submenu_page( null, sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanConfigurationController::CONFIGURATION_SLUG, array(
131
  $this,
132
+ 'outputManualConfigurationContent',
133
  ) );
134
  // When the plugin options page is loaded, also load the stylesheet
135
+ add_action( 'admin_print_styles-' . $page, array(
136
  $this,
137
+ 'enqueueConfigurationResources',
138
  ) );
139
  }
140
+
141
  /**
142
  */
143
  function enqueueConfigurationResources() {
144
+ $this->addLocalizeScriptsToPage();
145
+ wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
146
+ wp_enqueue_style( 'jquery_ui_style' );
147
+ wp_enqueue_script( 'postman_manual_config_script' );
148
+ wp_enqueue_script( 'jquery-ui-tabs' );
149
  }
150
+
151
  /**
152
  * Register the Setup Wizard screen
153
  */
154
  public function addSetupWizardSubmenu() {
155
+ $page = add_submenu_page( null, sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG, array(
156
  $this,
157
+ 'outputWizardContent',
158
  ) );
159
  // When the plugin options page is loaded, also load the stylesheet
160
+ add_action( 'admin_print_styles-' . $page, array(
161
  $this,
162
+ 'enqueueWizardResources',
163
  ) );
164
  }
165
+
166
  /**
167
  */
168
  function enqueueWizardResources() {
169
+ $this->addLocalizeScriptsToPage();
170
+ $this->importableConfiguration = new PostmanImportableConfiguration();
171
  $startPage = 1;
172
+ if ( $this->importableConfiguration->isImportAvailable() ) {
173
  $startPage = 0;
174
  }
175
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_setup_wizard', array(
176
+ 'start_page' => $startPage,
177
  ) );
178
+ wp_enqueue_style( 'jquery_steps_style' );
179
+ wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
180
+ wp_enqueue_script( 'postman_wizard_script' );
181
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, '$jq', 'jQuery.noConflict(true)' );
182
+ $shortLocale = substr( get_locale(), 0, 2 );
183
+ if ( $shortLocale != 'en' ) {
184
+ $url = plugins_url( sprintf( 'script/jquery-validate/localization/messages_%s.js', $shortLocale ), $this->rootPluginFilenameAndPath );
185
+ wp_enqueue_script( sprintf( 'jquery-validation-locale-%s', $shortLocale ), $url );
186
  }
187
  }
188
+
189
  /**
190
  */
191
  public function outputManualConfigurationContent() {
192
  print '<div class="wrap">';
193
+
194
+ PostmanViewController::outputChildPageHeader( __( 'Settings', Postman::TEXT_DOMAIN ), 'advanced_config' );
195
  print '<div id="config_tabs"><ul>';
196
+ print sprintf( '<li><a href="#account_config">%s</a></li>', __( 'Account', Postman::TEXT_DOMAIN ) );
197
+ print sprintf( '<li><a href="#message_config">%s</a></li>', __( 'Message', Postman::TEXT_DOMAIN ) );
198
+ print sprintf( '<li><a href="#logging_config">%s</a></li>', __( 'Logging', Postman::TEXT_DOMAIN ) );
199
+ print sprintf( '<li><a href="#advanced_options_config">%s</a></li>', __( 'Advanced', Postman::TEXT_DOMAIN ) );
200
  print '</ul>';
201
  print '<form method="post" action="options.php">';
202
  // This prints out all hidden setting fields
203
+ settings_fields( PostmanAdminController::SETTINGS_GROUP_NAME );
204
  print '<section id="account_config">';
205
+ if ( sizeof( PostmanTransportRegistry::getInstance()->getTransports() ) > 1 ) {
206
+ do_settings_sections( 'transport_options' );
207
  } else {
208
+ printf( '<input id="input_%2$s" type="hidden" name="%1$s[%2$s]" value="%3$s"/>', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::TRANSPORT_TYPE, PostmanSmtpModuleTransport::SLUG );
209
  }
210
  print '<div id="smtp_config" class="transport_setting">';
211
+ do_settings_sections( PostmanAdminController::SMTP_OPTIONS );
212
  print '</div>';
213
  print '<div id="password_settings" class="authentication_setting non-oauth2">';
214
+ do_settings_sections( PostmanAdminController::BASIC_AUTH_OPTIONS );
215
  print '</div>';
216
  print '<div id="oauth_settings" class="authentication_setting non-basic">';
217
+ do_settings_sections( PostmanAdminController::OAUTH_AUTH_OPTIONS );
218
  print '</div>';
219
  print '<div id="mandrill_settings" class="authentication_setting non-basic non-oauth2">';
220
+ do_settings_sections( PostmanMandrillTransport::MANDRILL_AUTH_OPTIONS );
221
  print '</div>';
222
  print '<div id="sendgrid_settings" class="authentication_setting non-basic non-oauth2">';
223
+ do_settings_sections( PostmanSendGridTransport::SENDGRID_AUTH_OPTIONS );
224
  print '</div>';
225
  print '</section>';
226
  print '<section id="message_config">';
227
+ do_settings_sections( PostmanAdminController::MESSAGE_SENDER_OPTIONS );
228
+ do_settings_sections( PostmanAdminController::MESSAGE_FROM_OPTIONS );
229
+ do_settings_sections( PostmanAdminController::EMAIL_VALIDATION_OPTIONS );
230
+ do_settings_sections( PostmanAdminController::MESSAGE_OPTIONS );
231
+ do_settings_sections( PostmanAdminController::MESSAGE_HEADERS_OPTIONS );
232
  print '</section>';
233
  print '<section id="logging_config">';
234
+ do_settings_sections( PostmanAdminController::LOGGING_OPTIONS );
235
  print '</section>';
236
  /*
237
  * print '<section id="logging_config">';
239
  * print '</section>';
240
  */
241
  print '<section id="advanced_options_config">';
242
+ do_settings_sections( PostmanAdminController::NETWORK_OPTIONS );
243
+ do_settings_sections( PostmanAdminController::ADVANCED_OPTIONS );
244
  print '</section>';
245
+ submit_button();
246
  print '</form>';
247
  print '</div>';
248
  print '</div>';
249
  }
250
+
251
  /**
252
  */
253
  public function outputWizardContent() {
254
  // Set default values for input fields
255
+ $this->options->setMessageSenderEmailIfEmpty( wp_get_current_user()->user_email );
256
+ $this->options->setMessageSenderNameIfEmpty( wp_get_current_user()->display_name );
257
+
258
  // construct Wizard
259
  print '<div class="wrap">';
260
+
261
+ PostmanViewController::outputChildPageHeader( __( 'Setup Wizard', Postman::TEXT_DOMAIN ) );
262
+
263
  print '<form id="postman_wizard" method="post" action="options.php">';
264
+
265
  // account tab
 
266
  // message tab
267
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE, $this->options->isPluginSenderEmailEnforced() );
268
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE, $this->options->isPluginSenderNameEnforced() );
269
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::REPLY_TO, $this->options->getReplyTo() );
270
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::FORCED_TO_RECIPIENTS, $this->options->getForcedToRecipients() );
271
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::FORCED_CC_RECIPIENTS, $this->options->getForcedCcRecipients() );
272
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::FORCED_BCC_RECIPIENTS, $this->options->getForcedBccRecipients() );
273
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::ADDITIONAL_HEADERS, $this->options->getAdditionalHeaders() );
274
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::DISABLE_EMAIL_VALIDAITON, $this->options->isEmailValidationDisabled() );
275
+
276
  // logging tab
277
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::MAIL_LOG_ENABLED_OPTION, $this->options->getMailLoggingEnabled() );
278
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::MAIL_LOG_MAX_ENTRIES, $this->options->getMailLoggingMaxEntries() );
279
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::TRANSCRIPT_SIZE, $this->options->getTranscriptSize() );
280
+
281
  // advanced tab
282
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::CONNECTION_TIMEOUT, $this->options->getConnectionTimeout() );
283
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::READ_TIMEOUT, $this->options->getReadTimeout() );
284
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::LOG_LEVEL, $this->options->getLogLevel() );
285
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::RUN_MODE, $this->options->getRunMode() );
286
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::STEALTH_MODE, $this->options->isStealthModeEnabled() );
287
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]" value="%3$s" />', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::TEMPORARY_DIRECTORY, $this->options->getTempDirectory() );
288
+
289
  // display the setting text
290
+ settings_fields( PostmanAdminController::SETTINGS_GROUP_NAME );
291
+
292
  // Wizard Step 0
293
+ printf( '<h5>%s</h5>', _x( 'Import Configuration', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
294
  print '<fieldset>';
295
+ printf( '<legend>%s</legend>', _x( 'Import configuration from another plugin?', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
296
+ printf( '<p>%s</p>', __( 'If you had a working configuration with another Plugin, the Setup Wizard can begin with those settings.', Postman::TEXT_DOMAIN ) );
297
  print '<table class="input_auth_type">';
298
+ printf( '<tr><td><input type="radio" id="import_none" name="input_plugin" value="%s" checked="checked"></input></td><td><label> %s</label></td></tr>', 'none', __( 'None', Postman::TEXT_DOMAIN ) );
299
+
300
+ if ( $this->importableConfiguration->isImportAvailable() ) {
301
+ foreach ( $this->importableConfiguration->getAvailableOptions() as $options ) {
302
+ printf( '<tr><td><input type="radio" name="input_plugin" value="%s"/></td><td><label> %s</label></td></tr>', $options->getPluginSlug(), $options->getPluginName() );
303
  }
304
  }
305
  print '</table>';
306
  print '</fieldset>';
307
+
308
  // Wizard Step 1
309
+ printf( '<h5>%s</h5>', _x( 'Sender Details', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
310
  print '<fieldset>';
311
+ printf( '<legend>%s</legend>', _x( 'Who is the mail coming from?', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
312
+ printf( '<p>%s</p>', __( 'Enter the email address and name you\'d like to send mail as.', Postman::TEXT_DOMAIN ) );
313
+ printf( '<p>%s</p>', __( 'Please note that to prevent abuse, many email services will <em>not</em> let you send from an email address other than the one you authenticate with.', Postman::TEXT_DOMAIN ) );
314
+ printf( '<label for="postman_options[sender_email]">%s</label>', __( 'Email Address', Postman::TEXT_DOMAIN ) );
315
+ print $this->settingsRegistry->from_email_callback();
316
  print '<br/>';
317
+ printf( '<label for="postman_options[sender_name]">%s</label>', __( 'Name', Postman::TEXT_DOMAIN ) );
318
+ print $this->settingsRegistry->sender_name_callback();
319
  print '</fieldset>';
320
+
321
  // Wizard Step 2
322
+ printf( '<h5>%s</h5>', __( 'Outgoing Mail Server Hostname', Postman::TEXT_DOMAIN ) );
323
  print '<fieldset>';
324
+ foreach ( PostmanTransportRegistry::getInstance()->getTransports() as $transport ) {
325
+ $transport->printWizardMailServerHostnameStep();
326
  }
327
  print '</fieldset>';
328
+
329
  // Wizard Step 3
330
+ printf( '<h5>%s</h5>', __( 'Connectivity Test', Postman::TEXT_DOMAIN ) );
331
  print '<fieldset>';
332
+ printf( '<legend>%s</legend>', __( 'How will the connection to the mail server be established?', Postman::TEXT_DOMAIN ) );
333
+ printf( '<p>%s</p>', __( 'Your connection settings depend on what your email service provider offers, and what your WordPress host allows.', Postman::TEXT_DOMAIN ) );
334
+ printf( '<p id="connectivity_test_status">%s: <span id="port_test_status">%s</span></p>', __( 'Connectivity Test', Postman::TEXT_DOMAIN ), _x( 'Ready', 'TCP Port Test Status', Postman::TEXT_DOMAIN ) );
335
+ printf( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url( 'post-smtp/style/ajax-loader.gif' ) );
336
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::TRANSPORT_TYPE );
337
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::PORT );
338
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::SECURITY_TYPE );
339
+ printf( '<input type="hidden" id="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::AUTHENTICATION_TYPE );
340
  print '<p id="wizard_recommendation"></p>';
341
  /* Translators: Where %1$s is the socket identifier and %2$s is the authentication type */
342
+ printf( '<p class="user_override" style="display:none"><label><span>%s:</span></label> <table id="user_socket_override" class="user_override"></table></p>', _x( 'Socket', 'A socket is the network term for host and port together', Postman::TEXT_DOMAIN ) );
343
+ printf( '<p class="user_override" style="display:none"><label><span>%s:</span></label> <table id="user_auth_override" class="user_override"></table></p>', __( 'Authentication', Postman::TEXT_DOMAIN ) );
344
  print ('<p><span id="smtp_mitm" style="display:none; background-color:yellow"></span></p>') ;
345
+ $warning = __( 'Warning', Postman::TEXT_DOMAIN );
346
+ $clearCredentialsWarning = __( 'This configuration option will send your authorization credentials in the clear.', Postman::TEXT_DOMAIN );
347
+ printf( '<p id="smtp_not_secure" style="display:none"><span style="background-color:yellow">%s: %s</span></p>', $warning, $clearCredentialsWarning );
348
  print '</fieldset>';
349
+
350
  // Wizard Step 4
351
+ printf( '<h5>%s</h5>', __( 'Authentication', Postman::TEXT_DOMAIN ) );
352
  print '<fieldset>';
353
+ printf( '<legend>%s</legend>', __( 'How will you prove your identity to the mail server?', Postman::TEXT_DOMAIN ) );
354
+ foreach ( PostmanTransportRegistry::getInstance()->getTransports() as $transport ) {
355
+ $transport->printWizardAuthenticationStep();
356
  }
357
  print '</fieldset>';
358
+
359
  // Wizard Step 5
360
+ printf( '<h5>%s</h5>', _x( 'Finish', 'The final step of the Wizard', Postman::TEXT_DOMAIN ) );
361
  print '<fieldset>';
362
+ printf( '<legend>%s</legend>', _x( 'You\'re Done!', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
363
  print '<section>';
364
+ printf( '<p>%s</p>', __( 'Click Finish to save these settings, then:', Postman::TEXT_DOMAIN ) );
365
  print '<ul style="margin-left: 20px">';
366
+ printf( '<li class="wizard-auth-oauth2">%s</li>', __( 'Grant permission with the Email Provider for Postman to send email and', Postman::TEXT_DOMAIN ) );
367
+ printf( '<li>%s</li>', __( 'Send yourself a Test Email to make sure everything is working!', Postman::TEXT_DOMAIN ) );
368
  print '</ul>';
369
  print '</section>';
370
  print '</fieldset>';
376
  /**
377
  *
378
  * @author jasonhendriks
 
379
  */
380
  class PostmanGetHostnameByEmailAjaxController extends PostmanAbstractAjaxHandler {
381
  const IS_GOOGLE_PARAMETER = 'is_google';
382
  function __construct() {
383
+ parent::__construct();
384
+ PostmanUtils::registerAjaxHandler( 'postman_check_email', $this, 'getAjaxHostnameByEmail' );
385
  }
386
  /**
387
  * This Ajax function retrieves the smtp hostname for a give e-mail address
388
  */
389
  function getAjaxHostnameByEmail() {
390
+ $goDaddyHostDetected = $this->getBooleanRequestParameter( 'go_daddy' );
391
+ $email = $this->getRequestParameter( 'email' );
392
+ $d = new PostmanSmtpDiscovery( $email );
393
+ $smtp = $d->getSmtpServer();
394
+ $this->logger->debug( 'given email ' . $email . ', smtp server is ' . $smtp );
395
+ $this->logger->trace( $d );
396
+ if ( $goDaddyHostDetected && ! $d->isGoogle ) {
397
  // override with the GoDaddy SMTP server
398
  $smtp = 'relay-hosting.secureserver.net';
399
+ $this->logger->debug( 'detected GoDaddy SMTP server, smtp server is ' . $smtp );
400
  }
401
+ $response = array(
402
  'hostname' => $smtp,
403
  self::IS_GOOGLE_PARAMETER => $d->isGoogle,
404
  'is_go_daddy' => $d->isGoDaddy,
405
+ 'is_well_known' => $d->isWellKnownDomain,
406
  );
407
+ $this->logger->trace( $response );
408
+ wp_send_json_success( $response );
409
  }
410
  }
411
  class PostmanManageConfigurationAjaxHandler extends PostmanAbstractAjaxHandler {
412
  function __construct() {
413
+ parent::__construct();
414
+ PostmanUtils::registerAjaxHandler( 'manual_config', $this, 'getManualConfigurationViaAjax' );
415
+ PostmanUtils::registerAjaxHandler( 'get_wizard_configuration_options', $this, 'getWizardConfigurationViaAjax' );
416
  }
417
+
418
  /**
419
  * Handle a Advanced Configuration request with Ajax
420
  *
421
  * @throws Exception
422
  */
423
  function getManualConfigurationViaAjax() {
424
+ $queryTransportType = $this->getTransportTypeFromRequest();
425
+ $queryAuthType = $this->getAuthenticationTypeFromRequest();
426
+ $queryHostname = $this->getHostnameFromRequest();
427
+
428
  // the outgoing server hostname is only required for the SMTP Transport
429
  // the Gmail API transport doesn't use an SMTP server
430
+ $transport = PostmanTransportRegistry::getInstance()->getTransport( $queryTransportType );
431
+ if ( ! $transport ) {
432
+ throw new Exception( 'Unable to find transport ' . $queryTransportType );
433
  }
434
+
435
  // create the response
436
+ $response = $transport->populateConfiguration( $queryHostname );
437
  $response ['referer'] = 'manual_config';
438
+
439
  // set the display_auth to oauth2 if the transport needs it
440
+ if ( $transport->isOAuthUsed( $queryAuthType ) ) {
441
  $response ['display_auth'] = 'oauth2';
442
+ $this->logger->debug( 'ajaxRedirectUrl answer display_auth:' . $response ['display_auth'] );
443
  }
444
+ $this->logger->trace( $response );
445
+ wp_send_json_success( $response );
446
  }
447
+
448
  /**
449
  * Once the Port Tests have run, the results are analyzed.
450
  * The Transport place bids on the sockets and highest bid becomes the recommended
451
  * The UI response is built so the user may choose a different socket with different options.
452
  */
453
  function getWizardConfigurationViaAjax() {
454
+ $this->logger->debug( 'in getWizardConfiguration' );
455
+ $originalSmtpServer = $this->getRequestParameter( 'original_smtp_server' );
456
+ $queryHostData = $this->getHostDataFromRequest();
457
+ $sockets = array();
458
  foreach ( $queryHostData as $id => $datum ) {
459
+ array_push( $sockets, new PostmanWizardSocket( $datum ) );
460
  }
461
+ $this->logger->error( $sockets );
462
+ $userPortOverride = $this->getUserPortOverride();
463
+ $userAuthOverride = $this->getUserAuthOverride();
464
+
465
  // determine a configuration recommendation
466
+ $winningRecommendation = $this->getWinningRecommendation( $sockets, $userPortOverride, $userAuthOverride, $originalSmtpServer );
467
+ if ( $this->logger->isTrace() ) {
468
+ $this->logger->trace( 'winning recommendation:' );
469
+ $this->logger->trace( $winningRecommendation );
470
  }
471
+
472
  // create the reponse
473
+ $response = array();
474
+ $configuration = array();
475
  $response ['referer'] = 'wizard';
476
+ if ( isset( $userPortOverride ) || isset( $userAuthOverride ) ) {
477
  $configuration ['user_override'] = true;
478
  }
479
+
480
+ if ( isset( $winningRecommendation ) ) {
481
+
482
  // create an appropriate (theoretical) transport
483
+ $transport = PostmanTransportRegistry::getInstance()->getTransport( $winningRecommendation ['transport'] );
484
+
485
  // create user override menu
486
+ $overrideMenu = $this->createOverrideMenus( $sockets, $winningRecommendation, $userPortOverride, $userAuthOverride );
487
+ if ( $this->logger->isTrace() ) {
488
+ $this->logger->trace( 'override menu:' );
489
+ $this->logger->trace( $overrideMenu );
490
  }
491
+
492
  $queryHostName = $winningRecommendation ['hostname'];
493
+ if ( $this->logger->isDebug() ) {
494
+ $this->logger->debug( 'Getting scribe for ' . $queryHostName );
495
  }
496
+ $generalConfig1 = $transport->populateConfiguration( $queryHostName );
497
+ $generalConfig2 = $transport->populateConfigurationFromRecommendation( $winningRecommendation );
498
+ $configuration = array_merge( $configuration, $generalConfig1, $generalConfig2 );
499
  $response ['override_menu'] = $overrideMenu;
500
  $response ['configuration'] = $configuration;
501
+ if ( $this->logger->isTrace() ) {
502
+ $this->logger->trace( 'configuration:' );
503
+ $this->logger->trace( $configuration );
504
+ $this->logger->trace( 'response:' );
505
+ $this->logger->trace( $response );
506
  }
507
+ wp_send_json_success( $response );
508
  } else {
509
  /* translators: where %s is the URL to the Connectivity Test page */
510
+ $configuration ['message'] = sprintf( __( 'Postman can\'t find any way to send mail on your system. Run a <a href="%s">connectivity test</a>.', Postman::TEXT_DOMAIN ), PostmanViewController::getPageUrl( PostmanViewController::PORT_TEST_SLUG ) );
511
  $response ['configuration'] = $configuration;
512
+ if ( $this->logger->isTrace() ) {
513
+ $this->logger->trace( 'configuration:' );
514
+ $this->logger->trace( $configuration );
515
  }
516
+ wp_send_json_error( $response );
517
  }
518
  }
519
+
520
  /**
521
  * // for each successful host/port combination
522
  * // ask a transport if they support it, and if they do at what priority is it
523
  * // configure for the highest priority you find
524
  *
525
+ * @param unknown $queryHostData
526
  * @return unknown
527
  */
528
+ private function getWinningRecommendation( $sockets, $userSocketOverride, $userAuthOverride, $originalSmtpServer ) {
529
  foreach ( $sockets as $socket ) {
530
+ $winningRecommendation = $this->getWin( $socket, $userSocketOverride, $userAuthOverride, $originalSmtpServer );
531
+ $this->logger->error( $socket->label );
532
  }
533
  return $winningRecommendation;
534
  }
535
+
536
  /**
537
  *
538
+ * @param PostmanSocket $socket
539
+ * @param unknown $userSocketOverride
540
+ * @param unknown $userAuthOverride
541
+ * @param unknown $originalSmtpServer
542
  * @return Ambigous <NULL, unknown, string>
543
  */
544
+ private function getWin( PostmanWizardSocket $socket, $userSocketOverride, $userAuthOverride, $originalSmtpServer ) {
545
  static $recommendationPriority = - 1;
546
  static $winningRecommendation = null;
547
  $available = $socket->success;
548
+ if ( $available ) {
549
+ $this->logger->debug( sprintf( 'Asking for judgement on %s:%s', $socket->hostname, $socket->port ) );
550
+ $recommendation = PostmanTransportRegistry::getInstance()->getRecommendation( $socket, $userAuthOverride, $originalSmtpServer );
551
+ $recommendationId = sprintf( '%s_%s', $socket->hostname, $socket->port );
552
  $recommendation ['id'] = $recommendationId;
553
+ $this->logger->debug( sprintf( 'Got a recommendation: [%d] %s', $recommendation ['priority'], $recommendationId ) );
554
+ if ( isset( $userSocketOverride ) ) {
555
+ if ( $recommendationId == $userSocketOverride ) {
556
  $winningRecommendation = $recommendation;
557
+ $this->logger->debug( sprintf( 'User chosen socket %s is the winner', $recommendationId ) );
558
  }
559
+ } elseif ( $recommendation && $recommendation ['priority'] > $recommendationPriority ) {
560
  $recommendationPriority = $recommendation ['priority'];
561
  $winningRecommendation = $recommendation;
562
  }
564
  }
565
  return $winningRecommendation;
566
  }
567
+
568
  /**
569
  *
570
+ * @param unknown $queryHostData
571
  * @return multitype:
572
  */
573
+ private function createOverrideMenus( $sockets, $winningRecommendation, $userSocketOverride, $userAuthOverride ) {
574
+ $overrideMenu = array();
575
  foreach ( $sockets as $socket ) {
576
+ $overrideItem = $this->createOverrideMenu( $socket, $winningRecommendation, $userSocketOverride, $userAuthOverride );
577
+ if ( $overrideItem != null ) {
578
+ $overrideMenu [ $socket->id ] = $overrideItem;
579
  }
580
  }
581
+
582
  // sort
583
+ krsort( $overrideMenu );
584
+ $sortedMenu = array();
585
  foreach ( $overrideMenu as $menu ) {
586
+ array_push( $sortedMenu, $menu );
587
  }
588
+
589
  return $sortedMenu;
590
  }
591
+
592
  /**
593
  *
594
+ * @param PostmanWizardSocket $socket
595
+ * @param unknown $winningRecommendation
596
+ * @param unknown $userSocketOverride
597
+ * @param unknown $userAuthOverride
598
  */
599
+ private function createOverrideMenu( PostmanWizardSocket $socket, $winningRecommendation, $userSocketOverride, $userAuthOverride ) {
600
+ if ( $socket->success ) {
601
+ $transport = PostmanTransportRegistry::getInstance()->getTransport( $socket->transport );
602
+ $this->logger->debug( sprintf( 'Transport %s is building the override menu for socket', $transport->getSlug() ) );
603
+ $overrideItem = $transport->createOverrideMenu( $socket, $winningRecommendation, $userSocketOverride, $userAuthOverride );
604
  return $overrideItem;
605
  }
606
  return null;
607
  }
608
+
609
  /**
610
  */
611
  private function getTransportTypeFromRequest() {
612
+ return $this->getRequestParameter( 'transport' );
613
  }
614
+
615
  /**
616
  */
617
  private function getHostnameFromRequest() {
618
+ return $this->getRequestParameter( 'hostname' );
619
  }
620
+
621
  /**
622
  */
623
  private function getAuthenticationTypeFromRequest() {
624
+ return $this->getRequestParameter( 'auth_type' );
625
  }
626
+
627
  /**
628
  */
629
  private function getHostDataFromRequest() {
630
+ return $this->getRequestParameter( 'host_data' );
631
  }
632
+
633
  /**
634
  */
635
  private function getUserPortOverride() {
636
+ return $this->getRequestParameter( 'user_port_override' );
637
  }
638
+
639
  /**
640
  */
641
  private function getUserAuthOverride() {
642
+ return $this->getRequestParameter( 'user_auth_override' );
643
  }
644
  }
645
  class PostmanImportConfigurationAjaxController extends PostmanAbstractAjaxHandler {
647
  /**
648
  * Constructor
649
  *
650
+ * @param PostmanOptions $options
651
  */
652
+ function __construct( PostmanOptions $options ) {
653
+ parent::__construct();
654
  $this->options = $options;
655
+ PostmanUtils::registerAjaxHandler( 'import_configuration', $this, 'getConfigurationFromExternalPluginViaAjax' );
656
  }
657
+
658
  /**
659
  * This function extracts configuration details form a competing SMTP plugin
660
  * and pushes them into the Postman configuration screen.
661
  */
662
  function getConfigurationFromExternalPluginViaAjax() {
663
+ $importableConfiguration = new PostmanImportableConfiguration();
664
+ $plugin = $this->getRequestParameter( 'plugin' );
665
+ $this->logger->debug( 'Looking for config=' . $plugin );
666
+ foreach ( $importableConfiguration->getAvailableOptions() as $this->options ) {
667
+ if ( $this->options->getPluginSlug() == $plugin ) {
668
+ $this->logger->debug( 'Sending configuration response' );
669
+ $response = array(
670
+ PostmanOptions::MESSAGE_SENDER_EMAIL => $this->options->getMessageSenderEmail(),
671
+ PostmanOptions::MESSAGE_SENDER_NAME => $this->options->getMessageSenderName(),
672
+ PostmanOptions::HOSTNAME => $this->options->getHostname(),
673
+ PostmanOptions::PORT => $this->options->getPort(),
674
+ PostmanOptions::AUTHENTICATION_TYPE => $this->options->getAuthenticationType(),
675
+ PostmanOptions::SECURITY_TYPE => $this->options->getEncryptionType(),
676
+ PostmanOptions::BASIC_AUTH_USERNAME => $this->options->getUsername(),
677
+ PostmanOptions::BASIC_AUTH_PASSWORD => $this->options->getPassword(),
678
+ 'success' => true,
679
  );
680
  break;
681
  }
682
  }
683
+ if ( ! isset( $response ) ) {
684
+ $response = array(
685
+ 'success' => false,
686
  );
687
  }
688
+ wp_send_json( $response );
689
  }
690
  }
Postman/Postman-Connectivity-Test/PostmanConnectivityTestController.php CHANGED
@@ -1,45 +1,43 @@
1
  <?php
2
 
3
- //
4
  class PostmanConnectivityTestController {
5
-
6
- //
7
- const PORT_TEST_SLUG = 'postman/port_test';
8
-
9
  // logging
10
  private $logger;
11
-
12
  // Holds the values to be used in the fields callbacks
13
  private $rootPluginFilenameAndPath;
14
-
15
  /**
16
  * Constructor
17
  *
18
- * @param unknown $rootPluginFilenameAndPath
19
  */
20
- public function __construct($rootPluginFilenameAndPath) {
21
- assert ( ! empty ( $rootPluginFilenameAndPath ) );
22
- assert ( PostmanUtils::isAdmin () );
23
- assert ( is_admin () );
24
-
25
- $this->logger = new PostmanLogger ( get_class ( $this ) );
26
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
27
-
28
- PostmanUtils::registerAdminMenu ( $this, 'addPortTestSubmenu' );
29
-
30
  // hook on the init event
31
- add_action ( 'init', array (
32
  $this,
33
- 'on_init'
34
  ) );
35
-
36
  // initialize the scripts, stylesheets and form fields
37
- add_action ( 'admin_init', array (
38
  $this,
39
- 'on_admin_init'
40
  ) );
41
  }
42
-
43
  /**
44
  * Functions to execute on the init event
45
  *
@@ -48,133 +46,132 @@ class PostmanConnectivityTestController {
48
  */
49
  public function on_init() {
50
  // register Ajax handlers
51
- new PostmanPortTestAjaxController ();
52
  }
53
-
54
  /**
55
  * Fires on the admin_init method
56
  */
57
  public function on_admin_init() {
58
- //
59
- $this->registerStylesAndScripts ();
60
  }
61
-
62
  /**
63
  * Register and add settings
64
  */
65
  private function registerStylesAndScripts() {
66
- if ($this->logger->isTrace ()) {
67
- $this->logger->trace ( 'registerStylesAndScripts()' );
68
  }
69
  // register the stylesheet and javascript external resources
70
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
71
- wp_register_script ( 'postman_port_test_script', plugins_url ( 'Postman/Postman-Connectivity-Test/postman_port_test.js', $this->rootPluginFilenameAndPath ), array (
72
  PostmanViewController::JQUERY_SCRIPT,
73
  'jquery_validation',
74
  PostmanViewController::POSTMAN_SCRIPT,
75
- 'sprintf'
76
  ), $pluginData ['version'] );
77
  }
78
-
79
  /**
80
  * Register the Email Test screen
81
  */
82
  public function addPortTestSubmenu() {
83
- $page = add_submenu_page ( null, sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanConnectivityTestController::PORT_TEST_SLUG, array (
84
  $this,
85
- 'outputPortTestContent'
86
  ) );
87
  // When the plugin options page is loaded, also load the stylesheet
88
- add_action ( 'admin_print_styles-' . $page, array (
89
  $this,
90
- 'enqueuePortTestResources'
91
  ) );
92
  }
93
-
94
  /**
95
  */
96
  function enqueuePortTestResources() {
97
- wp_enqueue_style ( PostmanViewController::POSTMAN_STYLE );
98
- wp_enqueue_script ( 'postman_port_test_script' );
99
- $warning = __ ( 'Warning', Postman::TEXT_DOMAIN );
100
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_hostname_element_name', '#input_' . PostmanOptions::HOSTNAME );
101
- PostmanConnectivityTestController::addLocalizeScriptForPortTest ();
102
  }
103
  static function addLocalizeScriptForPortTest() {
104
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_port_test', array (
105
- 'in_progress' => _x ( 'Checking..', 'The "please wait" message', Postman::TEXT_DOMAIN ),
106
- 'open' => _x ( 'Open', 'The port is open', Postman::TEXT_DOMAIN ),
107
- 'closed' => _x ( 'Closed', 'The port is closed', Postman::TEXT_DOMAIN ),
108
- 'yes' => __ ( 'Yes', Postman::TEXT_DOMAIN ),
109
- 'no' => __ ( 'No', Postman::TEXT_DOMAIN ),
110
- /* translators: where %d is a port number */
111
- 'blocked' => __ ( 'No outbound route between this site and the Internet on Port %d.', Postman::TEXT_DOMAIN ),
112
- /* translators: where %d is a port number and %s is a hostname */
113
- 'try_dif_smtp' => __ ( 'Port %d is open, but not to %s.', Postman::TEXT_DOMAIN ),
114
- /* translators: where %d is the port number and %s is the hostname */
115
- 'success' => __ ( 'Port %d can be used for SMTP to %s.', Postman::TEXT_DOMAIN ),
116
- 'mitm' => sprintf ( '%s: %s', __ ( 'Warning', Postman::TEXT_DOMAIN ), __ ( 'connected to %1$s instead of %2$s.', Postman::TEXT_DOMAIN ) ),
117
- /* translators: where %d is a port number and %s is the URL for the Postman Gmail Extension */
118
- 'https_success' => __ ( 'Port %d can be used with the %s.', Postman::TEXT_DOMAIN )
119
  ) );
120
  }
121
-
122
  /**
123
  * Get the settings option array and print one of its values
124
  */
125
  public function port_test_hostname_callback() {
126
- $hostname = PostmanTransportRegistry::getInstance ()->getSelectedTransport ()->getHostname ();
127
- if (empty ( $hostname )) {
128
- $hostname = PostmanTransportRegistry::getInstance ()->getActiveTransport ()->getHostname ();
129
  }
130
- printf ( '<input type="text" id="input_hostname" name="postman_options[hostname]" value="%s" size="40" class="required"/>', $hostname );
131
  }
132
-
133
  /**
134
  */
135
  public function outputPortTestContent() {
136
  print '<div class="wrap">';
137
-
138
- PostmanViewController::outputChildPageHeader ( __ ( 'Connectivity Test', Postman::TEXT_DOMAIN ) );
139
-
140
  print '<p>';
141
- print __ ( 'This test determines which well-known ports are available for Postman to use.', Postman::TEXT_DOMAIN );
142
  print '<form id="port_test_form_id" method="post">';
143
- printf ( '<label for="hostname">%s</label>', __ ( 'Outgoing Mail Server Hostname', Postman::TEXT_DOMAIN ) );
144
- $this->port_test_hostname_callback ();
145
- submit_button ( _x ( 'Begin Test', 'Button Label', Postman::TEXT_DOMAIN ), 'primary', 'begin-port-test', true );
146
  print '</form>';
147
  print '<table id="connectivity_test_table">';
148
- print sprintf ( '<tr><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th colspan="5">%s</th></tr>', __ ( 'Transport', Postman::TEXT_DOMAIN ), _x ( 'Socket', 'A socket is the network term for host and port together', Postman::TEXT_DOMAIN ), __ ( 'Status', Postman::TEXT_DOMAIN ) . '<sup>*</sup>', __ ( 'Service Available', Postman::TEXT_DOMAIN ), __ ( 'Server ID', Postman::TEXT_DOMAIN ), __ ( 'Authentication', Postman::TEXT_DOMAIN ) );
149
- print sprintf ( '<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>', 'None', 'Login', 'Plain', 'CRAM-MD5', 'OAuth 2.0' );
150
- $sockets = PostmanTransportRegistry::getInstance ()->getSocketsForSetupWizardToProbe ();
151
  foreach ( $sockets as $socket ) {
152
- if ($socket ['smtp']) {
153
- print sprintf ( '<tr id="%s"><th class="name">%s</th><td class="socket">%s:%s</td><td class="firewall resettable">-</td><td class="service resettable">-</td><td class="reported_id resettable">-</td><td class="auth_none resettable">-</td><td class="auth_login resettable">-</td><td class="auth_plain resettable">-</td><td class="auth_crammd5 resettable">-</td><td class="auth_xoauth2 resettable">-</td></tr>', $socket ['id'], $socket ['transport_name'], $socket ['host'], $socket ['port'] );
154
  } else {
155
- print sprintf ( '<tr id="%s"><th class="name">%s</th><td class="socket">%s:%s</td><td class="firewall resettable">-</td><td class="service resettable">-</td><td class="reported_id resettable">-</td><td colspan="5">%s</td></tr>', $socket ['id'], $socket ['transport_name'], $socket ['host'], $socket ['port'], __ ( 'n/a', Postman::TEXT_DOMAIN ) );
156
  }
157
  }
158
  print '</table>';
159
  /* Translators: Where %s is the name of the service providing Internet connectivity test */
160
- printf ( '<p class="portquiz" style="display:none; font-size:0.8em">* %s</p>', sprintf ( __ ( 'According to %s', Postman::TEXT_DOMAIN ), '<a target="_new" href="http://ww.downor.me/portquiz.net">portquiz.net</a>' ) );
161
- printf ( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url ( 'postman-smtp/style/ajax-loader.gif' ) );
162
  print '<section id="conclusion" style="display:none">';
163
- print sprintf ( '<h3>%s:</h3>', __ ( 'Summary', Postman::TEXT_DOMAIN ) );
164
  print '<ol class="conclusion">';
165
  print '</ol>';
166
  print '</section>';
167
  print '<section id="blocked-port-help" style="display:none">';
168
- print sprintf ( '<p><b>%s</b></p>', __ ( 'A test with <span style="color:red">"No"</span> Service Available indicates one or more of these issues:', Postman::TEXT_DOMAIN ) );
169
  print '<ol>';
170
- printf ( '<li>%s</li>', __ ( 'Your web host has placed a firewall between this site and the Internet', Postman::TEXT_DOMAIN ) );
171
- printf ( '<li>%s</li>', __ ( 'The SMTP hostname is wrong or the mail server does not provide service on this port', Postman::TEXT_DOMAIN ) );
172
  /* translators: where (1) is the URL and (2) is the system */
173
- $systemBlockMessage = __ ( 'Your <a href="%1$s">%2$s configuration</a> is preventing outbound connections', Postman::TEXT_DOMAIN );
174
- printf ( '<li>%s</li>', sprintf ( $systemBlockMessage, 'http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen', 'PHP' ) );
175
- printf ( '<li>%s</li>', sprintf ( $systemBlockMessage, 'http://wp-mix.com/disable-external-url-requests/', 'WordPress' ) );
176
  print '</ol></p>';
177
- print sprintf ( '<p><b>%s</b></p>', __ ( 'If the issues above can not be resolved, your last option is to configure Postman to use an email account managed by your web host with an SMTP server managed by your web host.', Postman::TEXT_DOMAIN ) );
178
  print '</section>';
179
  print '</div>';
180
  }
@@ -183,25 +180,24 @@ class PostmanConnectivityTestController {
183
  /**
184
  *
185
  * @author jasonhendriks
186
- *
187
  */
188
  class PostmanPortTestAjaxController {
189
  private $logger;
190
  /**
191
  * Constructor
192
  *
193
- * @param PostmanOptions $options
194
  */
195
  function __construct() {
196
- $this->logger = new PostmanLogger ( get_class ( $this ) );
197
- PostmanUtils::registerAjaxHandler ( 'postman_get_hosts_to_test', $this, 'getPortsToTestViaAjax' );
198
- PostmanUtils::registerAjaxHandler ( 'postman_wizard_port_test', $this, 'runSmtpTest' );
199
- PostmanUtils::registerAjaxHandler ( 'postman_wizard_port_test_smtps', $this, 'runSmtpsTest' );
200
- PostmanUtils::registerAjaxHandler ( 'postman_port_quiz_test', $this, 'runPortQuizTest' );
201
- PostmanUtils::registerAjaxHandler ( 'postman_test_port', $this, 'runSmtpTest' );
202
- PostmanUtils::registerAjaxHandler ( 'postman_test_smtps', $this, 'runSmtpsTest' );
203
  }
204
-
205
  /**
206
  * This Ajax function determines which hosts/ports to test in both the Wizard Connectivity Test and direct Connectivity Test
207
  *
@@ -209,79 +205,79 @@ class PostmanPortTestAjaxController {
209
  * combinations to run the connectivity test on
210
  */
211
  function getPortsToTestViaAjax() {
212
- $queryHostname = PostmanUtils::getRequestParameter ( 'hostname' );
213
  // originalSmtpServer is what SmtpDiscovery thinks the SMTP server should be, given an email address
214
- $originalSmtpServer = PostmanUtils::getRequestParameter ( 'original_smtp_server' );
215
- if ($this->logger->isDebug ()) {
216
- $this->logger->debug ( 'Probing available transports for sockets against hostname ' . $queryHostname );
217
  }
218
- $sockets = PostmanTransportRegistry::getInstance ()->getSocketsForSetupWizardToProbe ( $queryHostname, $originalSmtpServer );
219
- $response = array (
220
- 'hosts' => $sockets
221
  );
222
- wp_send_json_success ( $response );
223
  }
224
-
225
  /**
226
  * This Ajax function retrieves whether a TCP port is open or not
227
  */
228
  function runPortQuizTest() {
229
  $hostname = 'portquiz.net';
230
- $port = intval ( PostmanUtils::getRequestParameter ( 'port' ) );
231
- $this->logger->debug ( 'testing TCP port: hostname ' . $hostname . ' port ' . $port );
232
- $portTest = new PostmanPortTest ( $hostname, $port );
233
- $success = $portTest->genericConnectionTest ();
234
- $this->buildResponse ( $hostname, $port, $portTest, $success );
235
  }
236
-
237
  /**
238
  * This Ajax function retrieves whether a TCP port is open or not.
239
  * This is called by both the Wizard and Port Test
240
  */
241
  function runSmtpTest() {
242
- $hostname = trim ( PostmanUtils::getRequestParameter ( 'hostname' ) );
243
- $port = intval ( PostmanUtils::getRequestParameter ( 'port' ) );
244
- $transport = trim ( PostmanUtils::getRequestParameter ( 'transport' ) );
245
- $timeout = PostmanUtils::getRequestParameter ( 'timeout' );
246
- $this->logger->trace ( $timeout );
247
- $portTest = new PostmanPortTest ( $hostname, $port );
248
- if (isset ( $timeout )) {
249
- $portTest->setConnectionTimeout ( intval ( $timeout ) );
250
- $portTest->setReadTimeout ( intval ( $timeout ) );
251
  }
252
- if ($port != 443) {
253
- $this->logger->debug ( sprintf ( 'testing SMTP socket %s:%s (%s)', $hostname, $port, $transport ) );
254
- $success = $portTest->testSmtpPorts ();
255
  } else {
256
- $this->logger->debug ( sprintf ( 'testing HTTPS socket %s:%s (%s)', $hostname, $port, $transport ) );
257
- $success = $portTest->testHttpPorts ();
258
  }
259
- $this->buildResponse ( $hostname, $port, $portTest, $success, $transport );
260
  }
261
  /**
262
  * This Ajax function retrieves whether a TCP port is open or not
263
  */
264
  function runSmtpsTest() {
265
- $hostname = trim ( PostmanUtils::getRequestParameter ( 'hostname' ) );
266
- $port = intval ( PostmanUtils::getRequestParameter ( 'port' ) );
267
- $transport = trim ( PostmanUtils::getRequestParameter ( 'transport' ) );
268
- $transportName = trim ( PostmanUtils::getRequestParameter ( 'transport_name' ) );
269
- $this->logger->debug ( sprintf ( 'testing SMTPS socket %s:%s (%s)', $hostname, $port, $transport ) );
270
- $portTest = new PostmanPortTest ( $hostname, $port );
271
  $portTest->transportName = $transportName;
272
- $success = $portTest->testSmtpsPorts ();
273
- $this->buildResponse ( $hostname, $port, $portTest, $success, $transport );
274
  }
275
-
276
  /**
277
  *
278
- * @param unknown $hostname
279
- * @param unknown $port
280
- * @param unknown $success
281
  */
282
- private function buildResponse($hostname, $port, PostmanPortTest $portTest, $success, $transport = '') {
283
- $this->logger->debug ( sprintf ( 'testing port result for %s:%s success=%s', $hostname, $port, $success ) );
284
- $response = array (
285
  'hostname' => $hostname,
286
  'hostname_domain_only' => $portTest->hostnameDomainOnly,
287
  'port' => $port,
@@ -290,7 +286,7 @@ class PostmanPortTestAjaxController {
290
  'mitm' => ($portTest->mitm),
291
  'reported_hostname' => $portTest->reportedHostname,
292
  'reported_hostname_domain_only' => $portTest->reportedHostnameDomainOnly,
293
- 'message' => $portTest->getErrorMessage (),
294
  'start_tls' => $portTest->startTls,
295
  'auth_plain' => $portTest->authPlain,
296
  'auth_login' => $portTest->authLogin,
@@ -299,14 +295,14 @@ class PostmanPortTestAjaxController {
299
  'auth_none' => $portTest->authNone,
300
  'try_smtps' => $portTest->trySmtps,
301
  'success' => $success,
302
- 'transport' => $transport
303
  );
304
- $this->logger->trace ( 'Ajax response:' );
305
- $this->logger->trace ( $response );
306
- if ($success) {
307
- wp_send_json_success ( $response );
308
  } else {
309
- wp_send_json_error ( $response );
310
  }
311
  }
312
  }
1
  <?php
2
 
 
3
  class PostmanConnectivityTestController {
4
+
5
+ const PORT_TEST_SLUG = 'postman/port_test';
6
+
 
7
  // logging
8
  private $logger;
9
+
10
  // Holds the values to be used in the fields callbacks
11
  private $rootPluginFilenameAndPath;
12
+
13
  /**
14
  * Constructor
15
  *
16
+ * @param unknown $rootPluginFilenameAndPath
17
  */
18
+ public function __construct( $rootPluginFilenameAndPath ) {
19
+ assert( ! empty( $rootPluginFilenameAndPath ) );
20
+ assert( PostmanUtils::isAdmin() );
21
+ assert( is_admin() );
22
+
23
+ $this->logger = new PostmanLogger( get_class( $this ) );
24
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
25
+
26
+ PostmanUtils::registerAdminMenu( $this, 'addPortTestSubmenu' );
27
+
28
  // hook on the init event
29
+ add_action( 'init', array(
30
  $this,
31
+ 'on_init',
32
  ) );
33
+
34
  // initialize the scripts, stylesheets and form fields
35
+ add_action( 'admin_init', array(
36
  $this,
37
+ 'on_admin_init',
38
  ) );
39
  }
40
+
41
  /**
42
  * Functions to execute on the init event
43
  *
46
  */
47
  public function on_init() {
48
  // register Ajax handlers
49
+ new PostmanPortTestAjaxController();
50
  }
51
+
52
  /**
53
  * Fires on the admin_init method
54
  */
55
  public function on_admin_init() {
56
+ $this->registerStylesAndScripts();
 
57
  }
58
+
59
  /**
60
  * Register and add settings
61
  */
62
  private function registerStylesAndScripts() {
63
+ if ( $this->logger->isTrace() ) {
64
+ $this->logger->trace( 'registerStylesAndScripts()' );
65
  }
66
  // register the stylesheet and javascript external resources
67
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
68
+ wp_register_script( 'postman_port_test_script', plugins_url( 'Postman/Postman-Connectivity-Test/postman_port_test.js', $this->rootPluginFilenameAndPath ), array(
69
  PostmanViewController::JQUERY_SCRIPT,
70
  'jquery_validation',
71
  PostmanViewController::POSTMAN_SCRIPT,
72
+ 'sprintf',
73
  ), $pluginData ['version'] );
74
  }
75
+
76
  /**
77
  * Register the Email Test screen
78
  */
79
  public function addPortTestSubmenu() {
80
+ $page = add_submenu_page( null, sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanConnectivityTestController::PORT_TEST_SLUG, array(
81
  $this,
82
+ 'outputPortTestContent',
83
  ) );
84
  // When the plugin options page is loaded, also load the stylesheet
85
+ add_action( 'admin_print_styles-' . $page, array(
86
  $this,
87
+ 'enqueuePortTestResources',
88
  ) );
89
  }
90
+
91
  /**
92
  */
93
  function enqueuePortTestResources() {
94
+ wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
95
+ wp_enqueue_script( 'postman_port_test_script' );
96
+ $warning = __( 'Warning', Postman::TEXT_DOMAIN );
97
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_hostname_element_name', '#input_' . PostmanOptions::HOSTNAME );
98
+ PostmanConnectivityTestController::addLocalizeScriptForPortTest();
99
  }
100
  static function addLocalizeScriptForPortTest() {
101
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_port_test', array(
102
+ 'in_progress' => _x( 'Checking..', 'The "please wait" message', Postman::TEXT_DOMAIN ),
103
+ 'open' => _x( 'Open', 'The port is open', Postman::TEXT_DOMAIN ),
104
+ 'closed' => _x( 'Closed', 'The port is closed', Postman::TEXT_DOMAIN ),
105
+ 'yes' => __( 'Yes', Postman::TEXT_DOMAIN ),
106
+ 'no' => __( 'No', Postman::TEXT_DOMAIN ),
107
+ /* translators: where %d is a port number */
108
+ 'blocked' => __( 'No outbound route between this site and the Internet on Port %d.', Postman::TEXT_DOMAIN ),
109
+ /* translators: where %d is a port number and %s is a hostname */
110
+ 'try_dif_smtp' => __( 'Port %d is open, but not to %s.', Postman::TEXT_DOMAIN ),
111
+ /* translators: where %d is the port number and %s is the hostname */
112
+ 'success' => __( 'Port %d can be used for SMTP to %s.', Postman::TEXT_DOMAIN ),
113
+ 'mitm' => sprintf( '%s: %s', __( 'Warning', Postman::TEXT_DOMAIN ), __( 'connected to %1$s instead of %2$s.', Postman::TEXT_DOMAIN ) ),
114
+ /* translators: where %d is a port number and %s is the URL for the Postman Gmail Extension */
115
+ 'https_success' => __( 'Port %d can be used with the %s.', Postman::TEXT_DOMAIN ),
116
  ) );
117
  }
118
+
119
  /**
120
  * Get the settings option array and print one of its values
121
  */
122
  public function port_test_hostname_callback() {
123
+ $hostname = PostmanTransportRegistry::getInstance()->getSelectedTransport()->getHostname();
124
+ if ( empty( $hostname ) ) {
125
+ $hostname = PostmanTransportRegistry::getInstance()->getActiveTransport()->getHostname();
126
  }
127
+ printf( '<input type="text" id="input_hostname" name="postman_options[hostname]" value="%s" size="40" class="required"/>', $hostname );
128
  }
129
+
130
  /**
131
  */
132
  public function outputPortTestContent() {
133
  print '<div class="wrap">';
134
+
135
+ PostmanViewController::outputChildPageHeader( __( 'Connectivity Test', Postman::TEXT_DOMAIN ) );
136
+
137
  print '<p>';
138
+ print __( 'This test determines which well-known ports are available for Postman to use.', Postman::TEXT_DOMAIN );
139
  print '<form id="port_test_form_id" method="post">';
140
+ printf( '<label for="hostname">%s</label>', __( 'Outgoing Mail Server Hostname', Postman::TEXT_DOMAIN ) );
141
+ $this->port_test_hostname_callback();
142
+ submit_button( _x( 'Begin Test', 'Button Label', Postman::TEXT_DOMAIN ), 'primary', 'begin-port-test', true );
143
  print '</form>';
144
  print '<table id="connectivity_test_table">';
145
+ print sprintf( '<tr><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th rowspan="2">%s</th><th colspan="5">%s</th></tr>', __( 'Transport', Postman::TEXT_DOMAIN ), _x( 'Socket', 'A socket is the network term for host and port together', Postman::TEXT_DOMAIN ), __( 'Status', Postman::TEXT_DOMAIN ) . '<sup>*</sup>', __( 'Service Available', Postman::TEXT_DOMAIN ), __( 'Server ID', Postman::TEXT_DOMAIN ), __( 'Authentication', Postman::TEXT_DOMAIN ) );
146
+ print sprintf( '<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>', 'None', 'Login', 'Plain', 'CRAM-MD5', 'OAuth 2.0' );
147
+ $sockets = PostmanTransportRegistry::getInstance()->getSocketsForSetupWizardToProbe();
148
  foreach ( $sockets as $socket ) {
149
+ if ( $socket ['smtp'] ) {
150
+ print sprintf( '<tr id="%s"><th class="name">%s</th><td class="socket">%s:%s</td><td class="firewall resettable">-</td><td class="service resettable">-</td><td class="reported_id resettable">-</td><td class="auth_none resettable">-</td><td class="auth_login resettable">-</td><td class="auth_plain resettable">-</td><td class="auth_crammd5 resettable">-</td><td class="auth_xoauth2 resettable">-</td></tr>', $socket ['id'], $socket ['transport_name'], $socket ['host'], $socket ['port'] );
151
  } else {
152
+ print sprintf( '<tr id="%s"><th class="name">%s</th><td class="socket">%s:%s</td><td class="firewall resettable">-</td><td class="service resettable">-</td><td class="reported_id resettable">-</td><td colspan="5">%s</td></tr>', $socket ['id'], $socket ['transport_name'], $socket ['host'], $socket ['port'], __( 'n/a', Postman::TEXT_DOMAIN ) );
153
  }
154
  }
155
  print '</table>';
156
  /* Translators: Where %s is the name of the service providing Internet connectivity test */
157
+ printf( '<p class="portquiz" style="display:none; font-size:0.8em">* %s</p>', sprintf( __( 'According to %s', Postman::TEXT_DOMAIN ), '<a target="_new" href="http://ww.downor.me/portquiz.net">portquiz.net</a>' ) );
158
+ printf( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url( 'post-smtp/style/ajax-loader.gif' ) );
159
  print '<section id="conclusion" style="display:none">';
160
+ print sprintf( '<h3>%s:</h3>', __( 'Summary', Postman::TEXT_DOMAIN ) );
161
  print '<ol class="conclusion">';
162
  print '</ol>';
163
  print '</section>';
164
  print '<section id="blocked-port-help" style="display:none">';
165
+ print sprintf( '<p><b>%s</b></p>', __( 'A test with <span style="color:red">"No"</span> Service Available indicates one or more of these issues:', Postman::TEXT_DOMAIN ) );
166
  print '<ol>';
167
+ printf( '<li>%s</li>', __( 'Your web host has placed a firewall between this site and the Internet', Postman::TEXT_DOMAIN ) );
168
+ printf( '<li>%s</li>', __( 'The SMTP hostname is wrong or the mail server does not provide service on this port', Postman::TEXT_DOMAIN ) );
169
  /* translators: where (1) is the URL and (2) is the system */
170
+ $systemBlockMessage = __( 'Your <a href="%1$s">%2$s configuration</a> is preventing outbound connections', Postman::TEXT_DOMAIN );
171
+ printf( '<li>%s</li>', sprintf( $systemBlockMessage, 'http://php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen', 'PHP' ) );
172
+ printf( '<li>%s</li>', sprintf( $systemBlockMessage, 'http://wp-mix.com/disable-external-url-requests/', 'WordPress' ) );
173
  print '</ol></p>';
174
+ print sprintf( '<p><b>%s</b></p>', __( 'If the issues above can not be resolved, your last option is to configure Postman to use an email account managed by your web host with an SMTP server managed by your web host.', Postman::TEXT_DOMAIN ) );
175
  print '</section>';
176
  print '</div>';
177
  }
180
  /**
181
  *
182
  * @author jasonhendriks
 
183
  */
184
  class PostmanPortTestAjaxController {
185
  private $logger;
186
  /**
187
  * Constructor
188
  *
189
+ * @param PostmanOptions $options
190
  */
191
  function __construct() {
192
+ $this->logger = new PostmanLogger( get_class( $this ) );
193
+ PostmanUtils::registerAjaxHandler( 'postman_get_hosts_to_test', $this, 'getPortsToTestViaAjax' );
194
+ PostmanUtils::registerAjaxHandler( 'postman_wizard_port_test', $this, 'runSmtpTest' );
195
+ PostmanUtils::registerAjaxHandler( 'postman_wizard_port_test_smtps', $this, 'runSmtpsTest' );
196
+ PostmanUtils::registerAjaxHandler( 'postman_port_quiz_test', $this, 'runPortQuizTest' );
197
+ PostmanUtils::registerAjaxHandler( 'postman_test_port', $this, 'runSmtpTest' );
198
+ PostmanUtils::registerAjaxHandler( 'postman_test_smtps', $this, 'runSmtpsTest' );
199
  }
200
+
201
  /**
202
  * This Ajax function determines which hosts/ports to test in both the Wizard Connectivity Test and direct Connectivity Test
203
  *
205
  * combinations to run the connectivity test on
206
  */
207
  function getPortsToTestViaAjax() {
208
+ $queryHostname = PostmanUtils::getRequestParameter( 'hostname' );
209
  // originalSmtpServer is what SmtpDiscovery thinks the SMTP server should be, given an email address
210
+ $originalSmtpServer = PostmanUtils::getRequestParameter( 'original_smtp_server' );
211
+ if ( $this->logger->isDebug() ) {
212
+ $this->logger->debug( 'Probing available transports for sockets against hostname ' . $queryHostname );
213
  }
214
+ $sockets = PostmanTransportRegistry::getInstance()->getSocketsForSetupWizardToProbe( $queryHostname, $originalSmtpServer );
215
+ $response = array(
216
+ 'hosts' => $sockets,
217
  );
218
+ wp_send_json_success( $response );
219
  }
220
+
221
  /**
222
  * This Ajax function retrieves whether a TCP port is open or not
223
  */
224
  function runPortQuizTest() {
225
  $hostname = 'portquiz.net';
226
+ $port = intval( PostmanUtils::getRequestParameter( 'port' ) );
227
+ $this->logger->debug( 'testing TCP port: hostname ' . $hostname . ' port ' . $port );
228
+ $portTest = new PostmanPortTest( $hostname, $port );
229
+ $success = $portTest->genericConnectionTest();
230
+ $this->buildResponse( $hostname, $port, $portTest, $success );
231
  }
232
+
233
  /**
234
  * This Ajax function retrieves whether a TCP port is open or not.
235
  * This is called by both the Wizard and Port Test
236
  */
237
  function runSmtpTest() {
238
+ $hostname = trim( PostmanUtils::getRequestParameter( 'hostname' ) );
239
+ $port = intval( PostmanUtils::getRequestParameter( 'port' ) );
240
+ $transport = trim( PostmanUtils::getRequestParameter( 'transport' ) );
241
+ $timeout = PostmanUtils::getRequestParameter( 'timeout' );
242
+ $this->logger->trace( $timeout );
243
+ $portTest = new PostmanPortTest( $hostname, $port );
244
+ if ( isset( $timeout ) ) {
245
+ $portTest->setConnectionTimeout( intval( $timeout ) );
246
+ $portTest->setReadTimeout( intval( $timeout ) );
247
  }
248
+ if ( $port != 443 ) {
249
+ $this->logger->debug( sprintf( 'testing SMTP socket %s:%s (%s)', $hostname, $port, $transport ) );
250
+ $success = $portTest->testSmtpPorts();
251
  } else {
252
+ $this->logger->debug( sprintf( 'testing HTTPS socket %s:%s (%s)', $hostname, $port, $transport ) );
253
+ $success = $portTest->testHttpPorts();
254
  }
255
+ $this->buildResponse( $hostname, $port, $portTest, $success, $transport );
256
  }
257
  /**
258
  * This Ajax function retrieves whether a TCP port is open or not
259
  */
260
  function runSmtpsTest() {
261
+ $hostname = trim( PostmanUtils::getRequestParameter( 'hostname' ) );
262
+ $port = intval( PostmanUtils::getRequestParameter( 'port' ) );
263
+ $transport = trim( PostmanUtils::getRequestParameter( 'transport' ) );
264
+ $transportName = trim( PostmanUtils::getRequestParameter( 'transport_name' ) );
265
+ $this->logger->debug( sprintf( 'testing SMTPS socket %s:%s (%s)', $hostname, $port, $transport ) );
266
+ $portTest = new PostmanPortTest( $hostname, $port );
267
  $portTest->transportName = $transportName;
268
+ $success = $portTest->testSmtpsPorts();
269
+ $this->buildResponse( $hostname, $port, $portTest, $success, $transport );
270
  }
271
+
272
  /**
273
  *
274
+ * @param unknown $hostname
275
+ * @param unknown $port
276
+ * @param unknown $success
277
  */
278
+ private function buildResponse( $hostname, $port, PostmanPortTest $portTest, $success, $transport = '' ) {
279
+ $this->logger->debug( sprintf( 'testing port result for %s:%s success=%s', $hostname, $port, $success ) );
280
+ $response = array(
281
  'hostname' => $hostname,
282
  'hostname_domain_only' => $portTest->hostnameDomainOnly,
283
  'port' => $port,
286
  'mitm' => ($portTest->mitm),
287
  'reported_hostname' => $portTest->reportedHostname,
288
  'reported_hostname_domain_only' => $portTest->reportedHostnameDomainOnly,
289
+ 'message' => $portTest->getErrorMessage(),
290
  'start_tls' => $portTest->startTls,
291
  'auth_plain' => $portTest->authPlain,
292
  'auth_login' => $portTest->authLogin,
295
  'auth_none' => $portTest->authNone,
296
  'try_smtps' => $portTest->trySmtps,
297
  'success' => $success,
298
+ 'transport' => $transport,
299
  );
300
+ $this->logger->trace( 'Ajax response:' );
301
+ $this->logger->trace( $response );
302
+ if ( $success ) {
303
+ wp_send_json_success( $response );
304
  } else {
305
+ wp_send_json_error( $response );
306
  }
307
  }
308
  }
Postman/Postman-Diagnostic-Test/PostmanDiagnosticTestController.php CHANGED
@@ -1,44 +1,44 @@
1
  <?php
2
  class PostmanDiagnosticTestController {
3
  const DIAGNOSTICS_SLUG = 'postman/diagnostics';
4
-
5
  // logging
6
  private $logger;
7
  private $options;
8
-
9
  // Holds the values to be used in the fields callbacks
10
  private $rootPluginFilenameAndPath;
11
-
12
  /**
13
  * Constructor
14
  *
15
- * @param unknown $rootPluginFilenameAndPath
16
  */
17
- public function __construct($rootPluginFilenameAndPath) {
18
- assert ( ! empty ( $rootPluginFilenameAndPath ) );
19
- assert ( PostmanUtils::isAdmin () );
20
- assert ( is_admin () );
21
-
22
- $this->logger = new PostmanLogger ( get_class ( $this ) );
23
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
24
- $this->options = PostmanOptions::getInstance ();
25
-
26
  // register the admin menu
27
- PostmanUtils::registerAdminMenu ( $this, 'addDiagnosticsSubmenu' );
28
-
29
  // hook on the init event
30
- add_action ( 'init', array (
31
  $this,
32
- 'on_init'
33
  ) );
34
-
35
  // initialize the scripts, stylesheets and form fields
36
- add_action ( 'admin_init', array (
37
  $this,
38
- 'on_admin_init'
39
  ) );
40
  }
41
-
42
  /**
43
  * Functions to execute on the init event
44
  *
@@ -47,66 +47,65 @@ class PostmanDiagnosticTestController {
47
  */
48
  public function on_init() {
49
  // register Ajax handlers
50
- new PostmanGetDiagnosticsViaAjax ();
51
  }
52
-
53
  /**
54
  * Fires on the admin_init method
55
  */
56
  public function on_admin_init() {
57
- //
58
- $this->registerStylesAndScripts ();
59
  }
60
-
61
  /**
62
  * Register and add settings
63
  */
64
  private function registerStylesAndScripts() {
65
- if ($this->logger->isTrace ()) {
66
- $this->logger->trace ( 'registerStylesAndScripts()' );
67
  }
68
-
69
  // register the javascript resource
70
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
71
- wp_register_script ( 'postman_diagnostics_script', plugins_url ( 'Postman/Postman-Diagnostic-Test/postman_diagnostics.js', $this->rootPluginFilenameAndPath ), array (
72
  PostmanViewController::JQUERY_SCRIPT,
73
- PostmanViewController::POSTMAN_SCRIPT
74
  ), $pluginData ['version'] );
75
  }
76
-
77
  /**
78
  * Register the Diagnostics screen
79
  */
80
  public function addDiagnosticsSubmenu() {
81
- $page = add_submenu_page ( null, sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanDiagnosticTestController::DIAGNOSTICS_SLUG, array (
82
  $this,
83
- 'outputDiagnosticsContent'
84
  ) );
85
  // When the plugin options page is loaded, also load the stylesheet
86
- add_action ( 'admin_print_styles-' . $page, array (
87
  $this,
88
- 'enqueueDiagnosticsScreenStylesheet'
89
  ) );
90
  }
91
  function enqueueDiagnosticsScreenStylesheet() {
92
- wp_enqueue_style ( PostmanViewController::POSTMAN_STYLE );
93
- wp_enqueue_script ( 'postman_diagnostics_script' );
94
  }
95
-
96
  /**
97
  */
98
  public function outputDiagnosticsContent() {
99
  // test features
100
  print '<div class="wrap">';
101
-
102
- PostmanViewController::outputChildPageHeader ( __ ( 'Diagnostic Test', Postman::TEXT_DOMAIN ) );
103
-
104
- printf ( '<h4>%s</h4>', __ ( 'Are you having issues with Postman?', Postman::TEXT_DOMAIN ) );
105
  /* translators: where %1$s and %2$s are the URLs to the Troubleshooting and Support Forums on WordPress.org */
106
- printf ( '<p style="margin:0 10px">%s</p>', sprintf ( __ ( 'Please check the <a href="%1$s">troubleshooting and error messages</a> page and the <a href="%2$s">support forum</a>.', Postman::TEXT_DOMAIN ), 'https://wordpress.org/plugins/postman-smtp/other_notes/', 'https://wordpress.org/support/plugin/postman-smtp' ) );
107
- printf ( '<h4>%s</h4>', __ ( 'Diagnostic Test', Postman::TEXT_DOMAIN ) );
108
- printf ( '<p style="margin:0 10px">%s</p><br/>', sprintf ( __ ( 'If you write for help, please include the following:', Postman::TEXT_DOMAIN ), 'https://wordpress.org/plugins/postman-smtp/other_notes/', 'https://wordpress.org/support/plugin/postman-smtp' ) );
109
- printf ( '<textarea readonly="readonly" id="diagnostic-text" cols="80" rows="15">%s</textarea>', _x ( 'Checking..', 'The "please wait" message', Postman::TEXT_DOMAIN ) );
110
  print '</div>';
111
  }
112
  }
@@ -114,7 +113,6 @@ class PostmanDiagnosticTestController {
114
  /**
115
  *
116
  * @author jasonhendriks
117
- *
118
  */
119
  class PostmanGetDiagnosticsViaAjax {
120
  private $diagnostics;
@@ -123,59 +121,59 @@ class PostmanGetDiagnosticsViaAjax {
123
  /**
124
  * Constructor
125
  *
126
- * @param PostmanOptions $options
127
  */
128
  function __construct() {
129
- $this->options = PostmanOptions::getInstance ();
130
- $this->authorizationToken = PostmanOAuthToken::getInstance ();
131
  $this->diagnostics = '';
132
- PostmanUtils::registerAjaxHandler ( 'postman_diagnostics', $this, 'getDiagnostics' );
133
  }
134
- private function addToDiagnostics($header, $data) {
135
- if (isset ( $data )) {
136
- $this->diagnostics .= sprintf ( '%s: %s%s', $header, $data, PHP_EOL );
137
  }
138
  }
139
  private function getActivePlugins() {
140
  // from http://stackoverflow.com/questions/20488264/how-do-i-get-activated-plugin-list-in-wordpress-plugin-development
141
- $apl = get_option ( 'active_plugins' );
142
- $plugins = get_plugins ();
143
- $pluginText = array ();
144
  foreach ( $apl as $p ) {
145
- if (isset ( $plugins [$p] )) {
146
- array_push ( $pluginText, $plugins [$p] ['Name'] );
147
  }
148
  }
149
- return implode ( ', ', $pluginText );
150
  }
151
  private function getPhpDependencies() {
152
- $apl = PostmanPreRequisitesCheck::getState ();
153
- $pluginText = array ();
154
  foreach ( $apl as $p ) {
155
- array_push ( $pluginText, $p ['name'] . '=' . ($p ['ready'] ? 'Yes' : 'No') );
156
  }
157
- return implode ( ', ', $pluginText );
158
  }
159
  private function getTransports() {
160
  $transports = '';
161
- foreach ( PostmanTransportRegistry::getInstance ()->getTransports () as $transport ) {
162
- $transports .= ' : ' . $transport->getName ();
163
  }
164
  return $transports;
165
  }
166
-
167
  /**
168
  * Diagnostic Data test to current SMTP server
169
  *
170
  * @return string
171
  */
172
- private function testConnectivity(PostmanModuleTransport $transport) {
173
- $hostname = $transport->getHostname ( $this->options );
174
- $port = $transport->getPort ( $this->options );
175
- if (! empty ( $hostname ) && ! empty ( $port )) {
176
- $portTest = new PostmanPortTest ( $transport->getHostname ( $this->options ), $transport->getPort ( $this->options ) );
177
- $result = $portTest->genericConnectionTest ( $this->options->getConnectionTimeout () );
178
- if ($result) {
179
  return 'Yes';
180
  } else {
181
  return 'No';
@@ -183,93 +181,93 @@ class PostmanGetDiagnosticsViaAjax {
183
  }
184
  return 'n/a';
185
  }
186
-
187
  /**
188
  * Inspects the $wp_filter variable and returns the plugins attached to it
189
  * From: http://stackoverflow.com/questions/5224209/wordpress-how-do-i-get-all-the-registered-functions-for-the-content-filter
190
  */
191
- private function getFilters($hook = '') {
192
  global $wp_filter;
193
- if (empty ( $hook ) || ! isset ( $wp_filter [$hook] ))
194
- return null;
195
- $functionArray = array ();
196
- foreach ( $wp_filter [$hook] as $functions ) {
197
  foreach ( $functions as $function ) {
198
  $thing = $function ['function'];
199
- if (is_array ( $thing )) {
200
- $name = get_class ( $thing [0] ) . '->' . $thing [1];
201
- array_push ( $functionArray, $name );
202
  } else {
203
- array_push ( $functionArray, $thing );
204
  }
205
  }
206
  }
207
- return implode ( ', ', $functionArray );
208
  }
209
-
210
  /**
211
  */
212
  public function getDiagnostics() {
213
- $transportRegistry = PostmanTransportRegistry::getInstance ();
214
- $this->addToDiagnostics ( 'OS', php_uname () );
215
- $this->addToDiagnostics ( 'PHP', PHP_OS . ' ' . PHP_VERSION . ' ' . setlocale ( LC_CTYPE, 0 ) );
216
- $this->addToDiagnostics ( 'PHP Dependencies', $this->getPhpDependencies () );
217
- $this->addToDiagnostics ( 'WordPress', (is_multisite () ? 'Multisite ' : '') . get_bloginfo ( 'version' ) . ' ' . get_locale () . ' ' . get_bloginfo( 'charset', 'display' ) );
218
- $this->addToDiagnostics ( 'WordPress Theme', wp_get_theme () );
219
- $this->addToDiagnostics ( 'WordPress Plugins', $this->getActivePlugins () );
220
  {
221
- $bindResult = apply_filters ( 'postman_wp_mail_bind_status', null );
222
  $wp_mail_file_name = 'n/a';
223
- if (class_exists ( 'ReflectionFunction' )) {
224
- $wp_mail = new ReflectionFunction ( 'wp_mail' );
225
- $wp_mail_file_name = realpath ( $wp_mail->getFileName () );
226
- }
227
- if (! $bindResult ['bound']) {
228
- $this->addToDiagnostics ( 'WordPress wp_mail Owner', $wp_mail_file_name );
229
- }
230
  }
231
- $this->addToDiagnostics ( 'WordPress wp_mail Filter(s)', $this->getFilters ( 'wp_mail' ) );
232
- $this->addToDiagnostics ( 'WordPress wp_mail_from Filter(s)', $this->getFilters ( 'wp_mail_from' ) );
233
- $this->addToDiagnostics ( 'WordPress wp_mail_from_name Filter(s)', $this->getFilters ( 'wp_mail_from_name' ) );
234
- $this->addToDiagnostics ( 'WordPress wp_mail_content_type Filter(s)', $this->getFilters ( 'wp_mail_content_type' ) );
235
- $this->addToDiagnostics ( 'WordPress wp_mail_charset Filter(s)', $this->getFilters ( 'wp_mail_charset' ) );
236
- $this->addToDiagnostics ( 'WordPress phpmailer_init Action(s)', $this->getFilters ( 'phpmailer_init' ) );
237
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
238
- $this->addToDiagnostics ( 'Postman', $pluginData ['version'] );
 
239
  {
240
- $s1 = $this->options->getEnvelopeSender ();
241
- $s2 = $this->options->getMessageSenderEmail ();
242
- if (! empty ( $s1 ) || ! empty ( $s2 )) {
243
- $this->addToDiagnostics ( 'Postman Sender Domain (Envelope|Message)', ($hostname = substr ( strrchr ( $this->options->getEnvelopeSender (), "@" ), 1 )) . ' | ' . ($hostname = substr ( strrchr ( $this->options->getMessageSenderEmail (), "@" ), 1 )) );
244
- }
245
  }
246
- $this->addToDiagnostics ( 'Postman Prevent Message Sender Override (Email|Name)', ($this->options->isSenderEmailOverridePrevented () ? 'Yes' : 'No') . ' | ' . ($this->options->isSenderNameOverridePrevented () ? 'Yes' : 'No') );
247
  {
248
  // status of the active transport
249
- $transport = $transportRegistry->getActiveTransport ();
250
- $this->addToDiagnostics ( 'Postman Active Transport', sprintf ( '%s (%s)', $transport->getName (), $transportRegistry->getPublicTransportUri ( $transport ) ) );
251
- $this->addToDiagnostics ( 'Postman Active Transport Status (Ready|Connected)', ($transport->isConfiguredAndReady () ? 'Yes' : 'No') . ' | ' . ($this->testConnectivity ( $transport )) );
252
  }
253
- if ($transportRegistry->getActiveTransport () != $transportRegistry->getSelectedTransport () && $transportRegistry->getSelectedTransport () != null) {
254
  // status of the selected transport
255
- $transport = $transportRegistry->getSelectedTransport ();
256
- $this->addToDiagnostics ( 'Postman Selected Transport', sprintf ( '%s (%s)', $transport->getName (), $transportRegistry->getPublicTransportUri ( $transport ) ) );
257
- $this->addToDiagnostics ( 'Postman Selected Transport Status (Ready|Connected)', ($transport->isConfiguredAndReady () ? 'Yes' : 'No') . ' | ' . ($this->testConnectivity ( $transport )) );
258
  }
259
- $this->addToDiagnostics ( 'Postman Deliveries (Success|Fail)', (PostmanState::getInstance ()->getSuccessfulDeliveries ()) . ' | ' . (PostmanState::getInstance ()->getFailedDeliveries ()) );
260
- if ($this->options->getConnectionTimeout () != PostmanOptions::DEFAULT_TCP_CONNECTION_TIMEOUT || $this->options->getReadTimeout () != PostmanOptions::DEFAULT_TCP_READ_TIMEOUT) {
261
- $this->addToDiagnostics ( 'Postman TCP Timeout (Connection|Read)', $this->options->getConnectionTimeout () . ' | ' . $this->options->getReadTimeout () );
262
  }
263
- if ($this->options->isMailLoggingEnabled () != PostmanOptions::DEFAULT_MAIL_LOG_ENABLED || $this->options->getMailLoggingMaxEntries () != PostmanOptions::DEFAULT_MAIL_LOG_ENTRIES || $this->options->getTranscriptSize () != PostmanOptions::DEFAULT_TRANSCRIPT_SIZE) {
264
- $this->addToDiagnostics ( 'Postman Email Log (Enabled|Limit|Transcript Size)', ($this->options->isMailLoggingEnabled () ? 'Yes' : 'No') . ' | ' . $this->options->getMailLoggingMaxEntries () . ' | ' . $this->options->getTranscriptSize () );
265
  }
266
- $this->addToDiagnostics ( 'Postman Run Mode', $this->options->getRunMode () == PostmanOptions::RUN_MODE_PRODUCTION ? null : $this->options->getRunMode () );
267
- $this->addToDiagnostics ( 'Postman PHP LogLevel', $this->options->getLogLevel () == PostmanLogger::ERROR_INT ? null : $this->options->getLogLevel () );
268
- $this->addToDiagnostics ( 'Postman Stealth Mode', $this->options->isStealthModeEnabled () ? 'Yes' : null );
269
- $this->addToDiagnostics ( 'Postman File Locking (Enabled|Temp Dir)', PostmanState::getInstance ()->isFileLockingEnabled () ? null : 'No' . ' | ' . $this->options->getTempDirectory () );
270
- $response = array (
271
- 'message' => $this->diagnostics
272
  );
273
- wp_send_json_success ( $response );
274
  }
275
  }
1
  <?php
2
  class PostmanDiagnosticTestController {
3
  const DIAGNOSTICS_SLUG = 'postman/diagnostics';
4
+
5
  // logging
6
  private $logger;
7
  private $options;
8
+
9
  // Holds the values to be used in the fields callbacks
10
  private $rootPluginFilenameAndPath;
11
+
12
  /**
13
  * Constructor
14
  *
15
+ * @param unknown $rootPluginFilenameAndPath
16
  */
17
+ public function __construct( $rootPluginFilenameAndPath ) {
18
+ assert( ! empty( $rootPluginFilenameAndPath ) );
19
+ assert( PostmanUtils::isAdmin() );
20
+ assert( is_admin() );
21
+
22
+ $this->logger = new PostmanLogger( get_class( $this ) );
23
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
24
+ $this->options = PostmanOptions::getInstance();
25
+
26
  // register the admin menu
27
+ PostmanUtils::registerAdminMenu( $this, 'addDiagnosticsSubmenu' );
28
+
29
  // hook on the init event
30
+ add_action( 'init', array(
31
  $this,
32
+ 'on_init',
33
  ) );
34
+
35
  // initialize the scripts, stylesheets and form fields
36
+ add_action( 'admin_init', array(
37
  $this,
38
+ 'on_admin_init',
39
  ) );
40
  }
41
+
42
  /**
43
  * Functions to execute on the init event
44
  *
47
  */
48
  public function on_init() {
49
  // register Ajax handlers
50
+ new PostmanGetDiagnosticsViaAjax();
51
  }
52
+
53
  /**
54
  * Fires on the admin_init method
55
  */
56
  public function on_admin_init() {
57
+ $this->registerStylesAndScripts();
 
58
  }
59
+
60
  /**
61
  * Register and add settings
62
  */
63
  private function registerStylesAndScripts() {
64
+ if ( $this->logger->isTrace() ) {
65
+ $this->logger->trace( 'registerStylesAndScripts()' );
66
  }
67
+
68
  // register the javascript resource
69
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
70
+ wp_register_script( 'postman_diagnostics_script', plugins_url( 'Postman/Postman-Diagnostic-Test/postman_diagnostics.js', $this->rootPluginFilenameAndPath ), array(
71
  PostmanViewController::JQUERY_SCRIPT,
72
+ PostmanViewController::POSTMAN_SCRIPT,
73
  ), $pluginData ['version'] );
74
  }
75
+
76
  /**
77
  * Register the Diagnostics screen
78
  */
79
  public function addDiagnosticsSubmenu() {
80
+ $page = add_submenu_page( null, sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanDiagnosticTestController::DIAGNOSTICS_SLUG, array(
81
  $this,
82
+ 'outputDiagnosticsContent',
83
  ) );
84
  // When the plugin options page is loaded, also load the stylesheet
85
+ add_action( 'admin_print_styles-' . $page, array(
86
  $this,
87
+ 'enqueueDiagnosticsScreenStylesheet',
88
  ) );
89
  }
90
  function enqueueDiagnosticsScreenStylesheet() {
91
+ wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
92
+ wp_enqueue_script( 'postman_diagnostics_script' );
93
  }
94
+
95
  /**
96
  */
97
  public function outputDiagnosticsContent() {
98
  // test features
99
  print '<div class="wrap">';
100
+
101
+ PostmanViewController::outputChildPageHeader( __( 'Diagnostic Test', Postman::TEXT_DOMAIN ) );
102
+
103
+ printf( '<h4>%s</h4>', __( 'Are you having issues with Postman?', Postman::TEXT_DOMAIN ) );
104
  /* translators: where %1$s and %2$s are the URLs to the Troubleshooting and Support Forums on WordPress.org */
105
+ printf( '<p style="margin:0 10px">%s</p>', sprintf( __( 'Please check the <a href="%1$s">troubleshooting and error messages</a> page and the <a href="%2$s">support forum</a>.', Postman::TEXT_DOMAIN ), 'https://wordpress.org/plugins/post-smtp/other_notes/', 'https://wordpress.org/support/plugin/postman-smtp' ) );
106
+ printf( '<h4>%s</h4>', __( 'Diagnostic Test', Postman::TEXT_DOMAIN ) );
107
+ printf( '<p style="margin:0 10px">%s</p><br/>', sprintf( __( 'If you write for help, please include the following:', Postman::TEXT_DOMAIN ), 'https://wordpress.org/plugins/post-smtp/other_notes/', 'https://wordpress.org/support/plugin/postman-smtp' ) );
108
+ printf( '<textarea readonly="readonly" id="diagnostic-text" cols="80" rows="15">%s</textarea>', _x( 'Checking..', 'The "please wait" message', Postman::TEXT_DOMAIN ) );
109
  print '</div>';
110
  }
111
  }
113
  /**
114
  *
115
  * @author jasonhendriks
 
116
  */
117
  class PostmanGetDiagnosticsViaAjax {
118
  private $diagnostics;
121
  /**
122
  * Constructor
123
  *
124
+ * @param PostmanOptions $options
125
  */
126
  function __construct() {
127
+ $this->options = PostmanOptions::getInstance();
128
+ $this->authorizationToken = PostmanOAuthToken::getInstance();
129
  $this->diagnostics = '';
130
+ PostmanUtils::registerAjaxHandler( 'postman_diagnostics', $this, 'getDiagnostics' );
131
  }
132
+ private function addToDiagnostics( $header, $data ) {
133
+ if ( isset( $data ) ) {
134
+ $this->diagnostics .= sprintf( '%s: %s%s', $header, $data, PHP_EOL );
135
  }
136
  }
137
  private function getActivePlugins() {
138
  // from http://stackoverflow.com/questions/20488264/how-do-i-get-activated-plugin-list-in-wordpress-plugin-development
139
+ $apl = get_option( 'active_plugins' );
140
+ $plugins = get_plugins();
141
+ $pluginText = array();
142
  foreach ( $apl as $p ) {
143
+ if ( isset( $plugins [ $p ] ) ) {
144
+ array_push( $pluginText, $plugins [ $p ] ['Name'] );
145
  }
146
  }
147
+ return implode( ', ', $pluginText );
148
  }
149
  private function getPhpDependencies() {
150
+ $apl = PostmanPreRequisitesCheck::getState();
151
+ $pluginText = array();
152
  foreach ( $apl as $p ) {
153
+ array_push( $pluginText, $p ['name'] . '=' . ($p ['ready'] ? 'Yes' : 'No') );
154
  }
155
+ return implode( ', ', $pluginText );
156
  }
157
  private function getTransports() {
158
  $transports = '';
159
+ foreach ( PostmanTransportRegistry::getInstance()->getTransports() as $transport ) {
160
+ $transports .= ' : ' . $transport->getName();
161
  }
162
  return $transports;
163
  }
164
+
165
  /**
166
  * Diagnostic Data test to current SMTP server
167
  *
168
  * @return string
169
  */
170
+ private function testConnectivity( PostmanModuleTransport $transport ) {
171
+ $hostname = $transport->getHostname( $this->options );
172
+ $port = $transport->getPort( $this->options );
173
+ if ( ! empty( $hostname ) && ! empty( $port ) ) {
174
+ $portTest = new PostmanPortTest( $transport->getHostname( $this->options ), $transport->getPort( $this->options ) );
175
+ $result = $portTest->genericConnectionTest( $this->options->getConnectionTimeout() );
176
+ if ( $result ) {
177
  return 'Yes';
178
  } else {
179
  return 'No';
181
  }
182
  return 'n/a';
183
  }
184
+
185
  /**
186
  * Inspects the $wp_filter variable and returns the plugins attached to it
187
  * From: http://stackoverflow.com/questions/5224209/wordpress-how-do-i-get-all-the-registered-functions-for-the-content-filter
188
  */
189
+ private function getFilters( $hook = '' ) {
190
  global $wp_filter;
191
+ if ( empty( $hook ) || ! isset( $wp_filter [ $hook ] ) ) {
192
+ return null; }
193
+ $functionArray = array();
194
+ foreach ( $wp_filter [ $hook ] as $functions ) {
195
  foreach ( $functions as $function ) {
196
  $thing = $function ['function'];
197
+ if ( is_array( $thing ) ) {
198
+ $name = get_class( $thing [0] ) . '->' . $thing [1];
199
+ array_push( $functionArray, $name );
200
  } else {
201
+ array_push( $functionArray, $thing );
202
  }
203
  }
204
  }
205
+ return implode( ', ', $functionArray );
206
  }
207
+
208
  /**
209
  */
210
  public function getDiagnostics() {
211
+ $transportRegistry = PostmanTransportRegistry::getInstance();
212
+ $this->addToDiagnostics( 'OS', php_uname() );
213
+ $this->addToDiagnostics( 'PHP', PHP_OS . ' ' . PHP_VERSION . ' ' . setlocale( LC_CTYPE, 0 ) );
214
+ $this->addToDiagnostics( 'PHP Dependencies', $this->getPhpDependencies() );
215
+ $this->addToDiagnostics( 'WordPress', (is_multisite() ? 'Multisite ' : '') . get_bloginfo( 'version' ) . ' ' . get_locale() . ' ' . get_bloginfo( 'charset', 'display' ) );
216
+ $this->addToDiagnostics( 'WordPress Theme', wp_get_theme() );
217
+ $this->addToDiagnostics( 'WordPress Plugins', $this->getActivePlugins() );
218
  {
219
+ $bindResult = apply_filters( 'postman_wp_mail_bind_status', null );
220
  $wp_mail_file_name = 'n/a';
221
+ if ( class_exists( 'ReflectionFunction' ) ) {
222
+ $wp_mail = new ReflectionFunction( 'wp_mail' );
223
+ $wp_mail_file_name = realpath( $wp_mail->getFileName() );
224
+ }
225
+ if ( ! $bindResult ['bound'] ) {
226
+ $this->addToDiagnostics( 'WordPress wp_mail Owner', $wp_mail_file_name );
 
227
  }
228
+ }
229
+ $this->addToDiagnostics( 'WordPress wp_mail Filter(s)', $this->getFilters( 'wp_mail' ) );
230
+ $this->addToDiagnostics( 'WordPress wp_mail_from Filter(s)', $this->getFilters( 'wp_mail_from' ) );
231
+ $this->addToDiagnostics( 'WordPress wp_mail_from_name Filter(s)', $this->getFilters( 'wp_mail_from_name' ) );
232
+ $this->addToDiagnostics( 'WordPress wp_mail_content_type Filter(s)', $this->getFilters( 'wp_mail_content_type' ) );
233
+ $this->addToDiagnostics( 'WordPress wp_mail_charset Filter(s)', $this->getFilters( 'wp_mail_charset' ) );
234
+ $this->addToDiagnostics( 'WordPress phpmailer_init Action(s)', $this->getFilters( 'phpmailer_init' ) );
235
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
236
+ $this->addToDiagnostics( 'Postman', $pluginData ['version'] );
237
  {
238
+ $s1 = $this->options->getEnvelopeSender();
239
+ $s2 = $this->options->getMessageSenderEmail();
240
+ if ( ! empty( $s1 ) || ! empty( $s2 ) ) {
241
+ $this->addToDiagnostics( 'Postman Sender Domain (Envelope|Message)', ($hostname = substr( strrchr( $this->options->getEnvelopeSender(), '@' ), 1 )) . ' | ' . ($hostname = substr( strrchr( $this->options->getMessageSenderEmail(), '@' ), 1 )) );
242
+ }
243
  }
244
+ $this->addToDiagnostics( 'Postman Prevent Message Sender Override (Email|Name)', ($this->options->isSenderEmailOverridePrevented() ? 'Yes' : 'No') . ' | ' . ($this->options->isSenderNameOverridePrevented() ? 'Yes' : 'No') );
245
  {
246
  // status of the active transport
247
+ $transport = $transportRegistry->getActiveTransport();
248
+ $this->addToDiagnostics( 'Postman Active Transport', sprintf( '%s (%s)', $transport->getName(), $transportRegistry->getPublicTransportUri( $transport ) ) );
249
+ $this->addToDiagnostics( 'Postman Active Transport Status (Ready|Connected)', ($transport->isConfiguredAndReady() ? 'Yes' : 'No') . ' | ' . ($this->testConnectivity( $transport )) );
250
  }
251
+ if ( $transportRegistry->getActiveTransport() != $transportRegistry->getSelectedTransport() && $transportRegistry->getSelectedTransport() != null ) {
252
  // status of the selected transport
253
+ $transport = $transportRegistry->getSelectedTransport();
254
+ $this->addToDiagnostics( 'Postman Selected Transport', sprintf( '%s (%s)', $transport->getName(), $transportRegistry->getPublicTransportUri( $transport ) ) );
255
+ $this->addToDiagnostics( 'Postman Selected Transport Status (Ready|Connected)', ($transport->isConfiguredAndReady() ? 'Yes' : 'No') . ' | ' . ($this->testConnectivity( $transport )) );
256
  }
257
+ $this->addToDiagnostics( 'Postman Deliveries (Success|Fail)', (PostmanState::getInstance()->getSuccessfulDeliveries()) . ' | ' . (PostmanState::getInstance()->getFailedDeliveries()) );
258
+ if ( $this->options->getConnectionTimeout() != PostmanOptions::DEFAULT_TCP_CONNECTION_TIMEOUT || $this->options->getReadTimeout() != PostmanOptions::DEFAULT_TCP_READ_TIMEOUT ) {
259
+ $this->addToDiagnostics( 'Postman TCP Timeout (Connection|Read)', $this->options->getConnectionTimeout() . ' | ' . $this->options->getReadTimeout() );
260
  }
261
+ if ( $this->options->isMailLoggingEnabled() != PostmanOptions::DEFAULT_MAIL_LOG_ENABLED || $this->options->getMailLoggingMaxEntries() != PostmanOptions::DEFAULT_MAIL_LOG_ENTRIES || $this->options->getTranscriptSize() != PostmanOptions::DEFAULT_TRANSCRIPT_SIZE ) {
262
+ $this->addToDiagnostics( 'Postman Email Log (Enabled|Limit|Transcript Size)', ($this->options->isMailLoggingEnabled() ? 'Yes' : 'No') . ' | ' . $this->options->getMailLoggingMaxEntries() . ' | ' . $this->options->getTranscriptSize() );
263
  }
264
+ $this->addToDiagnostics( 'Postman Run Mode', $this->options->getRunMode() == PostmanOptions::RUN_MODE_PRODUCTION ? null : $this->options->getRunMode() );
265
+ $this->addToDiagnostics( 'Postman PHP LogLevel', $this->options->getLogLevel() == PostmanLogger::ERROR_INT ? null : $this->options->getLogLevel() );
266
+ $this->addToDiagnostics( 'Postman Stealth Mode', $this->options->isStealthModeEnabled() ? 'Yes' : null );
267
+ $this->addToDiagnostics( 'Postman File Locking (Enabled|Temp Dir)', PostmanState::getInstance()->isFileLockingEnabled() ? null : 'No' . ' | ' . $this->options->getTempDirectory() );
268
+ $response = array(
269
+ 'message' => $this->diagnostics,
270
  );
271
+ wp_send_json_success( $response );
272
  }
273
  }
Postman/Postman-Mail/PostmanMandrillMailEngine.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
- if (! class_exists ( "PostmanMandrillMailEngine" )) {
3
-
4
  require_once 'mailchimp-mandrill-api-php-da3adc10042e/src/Mandrill.php';
5
-
6
  /**
7
  * Sends mail with Mandrill API
8
  * https://mandrillapp.com/api/docs/messages.php.html
@@ -10,222 +10,221 @@ if (! class_exists ( "PostmanMandrillMailEngine" )) {
10
  * @author jasonhendriks
11
  */
12
  class PostmanMandrillMailEngine implements PostmanMailEngine {
13
-
14
  // logger for all concrete classes - populate with setLogger($logger)
15
  protected $logger;
16
-
17
  // the result
18
  private $transcript;
19
-
20
- //
21
  private $apiKey;
22
  private $mandrillMessage;
23
-
24
  /**
25
  *
26
- * @param unknown $senderEmail
27
- * @param unknown $accessToken
28
  */
29
- function __construct($apiKey) {
30
- assert ( ! empty ( $apiKey ) );
31
  $this->apiKey = $apiKey;
32
-
33
  // create the logger
34
- $this->logger = new PostmanLogger ( get_class ( $this ) );
35
-
36
  // create the Message
37
- $this->mandrillMessage = array (
38
- 'to' => array (),
39
- 'headers' => array ()
40
  );
41
  }
42
-
43
  /**
44
  * (non-PHPdoc)
45
  *
46
  * @see PostmanSmtpEngine::send()
47
  */
48
- public function send(PostmanMessage $message) {
49
- $options = PostmanOptions::getInstance ();
50
-
51
  // add the Postman signature - append it to whatever the user may have set
52
- if (! $options->isStealthModeEnabled ()) {
53
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
54
- $this->addHeader ( 'X-Mailer', sprintf ( 'Postman SMTP %s for WordPress (%s)', $pluginData ['version'], 'https://wordpress.org/plugins/postman-smtp/' ) );
55
  }
56
-
57
  // add the headers - see http://framework.zend.com/manual/1.12/en/zend.mail.additional-headers.html
58
- foreach ( ( array ) $message->getHeaders () as $header ) {
59
- $this->logger->debug ( sprintf ( 'Adding user header %s=%s', $header ['name'], $header ['content'] ) );
60
- $this->addHeader ( $header ['name'], $header ['content'], true );
61
  }
62
-
63
  // if the caller set a Content-Type header, use it
64
- $contentType = $message->getContentType ();
65
- if (! empty ( $contentType )) {
66
- $this->logger->debug ( 'Adding content-type ' . $contentType );
67
- $this->addHeader ( 'Content-Type', $contentType );
68
  }
69
-
70
  // add the From Header
71
- $sender = $message->getFromAddress ();
72
  {
73
- $senderEmail = $sender->getEmail ();
74
- $senderName = $sender->getName ();
75
- assert ( ! empty ( $senderEmail ) );
76
  $this->mandrillMessage ['from_email'] = $senderEmail;
77
- if (! empty ( $senderName )) {
78
- $this->mandrillMessage ['from_name'] = $senderName;
79
- }
80
  // now log it
81
- $sender->log ( $this->logger, 'From' );
82
  }
83
-
84
  // add the Sender Header, overriding what the user may have set
85
- $this->addHeader ( 'Sender', $options->getEnvelopeSender () );
86
-
87
  // add the to recipients
88
- foreach ( ( array ) $message->getToRecipients () as $recipient ) {
89
- $recipient->log ( $this->logger, 'To' );
90
- $recipient = array (
91
- 'email' => $recipient->getEmail (),
92
- 'name' => $recipient->getName (),
93
- 'type' => 'to'
94
  );
95
- array_push ( $this->mandrillMessage ['to'], $recipient );
96
  }
97
-
98
  // add the cc recipients
99
- foreach ( ( array ) $message->getCcRecipients () as $recipient ) {
100
- $recipient->log ( $this->logger, 'Cc' );
101
- $recipient = array (
102
- 'email' => $recipient->getEmail (),
103
- 'name' => $recipient->getName (),
104
- 'type' => 'cc'
105
  );
106
- array_push ( $this->mandrillMessage ['to'], $recipient );
107
  }
108
-
109
  // add the bcc recipients
110
- foreach ( ( array ) $message->getBccRecipients () as $recipient ) {
111
- $recipient->log ( $this->logger, 'Bcc' );
112
- $recipient = array (
113
- 'email' => $recipient->getEmail (),
114
- 'name' => $recipient->getName (),
115
- 'type' => 'bcc'
116
  );
117
- array_push ( $this->mandrillMessage ['to'], $recipient );
118
  }
119
-
120
  // add the reply-to
121
- $replyTo = $message->getReplyTo ();
122
  // $replyTo is null or a PostmanEmailAddress object
123
- if (isset ( $replyTo )) {
124
- $this->addHeader ( 'reply-to', $replyTo->format () );
125
  }
126
-
127
  // add the date
128
- $date = $message->getDate ();
129
- if (! empty ( $date )) {
130
- $this->addHeader ( 'date', $message->getDate () );
131
  }
132
-
133
  // add the messageId
134
- $messageId = $message->getMessageId ();
135
- if (! empty ( $messageId )) {
136
- $this->addHeader ( 'message-id', $messageId );
137
  }
138
-
139
  // add the subject
140
- if (null !== $message->getSubject ()) {
141
- $this->mandrillMessage ['subject'] = $message->getSubject ();
142
  }
143
-
144
  // add the message content
145
  {
146
- $textPart = $message->getBodyTextPart ();
147
- if (! empty ( $textPart )) {
148
- $this->logger->debug ( 'Adding body as text' );
149
- $this->mandrillMessage ['text'] = $textPart;
150
- }
151
- $htmlPart = $message->getBodyHtmlPart ();
152
- if (! empty ( $htmlPart )) {
153
- $this->logger->debug ( 'Adding body as html' );
154
- $this->mandrillMessage ['html'] = $htmlPart;
155
- }
156
  }
157
-
 
158
  // add attachments
159
- $this->logger->debug ( "Adding attachments" );
160
- $this->addAttachmentsToMail ( $message );
161
-
162
- $result = array ();
163
  try {
164
- if ($this->logger->isDebug ()) {
165
- $this->logger->debug ( "Creating Mandrill service with apiKey=" . $this->apiKey );
166
  }
167
- $mandrill = new Postman_Mandrill ( $this->apiKey );
168
-
169
  // send the message
170
- if ($this->logger->isDebug ()) {
171
- $this->logger->debug ( "Sending mail" );
172
  }
173
-
174
- $result = $mandrill->messages->send ( $this->mandrillMessage );
175
- if ($this->logger->isInfo ()) {
176
- $this->logger->info ( sprintf ( 'Message %d accepted for delivery', PostmanState::getInstance ()->getSuccessfulDeliveries () + 1 ) );
177
  }
178
-
179
- $this->transcript = print_r ( $result, true );
180
  $this->transcript .= PostmanModuleTransport::RAW_MESSAGE_FOLLOWS;
181
- $this->transcript .= print_r ( $this->mandrillMessage, true );
182
  } catch ( Exception $e ) {
183
- $this->transcript = $e->getMessage ();
184
  $this->transcript .= PostmanModuleTransport::RAW_MESSAGE_FOLLOWS;
185
- $this->transcript .= print_r ( $this->mandrillMessage, true );
186
  throw $e;
187
  }
188
  }
189
- private function addHeader($key, $value, $append = false) {
190
- $this->logger->debug ( 'Adding header: ' . $key . ' = ' . $value );
191
  $header = &$this->mandrillMessage ['headers'];
192
- if ($append && ! empty ( $header [$key] )) {
193
- $header [$key] = $header [$key] . ', ' . $value;
194
  } else {
195
- $header [$key] = $value;
196
  }
197
  }
198
-
199
  /**
200
  * Add attachments to the message
201
  *
202
- * @param Postman_Zend_Mail $mail
203
  */
204
- private function addAttachmentsToMail(PostmanMessage $message) {
205
- $attachments = $message->getAttachments ();
206
- if (isset ( $attachments )) {
207
- $this->mandrillMessage ['attachments'] = array ();
208
- if (! is_array ( $attachments )) {
209
  // WordPress may a single filename or a newline-delimited string list of multiple filenames
210
- $attArray = explode ( PHP_EOL, $attachments );
211
  } else {
212
  $attArray = $attachments;
213
  }
214
  // otherwise WordPress sends an array
215
  foreach ( $attArray as $file ) {
216
- if (! empty ( $file )) {
217
- $this->logger->debug ( "Adding attachment: " . $file );
218
- $attachment = array (
219
  'type' => 'attachment',
220
- 'name' => basename ( $file ),
221
- 'content' => file_get_contents ( $file )
222
  );
223
- array_push ( $this->mandrillMessage ['attachments'], $attachment );
224
  }
225
  }
226
  }
227
  }
228
-
229
  // return the SMTP session transcript
230
  public function getTranscript() {
231
  return $this->transcript;
1
  <?php
2
+ if ( ! class_exists( 'PostmanMandrillMailEngine' ) ) {
3
+
4
  require_once 'mailchimp-mandrill-api-php-da3adc10042e/src/Mandrill.php';
5
+
6
  /**
7
  * Sends mail with Mandrill API
8
  * https://mandrillapp.com/api/docs/messages.php.html
10
  * @author jasonhendriks
11
  */
12
  class PostmanMandrillMailEngine implements PostmanMailEngine {
13
+
14
  // logger for all concrete classes - populate with setLogger($logger)
15
  protected $logger;
16
+
17
  // the result
18
  private $transcript;
19
+
 
20
  private $apiKey;
21
  private $mandrillMessage;
22
+
23
  /**
24
  *
25
+ * @param unknown $senderEmail
26
+ * @param unknown $accessToken
27
  */
28
+ function __construct( $apiKey ) {
29
+ assert( ! empty( $apiKey ) );
30
  $this->apiKey = $apiKey;
31
+
32
  // create the logger
33
+ $this->logger = new PostmanLogger( get_class( $this ) );
34
+
35
  // create the Message
36
+ $this->mandrillMessage = array(
37
+ 'to' => array(),
38
+ 'headers' => array(),
39
  );
40
  }
41
+
42
  /**
43
  * (non-PHPdoc)
44
  *
45
  * @see PostmanSmtpEngine::send()
46
  */
47
+ public function send( PostmanMessage $message ) {
48
+ $options = PostmanOptions::getInstance();
49
+
50
  // add the Postman signature - append it to whatever the user may have set
51
+ if ( ! $options->isStealthModeEnabled() ) {
52
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
53
+ $this->addHeader( 'X-Mailer', sprintf( 'Postman SMTP %s for WordPress (%s)', $pluginData ['version'], 'https://wordpress.org/plugins/post-smtp/' ) );
54
  }
55
+
56
  // add the headers - see http://framework.zend.com/manual/1.12/en/zend.mail.additional-headers.html
57
+ foreach ( ( array ) $message->getHeaders() as $header ) {
58
+ $this->logger->debug( sprintf( 'Adding user header %s=%s', $header ['name'], $header ['content'] ) );
59
+ $this->addHeader( $header ['name'], $header ['content'], true );
60
  }
61
+
62
  // if the caller set a Content-Type header, use it
63
+ $contentType = $message->getContentType();
64
+ if ( ! empty( $contentType ) ) {
65
+ $this->logger->debug( 'Adding content-type ' . $contentType );
66
+ $this->addHeader( 'Content-Type', $contentType );
67
  }
68
+
69
  // add the From Header
70
+ $sender = $message->getFromAddress();
71
  {
72
+ $senderEmail = PostmanOptions::getInstance()->getMessageSenderEmail();
73
+ $senderName = $sender->getName();
74
+ assert( ! empty( $senderEmail ) );
75
  $this->mandrillMessage ['from_email'] = $senderEmail;
76
+ if ( ! empty( $senderName ) ) {
77
+ $this->mandrillMessage ['from_name'] = $senderName;
78
+ }
79
  // now log it
80
+ $sender->log( $this->logger, 'From' );
81
  }
82
+
83
  // add the Sender Header, overriding what the user may have set
84
+ $this->addHeader( 'Sender', $options->getEnvelopeSender() );
85
+
86
  // add the to recipients
87
+ foreach ( ( array ) $message->getToRecipients() as $recipient ) {
88
+ $recipient->log( $this->logger, 'To' );
89
+ $recipient = array(
90
+ 'email' => $recipient->getEmail(),
91
+ 'name' => $recipient->getName(),
92
+ 'type' => 'to',
93
  );
94
+ array_push( $this->mandrillMessage ['to'], $recipient );
95
  }
96
+
97
  // add the cc recipients
98
+ foreach ( ( array ) $message->getCcRecipients() as $recipient ) {
99
+ $recipient->log( $this->logger, 'Cc' );
100
+ $recipient = array(
101
+ 'email' => $recipient->getEmail(),
102
+ 'name' => $recipient->getName(),
103
+ 'type' => 'cc',
104
  );
105
+ array_push( $this->mandrillMessage ['to'], $recipient );
106
  }
107
+
108
  // add the bcc recipients
109
+ foreach ( ( array ) $message->getBccRecipients() as $recipient ) {
110
+ $recipient->log( $this->logger, 'Bcc' );
111
+ $recipient = array(
112
+ 'email' => $recipient->getEmail(),
113
+ 'name' => $recipient->getName(),
114
+ 'type' => 'bcc',
115
  );
116
+ array_push( $this->mandrillMessage ['to'], $recipient );
117
  }
118
+
119
  // add the reply-to
120
+ $replyTo = $message->getReplyTo();
121
  // $replyTo is null or a PostmanEmailAddress object
122
+ if ( isset( $replyTo ) ) {
123
+ $this->addHeader( 'reply-to', $replyTo->format() );
124
  }
125
+
126
  // add the date
127
+ $date = $message->getDate();
128
+ if ( ! empty( $date ) ) {
129
+ $this->addHeader( 'date', $message->getDate() );
130
  }
131
+
132
  // add the messageId
133
+ $messageId = $message->getMessageId();
134
+ if ( ! empty( $messageId ) ) {
135
+ $this->addHeader( 'message-id', $messageId );
136
  }
137
+
138
  // add the subject
139
+ if ( null !== $message->getSubject() ) {
140
+ $this->mandrillMessage ['subject'] = $message->getSubject();
141
  }
142
+
143
  // add the message content
144
  {
145
+ $textPart = $message->getBodyTextPart();
146
+ if ( ! empty( $textPart ) ) {
147
+ $this->logger->debug( 'Adding body as text' );
148
+ $this->mandrillMessage ['text'] = $textPart;
149
+ }
150
+ $htmlPart = $message->getBodyHtmlPart();
151
+ if ( ! empty( $htmlPart ) ) {
152
+ $this->logger->debug( 'Adding body as html' );
153
+ $this->mandrillMessage ['html'] = $htmlPart;
 
154
  }
155
+ }
156
+
157
  // add attachments
158
+ $this->logger->debug( 'Adding attachments' );
159
+ $this->addAttachmentsToMail( $message );
160
+
161
+ $result = array();
162
  try {
163
+ if ( $this->logger->isDebug() ) {
164
+ $this->logger->debug( 'Creating Mandrill service with apiKey=' . $this->apiKey );
165
  }
166
+ $mandrill = new Postman_Mandrill( $this->apiKey );
167
+
168
  // send the message
169
+ if ( $this->logger->isDebug() ) {
170
+ $this->logger->debug( 'Sending mail' );
171
  }
172
+
173
+ $result = $mandrill->messages->send( $this->mandrillMessage );
174
+ if ( $this->logger->isInfo() ) {
175
+ $this->logger->info( sprintf( 'Message %d accepted for delivery', PostmanState::getInstance()->getSuccessfulDeliveries() + 1 ) );
176
  }
177
+
178
+ $this->transcript = print_r( $result, true );
179
  $this->transcript .= PostmanModuleTransport::RAW_MESSAGE_FOLLOWS;
180
+ $this->transcript .= print_r( $this->mandrillMessage, true );
181
  } catch ( Exception $e ) {
182
+ $this->transcript = $e->getMessage();
183
  $this->transcript .= PostmanModuleTransport::RAW_MESSAGE_FOLLOWS;
184
+ $this->transcript .= print_r( $this->mandrillMessage, true );
185
  throw $e;
186
  }
187
  }
188
+ private function addHeader( $key, $value, $append = false ) {
189
+ $this->logger->debug( 'Adding header: ' . $key . ' = ' . $value );
190
  $header = &$this->mandrillMessage ['headers'];
191
+ if ( $append && ! empty( $header [ $key ] ) ) {
192
+ $header [ $key ] = $header [ $key ] . ', ' . $value;
193
  } else {
194
+ $header [ $key ] = $value;
195
  }
196
  }
197
+
198
  /**
199
  * Add attachments to the message
200
  *
201
+ * @param Postman_Zend_Mail $mail
202
  */
203
+ private function addAttachmentsToMail( PostmanMessage $message ) {
204
+ $attachments = $message->getAttachments();
205
+ if ( isset( $attachments ) ) {
206
+ $this->mandrillMessage ['attachments'] = array();
207
+ if ( ! is_array( $attachments ) ) {
208
  // WordPress may a single filename or a newline-delimited string list of multiple filenames
209
+ $attArray = explode( PHP_EOL, $attachments );
210
  } else {
211
  $attArray = $attachments;
212
  }
213
  // otherwise WordPress sends an array
214
  foreach ( $attArray as $file ) {
215
+ if ( ! empty( $file ) ) {
216
+ $this->logger->debug( 'Adding attachment: ' . $file );
217
+ $attachment = array(
218
  'type' => 'attachment',
219
+ 'name' => basename( $file ),
220
+ 'content' => base64_encode( file_get_contents( $file ) ),
221
  );
222
+ array_push( $this->mandrillMessage ['attachments'], $attachment );
223
  }
224
  }
225
  }
226
  }
227
+
228
  // return the SMTP session transcript
229
  public function getTranscript() {
230
  return $this->transcript;
Postman/Postman-Mail/PostmanMessage.php CHANGED
@@ -1,8 +1,8 @@
1
  <?php
2
- if (! class_exists ( "PostmanMessage" )) {
3
-
4
  require_once 'PostmanEmailAddress.php';
5
-
6
  /**
7
  * This class knows how to interface with Wordpress
8
  * including loading/saving to the database.
@@ -11,14 +11,13 @@ if (! class_exists ( "PostmanMessage" )) {
11
  * http://framework.zend.com/manual/current/en/modules/zend.mail.smtp.options.html
12
  *
13
  * @author jasonhendriks
14
- *
15
  */
16
  class PostmanMessage {
17
  const EOL = "\r\n";
18
-
19
  // logger for all concrete classes - populate with setLogger($logger)
20
  protected $logger;
21
-
22
  // set by the caller
23
  private $from;
24
  private $replyTo;
@@ -33,44 +32,43 @@ if (! class_exists ( "PostmanMessage" )) {
33
  private $attachments;
34
  private $date;
35
  private $messageId;
36
-
37
  // determined by the send() method
38
  private $isTextHtml;
39
  private $contentType;
40
  private $charset;
41
-
42
- //
43
  private $boundary;
44
-
45
  /**
46
  * No-argument constructor
47
  */
48
  function __construct() {
49
- $this->logger = new PostmanLogger ( get_class ( $this ) );
50
- $this->headers = array ();
51
- $this->toRecipients = array ();
52
- $this->ccRecipients = array ();
53
- $this->bccRecipients = array ();
54
  }
55
-
56
  /**
57
  *
58
  * @return boolean
59
  */
60
  public function isBodyPartsEmpty() {
61
- return empty ( $this->bodyTextPart ) && empty ( $this->bodyHtmlPart );
62
  }
63
-
64
  /**
65
  *
66
- * @param PostmanModuleTransport $transport
67
  */
68
- public function validate(PostmanModuleTransport $transport) {
69
- if ($transport->isEmailValidationSupported ()) {
70
- $this->internalValidate ();
71
  }
72
  }
73
-
74
  /**
75
  * Create body parts based on content type
76
  * MyMail creates its own body parts
@@ -78,176 +76,175 @@ if (! class_exists ( "PostmanMessage" )) {
78
  public function createBodyParts() {
79
 
80
  // modify the content-type to include the boundary
81
- if (false !== stripos ( $this->contentType, 'multipart' ) && ! empty ( $this->boundary )) {
82
  // Lines in email are terminated by CRLF ("\r\n") according to RFC2821
83
- $this->contentType = sprintf ( "%s;\r\n\t boundary=\"%s\"", $this->contentType, $this->getBoundary () );
84
  }
85
-
86
- //
87
- $body = $this->getBody ();
88
- $contentType = $this->getContentType ();
89
  // add the message content as either text or html
90
- if (empty ( $contentType ) || substr ( $contentType, 0, 10 ) === 'text/plain') {
91
- $this->logger->debug ( 'Creating text body part' );
92
- $this->setBodyTextPart ( $body );
93
- } else if (substr ( $contentType, 0, 9 ) === 'text/html') {
94
- $this->logger->debug ( 'Creating html body part' );
95
- $this->setBodyHtmlPart ( $body );
96
- } else if (substr ( $contentType, 0, 21 ) === 'multipart/alternative') {
97
- $this->logger->debug ( 'Adding body as multipart/alternative' );
98
- $arr = explode ( PHP_EOL, $body );
99
  $textBody = '';
100
  $htmlBody = '';
101
  $mode = '';
102
  foreach ( $arr as $s ) {
103
- $this->logger->trace ( 'mode: ' . $mode . ' bodyline: ' . $s );
104
- if (substr ( $s, 0, 25 ) === "Content-Type: text/plain;") {
105
  $mode = 'foundText';
106
- } else if (substr ( $s, 0, 24 ) === "Content-Type: text/html;") {
107
  $mode = 'foundHtml';
108
- } else if ($mode == 'textReading') {
109
  $textBody .= $s;
110
- } else if ($mode == 'htmlReading') {
111
  $htmlBody .= $s;
112
- } else if ($mode == 'foundText') {
113
- $trim = trim ( $s );
114
- if (empty ( $trim )) {
115
  $mode = 'textReading';
116
  }
117
- } else if ($mode == 'foundHtml') {
118
- $trim = trim ( $s );
119
- if (empty ( $trim )) {
120
  $mode = 'htmlReading';
121
  }
122
  }
123
  }
124
- $this->setBodyHtmlPart ( $htmlBody );
125
- $this->setBodyTextPart ( $textBody );
126
  } else {
127
- $this->logger->error ( 'Unknown content-type: ' . $contentType );
128
- $this->setBodyTextPart ( $body );
129
  }
130
  }
131
-
132
  /**
133
  * Apply the WordPress filters to the email
134
  */
135
  public function applyFilters() {
136
- if ($this->logger->isDebug ()) {
137
- $this->logger->debug ( 'Applying WordPress filters' );
138
  }
139
-
140
  /**
141
  * Filter the email address to send from.
142
  *
143
  * @since 2.2.0
144
- *
145
  * @param string $from_email
146
  * Email address to send from.
147
  */
148
- $filteredEmail = apply_filters ( 'wp_mail_from', $this->getFromAddress ()->getEmail () );
149
- if ($this->logger->isTrace ()) {
150
- $this->logger->trace ( 'wp_mail_from: ' . $filteredEmail );
151
  }
152
- if ($this->getFromAddress ()->getEmail () !== $filteredEmail) {
153
- $this->logger->debug ( sprintf ( 'Filtering From email address: before=%s after=%s', $this->getFromAddress ()->getEmail (), $filteredEmail ) );
154
- $this->getFromAddress ()->setEmail ( $filteredEmail );
155
  }
156
-
157
  /**
158
  * Filter the name to associate with the "from" email address.
159
  *
160
  * @since 2.3.0
161
- *
162
  * @param string $from_name
163
  * Name associated with the "from" email address.
164
  */
165
- $filteredName = apply_filters ( 'wp_mail_from_name', $this->getFromAddress ()->getName () );
166
- if ($this->logger->isTrace ()) {
167
- $this->logger->trace ( 'wp_mail_from_name: ' . $filteredName );
168
  }
169
- if ($this->getFromAddress ()->getName () !== $filteredName) {
170
- $this->logger->debug ( sprintf ( 'Filtering From email name: before=%s after=%s', $this->getFromAddress ()->getName (), $filteredName ) );
171
- $this->getFromAddress ()->setName ( $filteredName );
172
  }
173
-
174
  /**
175
  * Filter the default wp_mail() charset.
176
  *
177
  * @since 2.3.0
178
- *
179
  * @param string $charset
180
  * Default email charset.
181
  */
182
- $filteredCharset = apply_filters ( 'wp_mail_charset', $this->getCharset () );
183
- if ($this->logger->isTrace ()) {
184
- $this->logger->trace ( 'wp_mail_charset: ' . $filteredCharset );
185
  }
186
- if ($this->getCharset () !== $filteredCharset) {
187
- $this->logger->debug ( sprintf ( 'Filtering Charset: before=%s after=%s', $this->getCharset (), $filteredCharset ) );
188
- $this->setCharset ( $filteredCharset );
189
  }
190
-
191
  /**
192
  * Filter the wp_mail() content type.
193
  *
194
  * @since 2.3.0
195
- *
196
  * @param string $content_type
197
  * Default wp_mail() content type.
198
  */
199
- $filteredContentType = apply_filters ( 'wp_mail_content_type', $this->getContentType () );
200
- if ($this->logger->isTrace ()) {
201
- $this->logger->trace ( sprintf ( 'wp_mail_content_type: "%s"', $filteredContentType ) );
202
  }
203
- if ($this->getContentType () != $filteredContentType) {
204
- $this->logger->debug ( sprintf ( 'Filtering Content-Type: before=%s after=%s', $this->getContentType (), $filteredContentType ) );
205
- $this->setContentType ( $filteredContentType );
206
  }
207
-
208
  // Postman has it's own 'user override' filter
209
- $options = PostmanOptions::getInstance ();
210
- $forcedEmailAddress = $options->getMessageSenderEmail ();
211
- if ($options->isSenderEmailOverridePrevented () && $this->getFromAddress ()->getEmail () !== $forcedEmailAddress) {
212
- $this->logger->debug ( sprintf ( 'Forced From email address: before=%s after=%s', $this->getFromAddress ()->getEmail (), $forcedEmailAddress ) );
213
- $this->getFromAddress ()->setEmail ( $forcedEmailAddress );
214
  }
215
- $forcedEmailName = $options->getMessageSenderName ();
216
- if ($options->isSenderNameOverridePrevented () && $this->getFromAddress ()->getName () !== $forcedEmailName) {
217
- $this->logger->debug ( sprintf ( 'Forced From email name: before=%s after=%s', $this->getFromAddress ()->getName (), $forcedEmailName ) );
218
- $this->getFromAddress ()->setName ( $forcedEmailName );
219
  }
220
  }
221
-
222
  /**
223
  * Check all email headers for errors
224
  * Throw an exception if an error is found
225
  */
226
  private function internalValidate() {
227
  // check the reply-to address for errors
228
- if (isset ( $this->replyTo )) {
229
- $this->getReplyTo ()->validate ( 'Reply-To' );
230
  }
231
-
232
  // check the from address for errors
233
- $this->getFromAddress ()->validate ( 'From' );
234
-
235
  // validate the To recipients
236
- foreach ( ( array ) $this->getToRecipients () as $toRecipient ) {
237
- $toRecipient->validate ( 'To' );
238
  }
239
-
240
  // validate the Cc recipients
241
- foreach ( ( array ) $this->getCcRecipients () as $ccRecipient ) {
242
- $ccRecipient->validate ( 'Cc' );
243
  }
244
-
245
  // validate the Bcc recipients
246
- foreach ( ( array ) $this->getBccRecipients () as $bccRecipient ) {
247
- $bccRecipient->validate ( 'Bcc' );
248
  }
249
  }
250
-
251
  /**
252
  *
253
  * @return PostmanEmailAddress
@@ -255,7 +252,7 @@ if (! class_exists ( "PostmanMessage" )) {
255
  public function getFromAddress() {
256
  return $this->from;
257
  }
258
-
259
  /**
260
  * Get the charset, checking first the WordPress bloginfo, then the header, then the wp_mail_charset filter.
261
  *
@@ -264,16 +261,16 @@ if (! class_exists ( "PostmanMessage" )) {
264
  public function getCharset() {
265
  return $this->charset;
266
  }
267
-
268
  /**
269
  * Set the charset
270
  *
271
- * @param unknown $charset
272
  */
273
- public function setCharset($charset) {
274
  $this->charset = $charset;
275
  }
276
-
277
  /**
278
  * Get the content type, checking first the header, then the wp_mail_content_type filter
279
  *
@@ -282,7 +279,7 @@ if (! class_exists ( "PostmanMessage" )) {
282
  public function getContentType() {
283
  return $this->contentType;
284
  }
285
- public function setContentType($contentType) {
286
  $this->contentType = $contentType;
287
  }
288
  /**
@@ -291,8 +288,8 @@ if (! class_exists ( "PostmanMessage" )) {
291
  * Array or comma-separated list of email addresses to send message.
292
  * @throws Exception
293
  */
294
- public function addTo($to) {
295
- $this->addRecipients ( $this->toRecipients, $to );
296
  }
297
  /**
298
  *
@@ -300,8 +297,8 @@ if (! class_exists ( "PostmanMessage" )) {
300
  * Array or comma-separated list of email addresses to send message.
301
  * @throws Exception
302
  */
303
- public function addCc($cc) {
304
- $this->addRecipients ( $this->ccRecipients, $cc );
305
  }
306
  /**
307
  *
@@ -309,8 +306,8 @@ if (! class_exists ( "PostmanMessage" )) {
309
  * Array or comma-separated list of email addresses to send message.
310
  * @throws Exception
311
  */
312
- public function addBcc($bcc) {
313
- $this->addRecipients ( $this->bccRecipients, $bcc );
314
  }
315
  /**
316
  *
@@ -318,208 +315,208 @@ if (! class_exists ( "PostmanMessage" )) {
318
  * Array or comma-separated list of email addresses to send message.
319
  * @throws Exception
320
  */
321
- private function addRecipients(&$recipientList, $recipients) {
322
- if (! empty ( $recipients )) {
323
- $recipients = PostmanEmailAddress::convertToArray ( $recipients );
324
  foreach ( $recipients as $recipient ) {
325
- if (! empty ( $recipient )) {
326
- $this->logger->debug ( sprintf ( 'User added recipient: "%s"', $recipient ) );
327
- array_push ( $recipientList, new PostmanEmailAddress ( $recipient ) );
328
  }
329
  }
330
  }
331
  }
332
-
333
  /**
334
  * For the string version, each header line (beginning with From:, Cc:, etc.) is delimited with a newline ("\r\n")
335
  */
336
- public function addHeaders($headers) {
337
- if (! is_array ( $headers )) {
338
  // WordPress may send a string where "each header line (beginning with From:, Cc:, etc.) is delimited with a newline ("\r\n") (advanced)"
339
  // this converts that string to an array
340
- $headers = explode ( "\n", str_replace ( "\r\n", "\n", $headers ) );
341
  // $headers = explode ( PHP_EOL, $headers );
342
  }
343
  // otherwise WordPress sends an array
344
  foreach ( $headers as $header ) {
345
- if (! empty ( $header )) {
346
  // boundary may be in a header line, but it's not a header
347
  // eg. boundary="----=_NextPart_DC7E1BB5...
348
- if (strpos ( $header, ':' ) === false) {
349
- if (false !== stripos ( $header, 'boundary=' )) {
350
- $parts = preg_split ( '/boundary=/i', trim ( $header ) );
351
- $this->boundary = trim ( str_replace ( array (
352
  "'",
353
- '"'
354
  ), '', $parts [1] ) );
355
- $this->logger->debug ( sprintf ( 'Processing special boundary header \'%s\'', $this->getBoundary () ) );
356
  } else {
357
- $this->logger->debug ( sprintf ( 'Ignoring broken header \'%s\'', $header ) );
358
  }
359
  continue;
360
  }
361
- list ( $name, $content ) = explode ( ':', trim ( $header ), 2 );
362
- $this->processHeader ( $name, $content );
363
  }
364
  }
365
  }
366
-
367
  /**
368
  * Add the headers that were processed in processHeaders()
369
  * Zend requires that several headers are specially handled.
370
  *
371
- * @param unknown $name
372
- * @param unknown $value
373
- * @param Postman_Zend_Mail $mail
374
  */
375
- private function processHeader($name, $content) {
376
- $name = trim ( $name );
377
- $content = trim ( $content );
378
- switch (strtolower ( $name )) {
379
  case 'content-type' :
380
- $this->logProcessHeader ( 'Content-Type', $name, $content );
381
- if (strpos ( $content, ';' ) !== false) {
382
- list ( $type, $charset ) = explode ( ';', $content );
383
- $this->setContentType ( trim ( $type ) );
384
- if (false !== stripos ( $charset, 'charset=' )) {
385
- $charset = trim ( str_replace ( array (
386
  'charset=',
387
- '"'
388
  ), '', $charset ) );
389
- } elseif (false !== stripos ( $charset, 'boundary=' )) {
390
- $this->boundary = trim ( str_replace ( array (
391
  'BOUNDARY=',
392
  'boundary=',
393
- '"'
394
  ), '', $charset ) );
395
  $charset = '';
396
  }
397
- if (! empty ( $charset )) {
398
- $this->setCharset ( $charset );
399
  }
400
  } else {
401
- $this->setContentType ( trim ( $content ) );
402
  }
403
  break;
404
  case 'to' :
405
- $this->logProcessHeader ( 'To', $name, $content );
406
- $this->addTo ( $content );
407
  break;
408
  case 'cc' :
409
- $this->logProcessHeader ( 'Cc', $name, $content );
410
- $this->addCc ( $content );
411
  break;
412
  case 'bcc' :
413
- $this->logProcessHeader ( 'Bcc', $name, $content );
414
- $this->addBcc ( $content );
415
  break;
416
  case 'from' :
417
- $this->logProcessHeader ( 'From', $name, $content );
418
- $this->setFrom ( $content );
419
  break;
420
  case 'subject' :
421
- $this->logProcessHeader ( 'Subject', $name, $content );
422
- $this->setSubject ( $content );
423
  break;
424
  case 'reply-to' :
425
- $this->logProcessHeader ( 'Reply-To', $name, $content );
426
- $this->setReplyTo ( $content );
427
  break;
428
  case 'sender' :
429
- $this->logProcessHeader ( 'Sender', $name, $content );
430
- $this->logger->warn ( sprintf ( 'Ignoring Sender header \'%s\'', $content ) );
431
  break;
432
  case 'return-path' :
433
- $this->logProcessHeader ( 'Return-Path', $name, $content );
434
- $this->logger->warn ( sprintf ( 'Ignoring Return-Path header \'%s\'', $content ) );
435
  break;
436
  case 'date' :
437
- $this->logProcessHeader ( 'Date', $name, $content );
438
- $this->setDate ( $content );
439
  break;
440
  case 'message-id' :
441
- $this->logProcessHeader ( 'Message-Id', $name, $content );
442
- $this->setMessageId ( $content );
443
  break;
444
  default :
445
  // Add it to our grand headers array
446
- $this->logProcessHeader ( 'other', $name, $content );
447
- array_push ( $this->headers, array (
448
  'name' => $name,
449
- 'content' => $content
450
  ) );
451
  break;
452
  }
453
  }
454
-
455
  /**
456
  *
457
- * @param unknown $desc
458
- * @param unknown $name
459
- * @param unknown $content
460
  */
461
- private function logProcessHeader($desc, $name, $content) {
462
- $this->logger->debug ( 'Processing ' . $desc . ' Header - ' . $name . ': ' . $content );
463
  }
464
-
465
  /**
466
  * Add attachments to the message
467
  *
468
- * @param Postman_Zend_Mail $mail
469
  */
470
- public function addAttachmentsToMail(Postman_Zend_Mail $mail) {
471
  $attachments = $this->attachments;
472
- if (! is_array ( $attachments )) {
473
  // WordPress may a single filename or a newline-delimited string list of multiple filenames
474
- $attArray = explode ( PHP_EOL, $attachments );
475
  } else {
476
  $attArray = $attachments;
477
  }
478
  // otherwise WordPress sends an array
479
  foreach ( $attArray as $file ) {
480
- if (! empty ( $file )) {
481
- $this->logger->debug ( "Adding attachment: " . $file );
482
- $at = new Postman_Zend_Mime_Part ( file_get_contents ( $file ) );
483
  // $at->type = 'image/gif';
484
  $at->disposition = Postman_Zend_Mime::DISPOSITION_ATTACHMENT;
485
  $at->encoding = Postman_Zend_Mime::ENCODING_BASE64;
486
- $at->filename = basename ( $file );
487
- $mail->addAttachment ( $at );
488
  }
489
  }
490
  }
491
- function setBody($body) {
492
  $this->body = $body;
493
  }
494
- function setBodyTextPart($bodyTextPart) {
495
  $this->bodyTextPart = $bodyTextPart;
496
  }
497
- function setBodyHtmlPart($bodyHtmlPart) {
498
  $this->bodyHtmlPart = $bodyHtmlPart;
499
  }
500
- function setSubject($subject) {
501
  $this->subject = $subject;
502
  }
503
- function setAttachments($attachments) {
504
  $this->attachments = $attachments;
505
  }
506
- function setFrom($email, $name = null) {
507
- if (! empty ( $email )) {
508
- $this->from = new PostmanEmailAddress ( $email, $name );
509
  }
510
  }
511
- function setReplyTo($replyTo) {
512
- if (! empty ( $replyTo )) {
513
- $this->replyTo = new PostmanEmailAddress ( $replyTo );
514
  }
515
  }
516
- function setMessageId($messageId) {
517
  $this->messageId = $messageId;
518
  }
519
- function setDate($date) {
520
  $this->date = $date;
521
  }
522
-
523
  // return the headers
524
  public function getHeaders() {
525
  return $this->headers;
1
  <?php
2
+ if ( ! class_exists( 'PostmanMessage' ) ) {
3
+
4
  require_once 'PostmanEmailAddress.php';
5
+
6
  /**
7
  * This class knows how to interface with Wordpress
8
  * including loading/saving to the database.
11
  * http://framework.zend.com/manual/current/en/modules/zend.mail.smtp.options.html
12
  *
13
  * @author jasonhendriks
 
14
  */
15
  class PostmanMessage {
16
  const EOL = "\r\n";
17
+
18
  // logger for all concrete classes - populate with setLogger($logger)
19
  protected $logger;
20
+
21
  // set by the caller
22
  private $from;
23
  private $replyTo;
32
  private $attachments;
33
  private $date;
34
  private $messageId;
35
+
36
  // determined by the send() method
37
  private $isTextHtml;
38
  private $contentType;
39
  private $charset;
40
+
 
41
  private $boundary;
42
+
43
  /**
44
  * No-argument constructor
45
  */
46
  function __construct() {
47
+ $this->logger = new PostmanLogger( get_class( $this ) );
48
+ $this->headers = array();
49
+ $this->toRecipients = array();
50
+ $this->ccRecipients = array();
51
+ $this->bccRecipients = array();
52
  }
53
+
54
  /**
55
  *
56
  * @return boolean
57
  */
58
  public function isBodyPartsEmpty() {
59
+ return empty( $this->bodyTextPart ) && empty( $this->bodyHtmlPart );
60
  }
61
+
62
  /**
63
  *
64
+ * @param PostmanModuleTransport $transport
65
  */
66
+ public function validate( PostmanModuleTransport $transport ) {
67
+ if ( $transport->isEmailValidationSupported() ) {
68
+ $this->internalValidate();
69
  }
70
  }
71
+
72
  /**
73
  * Create body parts based on content type
74
  * MyMail creates its own body parts
76
  public function createBodyParts() {
77
 
78
  // modify the content-type to include the boundary
79
+ if ( false !== stripos( $this->contentType, 'multipart' ) && ! empty( $this->boundary ) ) {
80
  // Lines in email are terminated by CRLF ("\r\n") according to RFC2821
81
+ $this->contentType = sprintf( "%s;\r\n\t boundary=\"%s\"", $this->contentType, $this->getBoundary() );
82
  }
83
+
84
+ $body = $this->getBody();
85
+ $contentType = $this->getContentType();
 
86
  // add the message content as either text or html
87
+ if ( empty( $contentType ) || substr( $contentType, 0, 10 ) === 'text/plain' ) {
88
+ $this->logger->debug( 'Creating text body part' );
89
+ $this->setBodyTextPart( $body );
90
+ } else if ( substr( $contentType, 0, 9 ) === 'text/html' ) {
91
+ $this->logger->debug( 'Creating html body part' );
92
+ $this->setBodyHtmlPart( $body );
93
+ } else if ( substr( $contentType, 0, 21 ) === 'multipart/alternative' ) {
94
+ $this->logger->debug( 'Adding body as multipart/alternative' );
95
+ $arr = explode( PHP_EOL, $body );
96
  $textBody = '';
97
  $htmlBody = '';
98
  $mode = '';
99
  foreach ( $arr as $s ) {
100
+ $this->logger->trace( 'mode: ' . $mode . ' bodyline: ' . $s );
101
+ if ( substr( $s, 0, 25 ) === 'Content-Type: text/plain;' ) {
102
  $mode = 'foundText';
103
+ } else if ( substr( $s, 0, 24 ) === 'Content-Type: text/html;' ) {
104
  $mode = 'foundHtml';
105
+ } else if ( $mode == 'textReading' ) {
106
  $textBody .= $s;
107
+ } else if ( $mode == 'htmlReading' ) {
108
  $htmlBody .= $s;
109
+ } else if ( $mode == 'foundText' ) {
110
+ $trim = trim( $s );
111
+ if ( empty( $trim ) ) {
112
  $mode = 'textReading';
113
  }
114
+ } else if ( $mode == 'foundHtml' ) {
115
+ $trim = trim( $s );
116
+ if ( empty( $trim ) ) {
117
  $mode = 'htmlReading';
118
  }
119
  }
120
  }
121
+ $this->setBodyHtmlPart( $htmlBody );
122
+ $this->setBodyTextPart( $textBody );
123
  } else {
124
+ $this->logger->error( 'Unknown content-type: ' . $contentType );
125
+ $this->setBodyTextPart( $body );
126
  }
127
  }
128
+
129
  /**
130
  * Apply the WordPress filters to the email
131
  */
132
  public function applyFilters() {
133
+ if ( $this->logger->isDebug() ) {
134
+ $this->logger->debug( 'Applying WordPress filters' );
135
  }
136
+
137
  /**
138
  * Filter the email address to send from.
139
  *
140
  * @since 2.2.0
141
+ *
142
  * @param string $from_email
143
  * Email address to send from.
144
  */
145
+ $filteredEmail = apply_filters( 'wp_mail_from', $this->getFromAddress()->getEmail() );
146
+ if ( $this->logger->isTrace() ) {
147
+ $this->logger->trace( 'wp_mail_from: ' . $filteredEmail );
148
  }
149
+ if ( $this->getFromAddress()->getEmail() !== $filteredEmail ) {
150
+ $this->logger->debug( sprintf( 'Filtering From email address: before=%s after=%s', $this->getFromAddress()->getEmail(), $filteredEmail ) );
151
+ $this->getFromAddress()->setEmail( $filteredEmail );
152
  }
153
+
154
  /**
155
  * Filter the name to associate with the "from" email address.
156
  *
157
  * @since 2.3.0
158
+ *
159
  * @param string $from_name
160
  * Name associated with the "from" email address.
161
  */
162
+ $filteredName = apply_filters( 'wp_mail_from_name', $this->getFromAddress()->getName() );
163
+ if ( $this->logger->isTrace() ) {
164
+ $this->logger->trace( 'wp_mail_from_name: ' . $filteredName );
165
  }
166
+ if ( $this->getFromAddress()->getName() !== $filteredName ) {
167
+ $this->logger->debug( sprintf( 'Filtering From email name: before=%s after=%s', $this->getFromAddress()->getName(), $filteredName ) );
168
+ $this->getFromAddress()->setName( $filteredName );
169
  }
170
+
171
  /**
172
  * Filter the default wp_mail() charset.
173
  *
174
  * @since 2.3.0
175
+ *
176
  * @param string $charset
177
  * Default email charset.
178
  */
179
+ $filteredCharset = apply_filters( 'wp_mail_charset', $this->getCharset() );
180
+ if ( $this->logger->isTrace() ) {
181
+ $this->logger->trace( 'wp_mail_charset: ' . $filteredCharset );
182
  }
183
+ if ( $this->getCharset() !== $filteredCharset ) {
184
+ $this->logger->debug( sprintf( 'Filtering Charset: before=%s after=%s', $this->getCharset(), $filteredCharset ) );
185
+ $this->setCharset( $filteredCharset );
186
  }
187
+
188
  /**
189
  * Filter the wp_mail() content type.
190
  *
191
  * @since 2.3.0
192
+ *
193
  * @param string $content_type
194
  * Default wp_mail() content type.
195
  */
196
+ $filteredContentType = apply_filters( 'wp_mail_content_type', $this->getContentType() );
197
+ if ( $this->logger->isTrace() ) {
198
+ $this->logger->trace( sprintf( 'wp_mail_content_type: "%s"', $filteredContentType ) );
199
  }
200
+ if ( $this->getContentType() != $filteredContentType ) {
201
+ $this->logger->debug( sprintf( 'Filtering Content-Type: before=%s after=%s', $this->getContentType(), $filteredContentType ) );
202
+ $this->setContentType( $filteredContentType );
203
  }
204
+
205
  // Postman has it's own 'user override' filter
206
+ $options = PostmanOptions::getInstance();
207
+ $forcedEmailAddress = $options->getMessageSenderEmail();
208
+ if ( $options->isSenderEmailOverridePrevented() && $this->getFromAddress()->getEmail() !== $forcedEmailAddress ) {
209
+ $this->logger->debug( sprintf( 'Forced From email address: before=%s after=%s', $this->getFromAddress()->getEmail(), $forcedEmailAddress ) );
210
+ $this->getFromAddress()->setEmail( $forcedEmailAddress );
211
  }
212
+ $forcedEmailName = $options->getMessageSenderName();
213
+ if ( $options->isSenderNameOverridePrevented() && $this->getFromAddress()->getName() !== $forcedEmailName ) {
214
+ $this->logger->debug( sprintf( 'Forced From email name: before=%s after=%s', $this->getFromAddress()->getName(), $forcedEmailName ) );
215
+ $this->getFromAddress()->setName( $forcedEmailName );
216
  }
217
  }
218
+
219
  /**
220
  * Check all email headers for errors
221
  * Throw an exception if an error is found
222
  */
223
  private function internalValidate() {
224
  // check the reply-to address for errors
225
+ if ( isset( $this->replyTo ) ) {
226
+ $this->getReplyTo()->validate( 'Reply-To' );
227
  }
228
+
229
  // check the from address for errors
230
+ $this->getFromAddress()->validate( 'From' );
231
+
232
  // validate the To recipients
233
+ foreach ( ( array ) $this->getToRecipients() as $toRecipient ) {
234
+ $toRecipient->validate( 'To' );
235
  }
236
+
237
  // validate the Cc recipients
238
+ foreach ( ( array ) $this->getCcRecipients() as $ccRecipient ) {
239
+ $ccRecipient->validate( 'Cc' );
240
  }
241
+
242
  // validate the Bcc recipients
243
+ foreach ( ( array ) $this->getBccRecipients() as $bccRecipient ) {
244
+ $bccRecipient->validate( 'Bcc' );
245
  }
246
  }
247
+
248
  /**
249
  *
250
  * @return PostmanEmailAddress
252
  public function getFromAddress() {
253
  return $this->from;
254
  }
255
+
256
  /**
257
  * Get the charset, checking first the WordPress bloginfo, then the header, then the wp_mail_charset filter.
258
  *
261
  public function getCharset() {
262
  return $this->charset;
263
  }
264
+
265
  /**
266
  * Set the charset
267
  *
268
+ * @param unknown $charset
269
  */
270
+ public function setCharset( $charset ) {
271
  $this->charset = $charset;
272
  }
273
+
274
  /**
275
  * Get the content type, checking first the header, then the wp_mail_content_type filter
276
  *
279
  public function getContentType() {
280
  return $this->contentType;
281
  }
282
+ public function setContentType( $contentType ) {
283
  $this->contentType = $contentType;
284
  }
285
  /**
288
  * Array or comma-separated list of email addresses to send message.
289
  * @throws Exception
290
  */
291
+ public function addTo( $to ) {
292
+ $this->addRecipients( $this->toRecipients, $to );
293
  }
294
  /**
295
  *
297
  * Array or comma-separated list of email addresses to send message.
298
  * @throws Exception
299
  */
300
+ public function addCc( $cc ) {
301
+ $this->addRecipients( $this->ccRecipients, $cc );
302
  }
303
  /**
304
  *
306
  * Array or comma-separated list of email addresses to send message.
307
  * @throws Exception
308
  */
309
+ public function addBcc( $bcc ) {
310
+ $this->addRecipients( $this->bccRecipients, $bcc );
311
  }
312
  /**
313
  *
315
  * Array or comma-separated list of email addresses to send message.
316
  * @throws Exception
317
  */
318
+ private function addRecipients( &$recipientList, $recipients ) {
319
+ if ( ! empty( $recipients ) ) {
320
+ $recipients = PostmanEmailAddress::convertToArray( $recipients );
321
  foreach ( $recipients as $recipient ) {
322
+ if ( ! empty( $recipient ) ) {
323
+ $this->logger->debug( sprintf( 'User added recipient: "%s"', $recipient ) );
324
+ array_push( $recipientList, new PostmanEmailAddress( $recipient ) );
325
  }
326
  }
327
  }
328
  }
329
+
330
  /**
331
  * For the string version, each header line (beginning with From:, Cc:, etc.) is delimited with a newline ("\r\n")
332
  */
333
+ public function addHeaders( $headers ) {
334
+ if ( ! is_array( $headers ) ) {
335
  // WordPress may send a string where "each header line (beginning with From:, Cc:, etc.) is delimited with a newline ("\r\n") (advanced)"
336
  // this converts that string to an array
337
+ $headers = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
338
  // $headers = explode ( PHP_EOL, $headers );
339
  }
340
  // otherwise WordPress sends an array
341
  foreach ( $headers as $header ) {
342
+ if ( ! empty( $header ) ) {
343
  // boundary may be in a header line, but it's not a header
344
  // eg. boundary="----=_NextPart_DC7E1BB5...
345
+ if ( strpos( $header, ':' ) === false ) {
346
+ if ( false !== stripos( $header, 'boundary=' ) ) {
347
+ $parts = preg_split( '/boundary=/i', trim( $header ) );
348
+ $this->boundary = trim( str_replace( array(
349
  "'",
350
+ '"',
351
  ), '', $parts [1] ) );
352
+ $this->logger->debug( sprintf( 'Processing special boundary header \'%s\'', $this->getBoundary() ) );
353
  } else {
354
+ $this->logger->debug( sprintf( 'Ignoring broken header \'%s\'', $header ) );
355
  }
356
  continue;
357
  }
358
+ list ( $name, $content ) = explode( ':', trim( $header ), 2 );
359
+ $this->processHeader( $name, $content );
360
  }
361
  }
362
  }
363
+
364
  /**
365
  * Add the headers that were processed in processHeaders()
366
  * Zend requires that several headers are specially handled.
367
  *
368
+ * @param unknown $name
369
+ * @param unknown $value
370
+ * @param Postman_Zend_Mail $mail
371
  */
372
+ private function processHeader( $name, $content ) {
373
+ $name = trim( $name );
374
+ $content = trim( $content );
375
+ switch ( strtolower( $name ) ) {
376
  case 'content-type' :
377
+ $this->logProcessHeader( 'Content-Type', $name, $content );
378
+ if ( strpos( $content, ';' ) !== false ) {
379
+ list ( $type, $charset ) = explode( ';', $content );
380
+ $this->setContentType( trim( $type ) );
381
+ if ( false !== stripos( $charset, 'charset=' ) ) {
382
+ $charset = trim( str_replace( array(
383
  'charset=',
384
+ '"',
385
  ), '', $charset ) );
386
+ } elseif ( false !== stripos( $charset, 'boundary=' ) ) {
387
+ $this->boundary = trim( str_replace( array(
388
  'BOUNDARY=',
389
  'boundary=',
390
+ '"',
391
  ), '', $charset ) );
392
  $charset = '';
393
  }
394
+ if ( ! empty( $charset ) ) {
395
+ $this->setCharset( $charset );
396
  }
397
  } else {
398
+ $this->setContentType( trim( $content ) );
399
  }
400
  break;
401
  case 'to' :
402
+ $this->logProcessHeader( 'To', $name, $content );
403
+ $this->addTo( $content );
404
  break;
405
  case 'cc' :
406
+ $this->logProcessHeader( 'Cc', $name, $content );
407
+ $this->addCc( $content );
408
  break;
409
  case 'bcc' :
410
+ $this->logProcessHeader( 'Bcc', $name, $content );
411
+ $this->addBcc( $content );
412
  break;
413
  case 'from' :
414
+ $this->logProcessHeader( 'From', $name, $content );
415
+ $this->setFrom( $content );
416
  break;
417
  case 'subject' :
418
+ $this->logProcessHeader( 'Subject', $name, $content );
419
+ $this->setSubject( $content );
420
  break;
421
  case 'reply-to' :
422
+ $this->logProcessHeader( 'Reply-To', $name, $content );
423
+ $this->setReplyTo( $content );
424
  break;
425
  case 'sender' :
426
+ $this->logProcessHeader( 'Sender', $name, $content );
427
+ $this->logger->warn( sprintf( 'Ignoring Sender header \'%s\'', $content ) );
428
  break;
429
  case 'return-path' :
430
+ $this->logProcessHeader( 'Return-Path', $name, $content );
431
+ $this->logger->warn( sprintf( 'Ignoring Return-Path header \'%s\'', $content ) );
432
  break;
433
  case 'date' :
434
+ $this->logProcessHeader( 'Date', $name, $content );
435
+ $this->setDate( $content );
436
  break;
437
  case 'message-id' :
438
+ $this->logProcessHeader( 'Message-Id', $name, $content );
439
+ $this->setMessageId( $content );
440
  break;
441
  default :
442
  // Add it to our grand headers array
443
+ $this->logProcessHeader( 'other', $name, $content );
444
+ array_push( $this->headers, array(
445
  'name' => $name,
446
+ 'content' => $content,
447
  ) );
448
  break;
449
  }
450
  }
451
+
452
  /**
453
  *
454
+ * @param unknown $desc
455
+ * @param unknown $name
456
+ * @param unknown $content
457
  */
458
+ private function logProcessHeader( $desc, $name, $content ) {
459
+ $this->logger->debug( 'Processing ' . $desc . ' Header - ' . $name . ': ' . $content );
460
  }
461
+
462
  /**
463
  * Add attachments to the message
464
  *
465
+ * @param Postman_Zend_Mail $mail
466
  */
467
+ public function addAttachmentsToMail( Postman_Zend_Mail $mail ) {
468
  $attachments = $this->attachments;
469
+ if ( ! is_array( $attachments ) ) {
470
  // WordPress may a single filename or a newline-delimited string list of multiple filenames
471
+ $attArray = explode( PHP_EOL, $attachments );
472
  } else {
473
  $attArray = $attachments;
474
  }
475
  // otherwise WordPress sends an array
476
  foreach ( $attArray as $file ) {
477
+ if ( ! empty( $file ) ) {
478
+ $this->logger->debug( 'Adding attachment: ' . $file );
479
+ $at = new Postman_Zend_Mime_Part( file_get_contents( $file ) );
480
  // $at->type = 'image/gif';
481
  $at->disposition = Postman_Zend_Mime::DISPOSITION_ATTACHMENT;
482
  $at->encoding = Postman_Zend_Mime::ENCODING_BASE64;
483
+ $at->filename = basename( $file );
484
+ $mail->addAttachment( $at );
485
  }
486
  }
487
  }
488
+ function setBody( $body ) {
489
  $this->body = $body;
490
  }
491
+ function setBodyTextPart( $bodyTextPart ) {
492
  $this->bodyTextPart = $bodyTextPart;
493
  }
494
+ function setBodyHtmlPart( $bodyHtmlPart ) {
495
  $this->bodyHtmlPart = $bodyHtmlPart;
496
  }
497
+ function setSubject( $subject ) {
498
  $this->subject = $subject;
499
  }
500
+ function setAttachments( $attachments ) {
501
  $this->attachments = $attachments;
502
  }
503
+ function setFrom( $email, $name = null ) {
504
+ if ( ! empty( $email ) ) {
505
+ $this->from = new PostmanEmailAddress( $email, $name );
506
  }
507
  }
508
+ function setReplyTo( $replyTo ) {
509
+ if ( ! empty( $replyTo ) ) {
510
+ $this->replyTo = new PostmanEmailAddress( $replyTo );
511
  }
512
  }
513
+ function setMessageId( $messageId ) {
514
  $this->messageId = $messageId;
515
  }
516
+ function setDate( $date ) {
517
  $this->date = $date;
518
  }
519
+
520
  // return the headers
521
  public function getHeaders() {
522
  return $this->headers;
Postman/Postman-Mail/PostmanSendGridMailEngine.php CHANGED
@@ -1,196 +1,194 @@
1
  <?php
2
- if (! class_exists ( "PostmanSendGridMailEngine" )) {
3
-
4
  require_once 'sendgrid-php-3.2.0/sendgrid-php.php';
5
-
6
  /**
7
  * Sends mail with the SendGrid API
8
  * https://sendgrid.com/docs/API_Reference/Web_API/mail.html
9
  *
10
  * @author jasonhendriks
11
- *
12
  */
13
  class PostmanSendGridMailEngine implements PostmanMailEngine {
14
-
15
  // logger for all concrete classes - populate with setLogger($logger)
16
  protected $logger;
17
-
18
  // the result
19
  private $transcript;
20
-
21
- //
22
  private $email;
23
  private $apiKey;
24
-
25
  /**
26
  *
27
- * @param unknown $senderEmail
28
- * @param unknown $accessToken
29
  */
30
- function __construct($apiKey) {
31
- assert ( ! empty ( $apiKey ) );
32
  $this->apiKey = $apiKey;
33
-
34
  // create the logger
35
- $this->logger = new PostmanLogger ( get_class ( $this ) );
36
-
37
  // create the Message
38
- $this->email = new SendGrid\Email ();
39
  }
40
-
41
  /**
42
  * (non-PHPdoc)
43
  *
44
  * @see PostmanSmtpEngine::send()
45
  */
46
- public function send(PostmanMessage $message) {
47
- $options = PostmanOptions::getInstance ();
48
-
49
  // add the Postman signature - append it to whatever the user may have set
50
- if (! $options->isStealthModeEnabled ()) {
51
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
52
- $this->email->addHeader ( 'X-Mailer', sprintf ( 'Postman SMTP %s for WordPress (%s)', $pluginData ['version'], 'https://wordpress.org/plugins/postman-smtp/' ) );
53
  }
54
-
55
  // add the headers - see http://framework.zend.com/manual/1.12/en/zend.mail.additional-headers.html
56
- foreach ( ( array ) $message->getHeaders () as $header ) {
57
- $this->logger->debug ( sprintf ( 'Adding user header %s=%s', $header ['name'], $header ['content'] ) );
58
- $this->email->addHeader ( $header ['name'], $header ['content'] );
59
  }
60
-
61
  // if the caller set a Content-Type header, use it
62
- $contentType = $message->getContentType ();
63
- if (! empty ( $contentType )) {
64
- $this->logger->debug ( 'Adding content-type ' . $contentType );
65
- $this->email->addHeader ( 'Content-Type', $contentType );
66
  }
67
-
68
  // add the From Header
69
- $sender = $message->getFromAddress ();
70
  {
71
- $senderEmail = $sender->getEmail ();
72
- $senderName = $sender->getName ();
73
- assert ( ! empty ( $senderEmail ) );
74
- $this->email->setFrom ( $senderEmail );
75
- if (! empty ( $senderName )) {
76
- $this->email->setFromName ( $senderName );
77
- }
78
  // now log it
79
- $sender->log ( $this->logger, 'From' );
80
  }
81
-
82
  // add the Sender Header, overriding what the user may have set
83
- $this->email->addHeader ( 'Sender', $options->getEnvelopeSender () );
84
-
85
  // add the to recipients
86
- foreach ( ( array ) $message->getToRecipients () as $recipient ) {
87
- $recipient->log ( $this->logger, 'To' );
88
- $this->email->addTo ( $recipient->getEmail (), $recipient->getName () );
89
  }
90
-
91
  // add the cc recipients
92
- foreach ( ( array ) $message->getCcRecipients () as $recipient ) {
93
- $recipient->log ( $this->logger, 'Cc' );
94
- $this->email->addCc ( $recipient->getEmail (), $recipient->getName () );
95
  }
96
-
97
  // add the bcc recipients
98
- foreach ( ( array ) $message->getBccRecipients () as $recipient ) {
99
- $recipient->log ( $this->logger, 'Bcc' );
100
- $this->email->addBcc ( $recipient->getEmail (), $recipient->getName () );
101
  }
102
-
103
  // add the reply-to
104
- $replyTo = $message->getReplyTo ();
105
  // $replyTo is null or a PostmanEmailAddress object
106
- if (isset ( $replyTo )) {
107
- $this->email->setReplyTo ( $replyTo->format () );
108
  }
109
-
110
  // add the date
111
- $date = $message->getDate ();
112
- if (! empty ( $date )) {
113
- $this->email->setDate ( $message->getDate () );
114
  }
115
-
116
  // add the messageId
117
- $messageId = $message->getMessageId ();
118
- if (! empty ( $messageId )) {
119
- $this->email->addHeader ( 'message-id', $messageId );
120
  }
121
-
122
  // add the subject
123
- if (null !== $message->getSubject ()) {
124
- $this->email->setSubject ( $message->getSubject () );
125
  }
126
-
127
  // add the message content
128
  {
129
- $textPart = $message->getBodyTextPart ();
130
- if (! empty ( $textPart )) {
131
- $this->logger->debug ( 'Adding body as text' );
132
- $this->email->setText ( $textPart );
133
- }
134
- $htmlPart = $message->getBodyHtmlPart ();
135
- if (! empty ( $htmlPart )) {
136
- $this->logger->debug ( 'Adding body as html' );
137
- $this->email->setHtml ( $htmlPart );
138
- }
139
  }
140
-
 
 
 
 
 
 
141
  // add attachments
142
- $this->logger->debug ( "Adding attachments" );
143
- $this->addAttachmentsToMail ( $message );
144
-
145
- $result = array ();
146
  try {
147
-
148
- if ($this->logger->isDebug ()) {
149
- $this->logger->debug ( "Creating SendGrid service with apiKey=" . $this->apiKey );
150
  }
151
- $sendgrid = new SendGrid ( $this->apiKey );
152
-
153
  // send the message
154
- if ($this->logger->isDebug ()) {
155
- $this->logger->debug ( "Sending mail" );
156
  }
157
- $result = $sendgrid->send ( $this->email );
158
- if ($this->logger->isInfo ()) {
159
- $this->logger->info ( );
160
  }
161
- $this->transcript = print_r ( $result, true );
162
  $this->transcript .= PostmanModuleTransport::RAW_MESSAGE_FOLLOWS;
163
- $this->transcript .= print_r ( $this->email, true );
164
  } catch ( SendGrid\Exception $e ) {
165
- $this->transcript = $e->getMessage ();
166
  $this->transcript .= PostmanModuleTransport::RAW_MESSAGE_FOLLOWS;
167
- $this->transcript .= print_r ( $this->email, true );
168
  throw $e;
169
  }
170
  }
171
-
172
  /**
173
  * Add attachments to the message
174
  *
175
- * @param Postman_Zend_Mail $mail
176
  */
177
- private function addAttachmentsToMail(PostmanMessage $message) {
178
- $attachments = $message->getAttachments ();
179
- if (! is_array ( $attachments )) {
180
  // WordPress may a single filename or a newline-delimited string list of multiple filenames
181
- $attArray = explode ( PHP_EOL, $attachments );
182
  } else {
183
  $attArray = $attachments;
184
  }
185
  // otherwise WordPress sends an array
186
  foreach ( $attArray as $file ) {
187
- if (! empty ( $file )) {
188
- $this->logger->debug ( "Adding attachment: " . $file );
189
- $this->email->addAttachment ( basename ( $file ) );
190
  }
191
  }
192
  }
193
-
194
  // return the SMTP session transcript
195
  public function getTranscript() {
196
  return $this->transcript;
1
  <?php
2
+ if ( ! class_exists( 'PostmanSendGridMailEngine' ) ) {
3
+
4
  require_once 'sendgrid-php-3.2.0/sendgrid-php.php';
5
+
6
  /**
7
  * Sends mail with the SendGrid API
8
  * https://sendgrid.com/docs/API_Reference/Web_API/mail.html
9
  *
10
  * @author jasonhendriks
 
11
  */
12
  class PostmanSendGridMailEngine implements PostmanMailEngine {
13
+
14
  // logger for all concrete classes - populate with setLogger($logger)
15
  protected $logger;
16
+
17
  // the result
18
  private $transcript;
19
+
 
20
  private $email;
21
  private $apiKey;
22
+
23
  /**
24
  *
25
+ * @param unknown $senderEmail
26
+ * @param unknown $accessToken
27
  */
28
+ function __construct( $apiKey ) {
29
+ assert( ! empty( $apiKey ) );
30
  $this->apiKey = $apiKey;
31
+
32
  // create the logger
33
+ $this->logger = new PostmanLogger( get_class( $this ) );
34
+
35
  // create the Message
36
+ $this->email = new SendGrid\Email();
37
  }
38
+
39
  /**
40
  * (non-PHPdoc)
41
  *
42
  * @see PostmanSmtpEngine::send()
43
  */
44
+ public function send( PostmanMessage $message ) {
45
+ $options = PostmanOptions::getInstance();
46
+
47
  // add the Postman signature - append it to whatever the user may have set
48
+ if ( ! $options->isStealthModeEnabled() ) {
49
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
50
+ $this->email->addHeader( 'X-Mailer', sprintf( 'Postman SMTP %s for WordPress (%s)', $pluginData ['version'], 'https://wordpress.org/plugins/post-smtp/' ) );
51
  }
52
+
53
  // add the headers - see http://framework.zend.com/manual/1.12/en/zend.mail.additional-headers.html
54
+ foreach ( ( array ) $message->getHeaders() as $header ) {
55
+ $this->logger->debug( sprintf( 'Adding user header %s=%s', $header ['name'], $header ['content'] ) );
56
+ $this->email->addHeader( $header ['name'], $header ['content'] );
57
  }
58
+
59
  // if the caller set a Content-Type header, use it
60
+ $contentType = $message->getContentType();
61
+ if ( ! empty( $contentType ) ) {
62
+ $this->logger->debug( 'Adding content-type ' . $contentType );
63
+ $this->email->addHeader( 'Content-Type', $contentType );
64
  }
65
+
66
  // add the From Header
67
+ $sender = $message->getFromAddress();
68
  {
69
+ $senderEmail = $sender->getEmail();
70
+ $senderName = $sender->getName();
71
+ assert( ! empty( $senderEmail ) );
72
+ $this->email->setFrom( $senderEmail );
73
+ if ( ! empty( $senderName ) ) {
74
+ $this->email->setFromName( $senderName );
75
+ }
76
  // now log it
77
+ $sender->log( $this->logger, 'From' );
78
  }
79
+
80
  // add the Sender Header, overriding what the user may have set
81
+ $this->email->addHeader( 'Sender', $options->getEnvelopeSender() );
82
+
83
  // add the to recipients
84
+ foreach ( ( array ) $message->getToRecipients() as $recipient ) {
85
+ $recipient->log( $this->logger, 'To' );
86
+ $this->email->addTo( $recipient->getEmail(), $recipient->getName() );
87
  }
88
+
89
  // add the cc recipients
90
+ foreach ( ( array ) $message->getCcRecipients() as $recipient ) {
91
+ $recipient->log( $this->logger, 'Cc' );
92
+ $this->email->addCc( $recipient->getEmail(), $recipient->getName() );
93
  }
94
+
95
  // add the bcc recipients
96
+ foreach ( ( array ) $message->getBccRecipients() as $recipient ) {
97
+ $recipient->log( $this->logger, 'Bcc' );
98
+ $this->email->addBcc( $recipient->getEmail(), $recipient->getName() );
99
  }
100
+
101
  // add the reply-to
102
+ $replyTo = $message->getReplyTo();
103
  // $replyTo is null or a PostmanEmailAddress object
104
+ if ( isset( $replyTo ) ) {
105
+ $this->email->setReplyTo( $replyTo->format() );
106
  }
107
+
108
  // add the date
109
+ $date = $message->getDate();
110
+ if ( ! empty( $date ) ) {
111
+ $this->email->setDate( $message->getDate() );
112
  }
113
+
114
  // add the messageId
115
+ $messageId = $message->getMessageId();
116
+ if ( ! empty( $messageId ) ) {
117
+ $this->email->addHeader( 'message-id', $messageId );
118
  }
119
+
120
  // add the subject
121
+ if ( null !== $message->getSubject() ) {
122
+ $this->email->setSubject( $message->getSubject() );
123
  }
124
+
125
  // add the message content
126
  {
127
+ $textPart = $message->getBodyTextPart();
128
+ if ( ! empty( $textPart ) ) {
129
+ $this->logger->debug( 'Adding body as text' );
130
+ $this->email->setText( $textPart );
 
 
 
 
 
 
131
  }
132
+ $htmlPart = $message->getBodyHtmlPart();
133
+ if ( ! empty( $htmlPart ) ) {
134
+ $this->logger->debug( 'Adding body as html' );
135
+ $this->email->setHtml( $htmlPart );
136
+ }
137
+ }
138
+
139
  // add attachments
140
+ $this->logger->debug( 'Adding attachments' );
141
+ $this->addAttachmentsToMail( $message );
142
+
143
+ $result = array();
144
  try {
145
+
146
+ if ( $this->logger->isDebug() ) {
147
+ $this->logger->debug( 'Creating SendGrid service with apiKey=' . $this->apiKey );
148
  }
149
+ $sendgrid = new SendGrid( $this->apiKey );
150
+
151
  // send the message
152
+ if ( $this->logger->isDebug() ) {
153
+ $this->logger->debug( 'Sending mail' );
154
  }
155
+ $result = $sendgrid->send( $this->email );
156
+ if ( $this->logger->isInfo() ) {
157
+ $this->logger->info( );
158
  }
159
+ $this->transcript = print_r( $result, true );
160
  $this->transcript .= PostmanModuleTransport::RAW_MESSAGE_FOLLOWS;
161
+ $this->transcript .= print_r( $this->email, true );
162
  } catch ( SendGrid\Exception $e ) {
163
+ $this->transcript = $e->getMessage();
164
  $this->transcript .= PostmanModuleTransport::RAW_MESSAGE_FOLLOWS;
165
+ $this->transcript .= print_r( $this->email, true );
166
  throw $e;
167
  }
168
  }
169
+
170
  /**
171
  * Add attachments to the message
172
  *
173
+ * @param Postman_Zend_Mail $mail
174
  */
175
+ private function addAttachmentsToMail( PostmanMessage $message ) {
176
+ $attachments = $message->getAttachments();
177
+ if ( ! is_array( $attachments ) ) {
178
  // WordPress may a single filename or a newline-delimited string list of multiple filenames
179
+ $attArray = explode( PHP_EOL, $attachments );
180
  } else {
181
  $attArray = $attachments;
182
  }
183
  // otherwise WordPress sends an array
184
  foreach ( $attArray as $file ) {
185
+ if ( ! empty( $file ) ) {
186
+ $this->logger->debug( 'Adding attachment: ' . $file );
187
+ $this->email->addAttachment( $file );
188
  }
189
  }
190
  }
191
+
192
  // return the SMTP session transcript
193
  public function getTranscript() {
194
  return $this->transcript;
Postman/Postman-Mail/PostmanSmtpModuleTransport.php CHANGED
@@ -4,20 +4,19 @@ require_once 'PostmanModuleTransport.php';
4
  /**
5
  *
6
  * @author jasonhendriks
7
- *
8
  */
9
  class PostmanSmtpModuleTransport extends PostmanAbstractZendModuleTransport implements PostmanZendModuleTransport {
10
  const SLUG = 'smtp';
11
- public function __construct($rootPluginFilenameAndPath) {
12
- parent::__construct ( $rootPluginFilenameAndPath );
13
-
14
  // add a hook on the plugins_loaded event
15
- add_action ( 'admin_init', array (
16
  $this,
17
- 'on_admin_init'
18
  ) );
19
  }
20
-
21
  /**
22
  * (non-PHPdoc)
23
  *
@@ -25,30 +24,30 @@ class PostmanSmtpModuleTransport extends PostmanAbstractZendModuleTransport impl
25
  */
26
  public function createMailEngine() {
27
  require_once 'PostmanZendMailEngine.php';
28
- return new PostmanZendMailEngine ( $this );
29
  }
30
-
31
  /**
32
  * (non-PHPdoc)
33
  *
34
  * @see PostmanZendModuleTransport::createZendMailTransport()
35
  */
36
- public function createZendMailTransport($fakeHostname, $fakeConfig) {
37
- if (PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType ()) {
38
- $config = PostmanOAuth2ConfigurationFactory::createConfig ( $this );
39
  } else {
40
- $config = PostmanBasicAuthConfigurationFactory::createConfig ( $this );
41
  }
42
- return new Postman_Zend_Mail_Transport_Smtp ( $this->getHostname (), $config );
43
  }
44
-
45
  /**
46
  * Determines whether Mail Engine locking is needed
47
  *
48
  * @see PostmanModuleTransport::requiresLocking()
49
  */
50
  public function isLockingRequired() {
51
- return PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType ();
52
  }
53
  public function getSlug() {
54
  return self::SLUG;
@@ -58,193 +57,193 @@ class PostmanSmtpModuleTransport extends PostmanAbstractZendModuleTransport impl
58
  }
59
  public function getHostname() {
60
  $this->options = $this->options;
61
- return $this->options->getHostname ();
62
  }
63
  public function getPort() {
64
  $this->options = $this->options;
65
- return $this->options->getPort ();
66
  }
67
  public function getAuthenticationType() {
68
- return $this->options->getAuthenticationType ();
69
  }
70
  public function getCredentialsId() {
71
  $this->options = $this->options;
72
- if ($this->options->isAuthTypeOAuth2 ()) {
73
- return $this->options->getClientId ();
74
  } else {
75
- return $this->options->getUsername ();
76
  }
77
  }
78
  public function getCredentialsSecret() {
79
  $this->options = $this->options;
80
- if ($this->options->isAuthTypeOAuth2 ()) {
81
- return $this->options->getClientSecret ();
82
  } else {
83
- return $this->options->getPassword ();
84
  }
85
  }
86
-
87
  /**
88
  * (non-PHPdoc)
89
  *
90
  * @see PostmanTransport::getMisconfigurationMessage()
91
  */
92
  protected function validateTransportConfiguration() {
93
- $messages = parent::validateTransportConfiguration ();
94
- if (! $this->isHostConfigured ( $this->options )) {
95
- array_push ( $messages, __ ( 'Outgoing Mail Server Hostname and Port can not be empty.', Postman::TEXT_DOMAIN ) );
96
- $this->setNotConfiguredAndReady ();
97
  }
98
- if (! $this->isEnvelopeFromConfigured ()) {
99
- array_push ( $messages, __ ( 'Envelope-From Email Address can not be empty', Postman::TEXT_DOMAIN ) . '.' );
100
- $this->setNotConfiguredAndReady ();
101
  }
102
- if ($this->options->isAuthTypePassword () && ! $this->isPasswordAuthenticationConfigured ( $this->options )) {
103
- array_push ( $messages, __ ( 'Username and password can not be empty.', Postman::TEXT_DOMAIN ) );
104
- $this->setNotConfiguredAndReady ();
105
  }
106
- if ($this->getAuthenticationType () == PostmanOptions::AUTHENTICATION_TYPE_OAUTH2) {
107
- if (! $this->isOAuth2SupportedHostConfigured ()) {
108
  /* translators: %1$s is the Client ID label, and %2$s is the Client Secret label (e.g. Warning: OAuth 2.0 authentication requires an OAuth 2.0-capable Outgoing Mail Server, Sender Email Address, Client ID, and Client Secret.) */
109
- array_push ( $messages, sprintf ( __ ( 'OAuth 2.0 authentication requires a supported OAuth 2.0-capable Outgoing Mail Server.', Postman::TEXT_DOMAIN ) ) );
110
- $this->setNotConfiguredAndReady ();
111
  }
112
  }
113
- if (empty ( $messages )) {
114
- $this->setReadyForOAuthGrant ();
115
- if ($this->isPermissionNeeded ( $this->options, $this->getOAuthToken () )) {
116
  /* translators: %1$s is the Client ID label, and %2$s is the Client Secret label */
117
- $message = sprintf ( __ ( 'You have configured OAuth 2.0 authentication, but have not received permission to use it.', Postman::TEXT_DOMAIN ), $this->getScribe ()->getClientIdLabel (), $this->getScribe ()->getClientSecretLabel () );
118
- $message .= sprintf ( ' <a href="%s">%s</a>.', PostmanUtils::getGrantOAuthPermissionUrl (), $this->getScribe ()->getRequestPermissionLinkText () );
119
- array_push ( $messages, $message );
120
- $this->setNotConfiguredAndReady ();
121
  }
122
  }
123
  return $messages;
124
  }
125
-
126
  /**
127
  *
128
  * @return boolean
129
  */
130
  private function isOAuth2SupportedHostConfigured() {
131
- $options = PostmanOptions::getInstance ();
132
- $hostname = $options->getHostname ();
133
- $supportedOAuthProvider = $this->isServiceProviderGoogle ( $hostname ) || $this->isServiceProviderMicrosoft ( $hostname ) || $this->isServiceProviderYahoo ( $hostname );
134
  return $supportedOAuthProvider;
135
  }
136
-
137
  /**
138
  * Given a hostname, what ports should we test?
139
  *
140
  * May return an array of several combinations.
141
  */
142
- public function getSocketsForSetupWizardToProbe($hostname, $smtpServerGuess) {
143
- $hosts = array (
144
- $this->createSocketDefinition ( $hostname, 25 ),
145
- $this->createSocketDefinition ( $hostname, 465 ),
146
- $this->createSocketDefinition ( $hostname, 587 )
147
  );
148
-
149
  return $hosts;
150
  }
151
-
152
  /**
153
  * Creates a single socket for the Wizard to test
154
  */
155
- protected function createSocketDefinition($hostname, $port) {
156
- $socket = parent::createSocketDefinition ( $hostname, $port );
157
  $socket ['smtp'] = true;
158
  return $socket;
159
  }
160
-
161
  /**
162
  * SendGrid will never recommend it's configuration
163
  *
164
- * @param unknown $hostData
165
  */
166
- public function getConfigurationBid(PostmanWizardSocket $hostData, $userAuthOverride, $originalSmtpServer) {
167
  $port = $hostData->port;
168
  $hostname = $hostData->hostname;
169
  // because some servers, like smtp.broadband.rogers.com, report XOAUTH2 but have no OAuth2 front-end
170
- $supportedOAuth2Provider = $this->isServiceProviderGoogle ( $hostname ) || $this->isServiceProviderMicrosoft ( $hostname ) || $this->isServiceProviderYahoo ( $hostname );
171
  $score = 1;
172
- $recommendation = array ();
173
  // increment score for auth type
174
- if ($hostData->mitm) {
175
- $this->logger->debug ( 'Losing points for MITM' );
176
  $score -= 10000;
177
  $recommendation ['mitm'] = true;
178
  }
179
- if (! empty ( $originalSmtpServer ) && $hostname != $originalSmtpServer) {
180
- $this->logger->debug ( 'Losing points for Not The Original SMTP server' );
181
  $score -= 10000;
182
  }
183
  $secure = true;
184
- if ($hostData->startTls) {
185
  // STARTTLS was formalized in 2002
186
  // http://www.rfc-editor.org/rfc/rfc3207.txt
187
  $recommendation ['enc'] = PostmanOptions::SECURITY_TYPE_STARTTLS;
188
  $score += 30000;
189
- } elseif ($hostData->protocol == 'SMTPS') {
190
  // "The hopelessly confusing and imprecise term, SSL,
191
  // has often been used to indicate the SMTPS wrapper and
192
  // TLS to indicate the STARTTLS protocol extension."
193
  // http://stackoverflow.com/a/19942206/4368109
194
  $recommendation ['enc'] = PostmanOptions::SECURITY_TYPE_SMTPS;
195
  $score += 28000;
196
- } elseif ($hostData->protocol == 'SMTP') {
197
  $recommendation ['enc'] = PostmanOptions::SECURITY_TYPE_NONE;
198
  $score += 26000;
199
  $secure = false;
200
  }
201
-
202
  // if there is a way to send mail....
203
- if ($score > 10) {
204
-
205
  // determine the authentication type
206
- if ($hostData->auth_xoauth && $supportedOAuth2Provider && (empty ( $userAuthOverride ) || $userAuthOverride == 'oauth2')) {
207
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_OAUTH2;
208
  $recommendation ['display_auth'] = 'oauth2';
209
  $score += 500;
210
- if (! $secure) {
211
- $this->logger->debug ( 'Losing points for sending credentials in the clear' );
212
  $score -= 10000;
213
  }
214
- } elseif ($hostData->auth_crammd5 && (empty ( $userAuthOverride ) || $userAuthOverride == 'password')) {
215
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5;
216
  $recommendation ['display_auth'] = 'password';
217
  $score += 400;
218
- if (! $secure) {
219
- $this->logger->debug ( 'Losing points for sending credentials in the clear' );
220
  $score -= 10000;
221
  }
222
- } elseif ($hostData->authPlain && (empty ( $userAuthOverride ) || $userAuthOverride == 'password')) {
223
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_PLAIN;
224
  $recommendation ['display_auth'] = 'password';
225
  $score += 300;
226
- if (! $secure) {
227
- $this->logger->debug ( 'Losing points for sending credentials in the clear' );
228
  $score -= 10000;
229
  }
230
- } elseif ($hostData->auth_login && (empty ( $userAuthOverride ) || $userAuthOverride == 'password')) {
231
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_LOGIN;
232
  $recommendation ['display_auth'] = 'password';
233
  $score += 200;
234
- if (! $secure) {
235
- $this->logger->debug ( 'Losing points for sending credentials in the clear' );
236
  $score -= 10000;
237
  }
238
- } else if (empty ( $userAuthOverride ) || $userAuthOverride == 'none') {
239
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_NONE;
240
  $recommendation ['display_auth'] = 'none';
241
  $score += 100;
242
  }
243
-
244
  // tiny weighting to prejudice the port selection, all things being equal
245
- if ($port == 587) {
246
  $score += 4;
247
- } elseif ($port == 25) {
248
  // "due to the prevalence of machines that have worms,
249
  // viruses, or other malicious software that generate large amounts of
250
  // spam, many sites now prohibit outbound traffic on the standard SMTP
@@ -252,33 +251,33 @@ class PostmanSmtpModuleTransport extends PostmanAbstractZendModuleTransport impl
252
  // servers."
253
  // http://www.rfc-editor.org/rfc/rfc6409.txt
254
  $score += 3;
255
- } elseif ($port == 465) {
256
  // use of port 465 for SMTP was deprecated in 1998
257
  // http://www.imc.org/ietf-apps-tls/mail-archive/msg00204.html
258
  $score += 2;
259
  } else {
260
  $score += 1;
261
  }
262
-
263
  // create the recommendation message for the user
264
  // this can only be set if there is a valid ['auth'] and ['enc']
265
- $transportDescription = $this->getTransportDescription ( $recommendation ['enc'] );
266
- $authDesc = $this->getAuthenticationDescription ( $recommendation ['auth'] );
267
- $recommendation ['label'] = sprintf ( 'SMTP - %2$s:%3$d', $transportDescription, $hostData->hostnameDomainOnly, $port );
268
  /* translators: where %1$s is a description of the transport (eg. SMTPS-SSL), %2$s is a description of the authentication (eg. Password-CRAMMD5), %3$d is the TCP port (eg. 465), %4$d is the hostname */
269
- $recommendation ['message'] = sprintf ( __ ( 'Postman recommends %1$s with %2$s authentication to host %4$s on port %3$d.', Postman::TEXT_DOMAIN ), $transportDescription, $authDesc, $port, $hostname );
270
  }
271
-
272
  // fill-in the rest of the recommendation
273
  $recommendation ['transport'] = PostmanSmtpModuleTransport::SLUG;
274
  $recommendation ['priority'] = $score;
275
  $recommendation ['port'] = $port;
276
  $recommendation ['hostname'] = $hostname;
277
  $recommendation ['transport'] = self::SLUG;
278
-
279
  return $recommendation;
280
  }
281
-
282
  /**
283
  * Functions to execute on the admin_init event
284
  *
@@ -287,303 +286,303 @@ class PostmanSmtpModuleTransport extends PostmanAbstractZendModuleTransport impl
287
  */
288
  public function on_admin_init() {
289
  // only administrators should be able to trigger this
290
- if (PostmanUtils::isAdmin ()) {
291
- $this->addSettings ();
292
- $this->registerStylesAndScripts ();
293
  }
294
  }
295
-
296
  /**
297
  */
298
  public function registerStylesAndScripts() {
299
  // register the stylesheet and javascript external resources
300
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
301
- wp_register_script ( 'postman_smtp_script', plugins_url ( 'Postman/Postman-Mail/postman_smtp.js', $this->rootPluginFilenameAndPath ), array (
302
  PostmanViewController::JQUERY_SCRIPT,
303
  'jquery_validation',
304
- PostmanViewController::POSTMAN_SCRIPT
305
  ), $pluginData ['version'] );
306
  }
307
-
308
  /*
309
  * What follows in the code responsible for creating the Admin Settings page
310
  */
311
-
312
  /**
313
  */
314
  public function enqueueScript() {
315
- wp_enqueue_script ( 'postman_smtp_script' );
316
  }
317
-
318
  /**
319
  */
320
  public function addSettings() {
321
  $transport = $this;
322
  $this->options = $this->options;
323
- $oauthScribe = $transport->getScribe ();
324
-
325
  // Sanitize
326
- add_settings_section ( PostmanAdminController::SMTP_SECTION, __ ( 'Transport Settings', Postman::TEXT_DOMAIN ), array (
327
  $this,
328
- 'printSmtpSectionInfo'
329
  ), PostmanAdminController::SMTP_OPTIONS );
330
-
331
- add_settings_field ( PostmanOptions::HOSTNAME, __ ( 'Outgoing Mail Server Hostname', Postman::TEXT_DOMAIN ), array (
332
  $this,
333
- 'hostname_callback'
334
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
335
-
336
- add_settings_field ( PostmanOptions::PORT, __ ( 'Outgoing Mail Server Port', Postman::TEXT_DOMAIN ), array (
337
  $this,
338
- 'port_callback'
339
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
340
-
341
- add_settings_field ( PostmanOptions::ENVELOPE_SENDER, __ ( 'Envelope-From Email Address', Postman::TEXT_DOMAIN ), array (
342
  $this,
343
- 'sender_email_callback'
344
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
345
-
346
- add_settings_field ( PostmanOptions::SECURITY_TYPE, _x ( 'Security', 'Configuration Input Field', Postman::TEXT_DOMAIN ), array (
347
  $this,
348
- 'encryption_type_callback'
349
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
350
-
351
- add_settings_field ( PostmanOptions::AUTHENTICATION_TYPE, __ ( 'Authentication', Postman::TEXT_DOMAIN ), array (
352
  $this,
353
- 'authentication_type_callback'
354
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
355
-
356
- add_settings_section ( PostmanAdminController::BASIC_AUTH_SECTION, __ ( 'Authentication', Postman::TEXT_DOMAIN ), array (
357
  $this,
358
- 'printBasicAuthSectionInfo'
359
  ), PostmanAdminController::BASIC_AUTH_OPTIONS );
360
-
361
- add_settings_field ( PostmanOptions::BASIC_AUTH_USERNAME, __ ( 'Username', Postman::TEXT_DOMAIN ), array (
362
  $this,
363
- 'basic_auth_username_callback'
364
  ), PostmanAdminController::BASIC_AUTH_OPTIONS, PostmanAdminController::BASIC_AUTH_SECTION );
365
-
366
- add_settings_field ( PostmanOptions::BASIC_AUTH_PASSWORD, __ ( 'Password', Postman::TEXT_DOMAIN ), array (
367
  $this,
368
- 'basic_auth_password_callback'
369
  ), PostmanAdminController::BASIC_AUTH_OPTIONS, PostmanAdminController::BASIC_AUTH_SECTION );
370
-
371
  // the OAuth section
372
- add_settings_section ( PostmanAdminController::OAUTH_SECTION, __ ( 'Authentication', Postman::TEXT_DOMAIN ), array (
373
  $this,
374
- 'printOAuthSectionInfo'
375
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS );
376
-
377
- add_settings_field ( 'callback_domain', sprintf ( '<span id="callback_domain">%s</span>', $oauthScribe->getCallbackDomainLabel () ), array (
378
  $this,
379
- 'callback_domain_callback'
380
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS, PostmanAdminController::OAUTH_SECTION );
381
-
382
- add_settings_field ( 'redirect_url', sprintf ( '<span id="redirect_url">%s</span>', $oauthScribe->getCallbackUrlLabel () ), array (
383
  $this,
384
- 'redirect_url_callback'
385
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS, PostmanAdminController::OAUTH_SECTION );
386
-
387
- add_settings_field ( PostmanOptions::CLIENT_ID, $oauthScribe->getClientIdLabel (), array (
388
  $this,
389
- 'oauth_client_id_callback'
390
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS, PostmanAdminController::OAUTH_SECTION );
391
-
392
- add_settings_field ( PostmanOptions::CLIENT_SECRET, $oauthScribe->getClientSecretLabel (), array (
393
  $this,
394
- 'oauth_client_secret_callback'
395
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS, PostmanAdminController::OAUTH_SECTION );
396
  }
397
-
398
  /**
399
  * Print the Section text
400
  */
401
  public function printSmtpSectionInfo() {
402
- print __ ( 'Configure the communication with the mail server.', Postman::TEXT_DOMAIN );
403
  }
404
-
405
  /**
406
  * Get the settings option array and print one of its values
407
  */
408
  public function hostname_callback() {
409
- printf ( '<input type="text" id="input_hostname" name="postman_options[hostname]" value="%s" size="40" class="required" placeholder="%s"/>', null !== $this->options->getHostname () ? esc_attr ( $this->options->getHostname () ) : '', __ ( 'Required', Postman::TEXT_DOMAIN ) );
410
  }
411
-
412
  /**
413
  * Get the settings option array and print one of its values
414
  */
415
- public function port_callback($args) {
416
- printf ( '<input type="text" id="input_port" name="postman_options[port]" value="%s" %s placeholder="%s"/>', null !== $this->options->getPort () ? esc_attr ( $this->options->getPort () ) : '', isset ( $args ['style'] ) ? $args ['style'] : '', __ ( 'Required', Postman::TEXT_DOMAIN ) );
417
  }
418
-
419
  /**
420
  * Get the settings option array and print one of its values
421
  */
422
  public function encryption_type_callback() {
423
- $encType = $this->options->getEncryptionType ();
424
  print '<select id="input_enc_type" class="input_encryption_type" name="postman_options[enc_type]">';
425
- printf ( '<option class="input_enc_type_none" value="%s" %s>%s</option>', PostmanOptions::SECURITY_TYPE_NONE, $encType == PostmanOptions::SECURITY_TYPE_NONE ? 'selected="selected"' : '', __ ( 'None', Postman::TEXT_DOMAIN ) );
426
- printf ( '<option class="input_enc_type_ssl" value="%s" %s>%s</option>', PostmanOptions::SECURITY_TYPE_SMTPS, $encType == PostmanOptions::SECURITY_TYPE_SMTPS ? 'selected="selected"' : '', 'SMTPS' );
427
- printf ( '<option class="input_enc_type_tls" value="%s" %s>%s</option>', PostmanOptions::SECURITY_TYPE_STARTTLS, $encType == PostmanOptions::SECURITY_TYPE_STARTTLS ? 'selected="selected"' : '', 'STARTTLS' );
428
  print '</select>';
429
  }
430
-
431
  /**
432
  * Get the settings option array and print one of its values
433
  */
434
  public function authentication_type_callback() {
435
- $authType = $this->options->getAuthenticationType ();
436
- printf ( '<select id="input_%2$s" class="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::AUTHENTICATION_TYPE );
437
- printf ( '<option class="input_auth_type_none" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_NONE, $authType == PostmanOptions::AUTHENTICATION_TYPE_NONE ? 'selected="selected"' : '', 'None' );
438
- printf ( '<option class="input_auth_type_plain" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_PLAIN, $authType == PostmanOptions::AUTHENTICATION_TYPE_PLAIN ? 'selected="selected"' : '', 'Plain' );
439
- printf ( '<option class="input_auth_type_login" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_LOGIN, $authType == PostmanOptions::AUTHENTICATION_TYPE_LOGIN ? 'selected="selected"' : '', 'Login' );
440
- printf ( '<option class="input_auth_type_crammd5" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5, $authType == PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5 ? 'selected="selected"' : '', 'CRAM-MD5' );
441
- printf ( '<option class="input_auth_type_oauth2" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_OAUTH2, $authType == PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 ? 'selected="selected"' : '', 'OAuth 2.0' );
442
  print '</select>';
443
  }
444
-
445
  /**
446
  * Print the Section text
447
  */
448
  public function printBasicAuthSectionInfo() {
449
- print __ ( 'Enter the account credentials.', Postman::TEXT_DOMAIN );
450
  }
451
-
452
  /**
453
  * Get the settings option array and print one of its values
454
  */
455
  public function basic_auth_username_callback() {
456
- $inputValue = (null !== $this->options->getUsername () ? esc_attr ( $this->options->getUsername () ) : '');
457
- $inputDescription = __ ( 'The Username is usually the same as the Envelope-From Email Address.', Postman::TEXT_DOMAIN );
458
  print ('<input tabindex="99" id="fake_user_name" name="fake_user[name]" style="position:absolute; top:-500px;" type="text" value="Safari Autofill Me">') ;
459
- printf ( '<input type="text" id="input_basic_auth_username" name="postman_options[basic_auth_username]" value="%s" size="40" class="required" placeholder="%s"/><br/><span class="postman_input_description">%s</span>', $inputValue, __ ( 'Required', Postman::TEXT_DOMAIN ), $inputDescription );
460
  }
461
-
462
  /**
463
  * Get the settings option array and print one of its values
464
  */
465
  public function basic_auth_password_callback() {
466
  print ('<input tabindex="99" id="fake_password" name="fake[password]" style="position:absolute; top:-500px;" type="password" value="Safari Autofill Me">') ;
467
- printf ( '<input type="password" id="input_basic_auth_password" name="postman_options[basic_auth_password]" value="%s" size="40" class="required" placeholder="%s"/>', null !== $this->options->getPassword () ? esc_attr ( PostmanUtils::obfuscatePassword ( $this->options->getPassword () ) ) : '', __ ( 'Required', Postman::TEXT_DOMAIN ) );
468
  print ' <input type="button" id="togglePasswordField" value="Show Password" class="button button-secondary" style="visibility:hidden" />';
469
  }
470
-
471
  /**
472
  * Get the settings option array and print one of its values
473
  */
474
  public function oauth_client_id_callback() {
475
- printf ( '<input type="text" onClick="this.setSelectionRange(0, this.value.length)" id="oauth_client_id" name="postman_options[oauth_client_id]" value="%s" size="60" class="required" placeholder="%s"/>', null !== $this->options->getClientId () ? esc_attr ( $this->options->getClientId () ) : '', __ ( 'Required', Postman::TEXT_DOMAIN ) );
476
  }
477
-
478
  /**
479
  * Get the settings option array and print one of its values
480
  */
481
  public function oauth_client_secret_callback() {
482
- printf ( '<input type="text" onClick="this.setSelectionRange(0, this.value.length)" autocomplete="off" id="oauth_client_secret" name="postman_options[oauth_client_secret]" value="%s" size="60" class="required" placeholder="%s"/>', null !== $this->options->getClientSecret () ? esc_attr ( $this->options->getClientSecret () ) : '', __ ( 'Required', Postman::TEXT_DOMAIN ) );
483
  }
484
-
485
  /**
486
  * Print the Section text
487
  */
488
  public function printOAuthSectionInfo() {
489
  $this->options = $this->options;
490
  $transport = $this;
491
- $oauthScribe = $transport->getScribe ();
492
- printf ( '<p id="wizard_oauth2_help">%s</p>', $oauthScribe->getOAuthHelp () );
493
  }
494
-
495
  /**
496
  * Get the settings option array and print one of its values
497
  */
498
  public function callback_domain_callback() {
499
- printf ( '<input type="text" onClick="this.setSelectionRange(0, this.value.length)" readonly="readonly" id="input_oauth_callback_domain" value="%s" size="60"/>', $this->getCallbackDomain () );
500
  }
501
-
502
  /**
503
  */
504
  private function getCallbackDomain() {
505
  try {
506
  $this->options = $this->options;
507
  $transport = $this;
508
- $oauthScribe = $transport->getScribe ();
509
- return $oauthScribe->getCallbackDomain ();
510
  } catch ( Exception $e ) {
511
- return __ ( 'Error computing your domain root - please enter it manually', Postman::TEXT_DOMAIN );
512
  }
513
  }
514
-
515
  /**
516
  * Get the settings option array and print one of its values
517
  */
518
  public function redirect_url_callback() {
519
  $this->options = $this->options;
520
  $transport = $this;
521
- $oauthScribe = $transport->getScribe ();
522
- printf ( '<input type="text" onClick="this.setSelectionRange(0, this.value.length)" readonly="readonly" id="input_oauth_redirect_url" value="%s" size="60"/>', $oauthScribe->getCallbackUrl () );
523
  }
524
-
525
  /**
526
  * Get the settings option array and print one of its values
527
  */
528
  public function sender_email_callback() {
529
- $inputValue = (null !== $this->options->getEnvelopeSender () ? esc_attr ( $this->options->getEnvelopeSender () ) : '');
530
- $requiredLabel = __ ( 'Required', Postman::TEXT_DOMAIN );
531
- $envelopeFromMessage = __ ( 'This address, like the <b>return address</b> printed on an envelope, identifies the account owner to the SMTP server.', Postman::TEXT_DOMAIN );
532
- $spfMessage = sprintf ( __ ( 'For reliable delivery, this domain must specify an <a target="_new" href="%s">SPF record</a> permitting the use of the SMTP server named above.', Postman::TEXT_DOMAIN ), 'https://www.mail-tester.com/spf/' );
533
- printf ( '<input type="email" id="input_envelope_sender_email" name="postman_options[envelope_sender]" value="%s" size="40" class="required" placeholder="%s"/> <br/><span class="postman_input_description">%s %s</span>', $inputValue, $requiredLabel, $envelopeFromMessage, $spfMessage );
534
  }
535
-
536
  /**
537
  */
538
  public function printWizardMailServerHostnameStep() {
539
- printf ( '<legend>%s</legend>', _x ( 'Which host will relay the mail?', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
540
- printf ( '<p>%s</p>', __ ( 'This is the Outgoing (SMTP) Mail Server, or Mail Submission Agent (MSA), which Postman delegates mail delivery to. This server is specific to your email account, and if you don\'t know what to use, ask your email service provider.', Postman::TEXT_DOMAIN ) );
541
- printf ( '<p>%s</p>', __ ( 'Note that many WordPress hosts, such as GoDaddy, Bluehost and Dreamhost, require that you use their mail accounts with their mail servers, and prevent you from using others.', Postman::TEXT_DOMAIN ) );
542
- printf ( '<label for="hostname">%s</label>', __ ( 'Outgoing Mail Server Hostname', Postman::TEXT_DOMAIN ) );
543
- print $this->hostname_callback ();
544
- printf ( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url ( 'postman-smtp/style/ajax-loader.gif' ) );
545
- $warning = __ ( 'Warning', Postman::TEXT_DOMAIN );
546
  /* Translators: Where (%s) is the name of the web host */
547
- $nonGodaddyDomainMessage = sprintf ( __ ( 'Your email address <b>requires</b> access to a remote SMTP server blocked by %s.', Postman::TEXT_DOMAIN ), 'GoDaddy' );
548
- $nonGodaddyDomainMessage .= sprintf ( ' %s', __ ( 'If you have access to cPanel, enable the Remote Mail Exchanger.', Postman::TEXT_DOMAIN ) );
549
- printf ( '<p id="godaddy_block"><span style="background-color:yellow"><b>%s</b>: %s</span></p>', $warning, $nonGodaddyDomainMessage );
550
  /* Translators: Where (%1$s) is the SPF-info URL and (%2$s) is the name of the web host */
551
- $godaddyCustomDomainMessage = sprintf ( __ ( 'If you own this domain, make sure it has an <a href="%1$s">SPF record authorizing %2$s</a> as a relay, or you will have delivery problems.', Postman::TEXT_DOMAIN ), 'http://www.mail-tester.com/spf/godaddy', 'GoDaddy' );
552
- printf ( '<p id="godaddy_spf_required"><span style="background-color:yellow"><b>%s</b>: %s</span></p>', $warning, $godaddyCustomDomainMessage );
553
  }
554
-
555
  /**
556
  */
557
  public function printWizardAuthenticationStep() {
558
  print '<section class="wizard-auth-oauth2">';
559
  print '<p id="wizard_oauth2_help"></p>';
560
- printf ( '<label id="callback_domain" for="callback_domain">%s</label>', $this->getScribe ()->getCallbackDomainLabel () );
561
  print '<br />';
562
- print $this->callback_domain_callback ();
563
  print '<br />';
564
- printf ( '<label id="redirect_url" for="redirect_uri">%s</label>', $this->getScribe ()->getCallbackUrlLabel () );
565
  print '<br />';
566
- print $this->redirect_url_callback ();
567
  print '<br />';
568
- printf ( '<label id="client_id" for="client_id">%s</label>', $this->getScribe ()->getClientIdLabel () );
569
  print '<br />';
570
- print $this->oauth_client_id_callback ();
571
  print '<br />';
572
- printf ( '<label id="client_secret" for="client_secret">%s</label>', $this->getScribe ()->getClientSecretLabel () );
573
  print '<br />';
574
- print $this->oauth_client_secret_callback ();
575
  print '<br />';
576
  print '</section>';
577
-
578
  print '<section class="wizard-auth-basic">';
579
- printf ( '<p class="port-explanation-ssl">%s</p>', __ ( 'Enter the account credentials.', Postman::TEXT_DOMAIN ) );
580
- printf ( '<label for="username">%s</label>', __ ( 'Username', Postman::TEXT_DOMAIN ) );
581
  print '<br />';
582
- print $this->basic_auth_username_callback ();
583
  print '<br />';
584
- printf ( '<label for="password">%s</label>', __ ( 'Password', Postman::TEXT_DOMAIN ) );
585
  print '<br />';
586
- print $this->basic_auth_password_callback ();
587
  print '</section>';
588
  }
589
  }
4
  /**
5
  *
6
  * @author jasonhendriks
 
7
  */
8
  class PostmanSmtpModuleTransport extends PostmanAbstractZendModuleTransport implements PostmanZendModuleTransport {
9
  const SLUG = 'smtp';
10
+ public function __construct( $rootPluginFilenameAndPath ) {
11
+ parent::__construct( $rootPluginFilenameAndPath );
12
+
13
  // add a hook on the plugins_loaded event
14
+ add_action( 'admin_init', array(
15
  $this,
16
+ 'on_admin_init',
17
  ) );
18
  }
19
+
20
  /**
21
  * (non-PHPdoc)
22
  *
24
  */
25
  public function createMailEngine() {
26
  require_once 'PostmanZendMailEngine.php';
27
+ return new PostmanZendMailEngine( $this );
28
  }
29
+
30
  /**
31
  * (non-PHPdoc)
32
  *
33
  * @see PostmanZendModuleTransport::createZendMailTransport()
34
  */
35
+ public function createZendMailTransport( $fakeHostname, $fakeConfig ) {
36
+ if ( PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType() ) {
37
+ $config = PostmanOAuth2ConfigurationFactory::createConfig( $this );
38
  } else {
39
+ $config = PostmanBasicAuthConfigurationFactory::createConfig( $this );
40
  }
41
+ return new Postman_Zend_Mail_Transport_Smtp( $this->getHostname(), $config );
42
  }
43
+
44
  /**
45
  * Determines whether Mail Engine locking is needed
46
  *
47
  * @see PostmanModuleTransport::requiresLocking()
48
  */
49
  public function isLockingRequired() {
50
+ return PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType();
51
  }
52
  public function getSlug() {
53
  return self::SLUG;
57
  }
58
  public function getHostname() {
59
  $this->options = $this->options;
60
+ return $this->options->getHostname();
61
  }
62
  public function getPort() {
63
  $this->options = $this->options;
64
+ return $this->options->getPort();
65
  }
66
  public function getAuthenticationType() {
67
+ return $this->options->getAuthenticationType();
68
  }
69
  public function getCredentialsId() {
70
  $this->options = $this->options;
71
+ if ( $this->options->isAuthTypeOAuth2() ) {
72
+ return $this->options->getClientId();
73
  } else {
74
+ return $this->options->getUsername();
75
  }
76
  }
77
  public function getCredentialsSecret() {
78
  $this->options = $this->options;
79
+ if ( $this->options->isAuthTypeOAuth2() ) {
80
+ return $this->options->getClientSecret();
81
  } else {
82
+ return $this->options->getPassword();
83
  }
84
  }
85
+
86
  /**
87
  * (non-PHPdoc)
88
  *
89
  * @see PostmanTransport::getMisconfigurationMessage()
90
  */
91
  protected function validateTransportConfiguration() {
92
+ $messages = parent::validateTransportConfiguration();
93
+ if ( ! $this->isHostConfigured( $this->options ) ) {
94
+ array_push( $messages, __( 'Outgoing Mail Server Hostname and Port can not be empty.', Postman::TEXT_DOMAIN ) );
95
+ $this->setNotConfiguredAndReady();
96
  }
97
+ if ( ! $this->isEnvelopeFromConfigured() ) {
98
+ array_push( $messages, __( 'Envelope-From Email Address can not be empty', Postman::TEXT_DOMAIN ) . '.' );
99
+ $this->setNotConfiguredAndReady();
100
  }
101
+ if ( $this->options->isAuthTypePassword() && ! $this->isPasswordAuthenticationConfigured( $this->options ) ) {
102
+ array_push( $messages, __( 'Username and password can not be empty.', Postman::TEXT_DOMAIN ) );
103
+ $this->setNotConfiguredAndReady();
104
  }
105
+ if ( $this->getAuthenticationType() == PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 ) {
106
+ if ( ! $this->isOAuth2SupportedHostConfigured() ) {
107
  /* translators: %1$s is the Client ID label, and %2$s is the Client Secret label (e.g. Warning: OAuth 2.0 authentication requires an OAuth 2.0-capable Outgoing Mail Server, Sender Email Address, Client ID, and Client Secret.) */
108
+ array_push( $messages, sprintf( __( 'OAuth 2.0 authentication requires a supported OAuth 2.0-capable Outgoing Mail Server.', Postman::TEXT_DOMAIN ) ) );
109
+ $this->setNotConfiguredAndReady();
110
  }
111
  }
112
+ if ( empty( $messages ) ) {
113
+ $this->setReadyForOAuthGrant();
114
+ if ( $this->isPermissionNeeded( $this->options, $this->getOAuthToken() ) ) {
115
  /* translators: %1$s is the Client ID label, and %2$s is the Client Secret label */
116
+ $message = sprintf( __( 'You have configured OAuth 2.0 authentication, but have not received permission to use it.', Postman::TEXT_DOMAIN ), $this->getScribe()->getClientIdLabel(), $this->getScribe()->getClientSecretLabel() );
117
+ $message .= sprintf( ' <a href="%s">%s</a>.', PostmanUtils::getGrantOAuthPermissionUrl(), $this->getScribe()->getRequestPermissionLinkText() );
118
+ array_push( $messages, $message );
119
+ $this->setNotConfiguredAndReady();
120
  }
121
  }
122
  return $messages;
123
  }
124
+
125
  /**
126
  *
127
  * @return boolean
128
  */
129
  private function isOAuth2SupportedHostConfigured() {
130
+ $options = PostmanOptions::getInstance();
131
+ $hostname = $options->getHostname();
132
+ $supportedOAuthProvider = $this->isServiceProviderGoogle( $hostname ) || $this->isServiceProviderMicrosoft( $hostname ) || $this->isServiceProviderYahoo( $hostname );
133
  return $supportedOAuthProvider;
134
  }
135
+
136
  /**
137
  * Given a hostname, what ports should we test?
138
  *
139
  * May return an array of several combinations.
140
  */
141
+ public function getSocketsForSetupWizardToProbe( $hostname, $smtpServerGuess ) {
142
+ $hosts = array(
143
+ $this->createSocketDefinition( $hostname, 25 ),
144
+ $this->createSocketDefinition( $hostname, 465 ),
145
+ $this->createSocketDefinition( $hostname, 587 ),
146
  );
147
+
148
  return $hosts;
149
  }
150
+
151
  /**
152
  * Creates a single socket for the Wizard to test
153
  */
154
+ protected function createSocketDefinition( $hostname, $port ) {
155
+ $socket = parent::createSocketDefinition( $hostname, $port );
156
  $socket ['smtp'] = true;
157
  return $socket;
158
  }
159
+
160
  /**
161
  * SendGrid will never recommend it's configuration
162
  *
163
+ * @param unknown $hostData
164
  */
165
+ public function getConfigurationBid( PostmanWizardSocket $hostData, $userAuthOverride, $originalSmtpServer ) {
166
  $port = $hostData->port;
167
  $hostname = $hostData->hostname;
168
  // because some servers, like smtp.broadband.rogers.com, report XOAUTH2 but have no OAuth2 front-end
169
+ $supportedOAuth2Provider = $this->isServiceProviderGoogle( $hostname ) || $this->isServiceProviderMicrosoft( $hostname ) || $this->isServiceProviderYahoo( $hostname );
170
  $score = 1;
171
+ $recommendation = array();
172
  // increment score for auth type
173
+ if ( $hostData->mitm ) {
174
+ $this->logger->debug( 'Losing points for MITM' );
175
  $score -= 10000;
176
  $recommendation ['mitm'] = true;
177
  }
178
+ if ( ! empty( $originalSmtpServer ) && $hostname != $originalSmtpServer ) {
179
+ $this->logger->debug( 'Losing points for Not The Original SMTP server' );
180
  $score -= 10000;
181
  }
182
  $secure = true;
183
+ if ( $hostData->startTls ) {
184
  // STARTTLS was formalized in 2002
185
  // http://www.rfc-editor.org/rfc/rfc3207.txt
186
  $recommendation ['enc'] = PostmanOptions::SECURITY_TYPE_STARTTLS;
187
  $score += 30000;
188
+ } elseif ( $hostData->protocol == 'SMTPS' ) {
189
  // "The hopelessly confusing and imprecise term, SSL,
190
  // has often been used to indicate the SMTPS wrapper and
191
  // TLS to indicate the STARTTLS protocol extension."
192
  // http://stackoverflow.com/a/19942206/4368109
193
  $recommendation ['enc'] = PostmanOptions::SECURITY_TYPE_SMTPS;
194
  $score += 28000;
195
+ } elseif ( $hostData->protocol == 'SMTP' ) {
196
  $recommendation ['enc'] = PostmanOptions::SECURITY_TYPE_NONE;
197
  $score += 26000;
198
  $secure = false;
199
  }
200
+
201
  // if there is a way to send mail....
202
+ if ( $score > 10 ) {
203
+
204
  // determine the authentication type
205
+ if ( $hostData->auth_xoauth && $supportedOAuth2Provider && (empty( $userAuthOverride ) || $userAuthOverride == 'oauth2') ) {
206
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_OAUTH2;
207
  $recommendation ['display_auth'] = 'oauth2';
208
  $score += 500;
209
+ if ( ! $secure ) {
210
+ $this->logger->debug( 'Losing points for sending credentials in the clear' );
211
  $score -= 10000;
212
  }
213
+ } elseif ( $hostData->auth_crammd5 && (empty( $userAuthOverride ) || $userAuthOverride == 'password') ) {
214
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5;
215
  $recommendation ['display_auth'] = 'password';
216
  $score += 400;
217
+ if ( ! $secure ) {
218
+ $this->logger->debug( 'Losing points for sending credentials in the clear' );
219
  $score -= 10000;
220
  }
221
+ } elseif ( $hostData->authPlain && (empty( $userAuthOverride ) || $userAuthOverride == 'password') ) {
222
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_PLAIN;
223
  $recommendation ['display_auth'] = 'password';
224
  $score += 300;
225
+ if ( ! $secure ) {
226
+ $this->logger->debug( 'Losing points for sending credentials in the clear' );
227
  $score -= 10000;
228
  }
229
+ } elseif ( $hostData->auth_login && (empty( $userAuthOverride ) || $userAuthOverride == 'password') ) {
230
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_LOGIN;
231
  $recommendation ['display_auth'] = 'password';
232
  $score += 200;
233
+ if ( ! $secure ) {
234
+ $this->logger->debug( 'Losing points for sending credentials in the clear' );
235
  $score -= 10000;
236
  }
237
+ } else if ( empty( $userAuthOverride ) || $userAuthOverride == 'none' ) {
238
  $recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_NONE;
239
  $recommendation ['display_auth'] = 'none';
240
  $score += 100;
241
  }
242
+
243
  // tiny weighting to prejudice the port selection, all things being equal
244
+ if ( $port == 587 ) {
245
  $score += 4;
246
+ } elseif ( $port == 25 ) {
247
  // "due to the prevalence of machines that have worms,
248
  // viruses, or other malicious software that generate large amounts of
249
  // spam, many sites now prohibit outbound traffic on the standard SMTP
251
  // servers."
252
  // http://www.rfc-editor.org/rfc/rfc6409.txt
253
  $score += 3;
254
+ } elseif ( $port == 465 ) {
255
  // use of port 465 for SMTP was deprecated in 1998
256
  // http://www.imc.org/ietf-apps-tls/mail-archive/msg00204.html
257
  $score += 2;
258
  } else {
259
  $score += 1;
260
  }
261
+
262
  // create the recommendation message for the user
263
  // this can only be set if there is a valid ['auth'] and ['enc']
264
+ $transportDescription = $this->getTransportDescription( $recommendation ['enc'] );
265
+ $authDesc = $this->getAuthenticationDescription( $recommendation ['auth'] );
266
+ $recommendation ['label'] = sprintf( 'SMTP - %2$s:%3$d', $transportDescription, $hostData->hostnameDomainOnly, $port );
267
  /* translators: where %1$s is a description of the transport (eg. SMTPS-SSL), %2$s is a description of the authentication (eg. Password-CRAMMD5), %3$d is the TCP port (eg. 465), %4$d is the hostname */
268
+ $recommendation ['message'] = sprintf( __( 'Postman recommends %1$s with %2$s authentication to host %4$s on port %3$d.', Postman::TEXT_DOMAIN ), $transportDescription, $authDesc, $port, $hostname );
269
  }
270
+
271
  // fill-in the rest of the recommendation
272
  $recommendation ['transport'] = PostmanSmtpModuleTransport::SLUG;
273
  $recommendation ['priority'] = $score;
274
  $recommendation ['port'] = $port;
275
  $recommendation ['hostname'] = $hostname;
276
  $recommendation ['transport'] = self::SLUG;
277
+
278
  return $recommendation;
279
  }
280
+
281
  /**
282
  * Functions to execute on the admin_init event
283
  *
286
  */
287
  public function on_admin_init() {
288
  // only administrators should be able to trigger this
289
+ if ( PostmanUtils::isAdmin() ) {
290
+ $this->addSettings();
291
+ $this->registerStylesAndScripts();
292
  }
293
  }
294
+
295
  /**
296
  */
297
  public function registerStylesAndScripts() {
298
  // register the stylesheet and javascript external resources
299
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
300
+ wp_register_script( 'postman_smtp_script', plugins_url( 'Postman/Postman-Mail/postman_smtp.js', $this->rootPluginFilenameAndPath ), array(
301
  PostmanViewController::JQUERY_SCRIPT,
302
  'jquery_validation',
303
+ PostmanViewController::POSTMAN_SCRIPT,
304
  ), $pluginData ['version'] );
305
  }
306
+
307
  /*
308
  * What follows in the code responsible for creating the Admin Settings page
309
  */
310
+
311
  /**
312
  */
313
  public function enqueueScript() {
314
+ wp_enqueue_script( 'postman_smtp_script' );
315
  }
316
+
317
  /**
318
  */
319
  public function addSettings() {
320
  $transport = $this;
321
  $this->options = $this->options;
322
+ $oauthScribe = $transport->getScribe();
323
+
324
  // Sanitize
325
+ add_settings_section( PostmanAdminController::SMTP_SECTION, __( 'Transport Settings', Postman::TEXT_DOMAIN ), array(
326
  $this,
327
+ 'printSmtpSectionInfo',
328
  ), PostmanAdminController::SMTP_OPTIONS );
329
+
330
+ add_settings_field( PostmanOptions::HOSTNAME, __( 'Outgoing Mail Server Hostname', Postman::TEXT_DOMAIN ), array(
331
  $this,
332
+ 'hostname_callback',
333
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
334
+
335
+ add_settings_field( PostmanOptions::PORT, __( 'Outgoing Mail Server Port', Postman::TEXT_DOMAIN ), array(
336
  $this,
337
+ 'port_callback',
338
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
339
+
340
+ add_settings_field( PostmanOptions::ENVELOPE_SENDER, __( 'Envelope-From Email Address', Postman::TEXT_DOMAIN ), array(
341
  $this,
342
+ 'sender_email_callback',
343
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
344
+
345
+ add_settings_field( PostmanOptions::SECURITY_TYPE, _x( 'Security', 'Configuration Input Field', Postman::TEXT_DOMAIN ), array(
346
  $this,
347
+ 'encryption_type_callback',
348
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
349
+
350
+ add_settings_field( PostmanOptions::AUTHENTICATION_TYPE, __( 'Authentication', Postman::TEXT_DOMAIN ), array(
351
  $this,
352
+ 'authentication_type_callback',
353
  ), PostmanAdminController::SMTP_OPTIONS, PostmanAdminController::SMTP_SECTION );
354
+
355
+ add_settings_section( PostmanAdminController::BASIC_AUTH_SECTION, __( 'Authentication', Postman::TEXT_DOMAIN ), array(
356
  $this,
357
+ 'printBasicAuthSectionInfo',
358
  ), PostmanAdminController::BASIC_AUTH_OPTIONS );
359
+
360
+ add_settings_field( PostmanOptions::BASIC_AUTH_USERNAME, __( 'Username', Postman::TEXT_DOMAIN ), array(
361
  $this,
362
+ 'basic_auth_username_callback',
363
  ), PostmanAdminController::BASIC_AUTH_OPTIONS, PostmanAdminController::BASIC_AUTH_SECTION );
364
+
365
+ add_settings_field( PostmanOptions::BASIC_AUTH_PASSWORD, __( 'Password', Postman::TEXT_DOMAIN ), array(
366
  $this,
367
+ 'basic_auth_password_callback',
368
  ), PostmanAdminController::BASIC_AUTH_OPTIONS, PostmanAdminController::BASIC_AUTH_SECTION );
369
+
370
  // the OAuth section
371
+ add_settings_section( PostmanAdminController::OAUTH_SECTION, __( 'Authentication', Postman::TEXT_DOMAIN ), array(
372
  $this,
373
+ 'printOAuthSectionInfo',
374
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS );
375
+
376
+ add_settings_field( 'callback_domain', sprintf( '<span id="callback_domain">%s</span>', $oauthScribe->getCallbackDomainLabel() ), array(
377
  $this,
378
+ 'callback_domain_callback',
379
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS, PostmanAdminController::OAUTH_SECTION );
380
+
381
+ add_settings_field( 'redirect_url', sprintf( '<span id="redirect_url">%s</span>', $oauthScribe->getCallbackUrlLabel() ), array(
382
  $this,
383
+ 'redirect_url_callback',
384
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS, PostmanAdminController::OAUTH_SECTION );
385
+
386
+ add_settings_field( PostmanOptions::CLIENT_ID, $oauthScribe->getClientIdLabel(), array(
387
  $this,
388
+ 'oauth_client_id_callback',
389
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS, PostmanAdminController::OAUTH_SECTION );
390
+
391
+ add_settings_field( PostmanOptions::CLIENT_SECRET, $oauthScribe->getClientSecretLabel(), array(
392
  $this,
393
+ 'oauth_client_secret_callback',
394
  ), PostmanAdminController::OAUTH_AUTH_OPTIONS, PostmanAdminController::OAUTH_SECTION );
395
  }
396
+
397
  /**
398
  * Print the Section text
399
  */
400
  public function printSmtpSectionInfo() {
401
+ print __( 'Configure the communication with the mail server.', Postman::TEXT_DOMAIN );
402
  }
403
+
404
  /**
405
  * Get the settings option array and print one of its values
406
  */
407
  public function hostname_callback() {
408
+ printf( '<input type="text" id="input_hostname" name="postman_options[hostname]" value="%s" size="40" class="required" placeholder="%s"/>', null !== $this->options->getHostname() ? esc_attr( $this->options->getHostname() ) : '', __( 'Required', Postman::TEXT_DOMAIN ) );
409
  }
410
+
411
  /**
412
  * Get the settings option array and print one of its values
413
  */
414
+ public function port_callback( $args ) {
415
+ printf( '<input type="text" id="input_port" name="postman_options[port]" value="%s" %s placeholder="%s"/>', null !== $this->options->getPort() ? esc_attr( $this->options->getPort() ) : '', isset( $args ['style'] ) ? $args ['style'] : '', __( 'Required', Postman::TEXT_DOMAIN ) );
416
  }
417
+
418
  /**
419
  * Get the settings option array and print one of its values
420
  */
421
  public function encryption_type_callback() {
422
+ $encType = $this->options->getEncryptionType();
423
  print '<select id="input_enc_type" class="input_encryption_type" name="postman_options[enc_type]">';
424
+ printf( '<option class="input_enc_type_none" value="%s" %s>%s</option>', PostmanOptions::SECURITY_TYPE_NONE, $encType == PostmanOptions::SECURITY_TYPE_NONE ? 'selected="selected"' : '', __( 'None', Postman::TEXT_DOMAIN ) );
425
+ printf( '<option class="input_enc_type_ssl" value="%s" %s>%s</option>', PostmanOptions::SECURITY_TYPE_SMTPS, $encType == PostmanOptions::SECURITY_TYPE_SMTPS ? 'selected="selected"' : '', 'SMTPS' );
426
+ printf( '<option class="input_enc_type_tls" value="%s" %s>%s</option>', PostmanOptions::SECURITY_TYPE_STARTTLS, $encType == PostmanOptions::SECURITY_TYPE_STARTTLS ? 'selected="selected"' : '', 'STARTTLS' );
427
  print '</select>';
428
  }
429
+
430
  /**
431
  * Get the settings option array and print one of its values
432
  */
433
  public function authentication_type_callback() {
434
+ $authType = $this->options->getAuthenticationType();
435
+ printf( '<select id="input_%2$s" class="input_%2$s" name="%1$s[%2$s]">', PostmanOptions::POSTMAN_OPTIONS, PostmanOptions::AUTHENTICATION_TYPE );
436
+ printf( '<option class="input_auth_type_none" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_NONE, $authType == PostmanOptions::AUTHENTICATION_TYPE_NONE ? 'selected="selected"' : '', 'None' );
437
+ printf( '<option class="input_auth_type_plain" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_PLAIN, $authType == PostmanOptions::AUTHENTICATION_TYPE_PLAIN ? 'selected="selected"' : '', 'Plain' );
438
+ printf( '<option class="input_auth_type_login" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_LOGIN, $authType == PostmanOptions::AUTHENTICATION_TYPE_LOGIN ? 'selected="selected"' : '', 'Login' );
439
+ printf( '<option class="input_auth_type_crammd5" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5, $authType == PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5 ? 'selected="selected"' : '', 'CRAM-MD5' );
440
+ printf( '<option class="input_auth_type_oauth2" value="%s" %s>%s</option>', PostmanOptions::AUTHENTICATION_TYPE_OAUTH2, $authType == PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 ? 'selected="selected"' : '', 'OAuth 2.0' );
441
  print '</select>';
442
  }
443
+
444
  /**
445
  * Print the Section text
446
  */
447
  public function printBasicAuthSectionInfo() {
448
+ print __( 'Enter the account credentials.', Postman::TEXT_DOMAIN );
449
  }
450
+
451
  /**
452
  * Get the settings option array and print one of its values
453
  */
454
  public function basic_auth_username_callback() {
455
+ $inputValue = (null !== $this->options->getUsername() ? esc_attr( $this->options->getUsername() ) : '');
456
+ $inputDescription = __( 'The Username is usually the same as the Envelope-From Email Address.', Postman::TEXT_DOMAIN );
457
  print ('<input tabindex="99" id="fake_user_name" name="fake_user[name]" style="position:absolute; top:-500px;" type="text" value="Safari Autofill Me">') ;
458
+ printf( '<input type="text" id="input_basic_auth_username" name="postman_options[basic_auth_username]" value="%s" size="40" class="required" placeholder="%s"/><br/><span class="postman_input_description">%s</span>', $inputValue, __( 'Required', Postman::TEXT_DOMAIN ), $inputDescription );
459
  }
460
+
461
  /**
462
  * Get the settings option array and print one of its values
463
  */
464
  public function basic_auth_password_callback() {
465
  print ('<input tabindex="99" id="fake_password" name="fake[password]" style="position:absolute; top:-500px;" type="password" value="Safari Autofill Me">') ;
466
+ printf( '<input type="password" id="input_basic_auth_password" name="postman_options[basic_auth_password]" value="%s" size="40" class="required" placeholder="%s"/>', null !== $this->options->getPassword() ? esc_attr( PostmanUtils::obfuscatePassword( $this->options->getPassword() ) ) : '', __( 'Required', Postman::TEXT_DOMAIN ) );
467
  print ' <input type="button" id="togglePasswordField" value="Show Password" class="button button-secondary" style="visibility:hidden" />';
468
  }
469
+
470
  /**
471
  * Get the settings option array and print one of its values
472
  */
473
  public function oauth_client_id_callback() {
474
+ printf( '<input type="text" onClick="this.setSelectionRange(0, this.value.length)" id="oauth_client_id" name="postman_options[oauth_client_id]" value="%s" size="60" class="required" placeholder="%s"/>', null !== $this->options->getClientId() ? esc_attr( $this->options->getClientId() ) : '', __( 'Required', Postman::TEXT_DOMAIN ) );
475
  }
476
+
477
  /**
478
  * Get the settings option array and print one of its values
479
  */
480
  public function oauth_client_secret_callback() {
481
+ printf( '<input type="text" onClick="this.setSelectionRange(0, this.value.length)" autocomplete="off" id="oauth_client_secret" name="postman_options[oauth_client_secret]" value="%s" size="60" class="required" placeholder="%s"/>', null !== $this->options->getClientSecret() ? esc_attr( $this->options->getClientSecret() ) : '', __( 'Required', Postman::TEXT_DOMAIN ) );
482
  }
483
+
484
  /**
485
  * Print the Section text
486
  */
487
  public function printOAuthSectionInfo() {
488
  $this->options = $this->options;
489
  $transport = $this;
490
+ $oauthScribe = $transport->getScribe();
491
+ printf( '<p id="wizard_oauth2_help">%s</p>', $oauthScribe->getOAuthHelp() );
492
  }
493
+
494
  /**
495
  * Get the settings option array and print one of its values
496
  */
497
  public function callback_domain_callback() {
498
+ printf( '<input type="text" onClick="this.setSelectionRange(0, this.value.length)" readonly="readonly" id="input_oauth_callback_domain" value="%s" size="60"/>', $this->getCallbackDomain() );
499
  }
500
+
501
  /**
502
  */
503
  private function getCallbackDomain() {
504
  try {
505
  $this->options = $this->options;
506
  $transport = $this;
507
+ $oauthScribe = $transport->getScribe();
508
+ return $oauthScribe->getCallbackDomain();
509
  } catch ( Exception $e ) {
510
+ return __( 'Error computing your domain root - please enter it manually', Postman::TEXT_DOMAIN );
511
  }
512
  }
513
+
514
  /**
515
  * Get the settings option array and print one of its values
516
  */
517
  public function redirect_url_callback() {
518
  $this->options = $this->options;
519
  $transport = $this;
520
+ $oauthScribe = $transport->getScribe();
521
+ printf( '<input type="text" onClick="this.setSelectionRange(0, this.value.length)" readonly="readonly" id="input_oauth_redirect_url" value="%s" size="60"/>', $oauthScribe->getCallbackUrl() );
522
  }
523
+
524
  /**
525
  * Get the settings option array and print one of its values
526
  */
527
  public function sender_email_callback() {
528
+ $inputValue = (null !== $this->options->getEnvelopeSender() ? esc_attr( $this->options->getEnvelopeSender() ) : '');
529
+ $requiredLabel = __( 'Required', Postman::TEXT_DOMAIN );
530
+ $envelopeFromMessage = __( 'This address, like the <b>return address</b> printed on an envelope, identifies the account owner to the SMTP server.', Postman::TEXT_DOMAIN );
531
+ $spfMessage = sprintf( __( 'For reliable delivery, this domain must specify an <a target="_new" href="%s">SPF record</a> permitting the use of the SMTP server named above.', Postman::TEXT_DOMAIN ), 'https://www.mail-tester.com/spf/' );
532
+ printf( '<input type="email" id="input_envelope_sender_email" name="postman_options[envelope_sender]" value="%s" size="40" class="required" placeholder="%s"/> <br/><span class="postman_input_description">%s %s</span>', $inputValue, $requiredLabel, $envelopeFromMessage, $spfMessage );
533
  }
534
+
535
  /**
536
  */
537
  public function printWizardMailServerHostnameStep() {
538
+ printf( '<legend>%s</legend>', _x( 'Which host will relay the mail?', 'Wizard Step Title', Postman::TEXT_DOMAIN ) );
539
+ printf( '<p>%s</p>', __( 'This is the Outgoing (SMTP) Mail Server, or Mail Submission Agent (MSA), which Postman delegates mail delivery to. This server is specific to your email account, and if you don\'t know what to use, ask your email service provider.', Postman::TEXT_DOMAIN ) );
540
+ printf( '<p>%s</p>', __( 'Note that many WordPress hosts, such as GoDaddy, Bluehost and Dreamhost, require that you use their mail accounts with their mail servers, and prevent you from using others.', Postman::TEXT_DOMAIN ) );
541
+ printf( '<label for="hostname">%s</label>', __( 'Outgoing Mail Server Hostname', Postman::TEXT_DOMAIN ) );
542
+ print $this->hostname_callback();
543
+ printf( '<p class="ajax-loader" style="display:none"><img src="%s"/></p>', plugins_url( 'post-smtp/style/ajax-loader.gif' ) );
544
+ $warning = __( 'Warning', Postman::TEXT_DOMAIN );
545
  /* Translators: Where (%s) is the name of the web host */
546
+ $nonGodaddyDomainMessage = sprintf( __( 'Your email address <b>requires</b> access to a remote SMTP server blocked by %s.', Postman::TEXT_DOMAIN ), 'GoDaddy' );
547
+ $nonGodaddyDomainMessage .= sprintf( ' %s', __( 'If you have access to cPanel, enable the Remote Mail Exchanger.', Postman::TEXT_DOMAIN ) );
548
+ printf( '<p id="godaddy_block"><span style="background-color:yellow"><b>%s</b>: %s</span></p>', $warning, $nonGodaddyDomainMessage );
549
  /* Translators: Where (%1$s) is the SPF-info URL and (%2$s) is the name of the web host */
550
+ $godaddyCustomDomainMessage = sprintf( __( 'If you own this domain, make sure it has an <a href="%1$s">SPF record authorizing %2$s</a> as a relay, or you will have delivery problems.', Postman::TEXT_DOMAIN ), 'http://www.mail-tester.com/spf/godaddy', 'GoDaddy' );
551
+ printf( '<p id="godaddy_spf_required"><span style="background-color:yellow"><b>%s</b>: %s</span></p>', $warning, $godaddyCustomDomainMessage );
552
  }
553
+
554
  /**
555
  */
556
  public function printWizardAuthenticationStep() {
557
  print '<section class="wizard-auth-oauth2">';
558
  print '<p id="wizard_oauth2_help"></p>';
559
+ printf( '<label id="callback_domain" for="callback_domain">%s</label>', $this->getScribe()->getCallbackDomainLabel() );
560
  print '<br />';
561
+ print $this->callback_domain_callback();
562
  print '<br />';
563
+ printf( '<label id="redirect_url" for="redirect_uri">%s</label>', $this->getScribe()->getCallbackUrlLabel() );
564
  print '<br />';
565
+ print $this->redirect_url_callback();
566
  print '<br />';
567
+ printf( '<label id="client_id" for="client_id">%s</label>', $this->getScribe()->getClientIdLabel() );
568
  print '<br />';
569
+ print $this->oauth_client_id_callback();
570
  print '<br />';
571
+ printf( '<label id="client_secret" for="client_secret">%s</label>', $this->getScribe()->getClientSecretLabel() );
572
  print '<br />';
573
+ print $this->oauth_client_secret_callback();
574
  print '<br />';
575
  print '</section>';
576
+
577
  print '<section class="wizard-auth-basic">';
578
+ printf( '<p class="port-explanation-ssl">%s</p>', __( 'Enter the account credentials.', Postman::TEXT_DOMAIN ) );
579
+ printf( '<label for="username">%s</label>', __( 'Username', Postman::TEXT_DOMAIN ) );
580
  print '<br />';
581
+ print $this->basic_auth_username_callback();
582
  print '<br />';
583
+ printf( '<label for="password">%s</label>', __( 'Password', Postman::TEXT_DOMAIN ) );
584
  print '<br />';
585
+ print $this->basic_auth_password_callback();
586
  print '</section>';
587
  }
588
  }
Postman/Postman-Mail/PostmanZendMailEngine.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
- if (! class_exists ( "PostmanZendMailEngine" )) {
3
-
4
  require_once 'Zend-1.12.10/Loader.php';
5
  require_once 'Zend-1.12.10/Registry.php';
6
  require_once 'Zend-1.12.10/Mime/Message.php';
@@ -25,7 +25,7 @@ if (! class_exists ( "PostmanZendMailEngine" )) {
25
  require_once 'Zend-1.12.10/Mail/Protocol/Smtp/Auth/Login.php';
26
  require_once 'Zend-1.12.10/Mail/Protocol/Smtp/Auth/Crammd5.php';
27
  require_once 'Zend-1.12.10/Mail/Protocol/Smtp/Auth/Plain.php';
28
-
29
  /**
30
  * This class knows how to interface with Wordpress
31
  * including loading/saving to the database.
@@ -34,208 +34,206 @@ if (! class_exists ( "PostmanZendMailEngine" )) {
34
  * http://framework.zend.com/manual/current/en/modules/zend.mail.smtp.options.html
35
  *
36
  * @author jasonhendriks
37
- *
38
  */
39
  class PostmanZendMailEngine implements PostmanMailEngine {
40
-
41
  // logger for all concrete classes - populate with setLogger($logger)
42
  protected $logger;
43
-
44
  // the result
45
  private $transcript;
46
-
47
- //
48
  private $transport;
49
-
50
  /**
51
  *
52
- * @param unknown $senderEmail
53
- * @param unknown $accessToken
54
  */
55
- function __construct(PostmanZendModuleTransport $transport) {
56
- assert ( isset ( $transport ) );
57
  $this->transport = $transport;
58
-
59
  // create the logger
60
- $this->logger = new PostmanLogger ( get_class ( $this ) );
61
  }
62
-
63
  /**
64
  * (non-PHPdoc)
65
  *
66
  * @see PostmanSmtpEngine::send()
67
  */
68
- public function send(PostmanMessage $message) {
69
- $this->logger->debug ( "Prepping Zend" );
70
- $envelopeFrom = new PostmanEmailAddress ( $this->transport->getEnvelopeFromEmailAddress () );
71
- if ($this->transport->isEnvelopeFromValidationSupported ()) {
72
  // validate the envelope from since we didn't do it in the Message
73
- $envelopeFrom->validate ( 'Envelope From' );
74
  }
75
-
76
  // create the Message
77
- $charset = $message->getCharset ();
78
- $this->logger->debug ( 'Building Postman_Zend_Mail with charset=' . $charset );
79
- $mail = new Postman_Zend_Mail ( $charset );
80
-
81
  // add the Postman signature - append it to whatever the user may have set
82
- if (! PostmanOptions::getInstance ()->isStealthModeEnabled ()) {
83
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
84
- $mail->addHeader ( 'X-Mailer', sprintf ( 'Postman SMTP %s for WordPress (%s)', $pluginData ['version'], 'https://wordpress.org/plugins/postman-smtp/' ) );
85
  }
86
-
87
  // add the headers - see http://framework.zend.com/manual/1.12/en/zend.mail.additional-headers.html
88
- foreach ( ( array ) $message->getHeaders () as $header ) {
89
- $this->logger->debug ( sprintf ( 'Adding user header %s=%s', $header ['name'], $header ['content'] ) );
90
- $mail->addHeader ( $header ['name'], $header ['content'], true );
91
  }
92
-
93
  // if the caller set a Content-Type header, use it
94
- $contentType = $message->getContentType ();
95
- if (! empty ( $contentType )) {
96
- $mail->addHeader ( 'Content-Type', $contentType, false );
97
- $this->logger->debug ( 'Adding content-type ' . $contentType );
98
  }
99
-
100
  // add the From Header
101
- $fromHeader = $this->addFrom ( $message, $mail );
102
- $fromHeader->log ( $this->logger, 'From' );
103
-
104
  // add the Sender Header, overriding what the user may have set
105
- $mail->addHeader ( 'Sender', $this->transport->getFromEmailAddress (), false );
106
  // from RFC 5321: http://tools.ietf.org/html/rfc5321#section-4.4
107
  // A message-originating SMTP system SHOULD NOT send a message that
108
  // already contains a Return-path header field.
109
  // I changed Zend/Mail/Mail.php to fix this
110
- $mail->setReturnPath ( $this->transport->getEnvelopeFromEmailAddress () );
111
-
112
  // add the to recipients
113
- foreach ( ( array ) $message->getToRecipients () as $recipient ) {
114
- $recipient->log ( $this->logger, 'To' );
115
- $mail->addTo ( $recipient->getEmail (), $recipient->getName () );
116
  }
117
-
118
  // add the cc recipients
119
- foreach ( ( array ) $message->getCcRecipients () as $recipient ) {
120
- $recipient->log ( $this->logger, 'Cc' );
121
- $mail->addCc ( $recipient->getEmail (), $recipient->getName () );
122
  }
123
-
124
  // add the to recipients
125
- foreach ( ( array ) $message->getBccRecipients () as $recipient ) {
126
- $recipient->log ( $this->logger, 'Bcc' );
127
- $mail->addBcc ( $recipient->getEmail (), $recipient->getName () );
128
  }
129
-
130
  // add the reply-to
131
- $replyTo = $message->getReplyTo ();
132
  // $replyTo is null or a PostmanEmailAddress object
133
- if (isset ( $replyTo )) {
134
- $mail->setReplyTo ( $replyTo->getEmail (), $replyTo->getName () );
135
  }
136
-
137
  // add the date
138
- $date = $message->getDate ();
139
- if (! empty ( $date )) {
140
- $mail->setDate ( $date );
141
  }
142
-
143
  // add the messageId
144
- $messageId = $message->getMessageId ();
145
- if (! empty ( $messageId )) {
146
- $mail->setMessageId ( $messageId );
147
  }
148
-
149
  // add the subject
150
- if (null !== $message->getSubject ()) {
151
- $mail->setSubject ( $message->getSubject () );
152
  }
153
-
154
  // add the message content
155
  {
156
- $textPart = $message->getBodyTextPart ();
157
- if (! empty ( $textPart )) {
158
- $this->logger->debug ( 'Adding body as text' );
159
- $mail->setBodyText ( $textPart );
160
- }
161
- $htmlPart = $message->getBodyHtmlPart ();
162
- if (! empty ( $htmlPart )) {
163
- $this->logger->debug ( 'Adding body as html' );
164
- $mail->setBodyHtml ( $htmlPart );
165
- }
166
  }
167
-
 
 
 
 
 
 
168
  // add attachments
169
- $this->logger->debug ( "Adding attachments" );
170
- $message->addAttachmentsToMail ( $mail );
171
-
172
  // create the SMTP transport
173
- $this->logger->debug ( "Create the Zend_Mail transport" );
174
- $zendTransport = $this->transport->createZendMailTransport ( $this->transport->getHostname (), array () );
175
-
176
  try {
177
  // send the message
178
- $this->logger->debug ( "Sending mail" );
179
- $mail->send ( $zendTransport );
180
- if ($this->logger->isInfo ()) {
181
- $this->logger->info ( sprintf ( 'Message %d accepted for delivery', PostmanState::getInstance ()->getSuccessfulDeliveries () + 1 ) );
182
  }
183
  // finally not supported??
184
- if ($zendTransport->getConnection () && ! PostmanUtils::isEmpty ( $zendTransport->getConnection ()->getLog () )) {
185
- $this->transcript = $zendTransport->getConnection ()->getLog ();
186
- } else if (method_exists ( $zendTransport, 'getTranscript' ) && ! PostmanUtils::isEmpty ( $zendTransport->getTranscript () )) {
187
  // then use the API response
188
- $this->transcript = $zendTransport->getTranscript ();
189
- } else if (method_exists ( $zendTransport, 'getMessage' ) && ! PostmanUtils::isEmpty ( $zendTransport->getMessage () )) {
190
  // then use the Raw Message as the Transcript
191
- $this->transcript = $zendTransport->getMessage ();
192
  }
193
  } catch ( Exception $e ) {
194
  // finally not supported??
195
- if ($zendTransport->getConnection () && ! PostmanUtils::isEmpty ( $zendTransport->getConnection ()->getLog () )) {
196
- $this->transcript = $zendTransport->getConnection ()->getLog ();
197
- } else if (method_exists ( $zendTransport, 'getTranscript' ) && ! PostmanUtils::isEmpty ( $zendTransport->getTranscript () )) {
198
  // then use the API response
199
- $this->transcript = $zendTransport->getTranscript ();
200
- } else if (method_exists ( $zendTransport, 'getMessage' ) && ! PostmanUtils::isEmpty ( $zendTransport->getMessage () )) {
201
  // then use the Raw Message as the Transcript
202
- $this->transcript = $zendTransport->getMessage ();
203
  }
204
-
205
  // get the current exception message
206
- $message = $e->getMessage ();
207
- if ($e->getCode () == 334) {
208
  // replace the unusable Google message with a better one in the case of code 334
209
- $message = sprintf ( __ ( 'Communication Error [334] - make sure the Envelope From email is the same account used to create the Client ID.', Postman::TEXT_DOMAIN ) );
210
  }
211
  // create a new exception
212
- $newException = new Exception ( $message, $e->getCode () );
213
  // throw the new exception after handling
214
  throw $newException;
215
  }
216
  }
217
-
218
  /**
219
  * Get the sender from PostmanMessage and add it to the Postman_Zend_Mail object
220
  *
221
- * @param PostmanMessage $message
222
- * @param Postman_Zend_Mail $mail
223
  * @return PostmanEmailAddress
224
  */
225
- public function addFrom(PostmanMessage $message, Postman_Zend_Mail $mail) {
226
- $sender = $message->getFromAddress ();
227
  // now log it and push it into the message
228
- $senderEmail = $sender->getEmail ();
229
- $senderName = $sender->getName ();
230
- assert ( ! empty ( $senderEmail ) );
231
- if (! empty ( $senderName )) {
232
- $mail->setFrom ( $senderEmail, $senderName );
233
  } else {
234
- $mail->setFrom ( $senderEmail );
235
  }
236
  return $sender;
237
  }
238
-
239
  // return the SMTP session transcript
240
  public function getTranscript() {
241
  return $this->transcript;
1
  <?php
2
+ if ( ! class_exists( 'PostmanZendMailEngine' ) ) {
3
+
4
  require_once 'Zend-1.12.10/Loader.php';
5
  require_once 'Zend-1.12.10/Registry.php';
6
  require_once 'Zend-1.12.10/Mime/Message.php';
25
  require_once 'Zend-1.12.10/Mail/Protocol/Smtp/Auth/Login.php';
26
  require_once 'Zend-1.12.10/Mail/Protocol/Smtp/Auth/Crammd5.php';
27
  require_once 'Zend-1.12.10/Mail/Protocol/Smtp/Auth/Plain.php';
28
+
29
  /**
30
  * This class knows how to interface with Wordpress
31
  * including loading/saving to the database.
34
  * http://framework.zend.com/manual/current/en/modules/zend.mail.smtp.options.html
35
  *
36
  * @author jasonhendriks
 
37
  */
38
  class PostmanZendMailEngine implements PostmanMailEngine {
39
+
40
  // logger for all concrete classes - populate with setLogger($logger)
41
  protected $logger;
42
+
43
  // the result
44
  private $transcript;
45
+
 
46
  private $transport;
47
+
48
  /**
49
  *
50
+ * @param unknown $senderEmail
51
+ * @param unknown $accessToken
52
  */
53
+ function __construct( PostmanZendModuleTransport $transport ) {
54
+ assert( isset( $transport ) );
55
  $this->transport = $transport;
56
+
57
  // create the logger
58
+ $this->logger = new PostmanLogger( get_class( $this ) );
59
  }
60
+
61
  /**
62
  * (non-PHPdoc)
63
  *
64
  * @see PostmanSmtpEngine::send()
65
  */
66
+ public function send( PostmanMessage $message ) {
67
+ $this->logger->debug( 'Prepping Zend' );
68
+ $envelopeFrom = new PostmanEmailAddress( $this->transport->getEnvelopeFromEmailAddress() );
69
+ if ( $this->transport->isEnvelopeFromValidationSupported() ) {
70
  // validate the envelope from since we didn't do it in the Message
71
+ $envelopeFrom->validate( 'Envelope From' );
72
  }
73
+
74
  // create the Message
75
+ $charset = $message->getCharset();
76
+ $this->logger->debug( 'Building Postman_Zend_Mail with charset=' . $charset );
77
+ $mail = new Postman_Zend_Mail( $charset );
78
+
79
  // add the Postman signature - append it to whatever the user may have set
80
+ if ( ! PostmanOptions::getInstance()->isStealthModeEnabled() ) {
81
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
82
+ $mail->addHeader( 'X-Mailer', sprintf( 'Postman SMTP %s for WordPress (%s)', $pluginData ['version'], 'https://wordpress.org/plugins/post-smtp/' ) );
83
  }
84
+
85
  // add the headers - see http://framework.zend.com/manual/1.12/en/zend.mail.additional-headers.html
86
+ foreach ( ( array ) $message->getHeaders() as $header ) {
87
+ $this->logger->debug( sprintf( 'Adding user header %s=%s', $header ['name'], $header ['content'] ) );
88
+ $mail->addHeader( $header ['name'], $header ['content'], true );
89
  }
90
+
91
  // if the caller set a Content-Type header, use it
92
+ $contentType = $message->getContentType();
93
+ if ( ! empty( $contentType ) ) {
94
+ $mail->addHeader( 'Content-Type', $contentType, false );
95
+ $this->logger->debug( 'Adding content-type ' . $contentType );
96
  }
97
+
98
  // add the From Header
99
+ $fromHeader = $this->addFrom( $message, $mail );
100
+ $fromHeader->log( $this->logger, 'From' );
101
+
102
  // add the Sender Header, overriding what the user may have set
103
+ $mail->addHeader( 'Sender', $this->transport->getFromEmailAddress(), false );
104
  // from RFC 5321: http://tools.ietf.org/html/rfc5321#section-4.4
105
  // A message-originating SMTP system SHOULD NOT send a message that
106
  // already contains a Return-path header field.
107
  // I changed Zend/Mail/Mail.php to fix this
108
+ $mail->setReturnPath( $this->transport->getEnvelopeFromEmailAddress() );
109
+
110
  // add the to recipients
111
+ foreach ( ( array ) $message->getToRecipients() as $recipient ) {
112
+ $recipient->log( $this->logger, 'To' );
113
+ $mail->addTo( $recipient->getEmail(), $recipient->getName() );
114
  }
115
+
116
  // add the cc recipients
117
+ foreach ( ( array ) $message->getCcRecipients() as $recipient ) {
118
+ $recipient->log( $this->logger, 'Cc' );
119
+ $mail->addCc( $recipient->getEmail(), $recipient->getName() );
120
  }
121
+
122
  // add the to recipients
123
+ foreach ( ( array ) $message->getBccRecipients() as $recipient ) {
124
+ $recipient->log( $this->logger, 'Bcc' );
125
+ $mail->addBcc( $recipient->getEmail(), $recipient->getName() );
126
  }
127
+
128
  // add the reply-to
129
+ $replyTo = $message->getReplyTo();
130
  // $replyTo is null or a PostmanEmailAddress object
131
+ if ( isset( $replyTo ) ) {
132
+ $mail->setReplyTo( $replyTo->getEmail(), $replyTo->getName() );
133
  }
134
+
135
  // add the date
136
+ $date = $message->getDate();
137
+ if ( ! empty( $date ) ) {
138
+ $mail->setDate( $date );
139
  }
140
+
141
  // add the messageId
142
+ $messageId = $message->getMessageId();
143
+ if ( ! empty( $messageId ) ) {
144
+ $mail->setMessageId( $messageId );
145
  }
146
+
147
  // add the subject
148
+ if ( null !== $message->getSubject() ) {
149
+ $mail->setSubject( $message->getSubject() );
150
  }
151
+
152
  // add the message content
153
  {
154
+ $textPart = $message->getBodyTextPart();
155
+ if ( ! empty( $textPart ) ) {
156
+ $this->logger->debug( 'Adding body as text' );
157
+ $mail->setBodyText( $textPart );
 
 
 
 
 
 
158
  }
159
+ $htmlPart = $message->getBodyHtmlPart();
160
+ if ( ! empty( $htmlPart ) ) {
161
+ $this->logger->debug( 'Adding body as html' );
162
+ $mail->setBodyHtml( $htmlPart );
163
+ }
164
+ }
165
+
166
  // add attachments
167
+ $this->logger->debug( 'Adding attachments' );
168
+ $message->addAttachmentsToMail( $mail );
169
+
170
  // create the SMTP transport
171
+ $this->logger->debug( 'Create the Zend_Mail transport' );
172
+ $zendTransport = $this->transport->createZendMailTransport( $this->transport->getHostname(), array() );
173
+
174
  try {
175
  // send the message
176
+ $this->logger->debug( 'Sending mail' );
177
+ $mail->send( $zendTransport );
178
+ if ( $this->logger->isInfo() ) {
179
+ $this->logger->info( sprintf( 'Message %d accepted for delivery', PostmanState::getInstance()->getSuccessfulDeliveries() + 1 ) );
180
  }
181
  // finally not supported??
182
+ if ( $zendTransport->getConnection() && ! PostmanUtils::isEmpty( $zendTransport->getConnection()->getLog() ) ) {
183
+ $this->transcript = $zendTransport->getConnection()->getLog();
184
+ } else if ( method_exists( $zendTransport, 'getTranscript' ) && ! PostmanUtils::isEmpty( $zendTransport->getTranscript() ) ) {
185
  // then use the API response
186
+ $this->transcript = $zendTransport->getTranscript();
187
+ } else if ( method_exists( $zendTransport, 'getMessage' ) && ! PostmanUtils::isEmpty( $zendTransport->getMessage() ) ) {
188
  // then use the Raw Message as the Transcript
189
+ $this->transcript = $zendTransport->getMessage();
190
  }
191
  } catch ( Exception $e ) {
192
  // finally not supported??
193
+ if ( $zendTransport->getConnection() && ! PostmanUtils::isEmpty( $zendTransport->getConnection()->getLog() ) ) {
194
+ $this->transcript = $zendTransport->getConnection()->getLog();
195
+ } else if ( method_exists( $zendTransport, 'getTranscript' ) && ! PostmanUtils::isEmpty( $zendTransport->getTranscript() ) ) {
196
  // then use the API response
197
+ $this->transcript = $zendTransport->getTranscript();
198
+ } else if ( method_exists( $zendTransport, 'getMessage' ) && ! PostmanUtils::isEmpty( $zendTransport->getMessage() ) ) {
199
  // then use the Raw Message as the Transcript
200
+ $this->transcript = $zendTransport->getMessage();
201
  }
202
+
203
  // get the current exception message
204
+ $message = $e->getMessage();
205
+ if ( $e->getCode() == 334 ) {
206
  // replace the unusable Google message with a better one in the case of code 334
207
+ $message = sprintf( __( 'Communication Error [334] - make sure the Envelope From email is the same account used to create the Client ID.', Postman::TEXT_DOMAIN ) );
208
  }
209
  // create a new exception
210
+ $newException = new Exception( $message, $e->getCode() );
211
  // throw the new exception after handling
212
  throw $newException;
213
  }
214
  }
215
+
216
  /**
217
  * Get the sender from PostmanMessage and add it to the Postman_Zend_Mail object
218
  *
219
+ * @param PostmanMessage $message
220
+ * @param Postman_Zend_Mail $mail
221
  * @return PostmanEmailAddress
222
  */
223
+ public function addFrom( PostmanMessage $message, Postman_Zend_Mail $mail ) {
224
+ $sender = $message->getFromAddress();
225
  // now log it and push it into the message
226
+ $senderEmail = $sender->getEmail();
227
+ $senderName = $sender->getName();
228
+ assert( ! empty( $senderEmail ) );
229
+ if ( ! empty( $senderName ) ) {
230
+ $mail->setFrom( $senderEmail, $senderName );
231
  } else {
232
+ $mail->setFrom( $senderEmail );
233
  }
234
  return $sender;
235
  }
236
+
237
  // return the SMTP session transcript
238
  public function getTranscript() {
239
  return $this->transcript;
Postman/Postman-Mail/sendgrid-php-3.2.0/lib/SendGrid/Email.php CHANGED
@@ -4,689 +4,634 @@ namespace SendGrid;
4
 
5
  class Email
6
  {
7
- public
8
- $to,
9
- $toName,
10
- $from,
11
- $fromName,
12
- $replyTo,
13
- $cc,
14
- $ccName,
15
- $bcc,
16
- $bccName,
17
- $subject,
18
- $text,
19
- $html,
20
- $date,
21
- $content,
22
- $headers,
23
- $smtpapi,
24
- $attachments;
25
-
26
- public function __construct()
27
- {
28
- $this->fromName = false;
29
- $this->replyTo = false;
30
- $this->smtpapi = new \Smtpapi\Header();
31
- }
32
-
33
- /**
34
- * _removeFromList
35
- * Given a list of key/value pairs, removes the associated keys
36
- * where a value matches the given string ($item)
37
- *
38
- * @param Array $list - the list of key/value pairs
39
- * @param String $item - the value to be removed
40
- */
41
- private function _removeFromList(&$list, $item, $key_field = null)
42
- {
43
- foreach ($list as $key => $val) {
44
- if ($key_field) {
45
- if ($val[$key_field] == $item) {
46
- unset($list[$key]);
47
- }
48
- } else {
49
- if ($val == $item) {
50
- unset($list[$key]);
51
- }
52
- }
53
- }
54
- //repack the indices
55
- $list = array_values($list);
56
- }
57
-
58
- public function addTo($email, $name = null)
59
- {
60
- if ($this->to == null) {
61
- $this->to = array();
62
- }
63
-
64
- if (is_array($email)) {
65
- foreach ($email as $e) {
66
- $this->to[] = $e;
67
- }
68
- } else {
69
- $this->to[] = $email;
70
- }
71
-
72
- if (is_array($name)) {
73
- foreach ($name as $n) {
74
- $this->addToName($n);
75
- }
76
- } elseif ($name) {
77
- $this->addToName($name);
78
- }
79
-
80
- return $this;
81
- }
82
-
83
- public function addSmtpapiTo($email, $name = null)
84
- {
85
- $this->smtpapi->addTo($email, $name);
86
-
87
- return $this;
88
- }
89
-
90
- public function setTos(array $emails)
91
- {
92
- $this->to = $emails;
93
-
94
- return $this;
95
- }
96
-
97
- public function setSmtpapiTos(array $emails)
98
- {
99
- $this->smtpapi->setTos($emails);
100
-
101
- return $this;
102
- }
103
-
104
- public function addToName($name)
105
- {
106
- if ($this->toName == null) {
107
- $this->toName = array();
108
- }
109
-
110
- $this->toName[] = $name;
111
-
112
- return $this;
113
- }
114
-
115
- public function getToNames()
116
- {
117
- return $this->toName;
118
- }
119
-
120
- public function setFrom($email)
121
- {
122
- $this->from = $email;
123
-
124
- return $this;
125
- }
126
-
127
- public function getFrom($as_array = false)
128
- {
129
- if ($as_array && ($name = $this->getFromName())) {
130
- return array("$this->from" => $name);
131
- } else {
132
- return $this->from;
133
- }
134
- }
135
-
136
- public function setFromName($name)
137
- {
138
- $this->fromName = $name;
139
-
140
- return $this;
141
- }
142
-
143
- public function getFromName()
144
- {
145
- return $this->fromName;
146
- }
147
-
148
- public function setReplyTo($email)
149
- {
150
- $this->replyTo = $email;
151
-
152
- return $this;
153
- }
154
-
155
- public function getReplyTo()
156
- {
157
- return $this->replyTo;
158
- }
159
-
160
- public function setCc($email)
161
- {
162
- $this->cc = array($email);
163
-
164
- return $this;
165
- }
166
-
167
- public function setCcs(array $email_list)
168
- {
169
- $this->cc = $email_list;
170
-
171
- return $this;
172
- }
173
-
174
- public function addCc($email, $name = null)
175
- {
176
- if ($this->cc == null) {
177
- $this->cc = array();
178
- }
179
-
180
- if (is_array($email)) {
181
- foreach ($email as $e) {
182
- $this->cc[] = $e;
183
- }
184
- } else {
185
- $this->cc[] = $email;
186
- }
187
-
188
- if (is_array($name)) {
189
- foreach ($name as $n) {
190
- $this->addCcName($n);
191
- }
192
- } elseif ($name) {
193
- $this->addCcName($name);
194
- }
195
-
196
- return $this;
197
- }
198
-
199
- public function addCcName($name)
200
- {
201
- if ($this->ccName == null) {
202
- $this->ccName = array();
203
- }
204
-
205
- $this->ccName[] = $name;
206
-
207
- return $this;
208
- }
209
-
210
- public function removeCc($email)
211
- {
212
- $this->_removeFromList($this->cc, $email);
213
-
214
- return $this;
215
- }
216
-
217
- public function getCcs()
218
- {
219
- return $this->cc;
220
- }
221
-
222
- public function getCcNames()
223
- {
224
- return $this->ccName;
225
- }
226
-
227
- public function setBcc($email)
228
- {
229
- $this->bcc = array($email);
230
-
231
- return $this;
232
- }
233
-
234
- public function setBccs($email_list)
235
- {
236
- $this->bcc = $email_list;
237
-
238
- return $this;
239
- }
240
-
241
- public function addBcc($email, $name = null)
242
- {
243
- if ($this->bcc == null) {
244
- $this->bcc = array();
245
- }
246
-
247
- if (is_array($email)) {
248
- foreach ($email as $e) {
249
- $this->bcc[] = $e;
250
- }
251
- } else {
252
- $this->bcc[] = $email;
253
- }
254
-
255
- if (is_array($name)) {
256
- foreach ($name as $n) {
257
- $this->addBccName($n);
258
- }
259
- } elseif ($name) {
260
- $this->addBccName($name);
261
- }
262
-
263
- return $this;
264
- }
265
-
266
- public function addBccName($name)
267
- {
268
- if ($this->bccName == null) {
269
- $this->bccName = array();
270
- }
271
-
272
- $this->bccName[] = $name;
273
-
274
- return $this;
275
- }
276
-
277
- public function getBccNames()
278
- {
279
- return $this->bccName;
280
- }
281
-
282
- public function removeBcc($email)
283
- {
284
- $this->_removeFromList($this->bcc, $email);
285
-
286
- return $this;
287
- }
288
-
289
- public function getBccs()
290
- {
291
- return $this->bcc;
292
- }
293
-
294
- public function setSubject($subject)
295
- {
296
- $this->subject = $subject;
297
-
298
- return $this;
299
- }
300
-
301
- public function getSubject()
302
- {
303
- return $this->subject;
304
- }
305
-
306
- public function setDate($date)
307
- {
308
- $this->date = $date;
309
-
310
- return $this;
311
- }
312
-
313
- public function getDate()
314
- {
315
- return $this->date;
316
- }
317
-
318
- public function setText($text)
319
- {
320
- $this->text = $text;
321
-
322
- return $this;
323
- }
324
-
325
- public function getText()
326
- {
327
- return $this->text;
328
- }
329
-
330
- public function setHtml($html)
331
- {
332
- $this->html = $html;
333
-
334
- return $this;
335
- }
336
-
337
- public function getHtml()
338
- {
339
- return $this->html;
340
- }
341
-
342
- public function setSendAt($timestamp)
343
- {
344
- $this->smtpapi->setSendAt($timestamp);
345
-
346
- return $this;
347
- }
348
-
349
- public function setSendEachAt(array $timestamps)
350
- {
351
- $this->smtpapi->setSendEachAt($timestamps);
352
-
353
- return $this;
354
- }
355
-
356
- public function addSendEachAt($timestamp)
357
- {
358
- $this->smtpapi->addSendEachAt($timestamp);
359
-
360
- return $this;
361
- }
362
-
363
- /**
364
- * Convenience method to add template
365
- *
366
- * @param string The id of the template
367
- *
368
- * @return $this
369
- */
370
- public function setTemplateId($templateId)
371
- {
372
- $this->addFilter('templates', 'enabled', 1);
373
- $this->addFilter('templates', 'template_id', $templateId);
374
-
375
- return $this;
376
- }
377
-
378
- /** Convenience method to set asm group id
379
- *
380
- * @param string the group id
381
- *
382
- * @return $this
383
- */
384
- public function setAsmGroupId($groupId)
385
- {
386
- $this->smtpapi->setASMGroupID($groupId);
387
-
388
- return $this;
389
- }
390
-
391
- public function setAttachments(array $files)
392
- {
393
- $this->attachments = array();
394
-
395
- foreach ($files as $filename => $file) {
396
- if (is_string($filename)) {
397
- $this->addAttachment($file, $filename);
398
- } else {
399
- $this->addAttachment($file);
400
- }
401
- }
402
-
403
- return $this;
404
- }
405
-
406
- public function setAttachment($file, $custom_filename = null, $cid = null)
407
- {
408
- $this->attachments = array($this->getAttachmentInfo($file, $custom_filename, $cid));
409
-
410
- return $this;
411
- }
412
-
413
- public function addAttachment($file, $custom_filename = null, $cid = null)
414
- {
415
- $this->attachments[] = $this->getAttachmentInfo($file, $custom_filename, $cid);
416
-
417
- return $this;
418
- }
419
-
420
- public function getAttachments()
421
- {
422
- return $this->attachments;
423
- }
424
-
425
- public function removeAttachment($file)
426
- {
427
- $this->_removeFromList($this->attachments, $file, "file");
428
-
429
- return $this;
430
- }
431
-
432
- private function getAttachmentInfo($file, $custom_filename = null, $cid = null)
433
- {
434
- $info = pathinfo($file);
435
- $info['file'] = $file;
436
- if (!is_null($custom_filename)) {
437
- $info['custom_filename'] = $custom_filename;
438
- }
439
- if ($cid !== null) {
440
- $info['cid'] = $cid;
441
- }
442
-
443
- return $info;
444
- }
445
-
446
- public function setCategories($categories)
447
- {
448
- $this->smtpapi->setCategories($categories);
449
-
450
- return $this;
451
- }
452
-
453
- public function setCategory($category)
454
- {
455
- $this->smtpapi->setCategory($category);
456
-
457
- return $this;
458
- }
459
-
460
- public function addCategory($category)
461
- {
462
- $this->smtpapi->addCategory($category);
463
-
464
- return $this;
465
- }
466
-
467
- public function removeCategory($category)
468
- {
469
- $this->smtpapi->removeCategory($category);
470
-
471
- return $this;
472
- }
473
 
474
- public function setSubstitutions($key_value_pairs)
475
- {
476
- $this->smtpapi->setSubstitutions($key_value_pairs);
477
 
478
- return $this;
479
- }
 
 
 
 
 
480
 
481
- public function addSubstitution($from_value, array $to_values)
482
- {
483
- $this->smtpapi->addSubstitution($from_value, $to_values);
484
 
485
- return $this;
486
- }
487
 
488
- public function setSections(array $key_value_pairs)
489
- {
490
- $this->smtpapi->setSections($key_value_pairs);
491
 
492
- return $this;
493
- }
494
 
495
- public function addSection($from_value, $to_value)
496
- {
497
- $this->smtpapi->addSection($from_value, $to_value);
498
 
499
- return $this;
500
- }
501
 
502
- public function setUniqueArgs(array $key_value_pairs)
503
- {
504
- $this->smtpapi->setUniqueArgs($key_value_pairs);
505
 
506
- return $this;
507
- }
508
 
509
- ## synonym method
510
- public function setUniqueArguments(array $key_value_pairs)
511
- {
512
- $this->smtpapi->setUniqueArgs($key_value_pairs);
513
 
514
- return $this;
515
- }
 
 
 
 
 
516
 
517
- public function addUniqueArg($key, $value)
518
- {
519
- $this->smtpapi->addUniqueArg($key, $value);
520
-
521
- return $this;
522
- }
523
-
524
- ## synonym method
525
- public function addUniqueArgument($key, $value)
526
- {
527
- $this->smtpapi->addUniqueArg($key, $value);
528
-
529
- return $this;
530
- }
531
-
532
- public function setFilters($filter_settings)
533
- {
534
- $this->smtpapi->setFilters($filter_settings);
535
-
536
- return $this;
537
- }
538
-
539
- ## synonym method
540
- public function setFilterSettings($filter_settings)
541
- {
542
- $this->smtpapi->setFilters($filter_settings);
543
-
544
- return $this;
545
- }
546
-
547
- public function addFilter($filter_name, $parameter_name, $parameter_value)
548
- {
549
- $this->smtpapi->addFilter($filter_name, $parameter_name, $parameter_value);
550
-
551
- return $this;
552
- }
553
-
554
- ## synonym method
555
- public function addFilterSetting($filter_name, $parameter_name, $parameter_value)
556
- {
557
- $this->smtpapi->addFilter($filter_name, $parameter_name, $parameter_value);
558
-
559
- return $this;
560
- }
561
-
562
- public function getHeaders()
563
- {
564
- return $this->headers;
565
- }
566
-
567
- public function getHeadersJson()
568
- {
569
- if (count($this->getHeaders()) <= 0) {
570
- return "{}";
571
- }
572
-
573
- return json_encode($this->getHeaders(), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
574
- }
575
-
576
- public function setHeaders($key_value_pairs)
577
- {
578
- $this->headers = $key_value_pairs;
579
-
580
- return $this;
581
- }
582
-
583
- public function addHeader($key, $value)
584
- {
585
- $this->headers[$key] = $value;
586
-
587
- return $this;
588
- }
589
-
590
- public function removeHeader($key)
591
- {
592
- unset($this->headers[$key]);
593
-
594
- return $this;
595
- }
596
-
597
- public function getSmtpapi()
598
- {
599
- return $this->smtpapi;
600
- }
601
-
602
- public function toWebFormat()
603
- {
604
- $web = array(
605
- 'to' => $this->to,
606
- 'from' => $this->getFrom(),
607
- 'x-smtpapi' => $this->smtpapi->jsonString(),
608
- 'subject' => $this->getSubject(),
609
- 'text' => $this->getText(),
610
- 'html' => $this->getHtml(),
611
- 'headers' => $this->getHeadersJson(),
612
- );
613
-
614
- if ($this->getToNames()) {
615
- $web['toname'] = $this->getToNames();
616
- }
617
- if ($this->getCcs()) {
618
- $web['cc'] = $this->getCcs();
619
- }
620
- if ($this->getCcNames()) {
621
- $web['ccname'] = $this->getCcNames();
622
- }
623
- if ($this->getBccs()) {
624
- $web['bcc'] = $this->getBccs();
625
- }
626
- if ($this->getBccNames()) {
627
- $web['bccname'] = $this->getBccNames();
628
- }
629
- if ($this->getFromName()) {
630
- $web['fromname'] = $this->getFromName();
631
- }
632
- if ($this->getReplyTo()) {
633
- $web['replyto'] = $this->getReplyTo();
634
- }
635
- if ($this->getDate()) {
636
- $web['date'] = $this->getDate();
637
- }
638
- if ($this->smtpapi->to && (count($this->smtpapi->to) > 0)) {
639
- $web['to'] = "";
640
- }
641
-
642
- $web = $this->updateMissingTo($web);
643
-
644
- if ($this->getAttachments()) {
645
- foreach ($this->getAttachments() as $f) {
646
- $file = $f['file'];
647
- $extension = null;
648
- if (array_key_exists('extension', $f)) {
649
- $extension = $f['extension'];
650
- };
651
- $filename = $f['filename'];
652
- $full_filename = $filename;
653
-
654
- if (isset($extension)) {
655
- $full_filename = $filename . '.' . $extension;
656
- }
657
- if (array_key_exists('custom_filename', $f)) {
658
- $full_filename = $f['custom_filename'];
659
- }
660
-
661
- if (array_key_exists('cid', $f)) {
662
- $web['content[' . $full_filename . ']'] = $f['cid'];
663
- }
664
-
665
- $contents = '@' . $file;
666
-
667
- // Guzzle handles this for us.
668
- // http://guzzle3.readthedocs.org/en/latest/http-client/request.html#post-requests
669
- // if (class_exists('CurlFile', false)) { // php >= 5.5
670
- // $contents = new \CurlFile($file, $extension, $filename);
671
- // }
672
-
673
- $web['files[' . $full_filename . ']'] = $contents;
674
- };
675
- }
676
-
677
- return $web;
678
- }
679
-
680
- /**
681
- * There needs to be at least 1 to address, or else the mail won't send.
682
- * This method modifies the data that will be sent via either Rest
683
- */
684
- public function updateMissingTo($data)
685
- {
686
- if ($this->smtpapi->to && (count($this->smtpapi->to) > 0)) {
687
- $data['to'] = $this->getFrom();
688
- }
689
-
690
- return $data;
691
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
692
  }
4
 
5
  class Email
6
  {
7
+ public
8
+ $to,
9
+ $toName,
10
+ $from,
11
+ $fromName,
12
+ $replyTo,
13
+ $cc,
14
+ $ccName,
15
+ $bcc,
16
+ $bccName,
17
+ $subject,
18
+ $text,
19
+ $html,
20
+ $date,
21
+ $content,
22
+ $headers,
23
+ $smtpapi,
24
+ $attachments;
25
+
26
+ public function __construct() {
27
+
28
+ $this->fromName = false;
29
+ $this->replyTo = false;
30
+ $this->smtpapi = new \Smtpapi\Header();
31
+ }
32
+
33
+ /**
34
+ * _removeFromList
35
+ * Given a list of key/value pairs, removes the associated keys
36
+ * where a value matches the given string ($item)
37
+ *
38
+ * @param Array $list - the list of key/value pairs
39
+ * @param String $item - the value to be removed
40
+ */
41
+ private function _removeFromList( &$list, $item, $key_field = null ) {
42
+ foreach ( $list as $key => $val ) {
43
+ if ( $key_field ) {
44
+ if ( $val[ $key_field ] == $item ) {
45
+ unset( $list[ $key ] );
46
+ }
47
+ } else {
48
+ if ( $val == $item ) {
49
+ unset( $list[ $key ] );
50
+ }
51
+ }
52
+ }
53
+ // repack the indices
54
+ $list = array_values( $list );
55
+ }
56
+
57
+ public function addTo( $email, $name = null ) {
58
+ if ( $this->to == null ) {
59
+ $this->to = array();
60
+ }
61
+
62
+ if ( is_array( $email ) ) {
63
+ foreach ( $email as $e ) {
64
+ $this->to[] = $e;
65
+ }
66
+ } else {
67
+ $this->to[] = $email;
68
+ }
69
+
70
+ if ( is_array( $name ) ) {
71
+ foreach ( $name as $n ) {
72
+ $this->addToName( $n );
73
+ }
74
+ } elseif ( $name ) {
75
+ $this->addToName( $name );
76
+ }
77
+
78
+ return $this;
79
+ }
80
+
81
+ public function addSmtpapiTo( $email, $name = null ) {
82
+ $this->smtpapi->addTo( $email, $name );
83
+
84
+ return $this;
85
+ }
86
+
87
+ public function setTos( array $emails ) {
88
+ $this->to = $emails;
89
+
90
+ return $this;
91
+ }
92
+
93
+ public function setSmtpapiTos( array $emails ) {
94
+ $this->smtpapi->setTos( $emails );
95
+
96
+ return $this;
97
+ }
98
+
99
+ public function addToName( $name ) {
100
+ if ( $this->toName == null ) {
101
+ $this->toName = array();
102
+ }
103
+
104
+ $this->toName[] = $name;
105
+
106
+ return $this;
107
+ }
108
+
109
+ public function getToNames() {
110
+
111
+ return $this->toName;
112
+ }
113
+
114
+ public function setFrom( $email ) {
115
+ $this->from = $email;
116
+
117
+ return $this;
118
+ }
119
+
120
+ public function getFrom( $as_array = false ) {
121
+ if ( $as_array && ($name = $this->getFromName()) ) {
122
+ return array( "$this->from" => $name );
123
+ } else {
124
+ return $this->from;
125
+ }
126
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
+ public function setFromName( $name ) {
129
+ $this->fromName = $name;
 
130
 
131
+ return $this;
132
+ }
133
+
134
+ public function getFromName() {
135
+
136
+ return $this->fromName;
137
+ }
138
 
139
+ public function setReplyTo( $email ) {
140
+ $this->replyTo = $email;
 
141
 
142
+ return $this;
143
+ }
144
 
145
+ public function getReplyTo() {
 
 
146
 
147
+ return $this->replyTo;
148
+ }
149
 
150
+ public function setCc( $email ) {
151
+ $this->cc = array( $email );
 
152
 
153
+ return $this;
154
+ }
155
 
156
+ public function setCcs( array $email_list ) {
157
+ $this->cc = $email_list;
 
158
 
159
+ return $this;
160
+ }
161
 
162
+ public function addCc( $email, $name = null ) {
163
+ if ( $this->cc == null ) {
164
+ $this->cc = array();
165
+ }
166
 
167
+ if ( is_array( $email ) ) {
168
+ foreach ( $email as $e ) {
169
+ $this->cc[] = $e;
170
+ }
171
+ } else {
172
+ $this->cc[] = $email;
173
+ }
174
 
175
+ if ( is_array( $name ) ) {
176
+ foreach ( $name as $n ) {
177
+ $this->addCcName( $n );
178
+ }
179
+ } elseif ( $name ) {
180
+ $this->addCcName( $name );
181
+ }
182
+
183
+ return $this;
184
+ }
185
+
186
+ public function addCcName( $name ) {
187
+ if ( $this->ccName == null ) {
188
+ $this->ccName = array();
189
+ }
190
+
191
+ $this->ccName[] = $name;
192
+
193
+ return $this;
194
+ }
195
+
196
+ public function removeCc( $email ) {
197
+ $this->_removeFromList( $this->cc, $email );
198
+
199
+ return $this;
200
+ }
201
+
202
+ public function getCcs() {
203
+
204
+ return $this->cc;
205
+ }
206
+
207
+ public function getCcNames() {
208
+
209
+ return $this->ccName;
210
+ }
211
+
212
+ public function setBcc( $email ) {
213
+ $this->bcc = array( $email );
214
+
215
+ return $this;
216
+ }
217
+
218
+ public function setBccs( $email_list ) {
219
+ $this->bcc = $email_list;
220
+
221
+ return $this;
222
+ }
223
+
224
+ public function addBcc( $email, $name = null ) {
225
+ if ( $this->bcc == null ) {
226
+ $this->bcc = array();
227
+ }
228
+
229
+ if ( is_array( $email ) ) {
230
+ foreach ( $email as $e ) {
231
+ $this->bcc[] = $e;
232
+ }
233
+ } else {
234
+ $this->bcc[] = $email;
235
+ }
236
+
237
+ if ( is_array( $name ) ) {
238
+ foreach ( $name as $n ) {
239
+ $this->addBccName( $n );
240
+ }
241
+ } elseif ( $name ) {
242
+ $this->addBccName( $name );
243
+ }
244
+
245
+ return $this;
246
+ }
247
+
248
+ public function addBccName( $name ) {
249
+ if ( $this->bccName == null ) {
250
+ $this->bccName = array();
251
+ }
252
+
253
+ $this->bccName[] = $name;
254
+
255
+ return $this;
256
+ }
257
+
258
+ public function getBccNames() {
259
+
260
+ return $this->bccName;
261
+ }
262
+
263
+ public function removeBcc( $email ) {
264
+ $this->_removeFromList( $this->bcc, $email );
265
+
266
+ return $this;
267
+ }
268
+
269
+ public function getBccs() {
270
+
271
+ return $this->bcc;
272
+ }
273
+
274
+ public function setSubject( $subject ) {
275
+ $this->subject = $subject;
276
+
277
+ return $this;
278
+ }
279
+
280
+ public function getSubject() {
281
+
282
+ return $this->subject;
283
+ }
284
+
285
+ public function setDate( $date ) {
286
+ $this->date = $date;
287
+
288
+ return $this;
289
+ }
290
+
291
+ public function getDate() {
292
+
293
+ return $this->date;
294
+ }
295
+
296
+ public function setText( $text ) {
297
+ $this->text = $text;
298
+
299
+ return $this;
300
+ }
301
+
302
+ public function getText() {
303
+
304
+ return $this->text;
305
+ }
306
+
307
+ public function setHtml( $html ) {
308
+ $this->html = $html;
309
+
310
+ return $this;
311
+ }
312
+
313
+ public function getHtml() {
314
+
315
+ return $this->html;
316
+ }
317
+
318
+ public function setSendAt( $timestamp ) {
319
+ $this->smtpapi->setSendAt( $timestamp );
320
+
321
+ return $this;
322
+ }
323
+
324
+ public function setSendEachAt( array $timestamps ) {
325
+ $this->smtpapi->setSendEachAt( $timestamps );
326
+
327
+ return $this;
328
+ }
329
+
330
+ public function addSendEachAt( $timestamp ) {
331
+ $this->smtpapi->addSendEachAt( $timestamp );
332
+
333
+ return $this;
334
+ }
335
+
336
+ /**
337
+ * Convenience method to add template
338
+ *
339
+ * @param string The id of the template
340
+ *
341
+ * @return $this
342
+ */
343
+ public function setTemplateId( $templateId ) {
344
+ $this->addFilter( 'templates', 'enabled', 1 );
345
+ $this->addFilter( 'templates', 'template_id', $templateId );
346
+
347
+ return $this;
348
+ }
349
+
350
+ /** Convenience method to set asm group id
351
+ *
352
+ * @param string the group id
353
+ *
354
+ * @return $this
355
+ */
356
+ public function setAsmGroupId( $groupId ) {
357
+ $this->smtpapi->setASMGroupID( $groupId );
358
+
359
+ return $this;
360
+ }
361
+
362
+ public function setAttachments( array $files ) {
363
+ $this->attachments = array();
364
+
365
+ foreach ( $files as $filename => $file ) {
366
+ if ( is_string( $filename ) ) {
367
+ $this->addAttachment( $file, $filename );
368
+ } else {
369
+ $this->addAttachment( $file );
370
+ }
371
+ }
372
+
373
+ return $this;
374
+ }
375
+
376
+ public function setAttachment( $file, $custom_filename = null, $cid = null ) {
377
+ $this->attachments = array( $this->getAttachmentInfo( $file, $custom_filename, $cid ) );
378
+
379
+ return $this;
380
+ }
381
+
382
+ public function addAttachment( $file, $custom_filename = null, $cid = null ) {
383
+ $this->attachments[] = $this->getAttachmentInfo( $file, $custom_filename, $cid );
384
+
385
+ return $this;
386
+ }
387
+
388
+ public function getAttachments() {
389
+
390
+ return $this->attachments;
391
+ }
392
+
393
+ public function removeAttachment( $file ) {
394
+ $this->_removeFromList( $this->attachments, $file, 'file' );
395
+
396
+ return $this;
397
+ }
398
+
399
+ private function getAttachmentInfo( $file, $custom_filename = null, $cid = null ) {
400
+ $info = pathinfo( $file );
401
+ $info['file'] = $file;
402
+ if ( ! is_null( $custom_filename ) ) {
403
+ $info['custom_filename'] = $custom_filename;
404
+ }
405
+ if ( $cid !== null ) {
406
+ $info['cid'] = $cid;
407
+ }
408
+
409
+ return $info;
410
+ }
411
+
412
+ public function setCategories( $categories ) {
413
+ $this->smtpapi->setCategories( $categories );
414
+
415
+ return $this;
416
+ }
417
+
418
+ public function setCategory( $category ) {
419
+ $this->smtpapi->setCategory( $category );
420
+
421
+ return $this;
422
+ }
423
+
424
+ public function addCategory( $category ) {
425
+ $this->smtpapi->addCategory( $category );
426
+
427
+ return $this;
428
+ }
429
+
430
+ public function removeCategory( $category ) {
431
+ $this->smtpapi->removeCategory( $category );
432
+
433
+ return $this;
434
+ }
435
+
436
+ public function setSubstitutions( $key_value_pairs ) {
437
+ $this->smtpapi->setSubstitutions( $key_value_pairs );
438
+
439
+ return $this;
440
+ }
441
+
442
+ public function addSubstitution( $from_value, array $to_values ) {
443
+ $this->smtpapi->addSubstitution( $from_value, $to_values );
444
+
445
+ return $this;
446
+ }
447
+
448
+ public function setSections( array $key_value_pairs ) {
449
+ $this->smtpapi->setSections( $key_value_pairs );
450
+
451
+ return $this;
452
+ }
453
+
454
+ public function addSection( $from_value, $to_value ) {
455
+ $this->smtpapi->addSection( $from_value, $to_value );
456
+
457
+ return $this;
458
+ }
459
+
460
+ public function setUniqueArgs( array $key_value_pairs ) {
461
+ $this->smtpapi->setUniqueArgs( $key_value_pairs );
462
+
463
+ return $this;
464
+ }
465
+
466
+ // synonym method
467
+ public function setUniqueArguments( array $key_value_pairs ) {
468
+ $this->smtpapi->setUniqueArgs( $key_value_pairs );
469
+
470
+ return $this;
471
+ }
472
+
473
+ public function addUniqueArg( $key, $value ) {
474
+ $this->smtpapi->addUniqueArg( $key, $value );
475
+
476
+ return $this;
477
+ }
478
+
479
+ // synonym method
480
+ public function addUniqueArgument( $key, $value ) {
481
+ $this->smtpapi->addUniqueArg( $key, $value );
482
+
483
+ return $this;
484
+ }
485
+
486
+ public function setFilters( $filter_settings ) {
487
+ $this->smtpapi->setFilters( $filter_settings );
488
+
489
+ return $this;
490
+ }
491
+
492
+ // synonym method
493
+ public function setFilterSettings( $filter_settings ) {
494
+ $this->smtpapi->setFilters( $filter_settings );
495
+
496
+ return $this;
497
+ }
498
+
499
+ public function addFilter( $filter_name, $parameter_name, $parameter_value ) {
500
+ $this->smtpapi->addFilter( $filter_name, $parameter_name, $parameter_value );
501
+
502
+ return $this;
503
+ }
504
+
505
+ // synonym method
506
+ public function addFilterSetting( $filter_name, $parameter_name, $parameter_value ) {
507
+ $this->smtpapi->addFilter( $filter_name, $parameter_name, $parameter_value );
508
+
509
+ return $this;
510
+ }
511
+
512
+ public function getHeaders() {
513
+
514
+ return $this->headers;
515
+ }
516
+
517
+ public function getHeadersJson() {
518
+
519
+ if ( count( $this->getHeaders() ) <= 0 ) {
520
+ return '{}';
521
+ }
522
+
523
+ return json_encode( $this->getHeaders(), JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP );
524
+ }
525
+
526
+ public function setHeaders( $key_value_pairs ) {
527
+ $this->headers = $key_value_pairs;
528
+
529
+ return $this;
530
+ }
531
+
532
+ public function addHeader( $key, $value ) {
533
+ $this->headers[ $key ] = $value;
534
+
535
+ return $this;
536
+ }
537
+
538
+ public function removeHeader( $key ) {
539
+ unset( $this->headers[ $key ] );
540
+
541
+ return $this;
542
+ }
543
+
544
+ public function getSmtpapi() {
545
+
546
+ return $this->smtpapi;
547
+ }
548
+
549
+ public function toWebFormat() {
550
+
551
+ $web = array(
552
+ 'to' => $this->to,
553
+ 'from' => $this->getFrom(),
554
+ 'x-smtpapi' => $this->smtpapi->jsonString(),
555
+ 'subject' => $this->getSubject(),
556
+ 'text' => $this->getText(),
557
+ 'html' => $this->getHtml(),
558
+ 'headers' => $this->getHeadersJson(),
559
+ );
560
+
561
+ if ( $this->getToNames() ) {
562
+ $web['toname'] = $this->getToNames();
563
+ }
564
+ if ( $this->getCcs() ) {
565
+ $web['cc'] = $this->getCcs();
566
+ }
567
+ if ( $this->getCcNames() ) {
568
+ $web['ccname'] = $this->getCcNames();
569
+ }
570
+ if ( $this->getBccs() ) {
571
+ $web['bcc'] = $this->getBccs();
572
+ }
573
+ if ( $this->getBccNames() ) {
574
+ $web['bccname'] = $this->getBccNames();
575
+ }
576
+ if ( $this->getFromName() ) {
577
+ $web['fromname'] = $this->getFromName();
578
+ }
579
+ if ( $this->getReplyTo() ) {
580
+ $web['replyto'] = $this->getReplyTo();
581
+ }
582
+ if ( $this->getDate() ) {
583
+ $web['date'] = $this->getDate();
584
+ }
585
+ if ( $this->smtpapi->to && (count( $this->smtpapi->to ) > 0) ) {
586
+ $web['to'] = '';
587
+ }
588
+
589
+ $web = $this->updateMissingTo( $web );
590
+
591
+ if ( $this->getAttachments() ) {
592
+ foreach ( $this->getAttachments() as $f ) {
593
+ $file = $f['file'];
594
+ $extension = null;
595
+ if ( array_key_exists( 'extension', $f ) ) {
596
+ $extension = $f['extension'];
597
+ };
598
+ $filename = $f['filename'];
599
+ $full_filename = $filename;
600
+
601
+ if ( isset( $extension ) ) {
602
+ $full_filename = $filename . '.' . $extension;
603
+ }
604
+ if ( array_key_exists( 'custom_filename', $f ) ) {
605
+ $full_filename = $f['custom_filename'];
606
+ }
607
+
608
+ if ( array_key_exists( 'cid', $f ) ) {
609
+ $web[ 'content[' . $full_filename . ']' ] = $f['cid'];
610
+ }
611
+
612
+ $contents = '@' . $file;
613
+
614
+ // Guzzle handles this for us.
615
+ // http://guzzle3.readthedocs.org/en/latest/http-client/request.html#post-requests
616
+ // if (class_exists('CurlFile', false)) { // php >= 5.5
617
+ // $contents = new \CurlFile($file, $extension, $filename);
618
+ // }
619
+ $web[ 'files[' . $full_filename . ']' ] = $contents;
620
+ };
621
+ }
622
+
623
+ return $web;
624
+ }
625
+
626
+ /**
627
+ * There needs to be at least 1 to address, or else the mail won't send.
628
+ * This method modifies the data that will be sent via either Rest
629
+ */
630
+ public function updateMissingTo( $data ) {
631
+ if ( $this->smtpapi->to && (count( $this->smtpapi->to ) > 0) ) {
632
+ $data['to'] = $this->getFrom();
633
+ }
634
+
635
+ return $data;
636
+ }
637
  }
Postman/Postman-Send-Test-Email/PostmanSendTestEmailController.php CHANGED
@@ -2,43 +2,43 @@
2
  class PostmanSendTestEmailController {
3
  const EMAIL_TEST_SLUG = 'postman/email_test';
4
  const RECIPIENT_EMAIL_FIELD_NAME = 'postman_recipient_email';
5
-
6
  // logging
7
  private $logger;
8
  private $options;
9
-
10
  // Holds the values to be used in the fields callbacks
11
  private $rootPluginFilenameAndPath;
12
-
13
  /**
14
  * Constructor
15
  *
16
- * @param unknown $rootPluginFilenameAndPath
17
  */
18
- public function __construct($rootPluginFilenameAndPath) {
19
- assert ( ! empty ( $rootPluginFilenameAndPath ) );
20
- assert ( PostmanUtils::isAdmin () );
21
- assert ( is_admin () );
22
-
23
- $this->logger = new PostmanLogger ( get_class ( $this ) );
24
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
25
- $this->options = PostmanOptions::getInstance ();
26
-
27
- PostmanUtils::registerAdminMenu ( $this, 'addEmailTestSubmenu' );
28
-
29
  // hook on the init event
30
- add_action ( 'init', array (
31
  $this,
32
- 'on_init'
33
  ) );
34
-
35
  // initialize the scripts, stylesheets and form fields
36
- add_action ( 'admin_init', array (
37
  $this,
38
- 'on_admin_init'
39
  ) );
40
  }
41
-
42
  /**
43
  * Functions to execute on the init event
44
  *
@@ -47,124 +47,122 @@ class PostmanSendTestEmailController {
47
  */
48
  public function on_init() {
49
  // register Ajax handlers
50
- new PostmanSendTestEmailAjaxController ();
51
  }
52
-
53
  /**
54
  * Fires on the admin_init method
55
  */
56
  public function on_admin_init() {
57
- //
58
- $this->registerStylesAndScripts ();
59
  }
60
-
61
  /**
62
  * Get the settings option array and print one of its values
63
  */
64
  public function test_email_callback() {
65
- printf ( '<input type="text" id="%s" name="postman_test_options[test_email]" value="%s" class="required email" size="40"/>', self::RECIPIENT_EMAIL_FIELD_NAME, wp_get_current_user ()->user_email );
66
  }
67
-
68
  /**
69
  * Register and add settings
70
  */
71
  private function registerStylesAndScripts() {
72
- if ($this->logger->isTrace ()) {
73
- $this->logger->trace ( 'registerStylesAndScripts()' );
74
  }
75
-
76
- //
77
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
78
-
79
  // register the stylesheet resource
80
- wp_register_style ( 'postman_send_test_email', plugins_url ( 'Postman/Postman-Send-Test-Email/postman_send_test_email.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, $pluginData ['version'] );
81
-
82
  // register the javascript resource
83
- wp_register_script ( 'postman_test_email_wizard_script', plugins_url ( 'Postman/Postman-Send-Test-Email/postman_send_test_email.js', $this->rootPluginFilenameAndPath ), array (
84
  PostmanViewController::JQUERY_SCRIPT,
85
  'jquery_validation',
86
  'jquery_steps_script',
87
- PostmanViewController::POSTMAN_SCRIPT
88
  ), $pluginData ['version'] );
89
  }
90
-
91
  /**
92
  * Register the Email Test screen
93
  */
94
  public function addEmailTestSubmenu() {
95
- $page = add_submenu_page ( null, sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanSendTestEmailController::EMAIL_TEST_SLUG, array (
96
  $this,
97
- 'outputTestEmailContent'
98
  ) );
99
  // When the plugin options page is loaded, also load the stylesheet
100
- add_action ( 'admin_print_styles-' . $page, array (
101
  $this,
102
- 'enqueueEmailTestResources'
103
  ) );
104
  }
105
-
106
  /**
107
  */
108
  function enqueueEmailTestResources() {
109
- wp_enqueue_style ( 'jquery_steps_style' );
110
- wp_enqueue_style ( PostmanViewController::POSTMAN_STYLE );
111
- wp_enqueue_style ( 'postman_send_test_email' );
112
- wp_enqueue_script ( 'postman_test_email_wizard_script' );
113
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_email_test', array (
114
  'recipient' => '#' . self::RECIPIENT_EMAIL_FIELD_NAME,
115
- 'not_started' => _x ( 'In Outbox', 'Email Test Status', Postman::TEXT_DOMAIN ),
116
- 'sending' => _x ( 'Sending...', 'Email Test Status', Postman::TEXT_DOMAIN ),
117
- 'success' => _x ( 'Success', 'Email Test Status', Postman::TEXT_DOMAIN ),
118
- 'failed' => _x ( 'Failed', 'Email Test Status', Postman::TEXT_DOMAIN ),
119
- 'ajax_error' => __ ( 'Ajax Error', Postman::TEXT_DOMAIN )
120
  ) );
121
  }
122
-
123
  /**
124
  */
125
  public function outputTestEmailContent() {
126
  print '<div class="wrap">';
127
-
128
- PostmanViewController::outputChildPageHeader ( __ ( 'Send a Test Email', Postman::TEXT_DOMAIN ) );
129
-
130
- printf ( '<form id="postman_test_email_wizard" method="post" action="%s">', PostmanUtils::getSettingsPageUrl () );
131
-
132
  // Step 1
133
- printf ( '<h5>%s</h5>', __ ( 'Specify the Recipient', Postman::TEXT_DOMAIN ) );
134
  print '<fieldset>';
135
- printf ( '<legend>%s</legend>', __ ( 'Who is this message going to?', Postman::TEXT_DOMAIN ) );
136
- printf ( '<p>%s', __ ( 'This utility allows you to send an email message for testing.', Postman::TEXT_DOMAIN ) );
137
  print ' ';
138
  /* translators: where %d is an amount of time, in seconds */
139
- 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::TEXT_DOMAIN ), $this->options->getReadTimeout () ) );
140
- printf ( '<label for="postman_test_options[test_email]">%s</label>', _x ( 'Recipient Email Address', 'Configuration Input Field', Postman::TEXT_DOMAIN ) );
141
- print $this->test_email_callback ();
142
  print '</fieldset>';
143
-
144
  // Step 2
145
- printf ( '<h5>%s</h5>', __ ( 'Send The Message', Postman::TEXT_DOMAIN ) );
146
  print '<fieldset>';
147
  print '<legend>';
148
- print __ ( 'Sending the message:', Postman::TEXT_DOMAIN );
149
- printf ( ' <span id="postman_test_message_status">%s</span>', _x ( 'In Outbox', 'Email Test Status', Postman::TEXT_DOMAIN ) );
150
  print '</legend>';
151
  print '<section>';
152
- printf ( '<p><label>%s</label></p>', __ ( 'Status', Postman::TEXT_DOMAIN ) );
153
  print '<textarea id="postman_test_message_error_message" readonly="readonly" cols="65" rows="4"></textarea>';
154
  print '</section>';
155
  print '</fieldset>';
156
-
157
  // Step 3
158
- printf ( '<h5>%s</h5>', __ ( 'Session Transcript', Postman::TEXT_DOMAIN ) );
159
  print '<fieldset>';
160
- printf ( '<legend>%s</legend>', __ ( 'Examine the Session Transcript if you need to.', Postman::TEXT_DOMAIN ) );
161
- printf ( '<p>%s</p>', __ ( 'This is the conversation between Postman and the mail server. It can be useful for diagnosing problems. <b>DO NOT</b> post it on-line, it may contain your account password.', Postman::TEXT_DOMAIN ) );
162
  print '<section>';
163
- printf ( '<p><label for="postman_test_message_transcript">%s</label></p>', __ ( 'Session Transcript', Postman::TEXT_DOMAIN ) );
164
  print '<textarea readonly="readonly" id="postman_test_message_transcript" cols="65" rows="8"></textarea>';
165
  print '</section>';
166
  print '</fieldset>';
167
-
168
  print '</form>';
169
  print '</div>';
170
  }
@@ -173,22 +171,21 @@ class PostmanSendTestEmailController {
173
  /**
174
  *
175
  * @author jasonhendriks
176
- *
177
  */
178
  class PostmanSendTestEmailAjaxController extends PostmanAbstractAjaxHandler {
179
-
180
  /**
181
  * Constructor
182
  *
183
- * @param PostmanOptions $options
184
- * @param PostmanOAuthToken $authorizationToken
185
- * @param PostmanConfigTextHelper $oauthScribe
186
  */
187
  function __construct() {
188
- parent::__construct ();
189
- PostmanUtils::registerAjaxHandler ( 'postman_send_test_email', $this, 'sendTestEmailViaAjax' );
190
  }
191
-
192
  /**
193
  * Yes, this procedure is just for testing.
194
  *
@@ -197,92 +194,90 @@ class PostmanSendTestEmailAjaxController extends PostmanAbstractAjaxHandler {
197
  function test_mode() {
198
  return true;
199
  }
200
-
201
  /**
202
  * This Ajax sends a test email
203
  */
204
  function sendTestEmailViaAjax() {
205
  // get the email address of the recipient from the HTTP Request
206
- $email = $this->getRequestParameter ( 'email' );
207
-
208
  // get the name of the server from the HTTP Request
209
- $serverName = PostmanUtils::postmanGetServerName ();
210
-
211
  /* translators: where %s is the domain name of the site */
212
- $subject = sprintf ( _x ( 'Postman SMTP Test (%s)', 'Test Email Subject', Postman::TEXT_DOMAIN ), $serverName );
213
-
214
  // Postman API: indicate to Postman this is just for testing
215
- add_filter ( 'postman_test_email', array (
216
  $this,
217
- 'test_mode'
218
  ) );
219
-
220
  // this header specifies that there are many parts (one text part, one html part)
221
  $header = 'Content-Type: multipart/alternative;';
222
-
223
  // createt the message content
224
- $message = $this->createMessageContent ();
225
-
226
  // send the message
227
- $success = wp_mail ( $email, $subject, $message, $header );
228
-
229
  // Postman API: remove the testing indicator
230
- remove_filter ( 'postman_test_email', array (
231
  $this,
232
- 'test_mode'
233
  ) );
234
-
235
  // Postman API: retrieve the result of sending this message from Postman
236
- $result = apply_filters ( 'postman_wp_mail_result', null );
237
-
238
  // post-handling
239
- if ($success) {
240
- $this->logger->debug ( 'Test Email delivered to server' );
241
  // the message was sent successfully, generate an appropriate message for the user
242
- $statusMessage = sprintf ( __ ( 'Your message was delivered (%d ms) to the SMTP server! Congratulations :)', Postman::TEXT_DOMAIN ), $result ['time'] );
243
-
244
- //
245
- $this->logger->debug ( 'statusmessage: ' . $statusMessage );
246
-
247
  // compose the JSON response for the caller
248
- $response = array (
249
  'message' => $statusMessage,
250
- 'transcript' => $result ['transcript']
251
  );
252
-
253
  // log the response
254
- if ($this->logger->isTrace ()) {
255
- $this->logger->trace ( 'Ajax Response:' );
256
- $this->logger->trace ( $response );
257
  }
258
-
259
  // send the JSON response
260
- wp_send_json_success ( $response );
261
  } else {
262
- $this->logger->error ( 'Test Email NOT delivered to server - ' . $result ['exception']->getCode () );
263
  // the message was NOT sent successfully, generate an appropriate message for the user
264
- $statusMessage = $result ['exception']->getMessage ();
265
-
266
- //
267
- $this->logger->debug ( 'statusmessage: ' . $statusMessage );
268
-
269
  // compose the JSON response for the caller
270
- $response = array (
271
  'message' => $statusMessage,
272
- 'transcript' => $result ['transcript']
273
  );
274
-
275
  // log the response
276
- if ($this->logger->isTrace ()) {
277
- $this->logger->trace ( 'Ajax Response:' );
278
- $this->logger->trace ( $response );
279
  }
280
-
281
  // send the JSON response
282
- wp_send_json_error ( $response );
283
  }
284
  }
285
-
286
  /**
287
  * Create the multipart message content
288
  *
@@ -290,22 +285,23 @@ class PostmanSendTestEmailAjaxController extends PostmanAbstractAjaxHandler {
290
  */
291
  private function createMessageContent() {
292
  // Postman API: Get the plugin metadata
293
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
294
-
295
- /* translators: where %s is the Postman plugin version number (e.g. 1.4) */
 
296
  // English - Mandarin - French - Hindi - Spanish - Portuguese - Russian - Japanese
297
  // http://www.pinyin.info/tools/converter/chars2uninumbers.html
298
  $greeting = 'Hello! - &#20320;&#22909; - Bonjour! - &#2344;&#2350;&#2360;&#2381;&#2340;&#2375; - ¡Hola! - Ol&#225; - &#1055;&#1088;&#1080;&#1074;&#1077;&#1090;! - &#20170;&#26085;&#12399;';
299
- $sentBy = sprintf ( _x ( 'Sent by Postman %s', 'Test Email Tagline', Postman::TEXT_DOMAIN ), $pluginData ['version'] );
300
- $imageSource = __ ( 'Image source', Postman::TEXT_DOMAIN );
301
- $withPermission = __ ( 'Used with permission', Postman::TEXT_DOMAIN );
302
- $messageArray = array (
303
  'Content-Type: text/plain; charset = "UTF-8"',
304
  'Content-Transfer-Encoding: 8bit',
305
  '',
306
  'Hello!',
307
  '',
308
- sprintf ( '%s - https://wordpress.org/plugins/postman-smtp/', $sentBy ),
309
  '',
310
  'Content-Type: text/html; charset=UTF-8',
311
  'Content-Transfer-Encoding: quoted-printable',
@@ -331,23 +327,23 @@ class PostmanSendTestEmailAjaxController extends PostmanAbstractAjaxHandler {
331
  ' <tr>',
332
  ' <td>',
333
  ' <div style="max-width: 600px; height: 400px; margin: 0 auto; overflow: hidden;background-image:url(\'https://ps.w.org/postman-smtp/assets/email/poofytoo.png\');background-repeat: no-repeat;">',
334
- sprintf ( ' <div style="margin:50px 0 0 300px; width:300px; font-size:2em;">%s</div>', $greeting ),
335
- sprintf ( ' <div style="text-align:right;font-size: 1.4em; color:black;margin:150px 0 0 200px;">%s', $sentBy ),
336
- ' <br/><span style="font-size: 0.8em"><a style="color:#3f73b9" href="https://wordpress.org/plugins/postman-smtp/">https://wordpress.org/plugins/postman-smtp/</a></span>',
337
  ' </div>',
338
  ' </div>',
339
  ' </td>',
340
  ' </tr>',
341
  ' </tbody>',
342
  ' </table>',
343
- sprintf ( ' <br><span style="font-size:0.9em;color:#94c0dc;">%s: <a style="color:#94c0dc" href="http://poofytoo.com">poofytoo.com</a> - %s</span>', $imageSource, $withPermission ),
344
  ' </td>',
345
  ' </tr>',
346
  ' </tbody>',
347
  ' </table>',
348
  '</body>',
349
- '</html>'
350
  );
351
- return implode ( PostmanMessage::EOL, $messageArray );
352
  }
353
  }
2
  class PostmanSendTestEmailController {
3
  const EMAIL_TEST_SLUG = 'postman/email_test';
4
  const RECIPIENT_EMAIL_FIELD_NAME = 'postman_recipient_email';
5
+
6
  // logging
7
  private $logger;
8
  private $options;
9
+
10
  // Holds the values to be used in the fields callbacks
11
  private $rootPluginFilenameAndPath;
12
+
13
  /**
14
  * Constructor
15
  *
16
+ * @param unknown $rootPluginFilenameAndPath
17
  */
18
+ public function __construct( $rootPluginFilenameAndPath ) {
19
+ assert( ! empty( $rootPluginFilenameAndPath ) );
20
+ assert( PostmanUtils::isAdmin() );
21
+ assert( is_admin() );
22
+
23
+ $this->logger = new PostmanLogger( get_class( $this ) );
24
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
25
+ $this->options = PostmanOptions::getInstance();
26
+
27
+ PostmanUtils::registerAdminMenu( $this, 'addEmailTestSubmenu' );
28
+
29
  // hook on the init event
30
+ add_action( 'init', array(
31
  $this,
32
+ 'on_init',
33
  ) );
34
+
35
  // initialize the scripts, stylesheets and form fields
36
+ add_action( 'admin_init', array(
37
  $this,
38
+ 'on_admin_init',
39
  ) );
40
  }
41
+
42
  /**
43
  * Functions to execute on the init event
44
  *
47
  */
48
  public function on_init() {
49
  // register Ajax handlers
50
+ new PostmanSendTestEmailAjaxController();
51
  }
52
+
53
  /**
54
  * Fires on the admin_init method
55
  */
56
  public function on_admin_init() {
57
+ $this->registerStylesAndScripts();
 
58
  }
59
+
60
  /**
61
  * Get the settings option array and print one of its values
62
  */
63
  public function test_email_callback() {
64
+ printf( '<input type="text" id="%s" name="postman_test_options[test_email]" value="%s" class="required email" size="40"/>', self::RECIPIENT_EMAIL_FIELD_NAME, wp_get_current_user()->user_email );
65
  }
66
+
67
  /**
68
  * Register and add settings
69
  */
70
  private function registerStylesAndScripts() {
71
+ if ( $this->logger->isTrace() ) {
72
+ $this->logger->trace( 'registerStylesAndScripts()' );
73
  }
74
+
75
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
76
+
 
77
  // register the stylesheet resource
78
+ wp_register_style( 'postman_send_test_email', plugins_url( 'Postman/Postman-Send-Test-Email/postman_send_test_email.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, $pluginData ['version'] );
79
+
80
  // register the javascript resource
81
+ wp_register_script( 'postman_test_email_wizard_script', plugins_url( 'Postman/Postman-Send-Test-Email/postman_send_test_email.js', $this->rootPluginFilenameAndPath ), array(
82
  PostmanViewController::JQUERY_SCRIPT,
83
  'jquery_validation',
84
  'jquery_steps_script',
85
+ PostmanViewController::POSTMAN_SCRIPT,
86
  ), $pluginData ['version'] );
87
  }
88
+
89
  /**
90
  * Register the Email Test screen
91
  */
92
  public function addEmailTestSubmenu() {
93
+ $page = add_submenu_page( null, sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanSendTestEmailController::EMAIL_TEST_SLUG, array(
94
  $this,
95
+ 'outputTestEmailContent',
96
  ) );
97
  // When the plugin options page is loaded, also load the stylesheet
98
+ add_action( 'admin_print_styles-' . $page, array(
99
  $this,
100
+ 'enqueueEmailTestResources',
101
  ) );
102
  }
103
+
104
  /**
105
  */
106
  function enqueueEmailTestResources() {
107
+ wp_enqueue_style( 'jquery_steps_style' );
108
+ wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
109
+ wp_enqueue_style( 'postman_send_test_email' );
110
+ wp_enqueue_script( 'postman_test_email_wizard_script' );
111
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_email_test', array(
112
  'recipient' => '#' . self::RECIPIENT_EMAIL_FIELD_NAME,
113
+ 'not_started' => _x( 'In Outbox', 'Email Test Status', Postman::TEXT_DOMAIN ),
114
+ 'sending' => _x( 'Sending...', 'Email Test Status', Postman::TEXT_DOMAIN ),
115
+ 'success' => _x( 'Success', 'Email Test Status', Postman::TEXT_DOMAIN ),
116
+ 'failed' => _x( 'Failed', 'Email Test Status', Postman::TEXT_DOMAIN ),
117
+ 'ajax_error' => __( 'Ajax Error', Postman::TEXT_DOMAIN ),
118
  ) );
119
  }
120
+
121
  /**
122
  */
123
  public function outputTestEmailContent() {
124
  print '<div class="wrap">';
125
+
126
+ PostmanViewController::outputChildPageHeader( __( 'Send a Test Email', Postman::TEXT_DOMAIN ) );
127
+
128
+ printf( '<form id="postman_test_email_wizard" method="post" action="%s">', PostmanUtils::getSettingsPageUrl() );
129
+
130
  // Step 1
131
+ printf( '<h5>%s</h5>', __( 'Specify the Recipient', Postman::TEXT_DOMAIN ) );
132
  print '<fieldset>';
133
+ printf( '<legend>%s</legend>', __( 'Who is this message going to?', Postman::TEXT_DOMAIN ) );
134
+ printf( '<p>%s', __( 'This utility allows you to send an email message for testing.', Postman::TEXT_DOMAIN ) );
135
  print ' ';
136
  /* translators: where %d is an amount of time, in seconds */
137
+ 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::TEXT_DOMAIN ), $this->options->getReadTimeout() ) );
138
+ printf( '<label for="postman_test_options[test_email]">%s</label>', _x( 'Recipient Email Address', 'Configuration Input Field', Postman::TEXT_DOMAIN ) );
139
+ print $this->test_email_callback();
140
  print '</fieldset>';
141
+
142
  // Step 2
143
+ printf( '<h5>%s</h5>', __( 'Send The Message', Postman::TEXT_DOMAIN ) );
144
  print '<fieldset>';
145
  print '<legend>';
146
+ print __( 'Sending the message:', Postman::TEXT_DOMAIN );
147
+ printf( ' <span id="postman_test_message_status">%s</span>', _x( 'In Outbox', 'Email Test Status', Postman::TEXT_DOMAIN ) );
148
  print '</legend>';
149
  print '<section>';
150
+ printf( '<p><label>%s</label></p>', __( 'Status', Postman::TEXT_DOMAIN ) );
151
  print '<textarea id="postman_test_message_error_message" readonly="readonly" cols="65" rows="4"></textarea>';
152
  print '</section>';
153
  print '</fieldset>';
154
+
155
  // Step 3
156
+ printf( '<h5>%s</h5>', __( 'Session Transcript', Postman::TEXT_DOMAIN ) );
157
  print '<fieldset>';
158
+ printf( '<legend>%s</legend>', __( 'Examine the Session Transcript if you need to.', Postman::TEXT_DOMAIN ) );
159
+ printf( '<p>%s</p>', __( 'This is the conversation between Postman and the mail server. It can be useful for diagnosing problems. <b>DO NOT</b> post it on-line, it may contain your account password.', Postman::TEXT_DOMAIN ) );
160
  print '<section>';
161
+ printf( '<p><label for="postman_test_message_transcript">%s</label></p>', __( 'Session Transcript', Postman::TEXT_DOMAIN ) );
162
  print '<textarea readonly="readonly" id="postman_test_message_transcript" cols="65" rows="8"></textarea>';
163
  print '</section>';
164
  print '</fieldset>';
165
+
166
  print '</form>';
167
  print '</div>';
168
  }
171
  /**
172
  *
173
  * @author jasonhendriks
 
174
  */
175
  class PostmanSendTestEmailAjaxController extends PostmanAbstractAjaxHandler {
176
+
177
  /**
178
  * Constructor
179
  *
180
+ * @param PostmanOptions $options
181
+ * @param PostmanOAuthToken $authorizationToken
182
+ * @param PostmanConfigTextHelper $oauthScribe
183
  */
184
  function __construct() {
185
+ parent::__construct();
186
+ PostmanUtils::registerAjaxHandler( 'postman_send_test_email', $this, 'sendTestEmailViaAjax' );
187
  }
188
+
189
  /**
190
  * Yes, this procedure is just for testing.
191
  *
194
  function test_mode() {
195
  return true;
196
  }
197
+
198
  /**
199
  * This Ajax sends a test email
200
  */
201
  function sendTestEmailViaAjax() {
202
  // get the email address of the recipient from the HTTP Request
203
+ $email = $this->getRequestParameter( 'email' );
204
+
205
  // get the name of the server from the HTTP Request
206
+ $serverName = PostmanUtils::postmanGetServerName();
207
+
208
  /* translators: where %s is the domain name of the site */
209
+ $subject = sprintf( _x( 'Postman SMTP Test (%s)', 'Test Email Subject', Postman::TEXT_DOMAIN ), $serverName );
210
+
211
  // Postman API: indicate to Postman this is just for testing
212
+ add_filter( 'postman_test_email', array(
213
  $this,
214
+ 'test_mode',
215
  ) );
216
+
217
  // this header specifies that there are many parts (one text part, one html part)
218
  $header = 'Content-Type: multipart/alternative;';
219
+
220
  // createt the message content
221
+ $message = $this->createMessageContent();
222
+
223
  // send the message
224
+ $success = wp_mail( $email, $subject, $message, $header );
225
+
226
  // Postman API: remove the testing indicator
227
+ remove_filter( 'postman_test_email', array(
228
  $this,
229
+ 'test_mode',
230
  ) );
231
+
232
  // Postman API: retrieve the result of sending this message from Postman
233
+ $result = apply_filters( 'postman_wp_mail_result', null );
234
+
235
  // post-handling
236
+ if ( $success ) {
237
+ $this->logger->debug( 'Test Email delivered to server' );
238
  // the message was sent successfully, generate an appropriate message for the user
239
+ $statusMessage = sprintf( __( 'Your message was delivered (%d ms) to the SMTP server! Congratulations :)', Postman::TEXT_DOMAIN ), $result ['time'] );
240
+
241
+ $this->logger->debug( 'statusmessage: ' . $statusMessage );
242
+
 
243
  // compose the JSON response for the caller
244
+ $response = array(
245
  'message' => $statusMessage,
246
+ 'transcript' => $result ['transcript'],
247
  );
248
+
249
  // log the response
250
+ if ( $this->logger->isTrace() ) {
251
+ $this->logger->trace( 'Ajax Response:' );
252
+ $this->logger->trace( $response );
253
  }
254
+
255
  // send the JSON response
256
+ wp_send_json_success( $response );
257
  } else {
258
+ $this->logger->error( 'Test Email NOT delivered to server - ' . $result ['exception']->getCode() );
259
  // the message was NOT sent successfully, generate an appropriate message for the user
260
+ $statusMessage = $result ['exception']->getMessage();
261
+
262
+ $this->logger->debug( 'statusmessage: ' . $statusMessage );
263
+
 
264
  // compose the JSON response for the caller
265
+ $response = array(
266
  'message' => $statusMessage,
267
+ 'transcript' => $result ['transcript'],
268
  );
269
+
270
  // log the response
271
+ if ( $this->logger->isTrace() ) {
272
+ $this->logger->trace( 'Ajax Response:' );
273
+ $this->logger->trace( $response );
274
  }
275
+
276
  // send the JSON response
277
+ wp_send_json_error( $response );
278
  }
279
  }
280
+
281
  /**
282
  * Create the multipart message content
283
  *
285
  */
286
  private function createMessageContent() {
287
  // Postman API: Get the plugin metadata
288
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
289
+
290
+ /*
291
+ translators: where %s is the Postman plugin version number (e.g. 1.4) */
292
  // English - Mandarin - French - Hindi - Spanish - Portuguese - Russian - Japanese
293
  // http://www.pinyin.info/tools/converter/chars2uninumbers.html
294
  $greeting = 'Hello! - &#20320;&#22909; - Bonjour! - &#2344;&#2350;&#2360;&#2381;&#2340;&#2375; - ¡Hola! - Ol&#225; - &#1055;&#1088;&#1080;&#1074;&#1077;&#1090;! - &#20170;&#26085;&#12399;';
295
+ $sentBy = sprintf( _x( 'Sent by Postman %s', 'Test Email Tagline', Postman::TEXT_DOMAIN ), $pluginData ['version'] );
296
+ $imageSource = __( 'Image source', Postman::TEXT_DOMAIN );
297
+ $withPermission = __( 'Used with permission', Postman::TEXT_DOMAIN );
298
+ $messageArray = array(
299
  'Content-Type: text/plain; charset = "UTF-8"',
300
  'Content-Transfer-Encoding: 8bit',
301
  '',
302
  'Hello!',
303
  '',
304
+ sprintf( '%s - https://wordpress.org/plugins/post-smtp/', $sentBy ),
305
  '',
306
  'Content-Type: text/html; charset=UTF-8',
307
  'Content-Transfer-Encoding: quoted-printable',
327
  ' <tr>',
328
  ' <td>',
329
  ' <div style="max-width: 600px; height: 400px; margin: 0 auto; overflow: hidden;background-image:url(\'https://ps.w.org/postman-smtp/assets/email/poofytoo.png\');background-repeat: no-repeat;">',
330
+ sprintf( ' <div style="margin:50px 0 0 300px; width:300px; font-size:2em;">%s</div>', $greeting ),
331
+ sprintf( ' <div style="text-align:right;font-size: 1.4em; color:black;margin:150px 0 0 200px;">%s', $sentBy ),
332
+ ' <br/><span style="font-size: 0.8em"><a style="color:#3f73b9" href="https://wordpress.org/plugins/post-smtp/">https://wordpress.org/plugins/post-smtp/</a></span>',
333
  ' </div>',
334
  ' </div>',
335
  ' </td>',
336
  ' </tr>',
337
  ' </tbody>',
338
  ' </table>',
339
+ sprintf( ' <br><span style="font-size:0.9em;color:#94c0dc;">%s: <a style="color:#94c0dc" href="http://poofytoo.com">poofytoo.com</a> - %s</span>', $imageSource, $withPermission ),
340
  ' </td>',
341
  ' </tr>',
342
  ' </tbody>',
343
  ' </table>',
344
  '</body>',
345
+ '</html>',
346
  );
347
+ return implode( PostmanMessage::EOL, $messageArray );
348
  }
349
  }
Postman/Postman.php CHANGED
@@ -342,7 +342,7 @@ class Postman {
342
  * http://striderweb.com/nerdaphernalia/2008/06/give-your-wordpress-plugin-credit/
343
  */
344
  function print_signature() {
345
- printf( '<a href="https://wordpress.org/plugins/postman-smtp/">%s</a> %s<br/>', $this->pluginData ['name'], $this->pluginData ['version'] );
346
  }
347
 
348
  /**
342
  * http://striderweb.com/nerdaphernalia/2008/06/give-your-wordpress-plugin-credit/
343
  */
344
  function print_signature() {
345
+ printf( '<a href="https://wordpress.org/plugins/post-smtp/">%s</a> %s<br/>', $this->pluginData ['name'], $this->pluginData ['version'] );
346
  }
347
 
348
  /**
Postman/PostmanConfigTextHelper.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- if (! interface_exists ( 'PostmanConfigTextHelper' )) {
3
  interface PostmanConfigTextHelper {
4
  public function isOauthHost();
5
  public function isGoogle();
@@ -20,21 +20,21 @@ if (! interface_exists ( 'PostmanConfigTextHelper' )) {
20
  public function getEncryptionType();
21
  }
22
  }
23
- if (! class_exists ( 'PostmanAbstractConfigTextHelper' )) {
24
-
25
  /**
26
  *
27
  * @author jasonhendriks
28
  */
29
  abstract class PostmanAbstractConfigTextHelper implements PostmanConfigTextHelper {
30
  public function getOAuthHelp() {
31
- $attention = __ ( 'Attention' );
32
  /* translators: parameters available are 1=portal-url, 2=portal-name, 3=clientId-name, 4=clientSecret-name, 5=callbackUrl, 6=service-name, 7=portal-application (e.g. Open the Google Developer Console, create a Client ID for web application using the URL's displayed below, and copy the Client ID and Client Secret here.) */
33
- $errorMessage = sprintf ( __ ( 'Open the <a href="%1$s" target="_new">%2$s</a>, create <b>%7$s</b> with the values displayed below, and copy the generated %3$s and %4$s here.', Postman::TEXT_DOMAIN ), $this->getApplicationPortalUrl (), $this->getApplicationPortalName (), $this->getClientIdLabel (), $this->getClientSecretLabel (), $this->getCallbackUrlLabel (), $this->getOwnerName (), $this->getApplicationDescription () );
34
- $text = sprintf ( '<b style="color:red">%s!</b> %s', $attention, $errorMessage );
35
  /* translators: parameters available are 1=clientId-name, 2=service-name, 3=FAQ-URL, 4=Video-URL (e.g. See How do I get a Google Client ID? in the F.A.Q.) */
36
- $howToTemplate = __ ( 'See <a href="%3$s" target="_new">How do I get a %1$s %2$s?</a> in the F.A.Q. or <a href="%4$s" target="_new">watch our How-To video 📺</a>.', Postman::TEXT_DOMAIN );
37
- $text .= sprintf ( ' %s', sprintf ( $howToTemplate, $this->getOwnerName (), $this->getClientIdLabel (), 'https://wordpress.org/plugins/postman-smtp/faq/', 'https://vimeo.com/128589255' ) );
38
  return $text;
39
  }
40
  function isOauthHost() {
@@ -51,11 +51,11 @@ if (! class_exists ( 'PostmanAbstractConfigTextHelper' )) {
51
  }
52
  public function getRequestPermissionLinkText() {
53
  /* translators: where %s is the Email Service Owner (e.g. Google, Microsoft or Yahoo) */
54
- return sprintf ( _x ( 'Grant permission with %s', 'Command to initiate OAuth authentication', Postman::TEXT_DOMAIN ), $this->getOwnerName () );
55
  }
56
  }
57
  }
58
- if (! class_exists ( 'PostmanGoogleOAuthScribe' )) {
59
  class PostmanGoogleOAuthScribe extends PostmanAbstractConfigTextHelper {
60
  public function isGoogle() {
61
  return true;
@@ -65,47 +65,47 @@ if (! class_exists ( 'PostmanGoogleOAuthScribe' )) {
65
  }
66
  public function getCallbackUrl() {
67
  // see https://codex.wordpress.org/Function_Reference/admin_url#Related
68
- return admin_url ( 'options-general.php' ) . '?page=postman';
69
  }
70
  function getCallbackDomain() {
71
- $urlParts = parse_url ( $this->getCallbackUrl () );
72
- if (isset ( $urlParts ['scheme'] ) && isset ( $urlParts ['host'] )) {
73
- return $urlParts ['scheme'] . "://" . $urlParts ['host'];
74
  } else {
75
- throw new Exception ();
76
  }
77
  }
78
  public function getClientIdLabel() {
79
  /* Translators: This description is specific to Google */
80
- return _x ( 'Client ID', 'Name of the OAuth 2.0 Client ID', Postman::TEXT_DOMAIN );
81
  }
82
  public function getClientSecretLabel() {
83
  /* Translators: This description is specific to Google */
84
- return _x ( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', Postman::TEXT_DOMAIN );
85
  }
86
  public function getCallbackUrlLabel() {
87
  /* Translators: This description is specific to Google */
88
- return _x ( 'Authorized redirect URI', 'Name of the Application Callback URI', Postman::TEXT_DOMAIN );
89
  }
90
  public function getCallbackDomainLabel() {
91
  /* Translators: This description is specific to Google */
92
- return _x ( 'Authorized JavaScript origins', 'Name of the Application Callback Domain', Postman::TEXT_DOMAIN );
93
  }
94
  public function getOwnerName() {
95
  /* Translators: This description is specific to Google */
96
- return _x ( 'Google', 'Name of the email service owner', Postman::TEXT_DOMAIN );
97
  }
98
  public function getServiceName() {
99
  /* Translators: This description is specific to Google */
100
- return _x ( 'Gmail', 'Name of the email service', Postman::TEXT_DOMAIN );
101
  }
102
  public function getApplicationDescription() {
103
  /* Translators: This description is specific to Google */
104
- return _x ( 'a Client ID for web application', 'Description of the email service OAuth 2.0 Application', Postman::TEXT_DOMAIN );
105
  }
106
  public function getApplicationPortalName() {
107
  /* Translators: This description is specific to Google */
108
- return _x ( 'Google Developers Console Gmail Wizard', 'Name of the email service portal', Postman::TEXT_DOMAIN );
109
  }
110
  public function getApplicationPortalUrl() {
111
  return 'https://www.google.com/accounts/Logout?continue=https://console.developers.google.com/start/api?id=gmail';
@@ -118,7 +118,7 @@ if (! class_exists ( 'PostmanGoogleOAuthScribe' )) {
118
  }
119
  }
120
  }
121
- if (! class_exists ( 'PostmanMicrosoftOAuthScribe' )) {
122
  class PostmanMicrosoftOAuthScribe extends PostmanAbstractConfigTextHelper {
123
  public function isMicrosoft() {
124
  return true;
@@ -127,47 +127,47 @@ if (! class_exists ( 'PostmanMicrosoftOAuthScribe' )) {
127
  return true;
128
  }
129
  public function getCallbackUrl() {
130
- return admin_url ( 'options-general.php' );
131
  }
132
  function getCallbackDomain() {
133
- $urlParts = parse_url ( $this->getCallbackUrl () );
134
- if (isset ( $urlParts ['host'] )) {
135
  return $urlParts ['host'];
136
  } else {
137
- throw new Exception ();
138
  }
139
  }
140
  public function getClientIdLabel() {
141
  /* Translators: This description is specific to Microsoft */
142
- return _x ( 'Client ID', 'Name of the OAuth 2.0 Client ID', Postman::TEXT_DOMAIN );
143
  }
144
  public function getClientSecretLabel() {
145
  /* Translators: This description is specific to Microsoft */
146
- return _x ( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', Postman::TEXT_DOMAIN );
147
  }
148
  public function getCallbackUrlLabel() {
149
  /* Translators: This description is specific to Microsoft */
150
- return _x ( 'Redirect URL', 'Name of the Application Callback URI', Postman::TEXT_DOMAIN );
151
  }
152
  public function getCallbackDomainLabel() {
153
  /* Translators: This description is specific to Microsoft */
154
- return _x ( 'Root Domain', 'Name of the Application Callback Domain', Postman::TEXT_DOMAIN );
155
  }
156
  public function getOwnerName() {
157
  /* Translators: This description is specific to Microsoft */
158
- return _x ( 'Microsoft', 'Name of the email service owner', Postman::TEXT_DOMAIN );
159
  }
160
  public function getServiceName() {
161
  /* Translators: This description is specific to Microsoft */
162
- return _x ( 'Outlook.com', 'Name of the email service', Postman::TEXT_DOMAIN );
163
  }
164
  public function getApplicationDescription() {
165
  /* Translators: This description is specific to Microsoft */
166
- return _x ( 'an Application', 'Description of the email service OAuth 2.0 Application', Postman::TEXT_DOMAIN );
167
  }
168
  public function getApplicationPortalName() {
169
  /* Translators: This description is specific to Microsoft */
170
- return _x ( 'Microsoft Developer Center', 'Name of the email service portal', Postman::TEXT_DOMAIN );
171
  }
172
  public function getApplicationPortalUrl() {
173
  return 'https://account.live.com/developers/applications/index';
@@ -180,7 +180,7 @@ if (! class_exists ( 'PostmanMicrosoftOAuthScribe' )) {
180
  }
181
  }
182
  }
183
- if (! class_exists ( 'PostmanYahooOAuthScribe' )) {
184
  class PostmanYahooOAuthScribe extends PostmanAbstractConfigTextHelper {
185
  public function isYahoo() {
186
  return true;
@@ -189,47 +189,47 @@ if (! class_exists ( 'PostmanYahooOAuthScribe' )) {
189
  return true;
190
  }
191
  public function getCallbackUrl() {
192
- return admin_url ( 'options-general.php' ) . '?page=postman';
193
  }
194
  function getCallbackDomain() {
195
- $urlParts = parse_url ( $this->getCallbackUrl () );
196
- if (isset ( $urlParts ['host'] )) {
197
  return $urlParts ['host'];
198
  } else {
199
- throw new Exception ();
200
  }
201
  }
202
  public function getClientIdLabel() {
203
  /* Translators: This description is specific to Yahoo */
204
- return _x ( 'Client ID', 'Name of the OAuth 2.0 Client ID', Postman::TEXT_DOMAIN );
205
  }
206
  public function getClientSecretLabel() {
207
  /* Translators: This description is specific to Yahoo */
208
- return _x ( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', Postman::TEXT_DOMAIN );
209
  }
210
  public function getCallbackUrlLabel() {
211
  /* Translators: This description is specific to Yahoo */
212
- return _x ( 'Home Page URL', 'Name of the Application Callback URI', Postman::TEXT_DOMAIN );
213
  }
214
  public function getCallbackDomainLabel() {
215
  /* Translators: This description is specific to Yahoo */
216
- return _x ( 'Callback Domain', 'Name of the Application Callback Domain', Postman::TEXT_DOMAIN );
217
  }
218
  public function getOwnerName() {
219
  /* Translators: This description is specific to Yahoo */
220
- return _x ( 'Yahoo', 'Name of the email service owner', Postman::TEXT_DOMAIN );
221
  }
222
  public function getServiceName() {
223
  /* Translators: This description is specific to Yahoo */
224
- return _x ( 'Yahoo Mail', 'Name of the email service', Postman::TEXT_DOMAIN );
225
  }
226
  public function getApplicationDescription() {
227
  /* Translators: This description is specific to Yahoo */
228
- return _x ( 'an Application', 'Description of the email service OAuth 2.0 Application', Postman::TEXT_DOMAIN );
229
  }
230
  public function getApplicationPortalName() {
231
  /* Translators: This description is specific to Yahoo */
232
- return _x ( 'Yahoo Developer Network', 'Name of the email service portal', Postman::TEXT_DOMAIN );
233
  }
234
  public function getApplicationPortalUrl() {
235
  return 'https://developer.yahoo.com/apps/';
@@ -242,24 +242,24 @@ if (! class_exists ( 'PostmanYahooOAuthScribe' )) {
242
  }
243
  }
244
  }
245
- if (! class_exists ( 'PostmanNonOAuthScribe' )) {
246
  class PostmanNonOAuthScribe extends PostmanAbstractConfigTextHelper {
247
  protected $hostname;
248
- public function __construct($hostname) {
249
  $this->hostname = $hostname;
250
  }
251
  public function isGoogle() {
252
- return PostmanUtils::endsWith ( $this->hostname, 'gmail.com' );
253
  }
254
  public function isMicrosoft() {
255
- return PostmanUtils::endsWith ( $this->hostname, 'live.com' );
256
  }
257
  public function isYahoo() {
258
- return PostmanUtils::endsWith ( $this->hostname, 'yahoo.com' );
259
  }
260
  public function getOAuthHelp() {
261
- $text = __ ( 'Enter an Outgoing Mail Server with OAuth2 capabilities.', Postman::TEXT_DOMAIN );
262
- return sprintf ( '<span style="color:red" class="normal">%s</span>', $text );
263
  }
264
  public function getCallbackUrl() {
265
  return '';
@@ -268,16 +268,16 @@ if (! class_exists ( 'PostmanNonOAuthScribe' )) {
268
  return '';
269
  }
270
  public function getClientIdLabel() {
271
- return _x ( 'Client ID', 'Name of the OAuth 2.0 Client ID', Postman::TEXT_DOMAIN );
272
  }
273
  public function getClientSecretLabel() {
274
- return _x ( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', Postman::TEXT_DOMAIN );
275
  }
276
  public function getCallbackUrlLabel() {
277
- return _x ( 'Redirect URI', 'Name of the Application Callback URI', Postman::TEXT_DOMAIN );
278
  }
279
  public function getCallbackDomainLabel() {
280
- return _x ( 'Website Domain', 'Name of the Application Callback Domain', Postman::TEXT_DOMAIN );
281
  }
282
  public function getOwnerName() {
283
  return '';
@@ -301,7 +301,7 @@ if (! class_exists ( 'PostmanNonOAuthScribe' )) {
301
  return '';
302
  }
303
  public function getRequestPermissionLinkText() {
304
- return __ ( 'Grant OAuth 2.0 Permission', Postman::TEXT_DOMAIN );
305
  }
306
  }
307
- }
1
  <?php
2
+ if ( ! interface_exists( 'PostmanConfigTextHelper' ) ) {
3
  interface PostmanConfigTextHelper {
4
  public function isOauthHost();
5
  public function isGoogle();
20
  public function getEncryptionType();
21
  }
22
  }
23
+ if ( ! class_exists( 'PostmanAbstractConfigTextHelper' ) ) {
24
+
25
  /**
26
  *
27
  * @author jasonhendriks
28
  */
29
  abstract class PostmanAbstractConfigTextHelper implements PostmanConfigTextHelper {
30
  public function getOAuthHelp() {
31
+ $attention = __( 'Attention' );
32
  /* translators: parameters available are 1=portal-url, 2=portal-name, 3=clientId-name, 4=clientSecret-name, 5=callbackUrl, 6=service-name, 7=portal-application (e.g. Open the Google Developer Console, create a Client ID for web application using the URL's displayed below, and copy the Client ID and Client Secret here.) */
33
+ $errorMessage = sprintf( __( 'Open the <a href="%1$s" target="_new">%2$s</a>, create <b>%7$s</b> with the values displayed below, and copy the generated %3$s and %4$s here.', Postman::TEXT_DOMAIN ), $this->getApplicationPortalUrl(), $this->getApplicationPortalName(), $this->getClientIdLabel(), $this->getClientSecretLabel(), $this->getCallbackUrlLabel(), $this->getOwnerName(), $this->getApplicationDescription() );
34
+ $text = sprintf( '<b style="color:red">%s!</b> %s', $attention, $errorMessage );
35
  /* translators: parameters available are 1=clientId-name, 2=service-name, 3=FAQ-URL, 4=Video-URL (e.g. See How do I get a Google Client ID? in the F.A.Q.) */
36
+ $howToTemplate = __( 'See <a href="%3$s" target="_new">How do I get a %1$s %2$s?</a> in the F.A.Q. or <a href="%4$s" target="_new">watch our How-To video 📺</a>.', Postman::TEXT_DOMAIN );
37
+ $text .= sprintf( ' %s', sprintf( $howToTemplate, $this->getOwnerName(), $this->getClientIdLabel(), 'https://wordpress.org/plugins/post-smtp/faq/', 'https://vimeo.com/128589255' ) );
38
  return $text;
39
  }
40
  function isOauthHost() {
51
  }
52
  public function getRequestPermissionLinkText() {
53
  /* translators: where %s is the Email Service Owner (e.g. Google, Microsoft or Yahoo) */
54
+ return sprintf( _x( 'Grant permission with %s', 'Command to initiate OAuth authentication', Postman::TEXT_DOMAIN ), $this->getOwnerName() );
55
  }
56
  }
57
  }
58
+ if ( ! class_exists( 'PostmanGoogleOAuthScribe' ) ) {
59
  class PostmanGoogleOAuthScribe extends PostmanAbstractConfigTextHelper {
60
  public function isGoogle() {
61
  return true;
65
  }
66
  public function getCallbackUrl() {
67
  // see https://codex.wordpress.org/Function_Reference/admin_url#Related
68
+ return admin_url( 'options-general.php' ) . '?page=postman';
69
  }
70
  function getCallbackDomain() {
71
+ $urlParts = parse_url( $this->getCallbackUrl() );
72
+ if ( isset( $urlParts ['scheme'] ) && isset( $urlParts ['host'] ) ) {
73
+ return $urlParts ['scheme'] . '://' . $urlParts ['host'];
74
  } else {
75
+ throw new Exception();
76
  }
77
  }
78
  public function getClientIdLabel() {
79
  /* Translators: This description is specific to Google */
80
+ return _x( 'Client ID', 'Name of the OAuth 2.0 Client ID', Postman::TEXT_DOMAIN );
81
  }
82
  public function getClientSecretLabel() {
83
  /* Translators: This description is specific to Google */
84
+ return _x( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', Postman::TEXT_DOMAIN );
85
  }
86
  public function getCallbackUrlLabel() {
87
  /* Translators: This description is specific to Google */
88
+ return _x( 'Authorized redirect URI', 'Name of the Application Callback URI', Postman::TEXT_DOMAIN );
89
  }
90
  public function getCallbackDomainLabel() {
91
  /* Translators: This description is specific to Google */
92
+ return _x( 'Authorized JavaScript origins', 'Name of the Application Callback Domain', Postman::TEXT_DOMAIN );
93
  }
94
  public function getOwnerName() {
95
  /* Translators: This description is specific to Google */
96
+ return _x( 'Google', 'Name of the email service owner', Postman::TEXT_DOMAIN );
97
  }
98
  public function getServiceName() {
99
  /* Translators: This description is specific to Google */
100
+ return _x( 'Gmail', 'Name of the email service', Postman::TEXT_DOMAIN );
101
  }
102
  public function getApplicationDescription() {
103
  /* Translators: This description is specific to Google */
104
+ return _x( 'a Client ID for web application', 'Description of the email service OAuth 2.0 Application', Postman::TEXT_DOMAIN );
105
  }
106
  public function getApplicationPortalName() {
107
  /* Translators: This description is specific to Google */
108
+ return _x( 'Google Developers Console Gmail Wizard', 'Name of the email service portal', Postman::TEXT_DOMAIN );
109
  }
110
  public function getApplicationPortalUrl() {
111
  return 'https://www.google.com/accounts/Logout?continue=https://console.developers.google.com/start/api?id=gmail';
118
  }
119
  }
120
  }
121
+ if ( ! class_exists( 'PostmanMicrosoftOAuthScribe' ) ) {
122
  class PostmanMicrosoftOAuthScribe extends PostmanAbstractConfigTextHelper {
123
  public function isMicrosoft() {
124
  return true;
127
  return true;
128
  }
129
  public function getCallbackUrl() {
130
+ return admin_url( 'options-general.php' );
131
  }
132
  function getCallbackDomain() {
133
+ $urlParts = parse_url( $this->getCallbackUrl() );
134
+ if ( isset( $urlParts ['host'] ) ) {
135
  return $urlParts ['host'];
136
  } else {
137
+ throw new Exception();
138
  }
139
  }
140
  public function getClientIdLabel() {
141
  /* Translators: This description is specific to Microsoft */
142
+ return _x( 'Client ID', 'Name of the OAuth 2.0 Client ID', Postman::TEXT_DOMAIN );
143
  }
144
  public function getClientSecretLabel() {
145
  /* Translators: This description is specific to Microsoft */
146
+ return _x( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', Postman::TEXT_DOMAIN );
147
  }
148
  public function getCallbackUrlLabel() {
149
  /* Translators: This description is specific to Microsoft */
150
+ return _x( 'Redirect URL', 'Name of the Application Callback URI', Postman::TEXT_DOMAIN );
151
  }
152
  public function getCallbackDomainLabel() {
153
  /* Translators: This description is specific to Microsoft */
154
+ return _x( 'Root Domain', 'Name of the Application Callback Domain', Postman::TEXT_DOMAIN );
155
  }
156
  public function getOwnerName() {
157
  /* Translators: This description is specific to Microsoft */
158
+ return _x( 'Microsoft', 'Name of the email service owner', Postman::TEXT_DOMAIN );
159
  }
160
  public function getServiceName() {
161
  /* Translators: This description is specific to Microsoft */
162
+ return _x( 'Outlook.com', 'Name of the email service', Postman::TEXT_DOMAIN );
163
  }
164
  public function getApplicationDescription() {
165
  /* Translators: This description is specific to Microsoft */
166
+ return _x( 'an Application', 'Description of the email service OAuth 2.0 Application', Postman::TEXT_DOMAIN );
167
  }
168
  public function getApplicationPortalName() {
169
  /* Translators: This description is specific to Microsoft */
170
+ return _x( 'Microsoft Developer Center', 'Name of the email service portal', Postman::TEXT_DOMAIN );
171
  }
172
  public function getApplicationPortalUrl() {
173
  return 'https://account.live.com/developers/applications/index';
180
  }
181
  }
182
  }
183
+ if ( ! class_exists( 'PostmanYahooOAuthScribe' ) ) {
184
  class PostmanYahooOAuthScribe extends PostmanAbstractConfigTextHelper {
185
  public function isYahoo() {
186
  return true;
189
  return true;
190
  }
191
  public function getCallbackUrl() {
192
+ return admin_url( 'options-general.php' ) . '?page=postman';
193
  }
194
  function getCallbackDomain() {
195
+ $urlParts = parse_url( $this->getCallbackUrl() );
196
+ if ( isset( $urlParts ['host'] ) ) {
197
  return $urlParts ['host'];
198
  } else {
199
+ throw new Exception();
200
  }
201
  }
202
  public function getClientIdLabel() {
203
  /* Translators: This description is specific to Yahoo */
204
+ return _x( 'Client ID', 'Name of the OAuth 2.0 Client ID', Postman::TEXT_DOMAIN );
205
  }
206
  public function getClientSecretLabel() {
207
  /* Translators: This description is specific to Yahoo */
208
+ return _x( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', Postman::TEXT_DOMAIN );
209
  }
210
  public function getCallbackUrlLabel() {
211
  /* Translators: This description is specific to Yahoo */
212
+ return _x( 'Home Page URL', 'Name of the Application Callback URI', Postman::TEXT_DOMAIN );
213
  }
214
  public function getCallbackDomainLabel() {
215
  /* Translators: This description is specific to Yahoo */
216
+ return _x( 'Callback Domain', 'Name of the Application Callback Domain', Postman::TEXT_DOMAIN );
217
  }
218
  public function getOwnerName() {
219
  /* Translators: This description is specific to Yahoo */
220
+ return _x( 'Yahoo', 'Name of the email service owner', Postman::TEXT_DOMAIN );
221
  }
222
  public function getServiceName() {
223
  /* Translators: This description is specific to Yahoo */
224
+ return _x( 'Yahoo Mail', 'Name of the email service', Postman::TEXT_DOMAIN );
225
  }
226
  public function getApplicationDescription() {
227
  /* Translators: This description is specific to Yahoo */
228
+ return _x( 'an Application', 'Description of the email service OAuth 2.0 Application', Postman::TEXT_DOMAIN );
229
  }
230
  public function getApplicationPortalName() {
231
  /* Translators: This description is specific to Yahoo */
232
+ return _x( 'Yahoo Developer Network', 'Name of the email service portal', Postman::TEXT_DOMAIN );
233
  }
234
  public function getApplicationPortalUrl() {
235
  return 'https://developer.yahoo.com/apps/';
242
  }
243
  }
244
  }
245
+ if ( ! class_exists( 'PostmanNonOAuthScribe' ) ) {
246
  class PostmanNonOAuthScribe extends PostmanAbstractConfigTextHelper {
247
  protected $hostname;
248
+ public function __construct( $hostname ) {
249
  $this->hostname = $hostname;
250
  }
251
  public function isGoogle() {
252
+ return PostmanUtils::endsWith( $this->hostname, 'gmail.com' );
253
  }
254
  public function isMicrosoft() {
255
+ return PostmanUtils::endsWith( $this->hostname, 'live.com' );
256
  }
257
  public function isYahoo() {
258
+ return PostmanUtils::endsWith( $this->hostname, 'yahoo.com' );
259
  }
260
  public function getOAuthHelp() {
261
+ $text = __( 'Enter an Outgoing Mail Server with OAuth2 capabilities.', Postman::TEXT_DOMAIN );
262
+ return sprintf( '<span style="color:red" class="normal">%s</span>', $text );
263
  }
264
  public function getCallbackUrl() {
265
  return '';
268
  return '';
269
  }
270
  public function getClientIdLabel() {
271
+ return _x( 'Client ID', 'Name of the OAuth 2.0 Client ID', Postman::TEXT_DOMAIN );
272
  }
273
  public function getClientSecretLabel() {
274
+ return _x( 'Client Secret', 'Name of the OAuth 2.0 Client Secret', Postman::TEXT_DOMAIN );
275
  }
276
  public function getCallbackUrlLabel() {
277
+ return _x( 'Redirect URI', 'Name of the Application Callback URI', Postman::TEXT_DOMAIN );
278
  }
279
  public function getCallbackDomainLabel() {
280
+ return _x( 'Website Domain', 'Name of the Application Callback Domain', Postman::TEXT_DOMAIN );
281
  }
282
  public function getOwnerName() {
283
  return '';
301
  return '';
302
  }
303
  public function getRequestPermissionLinkText() {
304
+ return __( 'Grant OAuth 2.0 Permission', Postman::TEXT_DOMAIN );
305
  }
306
  }
307
+ }
Postman/PostmanOptions.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- if (! interface_exists ( "PostmanOptionsInterface" )) {
3
  interface PostmanOptionsInterface {
4
  /**
5
  * I'm stuck with these methods because of Gmail API Extension
@@ -28,24 +28,22 @@ if (! interface_exists ( "PostmanOptionsInterface" )) {
28
  public function isAuthTypePlain();
29
  public function isAuthTypeCrammd5();
30
  public function isAuthTypeNone();
31
-
32
  /**
33
  *
34
  * @deprecated
35
- *
36
  */
37
  public function getSenderEmail();
38
  /**
39
  *
40
  * @deprecated
41
- *
42
  */
43
  public function getSenderName();
44
  }
45
  }
46
 
47
- if (! class_exists ( "PostmanOptions" )) {
48
-
49
  /**
50
  * http://stackoverflow.com/questions/23880928/use-oauth-refresh-token-to-obtain-new-access-token-google-api
51
  * http://pastebin.com/jA9sBNTk
@@ -53,10 +51,10 @@ if (! class_exists ( "PostmanOptions" )) {
53
  * Make sure these emails are permitted (see http://en.wikipedia.org/wiki/E-mail_address#Internationalization):
54
  */
55
  class PostmanOptions implements PostmanOptionsInterface {
56
-
57
  // the option database name
58
  const POSTMAN_OPTIONS = 'postman_options';
59
-
60
  // the options fields
61
  const VERSION = 'version';
62
  const ENVELOPE_SENDER = 'envelope_sender';
@@ -104,7 +102,7 @@ if (! class_exists ( "PostmanOptions" )) {
104
  const TRANSCRIPT_SIZE = 'transcript_size';
105
  const TEMPORARY_DIRECTORY = 'tmp_dir';
106
  const DISABLE_EMAIL_VALIDAITON = 'disable_email_validation';
107
-
108
  // defaults
109
  const DEFAULT_TRANSCRIPT_SIZE = 128;
110
  const DEFAULT_STEALTH_MODE = false;
@@ -118,186 +116,175 @@ if (! class_exists ( "PostmanOptions" )) {
118
  const DEFAULT_PLUGIN_MESSAGE_SENDER_NAME_ENFORCED = false;
119
  const DEFAULT_PLUGIN_MESSAGE_SENDER_EMAIL_ENFORCED = false;
120
  const DEFAULT_TEMP_DIRECTORY = '/tmp';
121
-
122
  // options data
123
  private $options;
124
-
125
  // singleton instance
126
  public static function getInstance() {
127
  static $inst = null;
128
- if ($inst === null) {
129
- $inst = new PostmanOptions ();
130
  }
131
  return $inst;
132
  }
133
-
134
  /**
135
  * private constructor
136
  */
137
  private function __construct() {
138
- $this->load ();
139
  }
140
- //
141
  public function save() {
142
- update_option ( PostmanOptions::POSTMAN_OPTIONS, $this->options );
143
  }
144
  public function reload() {
145
- $this->load ();
146
  }
147
  private function load() {
148
- $this->options = get_option ( PostmanOptions::POSTMAN_OPTIONS );
149
  }
150
  public function isNew() {
151
- return ! isset ( $this->options [PostmanOptions::TRANSPORT_TYPE] );
152
  }
153
  public function isMailLoggingEnabled() {
154
- $allowed = $this->isMailLoggingAllowed ();
155
- $enabled = $this->getMailLoggingEnabled () == self::MAIL_LOG_ENABLED_OPTION_YES;
156
  return $allowed && $enabled;
157
  }
158
  public function getTempDirectory() {
159
- if (isset ( $this->options [self::TEMPORARY_DIRECTORY] ))
160
- return $this->options [self::TEMPORARY_DIRECTORY];
161
- else
162
- return self::DEFAULT_TEMP_DIRECTORY;
163
  }
164
  public function isMailLoggingAllowed() {
165
  return true;
166
  }
167
  public function isStealthModeEnabled() {
168
- if (isset ( $this->options [PostmanOptions::STEALTH_MODE] ))
169
- return $this->options [PostmanOptions::STEALTH_MODE];
170
- else
171
- return self::DEFAULT_STEALTH_MODE;
172
  }
173
  public function getMailLoggingEnabled() {
174
- if (isset ( $this->options [PostmanOptions::MAIL_LOG_ENABLED_OPTION] ))
175
- return $this->options [PostmanOptions::MAIL_LOG_ENABLED_OPTION];
176
- else
177
- return self::DEFAULT_MAIL_LOG_ENABLED;
178
  }
179
  public function getRunMode() {
180
- if (isset ( $this->options [self::RUN_MODE] ))
181
- return $this->options [self::RUN_MODE];
182
- else
183
- return self::DEFAULT_RUN_MODE;
184
  }
185
  public function getMailLoggingMaxEntries() {
186
- if (isset ( $this->options [PostmanOptions::MAIL_LOG_MAX_ENTRIES] ))
187
- return $this->options [PostmanOptions::MAIL_LOG_MAX_ENTRIES];
188
- else
189
- return self::DEFAULT_MAIL_LOG_ENTRIES;
190
  }
191
  public function getTranscriptSize() {
192
- if (isset ( $this->options [PostmanOptions::TRANSCRIPT_SIZE] ))
193
- return $this->options [PostmanOptions::TRANSCRIPT_SIZE];
194
- else
195
- return self::DEFAULT_TRANSCRIPT_SIZE;
196
  }
197
  public function getLogLevel() {
198
- if (isset ( $this->options [PostmanOptions::LOG_LEVEL] ))
199
- return $this->options [PostmanOptions::LOG_LEVEL];
200
- else
201
- return self::DEFAULT_LOG_LEVEL;
202
  }
203
  public function getForcedToRecipients() {
204
- if (isset ( $this->options [self::FORCED_TO_RECIPIENTS] ))
205
- return $this->options [self::FORCED_TO_RECIPIENTS];
206
  }
207
  public function getForcedCcRecipients() {
208
- if (isset ( $this->options [self::FORCED_CC_RECIPIENTS] ))
209
- return $this->options [self::FORCED_CC_RECIPIENTS];
210
  }
211
  public function getForcedBccRecipients() {
212
- if (isset ( $this->options [self::FORCED_BCC_RECIPIENTS] ))
213
- return $this->options [self::FORCED_BCC_RECIPIENTS];
214
  }
215
  public function getAdditionalHeaders() {
216
- if (isset ( $this->options [self::ADDITIONAL_HEADERS] ))
217
- return $this->options [self::ADDITIONAL_HEADERS];
218
  }
219
- //
220
  public function getHostname() {
221
- if (isset ( $this->options [PostmanOptions::HOSTNAME] ))
222
- return $this->options [PostmanOptions::HOSTNAME];
223
  }
224
  public function getPort() {
225
- if (isset ( $this->options [PostmanOptions::PORT] ))
226
- return $this->options [PostmanOptions::PORT];
227
  }
228
  public function getEnvelopeSender() {
229
- if (isset ( $this->options [PostmanOptions::ENVELOPE_SENDER] ))
230
- return $this->options [PostmanOptions::ENVELOPE_SENDER];
231
  }
232
  public function getMessageSenderEmail() {
233
- if (isset ( $this->options [PostmanOptions::MESSAGE_SENDER_EMAIL] ))
234
- return $this->options [PostmanOptions::MESSAGE_SENDER_EMAIL];
235
  }
236
  public function getMessageSenderName() {
237
- if (isset ( $this->options [PostmanOptions::MESSAGE_SENDER_NAME] ))
238
- return $this->options [PostmanOptions::MESSAGE_SENDER_NAME];
239
  }
240
  public function getClientId() {
241
- if (isset ( $this->options [PostmanOptions::CLIENT_ID] ))
242
- return $this->options [PostmanOptions::CLIENT_ID];
243
  }
244
  public function getClientSecret() {
245
- if (isset ( $this->options [PostmanOptions::CLIENT_SECRET] ))
246
- return $this->options [PostmanOptions::CLIENT_SECRET];
247
  }
248
  public function getTransportType() {
249
- if (isset ( $this->options [PostmanOptions::TRANSPORT_TYPE] ))
250
- return $this->options [PostmanOptions::TRANSPORT_TYPE];
251
  }
252
  public function getAuthenticationType() {
253
- if (isset ( $this->options [PostmanOptions::AUTHENTICATION_TYPE] ))
254
- return $this->options [PostmanOptions::AUTHENTICATION_TYPE];
255
  }
256
  public function getEncryptionType() {
257
- if (isset ( $this->options [PostmanOptions::SECURITY_TYPE] ))
258
- return $this->options [PostmanOptions::SECURITY_TYPE];
259
  }
260
  public function getUsername() {
261
- if (isset ( $this->options [PostmanOptions::BASIC_AUTH_USERNAME] ))
262
- return $this->options [PostmanOptions::BASIC_AUTH_USERNAME];
263
  }
264
  public function getPassword() {
265
- if (isset ( $this->options [PostmanOptions::BASIC_AUTH_PASSWORD] ))
266
- return base64_decode ( $this->options [PostmanOptions::BASIC_AUTH_PASSWORD] );
267
  }
268
  public function getMandrillApiKey() {
269
- if (isset ( $this->options [PostmanOptions::MANDRILL_API_KEY] ))
270
- return base64_decode ( $this->options [PostmanOptions::MANDRILL_API_KEY] );
271
  }
272
  public function getSendGridApiKey() {
273
- if (isset ( $this->options [PostmanOptions::SENDGRID_API_KEY] ))
274
- return base64_decode ( $this->options [PostmanOptions::SENDGRID_API_KEY] );
275
  }
276
  public function getReplyTo() {
277
- if (isset ( $this->options [PostmanOptions::REPLY_TO] ))
278
- return $this->options [PostmanOptions::REPLY_TO];
279
  }
280
  public function getConnectionTimeout() {
281
- if (! empty ( $this->options [self::CONNECTION_TIMEOUT] ))
282
- return $this->options [self::CONNECTION_TIMEOUT];
283
- else
284
- return self::DEFAULT_TCP_CONNECTION_TIMEOUT;
285
  }
286
  public function getReadTimeout() {
287
- if (! empty ( $this->options [self::READ_TIMEOUT] ))
288
- return $this->options [self::READ_TIMEOUT];
289
- else
290
- return self::DEFAULT_TCP_READ_TIMEOUT;
291
  }
292
  public function isPluginSenderNameEnforced() {
293
- if ($this->isNew ())
294
- return self::DEFAULT_PLUGIN_MESSAGE_SENDER_NAME_ENFORCED;
295
- if (isset ( $this->options [PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE] ))
296
- return $this->options [PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE];
297
  }
298
  public function isEmailValidationDisabled() {
299
- if (isset ( $this->options [PostmanOptions::DISABLE_EMAIL_VALIDAITON] ))
300
- return $this->options [PostmanOptions::DISABLE_EMAIL_VALIDAITON];
301
  }
302
  /**
303
  * (non-PHPdoc)
@@ -306,125 +293,125 @@ if (! class_exists ( "PostmanOptions" )) {
306
  * @deprecated by isPluginSenderNameEnforced
307
  */
308
  public function isSenderNameOverridePrevented() {
309
- return $this->isPluginSenderEmailEnforced ();
310
  }
311
  public function isPluginSenderEmailEnforced() {
312
- if ($this->isNew ())
313
- return self::DEFAULT_PLUGIN_MESSAGE_SENDER_EMAIL_ENFORCED;
314
- if (isset ( $this->options [PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE] ))
315
- return $this->options [PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE];
316
  }
317
  /**
318
  *
319
  * @deprecated by isPluginSenderEmailEnforced
320
  */
321
  public function isSenderEmailOverridePrevented() {
322
- return $this->isPluginSenderEmailEnforced ();
323
  }
324
- private function setSenderEmail($senderEmail) {
325
- $this->options [PostmanOptions::MESSAGE_SENDER_EMAIL] = $senderEmail;
326
  }
327
- public function setMessageSenderEmailIfEmpty($senderEmail) {
328
- if (empty ( $this->options [PostmanOptions::MESSAGE_SENDER_EMAIL] )) {
329
- $this->setSenderEmail ( $senderEmail );
330
  }
331
  }
332
- private function setSenderName($senderName) {
333
- $this->options [PostmanOptions::MESSAGE_SENDER_NAME] = $senderName;
334
  }
335
- public function setMessageSenderNameIfEmpty($senderName) {
336
- if (empty ( $this->options [PostmanOptions::MESSAGE_SENDER_NAME] )) {
337
- $this->setSenderName ( $senderName );
338
  }
339
  }
340
  public function isAuthTypePassword() {
341
- return $this->isAuthTypeLogin () || $this->isAuthTypeCrammd5 () || $this->isAuthTypePlain ();
342
  }
343
  public function isAuthTypeOAuth2() {
344
- return PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType ();
345
  }
346
  public function isAuthTypeLogin() {
347
- return PostmanOptions::AUTHENTICATION_TYPE_LOGIN == $this->getAuthenticationType ();
348
  }
349
  public function isAuthTypePlain() {
350
- return PostmanOptions::AUTHENTICATION_TYPE_PLAIN == $this->getAuthenticationType ();
351
  }
352
  public function isAuthTypeCrammd5() {
353
- return PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5 == $this->getAuthenticationType ();
354
  }
355
  public function isAuthTypeNone() {
356
- return PostmanOptions::AUTHENTICATION_TYPE_NONE == $this->getAuthenticationType ();
357
  }
358
  /**
359
  *
360
  * @deprecated Required by the Postman Gmail Extension
361
- *
362
  * @see PostmanOptionsInterface::getSenderEmail()
363
  */
364
  public function getSenderEmail() {
365
- return $this->getMessageSenderEmail ();
366
  }
367
  /**
368
  *
369
  * @deprecated Required by the Postman Gmail Extension
370
- *
371
  * @see PostmanOptionsInterface::getSenderEmail()
372
  */
373
  public function getSenderName() {
374
- return $this->getMessageNameEmail ();
375
  }
376
-
377
  /**
378
  *
379
  * @return string
380
  */
381
  public function export() {
382
- if (PostmanPreRequisitesCheck::checkZlibEncode ()) {
383
  $data = $this->options;
384
- $data ['version'] = PostmanState::getInstance ()->getVersion ();
385
- foreach ( PostmanTransportRegistry::getInstance ()->getTransports () as $transport ) {
386
- $data = $transport->prepareOptionsForExport ( $data );
387
  }
388
- $data = base64_encode ( gzcompress ( json_encode ( $data ), 9 ) );
389
  return $data;
390
  }
391
  }
392
-
393
  /**
394
  *
395
- * @param unknown $data
396
  */
397
- public function import($data) {
398
- if (PostmanPreRequisitesCheck::checkZlibEncode ()) {
399
- $logger = new PostmanLogger ( get_class ( $this ) );
400
- $logger->debug ( 'Importing Settings' );
401
  $base64 = $data;
402
- $logger->trace ( $base64 );
403
- $gz = base64_decode ( $base64 );
404
- $logger->trace ( $gz );
405
- $json = @gzuncompress ( $gz );
406
- $logger->trace ( $json );
407
- if (! empty ( $json )) {
408
- $data = json_decode ( $json, true );
409
- $logger->trace ( $data );
410
  {
411
  // overwrite the current version with the version from the imported options
412
  // this way database upgrading can occur
413
- $postmanState = get_option ( 'postman_state' );
414
  $postmanState ['version'] = $data ['version'];
415
- $logger->trace ( sprintf ( 'Setting Postman version to %s', $postmanState ['version'] ) );
416
- assert ( $postmanState ['version'] == $data ['version'] );
417
- update_option ( 'postman_state', $postmanState );
418
  }
419
  $this->options = $data;
420
- $logger->info ( 'Imported data' );
421
- $this->save ();
422
  return true;
423
  } else {
424
- $logger->error ( 'Could not import data - data error' );
425
  return false;
426
  }
427
  }
428
  }
429
  }
430
- }
1
  <?php
2
+ if ( ! interface_exists( 'PostmanOptionsInterface' ) ) {
3
  interface PostmanOptionsInterface {
4
  /**
5
  * I'm stuck with these methods because of Gmail API Extension
28
  public function isAuthTypePlain();
29
  public function isAuthTypeCrammd5();
30
  public function isAuthTypeNone();
31
+
32
  /**
33
  *
34
  * @deprecated
 
35
  */
36
  public function getSenderEmail();
37
  /**
38
  *
39
  * @deprecated
 
40
  */
41
  public function getSenderName();
42
  }
43
  }
44
 
45
+ if ( ! class_exists( 'PostmanOptions' ) ) {
46
+
47
  /**
48
  * http://stackoverflow.com/questions/23880928/use-oauth-refresh-token-to-obtain-new-access-token-google-api
49
  * http://pastebin.com/jA9sBNTk
51
  * Make sure these emails are permitted (see http://en.wikipedia.org/wiki/E-mail_address#Internationalization):
52
  */
53
  class PostmanOptions implements PostmanOptionsInterface {
54
+
55
  // the option database name
56
  const POSTMAN_OPTIONS = 'postman_options';
57
+
58
  // the options fields
59
  const VERSION = 'version';
60
  const ENVELOPE_SENDER = 'envelope_sender';
102
  const TRANSCRIPT_SIZE = 'transcript_size';
103
  const TEMPORARY_DIRECTORY = 'tmp_dir';
104
  const DISABLE_EMAIL_VALIDAITON = 'disable_email_validation';
105
+
106
  // defaults
107
  const DEFAULT_TRANSCRIPT_SIZE = 128;
108
  const DEFAULT_STEALTH_MODE = false;
116
  const DEFAULT_PLUGIN_MESSAGE_SENDER_NAME_ENFORCED = false;
117
  const DEFAULT_PLUGIN_MESSAGE_SENDER_EMAIL_ENFORCED = false;
118
  const DEFAULT_TEMP_DIRECTORY = '/tmp';
119
+
120
  // options data
121
  private $options;
122
+
123
  // singleton instance
124
  public static function getInstance() {
125
  static $inst = null;
126
+ if ( $inst === null ) {
127
+ $inst = new PostmanOptions();
128
  }
129
  return $inst;
130
  }
131
+
132
  /**
133
  * private constructor
134
  */
135
  private function __construct() {
136
+ $this->load();
137
  }
 
138
  public function save() {
139
+ update_option( PostmanOptions::POSTMAN_OPTIONS, $this->options );
140
  }
141
  public function reload() {
142
+ $this->load();
143
  }
144
  private function load() {
145
+ $this->options = get_option( PostmanOptions::POSTMAN_OPTIONS );
146
  }
147
  public function isNew() {
148
+ return ! isset( $this->options [ PostmanOptions::TRANSPORT_TYPE ] );
149
  }
150
  public function isMailLoggingEnabled() {
151
+ $allowed = $this->isMailLoggingAllowed();
152
+ $enabled = $this->getMailLoggingEnabled() == self::MAIL_LOG_ENABLED_OPTION_YES;
153
  return $allowed && $enabled;
154
  }
155
  public function getTempDirectory() {
156
+ if ( isset( $this->options [ self::TEMPORARY_DIRECTORY ] ) ) {
157
+ return $this->options [ self::TEMPORARY_DIRECTORY ];
158
+ } else { return self::DEFAULT_TEMP_DIRECTORY; }
 
159
  }
160
  public function isMailLoggingAllowed() {
161
  return true;
162
  }
163
  public function isStealthModeEnabled() {
164
+ if ( isset( $this->options [ PostmanOptions::STEALTH_MODE ] ) ) {
165
+ return $this->options [ PostmanOptions::STEALTH_MODE ];
166
+ } else { return self::DEFAULT_STEALTH_MODE; }
 
167
  }
168
  public function getMailLoggingEnabled() {
169
+ if ( isset( $this->options [ PostmanOptions::MAIL_LOG_ENABLED_OPTION ] ) ) {
170
+ return $this->options [ PostmanOptions::MAIL_LOG_ENABLED_OPTION ];
171
+ } else { return self::DEFAULT_MAIL_LOG_ENABLED; }
 
172
  }
173
  public function getRunMode() {
174
+ if ( isset( $this->options [ self::RUN_MODE ] ) ) {
175
+ return $this->options [ self::RUN_MODE ];
176
+ } else { return self::DEFAULT_RUN_MODE; }
 
177
  }
178
  public function getMailLoggingMaxEntries() {
179
+ if ( isset( $this->options [ PostmanOptions::MAIL_LOG_MAX_ENTRIES ] ) ) {
180
+ return $this->options [ PostmanOptions::MAIL_LOG_MAX_ENTRIES ];
181
+ } else { return self::DEFAULT_MAIL_LOG_ENTRIES; }
 
182
  }
183
  public function getTranscriptSize() {
184
+ if ( isset( $this->options [ PostmanOptions::TRANSCRIPT_SIZE ] ) ) {
185
+ return $this->options [ PostmanOptions::TRANSCRIPT_SIZE ];
186
+ } else { return self::DEFAULT_TRANSCRIPT_SIZE; }
 
187
  }
188
  public function getLogLevel() {
189
+ if ( isset( $this->options [ PostmanOptions::LOG_LEVEL ] ) ) {
190
+ return $this->options [ PostmanOptions::LOG_LEVEL ];
191
+ } else { return self::DEFAULT_LOG_LEVEL; }
 
192
  }
193
  public function getForcedToRecipients() {
194
+ if ( isset( $this->options [ self::FORCED_TO_RECIPIENTS ] ) ) {
195
+ return $this->options [ self::FORCED_TO_RECIPIENTS ]; }
196
  }
197
  public function getForcedCcRecipients() {
198
+ if ( isset( $this->options [ self::FORCED_CC_RECIPIENTS ] ) ) {
199
+ return $this->options [ self::FORCED_CC_RECIPIENTS ]; }
200
  }
201
  public function getForcedBccRecipients() {
202
+ if ( isset( $this->options [ self::FORCED_BCC_RECIPIENTS ] ) ) {
203
+ return $this->options [ self::FORCED_BCC_RECIPIENTS ]; }
204
  }
205
  public function getAdditionalHeaders() {
206
+ if ( isset( $this->options [ self::ADDITIONAL_HEADERS ] ) ) {
207
+ return $this->options [ self::ADDITIONAL_HEADERS ]; }
208
  }
 
209
  public function getHostname() {
210
+ if ( isset( $this->options [ PostmanOptions::HOSTNAME ] ) ) {
211
+ return $this->options [ PostmanOptions::HOSTNAME ]; }
212
  }
213
  public function getPort() {
214
+ if ( isset( $this->options [ PostmanOptions::PORT ] ) ) {
215
+ return $this->options [ PostmanOptions::PORT ]; }
216
  }
217
  public function getEnvelopeSender() {
218
+ if ( isset( $this->options [ PostmanOptions::ENVELOPE_SENDER ] ) ) {
219
+ return $this->options [ PostmanOptions::ENVELOPE_SENDER ]; }
220
  }
221
  public function getMessageSenderEmail() {
222
+ if ( isset( $this->options [ PostmanOptions::MESSAGE_SENDER_EMAIL ] ) ) {
223
+ return $this->options [ PostmanOptions::MESSAGE_SENDER_EMAIL ]; }
224
  }
225
  public function getMessageSenderName() {
226
+ if ( isset( $this->options [ PostmanOptions::MESSAGE_SENDER_NAME ] ) ) {
227
+ return $this->options [ PostmanOptions::MESSAGE_SENDER_NAME ]; }
228
  }
229
  public function getClientId() {
230
+ if ( isset( $this->options [ PostmanOptions::CLIENT_ID ] ) ) {
231
+ return $this->options [ PostmanOptions::CLIENT_ID ]; }
232
  }
233
  public function getClientSecret() {
234
+ if ( isset( $this->options [ PostmanOptions::CLIENT_SECRET ] ) ) {
235
+ return $this->options [ PostmanOptions::CLIENT_SECRET ]; }
236
  }
237
  public function getTransportType() {
238
+ if ( isset( $this->options [ PostmanOptions::TRANSPORT_TYPE ] ) ) {
239
+ return $this->options [ PostmanOptions::TRANSPORT_TYPE ]; }
240
  }
241
  public function getAuthenticationType() {
242
+ if ( isset( $this->options [ PostmanOptions::AUTHENTICATION_TYPE ] ) ) {
243
+ return $this->options [ PostmanOptions::AUTHENTICATION_TYPE ]; }
244
  }
245
  public function getEncryptionType() {
246
+ if ( isset( $this->options [ PostmanOptions::SECURITY_TYPE ] ) ) {
247
+ return $this->options [ PostmanOptions::SECURITY_TYPE ]; }
248
  }
249
  public function getUsername() {
250
+ if ( isset( $this->options [ PostmanOptions::BASIC_AUTH_USERNAME ] ) ) {
251
+ return $this->options [ PostmanOptions::BASIC_AUTH_USERNAME ]; }
252
  }
253
  public function getPassword() {
254
+ if ( isset( $this->options [ PostmanOptions::BASIC_AUTH_PASSWORD ] ) ) {
255
+ return base64_decode( $this->options [ PostmanOptions::BASIC_AUTH_PASSWORD ] ); }
256
  }
257
  public function getMandrillApiKey() {
258
+ if ( isset( $this->options [ PostmanOptions::MANDRILL_API_KEY ] ) ) {
259
+ return base64_decode( $this->options [ PostmanOptions::MANDRILL_API_KEY ] ); }
260
  }
261
  public function getSendGridApiKey() {
262
+ if ( isset( $this->options [ PostmanOptions::SENDGRID_API_KEY ] ) ) {
263
+ return base64_decode( $this->options [ PostmanOptions::SENDGRID_API_KEY ] ); }
264
  }
265
  public function getReplyTo() {
266
+ if ( isset( $this->options [ PostmanOptions::REPLY_TO ] ) ) {
267
+ return $this->options [ PostmanOptions::REPLY_TO ]; }
268
  }
269
  public function getConnectionTimeout() {
270
+ if ( ! empty( $this->options [ self::CONNECTION_TIMEOUT ] ) ) {
271
+ return $this->options [ self::CONNECTION_TIMEOUT ];
272
+ } else { return self::DEFAULT_TCP_CONNECTION_TIMEOUT; }
 
273
  }
274
  public function getReadTimeout() {
275
+ if ( ! empty( $this->options [ self::READ_TIMEOUT ] ) ) {
276
+ return $this->options [ self::READ_TIMEOUT ];
277
+ } else { return self::DEFAULT_TCP_READ_TIMEOUT; }
 
278
  }
279
  public function isPluginSenderNameEnforced() {
280
+ if ( $this->isNew() ) {
281
+ return self::DEFAULT_PLUGIN_MESSAGE_SENDER_NAME_ENFORCED; }
282
+ if ( isset( $this->options [ PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE ] ) ) {
283
+ return $this->options [ PostmanOptions::PREVENT_MESSAGE_SENDER_NAME_OVERRIDE ]; }
284
  }
285
  public function isEmailValidationDisabled() {
286
+ if ( isset( $this->options [ PostmanOptions::DISABLE_EMAIL_VALIDAITON ] ) ) {
287
+ return $this->options [ PostmanOptions::DISABLE_EMAIL_VALIDAITON ]; }
288
  }
289
  /**
290
  * (non-PHPdoc)
293
  * @deprecated by isPluginSenderNameEnforced
294
  */
295
  public function isSenderNameOverridePrevented() {
296
+ return $this->isPluginSenderEmailEnforced();
297
  }
298
  public function isPluginSenderEmailEnforced() {
299
+ if ( $this->isNew() ) {
300
+ return self::DEFAULT_PLUGIN_MESSAGE_SENDER_EMAIL_ENFORCED; }
301
+ if ( isset( $this->options [ PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE ] ) ) {
302
+ return $this->options [ PostmanOptions::PREVENT_MESSAGE_SENDER_EMAIL_OVERRIDE ]; }
303
  }
304
  /**
305
  *
306
  * @deprecated by isPluginSenderEmailEnforced
307
  */
308
  public function isSenderEmailOverridePrevented() {
309
+ return $this->isPluginSenderEmailEnforced();
310
  }
311
+ private function setSenderEmail( $senderEmail ) {
312
+ $this->options [ PostmanOptions::MESSAGE_SENDER_EMAIL ] = $senderEmail;
313
  }
314
+ public function setMessageSenderEmailIfEmpty( $senderEmail ) {
315
+ if ( empty( $this->options [ PostmanOptions::MESSAGE_SENDER_EMAIL ] ) ) {
316
+ $this->setSenderEmail( $senderEmail );
317
  }
318
  }
319
+ private function setSenderName( $senderName ) {
320
+ $this->options [ PostmanOptions::MESSAGE_SENDER_NAME ] = $senderName;
321
  }
322
+ public function setMessageSenderNameIfEmpty( $senderName ) {
323
+ if ( empty( $this->options [ PostmanOptions::MESSAGE_SENDER_NAME ] ) ) {
324
+ $this->setSenderName( $senderName );
325
  }
326
  }
327
  public function isAuthTypePassword() {
328
+ return $this->isAuthTypeLogin() || $this->isAuthTypeCrammd5() || $this->isAuthTypePlain();
329
  }
330
  public function isAuthTypeOAuth2() {
331
+ return PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType();
332
  }
333
  public function isAuthTypeLogin() {
334
+ return PostmanOptions::AUTHENTICATION_TYPE_LOGIN == $this->getAuthenticationType();
335
  }
336
  public function isAuthTypePlain() {
337
+ return PostmanOptions::AUTHENTICATION_TYPE_PLAIN == $this->getAuthenticationType();
338
  }
339
  public function isAuthTypeCrammd5() {
340
+ return PostmanOptions::AUTHENTICATION_TYPE_CRAMMD5 == $this->getAuthenticationType();
341
  }
342
  public function isAuthTypeNone() {
343
+ return PostmanOptions::AUTHENTICATION_TYPE_NONE == $this->getAuthenticationType();
344
  }
345
  /**
346
  *
347
  * @deprecated Required by the Postman Gmail Extension
348
+ *
349
  * @see PostmanOptionsInterface::getSenderEmail()
350
  */
351
  public function getSenderEmail() {
352
+ return $this->getMessageSenderEmail();
353
  }
354
  /**
355
  *
356
  * @deprecated Required by the Postman Gmail Extension
357
+ *
358
  * @see PostmanOptionsInterface::getSenderEmail()
359
  */
360
  public function getSenderName() {
361
+ return $this->getMessageNameEmail();
362
  }
363
+
364
  /**
365
  *
366
  * @return string
367
  */
368
  public function export() {
369
+ if ( PostmanPreRequisitesCheck::checkZlibEncode() ) {
370
  $data = $this->options;
371
+ $data ['version'] = PostmanState::getInstance()->getVersion();
372
+ foreach ( PostmanTransportRegistry::getInstance()->getTransports() as $transport ) {
373
+ $data = $transport->prepareOptionsForExport( $data );
374
  }
375
+ $data = base64_encode( gzcompress( json_encode( $data ), 9 ) );
376
  return $data;
377
  }
378
  }
379
+
380
  /**
381
  *
382
+ * @param unknown $data
383
  */
384
+ public function import( $data ) {
385
+ if ( PostmanPreRequisitesCheck::checkZlibEncode() ) {
386
+ $logger = new PostmanLogger( get_class( $this ) );
387
+ $logger->debug( 'Importing Settings' );
388
  $base64 = $data;
389
+ $logger->trace( $base64 );
390
+ $gz = base64_decode( $base64 );
391
+ $logger->trace( $gz );
392
+ $json = @gzuncompress( $gz );
393
+ $logger->trace( $json );
394
+ if ( ! empty( $json ) ) {
395
+ $data = json_decode( $json, true );
396
+ $logger->trace( $data );
397
  {
398
  // overwrite the current version with the version from the imported options
399
  // this way database upgrading can occur
400
+ $postmanState = get_option( 'postman_state' );
401
  $postmanState ['version'] = $data ['version'];
402
+ $logger->trace( sprintf( 'Setting Postman version to %s', $postmanState ['version'] ) );
403
+ assert( $postmanState ['version'] == $data ['version'] );
404
+ update_option( 'postman_state', $postmanState );
405
  }
406
  $this->options = $data;
407
+ $logger->info( 'Imported data' );
408
+ $this->save();
409
  return true;
410
  } else {
411
+ $logger->error( 'Could not import data - data error' );
412
  return false;
413
  }
414
  }
415
  }
416
  }
417
+ }
Postman/PostmanViewController.php CHANGED
@@ -1,5 +1,5 @@
1
  <?php
2
- if (! class_exists ( 'PostmanViewController' )) {
3
  class PostmanViewController {
4
  private $logger;
5
  private $rootPluginFilenameAndPath;
@@ -9,294 +9,292 @@ if (! class_exists ( 'PostmanViewController' )) {
9
  private $importableConfiguration;
10
  private $adminController;
11
  const POSTMAN_MENU_SLUG = 'postman';
12
-
13
  // style sheets and scripts
14
  const POSTMAN_STYLE = 'postman_style';
15
  const JQUERY_SCRIPT = 'jquery';
16
  const POSTMAN_SCRIPT = 'postman_script';
17
-
18
- //
19
- const BACK_ARROW_SYMBOL = '&#11013;';
20
-
21
  /**
22
  * Constructor
23
  *
24
- * @param PostmanOptions $options
25
- * @param PostmanOAuthToken $authorizationToken
26
- * @param PostmanConfigTextHelper $oauthScribe
27
  */
28
- function __construct($rootPluginFilenameAndPath, PostmanOptions $options, PostmanOAuthToken $authorizationToken, PostmanConfigTextHelper $oauthScribe, PostmanAdminController $adminController) {
29
  $this->options = $options;
30
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
31
  $this->authorizationToken = $authorizationToken;
32
  $this->oauthScribe = $oauthScribe;
33
  $this->adminController = $adminController;
34
- $this->logger = new PostmanLogger ( get_class ( $this ) );
35
- PostmanUtils::registerAdminMenu ( $this, 'generateDefaultContent' );
36
- PostmanUtils::registerAdminMenu ( $this, 'addPurgeDataSubmenu' );
37
-
38
  // initialize the scripts, stylesheets and form fields
39
- add_action ( 'admin_init', array (
40
  $this,
41
- 'registerStylesAndScripts'
42
  ), 0 );
43
  }
44
- public static function getPageUrl($slug) {
45
- return PostmanUtils::getPageUrl ( $slug );
46
  }
47
-
48
  /**
49
  * Add options page
50
  */
51
  public function generateDefaultContent() {
52
  // This page will be under "Settings"
53
- $pageTitle = sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) );
54
- $pluginName = __ ( 'Postman SMTP', Postman::TEXT_DOMAIN );
55
  $uniqueId = self::POSTMAN_MENU_SLUG;
56
- $pageOptions = array (
57
  $this,
58
- 'outputDefaultContent'
59
  );
60
- $mainPostmanSettingsPage = add_options_page ( $pageTitle, $pluginName, Postman::MANAGE_POSTMAN_CAPABILITY_NAME, $uniqueId, $pageOptions );
61
  // When the plugin options page is loaded, also load the stylesheet
62
- add_action ( 'admin_print_styles-' . $mainPostmanSettingsPage, array (
63
  $this,
64
- 'enqueueHomeScreenStylesheet'
65
  ) );
66
  }
67
  function enqueueHomeScreenStylesheet() {
68
- wp_enqueue_style ( PostmanViewController::POSTMAN_STYLE );
69
- wp_enqueue_script ( 'postman_script' );
70
  }
71
-
72
  /**
73
  * Register the Email Test screen
74
  */
75
  public function addPurgeDataSubmenu() {
76
- $page = add_submenu_page ( null, sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanAdminController::MANAGE_OPTIONS_PAGE_SLUG, array (
77
  $this,
78
- 'outputPurgeDataContent'
79
  ) );
80
  // When the plugin options page is loaded, also load the stylesheet
81
- add_action ( 'admin_print_styles-' . $page, array (
82
  $this,
83
- 'enqueueHomeScreenStylesheet'
84
  ) );
85
  }
86
-
87
  /**
88
  * Register and add settings
89
  */
90
  public function registerStylesAndScripts() {
91
- if ($this->logger->isTrace ()) {
92
- $this->logger->trace ( 'registerStylesAndScripts()' );
93
  }
94
  // register the stylesheet and javascript external resources
95
- $pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
96
- wp_register_style ( PostmanViewController::POSTMAN_STYLE, plugins_url ( 'style/postman.css', $this->rootPluginFilenameAndPath ), null, $pluginData ['version'] );
97
- wp_register_style ( 'jquery_ui_style', plugins_url ( 'style/jquery-steps/jquery-ui.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, '1.1.0' );
98
- wp_register_style ( 'jquery_steps_style', plugins_url ( 'style/jquery-steps/jquery.steps.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, '1.1.0' );
99
-
100
- wp_register_script ( PostmanViewController::POSTMAN_SCRIPT, plugins_url ( 'script/postman.js', $this->rootPluginFilenameAndPath ), array (
101
- PostmanViewController::JQUERY_SCRIPT
102
  ), $pluginData ['version'] );
103
- wp_register_script ( 'sprintf', plugins_url ( 'script/sprintf/sprintf.min.js', $this->rootPluginFilenameAndPath ), null, '1.0.2' );
104
- wp_register_script ( 'jquery_steps_script', plugins_url ( 'script/jquery-steps/jquery.steps.min.js', $this->rootPluginFilenameAndPath ), array (
105
- PostmanViewController::JQUERY_SCRIPT
106
  ), '1.1.0' );
107
- wp_register_script ( 'jquery_validation', plugins_url ( 'script/jquery-validate/jquery.validate.min.js', $this->rootPluginFilenameAndPath ), array (
108
- PostmanViewController::JQUERY_SCRIPT
109
  ), '1.13.1' );
110
 
111
- wp_localize_script ( PostmanViewController::POSTMAN_SCRIPT, 'postman_ajax_msg', array (
112
- 'bad_response' => __ ( 'An unexpected error occurred', Postman::TEXT_DOMAIN ),
113
- 'corrupt_response' => __ ( 'Unexpected PHP messages corrupted the Ajax response', Postman::TEXT_DOMAIN )
114
  ) );
115
-
116
- wp_localize_script ( 'jquery_steps_script', 'steps_current_step', 'steps_current_step' );
117
- wp_localize_script ( 'jquery_steps_script', 'steps_pagination', 'steps_pagination' );
118
- wp_localize_script ( 'jquery_steps_script', 'steps_finish', _x ( 'Finish', 'Press this button to Finish this task', Postman::TEXT_DOMAIN ) );
119
- wp_localize_script ( 'jquery_steps_script', 'steps_next', _x ( 'Next', 'Press this button to go to the next step', Postman::TEXT_DOMAIN ) );
120
- wp_localize_script ( 'jquery_steps_script', 'steps_previous', _x ( 'Previous', 'Press this button to go to the previous step', Postman::TEXT_DOMAIN ) );
121
- wp_localize_script ( 'jquery_steps_script', 'steps_loading', 'steps_loading' );
122
  }
123
-
124
  /**
125
  * Options page callback
126
  */
127
  public function outputDefaultContent() {
128
  // Set class property
129
  print '<div class="wrap">';
130
- $this->displayTopNavigation ();
131
- if (! PostmanPreRequisitesCheck::isReady ()) {
132
- printf ( '<p><span style="color:red; padding:2px 0; font-size:1.1em">%s</span></p>', __ ( 'Postman is unable to run. Email delivery is being handled by WordPress (or another plugin).', Postman::TEXT_DOMAIN ) );
133
  } else {
134
- $statusMessage = PostmanTransportRegistry::getInstance ()->getReadyMessage ();
135
- if (PostmanTransportRegistry::getInstance ()->getActiveTransport ()->isConfiguredAndReady ()) {
136
- if ($this->options->getRunMode () != PostmanOptions::RUN_MODE_PRODUCTION) {
137
- printf ( '<p><span style="background-color:yellow">%s</span></p>', $statusMessage );
138
  } else {
139
- printf ( '<p><span style="color:green;padding:2px 0; font-size:1.1em">%s</span></p>', $statusMessage );
140
  }
141
  } else {
142
- printf ( '<p><span style="color:red; padding:2px 0; font-size:1.1em">%s</span></p>', $statusMessage );
143
  }
144
- $this->printDeliveryDetails ();
145
  /* translators: where %d is the number of emails delivered */
146
  print '<p style="margin:10px 10px"><span>';
147
- printf ( _n ( 'Postman has delivered <span style="color:green">%d</span> email.', 'Postman has delivered <span style="color:green">%d</span> emails.', PostmanState::getInstance ()->getSuccessfulDeliveries (), Postman::TEXT_DOMAIN ), PostmanState::getInstance ()->getSuccessfulDeliveries () );
148
- if ($this->options->isMailLoggingEnabled ()) {
149
  print ' ';
150
- printf ( __ ( 'The last %d email attempts are recorded <a href="%s">in the log</a>.', Postman::TEXT_DOMAIN ), PostmanOptions::getInstance ()->getMailLoggingMaxEntries (), PostmanUtils::getEmailLogPageUrl () );
151
  }
152
  print '</span></p>';
153
  }
154
- if ($this->options->isNew ()) {
155
- printf ( '<h3 style="padding-top:10px">%s</h3>', __ ( 'Thank-you for choosing Postman!', Postman::TEXT_DOMAIN ) );
156
  /* translators: where %s is the URL of the Setup Wizard */
157
- printf ( '<p><span>%s</span></p>', sprintf ( __ ( 'Let\'s get started! All users are strongly encouraged to <a href="%s">run the Setup Wizard</a>.', Postman::TEXT_DOMAIN ), $this->getPageUrl ( PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG ) ) );
158
- printf ( '<p><span>%s</span></p>', sprintf ( __ ( 'Alternately, <a href="%s">manually configure</a> your own settings and/or modify advanced options.', Postman::TEXT_DOMAIN ), $this->getPageUrl ( PostmanConfigurationController::CONFIGURATION_SLUG ) ) );
159
  } else {
160
- if (PostmanState::getInstance ()->isTimeToReviewPostman () && ! PostmanOptions::getInstance ()->isNew ()) {
161
  print '</br><hr width="70%"></br>';
162
  /* translators: where %s is the URL to the WordPress.org review and ratings page */
163
- printf ( '%s</span></p>', sprintf ( __ ( 'Please consider <a href="%s">leaving a review</a> to help spread the word! :D', Postman::TEXT_DOMAIN ), 'https://wordpress.org/support/view/plugin-reviews/postman-smtp?filter=5' ) );
164
  }
165
- printf ( '<p><span>%s :-)</span></p>', sprintf ( __ ( 'Postman needs translators! Please take a moment to <a href="%s">translate a few sentences on-line</a>', Postman::TEXT_DOMAIN ), 'https://translate.wordpress.org/projects/wp-plugins/postman-smtp/stable' ) );
166
  }
167
- printf ( '<p><span>%s</span></p>', __ ( '<b style="background-color:yellow">New for v1.7!</style></b> Send mail with the Mandrill or SendGrid APIs.', Postman::TEXT_DOMAIN ) );
168
  }
169
-
170
  /**
171
  */
172
  private function printDeliveryDetails() {
173
- $currentTransport = PostmanTransportRegistry::getInstance ()->getActiveTransport ();
174
- $deliveryDetails = $currentTransport->getDeliveryDetails ( $this->options );
175
- printf ( '<p style="margin:0 10px"><span>%s</span></p>', $deliveryDetails );
176
  }
177
-
178
  /**
179
  *
180
- * @param unknown $title
181
- * @param string $slug
182
  */
183
- public static function outputChildPageHeader($title, $slug = '') {
184
- printf ( '<h2>%s</h2>', sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) ) );
185
- printf ( '<div id="postman-main-menu" class="welcome-panel %s">', $slug );
186
  print '<div class="welcome-panel-content">';
187
  print '<div class="welcome-panel-column-container">';
188
  print '<div class="welcome-panel-column welcome-panel-last">';
189
- printf ( '<h4>%s</h4>', $title );
190
  print '</div>';
191
- printf ( '<p id="back_to_main_menu">%s <a id="back_to_menu_link" href="%s">%s</a></p>', self::BACK_ARROW_SYMBOL, PostmanUtils::getSettingsPageUrl (), _x ( 'Back To Main Menu', 'Return to main menu link', Postman::TEXT_DOMAIN ) );
192
  print '</div></div></div>';
193
  }
194
-
195
  /**
196
  */
197
  public function outputPurgeDataContent() {
198
- $importTitle = __ ( 'Import', Postman::TEXT_DOMAIN );
199
- $exportTile = __ ( 'Export', Postman::TEXT_DOMAIN );
200
- $resetTitle = __ ( 'Reset Plugin', Postman::TEXT_DOMAIN );
201
  $options = $this->options;
202
  print '<div class="wrap">';
203
- PostmanViewController::outputChildPageHeader ( sprintf ( '%s/%s/%s', $importTitle, $exportTile, $resetTitle ) );
204
  print '<section id="export_settings">';
205
- printf ( '<h3><span>%s<span></h3>', $exportTile );
206
- printf ( '<p><span>%s</span></p>', __ ( 'Copy this data into another instance of Postman to duplicate the configuration.', Postman::TEXT_DOMAIN ) );
207
  $data = '';
208
- if (! PostmanPreRequisitesCheck::checkZlibEncode ()) {
209
- $extraDeleteButtonAttributes = sprintf ( 'disabled="true"' );
210
  $data = '';
211
  } else {
212
  $extraDeleteButtonAttributes = '';
213
- if (! $options->isNew ()) {
214
- $data = $options->export ();
215
  }
216
  }
217
- printf ( '<textarea cols="80" rows="5" readonly="true" name="settings" %s>%s</textarea>', $extraDeleteButtonAttributes, $data );
218
  print '</section>';
219
  print '<section id="import_settings">';
220
- printf ( '<h3><span>%s<span></h3>', $importTitle );
221
- print '<form method="POST" action="' . get_admin_url () . 'admin-post.php">';
222
- wp_nonce_field ( PostmanAdminController::IMPORT_SETTINGS_SLUG );
223
- printf ( '<input type="hidden" name="action" value="%s" />', PostmanAdminController::IMPORT_SETTINGS_SLUG );
224
  print '<p>';
225
- printf ( '<span>%s</span>', __ ( 'Paste data from another instance of Postman here to duplicate the configuration.', Postman::TEXT_DOMAIN ) );
226
- if (PostmanTransportRegistry::getInstance ()->getSelectedTransport ()->isOAuthUsed ( PostmanOptions::getInstance ()->getAuthenticationType () )) {
227
- $warning = __ ( 'Warning', Postman::TEXT_DOMAIN );
228
- $errorMessage = __ ( 'Using the same OAuth 2.0 Client ID and Client Secret from this site at the same time as another site will cause failures.', Postman::TEXT_DOMAIN );
229
- printf ( ' <span><b>%s</b>: %s</span>', $warning, $errorMessage );
230
  }
231
  print '</p>';
232
- printf ( '<textarea cols="80" rows="5" name="settings" %s></textarea>', $extraDeleteButtonAttributes );
233
- submit_button ( __ ( 'Import', Postman::TEXT_DOMAIN ), 'primary', 'import', true, $extraDeleteButtonAttributes );
234
  print '</form>';
235
  print '</section>';
236
  print '<section id="delete_settings">';
237
- printf ( '<h3><span>%s<span></h3>', $resetTitle );
238
- print '<form method="POST" action="' . get_admin_url () . 'admin-post.php">';
239
- wp_nonce_field ( PostmanAdminController::PURGE_DATA_SLUG );
240
- printf ( '<input type="hidden" name="action" value="%s" />', PostmanAdminController::PURGE_DATA_SLUG );
241
- printf ( '<p><span>%s</span></p><p><span>%s</span></p>', __ ( 'This will purge all of Postman\'s settings, including account credentials and the email log.', Postman::TEXT_DOMAIN ), __ ( 'Are you sure?', Postman::TEXT_DOMAIN ) );
242
  $extraDeleteButtonAttributes = 'style="background-color:red;color:white"';
243
- if ($this->options->isNew ()) {
244
  $extraDeleteButtonAttributes .= ' disabled="true"';
245
  }
246
- submit_button ( $resetTitle, 'delete', 'submit', true, $extraDeleteButtonAttributes );
247
  print '</form>';
248
  print '</section>';
249
  print '</div>';
250
  }
251
-
252
  /**
253
  */
254
  private function displayTopNavigation() {
255
- screen_icon ();
256
- printf ( '<h2>%s</h2>', sprintf ( __ ( '%s Setup', Postman::TEXT_DOMAIN ), __ ( 'Postman SMTP', Postman::TEXT_DOMAIN ) ) );
257
  print '<div id="postman-main-menu" class="welcome-panel">';
258
  print '<div class="welcome-panel-content">';
259
  print '<div class="welcome-panel-column-container">';
260
  print '<div class="welcome-panel-column">';
261
- printf ( '<h4>%s</h4>', __ ( 'Configuration', Postman::TEXT_DOMAIN ) );
262
- printf ( '<a class="button button-primary button-hero" href="%s">%s</a>', $this->getPageUrl ( PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG ), __ ( 'Start the Wizard', Postman::TEXT_DOMAIN ) );
263
- printf ( '<p class="">or <a href="%s" class="configure_manually">%s</a></p>', $this->getPageUrl ( PostmanConfigurationController::CONFIGURATION_SLUG ), __ ( 'Show All Settings', Postman::TEXT_DOMAIN ) );
264
  print '</div>';
265
  print '<div class="welcome-panel-column">';
266
- printf ( '<h4>%s</h4>', _x ( 'Actions', 'Main Menu', Postman::TEXT_DOMAIN ) );
267
  print '<ul>';
268
-
269
  // Grant permission with Google
270
- PostmanTransportRegistry::getInstance ()->getSelectedTransport ()->printActionMenuItem ();
271
-
272
- if (PostmanWpMailBinder::getInstance ()->isBound ()) {
273
- printf ( '<li><a href="%s" class="welcome-icon send_test_email">%s</a></li>', $this->getPageUrl ( PostmanSendTestEmailController::EMAIL_TEST_SLUG ), __ ( 'Send a Test Email', Postman::TEXT_DOMAIN ) );
274
  } else {
275
- printf ( '<li><div class="welcome-icon send_test_email">%s</div></li>', __ ( 'Send a Test Email', Postman::TEXT_DOMAIN ) );
276
  }
277
-
278
  // import-export-reset menu item
279
- if (! $this->options->isNew () || true) {
280
  $purgeLinkPattern = '<li><a href="%1$s" class="welcome-icon oauth-authorize">%2$s</a></li>';
281
  } else {
282
  $purgeLinkPattern = '<li>%2$s</li>';
283
  }
284
- $importTitle = __ ( 'Import', Postman::TEXT_DOMAIN );
285
- $exportTile = __ ( 'Export', Postman::TEXT_DOMAIN );
286
- $resetTitle = __ ( 'Reset Plugin', Postman::TEXT_DOMAIN );
287
- $importExportReset = sprintf ( '%s/%s/%s', $importTitle, $exportTile, $resetTitle );
288
- printf ( $purgeLinkPattern, $this->getPageUrl ( PostmanAdminController::MANAGE_OPTIONS_PAGE_SLUG ), sprintf ( '%s', $importExportReset ) );
289
  print '</ul>';
290
  print '</div>';
291
  print '<div class="welcome-panel-column welcome-panel-last">';
292
- printf ( '<h4>%s</h4>', _x ( 'Troubleshooting', 'Main Menu', Postman::TEXT_DOMAIN ) );
293
  print '<ul>';
294
- printf ( '<li><a href="%s" class="welcome-icon run-port-test">%s</a></li>', $this->getPageUrl ( PostmanConnectivityTestController::PORT_TEST_SLUG ), __ ( 'Connectivity Test', Postman::TEXT_DOMAIN ) );
295
- printf ( '<li><a href="%s" class="welcome-icon run-port-test">%s</a></li>', $this->getPageUrl ( PostmanDiagnosticTestController::DIAGNOSTICS_SLUG ), __ ( 'Diagnostic Test', Postman::TEXT_DOMAIN ) );
296
- printf ( '<li><a href="https://wordpress.org/support/plugin/postman-smtp" class="welcome-icon postman_support">%s</a></li>', __ ( 'Online Support', Postman::TEXT_DOMAIN ) );
297
  print '</ul></div></div></div></div>';
298
  }
299
-
300
  }
301
  }
302
-
1
  <?php
2
+ if ( ! class_exists( 'PostmanViewController' ) ) {
3
  class PostmanViewController {
4
  private $logger;
5
  private $rootPluginFilenameAndPath;
9
  private $importableConfiguration;
10
  private $adminController;
11
  const POSTMAN_MENU_SLUG = 'postman';
12
+
13
  // style sheets and scripts
14
  const POSTMAN_STYLE = 'postman_style';
15
  const JQUERY_SCRIPT = 'jquery';
16
  const POSTMAN_SCRIPT = 'postman_script';
17
+
18
+ const BACK_ARROW_SYMBOL = '&#11013;';
19
+
 
20
  /**
21
  * Constructor
22
  *
23
+ * @param PostmanOptions $options
24
+ * @param PostmanOAuthToken $authorizationToken
25
+ * @param PostmanConfigTextHelper $oauthScribe
26
  */
27
+ function __construct( $rootPluginFilenameAndPath, PostmanOptions $options, PostmanOAuthToken $authorizationToken, PostmanConfigTextHelper $oauthScribe, PostmanAdminController $adminController ) {
28
  $this->options = $options;
29
  $this->rootPluginFilenameAndPath = $rootPluginFilenameAndPath;
30
  $this->authorizationToken = $authorizationToken;
31
  $this->oauthScribe = $oauthScribe;
32
  $this->adminController = $adminController;
33
+ $this->logger = new PostmanLogger( get_class( $this ) );
34
+ PostmanUtils::registerAdminMenu( $this, 'generateDefaultContent' );
35
+ PostmanUtils::registerAdminMenu( $this, 'addPurgeDataSubmenu' );
36
+
37
  // initialize the scripts, stylesheets and form fields
38
+ add_action( 'admin_init', array(
39
  $this,
40
+ 'registerStylesAndScripts',
41
  ), 0 );
42
  }
43
+ public static function getPageUrl( $slug ) {
44
+ return PostmanUtils::getPageUrl( $slug );
45
  }
46
+
47
  /**
48
  * Add options page
49
  */
50
  public function generateDefaultContent() {
51
  // This page will be under "Settings"
52
+ $pageTitle = sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) );
53
+ $pluginName = __( 'Postman SMTP', Postman::TEXT_DOMAIN );
54
  $uniqueId = self::POSTMAN_MENU_SLUG;
55
+ $pageOptions = array(
56
  $this,
57
+ 'outputDefaultContent',
58
  );
59
+ $mainPostmanSettingsPage = add_options_page( $pageTitle, $pluginName, Postman::MANAGE_POSTMAN_CAPABILITY_NAME, $uniqueId, $pageOptions );
60
  // When the plugin options page is loaded, also load the stylesheet
61
+ add_action( 'admin_print_styles-' . $mainPostmanSettingsPage, array(
62
  $this,
63
+ 'enqueueHomeScreenStylesheet',
64
  ) );
65
  }
66
  function enqueueHomeScreenStylesheet() {
67
+ wp_enqueue_style( PostmanViewController::POSTMAN_STYLE );
68
+ wp_enqueue_script( 'postman_script' );
69
  }
70
+
71
  /**
72
  * Register the Email Test screen
73
  */
74
  public function addPurgeDataSubmenu() {
75
+ $page = add_submenu_page( null, sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ), Postman::MANAGE_POSTMAN_CAPABILITY_NAME, PostmanAdminController::MANAGE_OPTIONS_PAGE_SLUG, array(
76
  $this,
77
+ 'outputPurgeDataContent',
78
  ) );
79
  // When the plugin options page is loaded, also load the stylesheet
80
+ add_action( 'admin_print_styles-' . $page, array(
81
  $this,
82
+ 'enqueueHomeScreenStylesheet',
83
  ) );
84
  }
85
+
86
  /**
87
  * Register and add settings
88
  */
89
  public function registerStylesAndScripts() {
90
+ if ( $this->logger->isTrace() ) {
91
+ $this->logger->trace( 'registerStylesAndScripts()' );
92
  }
93
  // register the stylesheet and javascript external resources
94
+ $pluginData = apply_filters( 'postman_get_plugin_metadata', null );
95
+ wp_register_style( PostmanViewController::POSTMAN_STYLE, plugins_url( 'style/postman.css', $this->rootPluginFilenameAndPath ), null, $pluginData ['version'] );
96
+ wp_register_style( 'jquery_ui_style', plugins_url( 'style/jquery-steps/jquery-ui.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, '1.1.0' );
97
+ wp_register_style( 'jquery_steps_style', plugins_url( 'style/jquery-steps/jquery.steps.css', $this->rootPluginFilenameAndPath ), PostmanViewController::POSTMAN_STYLE, '1.1.0' );
98
+
99
+ wp_register_script( PostmanViewController::POSTMAN_SCRIPT, plugins_url( 'script/postman.js', $this->rootPluginFilenameAndPath ), array(
100
+ PostmanViewController::JQUERY_SCRIPT
101
  ), $pluginData ['version'] );
102
+ wp_register_script( 'sprintf', plugins_url( 'script/sprintf/sprintf.min.js', $this->rootPluginFilenameAndPath ), null, '1.0.2' );
103
+ wp_register_script( 'jquery_steps_script', plugins_url( 'script/jquery-steps/jquery.steps.min.js', $this->rootPluginFilenameAndPath ), array(
104
+ PostmanViewController::JQUERY_SCRIPT
105
  ), '1.1.0' );
106
+ wp_register_script( 'jquery_validation', plugins_url( 'script/jquery-validate/jquery.validate.min.js', $this->rootPluginFilenameAndPath ), array(
107
+ PostmanViewController::JQUERY_SCRIPT
108
  ), '1.13.1' );
109
 
110
+ wp_localize_script( PostmanViewController::POSTMAN_SCRIPT, 'postman_ajax_msg', array(
111
+ 'bad_response' => __( 'An unexpected error occurred', Postman::TEXT_DOMAIN ),
112
+ 'corrupt_response' => __( 'Unexpected PHP messages corrupted the Ajax response', Postman::TEXT_DOMAIN ),
113
  ) );
114
+
115
+ wp_localize_script( 'jquery_steps_script', 'steps_current_step', 'steps_current_step' );
116
+ wp_localize_script( 'jquery_steps_script', 'steps_pagination', 'steps_pagination' );
117
+ wp_localize_script( 'jquery_steps_script', 'steps_finish', _x( 'Finish', 'Press this button to Finish this task', Postman::TEXT_DOMAIN ) );
118
+ wp_localize_script( 'jquery_steps_script', 'steps_next', _x( 'Next', 'Press this button to go to the next step', Postman::TEXT_DOMAIN ) );
119
+ wp_localize_script( 'jquery_steps_script', 'steps_previous', _x( 'Previous', 'Press this button to go to the previous step', Postman::TEXT_DOMAIN ) );
120
+ wp_localize_script( 'jquery_steps_script', 'steps_loading', 'steps_loading' );
121
  }
122
+
123
  /**
124
  * Options page callback
125
  */
126
  public function outputDefaultContent() {
127
  // Set class property
128
  print '<div class="wrap">';
129
+ $this->displayTopNavigation();
130
+ if ( ! PostmanPreRequisitesCheck::isReady() ) {
131
+ printf( '<p><span style="color:red; padding:2px 0; font-size:1.1em">%s</span></p>', __( 'Postman is unable to run. Email delivery is being handled by WordPress (or another plugin).', Postman::TEXT_DOMAIN ) );
132
  } else {
133
+ $statusMessage = PostmanTransportRegistry::getInstance()->getReadyMessage();
134
+ if ( PostmanTransportRegistry::getInstance()->getActiveTransport()->isConfiguredAndReady() ) {
135
+ if ( $this->options->getRunMode() != PostmanOptions::RUN_MODE_PRODUCTION ) {
136
+ printf( '<p><span style="background-color:yellow">%s</span></p>', $statusMessage );
137
  } else {
138
+ printf( '<p><span style="color:green;padding:2px 0; font-size:1.1em">%s</span></p>', $statusMessage );
139
  }
140
  } else {
141
+ printf( '<p><span style="color:red; padding:2px 0; font-size:1.1em">%s</span></p>', $statusMessage );
142
  }
143
+ $this->printDeliveryDetails();
144
  /* translators: where %d is the number of emails delivered */
145
  print '<p style="margin:10px 10px"><span>';
146
+ printf( _n( 'Postman has delivered <span style="color:green">%d</span> email.', 'Postman has delivered <span style="color:green">%d</span> emails.', PostmanState::getInstance()->getSuccessfulDeliveries(), Postman::TEXT_DOMAIN ), PostmanState::getInstance()->getSuccessfulDeliveries() );
147
+ if ( $this->options->isMailLoggingEnabled() ) {
148
  print ' ';
149
+ printf( __( 'The last %d email attempts are recorded <a href="%s">in the log</a>.', Postman::TEXT_DOMAIN ), PostmanOptions::getInstance()->getMailLoggingMaxEntries(), PostmanUtils::getEmailLogPageUrl() );
150
  }
151
  print '</span></p>';
152
  }
153
+ if ( $this->options->isNew() ) {
154
+ printf( '<h3 style="padding-top:10px">%s</h3>', __( 'Thank-you for choosing Postman!', Postman::TEXT_DOMAIN ) );
155
  /* translators: where %s is the URL of the Setup Wizard */
156
+ printf( '<p><span>%s</span></p>', sprintf( __( 'Let\'s get started! All users are strongly encouraged to <a href="%s">run the Setup Wizard</a>.', Postman::TEXT_DOMAIN ), $this->getPageUrl( PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG ) ) );
157
+ printf( '<p><span>%s</span></p>', sprintf( __( 'Alternately, <a href="%s">manually configure</a> your own settings and/or modify advanced options.', Postman::TEXT_DOMAIN ), $this->getPageUrl( PostmanConfigurationController::CONFIGURATION_SLUG ) ) );
158
  } else {
159
+ if ( PostmanState::getInstance()->isTimeToReviewPostman() && ! PostmanOptions::getInstance()->isNew() ) {
160
  print '</br><hr width="70%"></br>';
161
  /* translators: where %s is the URL to the WordPress.org review and ratings page */
162
+ printf( '%s</span></p>', sprintf( __( 'Please consider <a href="%s">leaving a review</a> to help spread the word! :D', Postman::TEXT_DOMAIN ), 'https://wordpress.org/support/view/plugin-reviews/postman-smtp?filter=5' ) );
163
  }
164
+ printf( '<p><span>%s :-)</span></p>', sprintf( __( 'Postman needs translators! Please take a moment to <a href="%s">translate a few sentences on-line</a>', Postman::TEXT_DOMAIN ), 'https://translate.wordpress.org/projects/wp-plugins/post-smtp/stable' ) );
165
  }
166
+ printf( '<p><span>%s</span></p>', __( '<b style="background-color:yellow">New for v1.7!</style></b> Send mail with the Mandrill or SendGrid APIs.', Postman::TEXT_DOMAIN ) );
167
  }
168
+
169
  /**
170
  */
171
  private function printDeliveryDetails() {
172
+ $currentTransport = PostmanTransportRegistry::getInstance()->getActiveTransport();
173
+ $deliveryDetails = $currentTransport->getDeliveryDetails( $this->options );
174
+ printf( '<p style="margin:0 10px"><span>%s</span></p>', $deliveryDetails );
175
  }
176
+
177
  /**
178
  *
179
+ * @param unknown $title
180
+ * @param string $slug
181
  */
182
+ public static function outputChildPageHeader( $title, $slug = '' ) {
183
+ printf( '<h2>%s</h2>', sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) ) );
184
+ printf( '<div id="postman-main-menu" class="welcome-panel %s">', $slug );
185
  print '<div class="welcome-panel-content">';
186
  print '<div class="welcome-panel-column-container">';
187
  print '<div class="welcome-panel-column welcome-panel-last">';
188
+ printf( '<h4>%s</h4>', $title );
189
  print '</div>';
190
+ printf( '<p id="back_to_main_menu">%s <a id="back_to_menu_link" href="%s">%s</a></p>', self::BACK_ARROW_SYMBOL, PostmanUtils::getSettingsPageUrl(), _x( 'Back To Main Menu', 'Return to main menu link', Postman::TEXT_DOMAIN ) );
191
  print '</div></div></div>';
192
  }
193
+
194
  /**
195
  */
196
  public function outputPurgeDataContent() {
197
+ $importTitle = __( 'Import', Postman::TEXT_DOMAIN );
198
+ $exportTile = __( 'Export', Postman::TEXT_DOMAIN );
199
+ $resetTitle = __( 'Reset Plugin', Postman::TEXT_DOMAIN );
200
  $options = $this->options;
201
  print '<div class="wrap">';
202
+ PostmanViewController::outputChildPageHeader( sprintf( '%s/%s/%s', $importTitle, $exportTile, $resetTitle ) );
203
  print '<section id="export_settings">';
204
+ printf( '<h3><span>%s<span></h3>', $exportTile );
205
+ printf( '<p><span>%s</span></p>', __( 'Copy this data into another instance of Postman to duplicate the configuration.', Postman::TEXT_DOMAIN ) );
206
  $data = '';
207
+ if ( ! PostmanPreRequisitesCheck::checkZlibEncode() ) {
208
+ $extraDeleteButtonAttributes = sprintf( 'disabled="true"' );
209
  $data = '';
210
  } else {
211
  $extraDeleteButtonAttributes = '';
212
+ if ( ! $options->isNew() ) {
213
+ $data = $options->export();
214
  }
215
  }
216
+ printf( '<textarea cols="80" rows="5" readonly="true" name="settings" %s>%s</textarea>', $extraDeleteButtonAttributes, $data );
217
  print '</section>';
218
  print '<section id="import_settings">';
219
+ printf( '<h3><span>%s<span></h3>', $importTitle );
220
+ print '<form method="POST" action="' . get_admin_url() . 'admin-post.php">';
221
+ wp_nonce_field( PostmanAdminController::IMPORT_SETTINGS_SLUG );
222
+ printf( '<input type="hidden" name="action" value="%s" />', PostmanAdminController::IMPORT_SETTINGS_SLUG );
223
  print '<p>';
224
+ printf( '<span>%s</span>', __( 'Paste data from another instance of Postman here to duplicate the configuration.', Postman::TEXT_DOMAIN ) );
225
+ if ( PostmanTransportRegistry::getInstance()->getSelectedTransport()->isOAuthUsed( PostmanOptions::getInstance()->getAuthenticationType() ) ) {
226
+ $warning = __( 'Warning', Postman::TEXT_DOMAIN );
227
+ $errorMessage = __( 'Using the same OAuth 2.0 Client ID and Client Secret from this site at the same time as another site will cause failures.', Postman::TEXT_DOMAIN );
228
+ printf( ' <span><b>%s</b>: %s</span>', $warning, $errorMessage );
229
  }
230
  print '</p>';
231
+ printf( '<textarea cols="80" rows="5" name="settings" %s></textarea>', $extraDeleteButtonAttributes );
232
+ submit_button( __( 'Import', Postman::TEXT_DOMAIN ), 'primary', 'import', true, $extraDeleteButtonAttributes );
233
  print '</form>';
234
  print '</section>';
235
  print '<section id="delete_settings">';
236
+ printf( '<h3><span>%s<span></h3>', $resetTitle );
237
+ print '<form method="POST" action="' . get_admin_url() . 'admin-post.php">';
238
+ wp_nonce_field( PostmanAdminController::PURGE_DATA_SLUG );
239
+ printf( '<input type="hidden" name="action" value="%s" />', PostmanAdminController::PURGE_DATA_SLUG );
240
+ printf( '<p><span>%s</span></p><p><span>%s</span></p>', __( 'This will purge all of Postman\'s settings, including account credentials and the email log.', Postman::TEXT_DOMAIN ), __( 'Are you sure?', Postman::TEXT_DOMAIN ) );
241
  $extraDeleteButtonAttributes = 'style="background-color:red;color:white"';
242
+ if ( $this->options->isNew() ) {
243
  $extraDeleteButtonAttributes .= ' disabled="true"';
244
  }
245
+ submit_button( $resetTitle, 'delete', 'submit', true, $extraDeleteButtonAttributes );
246
  print '</form>';
247
  print '</section>';
248
  print '</div>';
249
  }
250
+
251
  /**
252
  */
253
  private function displayTopNavigation() {
254
+ screen_icon();
255
+ printf( '<h2>%s</h2>', sprintf( __( '%s Setup', Postman::TEXT_DOMAIN ), __( 'Postman SMTP', Postman::TEXT_DOMAIN ) ) );
256
  print '<div id="postman-main-menu" class="welcome-panel">';
257
  print '<div class="welcome-panel-content">';
258
  print '<div class="welcome-panel-column-container">';
259
  print '<div class="welcome-panel-column">';
260
+ printf( '<h4>%s</h4>', __( 'Configuration', Postman::TEXT_DOMAIN ) );
261
+ printf( '<a class="button button-primary button-hero" href="%s">%s</a>', $this->getPageUrl( PostmanConfigurationController::CONFIGURATION_WIZARD_SLUG ), __( 'Start the Wizard', Postman::TEXT_DOMAIN ) );
262
+ printf( '<p class="">or <a href="%s" class="configure_manually">%s</a></p>', $this->getPageUrl( PostmanConfigurationController::CONFIGURATION_SLUG ), __( 'Show All Settings', Postman::TEXT_DOMAIN ) );
263
  print '</div>';
264
  print '<div class="welcome-panel-column">';
265
+ printf( '<h4>%s</h4>', _x( 'Actions', 'Main Menu', Postman::TEXT_DOMAIN ) );
266
  print '<ul>';
267
+
268
  // Grant permission with Google
269
+ PostmanTransportRegistry::getInstance()->getSelectedTransport()->printActionMenuItem();
270
+
271
+ if ( PostmanWpMailBinder::getInstance()->isBound() ) {
272
+ printf( '<li><a href="%s" class="welcome-icon send_test_email">%s</a></li>', $this->getPageUrl( PostmanSendTestEmailController::EMAIL_TEST_SLUG ), __( 'Send a Test Email', Postman::TEXT_DOMAIN ) );
273
  } else {
274
+ printf( '<li><div class="welcome-icon send_test_email">%s</div></li>', __( 'Send a Test Email', Postman::TEXT_DOMAIN ) );
275
  }
276
+
277
  // import-export-reset menu item
278
+ if ( ! $this->options->isNew() || true ) {
279
  $purgeLinkPattern = '<li><a href="%1$s" class="welcome-icon oauth-authorize">%2$s</a></li>';
280
  } else {
281
  $purgeLinkPattern = '<li>%2$s</li>';
282
  }
283
+ $importTitle = __( 'Import', Postman::TEXT_DOMAIN );
284
+ $exportTile = __( 'Export', Postman::TEXT_DOMAIN );
285
+ $resetTitle = __( 'Reset Plugin', Postman::TEXT_DOMAIN );
286
+ $importExportReset = sprintf( '%s/%s/%s', $importTitle, $exportTile, $resetTitle );
287
+ printf( $purgeLinkPattern, $this->getPageUrl( PostmanAdminController::MANAGE_OPTIONS_PAGE_SLUG ), sprintf( '%s', $importExportReset ) );
288
  print '</ul>';
289
  print '</div>';
290
  print '<div class="welcome-panel-column welcome-panel-last">';
291
+ printf( '<h4>%s</h4>', _x( 'Troubleshooting', 'Main Menu', Postman::TEXT_DOMAIN ) );
292
  print '<ul>';
293
+ printf( '<li><a href="%s" class="welcome-icon run-port-test">%s</a></li>', $this->getPageUrl( PostmanConnectivityTestController::PORT_TEST_SLUG ), __( 'Connectivity Test', Postman::TEXT_DOMAIN ) );
294
+ printf( '<li><a href="%s" class="welcome-icon run-port-test">%s</a></li>', $this->getPageUrl( PostmanDiagnosticTestController::DIAGNOSTICS_SLUG ), __( 'Diagnostic Test', Postman::TEXT_DOMAIN ) );
295
+ printf( '<li><a href="https://wordpress.org/support/plugin/postman-smtp" class="welcome-icon postman_support">%s</a></li>', __( 'Online Support', Postman::TEXT_DOMAIN ) );
296
  print '</ul></div></div></div></div>';
297
  }
 
298
  }
299
  }
300
+
Postman/PostmanWpMail.php CHANGED
@@ -1,340 +1,339 @@
1
  <?php
2
- if (! class_exists ( "PostmanWpMail" )) {
3
-
4
  /**
5
  * Moved this code into a class so it could be used by both wp_mail() and PostmanSendTestEmailController
6
  *
7
  * @author jasonhendriks
8
- *
9
  */
10
  class PostmanWpMail {
11
  private $exception;
12
  private $transcript;
13
  private $totalTime;
14
  private $logger;
15
-
16
  /**
17
  * Load the dependencies
18
  */
19
  public function init() {
20
- $this->logger = new PostmanLogger ( get_class ( $this ) );
21
  require_once 'Postman-Mail/PostmanMessage.php';
22
  require_once 'Postman-Email-Log/PostmanEmailLogService.php';
23
  require_once 'Postman-Mail/PostmanMailEngine.php';
24
  require_once 'Postman-Auth/PostmanAuthenticationManagerFactory.php';
25
  require_once 'PostmanState.php';
26
  }
27
-
28
  /**
29
  * This methods follows the wp_mail function interface, but implements it Postman-style.
30
  * Exceptions are held for later inspection.
31
  * An instance of PostmanState updates the success/fail tally.
32
  *
33
- * @param unknown $to
34
- * @param unknown $subject
35
- * @param unknown $body
36
- * @param unknown $headers
37
- * @param unknown $attachments
38
  * @return boolean
39
  */
40
- public function send($to, $subject, $message, $headers = '', $attachments = array()) {
41
-
42
  // initialize for sending
43
- $this->init ();
44
-
45
  // build the message
46
- $postmanMessage = $this->processWpMailCall ( $to, $subject, $message, $headers, $attachments );
47
-
48
  // build the email log entry
49
- $log = new PostmanEmailLog ();
50
  $log->originalTo = $to;
51
  $log->originalSubject = $subject;
52
  $log->originalMessage = $message;
53
  $log->originalHeaders = $headers;
54
-
55
  // send the message and return the result
56
- return $this->sendMessage ( $postmanMessage, $log );
57
  }
58
-
59
  /**
60
  * Builds a PostmanMessage based on the WordPress wp_mail parameters
61
  *
62
- * @param unknown $to
63
- * @param unknown $subject
64
- * @param unknown $message
65
- * @param unknown $headers
66
- * @param unknown $attachments
67
  */
68
- private function processWpMailCall($to, $subject, $message, $headers, $attachments) {
69
- $this->logger->trace ( 'wp_mail parameters before applying WordPress wp_mail filter:' );
70
- $this->traceParameters ( $to, $subject, $message, $headers, $attachments );
71
-
72
  /**
73
  * Filter the wp_mail() arguments.
74
  *
75
  * @since 1.5.4
76
- *
77
  * @param array $args
78
  * A compacted array of wp_mail() arguments, including the "to" email,
79
  * subject, message, headers, and attachments values.
80
  */
81
- $atts = apply_filters ( 'wp_mail', compact ( 'to', 'subject', 'message', 'headers', 'attachments' ) );
82
- if (isset ( $atts ['to'] )) {
83
  $to = $atts ['to'];
84
  }
85
-
86
- if (isset ( $atts ['subject'] )) {
87
  $subject = $atts ['subject'];
88
  }
89
-
90
- if (isset ( $atts ['message'] )) {
91
  $message = $atts ['message'];
92
  }
93
-
94
- if (isset ( $atts ['headers'] )) {
95
  $headers = $atts ['headers'];
96
  }
97
-
98
- if (isset ( $atts ['attachments'] )) {
99
  $attachments = $atts ['attachments'];
100
  }
101
-
102
- if (! is_array ( $attachments )) {
103
- $attachments = explode ( "\n", str_replace ( "\r\n", "\n", $attachments ) );
104
  }
105
-
106
- $this->logger->trace ( 'wp_mail parameters after applying WordPress wp_mail filter:' );
107
- $this->traceParameters ( $to, $subject, $message, $headers, $attachments );
108
-
109
  // Postman API: register the response hook
110
- add_filter ( 'postman_wp_mail_result', array (
111
  $this,
112
- 'postman_wp_mail_result'
113
  ) );
114
-
115
  // create the message
116
- $postmanMessage = $this->createNewMessage ();
117
- $this->populateMessageFromWpMailParams ( $postmanMessage, $to, $subject, $message, $headers, $attachments );
118
-
119
  // return the message
120
  return $postmanMessage;
121
  }
122
-
123
  /**
124
  * Creates a new instance of PostmanMessage with a pre-set From and Reply-To
125
  *
126
  * @return PostmanMessage
127
  */
128
  public function createNewMessage() {
129
- $message = new PostmanMessage ();
130
- $options = PostmanOptions::getInstance ();
131
  // the From is set now so that it can be overridden
132
- $transport = PostmanTransportRegistry::getInstance ()->getActiveTransport ();
133
- $message->setFrom ( $transport->getFromEmailAddress (), $transport->getFromName () );
134
  // the Reply-To is set now so that it can be overridden
135
- $message->setReplyTo ( $options->getReplyTo () );
136
- $message->setCharset ( get_bloginfo ( 'charset' ) );
137
  return $message;
138
  }
139
-
140
  /**
141
  * A convenient place for any code to inject a constructed PostmanMessage
142
  * (for example, from MyMail)
143
  *
144
  * The body parts may be set already at this time.
145
  *
146
- * @param PostmanMessage $message
147
  * @return boolean
148
  */
149
- public function sendMessage(PostmanMessage $message, PostmanEmailLog $log) {
150
-
151
  // get the Options and AuthToken
152
- $options = PostmanOptions::getInstance ();
153
- $authorizationToken = PostmanOAuthToken::getInstance ();
154
-
155
  // get the transport and create the transportConfig and engine
156
- $transport = PostmanTransportRegistry::getInstance ()->getActiveTransport ();
157
-
158
  // create the Mail Engine
159
- $engine = $transport->createMailEngine ();
160
-
161
  // add plugin-specific attributes to PostmanMessage
162
- $message->addHeaders ( $options->getAdditionalHeaders () );
163
- $message->addTo ( $options->getForcedToRecipients () );
164
- $message->addCc ( $options->getForcedCcRecipients () );
165
- $message->addBcc ( $options->getForcedBccRecipients () );
166
-
167
  // apply the WordPress filters
168
  // may impact the from address, from email, charset and content-type
169
- $message->applyFilters ();
170
-
171
  // create the body parts (if they are both missing)
172
- if ($message->isBodyPartsEmpty ()) {
173
- $message->createBodyParts ();
174
  }
175
-
176
  // is this a test run?
177
- $testMode = apply_filters ( 'postman_test_email', false );
178
- if ($this->logger->isDebug ()) {
179
- $this->logger->debug ( 'testMode=' . $testMode );
180
  }
181
-
182
  // start the clock
183
- $startTime = microtime ( true ) * 1000;
184
-
185
  try {
186
-
187
  // prepare the message
188
- $message->validate ( $transport );
189
-
190
  // send the message
191
- if ($options->getRunMode () == PostmanOptions::RUN_MODE_PRODUCTION) {
192
- if ($transport->isLockingRequired ()) {
193
- PostmanUtils::lock ();
194
  // may throw an exception attempting to contact the OAuth2 provider
195
- $this->ensureAuthtokenIsUpdated ( $transport, $options, $authorizationToken );
196
  }
197
-
198
- $this->logger->debug ( 'Sending mail' );
199
  // may throw an exception attempting to contact the SMTP server
200
- $engine->send ( $message );
201
-
202
  // increment the success counter, unless we are just tesitng
203
- if (! $testMode) {
204
- PostmanState::getInstance ()->incrementSuccessfulDelivery ();
205
  }
206
  }
207
-
208
  // clean up
209
- $this->postSend ( $engine, $startTime, $options, $transport );
210
-
211
- if ($options->getRunMode () == PostmanOptions::RUN_MODE_PRODUCTION || $options->getRunMode () == PostmanOptions::RUN_MODE_LOG_ONLY) {
212
  // log the successful delivery
213
- PostmanEmailLogService::getInstance ()->writeSuccessLog ( $log, $message, $engine->getTranscript (), $transport );
214
  }
215
-
216
  // return successful
217
  return true;
218
  } catch ( Exception $e ) {
219
  // save the error for later
220
  $this->exception = $e;
221
-
222
  // write the error to the PHP log
223
- $this->logger->error ( get_class ( $e ) . ' code=' . $e->getCode () . ' message=' . trim ( $e->getMessage () ) );
224
-
225
  // increment the failure counter, unless we are just tesitng
226
- if (! $testMode && $options->getRunMode () == PostmanOptions::RUN_MODE_PRODUCTION) {
227
- PostmanState::getInstance ()->incrementFailedDelivery ();
228
  }
229
-
230
  // clean up
231
- $this->postSend ( $engine, $startTime, $options, $transport );
232
-
233
- if ($options->getRunMode () == PostmanOptions::RUN_MODE_PRODUCTION || $options->getRunMode () == PostmanOptions::RUN_MODE_LOG_ONLY) {
234
  // log the failed delivery
235
- PostmanEmailLogService::getInstance ()->writeFailureLog ( $log, $message, $engine->getTranscript (), $transport, $e->getMessage () );
236
  }
237
-
238
  // return failure
239
  return false;
240
  }
241
  }
242
-
243
  /**
244
  * Clean up after sending the mail
245
  *
246
- * @param PostmanZendMailEngine $engine
247
- * @param unknown $startTime
248
  */
249
- private function postSend(PostmanMailEngine $engine, $startTime, PostmanOptions $options, PostmanModuleTransport $transport) {
250
  // save the transcript
251
- $this->transcript = $engine->getTranscript ();
252
-
253
  // log the transcript
254
- if ($this->logger->isTrace ()) {
255
- $this->logger->trace ( 'Transcript:' );
256
- $this->logger->trace ( $this->transcript );
257
  }
258
-
259
  // delete the semaphore
260
- if ($transport->isLockingRequired ()) {
261
- PostmanUtils::unlock ();
262
  }
263
-
264
  // stop the clock
265
- $endTime = microtime ( true ) * 1000;
266
  $this->totalTime = $endTime - $startTime;
267
  }
268
-
269
  /**
270
  * Returns the result of the last call to send()
271
  *
272
  * @return multitype:Exception NULL
273
  */
274
  function postman_wp_mail_result() {
275
- $result = array (
276
  'time' => $this->totalTime,
277
  'exception' => $this->exception,
278
- 'transcript' => $this->transcript
279
  );
280
  return $result;
281
  }
282
-
283
  /**
284
  */
285
- private function ensureAuthtokenIsUpdated(PostmanModuleTransport $transport, PostmanOptions $options, PostmanOAuthToken $authorizationToken) {
286
- assert ( ! empty ( $transport ) );
287
- assert ( ! empty ( $options ) );
288
- assert ( ! empty ( $authorizationToken ) );
289
  // ensure the token is up-to-date
290
- $this->logger->debug ( 'Ensuring Access Token is up-to-date' );
291
  // interact with the Authentication Manager
292
- $wpMailAuthManager = PostmanAuthenticationManagerFactory::getInstance ()->createAuthenticationManager ();
293
- if ($wpMailAuthManager->isAccessTokenExpired ()) {
294
- $this->logger->debug ( 'Access Token has expired, attempting refresh' );
295
- $wpMailAuthManager->refreshToken ();
296
- $authorizationToken->save ();
297
  }
298
  }
299
-
300
  /**
301
  * Aggregates all the content into a Message to be sent to the MailEngine
302
  *
303
- * @param unknown $to
304
- * @param unknown $subject
305
- * @param unknown $body
306
- * @param unknown $headers
307
- * @param unknown $attachments
308
  */
309
- private function populateMessageFromWpMailParams(PostmanMessage $message, $to, $subject, $body, $headers, $attachments) {
310
- $message->addHeaders ( $headers );
311
- $message->setBody ( $body );
312
- $message->setSubject ( $subject );
313
- $message->addTo ( $to );
314
- $message->setAttachments ( $attachments );
315
  return $message;
316
  }
317
-
318
  /**
319
  * Trace the parameters to aid in debugging
320
  *
321
- * @param unknown $to
322
- * @param unknown $subject
323
- * @param unknown $body
324
- * @param unknown $headers
325
- * @param unknown $attachments
326
  */
327
- private function traceParameters($to, $subject, $message, $headers, $attachments) {
328
- $this->logger->trace ( 'to:' );
329
- $this->logger->trace ( $to );
330
- $this->logger->trace ( 'subject:' );
331
- $this->logger->trace ( $subject );
332
- $this->logger->trace ( 'headers:' );
333
- $this->logger->trace ( $headers );
334
- $this->logger->trace ( 'attachments:' );
335
- $this->logger->trace ( $attachments );
336
- $this->logger->trace ( 'message:' );
337
- $this->logger->trace ( $message );
338
  }
339
  }
340
- }
1
  <?php
2
+ if ( ! class_exists( 'PostmanWpMail' ) ) {
3
+
4
  /**
5
  * Moved this code into a class so it could be used by both wp_mail() and PostmanSendTestEmailController
6
  *
7
  * @author jasonhendriks
 
8
  */
9
  class PostmanWpMail {
10
  private $exception;
11
  private $transcript;
12
  private $totalTime;
13
  private $logger;
14
+
15
  /**
16
  * Load the dependencies
17
  */
18
  public function init() {
19
+ $this->logger = new PostmanLogger( get_class( $this ) );
20
  require_once 'Postman-Mail/PostmanMessage.php';
21
  require_once 'Postman-Email-Log/PostmanEmailLogService.php';
22
  require_once 'Postman-Mail/PostmanMailEngine.php';
23
  require_once 'Postman-Auth/PostmanAuthenticationManagerFactory.php';
24
  require_once 'PostmanState.php';
25
  }
26
+
27
  /**
28
  * This methods follows the wp_mail function interface, but implements it Postman-style.
29
  * Exceptions are held for later inspection.
30
  * An instance of PostmanState updates the success/fail tally.
31
  *
32
+ * @param unknown $to
33
+ * @param unknown $subject
34
+ * @param unknown $body
35
+ * @param unknown $headers
36
+ * @param unknown $attachments
37
  * @return boolean
38
  */
39
+ public function send( $to, $subject, $message, $headers = '', $attachments = array() ) {
40
+
41
  // initialize for sending
42
+ $this->init();
43
+
44
  // build the message
45
+ $postmanMessage = $this->processWpMailCall( $to, $subject, $message, $headers, $attachments );
46
+
47
  // build the email log entry
48
+ $log = new PostmanEmailLog();
49
  $log->originalTo = $to;
50
  $log->originalSubject = $subject;
51
  $log->originalMessage = $message;
52
  $log->originalHeaders = $headers;
53
+
54
  // send the message and return the result
55
+ return $this->sendMessage( $postmanMessage, $log );
56
  }
57
+
58
  /**
59
  * Builds a PostmanMessage based on the WordPress wp_mail parameters
60
  *
61
+ * @param unknown $to
62
+ * @param unknown $subject
63
+ * @param unknown $message
64
+ * @param unknown $headers
65
+ * @param unknown $attachments
66
  */
67
+ private function processWpMailCall( $to, $subject, $message, $headers, $attachments ) {
68
+ $this->logger->trace( 'wp_mail parameters before applying WordPress wp_mail filter:' );
69
+ $this->traceParameters( $to, $subject, $message, $headers, $attachments );
70
+
71
  /**
72
  * Filter the wp_mail() arguments.
73
  *
74
  * @since 1.5.4
75
+ *
76
  * @param array $args
77
  * A compacted array of wp_mail() arguments, including the "to" email,
78
  * subject, message, headers, and attachments values.
79
  */
80
+ $atts = apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) );
81
+ if ( isset( $atts ['to'] ) ) {
82
  $to = $atts ['to'];
83
  }
84
+
85
+ if ( isset( $atts ['subject'] ) ) {
86
  $subject = $atts ['subject'];
87
  }
88
+
89
+ if ( isset( $atts ['message'] ) ) {
90
  $message = $atts ['message'];
91
  }
92
+
93
+ if ( isset( $atts ['headers'] ) ) {
94
  $headers = $atts ['headers'];
95
  }
96
+
97
+ if ( isset( $atts ['attachments'] ) ) {
98
  $attachments = $atts ['attachments'];
99
  }
100
+
101
+ if ( ! is_array( $attachments ) ) {
102
+ $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
103
  }
104
+
105
+ $this->logger->trace( 'wp_mail parameters after applying WordPress wp_mail filter:' );
106
+ $this->traceParameters( $to, $subject, $message, $headers, $attachments );
107
+
108
  // Postman API: register the response hook
109
+ add_filter( 'postman_wp_mail_result', array(
110
  $this,
111
+ 'postman_wp_mail_result',
112
  ) );
113
+
114
  // create the message
115
+ $postmanMessage = $this->createNewMessage();
116
+ $this->populateMessageFromWpMailParams( $postmanMessage, $to, $subject, $message, $headers, $attachments );
117
+
118
  // return the message
119
  return $postmanMessage;
120
  }
121
+
122
  /**
123
  * Creates a new instance of PostmanMessage with a pre-set From and Reply-To
124
  *
125
  * @return PostmanMessage
126
  */
127
  public function createNewMessage() {
128
+ $message = new PostmanMessage();
129
+ $options = PostmanOptions::getInstance();
130
  // the From is set now so that it can be overridden
131
+ $transport = PostmanTransportRegistry::getInstance()->getActiveTransport();
132
+ $message->setFrom( $transport->getFromEmailAddress(), $transport->getFromName() );
133
  // the Reply-To is set now so that it can be overridden
134
+ $message->setReplyTo( $options->getReplyTo() );
135
+ $message->setCharset( get_bloginfo( 'charset' ) );
136
  return $message;
137
  }
138
+
139
  /**
140
  * A convenient place for any code to inject a constructed PostmanMessage
141
  * (for example, from MyMail)
142
  *
143
  * The body parts may be set already at this time.
144
  *
145
+ * @param PostmanMessage $message
146
  * @return boolean
147
  */
148
+ public function sendMessage( PostmanMessage $message, PostmanEmailLog $log ) {
149
+
150
  // get the Options and AuthToken
151
+ $options = PostmanOptions::getInstance();
152
+ $authorizationToken = PostmanOAuthToken::getInstance();
153
+
154
  // get the transport and create the transportConfig and engine
155
+ $transport = PostmanTransportRegistry::getInstance()->getActiveTransport();
156
+
157
  // create the Mail Engine
158
+ $engine = $transport->createMailEngine();
159
+
160
  // add plugin-specific attributes to PostmanMessage
161
+ $message->addHeaders( $options->getAdditionalHeaders() );
162
+ $message->addTo( $options->getForcedToRecipients() );
163
+ $message->addCc( $options->getForcedCcRecipients() );
164
+ $message->addBcc( $options->getForcedBccRecipients() );
165
+
166
  // apply the WordPress filters
167
  // may impact the from address, from email, charset and content-type
168
+ $message->applyFilters();
169
+
170
  // create the body parts (if they are both missing)
171
+ if ( $message->isBodyPartsEmpty() ) {
172
+ $message->createBodyParts();
173
  }
174
+
175
  // is this a test run?
176
+ $testMode = apply_filters( 'postman_test_email', false );
177
+ if ( $this->logger->isDebug() ) {
178
+ $this->logger->debug( 'testMode=' . $testMode );
179
  }
180
+
181
  // start the clock
182
+ $startTime = microtime( true ) * 1000;
183
+
184
  try {
185
+
186
  // prepare the message
187
+ $message->validate( $transport );
188
+
189
  // send the message
190
+ if ( $options->getRunMode() == PostmanOptions::RUN_MODE_PRODUCTION ) {
191
+ if ( $transport->isLockingRequired() ) {
192
+ PostmanUtils::lock();
193
  // may throw an exception attempting to contact the OAuth2 provider
194
+ $this->ensureAuthtokenIsUpdated( $transport, $options, $authorizationToken );
195
  }
196
+
197
+ $this->logger->debug( 'Sending mail' );
198
  // may throw an exception attempting to contact the SMTP server
199
+ $engine->send( $message );
200
+
201
  // increment the success counter, unless we are just tesitng
202
+ if ( ! $testMode ) {
203
+ PostmanState::getInstance()->incrementSuccessfulDelivery();
204
  }
205
  }
206
+
207
  // clean up
208
+ $this->postSend( $engine, $startTime, $options, $transport );
209
+
210
+ if ( $options->getRunMode() == PostmanOptions::RUN_MODE_PRODUCTION || $options->getRunMode() == PostmanOptions::RUN_MODE_LOG_ONLY ) {
211
  // log the successful delivery
212
+ PostmanEmailLogService::getInstance()->writeSuccessLog( $log, $message, $engine->getTranscript(), $transport );
213
  }
214
+
215
  // return successful
216
  return true;
217
  } catch ( Exception $e ) {
218
  // save the error for later
219
  $this->exception = $e;
220
+
221
  // write the error to the PHP log
222
+ $this->logger->error( get_class( $e ) . ' code=' . $e->getCode() . ' message=' . trim( $e->getMessage() ) );
223
+
224
  // increment the failure counter, unless we are just tesitng
225
+ if ( ! $testMode && $options->getRunMode() == PostmanOptions::RUN_MODE_PRODUCTION ) {
226
+ PostmanState::getInstance()->incrementFailedDelivery();
227
  }
228
+
229
  // clean up
230
+ $this->postSend( $engine, $startTime, $options, $transport );
231
+
232
+ if ( $options->getRunMode() == PostmanOptions::RUN_MODE_PRODUCTION || $options->getRunMode() == PostmanOptions::RUN_MODE_LOG_ONLY ) {
233
  // log the failed delivery
234
+ PostmanEmailLogService::getInstance()->writeFailureLog( $log, $message, $engine->getTranscript(), $transport, $e->getMessage() );
235
  }
236
+
237
  // return failure
238
  return false;
239
  }
240
  }
241
+
242
  /**
243
  * Clean up after sending the mail
244
  *
245
+ * @param PostmanZendMailEngine $engine
246
+ * @param unknown $startTime
247
  */
248
+ private function postSend( PostmanMailEngine $engine, $startTime, PostmanOptions $options, PostmanModuleTransport $transport ) {
249
  // save the transcript
250
+ $this->transcript = $engine->getTranscript();
251
+
252
  // log the transcript
253
+ if ( $this->logger->isTrace() ) {
254
+ $this->logger->trace( 'Transcript:' );
255
+ $this->logger->trace( $this->transcript );
256
  }
257
+
258
  // delete the semaphore
259
+ if ( $transport->isLockingRequired() ) {
260
+ PostmanUtils::unlock();
261
  }
262
+
263
  // stop the clock
264
+ $endTime = microtime( true ) * 1000;
265
  $this->totalTime = $endTime - $startTime;
266
  }
267
+
268
  /**
269
  * Returns the result of the last call to send()
270
  *
271
  * @return multitype:Exception NULL
272
  */
273
  function postman_wp_mail_result() {
274
+ $result = array(
275
  'time' => $this->totalTime,
276
  'exception' => $this->exception,
277
+ 'transcript' => $this->transcript,
278
  );
279
  return $result;
280
  }
281
+
282
  /**
283
  */
284
+ private function ensureAuthtokenIsUpdated( PostmanModuleTransport $transport, PostmanOptions $options, PostmanOAuthToken $authorizationToken ) {
285
+ assert( ! empty( $transport ) );
286
+ assert( ! empty( $options ) );
287
+ assert( ! empty( $authorizationToken ) );
288
  // ensure the token is up-to-date
289
+ $this->logger->debug( 'Ensuring Access Token is up-to-date' );
290
  // interact with the Authentication Manager
291
+ $wpMailAuthManager = PostmanAuthenticationManagerFactory::getInstance()->createAuthenticationManager();
292
+ if ( $wpMailAuthManager->isAccessTokenExpired() ) {
293
+ $this->logger->debug( 'Access Token has expired, attempting refresh' );
294
+ $wpMailAuthManager->refreshToken();
295
+ $authorizationToken->save();
296
  }
297
  }
298
+
299
  /**
300
  * Aggregates all the content into a Message to be sent to the MailEngine
301
  *
302
+ * @param unknown $to
303
+ * @param unknown $subject
304
+ * @param unknown $body
305
+ * @param unknown $headers
306
+ * @param unknown $attachments
307
  */
308
+ private function populateMessageFromWpMailParams( PostmanMessage $message, $to, $subject, $body, $headers, $attachments ) {
309
+ $message->addHeaders( $headers );
310
+ $message->setBody( $body );
311
+ $message->setSubject( $subject );
312
+ $message->addTo( $to );
313
+ $message->setAttachments( $attachments );
314
  return $message;
315
  }
316
+
317
  /**
318
  * Trace the parameters to aid in debugging
319
  *
320
+ * @param unknown $to
321
+ * @param unknown $subject
322
+ * @param unknown $body
323
+ * @param unknown $headers
324
+ * @param unknown $attachments
325
  */
326
+ private function traceParameters( $to, $subject, $message, $headers, $attachments ) {
327
+ $this->logger->trace( 'to:' );
328
+ $this->logger->trace( $to );
329
+ $this->logger->trace( 'subject:' );
330
+ $this->logger->trace( $subject );
331
+ $this->logger->trace( 'headers:' );
332
+ $this->logger->trace( $headers );
333
+ $this->logger->trace( 'attachments:' );
334
+ $this->logger->trace( $attachments );
335
+ $this->logger->trace( 'message:' );
336
+ $this->logger->trace( $message );
337
  }
338
  }
339
+ }
postman-smtp.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin Name: Post SMTP
5
  * Plugin URI: https://wordpress.org/plugins/post-smtp/
6
  * Description: Email not reliable? Post SMTP is the first and only WordPress SMTP plugin to implement OAuth 2.0 for Gmail, Hotmail and Yahoo Mail. Setup is a breeze with the Configuration Wizard and integrated Port Tester. Enjoy worry-free delivery even if your password changes!
7
- * Version: 1.7.6
8
  * Author: Jason Hendriks, Yehuda Hassine
9
  * Text Domain: post-smtp
10
  * Author URI: https://postmansmtp.com
@@ -70,5 +70,5 @@ function post_start( $startingMemory ) {
70
  */
71
  function post_setupPostman() {
72
  require_once 'Postman/Postman.php';
73
- $kevinCostner = new Postman( __FILE__, '1.7.6' );
74
  }
4
  * Plugin Name: Post SMTP
5
  * Plugin URI: https://wordpress.org/plugins/post-smtp/
6
  * Description: Email not reliable? Post SMTP is the first and only WordPress SMTP plugin to implement OAuth 2.0 for Gmail, Hotmail and Yahoo Mail. Setup is a breeze with the Configuration Wizard and integrated Port Tester. Enjoy worry-free delivery even if your password changes!
7
+ * Version: 1.7.7
8
  * Author: Jason Hendriks, Yehuda Hassine
9
  * Text Domain: post-smtp
10
  * Author URI: https://postmansmtp.com
70
  */
71
  function post_setupPostman() {
72
  require_once 'Postman/Postman.php';
73
+ $kevinCostner = new Postman( __FILE__, '1.7.7' );
74
  }
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: yehudah, jasonhendriks
3
  Tags: postman smtp, postman, smtp, email, mail, mailer, email log, oauth2, gmail, google apps, hotmail, yahoo, mandrill api, sendgrid api, sparkpost api
4
  Requires at least: 3.9
5
  Tested up to: 4.8
6
- Stable tag: 1.7.6
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -11,6 +11,15 @@ Send, log and troubleshoot your Outgoing Email easily. Supports everything: SMTP
11
 
12
  == Description ==
13
 
 
 
 
 
 
 
 
 
 
14
  Post is a next-generation [SMTP Mailer](https://wordpress.org/plugins/search.php?q=smtp), software that assists in the delivery of email generated by your WordPress site. Post is the first and only plugin to support the [latest security standards](http://googleonlinesecurity.blogspot.ca/2014/04/new-security-measures-will-affect-older.html). With OAuth 2.0, there is **no need** to [store your email passsword](http://blog.codinghorror.com/youre-probably-storing-passwords-incorrectly/) in the WordPress database where it might be found.
15
 
16
  > Post is one year old! SparkPost API Integration is coming soon as Mandrill is no longer offering a free service.
@@ -50,6 +59,7 @@ Post is *not* another WP Mail SMTP clone like WP Bank or Easy SMTP. It replaces
50
  * [Visual Forms Builder](https://wordpress.org/plugins/visual-form-builder/)
51
  * [Contact Form Builder](https://wordpress.org/plugins/contact-form-builder/)
52
  * [PlanSo Forms](https://wordpress.org/plugins/planso-forms/)
 
53
  * [MyMail Newsletter](http://revaxarts-themes.com/?t=mymail) by revaxarts
54
  * [SendPress Newsletters](https://wordpress.org/plugins/sendpress/)
55
  * [WP HTML Mail](https://wordpress.org/plugins/wp-html-mail/)
@@ -270,6 +280,10 @@ To avoid being flagged as spam, you need to prove your email isn't forged. On a
270
 
271
 
272
  == Changelog ==
 
 
 
 
273
 
274
  = 1.7.6 - 2017-10-17
275
  * Missing sendgrid files
3
  Tags: postman smtp, postman, smtp, email, mail, mailer, email log, oauth2, gmail, google apps, hotmail, yahoo, mandrill api, sendgrid api, sparkpost api
4
  Requires at least: 3.9
5
  Tested up to: 4.8
6
+ Stable tag: 1.7.7
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
11
 
12
  == Description ==
13
 
14
+ = Postman SMTP is back! =
15
+ Now under new maintenance, no need to search for another SMTP plugin anymore.
16
+
17
+ = The Most Fast And Easy =
18
+ See how fast and easy to setup Post SMTP with Google/Gsuite or any SMTP service.
19
+
20
+ https://www.youtube.com/watch?v=z-x1DhcAN0o
21
+
22
+
23
  Post is a next-generation [SMTP Mailer](https://wordpress.org/plugins/search.php?q=smtp), software that assists in the delivery of email generated by your WordPress site. Post is the first and only plugin to support the [latest security standards](http://googleonlinesecurity.blogspot.ca/2014/04/new-security-measures-will-affect-older.html). With OAuth 2.0, there is **no need** to [store your email passsword](http://blog.codinghorror.com/youre-probably-storing-passwords-incorrectly/) in the WordPress database where it might be found.
24
 
25
  > Post is one year old! SparkPost API Integration is coming soon as Mandrill is no longer offering a free service.
59
  * [Visual Forms Builder](https://wordpress.org/plugins/visual-form-builder/)
60
  * [Contact Form Builder](https://wordpress.org/plugins/contact-form-builder/)
61
  * [PlanSo Forms](https://wordpress.org/plugins/planso-forms/)
62
+ * [Quform](https://www.quform.com/)
63
  * [MyMail Newsletter](http://revaxarts-themes.com/?t=mymail) by revaxarts
64
  * [SendPress Newsletters](https://wordpress.org/plugins/sendpress/)
65
  * [WP HTML Mail](https://wordpress.org/plugins/wp-html-mail/)
280
 
281
 
282
  == Changelog ==
283
+ = 1.7.7 - 2017-10-17
284
+ * Fixed: Error sending files with sendgrid
285
+ * Fixed: Wrong attachments format in Mandrill
286
+ * Fixed: Wrong Sender Header in Mandrill
287
 
288
  = 1.7.6 - 2017-10-17
289
  * Missing sendgrid files