Better Notifications for WordPress - Version 1.6.1

Version Description

  • 17th February 2017 =
  • Improved: Emails sent via the "Send me a Test Email" button now prepend the Subject line with "Test Email: " so that you can tell which is a test notification and which is a real notification when using an email log plugin.
  • Fixed: The Global User Shortcodes weren't outputting anything when used in the 'User Email Changed - For User' notification. Fixed: When a 'Lost Password For User' notification had been set-up but disabled, it wasn't disabling the default WordPress notification.
  • Fixed: The 'WordPress Core Automatic Background Updates' notification wasn't working at all.
  • Fixed: The Global User Shortcodes were being output incorrectly in test emails.
  • Fixed: The [featured_image] shortcode was outputting the shortcode name as opposed to a blank when no featured image is set.
  • Fixed: A number of warnings and notices relating to the 'Lost Password' notifications when on WordPress's Lost Password screen.
  • Fixed: The 'Add-on Licenses' screen was displaying HTML characters where there shouldn't be any.
  • Fixed: An error was occurring when triggering notifications when used in conjunction with the latest version of the Custom Fields add-on.
  • Fixed: Some language translation strings were incorrect.
  • Updated: EDD_SL_Plugin_Updater is now at the latest version for add-ons.
Download this release

Release Info

Developer voltronik
Plugin Icon 128x128 Better Notifications for WordPress
Version 1.6.1
Comparing to
See all releases

Code changes from version 1.6 to 1.6.1

README.txt CHANGED
@@ -3,29 +3,39 @@ Contributors: voltronik
3
  Donate link: https://betternotificationsforwp.com/donate/
4
  Tags: notification, email, push, sms, alert, HTML, customize, bulk, trigger, CC, BCC
5
  Requires at least: 3.5
6
- Tested up to: 4.7
7
- Stable tag: 1.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
- Send customisable emails to your users for different WordPress notifications.
12
 
13
  == Description ==
14
 
