WP Mail SMTP by WPForms - Version 1.1.0

Version Description

  • 2017-12-18 =
  • Added: New option "Auto TLS" for SMTP mailer. Default is enabled. Migration routine for all sites.
  • Changed: Improve debug output - clear styles and context-aware content.
  • Changed: Better exceptions handling for Google authentication process.
  • Changed: Do not sanitize passwords, api keys etc - as they may contain special characters in certain order and sanitization will break those values.
  • Changed: Improve wording of some helpful texts inside plugin admin area.
  • Fixed: Do not include certain files in dependency libraries that are not used by Google mailer. This should stop flagging plugin by Wordfence and VaultPress.
  • Fixed: Constants usage is working now, to define the SMTP password, for example.
  • Fixed: Notice for default mailer.
Download this release

Release Info

Developer slaFFik
Plugin Icon 128x128 WP Mail SMTP by WPForms
Version 1.1.0
Comparing to
See all releases

Code changes from version 1.0.2 to 1.1.0

Files changed (64) hide show
  1. assets/js/smtp-admin.js +43 -36
  2. assets/js/smtp-admin.min.js +1 -1
  3. class-wpms-am-notification.php +450 -450
  4. languages/wp-mail-smtp.pot +25 -9
  5. readme.txt +10 -0
  6. src/AM_Notification.php +452 -452
  7. src/Admin/Area.php +457 -457
  8. src/Admin/PageAbstract.php +66 -66
  9. src/Admin/PageInterface.php +45 -45
  10. src/Admin/Pages/Auth.php +56 -56
  11. src/Admin/Pages/Misc.php +99 -99
  12. src/Admin/Pages/Settings.php +236 -236
  13. src/Admin/Pages/Test.php +235 -208
  14. src/Core.php +239 -213
  15. src/MailCatcher.php +66 -66
  16. src/Migration.php +245 -245
  17. src/Options.php +547 -469
  18. src/Processor.php +175 -170
  19. src/Providers/AuthAbstract.php +22 -22
  20. src/Providers/AuthInterface.php +19 -19
  21. src/Providers/Gmail/Auth.php +314 -299
  22. src/Providers/Gmail/Mailer.php +173 -173
  23. src/Providers/Gmail/Options.php +131 -131
  24. src/Providers/Loader.php +178 -178
  25. src/Providers/Mail/Options.php +42 -42
  26. src/Providers/MailerAbstract.php +346 -346
  27. src/Providers/MailerInterface.php +139 -139
  28. src/Providers/Mailgun/Mailer.php +299 -299
  29. src/Providers/Mailgun/Options.php +106 -106
  30. src/Providers/OptionAbstract.php +312 -291
  31. src/Providers/OptionInterface.php +64 -64
  32. src/Providers/Pepipost/Options.php +29 -29
  33. src/Providers/SMTP/Options.php +45 -45
  34. src/Providers/Sendgrid/Mailer.php +294 -294
  35. src/Providers/Sendgrid/Options.php +89 -89
  36. src/Upgrade.php +71 -0
  37. src/WP.php +140 -140
  38. vendor/autoload.php +2 -2
  39. vendor/composer/ClassLoader.php +45 -13
  40. vendor/composer/LICENSE +1 -1
  41. vendor/composer/autoload_classmap.php +228 -0
  42. vendor/composer/autoload_real.php +9 -18
  43. vendor/composer/autoload_static.php +233 -5
  44. vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php +0 -2558
  45. vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php +0 -577
  46. vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php +0 -1443
  47. vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php +0 -824
  48. vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php +0 -688
  49. vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php +0 -342
  50. vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php +0 -460
  51. vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php +0 -808
  52. vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php +0 -577
  53. vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php +0 -1325
  54. vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php +0 -47
  55. vendor/phpseclib/phpseclib/phpseclib/File/X509.php +0 -4846
  56. vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php +0 -337
  57. vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php +0 -3104
  58. vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php +0 -795
  59. vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php +0 -1642
  60. vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php +0 -4616
  61. vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php +0 -308
  62. vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php +0 -158
  63. wp-mail-smtp.php +61 -61
  64. wp_mail_smtp.php +2 -2
