PluginProbe
Customize WordPress Emails and Alerts – Better Notifications for WP / 1.8.3
Customize WordPress Emails and Alerts – Better Notifications for WP v1.8.3
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.8.3, at bnfw.php

1,354 lines 41.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.8.3
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 $post = get_post( $comment->comment_post_ID );
520
521 $notification_type = 'approve-'.$post->post_type.'-comment';
522
523 $this->send_notification( $notification_type, $comment->comment_ID );
524
525 // Send new comment notification after comment approve
526 $notification_type = 'new-comment'; // old notification name
527
528 if ( 'post' != $post->post_type ) {
529 $notification_type = 'comment-' . $post->post_type;
530 }
531
532 $this->send_notification( $notification_type, $comment->comment_ID );
533
534 // Send comment reply notification after comment approve.
535 $this->commentsReply($comment->comment_ID);
536 }
537
538 /**
539 * Send notification for new comments
540 *
541 * @since 1.0
542 * @param int $comment_id
543 */
544 public function comment_post( $comment_id ) {
545 $the_comment = get_comment( $comment_id );
546 $post = get_post( $the_comment->comment_post_ID );
547
548 if ( '1' !== $the_comment->comment_approved ) {
549 if ( $this->can_send_comment_notification( $the_comment ) ) {
550 $notification_type = 'moderate-' . $post->post_type . '-comment';
551 $this->send_notification( $notification_type, $comment_id );
552 }
553 } else {
554 $notification_type = 'new-comment'; // old notification name
555
556 if ( 'post' != $post->post_type ) {
557 $notification_type = 'comment-' . $post->post_type;
558 }
559
560 $this->send_notification( $notification_type, $comment_id );
561
562 // comment reply notification.
563 $this->commentsReply($comment_id);
564 }
565 }
566
567 /**
568 * Send notification for comments reply
569 *
570 * @since 1.0
571 * @param int $comment_id
572 */
573 public function commentsReply($comment_id) {
574 $the_comment = get_comment( $comment_id );
575 $post = get_post( $the_comment->comment_post_ID );
576
577 // comment reply notification.
578 if ( $this->can_send_comment_notification( $the_comment ) ) {
579 if ( $the_comment->comment_parent > 0 ) {
580 $notification_type = 'reply-comment'; // old notification name
581 if ( 'post' != $post->post_type ) {
582 $notification_type = 'commentreply-' . $post->post_type;
583 }
584 $notifications = $this->notifier->get_notifications( $notification_type );
585 if ( count( $notifications ) > 0 ) {
586 $parent = get_comment( $the_comment->comment_parent );
587 if ( $parent->comment_author_email != $the_comment->comment_author_email ) {
588 foreach ( $notifications as $notification ) {
589 $this->engine->send_comment_reply_email( $this->notifier->read_settings( $notification->ID ), $the_comment, $parent );
590 }
591 }
592 }
593 }
594 }
595 }
596
597 /**
598 * Send notification for new trackback
599 *
600 * @since 1.0
601 * @param unknown $comment_id
602 */
603 function trackback_post( $comment_id ) {
604 $the_comment = get_comment( $comment_id );
605 if ( $this->can_send_comment_notification( $the_comment ) ) {
606 $this->send_notification( 'new-trackback', $comment_id );
607 }
608 }
609
610 /**
611 * Send notification for new pingbacks
612 *
613 * @since 1.0
614 * @param unknown $comment_id
615 */
616 function pingback_post( $comment_id ) {
617 $the_comment = get_comment( $comment_id );
618 if ( $this->can_send_comment_notification( $the_comment ) ) {
619 $this->send_notification( 'new-pingback', $comment_id );
620 }
621 }
622
623 /**
624 * Send notification for lost password.
625 *
626 * @since 1.0
627 */
628 function on_lost_password() {
629 $user_login = sanitize_text_field( $_POST['user_login'] );
630 $user = get_user_by( 'login', $user_login );
631 if ( $user ) {
632 $this->send_notification( 'admin-password', $user->ID );
633 }
634 }
635
636 /**
637 * Change the title of the password reset email that is sent to the user.
638 *
639 * @since 1.1
640 *
641 * @param string $title
642 * @param string $user_login
643 * @param string $user_data
644 *
645 * @return string
646 */
647 public function change_password_email_title( $title, $user_login = '', $user_data = '' ) {
648 $notifications = $this->notifier->get_notifications( 'user-password' );
649 if ( count( $notifications ) > 0 ) {
650 // Ideally there should be only one notification for this type.
651 // If there are multiple notification then we will read data about only the last one
652 $setting = $this->notifier->read_settings( end( $notifications )->ID );
653
654 if ( '' === $user_data ) {
655 return $this->engine->handle_shortcodes( $setting['subject'], 'user-password', $user_data->ID );
656 } else {
657 return $this->engine->handle_shortcodes( $setting['subject'], 'user-password', $user_data->ID );
658 }
659 }
660
661 return $title;
662 }
663
664 /**
665 * Change the message of the password reset email.
666 *
667 * @since 1.1
668 *
669 * @param string $message
670 * @param string $key
671 * @param string $user_login
672 * @param string $user_data
673 *
674 * @return string
675 */
676 public function change_password_email_message( $message, $key, $user_login = '', $user_data = '' ) {
677 $notifications = $this->notifier->get_notifications( 'user-password' );
678 if ( count( $notifications ) > 0 ) {
679 // Ideally there should be only one notification for this type.
680 // If there are multiple notification then we will read data about only the last one
681 $setting = $this->notifier->read_settings( end( $notifications )->ID );
682
683 $message = $this->engine->handle_password_reset_shortcodes( $setting, $key, $user_login, $user_data );
684
685 if ( 'html' == $setting['email-formatting'] ) {
686 add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
687 if ( 'true' !== $setting['disable-autop'] ) {
688 $message = wpautop( $message );
689 }
690 } else {
691 add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
692 }
693 } else {
694 if ( $this->notifier->notification_exists( 'user-password', false ) ) {
695 // disabled notification exists, so disable the email by returning empty string.
696 return '';
697 }
698 }
699
700 return $message;
701 }
702
703 /**
704 * On Password reset.
705 *
706 * @param WP_User $user User who's password was changed.
707 */
708 public function on_password_reset( $user ) {
709 $notifications = $this->notifier->get_notifications( 'password-changed' );
710 foreach ( $notifications as $notification ) {
711 $this->engine->send_password_changed_email( $this->notifier->read_settings( $notification->ID ), $user );
712 }
713 }
714
715 /**
716 * Should the password changed email be sent?
717 *
718 * @param $send
719 * @param $user
720 * @param $userdata
721 *
722 * @return bool
723 */
724 public function should_password_changed_email_be_sent( $send, $user, $userdata ) {
725 $bnfw = BNFW::factory();
726
727 if ( ! $send ) {
728 return $send;
729 }
730
731 return ! $bnfw->notifier->is_notification_disabled( 'password-changed' );
732 }
733
734 /**
735 * On Password Changed.
736 *
737 * @since 1.6
738 *
739 * @param array $email_data Email Data.
740 * @param array $user User data.
741 *
742 * @return array Modified Email Data
743 */
744 public function on_password_changed( $email_data, $user ) {
745 return $this->handle_filtered_data_notification( 'password-changed', $email_data, $user['ID'] );
746 }
747
748 /**
749 * Should the email changed email be sent?
750 *
751 * @param $send
752 * @param $user
753 * @param $userdata
754 *
755 * @return bool
756 */
757 public function should_email_changed_email_be_sent( $send, $user, $userdata ) {
758 $bnfw = BNFW::factory();
759
760 if ( $bnfw->notifier->notification_exists( 'admin-email-changed', false ) ) {
761 $notifications = $bnfw->notifier->get_notifications( 'admin-email-changed' );
762
763 if ( count( $notifications ) > 0 ) {
764 // Ideally there should be only one notification for this type.
765 // If there are multiple notification then we will read data about only the last one
766 $bnfw->engine->send_notification( $bnfw->notifier->read_settings( end( $notifications )->ID ), $user['ID'] );
767 }
768 }
769
770 if ( ! $send ) {
771 return $send;
772 }
773
774 return ! $bnfw->notifier->is_notification_disabled( 'email-changed' );
775 }
776
777 /**
778 * On Email Changed.
779 *
780 * @since 1.6
781 *
782 * @param array $email_data Email Data.
783 * @param array $user User data.
784 *
785 * @return array Modified Email Data
786 */
787 public function on_email_changed( $email_data, $user ) {
788 return $this->handle_filtered_data_notification( 'email-changed', $email_data, $user['ID'] );
789 }
790
791 public function on_email_changing( $email_text, $new_user_details ) {
792 $notification_name = 'email-changing';
793
794 $notifications = $this->notifier->get_notifications( $notification_name );
795 if ( count( $notifications ) > 0 ) {
796 // Ideally there should be only one notification for this type.
797 // If there are multiple notification then we will read data about only the last one
798 $setting = $this->notifier->read_settings( end( $notifications )->ID );
799
800 $email_text = $this->engine->handle_shortcodes( $setting['message'], $setting['notification'], $new_user_details['newemail'] );
801 $email_text = $this->engine->handle_global_user_shortcodes( $email_text, $new_user_details['newemail'] );
802 $email_text = str_replace( '[email_change_confirmation_link]', esc_url( admin_url( 'profile.php?newuseremail=' . $new_user_details['hash'] ) ), $email_text );
803
804 }
805
806 return $email_text;
807 }
808
809 /**
810 * Send notification on core updated event.
811 *
812 * @since 1.6
813 *
814 * @param array $email_data Email Data.
815 * @param string $type The type of email being sent. Can be one of
816 * 'success', 'fail', 'manual', 'critical'.
817 * @param object $core_update The update offer that was attempted.
818 * @param mixed $result The result for the core update. Can be WP_Error.
819 *
820 * @return array Modified Email Data.
821 */
822 public function on_core_updated( $email_data, $type, $core_update, $result ) {
823 $notifications = $this->notifier->get_notifications( 'core-updated' );
824 if ( count( $notifications ) > 0 ) {
825 // Ideally there should be only one notification for this type.
826 // If there are multiple notification then we will read data about only the last one
827 $setting = $this->notifier->read_settings( end( $notifications )->ID );
828
829 $email_data = $this->engine->handle_core_updated_notification( $email_data, $setting, $type );
830 }
831
832 return $email_data;
833 }
834
835 /**
836 * Process User update notifications.
837 *
838 * @since 1.6
839 *
840 * @param string $notification_name Notification Name.
841 * @param array $email_data Email Data.
842 * @param string|int $extra_data User Id.
843 *
844 * @return array Modified Email Data.
845 */
846 private function handle_filtered_data_notification( $notification_name, $email_data, $extra_data ) {
847 $notifications = $this->notifier->get_notifications( $notification_name );
848 if ( count( $notifications ) > 0 ) {
849 // Ideally there should be only one notification for this type.
850 // If there are multiple notification then we will read data about only the last one
851 $setting = $this->notifier->read_settings( end( $notifications )->ID );
852
853 $email_data = $this->engine->handle_filtered_data_notification( $email_data, $setting, $extra_data );
854 }
855
856 return $email_data;
857 }
858
859 /**
860 * Set the email formatting to HTML.
861 *
862 * @since 1.4
863 */
864 public function set_html_content_type() {
865 return 'text/html';
866 }
867
868 /**
869 * Set the email formatting to text.
870 *
871 * @since 1.4
872 */
873 public function set_text_content_type() {
874 return 'text/plain';
875 }
876
877 /**
878 * Send notification for new users.
879 *
880 * @since 1.0
881 * @param int $user_id
882 */
883 public function user_register( $user_id ) {
884 $this->send_notification( 'admin-user', $user_id );
885 }
886
887 /**
888 * Send notification for user when user login.
889 *
890 * @since 1.0
891 * @param string $user_name
892 * @param object $user_data User object.
893 */
894 public function user_login( $user_name, $user_data ) {
895 $user_id = $user_data->ID;
896 $notifications = $this->notifier->get_notifications( 'user-login' );
897
898 foreach ( $notifications as $notification ) {
899 $this->engine->send_user_login_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
900 }
901
902 $this->user_login_admin_notification($user_id);
903 }
904
905 /**
906 * Send notification for admin when user login.
907 *
908 * @since 1.0
909 * @param int $user_id
910 */
911 public function user_login_admin_notification( $user_id ) {
912 $notifications = $this->notifier->get_notifications( 'admin-user-login' );
913
914 foreach ( $notifications as $notification ) {
915 $this->engine->send_user_login_email_for_admin( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
916 }
917 }
918
919 /**
920 * Send notification about new users to site admin.
921 *
922 * @since 1.7.1
923 *
924 * @param array $email_data Email details.
925 * @param WP_User $user User object.
926 * @param string $blogname Blog name.
927 *
928 * @return array Modified email details.
929 */
930 public function handle_user_registered_admin_email( $email_data, $user, $blogname ) {
931 return $this->handle_filtered_data_notification( 'admin-user', $email_data, $user->ID );
932 }
933
934 /**
935 * New User - Post-registration Email
936 *
937 * @since 1.1
938 * @param int $user_id New user id
939 */
940 public function welcome_email( $user_id ) {
941 $notifications = $this->notifier->get_notifications( 'welcome-email' );
942 foreach ( $notifications as $notification ) {
943 $this->engine->send_registration_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
944 }
945 }
946
947 /**
948 * Send notification when a user role changes.
949 *
950 * @since 1.3.9
951 *
952 * @param int $user_id User ID
953 * @param string $new_role New User role
954 * @param array $old_roles Old User role
955 */
956 public function user_role_changed( $user_id, $new_role, $old_roles ) {
957 if ( ! empty( $old_roles ) ) {
958 $notifications = $this->notifier->get_notifications( 'user-role' );
959 foreach ( $notifications as $notification ) {
960
961 /**
962 * Trigger User Role Changed - For User notification.
963 *
964 * @since 1.6.5
965 */
966 if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, $new_role, $old_roles ) ) {
967 $this->engine->send_user_role_changed_email(
968 $this->notifier->read_settings( $notification->ID ),
969 $user_id,
970 $old_roles[0],
971 $new_role
972 );
973 }
974 }
975
976 $notifications = $this->notifier->get_notifications( 'admin-role' );
977 foreach ( $notifications as $notification ) {
978
979 /**
980 * Trigger User Role Changed - For User notification.
981 *
982 * @since 1.6.5
983 */
984 if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, $new_role, $old_roles ) ) {
985 $setting = $this->notifier->read_settings( $notification->ID );
986 $setting['message'] = $this->engine->handle_user_role_shortcodes( $setting['message'], $old_roles[0], $new_role );
987 $setting['subject'] = $this->engine->handle_user_role_shortcodes( $setting['subject'], $old_roles[0], $new_role );
988
989 $this->engine->send_notification( $setting, $user_id );
990 }
991 }
992 }
993 }
994
995 /**
996 * Send notification when a user role added support User Role Editor by Members Plugin.
997 *
998 * @since 1.3.9
999 *
1000 * @param int $user_id User ID
1001 * @param string $new_role New User role
1002 * @param array $old_roles Old User role
1003 */
1004 public function user_role_added( $user_id, $old_user_data ) {
1005
1006 if(isset($_POST['members_user_roles']) && !empty($_POST['members_user_roles'])){
1007 // Get the current user roles.
1008 $old_roles = (array) $old_user_data->roles;
1009
1010 // Sanitize the posted roles.
1011 $new_roles = array_map( 'members_sanitize_role', $_POST['members_user_roles'] );
1012
1013 sort($old_roles);
1014 sort($new_roles);
1015 $old_roles_str = implode('', $old_roles);
1016 $new_roles_str = implode('', $new_roles);
1017 if ( ! empty( $old_roles ) && $old_roles_str !== $new_roles_str) {
1018 $notifications = $this->notifier->get_notifications( 'user-role' );
1019 foreach ( $notifications as $notification ) {
1020
1021 /**
1022 * Trigger User Role Changed - For User notification.
1023 *
1024 * @since 1.6.5
1025 */
1026 if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
1027 $this->engine->send_user_role_added_email(
1028 $this->notifier->read_settings( $notification->ID ),
1029 $user_id,
1030 $old_roles,
1031 $new_roles
1032 );
1033 }
1034 }
1035
1036 $notifications = $this->notifier->get_notifications( 'admin-role' );
1037 foreach ( $notifications as $notification ) {
1038
1039 /**
1040 * Trigger User Role Changed - For User notification.
1041 *
1042 * @since 1.6.5
1043 */
1044 if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
1045 $setting = $this->notifier->read_settings( $notification->ID );
1046 $setting['message'] = $this->engine->handle_user_added_role_shortcodes( $setting['message'], $old_roles, $new_roles );
1047 $setting['subject'] = $this->engine->handle_user_added_role_shortcodes( $setting['subject'], $old_roles, $new_roles );
1048
1049 $this->engine->send_notification( $setting, $user_id );
1050 }
1051 }
1052 }
1053 }
1054 }
1055
1056 /**
1057 * Sanitizes a role name. This is a wrapper for the `sanitize_key()` WordPress function. Only
1058 * alphanumeric characters and underscores are allowed. Hyphens are also replaced with underscores.
1059 *
1060 * @since 1.0.0
1061 * @access public
1062 * @return int
1063 */
1064 function members_sanitize_role( $role ) {
1065
1066 $_role = strtolower( $role );
1067 $_role = preg_replace( '/[^a-z0-9_\-\s]/', '', $_role );
1068
1069 return apply_filters( 'members_sanitize_role', str_replace( ' ', '_', $_role ), $role );
1070 }
1071
1072 /**
1073 * Send notification based on type and ref id
1074 *
1075 * @since 1.0
1076 * @param string $type Notification type.
1077 * @param mixed $ref_id Reference data.
1078 */
1079 public function send_notification( $type, $ref_id ) {
1080 $notifications = $this->notifier->get_notifications( $type );
1081 foreach ( $notifications as $notification ) {
1082 $this->engine->send_notification( $this->notifier->read_settings( $notification->ID ), $ref_id );
1083 }
1084 }
1085
1086 /**
1087 * Send notification async based on type and ref id.
1088 *
1089 * @param string $type Notification type.
1090 * @param mixed $ref_id Reference data.
1091 */
1092 public function send_notification_async( $type, $ref_id ) {
1093 $notifications = $this->notifier->get_notifications( $type, false );
1094 foreach ( $notifications as $notification ) {
1095 $transient = get_transient( 'bnfw-async-notifications' );
1096 if ( ! is_array( $transient ) ) {
1097 $transient = array();
1098 }
1099
1100 $notification_data = array(
1101 'ref_id' => $ref_id,
1102 'notification_id' => $notification->ID,
1103 'notification_type' => $type,
1104 );
1105
1106 if ( ! in_array( $notification_data, $transient ) ) {
1107 $transient[] = $notification_data;
1108 set_transient( 'bnfw-async-notifications', $transient, 600 );
1109 }
1110 }
1111 }
1112
1113 /**
1114 * Can send comment notification or not
1115 *
1116 * @since 1.0
1117 * @param unknown $comment
1118 * @return unknown
1119 */
1120 private function can_send_comment_notification( $comment ) {
1121 // Returns false if the comment is marked as spam AND admin has enabled suppression of spam
1122 $suppress_spam = get_option( 'bnfw_suppress_spam' );
1123 if ( '1' === $suppress_spam && ( 0 === strcmp( $comment->comment_approved, 'spam' ) ) ) {
1124 return false;
1125 }
1126 return true;
1127 }
1128
1129 /**
1130 * Handle user request email content.
1131 *
1132 * @param string $content Content.
1133 * @param array $email_data Email data.
1134 *
1135 * @return string Modified content.
1136 */
1137 public function handle_user_request_email_content( $content, $email_data ) {
1138 $field = 'message';
1139 $new_content = '';
1140
1141 switch ( $email_data['description'] ) {
1142 case 'Export Personal Data':
1143 $notification_name = 'ca-export-data';
1144 $new_content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1145 break;
1146 case 'Erase Personal Data':
1147 $notification_name = 'ca-erase-data';
1148 $new_content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1149 break;
1150 }
1151
1152 if(!empty($new_content)){
1153 return $new_content;
1154 }else{
1155 return $content;
1156 }
1157 }
1158
1159 /**
1160 * Handle user request email subject.
1161 *
1162 * @param string $subject Subject
1163 * @param string $blogname Blog name
1164 * @param array $email_data Email data.
1165 *
1166 * @return string Modified subject.
1167 */
1168 public function handle_user_request_email_subject( $subject, $blogname, $email_data ) {
1169 $field = 'subject';
1170 $new_subject = '';
1171
1172 switch ( $email_data['description'] ) {
1173 case 'Export Personal Data':
1174 $notification_name = 'ca-export-data';
1175 $new_subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1176 break;
1177 case 'Erase Personal Data':
1178 $notification_name = 'ca-erase-data';
1179 $new_subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1180 break;
1181 }
1182 if(!empty($new_subject)){
1183 return $new_subject;
1184 }else{
1185 return $subject;
1186 }
1187 }
1188
1189 /**
1190 * Handle user confirmed action email content.
1191 *
1192 * @param string $content Content.
1193 * @param array $email_data Email data.
1194 *
1195 * @return string Modified content.
1196 */
1197 public function handle_user_confirmed_action_email_content( $content, $email_data ) {
1198 $field = 'message';
1199 $new_content = '';
1200
1201 switch ( $email_data['description'] ) {
1202 case 'Export Personal Data':
1203 $notification_name = 'uc-export-data';
1204 $new_content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
1205 break;
1206 case 'Erase Personal Data':
1207 $notification_name = 'uc-erase-data';
1208 $new_content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
1209 break;
1210 }
1211
1212 if(!empty($new_content)){
1213 return $new_content;
1214 }else{
1215 return $content;
1216 }
1217 }
1218
1219 /**
1220 * Handle data exported email content.
1221 *
1222 * @param string $content Content.
1223 * @param int $request_id
1224 *
1225 * @return string Modified content.
1226 */
1227 public function handle_data_export_email_content( $content, $request_id ) {
1228 $field = 'message';
1229 $notification_name = 'data-export';
1230 $new_content = '';
1231
1232 $notifications = $this->notifier->get_notifications( $notification_name );
1233 if ( count( $notifications ) > 0 ) {
1234 // Ideally there should be only one notification for this type.
1235 // If there are multiple notification then we will read data about only the last one
1236 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1237
1238 $new_content = $this->engine->handle_data_export_email_shortcodes( $setting[ $field ], $setting, $request_id );
1239 }
1240
1241 if(!empty($new_content)){
1242 return $new_content;
1243 }else{
1244 return $content;
1245 }
1246 }
1247
1248 public function handle_erasure_complete_email_subject( $subject, $sitename, $email_data ) {
1249 return $this->handle_erasure_complete_email_notification( 'subject', $subject, $email_data );
1250 }
1251
1252 public function handle_erasure_complete_email_content( $content, $email_data ) {
1253 if ( isset( $email_data['privacy_policy_url'] ) ) {
1254 return $this->handle_erasure_complete_email_notification( 'message', $content, $email_data );
1255 }
1256
1257 return $content;
1258 }
1259
1260 protected function handle_erasure_complete_email_notification( $field, $content, $email_data ) {
1261 $notification_name = 'data-erased';
1262 $new_content = '';
1263 $notifications = $this->notifier->get_notifications( $notification_name );
1264 if ( count( $notifications ) > 0 ) {
1265 // Ideally there should be only one notification for this type.
1266 // If there are multiple notification then we will read data about only the last one
1267 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1268 $new_content = $this->engine->handle_shortcodes( $setting[ $field ], $notification_name, $email_data );
1269 }
1270 if(!empty($new_content)){
1271 return $new_content;
1272 }else{
1273 return $content;
1274 }
1275 }
1276
1277 /**
1278 * Send notification emails on shutdown.
1279 */
1280 public function on_shutdown() {
1281 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1282 return;
1283 }
1284
1285 $transient = get_transient( 'bnfw-async-notifications' );
1286 if ( is_array( $transient ) ) {
1287 delete_transient( 'bnfw-async-notifications' );
1288 foreach ( $transient as $id_pairs ) {
1289 $this->engine->send_notification( $this->notifier->read_settings( $id_pairs['notification_id'] ), $id_pairs['ref_id'] );
1290 }
1291 }
1292 }
1293
1294 /**
1295 * Handle user request notification.
1296 *
1297 * @param string $notification_name Notification name.
1298 * @param string $field Field name.
1299 * @param array $email_data Email data.
1300 *
1301 * @return string Content.
1302 */
1303 protected function handle_user_request_notification( $notification_name, $field, $email_data ) {
1304 $notifications = $this->notifier->get_notifications( $notification_name );
1305 if ( count( $notifications ) > 0 ) {
1306 // Ideally there should be only one notification for this type.
1307 // If there are multiple notification then we will read data about only the last one
1308 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1309
1310 return $this->engine->handle_user_request_email_shortcodes( $setting[ $field ], $setting, $email_data );
1311 }
1312
1313 return '';
1314 }
1315
1316 /**
1317 * Handle user confirmed action notification.
1318 *
1319 * @param string $notification_name Notification name.
1320 * @param string $field Field name.
1321 * @param array $email_data Email data.
1322 *
1323 * @return string Content.
1324 */
1325 protected function handle_user_confirmed_action_notification( $notification_name, $field, $email_data ) {
1326 $notifications = $this->notifier->get_notifications( $notification_name );
1327 if ( count( $notifications ) > 0 ) {
1328 // Ideally there should be only one notification for this type.
1329 // If there are multiple notification then we will read data about only the last one
1330 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1331
1332 return $this->engine->handle_user_confirmed_action_email_shortcodes( $setting[ $field ], $setting, $email_data );
1333 }
1334
1335 return '';
1336 }
1337
1338 /**
1339 * Is this a metabox request?
1340 *
1341 * Block editor sends duplicate requests on post update.
1342 *
1343 * @return bool True if metabox request, False otherwise.
1344 */
1345 protected function is_metabox_request() {
1346 return ( isset( $_GET['meta-box-loader'] ) || isset( $_GET['meta_box'] ) );
1347 }
1348 }
1349
1350 /* ------------------------------------------------------------------------ *
1351 * Fire up the plugin
1352 * ------------------------------------------------------------------------ */
1353 BNFW::factory();
1354