15
- > New add-ons are now available! [View Add-ons](https://betternotificationsforwp.com/store/)
16
-
17
- Better Notifications for WordPress allows you to create custom email notifications and send them to user roles (including custom roles) or individual users for all kinds of things happening on your WordPress website. Emails are sent out via your WordPress website (using `wp_mail`) but can be sent via SMTP using an appropriate 3rd party plugin should you wish.
18
 
 
19
  https://www.youtube.com/watch?v=MxPUyRZPJ1Q
20
 
21
- = For example: =
22
- You want a user with the editor role (or all users using the Editor role) to be alerted via email when a new post is published and you'd like to customise it to include your branding along with the author's display name and post time - with this plugin, that's easy.
23
-
24
- If you want to override the notifications that you've set-up on an individual post / page / custom post basis, you may be interested in the [Per-post Override add-on](https://betternotificationsforwp.com/downloads/per-post-override/).
25
 
26
  > A handy list of shortcodes you can use is available [here](https://betternotificationsforwp.com/shortcodes/ "Shortcodes for use in Better Notifications for WordPress").
27
 
28
- Notifications that are currently available to use are:
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  **WordPress Defaults**
31
 
@@ -34,16 +44,17 @@ Notifications that are currently available to use are:
34
  * New Pingback
35
  * Lost Password - For Admin
36
  * New User Registration - For Admin
37
- * User Password Changed
38
- * User Email Changed
39
  * WordPress Core Automatic Background Updates
40
 
41
  **Transactional**
42
 
43
  * Lost Password - For User
 
 
44
  * New User Registration - For User
45
  * New User - Post-registration Email
46
- * User Role Changed - For Admin
47
  * User Role Changed - For User
48
  * Comment Reply
49
 
@@ -80,8 +91,7 @@ Notifications that are currently available to use are:
80
 
81
  If you'd like to see a notification in the list above, please drop me a line in the forum and I'll see what I can do to add it.
82
 
83
- Like this plugin? Please leave it [a great review](https://wordpress.org/support/view/plugin-reviews/bnfw?rate=5#postform)!
84
- Don't think the plugin is worthy of 5 stars? Having problems? Let me know in the [forum](https://wordpress.org/support/plugin/bnfw) and I'll do my best to help.
85
 
86
  > DISCLAIMER
87
  > This is an incredibly useful and highly rated plugin however, it's possible that overuse or abuse of this plugin could upset your users by sending them too many notifications. By downloading / installing / using this plugin, you take full responsibility of the management / quantity / types of notifications that are sent out from it including abiding by any SPAM laws in your country / operating areas, dealing with / responding to subscription / unsubscription requests, complaints, and so on. I accept no liability or responsibility for SPAM or abuse of this plugin from the user(s) of or anyone that may receive notifications as a result of the use of this plugin. I'm trusting you, please don't abuse your users.
@@ -100,9 +110,11 @@ Don't think the plugin is worthy of 5 stars? Having problems? Let me know in the
100
 
101
  == Frequently Asked Questions ==
102
 
 
 
103
  = What are shortcodes? Where can I use them in this plugin? =
104
 
105
- Shortcodes are little blocks of content contained in square brackets. For example, if you want to add the content of a post to a notification for 'New Post Published', you can use the `[post_content]` shortcode to display this in the email that is sent out.
106
 
107
  Shortcodes can be used in the 'Subject' and 'Message Body' of your notifications, except for a select few (due to a restriction in WordPress).
108
 
@@ -187,18 +199,31 @@ An older version might work but this is untested. A lot of the newer features re
187
 
188
  == Changelog ==
189
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  = 1.6 - 12th December 2016 =
191
  * Merry Christmas & Happy New Year!
192
  * New: Anonymous tracking of the features you use in BNFW is now an opt-in checkbox on the Notifications > Settings page. Please consider checking this box to help make BNFW even better. You'll also receive a 10% off coupon code when you sign-up to the [mailing list](http://voltronik.us2.list-manage2.com/subscribe?u=57c012217219b2d81dda0085f&id=28eebdab28) too.
193
  * New: Notifications for privately published posts / pages / custom post types.
194
  * New: Notification and accompanying shortcode for customising WordPress Core Automatic Background Updates (Success / Fail / Critical).
195
  * New: Notification for User Password Changed.
196
- * New: Notification for User Email Changed.
197
  * New: Shortcodes for showing the old and new user role when used in conjunction with the User Role Changed notifications.
198
  * New: You can now add a 'Reply To' name and email address in the Additional Email Fields for all notifications that support it.
199
  * New: You can now prevent yourself from receiving notifications of comments or replies to comments on one of your posts by combining the two checkboxes 'Send this notification to the Author only' and 'Do not send this Notification to the User that triggered it'.
200
  * New: All transactional notifications can now be set to either HTML or Plain Text.
201
- * New: Better compatibility with [Theme My Login](https://en-gb.wordpress.org/plugins/theme-my-login/).
202
  * Improved: Re-worded a checkbox to be more understandable. It did say, "Disable this Notification for the User that triggered it", but now says, "Do not send this Notification to the User that triggered it".
203
  * Improved: Compatibility with Mashshare.
204
  * Fixed: Global User Shortcodes weren't being outputted correctly in the 'Lost Password - For User' notification.
@@ -216,7 +241,7 @@ An older version might work but this is untested. A lot of the newer features re
216
  * Updated: German Translation to show English in certain places where translation text breaks the WP Admin UI (props @helmi).
217
  * Full code review and submission to WordPress VIP!
218
 
219
- = 1.5.1 - 5th August July 2016 =
220
  * Fixed: 'Text' mode in the WYSIWYG editor didn't show any buttons when the BNFW Per-post Override Add-on was activated.
221
 
222
  = 1.5 - 25th July 2016 =
3
  Donate link: https://betternotificationsforwp.com/donate/
4
  Tags: notification, email, push, sms, alert, HTML, customize, bulk, trigger, CC, BCC
5
  Requires at least: 3.5
6
+ Tested up to: 4.7.2
7
+ Stable tag: 1.6.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
+ Supercharge your WordPress notifications using a WYSIWYG editor and shortcodes. Default and new notifications available. Add more power with Add-ons.
12
 
13
  == Description ==
14
 
15
+ Better Notifications for WordPress is a simple but powerful plugin for beginners to advanced users that allows you to customise the email notifications that WordPress sends using the WYSIWYG editor and shortcodes. All of the default WordPress email notifications are available to customise as well as lots of new ones. You can choose to send notifications to individual users, multiple users, all users in a user role, multiple roles - you name it! You can also power-up your notifications with [Premium Add-ons](https://betternotificationsforwp.com/store/). Emails are sent out via your WordPress website (using `wp_mail`) but can be sent via SMTP using an appropriate 3rd party plugin should you wish.
 
 
16
 
17
+ Here's a quick walkthrough of the plugin in action:
18
  https://www.youtube.com/watch?v=MxPUyRZPJ1Q
19
 
20
+ = An Example: =
21
+ You want all the users in the Editor role to be notified via email when a new post is published and you'd like to customise it to include your logo along with the author's name and date / time it was published - with this plugin, that's easy.
 
 
22
 
23
  > A handy list of shortcodes you can use is available [here](https://betternotificationsforwp.com/shortcodes/ "Shortcodes for use in Better Notifications for WordPress").
24
 
25
+ = Premium Add-ons =
26
+ Power-up your notifications using add-ons:
27
+
28
+ [Conditional Notifications](https://betternotificationsforwp.com/downloads/conditional-notifications/) - Limit certain notifications depending on which categories, tags, post formats, or terms you choose.
29
+ [Custom Fields](https://betternotificationsforwp.com/downloads/custom-fields/) - Provides a number of new shortcodes allowing you to include data from custom fields and custom user fields created using [ACF](https://wordpress.org/plugins/advanced-custom-fields/).
30
+ [Per-post Override](https://betternotificationsforwp.com/downloads/per-post-override/) - Override some of the settings of notifications directly when editing a post, page, or custom post type.
31
+ [Update Reminder](https://betternotificationsforwp.com/downloads/update-reminder/) - Send a reminder to your users and/or user roles when a post, page, or custom post type hasn't been updated in a certain number of days.
32
+ Send to Any Email - Coming Soon!
33
+ Multisite Notifications - Coming Soon!
34
+
35
+ ...and more coming soon!
36
+
37
+ = Notifications =
38
+ The notifications that are currently available to use are:
39
 
40
  **WordPress Defaults**
41
 
44
  * New Pingback
45
  * Lost Password - For Admin
46
  * New User Registration - For Admin
47
+ * Password Changed - For Admin
48
+ * User Role Changed - For Admin
49
  * WordPress Core Automatic Background Updates
50
 
51
  **Transactional**
52
 
53
  * Lost Password - For User
54
+ * Password Changed - For User
55
+ * User Email Changed - For Admin
56
  * New User Registration - For User
57
  * New User - Post-registration Email
 
58
  * User Role Changed - For User
59
  * Comment Reply
60
 
91
 
92
  If you'd like to see a notification in the list above, please drop me a line in the forum and I'll see what I can do to add it.
93
 
94
+ > Like this plugin? Please leave it [a great review](https://wordpress.org/support/view/plugin-reviews/bnfw?rate=5#postform)! Don't think the plugin is worthy of 5 stars? Having problems? Let me know in the [forum](https://wordpress.org/support/plugin/bnfw) and I'll do my best to help.
 
95
 
96
  > DISCLAIMER
97
  > This is an incredibly useful and highly rated plugin however, it's possible that overuse or abuse of this plugin could upset your users by sending them too many notifications. By downloading / installing / using this plugin, you take full responsibility of the management / quantity / types of notifications that are sent out from it including abiding by any SPAM laws in your country / operating areas, dealing with / responding to subscription / unsubscription requests, complaints, and so on. I accept no liability or responsibility for SPAM or abuse of this plugin from the user(s) of or anyone that may receive notifications as a result of the use of this plugin. I'm trusting you, please don't abuse your users.
110
 
111
  == Frequently Asked Questions ==
112
 
113
+ > Full Documentation for BNFW can be found [here](https://betternotificationsforwp.com/documentation/ "Documentation for Better Notifications for WordPress").
114
+
115
  = What are shortcodes? Where can I use them in this plugin? =
116
 
117
+ Shortcodes are text in square brackets that output content of some kind. For example, if you want to add the content of a post to a notification for 'New Post Published', you can use the `[post_content]` shortcode to display this in the email that is sent out.
118
 
119
  Shortcodes can be used in the 'Subject' and 'Message Body' of your notifications, except for a select few (due to a restriction in WordPress).
120
 
199
 
200
  == Changelog ==
201
 
202
+ = 1.6.1 - 17th February 2017 =
203
+ * Improved: Emails sent via the "Send me a Test Email" button now prepend the Subject line with "Test Email: " so that you can tell which is a test notification and which is a real notification when using an email log plugin.
204
+ * Fixed: The Global User Shortcodes weren't outputting anything when used in the 'User Email Changed - For User' notification.
205
+ Fixed: When a 'Lost Password – For User' notification had been set-up but disabled, it wasn't disabling the default WordPress notification.
206
+ * Fixed: The 'WordPress Core Automatic Background Updates' notification wasn't working at all.
207
+ * Fixed: The Global User Shortcodes were being output incorrectly in test emails.
208
+ * Fixed: The `[featured_image]` shortcode was outputting the shortcode name as opposed to a blank when no featured image is set.
209
+ * Fixed: A number of warnings and notices relating to the 'Lost Password' notifications when on WordPress's Lost Password screen.
210
+ * Fixed: The 'Add-on Licenses' screen was displaying HTML characters where there shouldn't be any.
211
+ * Fixed: An error was occurring when triggering notifications when used in conjunction with the latest version of the Custom Fields add-on.
212
+ * Fixed: Some language translation strings were incorrect.
213
+ * Updated: EDD_SL_Plugin_Updater is now at the latest version for add-ons.
214
+
215
  = 1.6 - 12th December 2016 =
216
  * Merry Christmas & Happy New Year!
217
  * New: Anonymous tracking of the features you use in BNFW is now an opt-in checkbox on the Notifications > Settings page. Please consider checking this box to help make BNFW even better. You'll also receive a 10% off coupon code when you sign-up to the [mailing list](http://voltronik.us2.list-manage2.com/subscribe?u=57c012217219b2d81dda0085f&id=28eebdab28) too.
218
  * New: Notifications for privately published posts / pages / custom post types.
219
  * New: Notification and accompanying shortcode for customising WordPress Core Automatic Background Updates (Success / Fail / Critical).
220
  * New: Notification for User Password Changed.
221
+ * New: Notification for User Email Changed - For Admin.
222
  * New: Shortcodes for showing the old and new user role when used in conjunction with the User Role Changed notifications.
223
  * New: You can now add a 'Reply To' name and email address in the Additional Email Fields for all notifications that support it.
224
  * New: You can now prevent yourself from receiving notifications of comments or replies to comments on one of your posts by combining the two checkboxes 'Send this notification to the Author only' and 'Do not send this Notification to the User that triggered it'.
225
  * New: All transactional notifications can now be set to either HTML or Plain Text.
226
+ * Improved: Better compatibility with [Theme My Login](https://en-gb.wordpress.org/plugins/theme-my-login/).
227
  * Improved: Re-worded a checkbox to be more understandable. It did say, "Disable this Notification for the User that triggered it", but now says, "Do not send this Notification to the User that triggered it".
228
  * Improved: Compatibility with Mashshare.
229
  * Fixed: Global User Shortcodes weren't being outputted correctly in the 'Lost Password - For User' notification.
241
  * Updated: German Translation to show English in certain places where translation text breaks the WP Admin UI (props @helmi).
242
  * Full code review and submission to WordPress VIP!
243
 
244
+ = 1.5.1 - 5th August 2016 =
245
  * Fixed: 'Text' mode in the WYSIWYG editor didn't show any buttons when the BNFW Per-post Override Add-on was activated.
246
 
247
  = 1.5 - 25th July 2016 =
assets/js/bnfw.js CHANGED
@@ -24,8 +24,8 @@ jQuery(document).ready(function($) {
24
  function init() {
25
  var notification = $('#notification').val();
26
 
27
- $(".select2").select2();
28
- $(".user-select2").select2( {
29
  ajax: {
30
  url: ajaxurl,
31
  dataType: 'json',
@@ -53,7 +53,7 @@ jQuery(document).ready(function($) {
53
 
54
  if ( 'reply-comment' === notification || notification.startsWith( 'commentreply-' ) ||
55
  'new-user' === notification || 'welcome-email' === notification || 'user-password' === notification ||
56
- 'user-role' === notification ) {
57
 
58
  $('#toggle-fields, #email, #cc, #bcc, #reply, #users, #current-user, #post-author').hide();
59
  $('#user-password-msg, #disable-autop, #email-formatting').show();
@@ -64,7 +64,7 @@ jQuery(document).ready(function($) {
64
  toggle_fields();
65
  toggle_users();
66
  $( '#user-password-msg' ).hide();
67
- } else if ( 'password-changed' === notification || 'email-changed' === notification || 'core-updated' === notification ) {
68
  $( '#toggle-fields, #users, #email-formatting, #disable-autop' ).show();
69
  toggle_fields();
70
  toggle_users();
@@ -84,7 +84,7 @@ jQuery(document).ready(function($) {
84
 
85
  if ( 'reply-comment' === notification || notification.startsWith( 'commentreply-' ) ||
86
  'new-user' === notification || 'welcome-email' === notification || 'user-password' === notification ||
87
- 'user-role' === notification ) {
88
 
89
  $('#toggle-fields, #email, #cc, #bcc, #reply, #users, #current-user, #post-author').hide();
90
  $('#user-password-msg, #disable-autop, #email-formatting').show();
@@ -94,7 +94,7 @@ jQuery(document).ready(function($) {
94
  $('#user-password-msg').hide();
95
  toggle_fields();
96
  toggle_users();
97
- } else if ( 'password-changed' === notification || 'email-changed' === notification || 'core-updated' === notification ) {
98
  $( '#toggle-fields, #users, #email-formatting, #disable-autop' ).show();
99
  toggle_fields();
100
  toggle_users();
24
  function init() {
25
  var notification = $('#notification').val();
26
 
27
+ $("#notification, .user-select2").select2();
28
+ $(".user-ajax-select2").select2( {
29
  ajax: {
30
  url: ajaxurl,
31
  dataType: 'json',
53
 
54
  if ( 'reply-comment' === notification || notification.startsWith( 'commentreply-' ) ||
55
  'new-user' === notification || 'welcome-email' === notification || 'user-password' === notification ||
56
+ 'password-changed' === notification || 'email-changed' === notification || 'user-role' === notification ) {
57
 
58
  $('#toggle-fields, #email, #cc, #bcc, #reply, #users, #current-user, #post-author').hide();
59
  $('#user-password-msg, #disable-autop, #email-formatting').show();
64
  toggle_fields();
65
  toggle_users();
66
  $( '#user-password-msg' ).hide();
67
+ } else if ( 'admin-password-changed' === notification || 'core-updated' === notification ) {
68
  $( '#toggle-fields, #users, #email-formatting, #disable-autop' ).show();
69
  toggle_fields();
70
  toggle_users();
84
 
85
  if ( 'reply-comment' === notification || notification.startsWith( 'commentreply-' ) ||
86
  'new-user' === notification || 'welcome-email' === notification || 'user-password' === notification ||
87
+ 'password-changed' === notification || 'email-changed' === notification || 'user-role' === notification ) {
88
 
89
  $('#toggle-fields, #email, #cc, #bcc, #reply, #users, #current-user, #post-author').hide();
90
  $('#user-password-msg, #disable-autop, #email-formatting').show();
94
  $('#user-password-msg').hide();
95
  toggle_fields();
96
  toggle_users();
97
+ } else if ( 'admin-password-changed' === notification || 'core-updated' === notification ) {
98
  $( '#toggle-fields, #users, #email-formatting, #disable-autop' ).show();
99
  toggle_fields();
100
  toggle_users();
bnfw.php CHANGED
@@ -2,8 +2,8 @@
2
  /**
3
  * Plugin Name: Better Notifications for WordPress
4
  * Plugin URI: https://wordpress.org/plugins/bnfw/
5
- * Description: Send customisable emails to your users for different WordPress notifications.
6
- * Version: 1.6
7
  * Author: Voltronik
8
  * Author URI: https://betternotificationsforwp.com/
9
  * Author Email: hello@betternotificationsforwp.com
@@ -14,7 +14,7 @@
14
  */
15
 
16
  /**
17
- * Copyright © 2016 Voltronik (hello@betternotificationsforwp.com)
18
  * This program is free software; you can redistribute it and/or modify
19
  * it under the terms of the GNU General Public License, version 2, as
20
  * published by the Free Software Foundation.
@@ -156,6 +156,7 @@ class BNFW {
156
  add_action( 'lostpassword_post' , array( $this, 'on_lost_password' ) );
157
  add_filter( 'retrieve_password_message' , array( $this, 'change_password_email_message' ), 10, 4 );
158
 
 
159
  add_filter( 'password_change_email' , array( $this, 'on_password_changed' ), 10, 2 );
160
  add_filter( 'email_change_email' , array( $this, 'on_email_changed' ), 10, 2 );
161
 
@@ -434,11 +435,28 @@ class BNFW {
434
  } else {
435
  add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
436
  }
 
 
 
 
 
437
  }
438
 
439
  return $message;
440
  }
441
 
 
 
 
 
 
 
 
 
 
 
 
 
442
  /**
443
  * On Password Changed.
444
  *
@@ -481,7 +499,16 @@ class BNFW {
481
  * @return array Modified Email Data.
482
  */
483
  public function on_core_updated( $email_data, $type, $core_update, $result ) {
484
- return $this->handle_filtered_data_notification( 'core-updated', $email_data, $type );
 
 
 
 
 
 
 
 
 
485
  }
486
 
487
  /**
2
  /**
3
  * Plugin Name: Better Notifications for WordPress
4
  * Plugin URI: https://wordpress.org/plugins/bnfw/
5
+ * Description: Supercharge your WordPress notifications using a WYSIWYG editor and shortcodes. Default and new notifications available. Add more power with Add-ons.
6
+ * Version: 1.6.1
7
  * Author: Voltronik
8
  * Author URI: https://betternotificationsforwp.com/
9
  * Author Email: hello@betternotificationsforwp.com
14
  */
15
 
16
  /**
17
+ * Copyright © 2016 Made with Fuel Ltd. (hello@betternotificationsforwp.com)
18
  * This program is free software; you can redistribute it and/or modify
19
  * it under the terms of the GNU General Public License, version 2, as
20
  * published by the Free Software Foundation.
156
  add_action( 'lostpassword_post' , array( $this, 'on_lost_password' ) );
157
  add_filter( 'retrieve_password_message' , array( $this, 'change_password_email_message' ), 10, 4 );
158
 
159
+ add_action( 'after_password_reset' , array( $this, 'on_password_reset' ) );
160
  add_filter( 'password_change_email' , array( $this, 'on_password_changed' ), 10, 2 );
161
  add_filter( 'email_change_email' , array( $this, 'on_email_changed' ), 10, 2 );
162
 
435
  } else {
436
  add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
437
  }
438
+ } else {
439
+ if ( $this->notifier->notification_exists( 'user-password', false ) ) {
440
+ // disabled notification exists, so disable the email by returning empty string.
441
+ return '';
442
+ }
443
  }
444
 
445
  return $message;
446
  }
447
 
448
+ /**
449
+ * On Password reset.
450
+ *
451
+ * @param WP_User $user User who's password was changed.
452
+ */
453
+ public function on_password_reset( $user ) {
454
+ $notifications = $this->notifier->get_notifications( 'password-changed' );
455
+ foreach ( $notifications as $notification ) {
456
+ $this->engine->send_password_changed_email( $this->notifier->read_settings( $notification->ID ), $user );
457
+ }
458
+ }
459
+
460
  /**
461
  * On Password Changed.
462
  *
499
  * @return array Modified Email Data.
500
  */
501
  public function on_core_updated( $email_data, $type, $core_update, $result ) {
502
+ $notifications = $this->notifier->get_notifications( 'core-updated' );
503
+ if ( count( $notifications ) > 0 ) {
504
+ // Ideally there should be only one notification for this type.
505
+ // If there are multiple notification then we will read data about only the last one
506
+ $setting = $this->notifier->read_settings( end( $notifications )->ID );
507
+
508
+ $email_data = $this->engine->handle_core_updated_notification( $email_data, $setting, $type );
509
+ }
510
+
511
+ return $email_data;
512
  }
513
 
514
  /**
includes/admin/bnfw-settings.php CHANGED
@@ -75,7 +75,7 @@ function bnfw_menu_item_links() {
75
 
76
  // Add-ons Link
77
  $submenu['edit.php?post_type=bnfw_notification'][600] = array(
78
- '<div id="bnfw-menu-item-addons" style="color: #ff6f59;">Add-ons</div>',
79
  'manage_options',
80
  $store_url,
81
  );
@@ -135,7 +135,7 @@ function bnfw_general_options() {
135
  'bnfw-settings', // Page to show on
136
  'bnfw_general_options_section', // Associate with which settings section?
137
  array(
138
- esc_html__( "Don't send notifications for comments marked as SPAM by Akismet", 'bnfw' )
139
  )
140
  );
141
 
75
 
76
  // Add-ons Link
77
  $submenu['edit.php?post_type=bnfw_notification'][600] = array(
78
+ '<div id="bnfw-menu-item-addons" style="color: #ff6f59;">Premium Add-ons</div>',
79
  'manage_options',
80
  $store_url,
81
  );
135
  'bnfw-settings', // Page to show on
136
  'bnfw_general_options_section', // Associate with which settings section?
137
  array(
138
+ esc_html__( "Don't send notifications for comments marked as SPAM by another plugin", 'bnfw' )
139
  )
140
  );
141
 
includes/admin/class-bnfw-notification.php CHANGED
@@ -164,22 +164,24 @@ class BNFW_Notification {
164
  value="admin-password" <?php selected( 'admin-password', $setting['notification'] ); ?>><?php esc_html_e( 'Lost Password - For Admin', 'bnfw' ); ?></option>
165
  <option
166
  value="admin-user" <?php selected( 'admin-user', $setting['notification'] ); ?>><?php esc_html_e( 'New User Registration - For Admin', 'bnfw' ); ?></option>
 
 
167
  <option
168
- value="password-changed" <?php selected( 'password-changed', $setting['notification'] ); ?>><?php esc_html_e( 'User Password Changed', 'bnfw' ); ?></option>
169
- <option
170
- value="email-changed" <?php selected( 'email-changed', $setting['notification'] ); ?>><?php esc_html_e( 'User Email Changed', 'bnfw' ); ?></option>
171
  <option
172
  value="core-updated" <?php selected( 'core-updated', $setting['notification'] ); ?>><?php esc_html_e( 'WordPress Core Automatic Background Updates', 'bnfw' ); ?></option>
173
  </optgroup>
174
  <optgroup label="Transactional">
175
  <option
176
  value="user-password" <?php selected( 'user-password', $setting['notification'] ); ?>><?php esc_html_e( 'Lost Password - For User', 'bnfw' ); ?></option>
 
 
 
 
177
  <option
178
  value="new-user" <?php selected( 'new-user', $setting['notification'] ); ?>><?php esc_html_e( 'New User Registration - For User', 'bnfw' ); ?></option>
179
  <option
180
  value="welcome-email" <?php selected( 'welcome-email', $setting['notification'] ); ?>><?php esc_html_e( 'New User - Post-registration Email', 'bnfw' ); ?></option>
181
- <option
182
- value="admin-role" <?php selected( 'admin-role', $setting['notification'] ); ?>><?php esc_html_e( 'User Role Changed - For Admin', 'bnfw' ); ?></option>
183
  <option
184
  value="user-role" <?php selected( 'user-role', $setting['notification'] ); ?>><?php esc_html_e( 'User Role Changed - For User', 'bnfw' ); ?></option>
185
  <option
@@ -287,7 +289,7 @@ class BNFW_Notification {
287
  <td>&nbsp;</td>
288
  <td>
289
  <div>
290
- <p style="margin-top: 0;"><?php esc_html_e( "This notification doesn't support additional email fields.", 'bnfw' ); ?></p>
291
  </div>
292
  </td>
293
  </tr>
@@ -942,11 +944,14 @@ class BNFW_Notification {
942
  case 'admin-password':
943
  $name = esc_html__( 'Lost Password - For Admin', 'bnfw' );
944
  break;
 
 
 
945
  case 'password-changed':
946
- $name = esc_html__( 'User Password Changed', 'bnfw' );
947
  break;
948
  case 'email-changed':
949
- $name = esc_html__( 'User Email Changed', 'bnfw' );
950
  break;
951
  case 'core-updated':
952
  $name = esc_html__( 'WordPress Core Automatic Background Updates', 'bnfw' );
164
  value="admin-password" <?php selected( 'admin-password', $setting['notification'] ); ?>><?php esc_html_e( 'Lost Password - For Admin', 'bnfw' ); ?></option>
165
  <option
166
  value="admin-user" <?php selected( 'admin-user', $setting['notification'] ); ?>><?php esc_html_e( 'New User Registration - For Admin', 'bnfw' ); ?></option>
167
+ <option
168
+ value="admin-password-changed" <?php selected( 'admin-password-changed', $setting['notification'] ); ?>><?php esc_html_e( 'Password Changed - For Admin', 'bnfw' ); ?></option>
169
  <option
170
+ value="admin-role" <?php selected( 'admin-role', $setting['notification'] ); ?>><?php esc_html_e( 'User Role Changed - For Admin', 'bnfw' ); ?></option>
 
 
171
  <option
172
  value="core-updated" <?php selected( 'core-updated', $setting['notification'] ); ?>><?php esc_html_e( 'WordPress Core Automatic Background Updates', 'bnfw' ); ?></option>
173
  </optgroup>
174
  <optgroup label="Transactional">
175
  <option
176
  value="user-password" <?php selected( 'user-password', $setting['notification'] ); ?>><?php esc_html_e( 'Lost Password - For User', 'bnfw' ); ?></option>
177
+ <option
178
+ value="password-changed" <?php selected( 'password-changed', $setting['notification'] ); ?>><?php esc_html_e( 'Password Changed - For User', 'bnfw' ); ?></option>
179
+ <option
180
+ value="email-changed" <?php selected( 'email-changed', $setting['notification'] ); ?>><?php esc_html_e( 'User Email Changed - For User', 'bnfw' ); ?></option>
181
  <option
182
  value="new-user" <?php selected( 'new-user', $setting['notification'] ); ?>><?php esc_html_e( 'New User Registration - For User', 'bnfw' ); ?></option>
183
  <option
184
  value="welcome-email" <?php selected( 'welcome-email', $setting['notification'] ); ?>><?php esc_html_e( 'New User - Post-registration Email', 'bnfw' ); ?></option>
 
 
185
  <option
186
  value="user-role" <?php selected( 'user-role', $setting['notification'] ); ?>><?php esc_html_e( 'User Role Changed - For User', 'bnfw' ); ?></option>
187
  <option
289
  <td>&nbsp;</td>
290
  <td>
291
  <div>
292
+ <p style="margin-top: 0;"><?php esc_html_e( "This notification doesn't support additional email fields due to a limitation in WordPress.", 'bnfw' ); ?></p>
293
  </div>
294
  </td>
295
  </tr>
944
  case 'admin-password':
945
  $name = esc_html__( 'Lost Password - For Admin', 'bnfw' );
946
  break;
947
+ case 'admin-password-changed':
948
+ $name = esc_html__( 'Password Changed - For Admin', 'bnfw' );
949
+ break;
950
  case 'password-changed':
951
+ $name = esc_html__( 'Password Changed - For User', 'bnfw' );
952
  break;
953
  case 'email-changed':
954
+ $name = esc_html__( 'User Email Changed - For User', 'bnfw' );
955
  break;
956
  case 'core-updated':
957
  $name = esc_html__( 'WordPress Core Automatic Background Updates', 'bnfw' );
includes/engine/class-bnfw-engine.php CHANGED
@@ -15,7 +15,7 @@ class BNFW_Engine {
15
  * @param array $setting
16
  */
17
  public function send_test_email( $setting ) {
18
- $subject = $setting['subject'];
19
  $message = '<p><strong>This is a test email. All shortcodes below will show in place but not be replaced with content.</strong></p>' . stripslashes( $setting['message'] );
20
 
21
  if ( 'true' != $setting['disable-autop'] && 'html' == $setting['email-formatting'] ) {
@@ -30,8 +30,6 @@ class BNFW_Engine {
30
  $headers[] = 'Content-type: text/html';
31
  }
32
 
33
- $subject = $this->handle_global_user_shortcodes( $subject, $email );
34
- $message = $this->handle_global_user_shortcodes( $message, $email );
35
  wp_mail( $email, stripslashes( $subject ), $message, $headers );
36
  }
37
 
@@ -225,8 +223,8 @@ class BNFW_Engine {
225
  $email_data['message'] = $this->handle_shortcodes( $setting['message'], $setting['notification'], $extra_data );
226
  $email_data['subject'] = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $extra_data );
227
 
228
- $emails = $this->get_emails( $setting, $extra_data );
229
- $headers = $this->get_headers( $emails );
230
 
231
  if ( 'true' != $setting['disable-autop'] && 'html' == $setting['email-formatting'] ) {
232
  $email_data['message'] = wpautop( $email_data['message'] );
@@ -243,6 +241,42 @@ class BNFW_Engine {
243
  return $email_data;
244
  }
245
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  /**
247
  * Handle shortcode for password reset email message.
248
  *
@@ -270,6 +304,32 @@ class BNFW_Engine {
270
  return $message;
271
  }
272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  /**
274
  * Generate message for notification.
275
  *
@@ -298,6 +358,7 @@ class BNFW_Engine {
298
  break;
299
 
300
  case 'admin-password':
 
301
  case 'user-password':
302
  case 'admin-user':
303
  case 'welcome-email':
@@ -375,6 +436,29 @@ class BNFW_Engine {
375
  return $message;
376
  }
377
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  /**
379
  * Handle post shortcodes.
380
  *
@@ -383,7 +467,7 @@ class BNFW_Engine {
383
  * @param int $post_id
384
  * @return string
385
  */
386
- private function post_shortcodes( $message, $post_id ) {
387
  $post = get_post( $post_id );
388
 
389
  $post_content = apply_filters( 'the_content', $post->post_content );
@@ -416,12 +500,14 @@ class BNFW_Engine {
416
  $message = str_replace( '[permalink]', get_permalink( $post->ID ), $message );
417
  $message = str_replace( '[edit_post]', get_edit_post_link( $post->ID ), $message );
418
 
 
419
  if ( has_post_thumbnail( $post->ID ) ) {
420
  $image_url = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail' );
421
  if ( is_array( $image_url ) ) {
422
- $message = str_replace( '[featured_image]', $image_url[0], $message );
423
  }
424
  }
 
425
 
426
  if ( 'future' == $post->post_status ) {
427
  $message = str_replace( '[post_scheduled_date]', $post->post_date, $message );
@@ -452,8 +538,20 @@ class BNFW_Engine {
452
  $message = str_replace( '[post_update_author]', $last_user_info->display_name, $message );
453
  }
454
 
455
- $message = apply_filters( 'bnfw_shortcodes_post', $message, $post_id );
456
- return $message;
 
 
 
 
 
 
 
 
 
 
 
 
457
  }
458
 
459
  /**
@@ -793,27 +891,4 @@ class BNFW_Engine {
793
 
794
  return $headers;
795
  }
796
-
797
- /**
798
- * Handle Global User Shortcodes.
799
- *
800
- * @param string $message String to be processed.
801
- * @param string $email Email of the user.
802
- *
803
- * @return string Processed string.
804
- */
805
- private function handle_global_user_shortcodes( $message, $email ) {
806
- $user = get_user_by( 'email', $email );
807
-
808
- if ( false === $user ) {
809
- $message = str_replace( '[global_user_firstname]', $email, $message );
810
- $message = str_replace( '[global_user_lastname]', $email, $message );
811
- } else {
812
- $message = str_replace( '[global_user_firstname]', $user->first_name, $message );
813
- $message = str_replace( '[global_user_lastname]', $user->last_name, $message );
814
- }
815
- $message = str_replace( '[global_user_email]', $email, $message );
816
-
817
- return $message;
818
- }
819
  }
15
  * @param array $setting
16
  */
17
  public function send_test_email( $setting ) {
18
+ $subject = 'Test Email: ' . $setting['subject'];
19
  $message = '<p><strong>This is a test email. All shortcodes below will show in place but not be replaced with content.</strong></p>' . stripslashes( $setting['message'] );
20
 
21
  if ( 'true' != $setting['disable-autop'] && 'html' == $setting['email-formatting'] ) {
30
  $headers[] = 'Content-type: text/html';
31
  }
32
 
 
 
33
  wp_mail( $email, stripslashes( $subject ), $message, $headers );
34
  }
35
 
223
  $email_data['message'] = $this->handle_shortcodes( $setting['message'], $setting['notification'], $extra_data );
224
  $email_data['subject'] = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $extra_data );
225
 
226
+ $email_data['message'] = $this->handle_global_user_shortcodes( $email_data['message'], $email_data['to'] );
227
+ $email_data['subject'] = $this->handle_global_user_shortcodes( $email_data['subject'], $email_data['to'] );
228
 
229
  if ( 'true' != $setting['disable-autop'] && 'html' == $setting['email-formatting'] ) {
230
  $email_data['message'] = wpautop( $email_data['message'] );
241
  return $email_data;
242
  }
243
 
244
+ /**
245
+ * Handle shortcodes for core updated notification.
246
+ *
247
+ * @since 1.6
248
+ *
249
+ * @param array $email_data Email data.
250
+ * @param array $setting Notification settings.
251
+ * @param string $type Result of update.
252
+ *
253
+ * @return array Modified email data.
254
+ */
255
+ public function handle_core_updated_notification( $email_data, $setting, $type ) {
256
+ $email_data['body'] = $this->handle_shortcodes( $setting['message'], $setting['notification'], $type );
257
+ $email_data['subject'] = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $type );
258
+
259
+ $emails = $this->get_emails( $setting, $type );
260
+ $headers = $this->get_headers( $emails );
261
+
262
+ $email_data['body'] = $this->handle_global_user_shortcodes( $email_data['body'], $emails['to'][0] );
263
+ $email_data['subject'] = $this->handle_global_user_shortcodes( $email_data['subject'], $emails['to'][0] );
264
+
265
+ if ( 'true' != $setting['disable-autop'] && 'html' == $setting['email-formatting'] ) {
266
+ $email_data['body'] = wpautop( $email_data['body'] );
267
+ }
268
+
269
+ if ( 'html' == $setting['email-formatting'] ) {
270
+ $headers[] = 'Content-type: text/html';
271
+ } else {
272
+ $headers[] = 'Content-type: text/plain';
273
+ }
274
+
275
+ $email_data['headers'] = $headers;
276
+
277
+ return $email_data;
278
+ }
279
+
280
  /**
281
  * Handle shortcode for password reset email message.
282
  *
304
  return $message;
305
  }
306
 
307
+ /**
308
+ * Send Password Changed email.
309
+ *
310
+ * @param array $setting Notification Setting.
311
+ * @param WP_User $user User for whom the password has changed.
312
+ */
313
+ public function send_password_changed_email( $setting, $user ) {
314
+ $user_id = $user->ID;
315
+
316
+ $subject = $this->handle_shortcodes( $setting['subject'], $setting['notification'], $user_id );
317
+ $message = $this->handle_shortcodes( $setting['message'], $setting['notification'], $user_id );
318
+
319
+ if ( 'true' != $setting['disable-autop'] && 'html' == $setting['email-formatting'] ) {
320
+ $message = wpautop( $message );
321
+ }
322
+
323
+ $headers = array();
324
+ if ( 'html' == $setting['email-formatting'] ) {
325
+ $headers[] = 'Content-type: text/html';
326
+ }
327
+
328
+ $subject = $this->handle_global_user_shortcodes( $subject, $user->user_email );
329
+ $message = $this->handle_global_user_shortcodes( $message, $user->user_email );
330
+ wp_mail( $user->user_email, stripslashes( $subject ), $message, $headers );
331
+ }
332
+
333
  /**
334
  * Generate message for notification.
335
  *
358
  break;
359
 
360
  case 'admin-password':
361
+ case 'admin-password-changed':
362
  case 'user-password':
363
  case 'admin-user':
364
  case 'welcome-email':
436
  return $message;
437
  }
438
 
439
+ /**
440
+ * Handle Global User Shortcodes.
441
+ *
442
+ * @param string $message String to be processed.
443
+ * @param string $email Email of the user.
444
+ *
445
+ * @return string Processed string.
446
+ */
447
+ private function handle_global_user_shortcodes( $message, $email ) {
448
+ $user = get_user_by( 'email', $email );
449
+
450
+ if ( false === $user ) {
451
+ $message = str_replace( '[global_user_firstname]', $email, $message );
452
+ $message = str_replace( '[global_user_lastname]', $email, $message );
453
+ } else {
454
+ $message = str_replace( '[global_user_firstname]', $user->first_name, $message );
455
+ $message = str_replace( '[global_user_lastname]', $user->last_name, $message );
456
+ }
457
+ $message = str_replace( '[global_user_email]', $email, $message );
458
+
459
+ return $message;
460
+ }
461
+
462
  /**
463
  * Handle post shortcodes.
464
  *
467
  * @param int $post_id
468
  * @return string
469
  */
470
+ public function post_shortcodes( $message, $post_id ) {
471
  $post = get_post( $post_id );
472
 
473
  $post_content = apply_filters( 'the_content', $post->post_content );
500
  $message = str_replace( '[permalink]', get_permalink( $post->ID ), $message );
501
  $message = str_replace( '[edit_post]', get_edit_post_link( $post->ID ), $message );
502
 
503
+ $featured_image = '';
504
  if ( has_post_thumbnail( $post->ID ) ) {
505
  $image_url = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'single-post-thumbnail' );
506
  if ( is_array( $image_url ) ) {
507
+ $featured_image = $image_url[0];
508
  }
509
  }
510
+ $message = str_replace( '[featured_image]', $featured_image, $message );
511
 
512
  if ( 'future' == $post->post_status ) {
513
  $message = str_replace( '[post_scheduled_date]', $post->post_date, $message );
538
  $message = str_replace( '[post_update_author]', $last_user_info->display_name, $message );
539
  }
540
 
541
+ $terms_list = '';
542
+ $taxonomy_matches = array();
543
+ preg_match( '/\[post_term taxonomy="([^"]*)"\]/i', $message, $taxonomy_matches );
544
+
545
+ if ( count( $taxonomy_matches ) > 0 ) {
546
+ $terms = wp_get_post_terms( $post_id, $taxonomy_matches[1], array( 'fields' => 'names' ) );
547
+
548
+ if ( ! is_wp_error( $terms ) ) {
549
+ $terms_list = implode( ', ', $terms );
550
+ }
551
+ }
552
+ $message = preg_replace( '/\[post_term taxonomy="([^"]*)"\]/i', $terms_list, $message );
553
+
554
+ return apply_filters( 'bnfw_shortcodes_post', $message, $post_id );
555
  }
556
 
557
  /**
891
 
892
  return $headers;
893
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
894
  }
includes/helpers/helpers.php CHANGED
@@ -16,9 +16,9 @@ function bnfw_get_user_select_class() {
16
  $user_count = count_users();
17
 
18
  if ( $user_count['total_users'] > 100 ) {
19
- return 'user-select2';
20
  } else {
21
- return 'select2';
22
  }
23
  }
24
 
16
  $user_count = count_users();
17
 
18
  if ( $user_count['total_users'] > 100 ) {
19
+ return 'user-ajax-select2';
20
  } else {
21
+ return 'user-select2';
22
  }
23
  }
24
 
includes/libraries/EDD_SL_Plugin_Updater.php CHANGED
@@ -1,23 +1,23 @@
1
  <?php
2
 
3
- // uncomment this line for testing
4
- //set_site_transient( 'update_plugins', null );
5
-
6
  // Exit if accessed directly
7
  if ( ! defined( 'ABSPATH' ) ) exit;
8
 
9
  /**
10
  * Allows plugins to use their own update API.
11
  *
12
- * @author Pippin Williamson
13
- * @version 1.6.2
14
  */
15
  class EDD_SL_Plugin_Updater {
16
- private $api_url = '';
17
- private $api_data = array();
18
- private $name = '';
19
- private $slug = '';
20
- private $version = '';
 
 
 
21
 
22
  /**
23
  * Class constructor.
@@ -29,16 +29,23 @@ class EDD_SL_Plugin_Updater {
29
  * @param string $_plugin_file Path to the plugin file.
30
  * @param array $_api_data Optional data to send with API calls.
31
  */
32
- function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
33
- $this->api_url = trailingslashit( $_api_url );
34
- $this->api_data = $_api_data;
35
- $this->name = plugin_basename( $_plugin_file );
36
- $this->slug = basename( $_plugin_file, '.php' );
37
- $this->version = $_api_data['version'];
 
 
 
 
 
 
 
 
38
 
39
  // Set up hooks.
40
  $this->init();
41
- add_action( 'admin_init', array( $this, 'show_changelog' ) );
42
 
43
  }
44
 
@@ -50,11 +57,13 @@ class EDD_SL_Plugin_Updater {
50
  * @return void
51
  */
52
  public function init() {
 
53
  add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
54
  add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
55
-
56
- remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10, 2 );
57
  add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
 
 
58
  }
59
 
60
  /**
@@ -70,35 +79,42 @@ class EDD_SL_Plugin_Updater {
70
  * @param array $_transient_data Update array build by WordPress.
71
  * @return array Modified update array with custom plugin data.
72
  */
73
- function check_update( $_transient_data ) {
74
 
75
  global $pagenow;
76
 
77
- if( ! is_object( $_transient_data ) ) {
78
  $_transient_data = new stdClass;
79
  }
80
 
81
- if( 'plugins.php' == $pagenow && is_multisite() ) {
 
 
 
 
82
  return $_transient_data;
83
  }
84
 
85
- if ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) {
86
 
87
- $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
 
88
 
89
- if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
90
 
91
- if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
92
 
93
- $_transient_data->response[ $this->name ] = $version_info;
94
 
95
- }
96
 
97
- $_transient_data->last_checked = time();
98
- $_transient_data->checked[ $this->name ] = $this->version;
99
 
100
  }
101
 
 
 
 
102
  }
103
 
104
  return $_transient_data;
@@ -112,6 +128,10 @@ class EDD_SL_Plugin_Updater {
112
  */
113
  public function show_update_notification( $file, $plugin ) {
114
 
 
 
 
 
115
  if( ! current_user_can( 'update_plugins' ) ) {
116
  return;
117
  }
@@ -128,33 +148,30 @@ class EDD_SL_Plugin_Updater {
128
  remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
129
 
130
  $update_cache = get_site_transient( 'update_plugins' );
131
-
132
  $update_cache = is_object( $update_cache ) ? $update_cache : new stdClass();
133
 
134
  if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
135
 
136
- $cache_key = md5( 'edd_plugin_' .sanitize_key( $this->name ) . '_version_info' );
137
- $version_info = get_transient( $cache_key );
138
 
139
- if( false === $version_info ) {
 
140
 
141
- $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug ) );
142
-
143
- set_transient( $cache_key, $version_info, 3600 );
144
  }
145
 
146
-
147
- if( ! is_object( $version_info ) ) {
148
  return;
149
  }
150
 
151
- if( version_compare( $this->version, $version_info->new_version, '<' ) ) {
152
 
153
  $update_cache->response[ $this->name ] = $version_info;
154
 
155
  }
156
 
157
- $update_cache->last_checked = time();
158
  $update_cache->checked[ $this->name ] = $this->version;
159
 
160
  set_site_transient( 'update_plugins', $update_cache );
@@ -172,32 +189,39 @@ class EDD_SL_Plugin_Updater {
172
 
173
  // build a plugin list row, with update notification
174
  $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
175
- echo '<tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange"><div class="update-message">';
 
 
 
176
 
177
  $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
178
 
179
  if ( empty( $version_info->download_link ) ) {
180
  printf(
181
- __( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a>.', 'bnfw' ),
182
  esc_html( $version_info->name ),
183
- esc_url( $changelog_link ),
184
- esc_html( $version_info->new_version )
 
185
  );
186
  } else {
187
  printf(
188
- __( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a> or <a href="%4$s">update now</a>.', 'bnfw' ),
189
  esc_html( $version_info->name ),
190
- esc_url( $changelog_link ),
191
  esc_html( $version_info->new_version ),
192
- esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) )
 
 
193
  );
194
  }
195
 
 
 
196
  echo '</div></td></tr>';
197
  }
198
  }
199
 
200
-
201
  /**
202
  * Updates information on the "View version x.x details" page with custom data.
203
  *
@@ -208,8 +232,7 @@ class EDD_SL_Plugin_Updater {
208
  * @param object $_args
209
  * @return object $_data
210
  */
211
- function plugins_api_filter( $_data, $_action = '', $_args = null ) {
212
-
213
 
214
  if ( $_action != 'plugin_information' ) {
215
 
@@ -227,21 +250,35 @@ class EDD_SL_Plugin_Updater {
227
  'slug' => $this->slug,
228
  'is_ssl' => is_ssl(),
229
  'fields' => array(
230
- 'banners' => false, // These will be supported soon hopefully
231
  'reviews' => false
232
  )
233
  );
234
 
235
- $api_response = $this->api_request( 'plugin_information', $to_send );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
- if ( false !== $api_response ) {
238
- $_data = $api_response;
239
  }
240
 
241
  return $_data;
242
  }
243
 
244
-
245
  /**
246
  * Disable SSL verification in order to prevent download update failures
247
  *
@@ -249,7 +286,7 @@ class EDD_SL_Plugin_Updater {
249
  * @param string $url
250
  * @return object $array
251
  */
252
- function http_request_args( $args, $url ) {
253
  // If it is an https request and we are performing a package download, disable ssl verification
254
  if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
255
  $args['sslverify'] = false;
@@ -278,7 +315,7 @@ class EDD_SL_Plugin_Updater {
278
  return;
279
  }
280
 
281
- if( $this->api_url == home_url() ) {
282
  return false; // Don't allow a plugin to ping itself
283
  }
284
 
@@ -289,7 +326,8 @@ class EDD_SL_Plugin_Updater {
289
  'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
290
  'slug' => $data['slug'],
291
  'author' => $data['author'],
292
- 'url' => home_url()
 
293
  );
294
 
295
  $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
@@ -304,11 +342,16 @@ class EDD_SL_Plugin_Updater {
304
  $request = false;
305
  }
306
 
 
 
 
 
307
  return $request;
308
  }
309
 
310
  public function show_changelog() {
311
 
 
312
 
313
  if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
314
  return;
@@ -323,17 +366,77 @@ class EDD_SL_Plugin_Updater {
323
  }
324
 
325
  if( ! current_user_can( 'update_plugins' ) ) {
326
- wp_die( __( 'You do not have permission to install plugin updates', 'bnfw' ), __( 'Error', 'bnfw' ), array( 'response' => 403 ) );
327
  }
328
 
329
- $response = $this->api_request( 'plugin_latest_version', array( 'slug' => $_REQUEST['slug'] ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
 
331
- if( $response && isset( $response->sections['changelog'] ) ) {
332
- echo '<div style="background:#fff;padding:10px;">' . $response->sections['changelog'] . '</div>';
333
  }
334
 
 
 
 
335
 
336
  exit;
337
  }
338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  }
1
  <?php
2
 
 
 
 
3
  // Exit if accessed directly
4
  if ( ! defined( 'ABSPATH' ) ) exit;
5
 
6
  /**
7
  * Allows plugins to use their own update API.
8
  *
9
+ * @author Easy Digital Downloads
10
+ * @version 1.6.8
11
  */
12
  class EDD_SL_Plugin_Updater {
13
+
14
+ private $api_url = '';
15
+ private $api_data = array();
16
+ private $name = '';
17
+ private $slug = '';
18
+ private $version = '';
19
+ private $wp_override = false;
20
+ private $cache_key = '';
21
 
22
  /**
23
  * Class constructor.
29
  * @param string $_plugin_file Path to the plugin file.
30
  * @param array $_api_data Optional data to send with API calls.
31
  */
32
+ public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
33
+
34
+ global $edd_plugin_data;
35
+
36
+ $this->api_url = trailingslashit( $_api_url );
37
+ $this->api_data = $_api_data;
38
+ $this->name = plugin_basename( $_plugin_file );
39
+ $this->slug = basename( $_plugin_file, '.php' );
40
+ $this->version = $_api_data['version'];
41
+ $this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
42
+
43
+ $this->cache_key = md5( serialize( $this->slug . $this->api_data['license'] ) );
44
+
45
+ $edd_plugin_data[ $this->slug ] = $this->api_data;
46
 
47
  // Set up hooks.
48
  $this->init();
 
49
 
50
  }
51
 
57
  * @return void
58
  */
59
  public function init() {
60
+
61
  add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
62
  add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
63
+ remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10 );
 
64
  add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
65
+ add_action( 'admin_init', array( $this, 'show_changelog' ) );
66
+
67
  }
68
 
69
  /**
79
  * @param array $_transient_data Update array build by WordPress.
80
  * @return array Modified update array with custom plugin data.
81
  */
82
+ public function check_update( $_transient_data ) {
83
 
84
  global $pagenow;
85
 
86
+ if ( ! is_object( $_transient_data ) ) {
87
  $_transient_data = new stdClass;
88
  }
89
 
90
+ if ( 'plugins.php' == $pagenow && is_multisite() ) {
91
+ return $_transient_data;
92
+ }
93
+
94
+ if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) {
95
  return $_transient_data;
96
  }
97
 
98
+ $version_info = $this->get_cached_version_info();
99
 
100
+ if ( false === $version_info ) {
101
+ $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => ! empty( $this->api_data['beta'] ) ) );
102
 
103
+ $this->set_version_info_cache( $version_info );
104
 
105
+ }
106
 
107
+ if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
108
 
109
+ if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
110
 
111
+ $_transient_data->response[ $this->name ] = $version_info;
 
112
 
113
  }
114
 
115
+ $_transient_data->last_checked = current_time( 'timestamp' );
116
+ $_transient_data->checked[ $this->name ] = $this->version;
117
+
118
  }
119
 
120
  return $_transient_data;
128
  */
129
  public function show_update_notification( $file, $plugin ) {
130
 
131
+ if ( is_network_admin() ) {
132
+ return;
133
+ }
134
+
135
  if( ! current_user_can( 'update_plugins' ) ) {
136
  return;
137
  }
148
  remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
149
 
150
  $update_cache = get_site_transient( 'update_plugins' );
151
+
152
  $update_cache = is_object( $update_cache ) ? $update_cache : new stdClass();
153
 
154
  if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
155
 
156
+ $version_info = $this->get_cached_version_info();
 
157
 
158
+ if ( false === $version_info ) {
159
+ $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => ! empty( $this->api_data['beta'] ) ) );
160
 
161
+ $this->set_version_info_cache( $version_info );
 
 
162
  }
163
 
164
+ if ( ! is_object( $version_info ) ) {
 
165
  return;
166
  }
167
 
168
+ if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
169
 
170
  $update_cache->response[ $this->name ] = $version_info;
171
 
172
  }
173
 
174
+ $update_cache->last_checked = current_time( 'timestamp' );
175
  $update_cache->checked[ $this->name ] = $this->version;
176
 
177
  set_site_transient( 'update_plugins', $update_cache );
189
 
190
  // build a plugin list row, with update notification
191
  $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
192
+ # <tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange">
193
+ echo '<tr class="plugin-update-tr" id="' . $this->slug . '-update" data-slug="' . $this->slug . '" data-plugin="' . $this->slug . '/' . $file . '">';
194
+ echo '<td colspan="3" class="plugin-update colspanchange">';
195
+ echo '<div class="update-message notice inline notice-warning notice-alt">';
196
 
197
  $changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
198
 
199
  if ( empty( $version_info->download_link ) ) {
200
  printf(
201
+ __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.', 'easy-digital-downloads' ),
202
  esc_html( $version_info->name ),
203
+ '<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
204
+ esc_html( $version_info->new_version ),
205
+ '</a>'
206
  );
207
  } else {
208
  printf(
209
+ __( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s.', 'easy-digital-downloads' ),
210
  esc_html( $version_info->name ),
211
+ '<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
212
  esc_html( $version_info->new_version ),
213
+ '</a>',
214
+ '<a href="' . esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) ) .'">',
215
+ '</a>'
216
  );
217
  }
218
 
219
+ do_action( "in_plugin_update_message-{$file}", $plugin, $version_info );
220
+
221
  echo '</div></td></tr>';
222
  }
223
  }
224
 
 
225
  /**
226
  * Updates information on the "View version x.x details" page with custom data.
227
  *
232
  * @param object $_args
233
  * @return object $_data
234
  */
235
+ public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
 
236
 
237
  if ( $_action != 'plugin_information' ) {
238
 
250
  'slug' => $this->slug,
251
  'is_ssl' => is_ssl(),
252
  'fields' => array(
253
+ 'banners' => array(),
254
  'reviews' => false
255
  )
256
  );
257
 
258
+ $cache_key = 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] ) );
259
+
260
+ // Get the transient where we store the api request for this plugin for 24 hours
261
+ $edd_api_request_transient = $this->get_cached_version_info( $cache_key );
262
+
263
+ //If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
264
+ if ( empty( $edd_api_request_transient ) ){
265
+
266
+ $api_response = $this->api_request( 'plugin_information', $to_send );
267
+
268
+ // Expires in 3 hours
269
+ $this->set_version_info_cache( $api_response, $cache_key );
270
+
271
+ if ( false !== $api_response ) {
272
+ $_data = $api_response;
273
+ }
274
 
275
+ } else {
276
+ $_data = $edd_api_request_transient;
277
  }
278
 
279
  return $_data;
280
  }
281
 
 
282
  /**
283
  * Disable SSL verification in order to prevent download update failures
284
  *
286
  * @param string $url
287
  * @return object $array
288
  */
289
+ public function http_request_args( $args, $url ) {
290
  // If it is an https request and we are performing a package download, disable ssl verification
291
  if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
292
  $args['sslverify'] = false;
315
  return;
316
  }
317
 
318
+ if( $this->api_url == trailingslashit (home_url() ) ) {
319
  return false; // Don't allow a plugin to ping itself
320
  }
321
 
326
  'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
327
  'slug' => $data['slug'],
328
  'author' => $data['author'],
329
+ 'url' => home_url(),
330
+ 'beta' => ! empty( $data['beta'] ),
331
  );
332
 
333
  $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
342
  $request = false;
343
  }
344
 
345
+ if ( $request && isset( $request->banners ) ) {
346
+ $request->banners = maybe_unserialize( $request->banners );
347
+ }
348
+
349
  return $request;
350
  }
351
 
352
  public function show_changelog() {
353
 
354
+ global $edd_plugin_data;
355
 
356
  if( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
357
  return;
366
  }
367
 
368
  if( ! current_user_can( 'update_plugins' ) ) {
369
+ wp_die( __( 'You do not have permission to install plugin updates', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
370
  }
371
 
372
+ $data = $edd_plugin_data[ $_REQUEST['slug'] ];
373
+ $cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_version_info' );
374
+ $version_info = $this->get_cached_version_info( $cache_key );
375
+
376
+ if( false === $version_info ) {
377
+
378
+ $api_params = array(
379
+ 'edd_action' => 'get_version',
380
+ 'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
381
+ 'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
382
+ 'slug' => $_REQUEST['slug'],
383
+ 'author' => $data['author'],
384
+ 'url' => home_url(),
385
+ 'beta' => ! empty( $data['beta'] )
386
+ );
387
+
388
+ $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );
389
+
390
+ if ( ! is_wp_error( $request ) ) {
391
+ $version_info = json_decode( wp_remote_retrieve_body( $request ) );
392
+ }
393
+
394
+ if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
395
+ $version_info->sections = maybe_unserialize( $version_info->sections );
396
+ } else {
397
+ $version_info = false;
398
+ }
399
+
400
+ $this->set_version_info_cache( $version_info, $cache_key );
401
 
 
 
402
  }
403
 
404
+ if( ! empty( $version_info ) && isset( $version_info->sections['changelog'] ) ) {
405
+ echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>';
406
+ }
407
 
408
  exit;
409
  }
410
 
411
+ public function get_cached_version_info( $cache_key = '' ) {
412
+
413
+ if( empty( $cache_key ) ) {
414
+ $cache_key = $this->cache_key;
415
+ }
416
+
417
+ $cache = get_option( $cache_key );
418
+
419
+ if( empty( $cache['timeout'] ) || current_time( 'timestamp' ) > $cache['timeout'] ) {
420
+ return false; // Cache is expired
421
+ }
422
+
423
+ return json_decode( $cache['value'] );
424
+
425
+ }
426
+
427
+ public function set_version_info_cache( $value = '', $cache_key = '' ) {
428
+
429
+ if( empty( $cache_key ) ) {
430
+ $cache_key = $this->cache_key;
431
+ }
432
+
433
+ $data = array(
434
+ 'timeout' => strtotime( '+3 hours', current_time( 'timestamp' ) ),
435
+ 'value' => json_encode( $value )
436
+ );
437
+
438
+ update_option( $cache_key, $data );
439
+
440
+ }
441
+
442
  }
includes/license/class-bnfw-license-setting.php CHANGED
@@ -46,7 +46,7 @@ function bnfw_render_license_page() {
46
  if ( ! empty( $settings ) ) {
47
  submit_button( esc_html__( 'Save License', 'bnfw' ) );
48
  } else {
49
- esc_html_e( '<br>You have no BNFW Add-ons installed yet. You can buy add-ons from the <a href="https://betternotificationsforwp.com/store/?utm_source=WP%20Admin%20Submenu%20Item%20-%20"Add-on%20Licenses"&amp;utm_medium=referral" target="_blank">Store</a>.', 'bnfw' );
50
  }
51
  ?>
52
  </form>
46
  if ( ! empty( $settings ) ) {
47
  submit_button( esc_html__( 'Save License', 'bnfw' ) );
48
  } else {
49
+ _e( '<br>You have no BNFW Premium Add-ons installed yet. You can buy add-ons from the <a href="https://betternotificationsforwp.com/store/?utm_source=WP%20Admin%20Submenu%20Item%20-%20Add-on%20Licenses&amp;utm_medium=referral" target="_blank">Store</a>.', 'bnfw' );
50
  }
51
  ?>
52
  </form>
includes/overrides.php CHANGED
@@ -115,4 +115,36 @@ if ( ! function_exists( 'wp_new_user_notification' ) ) {
115
  }
116
  }
117
  }
118
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
  }
117
  }
118
+
119
+ if ( ! function_exists( 'wp_password_change_notification' ) ) {
120
+ /**
121
+ * Notify the blog admin of a user changing password, normally via email.
122
+ *
123
+ * @param WP_User $user User object.
124
+ */
125
+ function wp_password_change_notification( $user ) {
126
+ $bnfw = BNFW::factory();
127
+
128
+ if ( $bnfw->notifier->notification_exists( 'admin-password-changed', false ) ) {
129
+ $notifications = $bnfw->notifier->get_notifications( 'admin-password-changed' );
130
+
131
+ if ( count( $notifications ) > 0 ) {
132
+ // Ideally there should be only one notification for this type.
133
+ // If there are multiple notification then we will read data about only the last one
134
+ $bnfw->engine->send_notification( $bnfw->notifier->read_settings( end( $notifications )->ID ), $user->ID );
135
+ }
136
+ } else {
137
+ // send a copy of password change notification to the admin
138
+ // but check to see if it's the admin whose password we're changing, and skip this.
139
+ if ( 0 !== strcasecmp( $user->user_email, get_option( 'admin_email' ) ) ) {
140
+ /* translators: %s: user name */
141
+ $message = sprintf( __( 'Password changed for user: %s' ), $user->user_login ) . "\r\n";
142
+ // The blogname option is escaped with esc_html on the way into the database in sanitize_option
143
+ // we want to reverse this for the plain text arena of emails.
144
+ $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
145
+ /* translators: %s: site title */
146
+ wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] Password Changed' ), $blogname ), $message );
147
+ }
148
+ }
149
+ }
150
+ }
languages/bnfw-de_DE.po CHANGED
@@ -442,5 +442,5 @@ msgid "Voltronik"
442
  msgstr "Voltronik"
443
 
444
  #. Author URI of the plugin/theme
445
- msgid "http://www.voltronik.co.uk/"
446
- msgstr "http://www.voltronik.co.uk/"
442
  msgstr "Voltronik"
443
 
444
  #. Author URI of the plugin/theme
445
+ msgid "https://betternotificationsforwp.com/"
446
+ msgstr "https://betternotificationsforwp.com/"
languages/bnfw-fr_FR.po CHANGED
@@ -41,7 +41,7 @@ msgstr "Envoyez d’emails personnalisés à vos utilisateurs pour les différen
41
 
42
  #. Author of the plugin/theme
43
  msgid "Voltronik"
44
- msgstr "Ludovic D"
45
 
46
  #. Author URI of the plugin/theme
47
  msgid "https://betternotificationsforwp.com/"
41
 
42
  #. Author of the plugin/theme
43
  msgid "Voltronik"
44
+ msgstr "Voltronik"
45
 
46
  #. Author URI of the plugin/theme
47
  msgid "https://betternotificationsforwp.com/"
languages/bnfw-pt_BR.po CHANGED
@@ -401,5 +401,5 @@ msgid "Voltronik"
401
  msgstr "Voltronik"
402
 
403
  #. Author URI of the plugin/theme
404
- msgid "http://www.voltronik.co.uk/"
405
- msgstr "http://www.voltronik.co.uk/"
401
  msgstr "Voltronik"
402
 
403
  #. Author URI of the plugin/theme
404
+ msgid "https://betternotificationsforwp.com/"
405
+ msgstr "https://betternotificationsforwp.com/"
languages/bnfw.pot CHANGED
@@ -415,5 +415,5 @@ msgid "Voltronik"
415
  msgstr ""
416
 
417
  #. Author URI of the plugin/theme
418
- msgid "http://www.voltronik.co.uk/"
419
  msgstr ""
415
  msgstr ""
416
 
417
  #. Author URI of the plugin/theme
418
+ msgid "https://betternotificationsforwp.com/"
419
  msgstr ""