assets/js/smtp-admin.js CHANGED
@@ -1,36 +1,43 @@
1
- /* globals jQuery */
2
- jQuery( document ).ready( function ( $ ) {
3
-
4
- $( '.wp-mail-smtp-mailer input' ).click( function () {
5
- if ( $( this ).prop( 'disabled' ) ) {
6
- return false;
7
- }
8
-
9
- // Deselect the current mailer.
10
- $( '.wp-mail-smtp-mailer' ).removeClass( 'active' );
11
- // Select the correct one.
12
- $( this ).parents( '.wp-mail-smtp-mailer' ).addClass( 'active' );
13
-
14
- $( '.wp-mail-smtp-mailer-option' ).addClass( 'hidden' ).removeClass( 'active' );
15
- $( '.wp-mail-smtp-mailer-option-' + $( this ).val() ).addClass( 'active' ).removeClass( 'hidden' );
16
- } );
17
-
18
- $( '.wp-mail-smtp-mailer-image' ).click( function () {
19
- $( this ).parents( '.wp-mail-smtp-mailer' ).find( 'input' ).trigger( 'click' );
20
- } );
21
-
22
- $( '.wp-mail-smtp-setting-copy' ).click( function ( e ) {
23
- e.preventDefault();
24
-
25
- var target = $( '#' + $( this ).data( 'source_id' ) ).get(0);
26
-
27
- target.select();
28
-
29
- document.execCommand( 'Copy' );
30
- } );
31
-
32
- $( '#wp-mail-smtp-setting-smtp-auth' ).change(function() {
33
- $( '#wp-mail-smtp-setting-row-smtp-user, #wp-mail-smtp-setting-row-smtp-pass' ).toggleClass( 'inactive' );
34
- });
35
-
36
- } );
1
+ /* globals jQuery */
2
+ jQuery( document ).ready( function ( $ ) {
3
+
4
+ $( '.wp-mail-smtp-mailer input' ).click( function () {
5
+ if ( $( this ).prop( 'disabled' ) ) {
6
+ return false;
7
+ }
8
+
9
+ // Deselect the current mailer.
10
+ $( '.wp-mail-smtp-mailer' ).removeClass( 'active' );
11
+ // Select the correct one.
12
+ $( this ).parents( '.wp-mail-smtp-mailer' ).addClass( 'active' );
13
+
14
+ $( '.wp-mail-smtp-mailer-option' ).addClass( 'hidden' ).removeClass( 'active' );
15
+ $( '.wp-mail-smtp-mailer-option-' + $( this ).val() ).addClass( 'active' ).removeClass( 'hidden' );
16
+ } );
17
+
18
+ $( '.wp-mail-smtp-mailer-image' ).click( function () {
19
+ $( this ).parents( '.wp-mail-smtp-mailer' ).find( 'input' ).trigger( 'click' );
20
+ } );
21
+
22
+ $( '.wp-mail-smtp-setting-copy' ).click( function ( e ) {
23
+ e.preventDefault();
24
+
25
+ var target = $( '#' + $( this ).data( 'source_id' ) ).get(0);
26
+
27
+ target.select();
28
+
29
+ document.execCommand( 'Copy' );
30
+ } );
31
+
32
+ $( '#wp-mail-smtp-setting-smtp-auth' ).change( function() {
33
+ $( '#wp-mail-smtp-setting-row-smtp-user, #wp-mail-smtp-setting-row-smtp-pass' ).toggleClass( 'inactive' );
34
+ });
35
+
36
+ $( '#wp-mail-smtp-setting-row-smtp-encryption input').change( function() {
37
+ if ( 'tls' === $(this).val() ) {
38
+ $(' #wp-mail-smtp-setting-row-smtp-autotls' ).addClass( 'inactive' );
39
+ } else {
40
+ $( '#wp-mail-smtp-setting-row-smtp-autotls' ).removeClass( 'inactive' );
41
+ }
42
+ } );
43
+ } );
assets/js/smtp-admin.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(i){i(".wp-mail-smtp-mailer input").click(function(){if(i(this).prop("disabled"))return!1;i(".wp-mail-smtp-mailer").removeClass("active"),i(this).parents(".wp-mail-smtp-mailer").addClass("active"),i(".wp-mail-smtp-mailer-option").addClass("hidden").removeClass("active"),i(".wp-mail-smtp-mailer-option-"+i(this).val()).addClass("active").removeClass("hidden")}),i(".wp-mail-smtp-mailer-image").click(function(){i(this).parents(".wp-mail-smtp-mailer").find("input").trigger("click")}),i(".wp-mail-smtp-setting-copy").click(function(t){t.preventDefault();i("#"+i(this).data("source_id")).get(0).select(),document.execCommand("Copy")}),i("#wp-mail-smtp-setting-smtp-auth").change(function(){i("#wp-mail-smtp-setting-row-smtp-user, #wp-mail-smtp-setting-row-smtp-pass").toggleClass("inactive")})});
1
+ jQuery(document).ready(function(t){t(".wp-mail-smtp-mailer input").click(function(){if(t(this).prop("disabled"))return!1;t(".wp-mail-smtp-mailer").removeClass("active"),t(this).parents(".wp-mail-smtp-mailer").addClass("active"),t(".wp-mail-smtp-mailer-option").addClass("hidden").removeClass("active"),t(".wp-mail-smtp-mailer-option-"+t(this).val()).addClass("active").removeClass("hidden")}),t(".wp-mail-smtp-mailer-image").click(function(){t(this).parents(".wp-mail-smtp-mailer").find("input").trigger("click")}),t(".wp-mail-smtp-setting-copy").click(function(i){i.preventDefault(),t("#"+t(this).data("source_id")).get(0).select(),document.execCommand("Copy")}),t("#wp-mail-smtp-setting-smtp-auth").change(function(){t("#wp-mail-smtp-setting-row-smtp-user, #wp-mail-smtp-setting-row-smtp-pass").toggleClass("inactive")}),t("#wp-mail-smtp-setting-row-smtp-encryption input").change(function(){"tls"===t(this).val()?t(" #wp-mail-smtp-setting-row-smtp-autotls").addClass("inactive"):t("#wp-mail-smtp-setting-row-smtp-autotls").removeClass("inactive")})});
class-wpms-am-notification.php CHANGED
@@ -1,450 +1,450 @@
1
- <?php
2
-
3
- /**
4
- * Awesome Motive Notifications
5
- *
6
- * This creates a custom post type (if it doesn't exist) and calls the API to
7
- * retrieve notifications for this product.
8
- *
9
- * @package AwesomeMotive
10
- * @author Benjamin Rojas
11
- * @license GPL-2.0+
12
- * @copyright Copyright (c) 2017, Retyp LLC
13
- * @version 1.0.2
14
- */
15
- class WPMS_AM_Notification {
16
- /**
17
- * The api url we are calling.
18
- *
19
- * @since 1.0.0
20
- *
21
- * @var string
22
- */
23
- public $api_url = 'https://api.awesomemotive.com/v1/notification/';
24
-
25
- /**
26
- * A unique slug for this plugin.
27
- * (Not the WordPress plugin slug)
28
- *
29
- * @since 1.0.0
30
- *
31
- * @var string
32
- */
33
- public $plugin;
34
-
35
- /**
36
- * The current plugin version.
37
- *
38
- * @since 1.0.0
39
- *
40
- * @var string
41
- */
42
- public $plugin_version;
43
-
44
- /**
45
- * Flag if a notice has been registered.
46
- *
47
- * @since 1.0.0
48
- *
49
- * @var bool
50
- */
51
- public static $registered = false;
52
-
53
- /**
54
- * Construct.
55
- *
56
- * @since 1.0.0
57
- *
58
- * @param string $plugin The plugin slug.
59
- * @param mixed $version The version of the plugin.
60
- */
61
- public function __construct( $plugin = '', $version = 0 ) {
62
- $this->plugin = $plugin;
63
- $this->plugin_version = $version;
64
-
65
- add_action( 'init', array( $this, 'custom_post_type' ) );
66
- add_action( 'admin_init', array( $this, 'get_remote_notifications' ), 100 );
67
- add_action( 'admin_notices', array( $this, 'display_notifications' ) );
68
- add_action( 'wp_ajax_am_notification_dismiss', array( $this, 'dismiss_notification' ) );
69
- }
70
-
71
- /**
72
- * Registers a custom post type.
73
- *
74
- * @since 1.0.0
75
- */
76
- public function custom_post_type() {
77
- register_post_type( 'amn_' . $this->plugin, array(
78
- 'label' => $this->plugin . ' Announcements',
79
- 'can_export' => false,
80
- 'supports' => false,
81
- ) );
82
- }
83
-
84
- /**
85
- * Retrieve the remote notifications if the time has expired.
86
- *
87
- * @since 1.0.0
88
- */
89
- public function get_remote_notifications() {
90
- if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
91
- return;
92
- }
93
-
94
- $last_checked = get_option( '_amn_' . $this->plugin . '_last_checked', strtotime( '-1 week' ) );
95
-
96
- if ( $last_checked < strtotime( 'today midnight' ) ) {
97
- $plugin_notifications = $this->get_plugin_notifications( 1 );
98
- $notification_id = null;
99
-
100
- if ( ! empty( $plugin_notifications ) ) {
101
- // Unset it from the array.
102
- $notification = $plugin_notifications[0];
103
- $notification_id = get_post_meta( $notification->ID, 'notification_id', true );
104
- }
105
-
106
- $response = wp_remote_retrieve_body( wp_remote_post( $this->api_url, array(
107
- 'body' => array(
108
- 'slug' => $this->plugin,
109
- 'version' => $this->plugin_version,
110
- 'last_notification' => $notification_id,
111
- ),
112
- ) ) );
113
-
114
- $data = json_decode( $response );
115
-
116
- if ( ! empty( $data->id ) ) {
117
- $notifications = array();
118
-
119
- foreach ( (array) $data->slugs as $slug ) {
120
- $notifications = array_merge(
121
- $notifications,
122
- (array) get_posts(
123
- array(
124
- 'post_type' => 'amn_' . $slug,
125
- 'post_status' => 'all',
126
- 'meta_key' => 'notification_id',
127
- 'meta_value' => $data->id,
128
- )
129
- )
130
- );
131
- }
132
-
133
- if ( empty( $notifications ) ) {
134
- $new_notification_id = wp_insert_post( array(
135
- 'post_content' => wp_kses_post( $data->content ),
136
- 'post_type' => 'amn_' . $this->plugin,
137
- ) );
138
-
139
- update_post_meta( $new_notification_id, 'notification_id', absint( $data->id ) );
140
- update_post_meta( $new_notification_id, 'type', sanitize_text_field( trim( $data->type ) ) );
141
- update_post_meta( $new_notification_id, 'dismissable', (bool) $data->dismissible ? 1 : 0 );
142
- update_post_meta( $new_notification_id, 'location', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->location ) : json_encode( $data->location ) );
143
- update_post_meta( $new_notification_id, 'version', sanitize_text_field( trim( $data->version ) ) );
144
- update_post_meta( $new_notification_id, 'viewed', 0 );
145
- update_post_meta( $new_notification_id, 'expiration', $data->expiration ? absint( $data->expiration ) : false );
146
- update_post_meta( $new_notification_id, 'plans', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->plans ) : json_encode( $data->plans ) );
147
- }
148
- }
149
-
150
- // Possibly revoke notifications.
151
- if ( ! empty( $data->revoked ) ) {
152
- $this->revoke_notifications( $data->revoked );
153
- }
154
-
155
- // Set the option now so we can't run this again until after 24 hours.
156
- update_option( '_amn_' . $this->plugin . '_last_checked', strtotime( 'today midnight' ) );
157
- }
158
- }
159
-
160
- /**
161
- * Get local plugin notifications that have already been set.
162
- *
163
- * @since 1.0.0
164
- *
165
- * @param integer $limit Set the limit for how many posts to retrieve.
166
- * @param array $args Any top-level arguments to add to the array.
167
- *
168
- * @return WP_Post[] WP_Post that match the query.
169
- */
170
- public function get_plugin_notifications( $limit = -1, $args = array() ) {
171
- return get_posts(
172
- array(
173
- 'posts_per_page' => $limit,
174
- 'post_type' => 'amn_' . $this->plugin,
175
- ) + $args
176
- );
177
- }
178
-
179
- /**
180
- * Display any notifications that should be displayed.
181
- *
182
- * @since 1.0.0
183
- */
184
- public function display_notifications() {
185
- if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
186
- return;
187
- }
188
-
189
- $plugin_notifications = $this->get_plugin_notifications( -1, array(
190
- 'post_status' => 'all',
191
- 'meta_key' => 'viewed',
192
- 'meta_value' => '0',
193
- ) );
194
-
195
- $plugin_notifications = $this->validate_notifications( $plugin_notifications );
196
-
197
- if ( ! empty( $plugin_notifications ) && ! self::$registered ) {
198
- foreach ( $plugin_notifications as $notification ) {
199
- $dismissable = get_post_meta( $notification->ID, 'dismissable', true );
200
- $type = get_post_meta( $notification->ID, 'type', true );
201
- ?>
202
- <div class="am-notification am-notification-<?php echo $notification->ID; ?> notice notice-<?php echo $type; ?><?php echo $dismissable ? ' is-dismissible' : ''; ?>">
203
- <?php echo $notification->post_content; ?>
204
- </div>
205
- <script type="text/javascript">
206
- jQuery(document).ready(function ($) {
207
- $(document).on('click', '.am-notification-<?php echo $notification->ID; ?> button.notice-dismiss', function (event) {
208
- $.post(ajaxurl, {
209
- action: 'am_notification_dismiss',
210
- notification_id: '<?php echo $notification->ID; ?>'
211
- });
212
- });
213
- });
214
- </script>
215
- <?php
216
- }
217
-
218
- self::$registered = true;
219
- }
220
- }
221
-
222
- /**
223
- * Validate the notifications before displaying them.
224
- *
225
- * @since 1.0.0
226
- *
227
- * @param array $plugin_notifications An array of plugin notifications.
228
- *
229
- * @return array A filtered array of plugin notifications.
230
- */
231
- public function validate_notifications( $plugin_notifications ) {
232
- global $pagenow;
233
-
234
- foreach ( $plugin_notifications as $key => $notification ) {
235
- // Location validation.
236
- $location = (array) json_decode( get_post_meta( $notification->ID, 'location', true ) );
237
- $continue = false;
238
- if ( ! in_array( 'everywhere', $location, true ) ) {
239
- if ( in_array( 'index.php', $location, true ) && 'index.php' === $pagenow ) {
240
- $continue = true;
241
- }
242
-
243
- if ( in_array( 'plugins.php', $location, true ) && 'plugins.php' === $pagenow ) {
244
- $continue = true;
245
- }
246
-
247
- if ( ! $continue ) {
248
- unset( $plugin_notifications[ $key ] );
249
- }
250
- }
251
-
252
- // Plugin validation (OR conditional).
253
- $plugins = (array) json_decode( get_post_meta( $notification->ID, 'plugins', true ) );
254
- $continue = false;
255
- if ( ! empty( $plugins ) ) {
256
- foreach ( $plugins as $plugin ) {
257
- if ( is_plugin_active( $plugin ) ) {
258
- $continue = true;
259
- }
260
- }
261
-
262
- if ( ! $continue ) {
263
- unset( $plugin_notifications[ $key ] );
264
- }
265
- }
266
-
267
- // Theme validation.
268
- $theme = get_post_meta( $notification->ID, 'theme', true );
269
- $continue = (string) wp_get_theme() === $theme;
270
-
271
- if ( ! empty( $theme ) && ! $continue ) {
272
- unset( $plugin_notifications[ $key ] );
273
- }
274
-
275
- // Version validation.
276
- $version = get_post_meta( $notification->ID, 'version', true );
277
- $continue = false;
278
- if ( ! empty( $version ) ) {
279
- if ( version_compare( $this->plugin_version, $version, '<=' ) ) {
280
- $continue = true;
281
- }
282
-
283
- if ( ! $continue ) {
284
- unset( $plugin_notifications[ $key ] );
285
- }
286
- }
287
-
288
- // Expiration validation.
289
- $expiration = get_post_meta( $notification->ID, 'expiration', true );
290
- $continue = false;
291
- if ( ! empty( $expiration ) ) {
292
- if ( $expiration > time() ) {
293
- $continue = true;
294
- }
295
-
296
- if ( ! $continue ) {
297
- unset( $plugin_notifications[ $key ] );
298
- }
299
- }
300
-
301
- // Plan validation.
302
- $plans = (array) json_decode( get_post_meta( $notification->ID, 'plans', true ) );
303
- $continue = false;
304
- if ( ! empty( $plans ) ) {
305
- $level = $this->get_plan_level();
306
- if ( in_array( $level, $plans, true ) ) {
307
- $continue = true;
308
- }
309
-
310
- if ( ! $continue ) {
311
- unset( $plugin_notifications[ $key ] );
312
- }
313
- }
314
- }
315
-
316
- return $plugin_notifications;
317
- }
318
-
319
- /**
320
- * Grab the current plan level.
321
- *
322
- * @since 1.0.0
323
- *
324
- * @return string The current plan level.
325
- */
326
- public function get_plan_level() {
327
- // Prepare variables.
328
- $key = '';
329
- $level = '';
330
- $option = false;
331
- switch ( $this->plugin ) {
332
- case 'wpforms' :
333
- $option = get_option( 'wpforms_license' );
334
- $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
335
- $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
336
-
337
- // Possibly check for a constant.
338
- if ( empty( $key ) && defined( 'WPFORMS_LICENSE_KEY' ) ) {
339
- $key = WPFORMS_LICENSE_KEY;
340
- }
341
- break;
342
- case 'mi' :
343
- $option = get_option( 'monsterinsights_license' );
344
- $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
345
- $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
346
-
347
- // Possibly check for a constant.
348
- if ( empty( $key ) && defined( 'MONSTERINSIGHTS_LICENSE_KEY' ) && is_string( MONSTERINSIGHTS_LICENSE_KEY ) && strlen( MONSTERINSIGHTS_LICENSE_KEY ) > 10 ) {
349
- $key = MONSTERINSIGHTS_LICENSE_KEY;
350
- }
351
- break;
352
- case 'sol' :
353
- $option = get_option( 'soliloquy' );
354
- $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
355
- $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
356
-
357
- // Possibly check for a constant.
358
- if ( empty( $key ) && defined( 'SOLILOQUY_LICENSE_KEY' ) ) {
359
- $key = SOLILOQUY_LICENSE_KEY;
360
- }
361
- break;
362
- case 'envira' :
363
- $option = get_option( 'envira_gallery' );
364
- $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
365
- $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
366
-
367
- // Possibly check for a constant.
368
- if ( empty( $key ) && defined( 'ENVIRA_LICENSE_KEY' ) ) {
369
- $key = ENVIRA_LICENSE_KEY;
370
- }
371
- break;
372
- case 'om' :
373
- $option = get_option( 'optin_monster_api' );
374
- $key = is_array( $option ) && isset( $option['api']['apikey'] ) ? $option['api']['apikey'] : '';
375
-
376
- // Possibly check for a constant.
377
- if ( empty( $key ) && defined( 'OPTINMONSTER_REST_API_LICENSE_KEY' ) ) {
378
- $key = OPTINMONSTER_REST_API_LICENSE_KEY;
379
- }
380
-
381
- // If the key is still empty, check for the old legacy key.
382
- if ( empty( $key ) ) {
383
- $key = is_array( $option ) && isset( $option['api']['key'] ) ? $option['api']['key'] : '';
384
- }
385
- break;
386
- }
387
-
388
- // Possibly set the level to 'none' if the key is empty and no level has been set.
389
- if ( empty( $key ) && empty( $level ) ) {
390
- $level = 'none';
391
- }
392
-
393
- // Normalize the level.
394
- switch ( $level ) {
395
- case 'bronze' :
396
- case 'personal' :
397
- $level = 'basic';
398
- break;
399
- case 'silver' :
400
- case 'multi' :
401
- $level = 'plus';
402
- break;
403
- case 'gold' :
404
- case 'developer' :
405
- $level = 'pro';
406
- break;
407
- case 'platinum' :
408
- case 'master' :
409
- $level = 'ultimate';
410
- break;
411
- }
412
-
413
- // Return the plan level.
414
- return $level;
415
- }
416
-
417
- /**
418
- * Dismiss the notification via AJAX.
419
- *
420
- * @since 1.0.0
421
- */
422
- public function dismiss_notification() {
423
- if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
424
- die;
425
- }
426
-
427
- $notification_id = intval( $_POST['notification_id'] );
428
- update_post_meta( $notification_id, 'viewed', 1 );
429
- die;
430
- }
431
-
432
- /**
433
- * Revokes notifications.
434
- *
435
- * @since 1.0.0
436
- *
437
- * @param array $ids An array of notification IDs to revoke.
438
- */
439
- public function revoke_notifications( $ids ) {
440
- // Loop through each of the IDs and find the post that has it as meta.
441
- foreach ( (array) $ids as $id ) {
442
- $notifications = $this->get_plugin_notifications( -1, array( 'post_status' => 'all', 'meta_key' => 'notification_id', 'meta_value' => $id ) );
443
- if ( $notifications ) {
444
- foreach ( $notifications as $notification ) {
445
- update_post_meta( $notification->ID, 'viewed', 1 );
446
- }
447
- }
448
- }
449
- }
450
- }
1
+ <?php
2
+
3
+ /**
4
+ * Awesome Motive Notifications
5
+ *
6
+ * This creates a custom post type (if it doesn't exist) and calls the API to
7
+ * retrieve notifications for this product.
8
+ *
9
+ * @package AwesomeMotive
10
+ * @author Benjamin Rojas
11
+ * @license GPL-2.0+
12
+ * @copyright Copyright (c) 2017, Retyp LLC
13
+ * @version 1.0.2
14
+ */
15
+ class WPMS_AM_Notification {
16
+ /**
17
+ * The api url we are calling.
18
+ *
19
+ * @since 1.0.0
20
+ *
21
+ * @var string
22
+ */
23
+ public $api_url = 'https://api.awesomemotive.com/v1/notification/';
24
+
25
+ /**
26
+ * A unique slug for this plugin.
27
+ * (Not the WordPress plugin slug)
28
+ *
29
+ * @since 1.0.0
30
+ *
31
+ * @var string
32
+ */
33
+ public $plugin;
34
+
35
+ /**
36
+ * The current plugin version.
37
+ *
38
+ * @since 1.0.0
39
+ *
40
+ * @var string
41
+ */
42
+ public $plugin_version;
43
+
44
+ /**
45
+ * Flag if a notice has been registered.
46
+ *
47
+ * @since 1.0.0
48
+ *
49
+ * @var bool
50
+ */
51
+ public static $registered = false;
52
+
53
+ /**
54
+ * Construct.
55
+ *
56
+ * @since 1.0.0
57
+ *
58
+ * @param string $plugin The plugin slug.
59
+ * @param mixed $version The version of the plugin.
60
+ */
61
+ public function __construct( $plugin = '', $version = 0 ) {
62
+ $this->plugin = $plugin;
63
+ $this->plugin_version = $version;
64
+
65
+ add_action( 'init', array( $this, 'custom_post_type' ) );
66
+ add_action( 'admin_init', array( $this, 'get_remote_notifications' ), 100 );
67
+ add_action( 'admin_notices', array( $this, 'display_notifications' ) );
68
+ add_action( 'wp_ajax_am_notification_dismiss', array( $this, 'dismiss_notification' ) );
69
+ }
70
+
71
+ /**
72
+ * Registers a custom post type.
73
+ *
74
+ * @since 1.0.0
75
+ */
76
+ public function custom_post_type() {
77
+ register_post_type( 'amn_' . $this->plugin, array(
78
+ 'label' => $this->plugin . ' Announcements',
79
+ 'can_export' => false,
80
+ 'supports' => false,
81
+ ) );
82
+ }
83
+
84
+ /**
85
+ * Retrieve the remote notifications if the time has expired.
86
+ *
87
+ * @since 1.0.0
88
+ */
89
+ public function get_remote_notifications() {
90
+ if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
91
+ return;
92
+ }
93
+
94
+ $last_checked = get_option( '_amn_' . $this->plugin . '_last_checked', strtotime( '-1 week' ) );
95
+
96
+ if ( $last_checked < strtotime( 'today midnight' ) ) {
97
+ $plugin_notifications = $this->get_plugin_notifications( 1 );
98
+ $notification_id = null;
99
+
100
+ if ( ! empty( $plugin_notifications ) ) {
101
+ // Unset it from the array.
102
+ $notification = $plugin_notifications[0];
103
+ $notification_id = get_post_meta( $notification->ID, 'notification_id', true );
104
+ }
105
+
106
+ $response = wp_remote_retrieve_body( wp_remote_post( $this->api_url, array(
107
+ 'body' => array(
108
+ 'slug' => $this->plugin,
109
+ 'version' => $this->plugin_version,
110
+ 'last_notification' => $notification_id,
111
+ ),
112
+ ) ) );
113
+
114
+ $data = json_decode( $response );
115
+
116
+ if ( ! empty( $data->id ) ) {
117
+ $notifications = array();
118
+
119
+ foreach ( (array) $data->slugs as $slug ) {
120
+ $notifications = array_merge(
121
+ $notifications,
122
+ (array) get_posts(
123
+ array(
124
+ 'post_type' => 'amn_' . $slug,
125
+ 'post_status' => 'all',
126
+ 'meta_key' => 'notification_id',
127
+ 'meta_value' => $data->id,
128
+ )
129
+ )
130
+ );
131
+ }
132
+
133
+ if ( empty( $notifications ) ) {
134
+ $new_notification_id = wp_insert_post( array(
135
+ 'post_content' => wp_kses_post( $data->content ),
136
+ 'post_type' => 'amn_' . $this->plugin,
137
+ ) );
138
+
139
+ update_post_meta( $new_notification_id, 'notification_id', absint( $data->id ) );
140
+ update_post_meta( $new_notification_id, 'type', sanitize_text_field( trim( $data->type ) ) );
141
+ update_post_meta( $new_notification_id, 'dismissable', (bool) $data->dismissible ? 1 : 0 );
142
+ update_post_meta( $new_notification_id, 'location', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->location ) : json_encode( $data->location ) );
143
+ update_post_meta( $new_notification_id, 'version', sanitize_text_field( trim( $data->version ) ) );
144
+ update_post_meta( $new_notification_id, 'viewed', 0 );
145
+ update_post_meta( $new_notification_id, 'expiration', $data->expiration ? absint( $data->expiration ) : false );
146
+ update_post_meta( $new_notification_id, 'plans', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->plans ) : json_encode( $data->plans ) );
147
+ }
148
+ }
149
+
150
+ // Possibly revoke notifications.
151
+ if ( ! empty( $data->revoked ) ) {
152
+ $this->revoke_notifications( $data->revoked );
153
+ }
154
+
155
+ // Set the option now so we can't run this again until after 24 hours.
156
+ update_option( '_amn_' . $this->plugin . '_last_checked', strtotime( 'today midnight' ) );
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Get local plugin notifications that have already been set.
162
+ *
163
+ * @since 1.0.0
164
+ *
165
+ * @param integer $limit Set the limit for how many posts to retrieve.
166
+ * @param array $args Any top-level arguments to add to the array.
167
+ *
168
+ * @return WP_Post[] WP_Post that match the query.
169
+ */
170
+ public function get_plugin_notifications( $limit = -1, $args = array() ) {
171
+ return get_posts(
172
+ array(
173
+ 'posts_per_page' => $limit,
174
+ 'post_type' => 'amn_' . $this->plugin,
175
+ ) + $args
176
+ );
177
+ }
178
+
179
+ /**
180
+ * Display any notifications that should be displayed.
181
+ *
182
+ * @since 1.0.0
183
+ */
184
+ public function display_notifications() {
185
+ if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
186
+ return;
187
+ }
188
+
189
+ $plugin_notifications = $this->get_plugin_notifications( -1, array(
190
+ 'post_status' => 'all',
191
+ 'meta_key' => 'viewed',
192
+ 'meta_value' => '0',
193
+ ) );
194
+
195
+ $plugin_notifications = $this->validate_notifications( $plugin_notifications );
196
+
197
+ if ( ! empty( $plugin_notifications ) && ! self::$registered ) {
198
+ foreach ( $plugin_notifications as $notification ) {
199
+ $dismissable = get_post_meta( $notification->ID, 'dismissable', true );
200
+ $type = get_post_meta( $notification->ID, 'type', true );
201
+ ?>
202
+ <div class="am-notification am-notification-<?php echo $notification->ID; ?> notice notice-<?php echo $type; ?><?php echo $dismissable ? ' is-dismissible' : ''; ?>">
203
+ <?php echo $notification->post_content; ?>
204
+ </div>
205
+ <script type="text/javascript">
206
+ jQuery(document).ready(function ($) {
207
+ $(document).on('click', '.am-notification-<?php echo $notification->ID; ?> button.notice-dismiss', function (event) {
208
+ $.post(ajaxurl, {
209
+ action: 'am_notification_dismiss',
210
+ notification_id: '<?php echo $notification->ID; ?>'
211
+ });
212
+ });
213
+ });
214
+ </script>
215
+ <?php
216
+ }
217
+
218
+ self::$registered = true;
219
+ }
220
+ }
221
+
222
+ /**
223
+ * Validate the notifications before displaying them.
224
+ *
225
+ * @since 1.0.0
226
+ *
227
+ * @param array $plugin_notifications An array of plugin notifications.
228
+ *
229
+ * @return array A filtered array of plugin notifications.
230
+ */
231
+ public function validate_notifications( $plugin_notifications ) {
232
+ global $pagenow;
233
+
234
+ foreach ( $plugin_notifications as $key => $notification ) {
235
+ // Location validation.
236
+ $location = (array) json_decode( get_post_meta( $notification->ID, 'location', true ) );
237
+ $continue = false;
238
+ if ( ! in_array( 'everywhere', $location, true ) ) {
239
+ if ( in_array( 'index.php', $location, true ) && 'index.php' === $pagenow ) {
240
+ $continue = true;
241
+ }
242
+
243
+ if ( in_array( 'plugins.php', $location, true ) && 'plugins.php' === $pagenow ) {
244
+ $continue = true;
245
+ }
246
+
247
+ if ( ! $continue ) {
248
+ unset( $plugin_notifications[ $key ] );
249
+ }
250
+ }
251
+
252
+ // Plugin validation (OR conditional).
253
+ $plugins = (array) json_decode( get_post_meta( $notification->ID, 'plugins', true ) );
254
+ $continue = false;
255
+ if ( ! empty( $plugins ) ) {
256
+ foreach ( $plugins as $plugin ) {
257
+ if ( is_plugin_active( $plugin ) ) {
258
+ $continue = true;
259
+ }
260
+ }
261
+
262
+ if ( ! $continue ) {
263
+ unset( $plugin_notifications[ $key ] );
264
+ }
265
+ }
266
+
267
+ // Theme validation.
268
+ $theme = get_post_meta( $notification->ID, 'theme', true );
269
+ $continue = (string) wp_get_theme() === $theme;
270
+
271
+ if ( ! empty( $theme ) && ! $continue ) {
272
+ unset( $plugin_notifications[ $key ] );
273
+ }
274
+
275
+ // Version validation.
276
+ $version = get_post_meta( $notification->ID, 'version', true );
277
+ $continue = false;
278
+ if ( ! empty( $version ) ) {
279
+ if ( version_compare( $this->plugin_version, $version, '<=' ) ) {
280
+ $continue = true;
281
+ }
282
+
283
+ if ( ! $continue ) {
284
+ unset( $plugin_notifications[ $key ] );
285
+ }
286
+ }
287
+
288
+ // Expiration validation.
289
+ $expiration = get_post_meta( $notification->ID, 'expiration', true );
290
+ $continue = false;
291
+ if ( ! empty( $expiration ) ) {
292
+ if ( $expiration > time() ) {
293
+ $continue = true;
294
+ }
295
+
296
+ if ( ! $continue ) {
297
+ unset( $plugin_notifications[ $key ] );
298
+ }
299
+ }
300
+
301
+ // Plan validation.
302
+ $plans = (array) json_decode( get_post_meta( $notification->ID, 'plans', true ) );
303
+ $continue = false;
304
+ if ( ! empty( $plans ) ) {
305
+ $level = $this->get_plan_level();
306
+ if ( in_array( $level, $plans, true ) ) {
307
+ $continue = true;
308
+ }
309
+
310
+ if ( ! $continue ) {
311
+ unset( $plugin_notifications[ $key ] );
312
+ }
313
+ }
314
+ }
315
+
316
+ return $plugin_notifications;
317
+ }
318
+
319
+ /**
320
+ * Grab the current plan level.
321
+ *
322
+ * @since 1.0.0
323
+ *
324
+ * @return string The current plan level.
325
+ */
326
+ public function get_plan_level() {
327
+ // Prepare variables.
328
+ $key = '';
329
+ $level = '';
330
+ $option = false;
331
+ switch ( $this->plugin ) {
332
+ case 'wpforms' :
333
+ $option = get_option( 'wpforms_license' );
334
+ $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
335
+ $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
336
+
337
+ // Possibly check for a constant.
338
+ if ( empty( $key ) && defined( 'WPFORMS_LICENSE_KEY' ) ) {
339
+ $key = WPFORMS_LICENSE_KEY;
340
+ }
341
+ break;
342
+ case 'mi' :
343
+ $option = get_option( 'monsterinsights_license' );
344
+ $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
345
+ $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
346
+
347
+ // Possibly check for a constant.
348
+ if ( empty( $key ) && defined( 'MONSTERINSIGHTS_LICENSE_KEY' ) && is_string( MONSTERINSIGHTS_LICENSE_KEY ) && strlen( MONSTERINSIGHTS_LICENSE_KEY ) > 10 ) {
349
+ $key = MONSTERINSIGHTS_LICENSE_KEY;
350
+ }
351
+ break;
352
+ case 'sol' :
353
+ $option = get_option( 'soliloquy' );
354
+ $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
355
+ $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
356
+
357
+ // Possibly check for a constant.
358
+ if ( empty( $key ) && defined( 'SOLILOQUY_LICENSE_KEY' ) ) {
359
+ $key = SOLILOQUY_LICENSE_KEY;
360
+ }
361
+ break;
362
+ case 'envira' :
363
+ $option = get_option( 'envira_gallery' );
364
+ $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
365
+ $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
366
+
367
+ // Possibly check for a constant.
368
+ if ( empty( $key ) && defined( 'ENVIRA_LICENSE_KEY' ) ) {
369
+ $key = ENVIRA_LICENSE_KEY;
370
+ }
371
+ break;
372
+ case 'om' :
373
+ $option = get_option( 'optin_monster_api' );
374
+ $key = is_array( $option ) && isset( $option['api']['apikey'] ) ? $option['api']['apikey'] : '';
375
+
376
+ // Possibly check for a constant.
377
+ if ( empty( $key ) && defined( 'OPTINMONSTER_REST_API_LICENSE_KEY' ) ) {
378
+ $key = OPTINMONSTER_REST_API_LICENSE_KEY;
379
+ }
380
+
381
+ // If the key is still empty, check for the old legacy key.
382
+ if ( empty( $key ) ) {
383
+ $key = is_array( $option ) && isset( $option['api']['key'] ) ? $option['api']['key'] : '';
384
+ }
385
+ break;
386
+ }
387
+
388
+ // Possibly set the level to 'none' if the key is empty and no level has been set.
389
+ if ( empty( $key ) && empty( $level ) ) {
390
+ $level = 'none';
391
+ }
392
+
393
+ // Normalize the level.
394
+ switch ( $level ) {
395
+ case 'bronze' :
396
+ case 'personal' :
397
+ $level = 'basic';
398
+ break;
399
+ case 'silver' :
400
+ case 'multi' :
401
+ $level = 'plus';
402
+ break;
403
+ case 'gold' :
404
+ case 'developer' :
405
+ $level = 'pro';
406
+ break;
407
+ case 'platinum' :
408
+ case 'master' :
409
+ $level = 'ultimate';
410
+ break;
411
+ }
412
+
413
+ // Return the plan level.
414
+ return $level;
415
+ }
416
+
417
+ /**
418
+ * Dismiss the notification via AJAX.
419
+ *
420
+ * @since 1.0.0
421
+ */
422
+ public function dismiss_notification() {
423
+ if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
424
+ die;
425
+ }
426
+
427
+ $notification_id = intval( $_POST['notification_id'] );
428
+ update_post_meta( $notification_id, 'viewed', 1 );
429
+ die;
430
+ }
431
+
432
+ /**
433
+ * Revokes notifications.
434
+ *
435
+ * @since 1.0.0
436
+ *
437
+ * @param array $ids An array of notification IDs to revoke.
438
+ */
439
+ public function revoke_notifications( $ids ) {
440
+ // Loop through each of the IDs and find the post that has it as meta.
441
+ foreach ( (array) $ids as $id ) {
442
+ $notifications = $this->get_plugin_notifications( -1, array( 'post_status' => 'all', 'meta_key' => 'notification_id', 'meta_value' => $id ) );
443
+ if ( $notifications ) {
444
+ foreach ( $notifications as $notification ) {
445
+ update_post_meta( $notification->ID, 'viewed', 1 );
446
+ }
447
+ }
448
+ }
449
+ }
450
+ }
languages/wp-mail-smtp.pot CHANGED
@@ -142,11 +142,11 @@ msgstr ""
142
msgid "Use TLS encryption."
143
msgstr ""
144
145
- #: wp_mail_smtp.php:462, src/Providers/OptionAbstract.php:186
146
msgid "TLS is not the same as STARTTLS. For most servers SSL is the recommended option."
147
msgstr ""
148
149
- #: wp_mail_smtp.php:467, wp_mail_smtp.php:471, src/Providers/OptionAbstract.php:195
150
msgid "Authentication"
151
msgstr ""
152
@@ -238,31 +238,43 @@ msgstr ""
238
msgid "TLS"
239
msgstr ""
240
241
- #: src/Providers/OptionAbstract.php:205
242
msgid "On"
243
msgstr ""
244
245
- #: src/Providers/OptionAbstract.php:206
246
msgid "Off"
247
msgstr ""
248
249
- #: src/Providers/OptionAbstract.php:214
250
msgid "SMTP Username"
251
msgstr ""
252
253
- #: src/Providers/OptionAbstract.php:228
254
msgid "SMTP Password"
255
msgstr ""
256
257
- #: src/Providers/OptionAbstract.php:242
258
msgid "The password is stored in plain text. We highly recommend you setup your password in your WordPress configuration file for improved security; to do this add the lines below to your %s file."
259
msgstr ""
260
261
- #: src/Providers/OptionAbstract.php:279
262
msgid "%1$s requires PHP %2$s to work and does not support your current PHP version %3$s. Please contact your host and request a PHP upgrade to the latest one."
263
msgstr ""
264
265
- #: src/Providers/OptionAbstract.php:286
266
msgid "Meanwhile you can switch to the \"Other SMTP\" Mailer option."
267
msgstr ""
268
@@ -350,6 +362,10 @@ msgstr ""
350
msgid "The related debugging output is shown below:"
351
msgstr ""
352
353
#: src/Providers/Gmail/Options.php:25
354
msgid "Gmail"
355
msgstr ""
142
msgid "Use TLS encryption."
143
msgstr ""
144
145
+ #: wp_mail_smtp.php:462
146
msgid "TLS is not the same as STARTTLS. For most servers SSL is the recommended option."
147
msgstr ""
148
149
+ #: wp_mail_smtp.php:467, wp_mail_smtp.php:471, src/Providers/OptionAbstract.php:216
150
msgid "Authentication"
151
msgstr ""
152
238
msgid "TLS"
239
msgstr ""
240
241
+ #: src/Providers/OptionAbstract.php:186
242
+ msgid "For most servers TLS is the recommended option. If your SMTP provider offers both SSL and TLS options, we recommend using TLS."
243
+ msgstr ""
244
+
245
+ #: src/Providers/OptionAbstract.php:194
246
+ msgid "Auto TLS"
247
+ msgstr ""
248
+
249
+ #: src/Providers/OptionAbstract.php:204, src/Providers/OptionAbstract.php:226
250
msgid "On"
251
msgstr ""
252
253
+ #: src/Providers/OptionAbstract.php:205, src/Providers/OptionAbstract.php:227
254
msgid "Off"
255
msgstr ""
256
257
+ #: src/Providers/OptionAbstract.php:208
258
+ msgid "By default TLS encryption is automatically used if the server supports it, which is recommended. In some cases, due to server misconfigurations, this can cause issues and may need to be disabled."
259
+ msgstr ""
260
+
261
+ #: src/Providers/OptionAbstract.php:235
262
msgid "SMTP Username"
263
msgstr ""
264
265
+ #: src/Providers/OptionAbstract.php:249
266
msgid "SMTP Password"
267
msgstr ""
268
269
+ #: src/Providers/OptionAbstract.php:263
270
msgid "The password is stored in plain text. We highly recommend you setup your password in your WordPress configuration file for improved security; to do this add the lines below to your %s file."
271
msgstr ""
272
273
+ #: src/Providers/OptionAbstract.php:300
274
msgid "%1$s requires PHP %2$s to work and does not support your current PHP version %3$s. Please contact your host and request a PHP upgrade to the latest one."
275
msgstr ""
276
277
+ #: src/Providers/OptionAbstract.php:307
278
msgid "Meanwhile you can switch to the \"Other SMTP\" Mailer option."
279
msgstr ""
280
362
msgid "The related debugging output is shown below:"
363
msgstr ""
364
365
+ #: src/Admin/Pages/Test.php:136
366
+ msgid "Please copy only the content of the error debug message above, identified with an orange left border, into the support forum topic if you experience any issues."
367
+ msgstr ""
368
+
369
#: src/Providers/Gmail/Options.php:25
370
msgid "Gmail"
371
msgstr ""
readme.txt CHANGED
@@ -146,6 +146,16 @@ By all means please contact us to discuss features or options you'd like to see
146
147
== Changelog ==
148
149
= 1.0.2 - 2017-12-12 =
150
* Fixed: PHPMailer using incorrect SMTPSecure value.
151
146
147
== Changelog ==
148
149
+ = 1.1.0 - 2017-12-18 =
150
+ * Added: New option "Auto TLS" for SMTP mailer. Default is enabled. Migration routine for all sites.
151
+ * Changed: Improve debug output - clear styles and context-aware content.
152
+ * Changed: Better exceptions handling for Google authentication process.
153
+ * Changed: Do not sanitize passwords, api keys etc - as they may contain special characters in certain order and sanitization will break those values.
154
+ * Changed: Improve wording of some helpful texts inside plugin admin area.
155
+ * Fixed: Do not include certain files in dependency libraries that are not used by Google mailer. This should stop flagging plugin by Wordfence and VaultPress.
156
+ * Fixed: Constants usage is working now, to define the SMTP password, for example.
157
+ * Fixed: Notice for default mailer.
158
+
159
= 1.0.2 - 2017-12-12 =
160
* Fixed: PHPMailer using incorrect SMTPSecure value.
161
src/AM_Notification.php CHANGED
@@ -1,452 +1,452 @@
1
- <?php
2
-
3
- namespace WPMailSMTP;
4
-
5
- /**
6
- * Awesome Motive Notifications
7
- *
8
- * This creates a custom post type (if it doesn't exist) and calls the API to
9
- * retrieve notifications for this product.
10
- *
11
- * @package AwesomeMotive
12
- * @author Benjamin Rojas
13
- * @license GPL-2.0+
14
- * @copyright Copyright (c) 2017, Retyp LLC
15
- * @version 1.0.2
16
- */
17
- class AM_Notification {
18
- /**
19
- * The api url we are calling.
20
- *
21
- * @since 1.0.0
22
- *
23
- * @var string
24
- */
25
- public $api_url = 'https://api.awesomemotive.com/v1/notification/';
26
-
27
- /**
28
- * A unique slug for this plugin.
29
- * (Not the WordPress plugin slug)
30
- *
31
- * @since 1.0.0
32
- *
33
- * @var string
34
- */
35
- public $plugin;
36
-
37
- /**
38
- * The current plugin version.
39
- *
40
- * @since 1.0.0
41
- *
42
- * @var string
43
- */
44
- public $plugin_version;
45
-
46
- /**
47
- * Flag if a notice has been registered.
48
- *
49
- * @since 1.0.0
50
- *
51
- * @var bool
52
- */
53
- public static $registered = false;
54
-
55
- /**
56
- * Construct.
57
- *
58
- * @since 1.0.0
59
- *
60
- * @param string $plugin The plugin slug.
61
- * @param mixed $version The version of the plugin.
62
- */
63
- public function __construct( $plugin = '', $version = 0 ) {
64
- $this->plugin = $plugin;
65
- $this->plugin_version = $version;
66
-
67
- add_action( 'init', array( $this, 'custom_post_type' ) );
68
- add_action( 'admin_init', array( $this, 'get_remote_notifications' ), 100 );
69
- add_action( 'admin_notices', array( $this, 'display_notifications' ) );
70
- add_action( 'wp_ajax_am_notification_dismiss', array( $this, 'dismiss_notification' ) );
71
- }
72
-
73
- /**
74
- * Registers a custom post type.
75
- *
76
- * @since 1.0.0
77
- */
78
- public function custom_post_type() {
79
- register_post_type( 'amn_' . $this->plugin, array(
80
- 'label' => $this->plugin . ' Announcements',
81
- 'can_export' => false,
82
- 'supports' => false,
83
- ) );
84
- }
85
-
86
- /**
87
- * Retrieve the remote notifications if the time has expired.
88
- *
89
- * @since 1.0.0
90
- */
91
- public function get_remote_notifications() {
92
- if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
93
- return;
94
- }
95
-
96
- $last_checked = get_option( '_amn_' . $this->plugin . '_last_checked', strtotime( '-1 week' ) );
97
-
98
- if ( $last_checked < strtotime( 'today midnight' ) ) {
99
- $plugin_notifications = $this->get_plugin_notifications( 1 );
100
- $notification_id = null;
101
-
102
- if ( ! empty( $plugin_notifications ) ) {
103
- // Unset it from the array.
104
- $notification = $plugin_notifications[0];
105
- $notification_id = get_post_meta( $notification->ID, 'notification_id', true );
106
- }
107
-
108
- $response = wp_remote_retrieve_body( wp_remote_post( $this->api_url, array(
109
- 'body' => array(
110
- 'slug' => $this->plugin,
111
- 'version' => $this->plugin_version,
112
- 'last_notification' => $notification_id,
113
- ),
114
- ) ) );
115
-
116
- $data = json_decode( $response );
117
-
118
- if ( ! empty( $data->id ) ) {
119
- $notifications = array();
120
-
121
- foreach ( (array) $data->slugs as $slug ) {
122
- $notifications = array_merge(
123
- $notifications,
124
- (array) get_posts(
125
- array(
126
- 'post_type' => 'amn_' . $slug,
127
- 'post_status' => 'all',
128
- 'meta_key' => 'notification_id',
129
- 'meta_value' => $data->id,
130
- )
131
- )
132
- );
133
- }
134
-
135
- if ( empty( $notifications ) ) {
136
- $new_notification_id = wp_insert_post( array(
137
- 'post_content' => wp_kses_post( $data->content ),
138
- 'post_type' => 'amn_' . $this->plugin,
139
- ) );
140
-
141
- update_post_meta( $new_notification_id, 'notification_id', absint( $data->id ) );
142
- update_post_meta( $new_notification_id, 'type', sanitize_text_field( trim( $data->type ) ) );
143
- update_post_meta( $new_notification_id, 'dismissable', (bool) $data->dismissible ? 1 : 0 );
144
- update_post_meta( $new_notification_id, 'location', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->location ) : json_encode( $data->location ) );
145
- update_post_meta( $new_notification_id, 'version', sanitize_text_field( trim( $data->version ) ) );
146
- update_post_meta( $new_notification_id, 'viewed', 0 );
147
- update_post_meta( $new_notification_id, 'expiration', $data->expiration ? absint( $data->expiration ) : false );
148
- update_post_meta( $new_notification_id, 'plans', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->plans ) : json_encode( $data->plans ) );
149
- }
150
- }
151
-
152
- // Possibly revoke notifications.
153
- if ( ! empty( $data->revoked ) ) {
154
- $this->revoke_notifications( $data->revoked );
155
- }
156
-
157
- // Set the option now so we can't run this again until after 24 hours.
158
- update_option( '_amn_' . $this->plugin . '_last_checked', strtotime( 'today midnight' ) );
159
- }
160
- }
161
-
162
- /**
163
- * Get local plugin notifications that have already been set.
164
- *
165
- * @since 1.0.0
166
- *
167
- * @param integer $limit Set the limit for how many posts to retrieve.
168
- * @param array $args Any top-level arguments to add to the array.
169
- *
170
- * @return WP_Post[] WP_Post that match the query.
171
- */
172
- public function get_plugin_notifications( $limit = -1, $args = array() ) {
173
- return get_posts(
174
- array(
175
- 'posts_per_page' => $limit,
176
- 'post_type' => 'amn_' . $this->plugin,
177
- ) + $args
178
- );
179
- }
180
-
181
- /**
182
- * Display any notifications that should be displayed.
183
- *
184
- * @since 1.0.0
185
- */
186
- public function display_notifications() {
187
- if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
188
- return;
189
- }
190
-
191
- $plugin_notifications = $this->get_plugin_notifications( -1, array(
192
- 'post_status' => 'all',
193
- 'meta_key' => 'viewed',
194
- 'meta_value' => '0',
195
- ) );
196
-
197
- $plugin_notifications = $this->validate_notifications( $plugin_notifications );
198
-
199
- if ( ! empty( $plugin_notifications ) && ! self::$registered ) {
200
- foreach ( $plugin_notifications as $notification ) {
201
- $dismissable = get_post_meta( $notification->ID, 'dismissable', true );
202
- $type = get_post_meta( $notification->ID, 'type', true );
203
- ?>
204
- <div class="am-notification am-notification-<?php echo $notification->ID; ?> notice notice-<?php echo $type; ?><?php echo $dismissable ? ' is-dismissible' : ''; ?>">
205
- <?php echo $notification->post_content; ?>
206
- </div>
207
- <script type="text/javascript">
208
- jQuery(document).ready(function ($) {
209
- $(document).on('click', '.am-notification-<?php echo $notification->ID; ?> button.notice-dismiss', function (event) {
210
- $.post(ajaxurl, {
211
- action: 'am_notification_dismiss',
212
- notification_id: '<?php echo $notification->ID; ?>'
213
- });
214
- });
215
- });
216
- </script>
217
- <?php
218
- }
219
-
220
- self::$registered = true;
221
- }
222
- }
223
-
224
- /**
225
- * Validate the notifications before displaying them.
226
- *
227
- * @since 1.0.0
228
- *
229
- * @param array $plugin_notifications An array of plugin notifications.
230
- *
231
- * @return array A filtered array of plugin notifications.
232
- */
233
- public function validate_notifications( $plugin_notifications ) {
234
- global $pagenow;
235
-
236
- foreach ( $plugin_notifications as $key => $notification ) {
237
- // Location validation.
238
- $location = (array) json_decode( get_post_meta( $notification->ID, 'location', true ) );
239
- $continue = false;
240
- if ( ! in_array( 'everywhere', $location, true ) ) {
241
- if ( in_array( 'index.php', $location, true ) && 'index.php' === $pagenow ) {
242
- $continue = true;
243
- }
244
-
245
- if ( in_array( 'plugins.php', $location, true ) && 'plugins.php' === $pagenow ) {
246
- $continue = true;
247
- }
248
-
249
- if ( ! $continue ) {
250
- unset( $plugin_notifications[ $key ] );
251
- }
252
- }
253
-
254
- // Plugin validation (OR conditional).
255
- $plugins = (array) json_decode( get_post_meta( $notification->ID, 'plugins', true ) );
256
- $continue = false;
257
- if ( ! empty( $plugins ) ) {
258
- foreach ( $plugins as $plugin ) {
259
- if ( is_plugin_active( $plugin ) ) {
260
- $continue = true;
261
- }
262
- }
263
-
264
- if ( ! $continue ) {
265
- unset( $plugin_notifications[ $key ] );
266
- }
267
- }
268
-
269
- // Theme validation.
270
- $theme = get_post_meta( $notification->ID, 'theme', true );
271
- $continue = (string) wp_get_theme() === $theme;
272
-
273
- if ( ! empty( $theme ) && ! $continue ) {
274
- unset( $plugin_notifications[ $key ] );
275
- }
276
-
277
- // Version validation.
278
- $version = get_post_meta( $notification->ID, 'version', true );
279
- $continue = false;
280
- if ( ! empty( $version ) ) {
281
- if ( version_compare( $this->plugin_version, $version, '<=' ) ) {
282
- $continue = true;
283
- }
284
-
285
- if ( ! $continue ) {
286
- unset( $plugin_notifications[ $key ] );
287
- }
288
- }
289
-
290
- // Expiration validation.
291
- $expiration = get_post_meta( $notification->ID, 'expiration', true );
292
- $continue = false;
293
- if ( ! empty( $expiration ) ) {
294
- if ( $expiration > time() ) {
295
- $continue = true;
296
- }
297
-
298
- if ( ! $continue ) {
299
- unset( $plugin_notifications[ $key ] );
300
- }
301
- }
302
-
303
- // Plan validation.
304
- $plans = (array) json_decode( get_post_meta( $notification->ID, 'plans', true ) );
305
- $continue = false;
306
- if ( ! empty( $plans ) ) {
307
- $level = $this->get_plan_level();
308
- if ( in_array( $level, $plans, true ) ) {
309
- $continue = true;
310
- }
311
-
312
- if ( ! $continue ) {
313
- unset( $plugin_notifications[ $key ] );
314
- }
315
- }
316
- }
317
-
318
- return $plugin_notifications;
319
- }
320
-
321
- /**
322
- * Grab the current plan level.
323
- *
324
- * @since 1.0.0
325
- *
326
- * @return string The current plan level.
327
- */
328
- public function get_plan_level() {
329
- // Prepare variables.
330
- $key = '';
331
- $level = '';
332
- $option = false;
333
- switch ( $this->plugin ) {
334
- case 'wpforms' :
335
- $option = get_option( 'wpforms_license' );
336
- $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
337
- $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
338
-
339
- // Possibly check for a constant.
340
- if ( empty( $key ) && defined( 'WPFORMS_LICENSE_KEY' ) ) {
341
- $key = WPFORMS_LICENSE_KEY;
342
- }
343
- break;
344
- case 'mi' :
345
- $option = get_option( 'monsterinsights_license' );
346
- $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
347
- $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
348
-
349
- // Possibly check for a constant.
350
- if ( empty( $key ) && defined( 'MONSTERINSIGHTS_LICENSE_KEY' ) && is_string( MONSTERINSIGHTS_LICENSE_KEY ) && strlen( MONSTERINSIGHTS_LICENSE_KEY ) > 10 ) {
351
- $key = MONSTERINSIGHTS_LICENSE_KEY;
352
- }
353
- break;
354
- case 'sol' :
355
- $option = get_option( 'soliloquy' );
356
- $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
357
- $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
358
-
359
- // Possibly check for a constant.
360
- if ( empty( $key ) && defined( 'SOLILOQUY_LICENSE_KEY' ) ) {
361
- $key = SOLILOQUY_LICENSE_KEY;
362
- }
363
- break;
364
- case 'envira' :
365
- $option = get_option( 'envira_gallery' );
366
- $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
367
- $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
368
-
369
- // Possibly check for a constant.
370
- if ( empty( $key ) && defined( 'ENVIRA_LICENSE_KEY' ) ) {
371
- $key = ENVIRA_LICENSE_KEY;
372
- }
373
- break;
374
- case 'om' :
375
- $option = get_option( 'optin_monster_api' );
376
- $key = is_array( $option ) && isset( $option['api']['apikey'] ) ? $option['api']['apikey'] : '';
377
-
378
- // Possibly check for a constant.
379
- if ( empty( $key ) && defined( 'OPTINMONSTER_REST_API_LICENSE_KEY' ) ) {
380
- $key = OPTINMONSTER_REST_API_LICENSE_KEY;
381
- }
382
-
383
- // If the key is still empty, check for the old legacy key.
384
- if ( empty( $key ) ) {
385
- $key = is_array( $option ) && isset( $option['api']['key'] ) ? $option['api']['key'] : '';
386
- }
387
- break;
388
- }
389
-
390
- // Possibly set the level to 'none' if the key is empty and no level has been set.
391
- if ( empty( $key ) && empty( $level ) ) {
392
- $level = 'none';
393
- }
394
-
395
- // Normalize the level.
396
- switch ( $level ) {
397
- case 'bronze' :
398
- case 'personal' :
399
- $level = 'basic';
400
- break;
401
- case 'silver' :
402
- case 'multi' :
403
- $level = 'plus';
404
- break;
405
- case 'gold' :
406
- case 'developer' :
407
- $level = 'pro';
408
- break;
409
- case 'platinum' :
410
- case 'master' :
411
- $level = 'ultimate';
412
- break;
413
- }
414
-
415
- // Return the plan level.
416
- return $level;
417
- }
418
-
419
- /**
420
- * Dismiss the notification via AJAX.
421
- *
422
- * @since 1.0.0
423
- */
424
- public function dismiss_notification() {
425
- if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
426
- die;
427
- }
428
-
429
- $notification_id = intval( $_POST['notification_id'] );
430
- update_post_meta( $notification_id, 'viewed', 1 );
431
- die;
432
- }
433
-
434
- /**
435
- * Revokes notifications.
436
- *
437
- * @since 1.0.0
438
- *
439
- * @param array $ids An array of notification IDs to revoke.
440
- */
441
- public function revoke_notifications( $ids ) {
442
- // Loop through each of the IDs and find the post that has it as meta.
443
- foreach ( (array) $ids as $id ) {
444
- $notifications = $this->get_plugin_notifications( -1, array( 'post_status' => 'all', 'meta_key' => 'notification_id', 'meta_value' => $id ) );
445
- if ( $notifications ) {
446
- foreach ( $notifications as $notification ) {
447
- update_post_meta( $notification->ID, 'viewed', 1 );
448
- }
449
- }
450
- }
451
- }
452
- }
1
+ <?php
2
+
3
+ namespace WPMailSMTP;
4
+
5
+ /**
6
+ * Awesome Motive Notifications
7
+ *
8
+ * This creates a custom post type (if it doesn't exist) and calls the API to
9
+ * retrieve notifications for this product.
10
+ *
11
+ * @package AwesomeMotive
12
+ * @author Benjamin Rojas
13
+ * @license GPL-2.0+
14
+ * @copyright Copyright (c) 2017, Retyp LLC
15
+ * @version 1.0.2
16
+ */
17
+ class AM_Notification {
18
+ /**
19
+ * The api url we are calling.
20
+ *
21
+ * @since 1.0.0
22
+ *
23
+ * @var string
24
+ */
25
+ public $api_url = 'https://api.awesomemotive.com/v1/notification/';
26
+
27
+ /**
28
+ * A unique slug for this plugin.
29
+ * (Not the WordPress plugin slug)
30
+ *
31
+ * @since 1.0.0
32
+ *
33
+ * @var string
34
+ */
35
+ public $plugin;
36
+
37
+ /**
38
+ * The current plugin version.
39
+ *
40
+ * @since 1.0.0
41
+ *
42
+ * @var string
43
+ */
44
+ public $plugin_version;
45
+
46
+ /**
47
+ * Flag if a notice has been registered.
48
+ *
49
+ * @since 1.0.0
50
+ *
51
+ * @var bool
52
+ */
53
+ public static $registered = false;
54
+
55
+ /**
56
+ * Construct.
57
+ *
58
+ * @since 1.0.0
59
+ *
60
+ * @param string $plugin The plugin slug.
61
+ * @param mixed $version The version of the plugin.
62
+ */
63
+ public function __construct( $plugin = '', $version = 0 ) {
64
+ $this->plugin = $plugin;
65
+ $this->plugin_version = $version;
66
+
67
+ add_action( 'init', array( $this, 'custom_post_type' ) );
68
+ add_action( 'admin_init', array( $this, 'get_remote_notifications' ), 100 );
69
+ add_action( 'admin_notices', array( $this, 'display_notifications' ) );
70
+ add_action( 'wp_ajax_am_notification_dismiss', array( $this, 'dismiss_notification' ) );
71
+ }
72
+
73
+ /**
74
+ * Registers a custom post type.
75
+ *
76
+ * @since 1.0.0
77
+ */
78
+ public function custom_post_type() {
79
+ register_post_type( 'amn_' . $this->plugin, array(
80
+ 'label' => $this->plugin . ' Announcements',
81
+ 'can_export' => false,
82
+ 'supports' => false,
83
+ ) );
84
+ }
85
+
86
+ /**
87
+ * Retrieve the remote notifications if the time has expired.
88
+ *
89
+ * @since 1.0.0
90
+ */
91
+ public function get_remote_notifications() {
92
+ if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
93
+ return;
94
+ }
95
+
96
+ $last_checked = get_option( '_amn_' . $this->plugin . '_last_checked', strtotime( '-1 week' ) );
97
+
98
+ if ( $last_checked < strtotime( 'today midnight' ) ) {
99
+ $plugin_notifications = $this->get_plugin_notifications( 1 );
100
+ $notification_id = null;
101
+
102
+ if ( ! empty( $plugin_notifications ) ) {
103
+ // Unset it from the array.
104
+ $notification = $plugin_notifications[0];
105
+ $notification_id = get_post_meta( $notification->ID, 'notification_id', true );
106
+ }
107
+
108
+ $response = wp_remote_retrieve_body( wp_remote_post( $this->api_url, array(
109
+ 'body' => array(
110
+ 'slug' => $this->plugin,
111
+ 'version' => $this->plugin_version,
112
+ 'last_notification' => $notification_id,
113
+ ),
114
+ ) ) );
115
+
116
+ $data = json_decode( $response );
117
+
118
+ if ( ! empty( $data->id ) ) {
119
+ $notifications = array();
120
+
121
+ foreach ( (array) $data->slugs as $slug ) {
122
+ $notifications = array_merge(
123
+ $notifications,
124
+ (array) get_posts(
125
+ array(
126
+ 'post_type' => 'amn_' . $slug,
127
+ 'post_status' => 'all',
128
+ 'meta_key' => 'notification_id',
129
+ 'meta_value' => $data->id,
130
+ )
131
+ )
132
+ );
133
+ }
134
+
135
+ if ( empty( $notifications ) ) {
136
+ $new_notification_id = wp_insert_post( array(
137
+ 'post_content' => wp_kses_post( $data->content ),
138
+ 'post_type' => 'amn_' . $this->plugin,
139
+ ) );
140
+
141
+ update_post_meta( $new_notification_id, 'notification_id', absint( $data->id ) );
142
+ update_post_meta( $new_notification_id, 'type', sanitize_text_field( trim( $data->type ) ) );
143
+ update_post_meta( $new_notification_id, 'dismissable', (bool) $data->dismissible ? 1 : 0 );
144
+ update_post_meta( $new_notification_id, 'location', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->location ) : json_encode( $data->location ) );
145
+ update_post_meta( $new_notification_id, 'version', sanitize_text_field( trim( $data->version ) ) );
146
+ update_post_meta( $new_notification_id, 'viewed', 0 );
147
+ update_post_meta( $new_notification_id, 'expiration', $data->expiration ? absint( $data->expiration ) : false );
148
+ update_post_meta( $new_notification_id, 'plans', function_exists( 'wp_json_encode' ) ? wp_json_encode( $data->plans ) : json_encode( $data->plans ) );
149
+ }
150
+ }
151
+
152
+ // Possibly revoke notifications.
153
+ if ( ! empty( $data->revoked ) ) {
154
+ $this->revoke_notifications( $data->revoked );
155
+ }
156
+
157
+ // Set the option now so we can't run this again until after 24 hours.
158
+ update_option( '_amn_' . $this->plugin . '_last_checked', strtotime( 'today midnight' ) );
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Get local plugin notifications that have already been set.
164
+ *
165
+ * @since 1.0.0
166
+ *
167
+ * @param integer $limit Set the limit for how many posts to retrieve.
168
+ * @param array $args Any top-level arguments to add to the array.
169
+ *
170
+ * @return WP_Post[] WP_Post that match the query.
171
+ */
172
+ public function get_plugin_notifications( $limit = -1, $args = array() ) {
173
+ return get_posts(
174
+ array(
175
+ 'posts_per_page' => $limit,
176
+ 'post_type' => 'amn_' . $this->plugin,
177
+ ) + $args
178
+ );
179
+ }
180
+
181
+ /**
182
+ * Display any notifications that should be displayed.
183
+ *
184
+ * @since 1.0.0
185
+ */
186
+ public function display_notifications() {
187
+ if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
188
+ return;
189
+ }
190
+
191
+ $plugin_notifications = $this->get_plugin_notifications( -1, array(
192
+ 'post_status' => 'all',
193
+ 'meta_key' => 'viewed',
194
+ 'meta_value' => '0',
195
+ ) );
196
+
197
+ $plugin_notifications = $this->validate_notifications( $plugin_notifications );
198
+
199
+ if ( ! empty( $plugin_notifications ) && ! self::$registered ) {
200
+ foreach ( $plugin_notifications as $notification ) {
201
+ $dismissable = get_post_meta( $notification->ID, 'dismissable', true );
202
+ $type = get_post_meta( $notification->ID, 'type', true );
203
+ ?>
204
+ <div class="am-notification am-notification-<?php echo $notification->ID; ?> notice notice-<?php echo $type; ?><?php echo $dismissable ? ' is-dismissible' : ''; ?>">
205
+ <?php echo $notification->post_content; ?>
206
+ </div>
207
+ <script type="text/javascript">
208
+ jQuery(document).ready(function ($) {
209
+ $(document).on('click', '.am-notification-<?php echo $notification->ID; ?> button.notice-dismiss', function (event) {
210
+ $.post(ajaxurl, {
211
+ action: 'am_notification_dismiss',
212
+ notification_id: '<?php echo $notification->ID; ?>'
213
+ });
214
+ });
215
+ });
216
+ </script>
217
+ <?php
218
+ }
219
+
220
+ self::$registered = true;
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Validate the notifications before displaying them.
226
+ *
227
+ * @since 1.0.0
228
+ *
229
+ * @param array $plugin_notifications An array of plugin notifications.
230
+ *
231
+ * @return array A filtered array of plugin notifications.
232
+ */
233
+ public function validate_notifications( $plugin_notifications ) {
234
+ global $pagenow;
235
+
236
+ foreach ( $plugin_notifications as $key => $notification ) {
237
+ // Location validation.
238
+ $location = (array) json_decode( get_post_meta( $notification->ID, 'location', true ) );
239
+ $continue = false;
240
+ if ( ! in_array( 'everywhere', $location, true ) ) {
241
+ if ( in_array( 'index.php', $location, true ) && 'index.php' === $pagenow ) {
242
+ $continue = true;
243
+ }
244
+
245
+ if ( in_array( 'plugins.php', $location, true ) && 'plugins.php' === $pagenow ) {
246
+ $continue = true;
247
+ }
248
+
249
+ if ( ! $continue ) {
250
+ unset( $plugin_notifications[ $key ] );
251
+ }
252
+ }
253
+
254
+ // Plugin validation (OR conditional).
255
+ $plugins = (array) json_decode( get_post_meta( $notification->ID, 'plugins', true ) );
256
+ $continue = false;
257
+ if ( ! empty( $plugins ) ) {
258
+ foreach ( $plugins as $plugin ) {
259
+ if ( is_plugin_active( $plugin ) ) {
260
+ $continue = true;
261
+ }
262
+ }
263
+
264
+ if ( ! $continue ) {
265
+ unset( $plugin_notifications[ $key ] );
266
+ }
267
+ }
268
+
269
+ // Theme validation.
270
+ $theme = get_post_meta( $notification->ID, 'theme', true );
271
+ $continue = (string) wp_get_theme() === $theme;
272
+
273
+ if ( ! empty( $theme ) && ! $continue ) {
274
+ unset( $plugin_notifications[ $key ] );
275
+ }
276
+
277
+ // Version validation.
278
+ $version = get_post_meta( $notification->ID, 'version', true );
279
+ $continue = false;
280
+ if ( ! empty( $version ) ) {
281
+ if ( version_compare( $this->plugin_version, $version, '<=' ) ) {
282
+ $continue = true;
283
+ }
284
+
285
+ if ( ! $continue ) {
286
+ unset( $plugin_notifications[ $key ] );
287
+ }
288
+ }
289
+
290
+ // Expiration validation.
291
+ $expiration = get_post_meta( $notification->ID, 'expiration', true );
292
+ $continue = false;
293
+ if ( ! empty( $expiration ) ) {
294
+ if ( $expiration > time() ) {
295
+ $continue = true;
296
+ }
297
+
298
+ if ( ! $continue ) {
299
+ unset( $plugin_notifications[ $key ] );
300
+ }
301
+ }
302
+
303
+ // Plan validation.
304
+ $plans = (array) json_decode( get_post_meta( $notification->ID, 'plans', true ) );
305
+ $continue = false;
306
+ if ( ! empty( $plans ) ) {
307
+ $level = $this->get_plan_level();
308
+ if ( in_array( $level, $plans, true ) ) {
309
+ $continue = true;
310
+ }
311
+
312
+ if ( ! $continue ) {
313
+ unset( $plugin_notifications[ $key ] );
314
+ }
315
+ }
316
+ }
317
+
318
+ return $plugin_notifications;
319
+ }
320
+
321
+ /**
322
+ * Grab the current plan level.
323
+ *
324
+ * @since 1.0.0
325
+ *
326
+ * @return string The current plan level.
327
+ */
328
+ public function get_plan_level() {
329
+ // Prepare variables.
330
+ $key = '';
331
+ $level = '';
332
+ $option = false;
333
+ switch ( $this->plugin ) {
334
+ case 'wpforms' :
335
+ $option = get_option( 'wpforms_license' );
336
+ $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
337
+ $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
338
+
339
+ // Possibly check for a constant.
340
+ if ( empty( $key ) && defined( 'WPFORMS_LICENSE_KEY' ) ) {
341
+ $key = WPFORMS_LICENSE_KEY;
342
+ }
343
+ break;
344
+ case 'mi' :
345
+ $option = get_option( 'monsterinsights_license' );
346
+ $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
347
+ $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
348
+
349
+ // Possibly check for a constant.
350
+ if ( empty( $key ) && defined( 'MONSTERINSIGHTS_LICENSE_KEY' ) && is_string( MONSTERINSIGHTS_LICENSE_KEY ) && strlen( MONSTERINSIGHTS_LICENSE_KEY ) > 10 ) {
351
+ $key = MONSTERINSIGHTS_LICENSE_KEY;
352
+ }
353
+ break;
354
+ case 'sol' :
355
+ $option = get_option( 'soliloquy' );
356
+ $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
357
+ $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
358
+
359
+ // Possibly check for a constant.
360
+ if ( empty( $key ) && defined( 'SOLILOQUY_LICENSE_KEY' ) ) {
361
+ $key = SOLILOQUY_LICENSE_KEY;
362
+ }
363
+ break;
364
+ case 'envira' :
365
+ $option = get_option( 'envira_gallery' );
366
+ $key = is_array( $option ) && isset( $option['key'] ) ? $option['key'] : '';
367
+ $level = is_array( $option ) && isset( $option['type'] ) ? $option['type'] : '';
368
+
369
+ // Possibly check for a constant.
370
+ if ( empty( $key ) && defined( 'ENVIRA_LICENSE_KEY' ) ) {
371
+ $key = ENVIRA_LICENSE_KEY;
372
+ }
373
+ break;
374
+ case 'om' :
375
+ $option = get_option( 'optin_monster_api' );
376
+ $key = is_array( $option ) && isset( $option['api']['apikey'] ) ? $option['api']['apikey'] : '';
377
+
378
+ // Possibly check for a constant.
379
+ if ( empty( $key ) && defined( 'OPTINMONSTER_REST_API_LICENSE_KEY' ) ) {
380
+ $key = OPTINMONSTER_REST_API_LICENSE_KEY;
381
+ }
382
+
383
+ // If the key is still empty, check for the old legacy key.
384
+ if ( empty( $key ) ) {
385
+ $key = is_array( $option ) && isset( $option['api']['key'] ) ? $option['api']['key'] : '';
386
+ }
387
+ break;
388
+ }
389
+
390
+ // Possibly set the level to 'none' if the key is empty and no level has been set.
391
+ if ( empty( $key ) && empty( $level ) ) {
392
+ $level = 'none';
393
+ }
394
+
395
+ // Normalize the level.
396
+ switch ( $level ) {
397
+ case 'bronze' :
398
+ case 'personal' :
399
+ $level = 'basic';
400
+ break;
401
+ case 'silver' :
402
+ case 'multi' :
403
+ $level = 'plus';
404
+ break;
405
+ case 'gold' :
406
+ case 'developer' :
407
+ $level = 'pro';
408
+ break;
409
+ case 'platinum' :
410
+ case 'master' :
411
+ $level = 'ultimate';
412
+ break;
413
+ }
414
+
415
+ // Return the plan level.
416
+ return $level;
417
+ }
418
+
419
+ /**
420
+ * Dismiss the notification via AJAX.
421
+ *
422
+ * @since 1.0.0
423
+ */
424
+ public function dismiss_notification() {
425
+ if ( ! current_user_can( apply_filters( 'am_notifications_display', 'manage_options' ) ) ) {
426
+ die;
427
+ }
428
+
429
+ $notification_id = intval( $_POST['notification_id'] );
430
+ update_post_meta( $notification_id, 'viewed', 1 );
431
+ die;
432
+ }
433
+
434
+ /**
435
+ * Revokes notifications.
436
+ *
437
+ * @since 1.0.0
438
+ *
439
+ * @param array $ids An array of notification IDs to revoke.
440
+ */
441
+ public function revoke_notifications( $ids ) {
442
+ // Loop through each of the IDs and find the post that has it as meta.
443
+ foreach ( (array) $ids as $id ) {
444
+ $notifications = $this->get_plugin_notifications( -1, array( 'post_status' => 'all', 'meta_key' => 'notification_id', 'meta_value' => $id ) );
445
+ if ( $notifications ) {
446
+ foreach ( $notifications as $notification ) {
447
+ update_post_meta( $notification->ID, 'viewed', 1 );
448
+ }
449
+ }
450
+ }
451
+ }
452
+ }
src/Admin/Area.php CHANGED
@@ -1,457 +1,457 @@
1
- <?php
2
-
3
- namespace WPMailSMTP\Admin;
4
-
5
- use WPMailSMTP\WP;
6
-
7
- /**
8
- * Class Area registers and process all wp-admin display functionality.
9
- *
10
- * @since 1.0.0
11
- */
12
- class Area {
13
-
14
- /**
15
- * @var string Slug of the admin area page.
16
- */
17
- const SLUG = 'wp-mail-smtp';
18
-
19
- /**
20
- * @var string Admin page unique hook.
21
- */
22
- public $hook;
23
-
24
- /**
25
- * @var PageAbstract[]
26
- */
27
- private $pages;
28
-
29
- /**
30
- * Area constructor.
31
- *
32
- * @since 1.0.0
33
- */
34
- public function __construct() {
35
- $this->hooks();
36
- }
37
-
38
- /**
39
- * Assign all hooks to proper places.
40
- *
41
- * @since 1.0.0
42
- */
43
- protected function hooks() {
44
-
45
- // Add the Settings link to a plugin on Plugins page.
46
- add_filter( 'plugin_action_links', array( $this, 'add_plugin_action_link' ), 10, 2 );
47
-
48
- // Add the options page.
49
- add_action( 'admin_menu', array( $this, 'add_admin_options_page' ) );
50
-
51
- // Admin footer text.
52
- add_filter( 'admin_footer_text', array( $this, 'get_admin_footer' ), 1, 2 );
53
-
54
- // Enqueue admin area scripts and styles.
55
- add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
56
-
57
- // Process the admin page forms actions.
58
- add_action( 'admin_init', array( $this, 'process_actions' ) );
59
-
60
- // Display custom notices based on the error/success codes.
61
- add_action( 'admin_init', array( $this, 'display_custom_auth_notices' ) );
62
-
63
- // Outputs the plugin admin header.
64
- add_action( 'in_admin_header', array( $this, 'display_admin_header' ), 100 );
65
-
66
- // Hide all unrelated to the plugin notices on the plugin admin pages.
67
- add_action( 'admin_print_scripts', array( $this, 'hide_unrelated_notices' ) );
68
- }
69
-
70
- /**
71
- * Display custom notices based on the error/success codes.
72
- *
73
- * @since 1.0.0
74
- */
75
- public function display_custom_auth_notices() {
76
-
77
- $error = isset( $_GET['error'] ) ? $_GET['error'] : '';
78
- $success = isset( $_GET['success'] ) ? $_GET['success'] : '';
79
-
80
- if ( empty( $error ) && empty( $success ) ) {
81
- return;
82
- }
83
-
84
- switch ( $error ) {
85
- case 'google_access_denied':
86
- WP::add_admin_notice(
87
- /* translators: %s - error code, returned by Google API. */
88
- sprintf( esc_html__( 'There was an error while processing the authentication request: %s. Please try again.', 'wp-mail-smtp' ), '<code>' . $error . '</code>' ),
89
- WP::ADMIN_NOTICE_ERROR
90
- );
91
- break;
92
-
93
- case 'google_no_code_scope':
94
- WP::add_admin_notice(
95
- esc_html__( 'There was an error while processing the authentication request. Please try again.', 'wp-mail-smtp' ),
96
- WP::ADMIN_NOTICE_ERROR
97
- );
98
- break;
99
-
100
- case 'google_no_clients':
101
- WP::add_admin_notice(
102
- esc_html__( 'There was an error while processing the authentication request. Please make sure that you have Client ID and Client Secret both valid and saved.', 'wp-mail-smtp' ),
103
- WP::ADMIN_NOTICE_ERROR
104
- );
105
- break;
106
- }
107
-
108
- switch ( $success ) {
109
- case 'google_site_linked':
110
- WP::add_admin_notice(
111
- esc_html__( 'You have successfully linked the current site with you Google API project. Now you can start sending emails through Google.', 'wp-mail-smtp' ),
112
- WP::ADMIN_NOTICE_SUCCESS
113
- );
114
- break;
115
- }
116
- }
117
-
118
- /**
119
- * Add admin area menu item.
120
- *
121
- * @since 1.0.0
122
- */
123
- public function add_admin_options_page() {
124
-
125
- $this->hook = add_options_page(
126
- esc_html__( 'WP Mail SMTP Options', 'wp-mail-smtp' ),
127
- esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
128
- 'manage_options',
129
- self::SLUG,
130
- array( $this, 'display' )
131
- );
132
- }
133
-
134
- /**
135
- * Enqueue admin area scripts and styles.
136
- *
137
- * @since 1.0.0
138
- *
139
- * @param string $hook
140
- */
141
- public function enqueue_assets( $hook ) {
142
-
143
- if ( $hook !== $this->hook ) {
144
- return;
145
- }
146
-
147
- wp_enqueue_style(
148
- 'wp-mail-smtp-admin',
149
- wp_mail_smtp()->plugin_url . '/assets/css/smtp-admin.min.css',
150
- false,
151
- WPMS_PLUGIN_VER
152
- );
153
-
154
- wp_enqueue_script(
155
- 'wp-mail-smtp-admin',
156
- wp_mail_smtp()->plugin_url . '/assets/js/smtp-admin' . WP::asset_min() . '.js',
157
- array( 'jquery' ),
158
- WPMS_PLUGIN_VER
159
- );
160
- }
161
-
162
- /**
163
- * Outputs the plugin admin header.
164
- *
165
- * @since 1.0.0
166
- */
167
- public function display_admin_header() {
168
-
169
- // Bail if we're not on a plugin page.
170
- if ( ! $this->is_admin_page() ) {
171
- return;
172
- }
173
- ?>
174
-
175
- <div id="wp-mail-smtp-header">
176
- <!--suppress HtmlUnknownTarget -->
177
- <img class="wp-mail-smtp-header-logo" src="<?php echo wp_mail_smtp()->plugin_url; ?>/assets/images/logo.png" alt="WP Mail SMTP"/>
178
- </div>
179
-
180
- <?php
181
- }
182
-
183
- /**
184
- * Display a text to ask users to review the plugin on WP.org.
185
- *
186
- * @since 1.0.0
187
- *
188
- * @param string $text
189
- *
190
- * @return string
191
- */
192
- public function get_admin_footer( $text ) {
193
-
194
- if ( $this->is_admin_page() ) {
195
- $url = 'https://wordpress.org/support/plugin/wp-mail-smtp/reviews/?filter=5#new-post';
196
-
197
- $text = sprintf(
198
- /* translators: %1$s - WP.org link; %2$s - same WP.org link. */
199
- __( 'Please rate <strong>WP Mail SMTP</strong> <a href="%1$s" target="_blank" rel="noopener noreferrer">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href="%2$s" target="_blank">WordPress.org</a> to help us spread the word. Thank you from the WP Mail SMTP team!', 'wp-mail-smtp' ),
200
- $url,
201
- $url
202
- );
203
- }
204
-
205
- return $text;
206
- }
207
-
208
- /**
209
- * Display content of the admin area page.
210
- *
211
- * @since 1.0.0
212
- */
213
- public function display() {
214
- ?>
215
-
216
- <div class="wrap" id="wp-mail-smtp">
217
-
218
- <div class="wp-mail-smtp-page-title">
219
- <?php
220
- foreach ( $this->get_pages() as $page_slug => $page ) :
221
- $label = $page->get_label();
222
- if ( empty( $label ) ) {
223
- continue;
224
- }
225
- $class = $page_slug === $this->get_current_tab() ? 'class="active"' : '';
226
- ?>
227
-
228
- <a href="<?php echo $page->get_link(); ?>" <?php echo $class; ?>><?php echo $label; ?></a>
229
-
230
- <?php endforeach; ?>
231
- </div>
232
-
233
- <div class="wp-mail-smtp-page wp-mail-smtp-tab-<?php echo $this->get_current_tab(); ?>">
234
- <h1 class="screen-reader-text"><?php echo $this->get_current_tab_title(); ?></h1>
235
-
236
- <?php $this->display_current_tab_content(); ?>
237
- </div>
238
-
239
- </div>
240
-
241
- <?php
242
- }
243
-
244
- /**
245
- * Get the current tab title.
246
- *
247
- * @since 1.0.0
248
- */
249
- public function display_current_tab_content() {
250
-
251
- if ( ! array_key_exists( $this->get_current_tab(), $this->get_pages() ) ) {
252
- return;
253
- }
254
-
255
- $this->pages[ $this->get_current_tab() ]->display();
256
- }
257
-
258
- /**
259
- * Get the current admin area tab.
260
- *
261
- * @since 1.0.0
262
- *
263
- * @return string
264
- */
265
- protected function get_current_tab() {
266
-
267
- $current = '';
268
-
269
- if ( $this->is_admin_page() ) {
270
- $current = ! empty( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'settings';
271
- }
272
-
273
- return $current;
274
- }
275
-
276
- /**
277
- * Get the array of default registered tabs for plugin admin area.
278
- *
279
- * @since 1.0.0
280
- *
281
- * @return \WPMailSMTP\Admin\PageAbstract[]
282
- */
283
- public function get_pages() {
284
-
285
- if ( empty( $this->pages ) ) {
286
- $this->pages = array(
287
- 'settings' => new Pages\Settings(),
288
- 'test' => new Pages\Test(),
289
- 'misc' => new Pages\Misc(),
290
- 'auth' => new Pages\Auth(),
291
- );
292
- }
293
-
294
- return apply_filters( 'wp_mail_smtp_admin_get_pages', $this->pages );
295
- }
296
-
297
- /**
298
- * Get the current tab title.
299
- *
300
- * @since 1.0.0
301
- *
302
- * @return string
303
- */
304
- public function get_current_tab_title() {
305
-
306
- if ( ! array_key_exists( $this->get_current_tab(), $this->get_pages() ) ) {
307
- return '';
308
- }
309
-
310
- return $this->pages[ $this->get_current_tab() ]->get_title();
311
- }
312
-
313
- /**
314
- * Check whether we are on an admin page.
315
- *
316
- * @since 1.0.0
317
- *
318
- * @return bool
319
- */
320
- public function is_admin_page() {
321
-
322
- $page = isset( $_GET['page'] ) ? $_GET['page'] : '';
323
-
324
- return self::SLUG === $page;
325
- }
326
-
327
- /**
328
- * All possible plugin forms manipulation will be done here.
329
- *
330
- * @since 1.0.0
331
- */
332
- public function process_actions() {
333
-
334
- // Allow to process only own tabs.
335
- if ( ! array_key_exists( $this->get_current_tab(), $this->get_pages() ) ) {
336
- return;
337
- }
338
-
339
- // Process POST only if it exists.
340
- if ( ! empty( $_POST ) ) {
341
- if ( ! empty( $_POST['wp-mail-smtp'] ) ) {
342
- $post = $_POST['wp-mail-smtp'];
343
- } else {
344
- $post = array();
345
- }
346
-
347
- $this->pages[ $this->get_current_tab() ]->process_post( $post );
348
- }
349
-
350
- // This won't do anything for most pages.
351
- $this->pages[ $this->get_current_tab() ]->process_auth();
352
- }
353
-
354
- /**
355
- * Add a link to Settings page of a plugin on Plugins page.
356
- *
357
- * @since 1.0.0
358
- *
359
- * @param array $links
360
- * @param string $file
361
- *
362
- * @return mixed
363
- */
364
- public function add_plugin_action_link( $links, $file ) {
365
-
366
- if ( strpos( $file, 'wp-mail-smtp' ) === false ) {
367
- return $links;
368
- }
369
-
370
- $settings_link = '<a href="' . $this->get_admin_page_url() . '">' . esc_html__( 'Settings', 'wp-mail-smtp' ) . '</a>';
371
-
372
- array_unshift( $links, $settings_link );
373
-
374
- return $links;
375
- }
376
-
377
- /**
378
- * Get plugin admin area page URL.
379
- *
380
- * @since 1.0.0
381
- *
382
- * @return string
383
- */
384
- public function get_admin_page_url() {
385
- return add_query_arg(
386
- 'page',
387
- self::SLUG,
388
- admin_url( 'options-general.php' )
389
- );
390
- }
391
-
392
- /**
393
- * Remove all non-WP Mail SMTP plugin notices from plugin pages.
394
- *
395
- * @since 1.0.0
396
- */
397
- public function hide_unrelated_notices() {
398
-
399
- // Bail if we're not on a our screen or page.
400
- if ( empty( $_REQUEST['page'] ) || strpos( $_REQUEST['page'], self::SLUG ) === false ) {
401
- return;
402
- }
403
-
404
- global $wp_filter;
405
-
406
- if ( ! empty( $wp_filter['user_admin_notices']->callbacks ) && is_array( $wp_filter['user_admin_notices']->callbacks ) ) {
407
- foreach ( $wp_filter['user_admin_notices']->callbacks as $priority => $hooks ) {
408
- foreach ( $hooks as $name => $arr ) {
409
- if ( is_object( $arr['function'] ) && $arr['function'] instanceof \Closure ) {
410
- unset( $wp_filter['user_admin_notices']->callbacks[ $priority ][ $name ] );
411
- continue;
412
- }
413
- if ( ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) && strpos( strtolower( get_class( $arr['function'][0] ) ), 'wpmailsmtp' ) !== false ) {
414
- continue;
415
- }
416
- if ( ! empty( $name ) && strpos( strtolower( $name ), 'wpmailsmtp' ) === false ) {
417
- unset( $wp_filter['user_admin_notices']->callbacks[ $priority ][ $name ] );
418
- }
419
- }
420
- }
421
- }
422
-
423
- if ( ! empty( $wp_filter['admin_notices']->callbacks ) && is_array( $wp_filter['admin_notices']->callbacks ) ) {
424
- foreach ( $wp_filter['admin_notices']->callbacks as $priority => $hooks ) {
425
- foreach ( $hooks as $name => $arr ) {
426
- if ( is_object( $arr['function'] ) && $arr['function'] instanceof \Closure ) {
427
- unset( $wp_filter['admin_notices']->callbacks[ $priority ][ $name ] );
428
- continue;
429
- }
430
- if ( ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) && strpos( strtolower( get_class( $arr['function'][0] ) ), 'wpmailsmtp' ) !== false ) {
431
- continue;
432
- }
433
- if ( ! empty( $name ) && strpos( strtolower( $name ), 'wpmailsmtp' ) === false ) {
434
- unset( $wp_filter['admin_notices']->callbacks[ $priority ][ $name ] );
435
- }
436
- }
437
- }
438
- }
439
-
440
- if ( ! empty( $wp_filter['all_admin_notices']->callbacks ) && is_array( $wp_filter['all_admin_notices']->callbacks ) ) {
441
- foreach ( $wp_filter['all_admin_notices']->callbacks as $priority => $hooks ) {
442
- foreach ( $hooks as $name => $arr ) {
443
- if ( is_object( $arr['function'] ) && $arr['function'] instanceof \Closure ) {
444
- unset( $wp_filter['all_admin_notices']->callbacks[ $priority ][ $name ] );
445
- continue;
446
- }
447
- if ( ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) && strpos( strtolower( get_class( $arr['function'][0] ) ), 'wpmailsmtp' ) !== false ) {
448
- continue;
449
- }
450
- if ( ! empty( $name ) && strpos( strtolower( $name ), 'wpmailsmtp' ) === false ) {
451
- unset( $wp_filter['all_admin_notices']->callbacks[ $priority ][ $name ] );
452
- }
453
- }
454
- }
455
- }
456
- }
457
- }
1
+ <?php
2
+
3
+ namespace WPMailSMTP\Admin;
4
+
5
+ use WPMailSMTP\WP;
6
+
7
+ /**
8
+ * Class Area registers and process all wp-admin display functionality.
9
+ *
10
+ * @since 1.0.0
11
+ */
12
+ class Area {
13
+
14
+ /**
15
+ * @var string Slug of the admin area page.
16
+ */
17
+ const SLUG = 'wp-mail-smtp';
18
+
19
+ /**
20
+ * @var string Admin page unique hook.
21
+ */
22
+ public $hook;
23
+
24
+ /**
25
+ * @var PageAbstract[]
26
+ */
27
+ private $pages;
28
+
29
+ /**
30
+ * Area constructor.
31
+ *
32
+ * @since 1.0.0
33
+ */
34
+ public function __construct() {
35
+ $this->hooks();
36
+ }
37
+
38
+ /**
39
+ * Assign all hooks to proper places.
40
+ *
41
+ * @since 1.0.0
42
+ */
43
+ protected function hooks() {
44
+
45
+ // Add the Settings link to a plugin on Plugins page.
46
+ add_filter( 'plugin_action_links', array( $this, 'add_plugin_action_link' ), 10, 2 );
47
+
48
+ // Add the options page.
49
+ add_action( 'admin_menu', array( $this, 'add_admin_options_page' ) );
50
+
51
+ // Admin footer text.
52
+ add_filter( 'admin_footer_text', array( $this, 'get_admin_footer' ), 1, 2 );
53
+
54
+ // Enqueue admin area scripts and styles.
55
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
56
+
57
+ // Process the admin page forms actions.
58
+ add_action( 'admin_init', array( $this, 'process_actions' ) );
59
+
60
+ // Display custom notices based on the error/success codes.
61
+ add_action( 'admin_init', array( $this, 'display_custom_auth_notices' ) );
62
+
63
+ // Outputs the plugin admin header.
64
+ add_action( 'in_admin_header', array( $this, 'display_admin_header' ), 100 );
65
+
66
+ // Hide all unrelated to the plugin notices on the plugin admin pages.
67
+ add_action( 'admin_print_scripts', array( $this, 'hide_unrelated_notices' ) );
68
+ }
69
+
70
+ /**
71
+ * Display custom notices based on the error/success codes.
72
+ *
73
+ * @since 1.0.0
74
+ */
75
+ public function display_custom_auth_notices() {
76
+
77
+ $error = isset( $_GET['error'] ) ? $_GET['error'] : '';
78
+ $success = isset( $_GET['success'] ) ? $_GET['success'] : '';
79
+
80
+ if ( empty( $error ) && empty( $success ) ) {
81
+ return;
82
+ }
83
+
84
+ switch ( $error ) {
85
+ case 'google_access_denied':
86
+ WP::add_admin_notice(
87
+ /* translators: %s - error code, returned by Google API. */
88
+ sprintf( esc_html__( 'There was an error while processing the authentication request: %s. Please try again.', 'wp-mail-smtp' ), '<code>' . $error . '</code>' ),
89
+ WP::ADMIN_NOTICE_ERROR
90
+ );
91
+ break;
92
+
93
+ case 'google_no_code_scope':
94
+ WP::add_admin_notice(
95
+ esc_html__( 'There was an error while processing the authentication request. Please try again.', 'wp-mail-smtp' ),
96
+ WP::ADMIN_NOTICE_ERROR
97
+ );
98
+ break;
99
+
100
+ case 'google_no_clients':
101
+ WP::add_admin_notice(
102
+ esc_html__( 'There was an error while processing the authentication request. Please make sure that you have Client ID and Client Secret both valid and saved.', 'wp-mail-smtp' ),
103
+ WP::ADMIN_NOTICE_ERROR
104
+ );
105
+ break;
106
+ }
107
+
108
+ switch ( $success ) {
109
+ case 'google_site_linked':
110
+ WP::add_admin_notice(
111
+ esc_html__( 'You have successfully linked the current site with you Google API project. Now you can start sending emails through Google.', 'wp-mail-smtp' ),
112
+ WP::ADMIN_NOTICE_SUCCESS
113
+ );
114
+ break;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Add admin area menu item.
120
+ *
121
+ * @since 1.0.0
122
+ */
123
+ public function add_admin_options_page() {
124
+
125
+ $this->hook = add_options_page(
126
+ esc_html__( 'WP Mail SMTP Options', 'wp-mail-smtp' ),
127
+ esc_html__( 'WP Mail SMTP', 'wp-mail-smtp' ),
128
+ 'manage_options',
129
+ self::SLUG,
130
+ array( $this, 'display' )
131
+ );
132
+ }
133
+
134
+ /**
135
+ * Enqueue admin area scripts and styles.
136
+ *
137
+ * @since 1.0.0
138
+ *
139
+ * @param string $hook
140
+ */
141
+ public function enqueue_assets( $hook ) {
142
+
143
+ if ( $hook !== $this->hook ) {
144
+ return;
145
+ }
146
+
147
+ wp_enqueue_style(
148
+ 'wp-mail-smtp-admin',
149
+ wp_mail_smtp()->plugin_url . '/assets/css/smtp-admin.min.css',
150
+ false,
151
+ WPMS_PLUGIN_VER
152
+ );
153
+
154
+ wp_enqueue_script(
155
+ 'wp-mail-smtp-admin',
156
+ wp_mail_smtp()->plugin_url . '/assets/js/smtp-admin' . WP::asset_min() . '.js',
157
+ array( 'jquery' ),
158
+ WPMS_PLUGIN_VER
159
+ );
160
+ }
161
+
162
+ /**
163
+ * Outputs the plugin admin header.
164
+ *
165
+ * @since 1.0.0
166
+ */
167
+ public function display_admin_header() {
168
+
169
+ // Bail if we're not on a plugin page.
170
+ if ( ! $this->is_admin_page() ) {
171
+ return;
172
+ }
173
+ ?>
174
+
175
+ <div id="wp-mail-smtp-header">
176
+ <!--suppress HtmlUnknownTarget -->
177
+ <img class="wp-mail-smtp-header-logo" src="<?php echo wp_mail_smtp()->plugin_url; ?>/assets/images/logo.png" alt="WP Mail SMTP"/>
178
+ </div>
179
+
180
+ <?php
181
+ }
182
+
183
+ /**
184
+ * Display a text to ask users to review the plugin on WP.org.
185
+ *
186
+ * @since 1.0.0
187
+ *
188
+ * @param string $text
189
+ *
190
+ * @return string
191
+ */
192
+ public function get_admin_footer( $text ) {
193
+
194
+ if ( $this->is_admin_page() ) {
195
+ $url = 'https://wordpress.org/support/plugin/wp-mail-smtp/reviews/?filter=5#new-post';
196
+
197
+ $text = sprintf(
198
+ /* translators: %1$s - WP.org link; %2$s - same WP.org link. */
199
+ __( 'Please rate <strong>WP Mail SMTP</strong> <a href="%1$s" target="_blank" rel="noopener noreferrer">&#9733;&#9733;&#9733;&#9733;&#9733;</a> on <a href="%2$s" target="_blank">WordPress.org</a> to help us spread the word. Thank you from the WP Mail SMTP team!', 'wp-mail-smtp' ),
200
+ $url,
201
+ $url
202
+ );
203
+ }
204
+
205
+ return $text;
206
+ }
207
+
208
+ /**
209
+ * Display content of the admin area page.
210
+ *
211
+ * @since 1.0.0
212
+ */
213
+ public function display() {
214
+ ?>
215
+
216
+ <div class="wrap" id="wp-mail-smtp">
217
+
218
+ <div class="wp-mail-smtp-page-title">
219
+ <?php
220
+ foreach ( $this->get_pages() as $page_slug => $page ) :
221
+ $label = $page->get_label();
222
+ if ( empty( $label ) ) {
223
+ continue;
224
+ }
225
+ $class = $page_slug === $this->get_current_tab() ? 'class="active"' : '';
226
+ ?>
227
+
228
+ <a href="<?php echo $page->get_link(); ?>" <?php echo $class; ?>><?php echo $label; ?></a>
229
+
230
+ <?php endforeach; ?>
231
+ </div>
232
+
233
+ <div class="wp-mail-smtp-page wp-mail-smtp-tab-<?php echo $this->get_current_tab(); ?>">
234
+ <h1 class="screen-reader-text"><?php echo $this->get_current_tab_title(); ?></h1>
235
+
236
+ <?php $this->display_current_tab_content(); ?>
237
+ </div>
238
+
239
+ </div>
240
+
241
+ <?php
242
+ }
243
+
244
+ /**
245
+ * Get the current tab title.
246
+ *
247
+ * @since 1.0.0
248
+ */
249
+ public function display_current_tab_content() {
250
+
251
+ if ( ! array_key_exists( $this->get_current_tab(), $this->get_pages() ) ) {
252
+ return;
253
+ }
254
+
255
+ $this->pages[ $this->get_current_tab() ]->display();
256
+ }
257
+
258
+ /**
259
+ * Get the current admin area tab.
260
+ *
261
+ * @since 1.0.0
262
+ *
263
+ * @return string
264
+ */
265
+ protected function get_current_tab() {
266
+
267
+ $current = '';
268
+
269
+ if ( $this->is_admin_page() ) {
270
+ $current = ! empty( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'settings';
271
+ }
272
+
273
+ return $current;
274
+ }
275
+
276
+ /**
277
+ * Get the array of default registered tabs for plugin admin area.
278
+ *
279
+ * @since 1.0.0
280
+ *
281
+ * @return \WPMailSMTP\Admin\PageAbstract[]
282
+ */
283
+ public function get_pages() {
284
+
285
+ if ( empty( $this->pages ) ) {
286
+ $this->pages = array(
287
+ 'settings' => new Pages\Settings(),
288
+ 'test' => new Pages\Test(),
289
+ 'misc' => new Pages\Misc(),
290
+ 'auth' => new Pages\Auth(),
291
+ );
292
+ }
293
+
294
+ return apply_filters( 'wp_mail_smtp_admin_get_pages', $this->pages );
295
+ }
296
+
297
+ /**
298
+ * Get the current tab title.
299
+ *
300
+ * @since 1.0.0
301
+ *
302
+ * @return string
303
+ */
304
+ public function get_current_tab_title() {
305
+
306
+ if ( ! array_key_exists( $this->get_current_tab(), $this->get_pages() ) ) {
307
+ return '';
308
+ }
309
+
310
+ return $this->pages[ $this->get_current_tab() ]->get_title();
311
+ }
312
+
313
+ /**
314
+ * Check whether we are on an admin page.
315
+ *
316
+ * @since 1.0.0
317
+ *
318
+ * @return bool
319
+ */
320
+ public function is_admin_page() {
321
+
322
+ $page = isset( $_GET['page'] ) ? $_GET['page'] : '';
323
+
324
+ return self::SLUG === $page;
325
+ }
326
+
327
+ /**
328
+ * All possible plugin forms manipulation will be done here.
329
+ *
330
+ * @since 1.0.0
331
+ */
332
+ public function process_actions() {
333
+
334
+ // Allow to process only own tabs.
335
+ if ( ! array_key_exists( $this->get_current_tab(), $this->get_pages() ) ) {
336
+ return;
337
+ }
338
+
339
+ // Process POST only if it exists.
340
+ if ( ! empty( $_POST ) ) {
341
+ if ( ! empty( $_POST['wp-mail-smtp'] ) ) {
342
+ $post = $_POST['wp-mail-smtp'];
343
+ } else {
344
+ $post = array();
345
+ }
346
+
347
+ $this->pages[ $this->get_current_tab() ]->process_post( $post );
348
+ }
349
+
350
+ // This won't do anything for most pages.
351
+ $this->pages[ $this->get_current_tab() ]->process_auth();
352
+ }
353
+
354
+ /**
355
+ * Add a link to Settings page of a plugin on Plugins page.
356
+ *
357
+ * @since 1.0.0
358
+ *
359
+ * @param array $links
360
+ * @param string $file
361
+ *
362
+ * @return mixed
363
+ */
364
+ public function add_plugin_action_link( $links, $file ) {
365
+
366
+ if ( strpos( $file, 'wp-mail-smtp' ) === false ) {
367
+ return $links;
368
+ }
369
+
370
+ $settings_link = '<a href="' . $this->get_admin_page_url() . '">' . esc_html__( 'Settings', 'wp-mail-smtp' ) . '</a>';
371
+
372
+ array_unshift( $links, $settings_link );
373
+
374
+ return $links;
375
+ }
376
+
377
+ /**
378
+ * Get plugin admin area page URL.
379
+ *
380
+ * @since 1.0.0
381
+ *
382
+ * @return string
383
+ */
384
+ public function get_admin_page_url() {
385
+ return add_query_arg(
386
+ 'page',
387
+ self::SLUG,
388
+ admin_url( 'options-general.php' )
389
+ );
390
+ }
391
+
392
+ /**
393
+ * Remove all non-WP Mail SMTP plugin notices from plugin pages.
394
+ *
395
+ * @since 1.0.0
396
+ */
397
+ public function hide_unrelated_notices() {
398
+
399
+ // Bail if we're not on a our screen or page.
400
+ if ( empty( $_REQUEST['page'] ) || strpos( $_REQUEST['page'], self::SLUG ) === false ) {
401
+ return;
402
+ }
403
+
404
+ global $wp_filter;
405
+
406
+ if ( ! empty( $wp_filter['user_admin_notices']->callbacks ) && is_array( $wp_filter['user_admin_notices']->callbacks ) ) {
407
+ foreach ( $wp_filter['user_admin_notices']->callbacks as $priority => $hooks ) {
408
+ foreach ( $hooks as $name => $arr ) {
409
+ if ( is_object( $arr['function'] ) && $arr['function'] instanceof \Closure ) {
410
+ unset( $wp_filter['user_admin_notices']->callbacks[ $priority ][ $name ] );
411
+ continue;
412
+ }
413
+ if ( ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) && strpos( strtolower( get_class( $arr['function'][0] ) ), 'wpmailsmtp' ) !== false ) {
414
+ continue;
415
+ }
416
+ if ( ! empty( $name ) && strpos( strtolower( $name ), 'wpmailsmtp' ) === false ) {
417
+ unset( $wp_filter['user_admin_notices']->callbacks[ $priority ][ $name ] );
418
+ }
419
+ }
420
+ }
421
+ }
422
+
423
+ if ( ! empty( $wp_filter['admin_notices']->callbacks ) && is_array( $wp_filter['admin_notices']->callbacks ) ) {
424
+ foreach ( $wp_filter['admin_notices']->callbacks as $priority => $hooks ) {
425
+ foreach ( $hooks as $name => $arr ) {
426
+ if ( is_object( $arr['function'] ) && $arr['function'] instanceof \Closure ) {
427
+ unset( $wp_filter['admin_notices']->callbacks[ $priority ][ $name ] );
428
+ continue;
429
+ }
430
+ if ( ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) && strpos( strtolower( get_class( $arr['function'][0] ) ), 'wpmailsmtp' ) !== false ) {
431
+ continue;
432
+ }
433
+ if ( ! empty( $name ) && strpos( strtolower( $name ), 'wpmailsmtp' ) === false ) {
434
+ unset( $wp_filter['admin_notices']->callbacks[ $priority ][ $name ] );
435
+ }
436
+ }
437
+ }
438
+ }
439
+
440
+ if ( ! empty( $wp_filter['all_admin_notices']->callbacks ) && is_array( $wp_filter['all_admin_notices']->callbacks ) ) {
441
+ foreach ( $wp_filter['all_admin_notices']->callbacks as $priority => $hooks ) {
442
+ foreach ( $hooks as $name => $arr ) {
443
+ if ( is_object( $arr['function'] ) && $arr['function'] instanceof \Closure ) {
444
+ unset( $wp_filter['all_admin_notices']->callbacks[ $priority ][ $name ] );
445
+ continue;
446
+ }
447
+ if ( ! empty( $arr['function'][0] ) && is_object( $arr['function'][0] ) && strpos( strtolower( get_class( $arr['function'][0] ) ), 'wpmailsmtp' ) !== false ) {
448
+ continue;
449
+ }
450
+ if ( ! empty( $name ) && strpos( strtolower( $name ), 'wpmailsmtp' ) === false ) {
451
+ unset( $wp_filter['all_admin_notices']->callbacks[ $priority ][ $name ] );
452
+ }
453
+ }
454
+ }
455
+ }
456
+ }
457
+ }
src/Admin/PageAbstract.php CHANGED
@@ -1,66 +1,66 @@
1
- <?php
2
-
3
- namespace WPMailSMTP\Admin;
4
-
5
- /**
6
- * Class PageAbstract.
7
- *
8
- * @since 1.0.0
9
- */
10
- abstract class PageAbstract implements PageInterface {
11
-
12
- /**
13
- * @var string Slug of a tab.
14
- */
15
- protected $slug;
16
-
17
- /**
18
- * @inheritdoc
19
- */
20
- public function get_link() {
21
- return esc_url(
22
- add_query_arg(
23
- 'tab',
24
- $this->slug,
25
- admin_url( 'options-general.php?page=' . Area::SLUG )
26
- )
27
- );
28
- }
29
-
30
- /**
31
- * Process tab form submission ($_POST ).
32
- *
33
- * @since 1.0.0
34
- *
35
- * @param array $data $_POST data specific for the plugin.
36
- */
37
- public function process_post( $data ) {
38
- }
39
-
40
- /**
41
- * Process tab & mailer specific Auth actions.
42
- *
43
- * @since 1.0.0
44
- */
45
- public function process_auth() {
46
- }
47
-
48
- /**
49
- * Print the nonce field for a specific tab.
50
- *
51
- * @since 1.0.0
52
- */
53
- public function wp_nonce_field() {
54
- wp_nonce_field( Area::SLUG . '-' . $this->slug );
55
- }
56
-
57