PluginProbe
Customize WordPress Emails and Alerts – Better Notifications for WP / 1.7.7
Customize WordPress Emails and Alerts – Better Notifications for WP v1.7.7
1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.8 1.8.1 1.8.10 1.8.11 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 All 81 releases
bnfw / bnfw.php

bnfw.php in Customize WordPress Emails and Alerts – Better Notifications for WP 1.7.7, at bnfw.php

1,307 lines 39.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Better Notifications for WP
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.7.7
7 * Author: Made with Fuel
8 * Author URI: https://betternotificationsforwp.com/
9 * Author Email: hello@betternotificationsforwp.com
10 * License: GPLv2 or later
11 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
12 * Text Domain: bnfw
13 * Domain Path: /languages
14 */
15
16 /**
17 * Copyright © 2020 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.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30 class BNFW {
31
32 /**
33 * Constructor.
34 *
35 * @since 1.0
36 */
37 function __construct() {
38 $this->load_textdomain();
39 $this->includes();
40 $this->hooks();
41
42 /**
43 * BNFW Notification.
44 *
45 * @var \BNFW_Notification
46 */
47 $this->notifier = new BNFW_Notification;
48
49 /**
50 * BNFW Engine.
51 *
52 * @var \BNFW_Engine
53 */
54 $this->engine = new BNFW_Engine;
55 }
56
57 /**
58 * Factory method to return the instance of the class.
59 *
60 * Makes sure that only one instance is created.
61 *
62 * @return \BNFW Instance of the class.
63 */
64 public static function factory() {
65 static $instance = false;
66 if ( ! $instance ) {
67 $instance = new self();
68 }
69 return $instance;
70 }
71
72 /**
73 * Loads the plugin language files
74 *
75 * @since 1.0
76 */
77 public function load_textdomain() {
78 // Load localization domain
79 $this->translations = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
80 load_plugin_textdomain( 'bnfw', false, $this->translations );
81 }
82
83 /**
84 * Include required files.
85 *
86 * @since 1.0
87 */
88 public function includes() {
89
90 // Load license related classes
91 if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
92 require_once 'includes/libraries/EDD_SL_Plugin_Updater.php';
93 }
94
95 include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
96
97 require_once 'vendor/persist-admin-notices-dismissal/persist-admin-notices-dismissal.php';
98
99 require_once 'includes/license/class-bnfw-license.php';
100 require_once 'includes/license/class-bnfw-license-setting.php';
101
102 // Load Engine
103 require_once 'includes/engine/class-bnfw-engine.php';
104 require_once 'includes/overrides.php';
105
106 // Load notification post type and notification helpers
107 require_once 'includes/admin/class-bnfw-notification.php';
108 require_once 'includes/notification/post-notification.php';
109
110 // Helpers
111 require_once 'includes/helpers/helpers.php';
112 require_once 'includes/helpers/ajax-helpers.php';
113
114 // Load Admin Pages
115 if ( is_admin() ) {
116 require_once 'includes/admin/bnfw-settings.php';
117 }
118 }
119
120 /**
121 * Register Hooks.
122 *
123 * @since 1.0
124 */
125 public function hooks() {
126 global $wp_version;
127
128 register_activation_hook( __FILE__, array( $this, 'activate' ) );
129
130 add_action( 'admin_init', array( 'PAnD', 'init' ) );
131 add_action( 'admin_init', array( $this, 'add_capability_to_admin' ) );
132
133 add_action( 'draft_to_private' , array( $this, 'private_post' ) );
134 add_action( 'future_to_private' , array( $this, 'private_post' ) );
135 add_action( 'pending_to_private' , array( $this, 'private_post' ) );
136 add_action( 'publish_to_private' , array( $this, 'private_post' ) );
137
138 add_action( 'wp_insert_post' , array( $this, 'insert_post' ), 10, 3 );
139
140 add_action( 'publish_to_trash' , array( $this, 'trash_post' ));
141
142 add_action( 'auto-draft_to_publish' , array( $this, 'publish_post' ) );
143 add_action( 'draft_to_publish' , array( $this, 'publish_post' ) );
144 add_action( 'future_to_publish' , array( $this, 'publish_post' ) );
145 add_action( 'pending_to_publish' , array( $this, 'publish_post' ) );
146 add_action( 'private_to_publish' , array( $this, 'publish_post' ) );
147 // add_action( 'acf/submit_form' , array( $this, 'acf_submit_form' ), 10, 2 );
148
149 add_action( 'publish_to_publish' , array( $this, 'update_post' ) );
150 add_action( 'private_to_private' , array( $this, 'update_post' ) );
151
152 add_action( 'add_attachment' , array( $this, 'new_publish_media_notification' ), 10, 1 );
153 add_action( 'edit_attachment' , array( $this, 'media_attachment_data_update_notification' ), 10 );
154
155 add_action( 'transition_post_status' , array( $this, 'on_post_transition' ), 10, 3 );
156
157 add_action( 'init' , array( $this, 'custom_post_type_hooks' ), 100 );
158 add_action( 'create_term' , array( $this, 'create_term' ), 10, 3 );
159
160 add_action( 'transition_comment_status' , array( $this, 'on_comment_status_change' ), 10, 3 );
161 add_action( 'comment_post' , array( $this, 'comment_post' ) );
162 add_action( 'trackback_post' , array( $this, 'trackback_post' ) );
163 add_action( 'pingback_post' , array( $this, 'pingback_post' ) );
164
165 add_action( 'user_register' , array( $this, 'user_register' ) );
166
167 add_action( 'user_register' , array( $this, 'welcome_email' ) );
168
169 if ( is_plugin_active('members/members.php') ) {
170 add_action( 'profile_update' , array( $this, 'user_role_added' ), 10, 2 );
171 }else{
172 add_action( 'set_user_role' , array( $this, 'user_role_changed' ), 10, 3 );
173 }
174
175 add_action( 'wp_login' , array( $this, 'user_login' ),10,2);
176
177 if ( version_compare( $wp_version, '4.4', '>=' ) ) {
178 add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ), 10, 3 );
179 } else {
180 add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ) );
181 }
182 add_action( 'lostpassword_post' , array( $this, 'on_lost_password' ) );
183 add_filter( 'retrieve_password_message' , array( $this, 'change_password_email_message' ), 10, 4 );
184
185 add_action( 'after_password_reset' , array( $this, 'on_password_reset' ) );
186
187 add_filter( 'send_password_change_email', array( $this, 'should_password_changed_email_be_sent' ), 10, 3 );
188 add_filter( 'password_change_email' , array( $this, 'on_password_changed' ), 10, 2 );
189
190 add_filter( 'send_email_change_email' , array( $this, 'should_email_changed_email_be_sent' ), 10, 3 );
191 add_filter( 'email_change_email' , array( $this, 'on_email_changed' ), 10, 2 );
192 add_filter( 'new_user_email_content' , array( $this, 'on_email_changing' ), 10, 2 );
193
194 add_filter( 'auto_core_update_email' , array( $this, 'on_core_updated' ), 10, 4 );
195
196 add_filter( 'user_request_action_email_content', array( $this, 'handle_user_request_email_content' ), 10, 2 );
197 add_filter( 'user_request_action_email_subject', array( $this, 'handle_user_request_email_subject' ), 10, 3 );
198
199 add_filter( 'user_confirmed_action_email_content', array( $this, 'handle_user_confirmed_action_email_content' ), 10, 2 );
200
201 add_filter( 'wp_privacy_personal_data_email_content', array( $this, 'handle_data_export_email_content' ), 10, 2 );
202
203 add_filter( 'user_erasure_complete_email_subject', array( $this, 'handle_erasure_complete_email_subject' ), 10, 3 );
204 add_filter( 'user_confirmed_action_email_content', array( $this, 'handle_erasure_complete_email_content' ), 10, 2 );
205
206 add_filter( 'plugin_action_links' , array( $this, 'plugin_action_links' ), 10, 4 );
207 add_action( 'shutdown' , array( $this, 'on_shutdown' ) );
208 }
209
210 /**
211 * Add 'bnfw' capability to admin.
212 */
213 public function add_capability_to_admin() {
214 $admins = get_role( 'administrator' );
215
216 if ( is_null( $admins ) ) {
217 return;
218 }
219
220 if ( ! $admins->has_cap( 'bnfw' ) ) {
221 $admins->add_cap( 'bnfw' );
222 }
223 }
224
225 /**
226 * On post transition.
227 *
228 * @param string $new_status New post status.
229 * @param string $old_status Old post status.
230 * @param \WP_Post $post Post object.
231 */
232 public function on_post_transition( $new_status, $old_status, $post ) {
233 if ( ! is_a( $post, 'WP_Post' ) ) {
234 return;
235 }
236
237 if ( 'pending' === $old_status ) {
238 return;
239 }
240
241 if ( 'pending' !== $new_status ) {
242 return;
243 }
244
245 $this->on_post_pending( $post->ID, $post );
246 }
247
248 /**
249 * Setup hooks for custom post types.
250 *
251 * @since 1.2
252 */
253 function custom_post_type_hooks() {
254 $post_types = get_post_types( array( 'public' => true ), 'names' );
255 $post_types = array_diff( $post_types, array( BNFW_Notification::POST_TYPE ) );
256
257 foreach ( $post_types as $post_type ) {
258 add_action( 'future_' . $post_type, array( $this, 'on_post_scheduled' ), 10, 2 );
259 }
260 }
261
262 /**
263 * importer
264 */
265 public function activate() {
266 require_once dirname( __FILE__ ) . '/includes/import.php';
267 $importer = new BNFW_Import;
268 $importer->import();
269 }
270
271 /**
272 * Add 'Settings' link below BNFW in Plugins list.
273 *
274 * @since 1.0
275 * @param unknown $links
276 * @param unknown $file
277 * @return unknown
278 */
279 public function plugin_action_links( $links, $file ) {
280 $plugin_file = 'bnfw/bnfw.php';
281 if ( $file == $plugin_file ) {
282 $settings_link = '<a href="' . esc_url( admin_url( 'edit.php?post_type=bnfw_notification&page=bnfw-settings' ) ) . '">' . esc_html__( 'Settings', 'bnfw' ) . '</a>';
283 array_unshift( $links, $settings_link );
284 }
285 return $links;
286 }
287
288 /**
289 * When a new term is created.
290 *
291 * @since 1.0
292 * @param int $term_id
293 * @param int $tt_id
294 * @param string $taxonomy
295 */
296 public function create_term( $term_id, $tt_id, $taxonomy ) {
297 $this->send_notification( 'newterm-' . $taxonomy, $term_id );
298 }
299
300 /**
301 * Fires when a post is created for the first time.
302 *
303 * @param int $post_id Post ID
304 * @param object $post Post object
305 * @param bool $update Whether this is an existing post being updated or not.
306 *
307 * @since 1.3.1
308 */
309 public function insert_post( $post_id, $post, $update ) {
310 // Some themes like P2, directly insert posts into DB.
311 $insert_post_themes = apply_filters( 'bnfw_insert_post_themes', array( 'P2', 'Syncope' ) );
312 $current_theme = wp_get_theme();
313
314 /**
315 * Whether to trigger insert post hook.
316 *
317 * @since 1.4
318 */
319 $trigger_insert_post = apply_filters( 'bnfw_trigger_insert_post', false, $post_id, $update );
320
321 if ( in_array( $current_theme->get( 'Name' ), $insert_post_themes ) || $trigger_insert_post ) {
322 $this->handle_inserted_post( $post_id, $update );
323 }
324 }
325
326 /**
327 * Trigger New Post published notification for ACF forms.
328 *
329 * @param string $form ACF Form.
330 * @param int $post_id Post ID.
331 */
332 public function acf_submit_form( $form, $post_id ) {
333 $this->handle_inserted_post( $post_id );
334 }
335
336 /**
337 * Trigger correct notifications for inserted posts.
338 *
339 * @param int $post_id Post id.
340 * @param bool $update Whether the post was updated.
341 *
342 * @since 1.6.7
343 */
344 private function handle_inserted_post( $post_id, $update ) {
345 $post = get_post( $post_id );
346
347 if ( ! is_a( $post, 'WP_Post' ) ) {
348 return;
349 }
350
351 switch ( $post->post_status ) {
352 case 'publish':
353 if ( $update ) {
354 $this->update_post( $post );
355 } else {
356 $this->publish_post( $post );
357 }
358 break;
359
360 case 'private':
361 $this->private_post( $post );
362 break;
363
364 case 'pending':
365 $this->on_post_pending( $post_id, $post );
366 break;
367
368 case 'future':
369 $this->on_post_scheduled( $post_id, $post );
370 break;
371 }
372 }
373
374 /**
375 * Fires when a post is created for the first time.
376 *
377 * @since 1.0
378 * @param object $post Post Object
379 */
380 function publish_post( $post ) {
381 $post_id = $post->ID;
382 $post_type = $post->post_type;
383
384 if ( BNFW_Notification::POST_TYPE != $post_type ) {
385 $this->send_notification_async( 'new-' . $post_type, $post_id );
386 }
387 }
388
389 /**
390 * Fires when a private post is created.
391 *
392 * @since 1.6
393 * @param object $post Post Object
394 */
395 public function private_post( $post ) {
396 $post_id = $post->ID;
397 $post_type = $post->post_type;
398
399 if ( BNFW_Notification::POST_TYPE != $post_type ) {
400 $this->send_notification_async( 'private-' . $post_type, $post_id );
401 }
402 }
403
404 /**
405 * Fires when a post is updated.
406 *
407 * @since 1.0
408 * @param unknown $post
409 */
410 public function update_post( $post ) {
411 if ( $this->is_metabox_request() ) {
412 return;
413 }
414
415 $post_id = $post->ID;
416 $post_type = $post->post_type;
417
418 if ( BNFW_Notification::POST_TYPE != $post_type ) {
419 $this->send_notification_async( 'update-' . $post_type, $post_id );
420 }
421 }
422
423
424 /**
425 * Fires when a post is moved publish to trash.
426 *
427 */
428 public function trash_post($post) {
429 if ($this->is_metabox_request()) {
430 return;
431 }
432 $post_id = $post->ID;
433 $post_type = $post->post_type;
434
435 if (BNFW_Notification::POST_TYPE != $post_type) {
436 $this->send_notification_async('trash-' . $post_type, $post_id);
437 }
438 }
439
440 /**
441 * Fires when a post is pending for review.
442 *
443 * @since 1.1
444 * @param int $post_id Post ID
445 * @param object $post Post object
446 */
447 public function on_post_pending( $post_id, $post ) {
448 if ( $this->is_metabox_request() ) {
449 return;
450 }
451
452 $post_type = $post->post_type;
453
454 if ( BNFW_Notification::POST_TYPE != $post_type ) {
455 $this->send_notification_async( 'pending-' . $post_type, $post_id );
456 }
457 }
458
459
460 /**
461 * On Media Published.
462 *
463 * @param int $post_id Attachment post id.
464 */
465
466 public function new_publish_media_notification( $post_id ) {
467 $post_type = get_post_type($post_id);
468
469 if (BNFW_Notification::POST_TYPE != $post_type && $post_type == 'attachment') {
470 $this->send_notification_async( 'new-media', $post_id );
471 }
472 }
473
474 /**
475 * On Media Attachment Data Update.
476 *
477 * @param int $post_id Attachment post id.
478 */
479
480 public function media_attachment_data_update_notification($post_id ) {
481 $post_type = get_post_type($post_id);
482 if (BNFW_Notification::POST_TYPE != $post_type && $post_type == 'attachment') {
483 $this->send_notification_async( 'update-media', $post_id );
484 }
485 }
486
487 /**
488 * Fires when a post is scheduled.
489 *
490 * @since 1.1.5
491 * @param int $post_id Post ID
492 * @param object $post Post object
493 */
494 function on_post_scheduled( $post_id, $post ) {
495 // Rest request also triggers the same hook. We can ignore it.
496 if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
497 return;
498 }
499
500 $post_type = $post->post_type;
501
502 if ( BNFW_Notification::POST_TYPE != $post_type ) {
503 $this->send_notification_async( 'future-' . $post_type, $post_id );
504 }
505 }
506
507 /**
508 * When the status of a comment is changed.
509 *
510 * @param string $new_status New status.
511 * @param string $old_status Old status.
512 * @param \WP_Comment $comment Comment.
513 */
514 public function on_comment_status_change( $new_status, $old_status, $comment ) {
515 if ( 'approved' !== $new_status ) {
516 return;
517 }
518
519 $this->send_notification( 'approve-comment', $comment->comment_ID );
520 }
521
522 /**
523 * Send notification for new comments
524 *
525 * @since 1.0
526 * @param int $comment_id
527 */
528 public function comment_post( $comment_id ) {
529 $the_comment = get_comment( $comment_id );
530 $post = get_post( $the_comment->comment_post_ID );
531
532 if ( '1' !== $the_comment->comment_approved ) {
533 if ( $this->can_send_comment_notification( $the_comment ) ) {
534 $notification_type = 'moderate-' . $post->post_type . '-comment';
535 $this->send_notification( $notification_type, $comment_id );
536 }
537 } else {
538 $notification_type = 'new-comment'; // old notification name
539
540 if ( 'post' != $post->post_type ) {
541 $notification_type = 'comment-' . $post->post_type;
542 }
543
544 if('attachment' == $post->post_type){
545 $notification_type = 'comment-media';
546 }
547
548 $this->send_notification( $notification_type, $comment_id );
549 }
550
551 // comment reply notification.
552 if ( $this->can_send_comment_notification( $the_comment ) ) {
553 if ( $the_comment->comment_parent > 0 ) {
554 $notification_type = 'reply-comment'; // old notification name
555 if ( 'post' != $post->post_type ) {
556 $notification_type = 'commentreply-' . $post->post_type;
557 }
558 $notifications = $this->notifier->get_notifications( $notification_type );
559 if ( count( $notifications ) > 0 ) {
560 $parent = get_comment( $the_comment->comment_parent );
561 if ( $parent->comment_author_email != $the_comment->comment_author_email ) {
562 foreach ( $notifications as $notification ) {
563 $this->engine->send_comment_reply_email( $this->notifier->read_settings( $notification->ID ), $the_comment, $parent );
564 }
565 }
566 }
567 }
568 }
569 }
570
571 /**
572 * Send notification for new trackback
573 *
574 * @since 1.0
575 * @param unknown $comment_id
576 */
577 function trackback_post( $comment_id ) {
578 $the_comment = get_comment( $comment_id );
579 if ( $this->can_send_comment_notification( $the_comment ) ) {
580 $this->send_notification( 'new-trackback', $comment_id );
581 }
582 }
583
584 /**
585 * Send notification for new pingbacks
586 *
587 * @since 1.0
588 * @param unknown $comment_id
589 */
590 function pingback_post( $comment_id ) {
591 $the_comment = get_comment( $comment_id );
592 if ( $this->can_send_comment_notification( $the_comment ) ) {
593 $this->send_notification( 'new-pingback', $comment_id );
594 }
595 }
596
597 /**
598 * Send notification for lost password.
599 *
600 * @since 1.0
601 */
602 function on_lost_password() {
603 $user_login = sanitize_text_field( $_POST['user_login'] );
604 $user = get_user_by( 'login', $user_login );
605 if ( $user ) {
606 $this->send_notification( 'admin-password', $user->ID );
607 }
608 }
609
610 /**
611 * Change the title of the password reset email that is sent to the user.
612 *
613 * @since 1.1
614 *
615 * @param string $title
616 * @param string $user_login
617 * @param string $user_data
618 *
619 * @return string
620 */
621 public function change_password_email_title( $title, $user_login = '', $user_data = '' ) {
622 $notifications = $this->notifier->get_notifications( 'user-password' );
623 if ( count( $notifications ) > 0 ) {
624 // Ideally there should be only one notification for this type.
625 // If there are multiple notification then we will read data about only the last one
626 $setting = $this->notifier->read_settings( end( $notifications )->ID );
627
628 if ( '' === $user_data ) {
629 return $this->engine->handle_shortcodes( $setting['subject'], 'user-password', $user_data->ID );
630 } else {
631 return $setting['subject'];
632 }
633 }
634
635 return $title;
636 }
637
638 /**
639 * Change the message of the password reset email.
640 *
641 * @since 1.1
642 *
643 * @param string $message
644 * @param string $key
645 * @param string $user_login
646 * @param string $user_data
647 *
648 * @return string
649 */
650 public function change_password_email_message( $message, $key, $user_login = '', $user_data = '' ) {
651 $notifications = $this->notifier->get_notifications( 'user-password' );
652 if ( count( $notifications ) > 0 ) {
653 // Ideally there should be only one notification for this type.
654 // If there are multiple notification then we will read data about only the last one
655 $setting = $this->notifier->read_settings( end( $notifications )->ID );
656
657 $message = $this->engine->handle_password_reset_shortcodes( $setting, $key, $user_login, $user_data );
658
659 if ( 'html' == $setting['email-formatting'] ) {
660 add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
661 if ( 'true' !== $setting['disable-autop'] ) {
662 $message = wpautop( $message );
663 }
664 } else {
665 add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
666 }
667 } else {
668 if ( $this->notifier->notification_exists( 'user-password', false ) ) {
669 // disabled notification exists, so disable the email by returning empty string.
670 return '';
671 }
672 }
673
674 return $message;
675 }
676
677 /**
678 * On Password reset.
679 *
680 * @param WP_User $user User who's password was changed.
681 */
682 public function on_password_reset( $user ) {
683 $notifications = $this->notifier->get_notifications( 'password-changed' );
684 foreach ( $notifications as $notification ) {
685 $this->engine->send_password_changed_email( $this->notifier->read_settings( $notification->ID ), $user );
686 }
687 }
688
689 /**
690 * Should the password changed email be sent?
691 *
692 * @param $send
693 * @param $user
694 * @param $userdata
695 *
696 * @return bool
697 */
698 public function should_password_changed_email_be_sent( $send, $user, $userdata ) {
699 $bnfw = BNFW::factory();
700
701 if ( ! $send ) {
702 return $send;
703 }
704
705 return ! $bnfw->notifier->is_notification_disabled( 'password-changed' );
706 }
707
708 /**
709 * On Password Changed.
710 *
711 * @since 1.6
712 *
713 * @param array $email_data Email Data.
714 * @param array $user User data.
715 *
716 * @return array Modified Email Data
717 */
718 public function on_password_changed( $email_data, $user ) {
719 return $this->handle_filtered_data_notification( 'password-changed', $email_data, $user['ID'] );
720 }
721
722 /**
723 * Should the email changed email be sent?
724 *
725 * @param $send
726 * @param $user
727 * @param $userdata
728 *
729 * @return bool
730 */
731 public function should_email_changed_email_be_sent( $send, $user, $userdata ) {
732 $bnfw = BNFW::factory();
733
734 if ( $bnfw->notifier->notification_exists( 'admin-email-changed', false ) ) {
735 $notifications = $bnfw->notifier->get_notifications( 'admin-email-changed' );
736
737 if ( count( $notifications ) > 0 ) {
738 // Ideally there should be only one notification for this type.
739 // If there are multiple notification then we will read data about only the last one
740 $bnfw->engine->send_notification( $bnfw->notifier->read_settings( end( $notifications )->ID ), $user['ID'] );
741 }
742 }
743
744 if ( ! $send ) {
745 return $send;
746 }
747
748 return ! $bnfw->notifier->is_notification_disabled( 'email-changed' );
749 }
750
751 /**
752 * On Email Changed.
753 *
754 * @since 1.6
755 *
756 * @param array $email_data Email Data.
757 * @param array $user User data.
758 *
759 * @return array Modified Email Data
760 */
761 public function on_email_changed( $email_data, $user ) {
762 return $this->handle_filtered_data_notification( 'email-changed', $email_data, $user['ID'] );
763 }
764
765 public function on_email_changing( $email_text, $new_user_details ) {
766 $notification_name = 'email-changing';
767
768 $notifications = $this->notifier->get_notifications( $notification_name );
769 if ( count( $notifications ) > 0 ) {
770 // Ideally there should be only one notification for this type.
771 // If there are multiple notification then we will read data about only the last one
772 $setting = $this->notifier->read_settings( end( $notifications )->ID );
773
774 $email_text = $this->engine->handle_shortcodes( $setting['message'], $setting['notification'], $new_user_details['newemail'] );
775 $email_text = $this->engine->handle_global_user_shortcodes( $email_text, $new_user_details['newemail'] );
776 $email_text = str_replace( '[email_change_confirmation_link]', esc_url( admin_url( 'profile.php?newuseremail=' . $new_user_details['hash'] ) ), $email_text );
777
778 }
779
780 return $email_text;
781 }
782
783 /**
784 * Send notification on core updated event.
785 *
786 * @since 1.6
787 *
788 * @param array $email_data Email Data.
789 * @param string $type The type of email being sent. Can be one of
790 * 'success', 'fail', 'manual', 'critical'.
791 * @param object $core_update The update offer that was attempted.
792 * @param mixed $result The result for the core update. Can be WP_Error.
793 *
794 * @return array Modified Email Data.
795 */
796 public function on_core_updated( $email_data, $type, $core_update, $result ) {
797 $notifications = $this->notifier->get_notifications( 'core-updated' );
798 if ( count( $notifications ) > 0 ) {
799 // Ideally there should be only one notification for this type.
800 // If there are multiple notification then we will read data about only the last one
801 $setting = $this->notifier->read_settings( end( $notifications )->ID );
802
803 $email_data = $this->engine->handle_core_updated_notification( $email_data, $setting, $type );
804 }
805
806 return $email_data;
807 }
808
809 /**
810 * Process User update notifications.
811 *
812 * @since 1.6
813 *
814 * @param string $notification_name Notification Name.
815 * @param array $email_data Email Data.
816 * @param string|int $extra_data User Id.
817 *
818 * @return array Modified Email Data.
819 */
820 private function handle_filtered_data_notification( $notification_name, $email_data, $extra_data ) {
821 $notifications = $this->notifier->get_notifications( $notification_name );
822 if ( count( $notifications ) > 0 ) {
823 // Ideally there should be only one notification for this type.
824 // If there are multiple notification then we will read data about only the last one
825 $setting = $this->notifier->read_settings( end( $notifications )->ID );
826
827 $email_data = $this->engine->handle_filtered_data_notification( $email_data, $setting, $extra_data );
828 }
829
830 return $email_data;
831 }
832
833 /**
834 * Set the email formatting to HTML.
835 *
836 * @since 1.4
837 */
838 public function set_html_content_type() {
839 return 'text/html';
840 }
841
842 /**
843 * Set the email formatting to text.
844 *
845 * @since 1.4
846 */
847 public function set_text_content_type() {
848 return 'text/plain';
849 }
850
851 /**
852 * Send notification for new users.
853 *
854 * @since 1.0
855 * @param int $user_id
856 */
857 public function user_register( $user_id ) {
858 $this->send_notification( 'admin-user', $user_id );
859 }
860
861 /**
862 * Send notification for user when user login.
863 *
864 * @since 1.0
865 * @param string $user_name
866 * @param object $user_data User object.
867 */
868 public function user_login( $user_name, $user_data ) {
869 $user_id = $user_data->ID;
870 $notifications = $this->notifier->get_notifications( 'user-login' );
871
872 foreach ( $notifications as $notification ) {
873 $this->engine->send_user_login_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
874 }
875
876 $this->user_login_admin_notification($user_id);
877 }
878
879 /**
880 * Send notification for admin when user login.
881 *
882 * @since 1.0
883 * @param int $user_id
884 */
885 public function user_login_admin_notification( $user_id ) {
886 $notifications = $this->notifier->get_notifications( 'admin-user-login' );
887
888 foreach ( $notifications as $notification ) {
889 $this->engine->send_user_login_email_for_admin( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
890 }
891 }
892
893 /**
894 * Send notification about new users to site admin.
895 *
896 * @since 1.7.1
897 *
898 * @param array $email_data Email details.
899 * @param WP_User $user User object.
900 * @param string $blogname Blog name.
901 *
902 * @return array Modified email details.
903 */
904 public function handle_user_registered_admin_email( $email_data, $user, $blogname ) {
905 return $this->handle_filtered_data_notification( 'admin-user', $email_data, $user->ID );
906 }
907
908 /**
909 * New User - Post-registration Email
910 *
911 * @since 1.1
912 * @param int $user_id New user id
913 */
914 public function welcome_email( $user_id ) {
915 $notifications = $this->notifier->get_notifications( 'welcome-email' );
916 foreach ( $notifications as $notification ) {
917 $this->engine->send_registration_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
918 }
919 }
920
921 /**
922 * Send notification when a user role changes.
923 *
924 * @since 1.3.9
925 *
926 * @param int $user_id User ID
927 * @param string $new_role New User role
928 * @param array $old_roles Old User role
929 */
930 public function user_role_changed( $user_id, $new_role, $old_roles ) {
931 if ( ! empty( $old_roles ) ) {
932 $notifications = $this->notifier->get_notifications( 'user-role' );
933 foreach ( $notifications as $notification ) {
934
935 /**
936 * Trigger User Role Changed - For User notification.
937 *
938 * @since 1.6.5
939 */
940 if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, $new_role, $old_roles ) ) {
941 $this->engine->send_user_role_changed_email(
942 $this->notifier->read_settings( $notification->ID ),
943 $user_id,
944 $old_roles[0],
945 $new_role
946 );
947 }
948 }
949
950 $notifications = $this->notifier->get_notifications( 'admin-role' );
951 foreach ( $notifications as $notification ) {
952
953 /**
954 * Trigger User Role Changed - For User notification.
955 *
956 * @since 1.6.5
957 */
958 if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, $new_role, $old_roles ) ) {
959 $setting = $this->notifier->read_settings( $notification->ID );
960 $setting['message'] = $this->engine->handle_user_role_shortcodes( $setting['message'], $old_roles[0], $new_role );
961 $setting['subject'] = $this->engine->handle_user_role_shortcodes( $setting['subject'], $old_roles[0], $new_role );
962
963 $this->engine->send_notification( $setting, $user_id );
964 }
965 }
966 }
967 }
968
969 /**
970 * Send notification when a user role added support User Role Editor by Members Plugin.
971 *
972 * @since 1.3.9
973 *
974 * @param int $user_id User ID
975 * @param string $new_role New User role
976 * @param array $old_roles Old User role
977 */
978 public function user_role_added( $user_id, $old_user_data ) {
979
980 if(isset($_POST['members_user_roles']) && !empty($_POST['members_user_roles'])){
981 // Get the current user roles.
982 $old_roles = (array) $old_user_data->roles;
983
984 // Sanitize the posted roles.
985 $new_roles = array_map( 'members_sanitize_role', $_POST['members_user_roles'] );
986
987 sort($old_roles);
988 sort($new_roles);
989 $old_roles_str = implode('', $old_roles);
990 $new_roles_str = implode('', $new_roles);
991 if ( ! empty( $old_roles ) && $old_roles_str !== $new_roles_str) {
992 $notifications = $this->notifier->get_notifications( 'user-role' );
993 foreach ( $notifications as $notification ) {
994
995 /**
996 * Trigger User Role Changed - For User notification.
997 *
998 * @since 1.6.5
999 */
1000 if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
1001 $this->engine->send_user_role_added_email(
1002 $this->notifier->read_settings( $notification->ID ),
1003 $user_id,
1004 $old_roles,
1005 $new_roles
1006 );
1007 }
1008 }
1009
1010 $notifications = $this->notifier->get_notifications( 'admin-role' );
1011 foreach ( $notifications as $notification ) {
1012
1013 /**
1014 * Trigger User Role Changed - For User notification.
1015 *
1016 * @since 1.6.5
1017 */
1018 if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
1019 $setting = $this->notifier->read_settings( $notification->ID );
1020 $setting['message'] = $this->engine->handle_user_added_role_shortcodes( $setting['message'], $old_roles, $new_roles );
1021 $setting['subject'] = $this->engine->handle_user_added_role_shortcodes( $setting['subject'], $old_roles, $new_roles );
1022
1023 $this->engine->send_notification( $setting, $user_id );
1024 }
1025 }
1026 }
1027 }
1028 }
1029
1030 /**
1031 * Sanitizes a role name. This is a wrapper for the `sanitize_key()` WordPress function. Only
1032 * alphanumeric characters and underscores are allowed. Hyphens are also replaced with underscores.
1033 *
1034 * @since 1.0.0
1035 * @access public
1036 * @return int
1037 */
1038 function members_sanitize_role( $role ) {
1039
1040 $_role = strtolower( $role );
1041 $_role = preg_replace( '/[^a-z0-9_\-\s]/', '', $_role );
1042
1043 return apply_filters( 'members_sanitize_role', str_replace( ' ', '_', $_role ), $role );
1044 }
1045
1046 /**
1047 * Send notification based on type and ref id
1048 *
1049 * @since 1.0
1050 * @param string $type Notification type.
1051 * @param mixed $ref_id Reference data.
1052 */
1053 public function send_notification( $type, $ref_id ) {
1054 $notifications = $this->notifier->get_notifications( $type );
1055 foreach ( $notifications as $notification ) {
1056 $this->engine->send_notification( $this->notifier->read_settings( $notification->ID ), $ref_id );
1057 }
1058 }
1059
1060 /**
1061 * Send notification async based on type and ref id.
1062 *
1063 * @param string $type Notification type.
1064 * @param mixed $ref_id Reference data.
1065 */
1066 public function send_notification_async( $type, $ref_id ) {
1067 $notifications = $this->notifier->get_notifications( $type, false );
1068 foreach ( $notifications as $notification ) {
1069 $transient = get_transient( 'bnfw-async-notifications' );
1070 if ( ! is_array( $transient ) ) {
1071 $transient = array();
1072 }
1073
1074 $notification_data = array(
1075 'ref_id' => $ref_id,
1076 'notification_id' => $notification->ID,
1077 'notification_type' => $type,
1078 );
1079
1080 if ( ! in_array( $notification_data, $transient ) ) {
1081 $transient[] = $notification_data;
1082 set_transient( 'bnfw-async-notifications', $transient, 600 );
1083 }
1084 }
1085 }
1086
1087 /**
1088 * Can send comment notification or not
1089 *
1090 * @since 1.0
1091 * @param unknown $comment
1092 * @return unknown
1093 */
1094 private function can_send_comment_notification( $comment ) {
1095 // Returns false if the comment is marked as spam AND admin has enabled suppression of spam
1096 $suppress_spam = get_option( 'bnfw_suppress_spam' );
1097 if ( '1' === $suppress_spam && ( 0 === strcmp( $comment->comment_approved, 'spam' ) ) ) {
1098 return false;
1099 }
1100 return true;
1101 }
1102
1103 /**
1104 * Handle user request email content.
1105 *
1106 * @param string $content Content.
1107 * @param array $email_data Email data.
1108 *
1109 * @return string Modified content.
1110 */
1111 public function handle_user_request_email_content( $content, $email_data ) {
1112 $field = 'message';
1113
1114 switch ( $email_data['description'] ) {
1115 case 'Export Personal Data':
1116 $notification_name = 'ca-export-data';
1117 $content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1118 break;
1119 case 'Erase Personal Data':
1120 $notification_name = 'ca-erase-data';
1121 $content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1122 break;
1123 }
1124
1125 return $content;
1126 }
1127
1128 /**
1129 * Handle user request email subject.
1130 *
1131 * @param string $subject Subject
1132 * @param string $blogname Blog name
1133 * @param array $email_data Email data.
1134 *
1135 * @return string Modified subject.
1136 */
1137 public function handle_user_request_email_subject( $subject, $blogname, $email_data ) {
1138 $field = 'subject';
1139
1140 switch ( $email_data['description'] ) {
1141 case 'Export Personal Data':
1142 $notification_name = 'ca-export-data';
1143 $subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1144 break;
1145 case 'Erase Personal Data':
1146 $notification_name = 'ca-erase-data';
1147 $content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1148 break;
1149 }
1150
1151 return $subject;
1152 }
1153
1154 /**
1155 * Handle user confirmed action email content.
1156 *
1157 * @param string $content Content.
1158 * @param array $email_data Email data.
1159 *
1160 * @return string Modified content.
1161 */
1162 public function handle_user_confirmed_action_email_content( $content, $email_data ) {
1163 $field = 'message';
1164
1165 switch ( $email_data['description'] ) {
1166 case 'Export Personal Data':
1167 $notification_name = 'uc-export-data';
1168 $content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
1169 break;
1170 case 'Erase Personal Data':
1171 $notification_name = 'uc-erase-data';
1172 $content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
1173 break;
1174 }
1175
1176 return $content;
1177 }
1178
1179 /**
1180 * Handle data exported email content.
1181 *
1182 * @param string $content Content.
1183 * @param int $request_id
1184 *
1185 * @return string Modified content.
1186 */
1187 public function handle_data_export_email_content( $content, $request_id ) {
1188 $field = 'message';
1189 $notification_name = 'data-export';
1190
1191 $notifications = $this->notifier->get_notifications( $notification_name );
1192 if ( count( $notifications ) > 0 ) {
1193 // Ideally there should be only one notification for this type.
1194 // If there are multiple notification then we will read data about only the last one
1195 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1196
1197 return $this->engine->handle_data_export_email_shortcodes( $setting[ $field ], $setting, $request_id );
1198 }
1199
1200 return $content;
1201 }
1202
1203 public function handle_erasure_complete_email_subject( $subject, $sitename, $email_data ) {
1204 return $this->handle_erasure_complete_email_notification( 'subject', $subject, $email_data );
1205 }
1206
1207 public function handle_erasure_complete_email_content( $content, $email_data ) {
1208 if ( isset( $email_data['privacy_policy_url'] ) ) {
1209 return $this->handle_erasure_complete_email_notification( 'message', $content, $email_data );
1210 }
1211
1212 return $content;
1213 }
1214
1215 protected function handle_erasure_complete_email_notification( $field, $content, $email_data ) {
1216 $notification_name = 'data-erased';
1217
1218 $notifications = $this->notifier->get_notifications( $notification_name );
1219 if ( count( $notifications ) > 0 ) {
1220 // Ideally there should be only one notification for this type.
1221 // If there are multiple notification then we will read data about only the last one
1222 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1223
1224 return $this->engine->handle_shortcodes( $setting[ $field ], $notification_name, $email_data );
1225 }
1226
1227 return $content;
1228 }
1229
1230 /**
1231 * Send notification emails on shutdown.
1232 */
1233 public function on_shutdown() {
1234 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1235 return;
1236 }
1237
1238 $transient = get_transient( 'bnfw-async-notifications' );
1239 if ( is_array( $transient ) ) {
1240 delete_transient( 'bnfw-async-notifications' );
1241 foreach ( $transient as $id_pairs ) {
1242 $this->engine->send_notification( $this->notifier->read_settings( $id_pairs['notification_id'] ), $id_pairs['ref_id'] );
1243 }
1244 }
1245 }
1246
1247 /**
1248 * Handle user request notification.
1249 *
1250 * @param string $notification_name Notification name.
1251 * @param string $field Field name.
1252 * @param array $email_data Email data.
1253 *
1254 * @return string Content.
1255 */
1256 protected function handle_user_request_notification( $notification_name, $field, $email_data ) {
1257 $notifications = $this->notifier->get_notifications( $notification_name );
1258 if ( count( $notifications ) > 0 ) {
1259 // Ideally there should be only one notification for this type.
1260 // If there are multiple notification then we will read data about only the last one
1261 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1262
1263 return $this->engine->handle_user_request_email_shortcodes( $setting[ $field ], $setting, $email_data );
1264 }
1265
1266 return '';
1267 }
1268
1269 /**
1270 * Handle user confirmed action notification.
1271 *
1272 * @param string $notification_name Notification name.
1273 * @param string $field Field name.
1274 * @param array $email_data Email data.
1275 *
1276 * @return string Content.
1277 */
1278 protected function handle_user_confirmed_action_notification( $notification_name, $field, $email_data ) {
1279 $notifications = $this->notifier->get_notifications( $notification_name );
1280 if ( count( $notifications ) > 0 ) {
1281 // Ideally there should be only one notification for this type.
1282 // If there are multiple notification then we will read data about only the last one
1283 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1284
1285 return $this->engine->handle_user_confirmed_action_email_shortcodes( $setting[ $field ], $setting, $email_data );
1286 }
1287
1288 return '';
1289 }
1290
1291 /**
1292 * Is this a metabox request?
1293 *
1294 * Block editor sends duplicate requests on post update.
1295 *
1296 * @return bool True if metabox request, False otherwise.
1297 */
1298 protected function is_metabox_request() {
1299 return ( isset( $_GET['meta-box-loader'] ) || isset( $_GET['meta_box'] ) );
1300 }
1301 }
1302
1303 /* ------------------------------------------------------------------------ *
1304 * Fire up the plugin
1305 * ------------------------------------------------------------------------ */
1306 BNFW::factory();
1307