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

1,655 lines 55.5 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.9
7 * Requires at least: 4.8
8 * Requires PHP: 7.1
9 * Author: Made with Fuel
10 * Author URI: https://madewithfuel.com/
11 * License: GPLv2 or later
12 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
13 * Text Domain: bnfw
14 * Domain Path: /languages
15 *
16 * @package bnfw
17 */
18
19 /**
20 * Copyright © 2022 Made with Fuel Ltd. (hello@betternotificationsforwp.com)
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License, version 2, as
23 * published by the Free Software Foundation.
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 */
32 if ( ! class_exists( 'BNFW', false ) ) {
33 /**
34 * BNFW main class.
35 */
36 class BNFW {
37 /**
38 * BNFW version.
39 *
40 * @var string
41 */
42 public $bnfw_version = '1.9';
43 /**
44 * Class Constructor.
45 *
46 * @since 1.0
47 */
48 public function __construct() {
49 $this->bnfw_define_constants();
50 $this->load_textdomain();
51 $this->includes();
52 $this->hooks();
53 /**
54 * BNFW Notification.
55 *
56 * @var \BNFW_Notification
57 */
58 $this->notifier = new BNFW_Notification();
59
60 /**
61 * BNFW Engine.
62 *
63 * @var \BNFW_Engine
64 */
65 $this->engine = new BNFW_Engine();
66 }
67
68 /**
69 * Factory method to return the instance of the class.
70 *
71 * Makes sure that only one instance is created.
72 *
73 * @return \BNFW Instance of the class.
74 */
75 public static function factory() {
76 static $instance = false;
77 if ( ! $instance ) {
78 $instance = new self();
79 }
80 return $instance;
81 }
82
83 /**
84 * Loads the plugin language files
85 *
86 * @since 1.0
87 */
88 public function load_textdomain() {
89 // Load localization domain.
90 $this->translations = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
91 load_plugin_textdomain( 'bnfw', false, $this->translations );
92 }
93
94 /**
95 * Include required files.
96 *
97 * @since 1.0
98 */
99 public function includes() {
100
101 // Load license related classes.
102 if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
103 require_once 'includes/libraries/class-edd-sl-plugin-updater.php';
104 }
105
106 include_once ABSPATH . 'wp-admin/includes/plugin.php';
107
108 require_once 'vendor/persist-admin-notices-dismissal/persist-admin-notices-dismissal.php';
109
110 require_once 'includes/license/class-bnfw-license.php';
111 require_once 'includes/license/class-bnfw-license-setting.php';
112
113 // Load Engine.
114 require_once 'includes/engine/class-bnfw-engine.php';
115 require_once 'includes/overrides.php';
116
117 // Load notification post type and notification helpers.
118 require_once 'includes/admin/class-bnfw-notification.php';
119 require_once 'includes/notification/post-notification.php';
120
121 // Helpers.
122 require_once 'includes/helpers/helpers.php';
123 require_once 'includes/helpers/class-bnfw-ajax.php';
124
125 // Load Admin Pages.
126 if ( is_admin() ) {
127 require_once 'includes/admin/class-bnfw-settings.php';
128 }
129 }
130 /**
131 * Define BNFW Constants.
132 */
133 private function bnfw_define_constants() {
134 define( 'BNFW_VERSION', $this->bnfw_version );
135 }
136 /**
137 * Register Hooks.
138 *
139 * @since 1.0
140 */
141 public function hooks() {
142 global $wp_version;
143
144 register_activation_hook( __FILE__, array( $this, 'activate' ) );
145
146 add_action( 'admin_init', array( 'PAnD', 'init' ) );
147 add_action( 'admin_init', array( $this, 'add_capability_to_admin' ) );
148
149 // Fire when privately publish.
150 add_action( 'auto-draft_to_private', array( $this, 'publish_private_post' ), 10, 1 );
151
152 add_action( 'draft_to_private', array( $this, 'private_post' ) );
153 add_action( 'future_to_private', array( $this, 'private_post' ) );
154 add_action( 'pending_to_private', array( $this, 'private_post' ) );
155 add_action( 'publish_to_private', array( $this, 'private_post' ) );
156
157 add_action( 'wp_insert_post', array( $this, 'insert_post' ), 10, 3 );
158
159 add_action( 'attachment_updated', array( $this, 'trash_attachment' ), 10, 3 );
160
161 add_action( 'publish_to_trash', array( $this, 'trash_post' ) );
162
163 add_action( 'auto-draft_to_publish', array( $this, 'publish_post' ) );
164 add_action( 'draft_to_publish', array( $this, 'publish_post' ) );
165 add_action( 'future_to_publish', array( $this, 'publish_post' ) );
166 add_action( 'pending_to_publish', array( $this, 'publish_post' ) );
167 add_action( 'private_to_publish', array( $this, 'publish_post' ) );
168
169 add_action( 'publish_to_publish', array( $this, 'update_post' ) );
170 add_action( 'private_to_private', array( $this, 'update_post' ) );
171
172 add_action( 'add_attachment', array( $this, 'new_publish_media_notification' ), 10, 1 );
173 add_action( 'edit_attachment', array( $this, 'media_attachment_data_update_notification' ), 10 );
174
175 add_action( 'transition_post_status', array( $this, 'on_post_transition' ), 10, 3 );
176
177 add_action( 'init', array( $this, 'custom_post_type_hooks' ), 100 );
178 add_action( 'create_term', array( $this, 'create_term' ), 10, 3 );
179
180 add_action( 'transition_comment_status', array( $this, 'on_comment_status_change' ), 10, 3 );
181 add_action( 'comment_post', array( $this, 'comment_post' ) );
182 add_action( 'trackback_post', array( $this, 'trackback_post' ) );
183 add_action( 'pingback_post', array( $this, 'pingback_post' ) );
184
185 add_action( 'user_register', array( $this, 'user_register' ) );
186
187 add_action( 'user_register', array( $this, 'welcome_email' ) );
188
189 if ( is_plugin_active( 'members/members.php' ) ) {
190
191 add_action( 'add_user_role', array( $this, 'user_role_added_from_member_plugin' ), 10, 2 );
192 add_action( 'remove_user_role', array( $this, 'user_role_removed_from_member_plugin' ), 10, 2 );
193 add_action( 'set_user_role', array( $this, 'user_role_changed' ), 10, 3 );
194
195 add_action( 'profile_update', array( $this, 'user_role_added' ), 10, 2 );
196 } else {
197 add_action( 'set_user_role', array( $this, 'user_role_changed' ), 10, 3 );
198 }
199
200 add_action( 'wp_login', array( $this, 'user_login' ), 10, 2 );
201
202 if ( version_compare( $wp_version, '4.4', '>=' ) ) {
203 add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ), 10, 3 );
204 } else {
205 add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ) );
206 }
207 add_action( 'lostpassword_post', array( $this, 'on_lost_password' ) );
208 add_filter( 'retrieve_password_message', array( $this, 'change_password_email_message' ), 10, 4 );
209
210 add_action( 'after_password_reset', array( $this, 'on_password_reset' ) );
211
212 add_filter( 'send_password_change_email', array( $this, 'should_password_changed_email_be_sent' ), 10, 3 );
213 add_filter( 'password_change_email', array( $this, 'on_password_changed' ), 10, 2 );
214
215 add_filter( 'send_email_change_email', array( $this, 'should_email_changed_email_be_sent' ), 10, 3 );
216 add_filter( 'email_change_email', array( $this, 'on_email_changed' ), PHP_INT_MAX, 3 );
217 add_filter( 'new_user_email_content', array( $this, 'on_email_changing' ), PHP_INT_MAX, 2 );
218
219 add_filter( 'auto_core_update_email', array( $this, 'on_core_updated' ), 10, 4 );
220
221 add_filter( 'user_request_action_email_content', array( $this, 'handle_user_request_email_content' ), 10, 2 );
222 add_filter( 'user_request_action_email_subject', array( $this, 'handle_user_request_email_subject' ), 10, 3 );
223
224 add_filter( 'user_confirmed_action_email_content', array( $this, 'handle_user_confirmed_action_email_content' ), 10, 2 );
225
226 add_filter( 'wp_privacy_personal_data_email_content', array( $this, 'handle_data_export_email_content' ), 10, 3 );
227
228 add_filter( 'user_erasure_complete_email_subject', array( $this, 'handle_erasure_complete_email_subject' ), 10, 3 );
229 add_filter( 'user_confirmed_action_email_content', array( $this, 'handle_erasure_complete_email_content' ), 10, 2 );
230
231 add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 4 );
232 add_filter( 'wp_mail', array( $this, 'bnfw_update_email_changing_subject' ), 10, 1 );
233 add_action( 'shutdown', array( $this, 'on_shutdown' ) );
234
235 }
236
237 /**
238 * Changed the subject when use request to change the email.
239 *
240 * @param array $args Email arguments.
241 *
242 * @return mixed
243 */
244 public function bnfw_update_email_changing_subject( $args ) {
245 $notification_name = 'email-changed';
246 $notifications = $this->notifier->get_notifications( $notification_name );
247 if ( count( $notifications ) > 0 ) {
248 $setting = $this->notifier->read_settings( end( $notifications )->ID );
249 if ( str_contains( $args['message'], '/profile.php?newuseremail=' ) ) {
250 $subject = str_replace( '[global_site_title]', get_bloginfo( 'name' ), $setting['subject'] );
251 $subject = str_replace( '[[global_site_title]]', get_bloginfo( 'name' ), $subject );
252 $args['subject'] = $subject;
253 } elseif ( str_contains( $args['message'], '?newuseremail=' ) ) {
254 $subject = str_replace( '[global_site_title]', get_bloginfo( 'name' ), $setting['subject'] );
255 $subject = str_replace( '[[global_site_title]]', get_bloginfo( 'name' ), $subject );
256 $args['subject'] = $subject;
257 }
258 }
259
260 return $args;
261 }
262
263 /**
264 * Fires when a media is moved to trash.
265 *
266 * @param int $post_id Post ID.
267 * @param WP_Post $post_after Post object following the update.
268 * @param WP_Post $post_before Post object before the update.
269 */
270 public function trash_attachment( $post_id, $post_after, $post_before ) {
271 $post_type = get_post_type( $post_id );
272 $post_status_before = $post_before->post_status;
273 $post_status_after = $post_after->post_status;
274 if ( BNFW_Notification::POST_TYPE !== $post_type && 'inherit' === $post_status_before && 'trash' === $post_status_after ) {
275 $this->send_notification_async( 'trash-' . $post_type, $post_id );
276 }
277 }
278
279 /**
280 * Add 'bnfw' capability to admin.
281 */
282 public function add_capability_to_admin() {
283 $admins = get_role( 'administrator' );
284
285 if ( is_null( $admins ) ) {
286 return;
287 }
288
289 if ( ! $admins->has_cap( 'bnfw' ) ) {
290 $admins->add_cap( 'bnfw' );
291 }
292 }
293
294 /**
295 * On post transition.
296 *
297 * @param string $new_status New post status.
298 * @param string $old_status Old post status.
299 * @param \WP_Post $post Post object.
300 */
301 public function on_post_transition( $new_status, $old_status, $post ) {
302 if ( ! is_a( $post, 'WP_Post' ) ) {
303 return;
304 }
305
306 if ( 'pending' === $old_status ) {
307 return;
308 }
309
310 if ( 'pending' !== $new_status ) {
311 return;
312 }
313
314 $this->on_post_pending( $post->ID, $post );
315 }
316
317 /**
318 * Setup hooks for custom post types.
319 *
320 * @since 1.2
321 */
322 public function custom_post_type_hooks() {
323 $post_types = get_post_types( array( 'public' => true ), 'names' );
324 $post_types = array_diff( $post_types, array( BNFW_Notification::POST_TYPE ) );
325
326 foreach ( $post_types as $post_type ) {
327 add_action( 'future_' . $post_type, array( $this, 'on_post_scheduled' ), 10, 2 );
328 }
329 }
330
331 /**
332 * Importer.
333 */
334 public function activate() {
335 require_once dirname( __FILE__ ) . '/includes/class-bnfw-import.php';
336 $importer = new BNFW_Import();
337 $importer->import();
338 }
339
340 /**
341 * Add 'Settings' link below BNFW in Plugins list.
342 *
343 * @since 1.0
344 * @param string[] $links An array of plugin action links. By default this can include 'activate',
345 * 'deactivate', and 'delete'. With Multisite active this can also include.
346 * @param string $file Path to the plugin file relative to the plugins directory.
347 * @return array plugin action links.
348 */
349 public function plugin_action_links( $links, $file ) {
350 $plugin_file = 'bnfw/bnfw.php';
351 if ( $file === $plugin_file ) {
352 $settings_link = '<a href="' . esc_url( admin_url( 'edit.php?post_type=bnfw_notification&page=bnfw-settings' ) ) . '">' . esc_html__( 'Settings', 'bnfw' ) . '</a>';
353 array_unshift( $links, $settings_link );
354 }
355 return $links;
356 }
357
358 /**
359 * When a new term is created.
360 *
361 * @since 1.0
362 * @param int $term_id Term ID.
363 * @param int $tt_id Term taxonomy ID.
364 * @param string $taxonomy Taxonomy slug.
365 */
366 public function create_term( $term_id, $tt_id, $taxonomy ) {
367 $this->send_notification( 'newterm-' . $taxonomy, $term_id );
368 }
369
370 /**
371 * Fires when a post is created for the first time.
372 *
373 * @param int $post_id Post ID.
374 * @param object $post Post object.
375 * @param bool $update Whether this is an existing post being updated or not.
376 *
377 * @since 1.3.1
378 */
379 public function insert_post( $post_id, $post, $update ) {
380 // Some themes like P2, directly insert posts into DB.
381 $insert_post_themes = apply_filters( 'bnfw_insert_post_themes', array( 'P2', 'Syncope' ) );
382 $current_theme = wp_get_theme();
383
384 /**
385 * Whether to trigger insert post hook.
386 *
387 * @since 1.4
388 */
389 $trigger_insert_post = apply_filters( 'bnfw_trigger_insert_post', false, $post_id, $update );
390
391 if ( in_array( $current_theme->get( 'Name' ), $insert_post_themes, true ) || $trigger_insert_post ) {
392 $this->handle_inserted_post( $post_id, $update );
393 }
394 }
395
396 /**
397 * Trigger New Post published notification for ACF forms.
398 *
399 * @param string $form ACF Form.
400 * @param int $post_id Post ID.
401 */
402 public function acf_submit_form( $form, $post_id ) {
403 $this->handle_inserted_post( $post_id );
404 }
405
406 /**
407 * Trigger correct notifications for inserted posts.
408 *
409 * @param int $post_id Post id.
410 * @param bool $update Whether the post was updated.
411 *
412 * @since 1.6.7
413 */
414 private function handle_inserted_post( $post_id, $update ) {
415 $post = get_post( $post_id );
416
417 if ( ! is_a( $post, 'WP_Post' ) ) {
418 return;
419 }
420
421 switch ( $post->post_status ) {
422 case 'publish':
423 if ( $update ) {
424 $this->update_post( $post );
425 } else {
426 $this->publish_post( $post );
427 }
428 break;
429
430 case 'private':
431 $this->private_post( $post );
432 break;
433
434 case 'pending':
435 $this->on_post_pending( $post_id, $post );
436 break;
437
438 case 'future':
439 $this->on_post_scheduled( $post_id, $post );
440 break;
441 }
442 }
443
444 /**
445 * Fires when a post is created for the first time.
446 *
447 * @since 1.0
448 * @param object $post Post Object.
449 */
450 public function publish_post( $post ) {
451 $post_id = $post->ID;
452 $post_type = $post->post_type;
453
454 if ( BNFW_Notification::POST_TYPE !== $post_type ) {
455 $this->send_notification_async( 'new-' . $post_type, $post_id );
456 }
457 }
458
459 /**
460 * Fire an email when post status change to private.
461 *
462 * @param object $post Post Object.
463 *
464 * @return void
465 */
466 public function publish_private_post( $post ) {
467 $this->private_post( $post );
468 }
469
470 /**
471 * Fires when a private post is created.
472 *
473 * @since 1.6
474 * @param object $post Post Object.
475 */
476 public function private_post( $post ) {
477 $post_id = $post->ID;
478 $post_type = $post->post_type;
479
480 if ( BNFW_Notification::POST_TYPE !== $post_type ) {
481 $this->send_notification_async( 'private-' . $post_type, $post_id );
482 }
483 }
484
485 /**
486 * Fires when a post is updated.
487 *
488 * @since 1.0
489 * @param WP_Post $post Post object.
490 */
491 public function update_post( $post ) {
492 if ( $this->is_metabox_request() ) {
493 return;
494 }
495
496 $post_id = $post->ID;
497 $post_type = $post->post_type;
498
499 if ( BNFW_Notification::POST_TYPE !== $post_type ) {
500 $this->send_notification_async( 'update-' . $post_type, $post_id );
501 }
502 }
503
504 /**
505 * Fires when a post is moved publish to trash.
506 *
507 * @param WP_Post $post Post object.
508 */
509 public function trash_post( $post ) {
510 if ( $this->is_metabox_request() ) {
511 return;
512 }
513 $post_id = $post->ID;
514 $post_type = $post->post_type;
515
516 if ( BNFW_Notification::POST_TYPE !== $post_type ) {
517 $this->send_notification_async( 'trash-' . $post_type, $post_id );
518 }
519 }
520
521 /**
522 * Fires when a post is pending for review.
523 *
524 * @since 1.1
525 * @param int $post_id Post ID.
526 * @param object $post Post object.
527 */
528 public function on_post_pending( $post_id, $post ) {
529 if ( $this->is_metabox_request() ) {
530 return;
531 }
532
533 $post_type = $post->post_type;
534
535 if ( BNFW_Notification::POST_TYPE !== $post_type ) {
536 $this->send_notification_async( 'pending-' . $post_type, $post_id );
537 }
538 }
539
540 /**
541 * On Media Published.
542 *
543 * @param int $post_id Attachment post id.
544 */
545 public function new_publish_media_notification( $post_id ) {
546 $post_type = get_post_type( $post_id );
547
548 if ( BNFW_Notification::POST_TYPE !== $post_type && 'attachment' === $post_type ) {
549 $this->send_notification_async( 'new-media', $post_id );
550 }
551 }
552
553 /**
554 * On Media Attachment Data Update.
555 *
556 * @param int $post_id Attachment post id.
557 */
558 public function media_attachment_data_update_notification( $post_id ) {
559 $post_type = get_post_type( $post_id );
560 if ( BNFW_Notification::POST_TYPE !== $post_type && 'attachment' === $post_type ) {
561 $this->send_notification_async( 'update-media', $post_id );
562 }
563 }
564
565 /**
566 * Fires when a post is scheduled.
567 *
568 * @since 1.1.5
569 * @param int $post_id Post ID.
570 * @param object $post Post object.
571 */
572 public function on_post_scheduled( $post_id, $post ) {
573 // Rest request also triggers the same hook. We can ignore it.
574 if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
575 return;
576 }
577
578 $post_type = $post->post_type;
579
580 if ( BNFW_Notification::POST_TYPE !== $post_type ) {
581 $this->send_notification_async( 'future-' . $post_type, $post_id );
582 }
583 }
584
585 /**
586 * When the status of a comment is changed.
587 *
588 * @param string $new_status New status.
589 * @param string $old_status Old status.
590 * @param \WP_Comment $comment Comment.
591 */
592 public function on_comment_status_change( $new_status, $old_status, $comment ) {
593 if ( 'approved' !== $new_status ) {
594 return;
595 }
596
597 $post = get_post( $comment->comment_post_ID );
598
599 $notification_type = 'approve-' . $post->post_type . '-comment';
600
601 $this->send_notification( $notification_type, $comment->comment_ID, false );
602
603 // Send new comment notification after comment approve.
604 $notification_type = 'new-comment'; // old notification name.
605
606 if ( 'post' !== $post->post_type ) {
607 $notification_type = 'comment-' . $post->post_type;
608 }
609
610 $this->send_notification( $notification_type, $comment->comment_ID );
611
612 // Send comment reply notification after comment approve.
613 $this->comments_reply( $comment->comment_ID );
614 }
615
616 /**
617 * Send notification for new comments
618 *
619 * @since 1.0
620 * @param int $comment_id The comment ID.
621 */
622 public function comment_post( $comment_id ) {
623 $the_comment = get_comment( $comment_id );
624 $post = get_post( $the_comment->comment_post_ID );
625
626 if ( '1' !== $the_comment->comment_approved ) {
627 if ( $this->can_send_comment_notification( $the_comment ) ) {
628 $notification_type = 'moderate-' . $post->post_type . '-comment';
629 $this->send_notification( $notification_type, $comment_id );
630 }
631 } else {
632 $notification_type = 'new-comment'; // old notification name.
633
634 if ( 'post' !== $post->post_type ) {
635 $notification_type = 'comment-' . $post->post_type;
636 }
637
638 $this->send_notification( $notification_type, $comment_id );
639
640 // comment reply notification.
641 $this->comments_reply( $comment_id );
642 }
643 }
644
645 /**
646 * Send notification for comments reply
647 *
648 * @since 1.0
649 * @param int $comment_id The comment ID.
650 */
651 public function comments_reply( $comment_id ) {
652 $the_comment = get_comment( $comment_id );
653 $post = get_post( $the_comment->comment_post_ID );
654
655 // comment reply notification.
656 if ( $this->can_send_comment_notification( $the_comment ) ) {
657 if ( $the_comment->comment_parent > 0 ) {
658 $notification_type = 'reply-comment'; // old notification name.
659 if ( 'post' !== $post->post_type ) {
660 $notification_type = 'commentreply-' . $post->post_type;
661 }
662 $notifications = $this->notifier->get_notifications( $notification_type );
663 if ( count( $notifications ) > 0 ) {
664 $parent = get_comment( $the_comment->comment_parent );
665 if ( $parent->comment_author_email !== $the_comment->comment_author_email ) {
666 foreach ( $notifications as $notification ) {
667 $this->engine->send_comment_reply_email( $this->notifier->read_settings( $notification->ID ), $the_comment, $parent );
668 }
669 }
670 }
671 }
672 }
673 }
674
675 /**
676 * Send notification for new trackback.
677 *
678 * @since 1.0
679 * @param int $comment_id Trackback ID.
680 */
681 public function trackback_post( $comment_id ) {
682 $the_comment = get_comment( $comment_id );
683 if ( $this->can_send_comment_notification( $the_comment ) ) {
684 $this->send_notification( 'new-trackback', $comment_id );
685 }
686 }
687
688 /**
689 * Send notification for new pingbacks
690 *
691 * @since 1.0
692 * @param int $comment_id Comment ID.
693 */
694 public function pingback_post( $comment_id ) {
695 $the_comment = get_comment( $comment_id );
696 if ( $this->can_send_comment_notification( $the_comment ) ) {
697 $this->send_notification( 'new-pingback', $comment_id );
698 }
699 }
700
701 /**
702 * Send notification for lost password.
703 *
704 * @since 1.0
705 */
706 public function on_lost_password() {
707 $user_login = ! empty( $_POST['user_login'] ) ? sanitize_text_field( wp_unslash( $_POST['user_login'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
708 $user = get_user_by( 'login', $user_login );
709 if ( false === $user ) {
710 $user = get_user_by( 'email', $user_login );
711 }
712 if ( $user ) {
713 $this->send_notification( 'admin-password', $user->ID );
714 }
715 }
716
717 /**
718 * Change the title of the password reset email that is sent to the user.
719 *
720 * @since 1.1
721 *
722 * @param string $title Email subject.
723 * @param string $user_login The username for the user.
724 * @param string $user_data WP_User object.
725 *
726 * @return string
727 */
728 public function change_password_email_title( $title, $user_login = '', $user_data = '' ) {
729 $notifications = $this->notifier->get_notifications( 'user-password' );
730 if ( count( $notifications ) > 0 ) {
731 // Ideally there should be only one notification for this type.
732 // If there are multiple notification then we will read data about only the last one.
733 $setting = $this->notifier->read_settings( end( $notifications )->ID );
734
735 if ( '' === $user_data ) {
736 return $this->engine->handle_shortcodes( $setting['subject'], 'user-password', $user_data->ID );
737 } else {
738 return $this->engine->handle_shortcodes( $setting['subject'], 'user-password', $user_data->ID );
739 }
740 }
741
742 return $title;
743 }
744
745 /**
746 * Change the message of the password reset email.
747 *
748 * @since 1.1
749 *
750 * @param string $message Email message.
751 * @param string $key The activation key.
752 * @param string $user_login The username for the user.
753 * @param string $user_data WP_User object.
754 *
755 * @return string
756 */
757 public function change_password_email_message( $message, $key, $user_login = '', $user_data = '' ) {
758 $notifications = $this->notifier->get_notifications( 'user-password' );
759 if ( count( $notifications ) > 0 ) {
760 // Ideally there should be only one notification for this type.
761 // If there are multiple notification then we will read data about only the last one.
762 $setting = $this->notifier->read_settings( end( $notifications )->ID );
763
764 $message = $this->engine->handle_password_reset_shortcodes( $setting, $key, $user_login, $user_data );
765
766 if ( 'html' === $setting['email-formatting'] ) {
767 add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
768 if ( 'true' !== $setting['disable-autop'] ) {
769 $message = wpautop( $message );
770 }
771 } else {
772 add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
773 if ( 'text' === $setting['email-formatting'] ) {
774 $message = wp_strip_all_tags( $message );
775 }
776 }
777 } else {
778 if ( $this->notifier->notification_exists( 'user-password', false ) ) {
779 // disabled notification exists, so disable the email by returning empty string.
780 return '';
781 }
782 }
783
784 return $message;
785 }
786
787 /**
788 * On Password reset.
789 *
790 * @param WP_User $user User who's password was changed.
791 */
792 public function on_password_reset( $user ) {
793 $notifications = $this->notifier->get_notifications( 'password-changed' );
794 foreach ( $notifications as $notification ) {
795 $this->engine->send_password_changed_email( $this->notifier->read_settings( $notification->ID ), $user );
796 }
797 }
798
799 /**
800 * Should the password changed email be sent?
801 *
802 * @param bool $send Whether to send the email.
803 * @param array $user The original user array.
804 * @param array $userdata The updated user array.
805 *
806 * @return bool
807 */
808 public function should_password_changed_email_be_sent( $send, $user, $userdata ) {
809 $bnfw = self::factory();
810
811 if ( ! $send ) {
812 return $send;
813 }
814
815 return ! $bnfw->notifier->is_notification_disabled( 'password-changed' );
816 }
817
818 /**
819 * On Password Changed.
820 *
821 * @since 1.6
822 *
823 * @param array $email_data Email Data.
824 * @param array $user User data.
825 *
826 * @return array Modified Email Data
827 */
828 public function on_password_changed( $email_data, $user ) {
829 return $this->handle_filtered_data_notification( 'password-changed', $email_data, $user['ID'] );
830 }
831
832 /**
833 * Should the email changed email be sent?
834 *
835 * @param bool $send Whether to send the email.
836 * @param array $user_old_data The original user array.
837 * @param array $user_new_data The updated user array.
838 *
839 * @return bool
840 */
841 public function should_email_changed_email_be_sent( $send, $user_old_data, $user_new_data ) {
842 $bnfw = self::factory();
843
844 if ( $bnfw->notifier->notification_exists( 'admin-email-changed', false ) ) {
845 $notifications = $bnfw->notifier->get_notifications( 'admin-email-changed' );
846
847 if ( count( $notifications ) > 0 ) {
848 // Ideally there should be only one notification for this type.
849 // If there are multiple notification then we will read data about only the last one.
850 $setting = $bnfw->notifier->read_settings( end( $notifications )->ID );
851 $notification_disabled = apply_filters( 'bnfw_notification_disabled', ( 'true' === $setting['disabled'] ), $id, $setting );
852
853 if ( ! $notification_disabled ) {
854
855 $setting['message'] = str_replace( '[user_old_email]', $user_old_data['user_email'], $setting['message'] );
856 $setting['message'] = str_replace( '[user_new_email]', $user_new_data['user_email'], $setting['message'] );
857 $bnfw->engine->send_notification( $setting, $user_old_data['ID'] );
858 }
859 }
860 }
861
862 if ( ! $send ) {
863 return $send;
864 }
865
866 return ! $bnfw->notifier->is_notification_disabled( 'email-changed' );
867 }
868
869 /**
870 * On Email Changed.
871 *
872 * @since 1.6
873 *
874 * @param array $email_data Email Data.
875 * @param array $user_old_data The original user array.
876 * @param array $user_new_data The updated user array.
877 *
878 * @return array Modified Email Data
879 */
880 public function on_email_changed( $email_data, $user_old_data, $user_new_data ) {
881
882 $email = $this->handle_filtered_data_notification( 'email-changed', $email_data, $user_old_data['ID'] );
883 $user = get_user_by( 'ID', $user_old_data['ID'] );
884 $email['message'] = str_replace( '[user_nicename]', $user->user_login, $email['message'] );
885 $email['message'] = str_replace( '[user_old_email]', $user_old_data['user_email'], $email['message'] );
886 $email['message'] = str_replace( '[user_new_email]', $user_new_data['user_email'], $email['message'] );
887 $email_data['message'] = $email['message'];
888
889 $notifications = $this->notifier->get_notifications( 'email-changed' );
890 if ( count( $notifications ) > 0 ) {
891 $setting = $this->notifier->read_settings( end( $notifications )->ID );
892 // Ensures the content type of the message.
893 if ( 'html' === $setting['email-formatting'] ) {
894 $email_data['message'] = wpautop( $email_data['message'] );
895 }
896 }
897
898 return $email_data;
899 }
900 /**
901 * Filters the text of the email sent when a change of user email address is attempted.
902 *
903 * @param string $email_text Text in the email.
904 * @param array $new_user_details {
905 * Data relating to the new user email address.
906 *
907 * @type string $hash The secure hash used in the confirmation link URL.
908 * @type string $newemail The proposed new email address.
909 * }
910 */
911 public function on_email_changing( $email_text, $new_user_details ) {
912 $notification_name = 'email-changing';
913
914 $notifications = $this->notifier->get_notifications( $notification_name );
915 if ( count( $notifications ) > 0 ) {
916
917 $user = wp_get_current_user();
918
919 // Ideally there should be only one notification for this type.
920 // If there are multiple notification then we will read data about only the last one.
921 $setting = $this->notifier->read_settings( end( $notifications )->ID );
922
923 // Ensures the content type of the message.
924 if ( 'html' === $setting['email-formatting'] ) {
925 add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
926 } else {
927 add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
928 }
929
930 $email_text = $this->engine->handle_shortcodes( $setting['message'], $setting['notification'], $new_user_details['newemail'] );
931 $email_text = $this->engine->handle_global_user_shortcodes( $email_text, $new_user_details['newemail'] );
932 $email_text = str_replace( '[email_change_confirmation_link]', esc_url( admin_url( 'profile.php?newuseremail=' . $new_user_details['hash'] ) ), $email_text );
933 $email_text = str_replace( '[user_nicename]', $user->data->user_nicename, $email_text );
934 $email_text = str_replace( '[user_id]', $user->data->ID, $email_text );
935 $email_text = str_replace( '[user_login]', $user->data->user_login, $email_text );
936 $email_text = str_replace( '[user_email]', $user->data->user_email, $email_text );
937 $email_text = str_replace( '[user_url]', $user->data->user_url, $email_text );
938 $email_text = str_replace( '[user_registered]', $user->data->user_registered, $email_text );
939 $email_text = str_replace( '[user_display_name]', $user->data->display_name, $email_text );
940 $email_text = str_replace( '[user_firstname]', get_user_meta( $user->data->ID, 'first_name', true ), $email_text );
941 $email_text = str_replace( '[user_lastname]', get_user_meta( $user->data->ID, 'last_name', true ), $email_text );
942 $email_text = str_replace( '[user_nickname]', get_user_meta( $user->data->ID, 'nickname', true ), $email_text );
943 $email_text = str_replace( '[user_description]', get_user_meta( $user->data->ID, 'description', true ), $email_text );
944 $email_text = str_replace( '[user_wp_capabilities]', implode( ', ', $user->roles ), $email_text );
945 $email_text = str_replace( '[user_avatar]', get_avatar( $user->data->ID ), $email_text );
946 $email_text = str_replace( '[nickname]', $user->nickname, $email_text );
947 $email_text = str_replace( '[display_name]', $user->display_name, $email_text );
948 $email_text = str_replace( '[email_user_id]', $user->data->ID, $email_text );
949 $email_text = str_replace( '[email_user_login]', $user->data->user_login, $email_text );
950 $email_text = str_replace( '[email_user_nicename]', $user->data->user_nicename, $email_text );
951 $email_text = str_replace( '[email_user_email]', $user->data->user_email, $email_text );
952 $email_text = str_replace( '[email_user_url]', $user->data->user_url, $email_text );
953 $email_text = str_replace( '[email_user_registered]', $user->data->user_registered, $email_text );
954 $email_text = str_replace( '[email_user_display_name]', $user->data->display_name, $email_text );
955 $email_text = str_replace( '[email_user_firstname]', get_user_meta( $user->data->ID, 'first_name', true ), $email_text );
956 $email_text = str_replace( '[email_user_lastname]', get_user_meta( $user->data->ID, 'last_name', true ), $email_text );
957 $email_text = str_replace( '[email_user_nickname]', get_user_meta( $user->data->ID, 'nickname', true ), $email_text );
958 $email_text = str_replace( '[email_user_description]', get_user_meta( $user->data->ID, 'description', true ), $email_text );
959 $email_text = str_replace( '[email_user_wp_capabilities]', implode( ', ', $user->roles ), $email_text );
960 $email_text = str_replace( '[email_user_avatar]', get_avatar( $user->data->ID ), $email_text );
961 $email_text = str_replace( '[user_old_email]', $user->data->user_email, $email_text );
962 $email_text = str_replace( '[user_new_email]', $new_user_details['newemail'], $email_text );
963 $email_text = str_replace( '[user_role]', implode( ',', $user->roles ), $email_text );
964
965 $user_capabilities = bnfw_format_user_capabilities( $user->wp_capabilities );
966 if ( ! empty( $user_capabilities ) ) {
967 $email_text = str_replace( '[wp_capabilities]', $user_capabilities, $email_text );
968 }
969
970 if ( 'html' === $setting['email-formatting'] ) {
971 $email_text = wpautop( $email_text );
972 }
973 }
974
975 return $email_text;
976 }
977
978 /**
979 * Send notification on core updated event.
980 *
981 * @since 1.6
982 *
983 * @param array $email_data Email Data.
984 * @param string $type The type of email being sent. Can be one of
985 * 'success', 'fail', 'manual', 'critical'.
986 * @param object $core_update The update offer that was attempted.
987 * @param mixed $result The result for the core update. Can be WP_Error.
988 *
989 * @return array Modified Email Data.
990 */
991 public function on_core_updated( $email_data, $type, $core_update, $result ) {
992 $notifications = $this->notifier->get_notifications( 'core-updated' );
993 if ( count( $notifications ) > 0 ) {
994 // Ideally there should be only one notification for this type.
995 // If there are multiple notification then we will read data about only the last one.
996 $setting = $this->notifier->read_settings( end( $notifications )->ID );
997
998 $email_data = $this->engine->handle_core_updated_notification( $email_data, $setting, $type );
999 }
1000
1001 return $email_data;
1002 }
1003
1004 /**
1005 * Process User update notifications.
1006 *
1007 * @since 1.6
1008 *
1009 * @param string $notification_name Notification Name.
1010 * @param array $email_data Email Data.
1011 * @param string|int $extra_data User Id.
1012 *
1013 * @return array Modified Email Data.
1014 */
1015 private function handle_filtered_data_notification( $notification_name, $email_data, $extra_data ) {
1016 $notifications = $this->notifier->get_notifications( $notification_name );
1017 if ( count( $notifications ) > 0 ) {
1018 // Ideally there should be only one notification for this type.
1019 // If there are multiple notification then we will read data about only the last one.
1020 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1021
1022 // Ensures the content type of the message.
1023 if ( 'html' === $setting['email-formatting'] ) {
1024 add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
1025 } else {
1026 add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
1027 }
1028
1029 $email_data = $this->engine->handle_filtered_data_notification( $email_data, $setting, $extra_data );
1030 }
1031
1032 return $email_data;
1033 }
1034
1035 /**
1036 * Set the email formatting to HTML.
1037 *
1038 * @since 1.4
1039 */
1040 public function set_html_content_type() {
1041 return 'text/html';
1042 }
1043
1044 /**
1045 * Set the email formatting to text.
1046 *
1047 * @since 1.4
1048 */
1049 public function set_text_content_type() {
1050 return 'text/plain';
1051 }
1052
1053 /**
1054 * Send notification for new users.
1055 *
1056 * @since 1.0
1057 * @param int $user_id User ID.
1058 */
1059 public function user_register( $user_id ) {
1060 $this->send_notification( 'admin-user', $user_id );
1061 }
1062
1063 /**
1064 * Send notification for user when user login.
1065 *
1066 * @since 1.0
1067 * @param string $user_name Username.
1068 * @param object $user_data User object.
1069 */
1070 public function user_login( $user_name, $user_data ) {
1071 $user_id = $user_data->ID;
1072 $notifications = $this->notifier->get_notifications( 'user-login' );
1073
1074 foreach ( $notifications as $notification ) {
1075 $this->engine->send_user_login_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
1076 }
1077
1078 $this->user_login_admin_notification( $user_id );
1079 }
1080
1081 /**
1082 * Send notification for admin when user login.
1083 *
1084 * @since 1.0
1085 * @param int $user_id User ID.
1086 */
1087 public function user_login_admin_notification( $user_id ) {
1088 $notifications = $this->notifier->get_notifications( 'admin-user-login' );
1089
1090 foreach ( $notifications as $notification ) {
1091 $this->engine->send_user_login_email_for_admin( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
1092 }
1093 }
1094
1095 /**
1096 * Send notification about new users to site admin.
1097 *
1098 * @since 1.7.1
1099 *
1100 * @param array $email_data Email details.
1101 * @param WP_User $user User object.
1102 * @param string $blogname Blog name.
1103 *
1104 * @return array Modified email details.
1105 */
1106 public function handle_user_registered_admin_email( $email_data, $user, $blogname ) {
1107 return $this->handle_filtered_data_notification( 'admin-user', $email_data, $user->ID );
1108 }
1109
1110 /**
1111 * New User - Post-registration Email
1112 *
1113 * @since 1.1
1114 * @param int $user_id New user id.
1115 */
1116 public function welcome_email( $user_id ) {
1117 $notifications = $this->notifier->get_notifications( 'welcome-email' );
1118 foreach ( $notifications as $notification ) {
1119 $this->engine->send_registration_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
1120 }
1121 }
1122
1123 /**
1124 * Send notification when a user role changes.
1125 *
1126 * @since 1.3.9
1127 *
1128 * @param int $user_id User ID.
1129 * @param string $new_role New User role.
1130 * @param array $old_roles Old User role.
1131 */
1132 public function user_role_changed( $user_id, $new_role, $old_roles ) {
1133 if ( ! empty( $old_roles ) ) {
1134 $notifications = $this->notifier->get_notifications( 'user-role' );
1135 foreach ( $notifications as $notification ) {
1136
1137 /**
1138 * Trigger User Role Changed - For User notification.
1139 *
1140 * @since 1.6.5
1141 */
1142 if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, $new_role, $old_roles ) ) {
1143 $this->engine->send_user_role_changed_email( $this->notifier->read_settings( $notification->ID ), $user_id, $old_roles[0], $new_role );
1144 }
1145 }
1146 $notifications = $this->notifier->get_notifications( 'admin-role' );
1147 foreach ( $notifications as $notification ) {
1148
1149 /**
1150 * Trigger User Role Changed - For User notification.
1151 *
1152 * @since 1.6.5
1153 */
1154 if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, $new_role, $old_roles ) ) {
1155 $setting = $this->notifier->read_settings( $notification->ID );
1156 $setting['message'] = $this->engine->handle_user_role_shortcodes( $setting['message'], $old_roles[0], $new_role );
1157 $setting['subject'] = $this->engine->handle_user_role_shortcodes( $setting['subject'], $old_roles[0], $new_role );
1158
1159 $this->engine->send_notification( $setting, $user_id );
1160 }
1161 }
1162 }
1163 }
1164
1165 /**
1166 * Send notification when a user role added through Members Plugin.
1167 *
1168 * @since 1.8.4
1169 *
1170 * @param int $user_id User ID.
1171 * @param string $new_role New User role.
1172 */
1173 public function user_role_added_from_member_plugin( $user_id, $new_role ) {
1174
1175 global $pagenow;
1176
1177 if ( 'users.php' !== $pagenow ) {
1178 return;
1179 }
1180 if ( ! $user_id ) {
1181 return;
1182 }
1183
1184 $notifications = $this->notifier->get_notifications( 'user-role' );
1185
1186 foreach ( $notifications as $notification ) {
1187 if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, $new_role, null ) ) {
1188 $this->engine->send_user_role_changed_email( $this->notifier->read_settings( $notification->ID ), $user_id, null, $new_role );
1189 }
1190 }
1191
1192 $notifications_admin = $this->notifier->get_notifications( 'admin-role' );
1193 foreach ( $notifications_admin as $notification ) {
1194 if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, $new_role, null ) ) {
1195 $setting = $this->notifier->read_settings( $notification->ID );
1196 $setting['message'] = $this->engine->handle_user_role_shortcodes( $setting['message'], null, $new_role );
1197 $setting['subject'] = $this->engine->handle_user_role_shortcodes( $setting['subject'], null, $new_role );
1198
1199 $this->engine->send_notification( $setting, $user_id );
1200 }
1201 }
1202
1203 }
1204
1205 /**
1206 * Send notification when a user role removed through Members Plugin.
1207 *
1208 * @since 1.8.4
1209 *
1210 * @param int $user_id User ID.
1211 * @param string $old_role New User role.
1212 */
1213 public function user_role_removed_from_member_plugin( $user_id, $old_role ) {
1214 global $pagenow;
1215
1216 if ( 'users.php' !== $pagenow ) {
1217 return;
1218 }
1219 if ( ! $user_id ) {
1220 return;
1221 }
1222
1223 $notifications = $this->notifier->get_notifications( 'user-role' );
1224
1225 foreach ( $notifications as $notification ) {
1226 if ( apply_filters( 'bnfw_trigger_user-role_notification', true, $notification, null, array( $old_role ) ) ) {
1227 $this->engine->send_user_role_changed_email( $this->notifier->read_settings( $notification->ID ), $user_id, $old_role, null );
1228 }
1229 }
1230
1231 $notifications_admin = $this->notifier->get_notifications( 'admin-role' );
1232 foreach ( $notifications_admin as $notification ) {
1233 if ( apply_filters( 'bnfw_trigger_admin-role_notification', true, $notification, null, array( $old_role ) ) ) {
1234 $setting = $this->notifier->read_settings( $notification->ID );
1235 $setting['message'] = $this->engine->handle_user_role_shortcodes( $setting['message'], $old_role, null );
1236 $setting['subject'] = $this->engine->handle_user_role_shortcodes( $setting['subject'], $old_role, null );
1237
1238 $this->engine->send_notification( $setting, $user_id );
1239 }
1240 }
1241
1242 }
1243
1244 /**
1245 * Send notification when a user role added support User Role Editor by Members Plugin.
1246 *
1247 * @since 1.3.9
1248 *
1249 * @param int $user_id User ID.
1250 * @param array $old_user_data Old User role.
1251 */
1252 public function user_role_added( $user_id, $old_user_data ) {
1253
1254 if ( isset( $_POST['members_user_roles'] ) && ! empty( $_POST['members_user_roles'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1255 // Get the current user roles.
1256 $old_roles = (array) $old_user_data->roles;
1257
1258 // Sanitize the posted roles.
1259 $new_roles = array_map( array( $this, 'bnfw_members_sanitize_role' ), $_POST['members_user_roles'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
1260
1261 sort( $old_roles );
1262 sort( $new_roles );
1263 $old_roles_str = implode( '', $old_roles );
1264 $new_roles_str = implode( '', $new_roles );
1265 if ( ! empty( $old_roles ) && $old_roles_str !== $new_roles_str ) {
1266 $notifications = $this->notifier->get_notifications( 'user-role' );
1267 foreach ( $notifications as $notification ) {
1268
1269 /**
1270 * Trigger User Role Changed - For User notification.
1271 *
1272 * @since 1.6.5
1273 */
1274 if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
1275 $this->engine->send_user_role_added_email( $this->notifier->read_settings( $notification->ID ), $user_id, $old_roles, $new_roles );
1276 }
1277 }
1278
1279 $notifications = $this->notifier->get_notifications( 'admin-role' );
1280 foreach ( $notifications as $notification ) {
1281
1282 /**
1283 * Trigger User Role Changed - For User notification.
1284 *
1285 * @since 1.6.5
1286 */
1287 if ( apply_filters( 'bnfw_trigger_user-role-added_notification', true, $notification, $new_roles, $old_roles ) ) {
1288 $setting = $this->notifier->read_settings( $notification->ID );
1289 $setting['message'] = $this->engine->handle_user_added_role_shortcodes( $setting['message'], $old_roles, $new_roles );
1290 $setting['subject'] = $this->engine->handle_user_added_role_shortcodes( $setting['subject'], $old_roles, $new_roles );
1291
1292 $this->engine->send_notification( $setting, $user_id );
1293 }
1294 }
1295 }
1296 }
1297 }
1298
1299 /**
1300 * Sanitizes a role name. This is a wrapper for the `sanitize_key()` WordPress function. Only
1301 * alphanumeric characters and underscores are allowed. Hyphens are also replaced with underscores.
1302 *
1303 * @since 1.0.0
1304 * @access public
1305 * @param array $role Posted user role.
1306 * @return int
1307 */
1308 public function bnfw_members_sanitize_role( $role ) {
1309
1310 $_role = strtolower( $role );
1311 $_role = preg_replace( '/[^a-z0-9_\-\s]/', '', $_role );
1312
1313 return apply_filters( 'bnfw_members_sanitize_role', str_replace( ' ', '_', $_role ), $role );
1314 }
1315
1316 /**
1317 * Send notification based on type and ref id.
1318 *
1319 * @since 1.0
1320 * @param string $type Notification type.
1321 * @param mixed $ref_id Reference data.
1322 * @param bool $include_disabled Include disabled.
1323 */
1324 public function send_notification( $type, $ref_id, $include_disabled = true ) {
1325 $notifications = $this->notifier->get_notifications( $type, $include_disabled );
1326 foreach ( $notifications as $notification ) {
1327 $this->engine->send_notification( $this->notifier->read_settings( $notification->ID ), $ref_id );
1328 }
1329 }
1330
1331 /**
1332 * Send notification async based on type and ref id.
1333 *
1334 * @param string $type Notification type.
1335 * @param mixed $ref_id Reference data.
1336 */
1337 public function send_notification_async( $type, $ref_id ) {
1338 $notifications = $this->notifier->get_notifications( $type, false );
1339 foreach ( $notifications as $notification ) {
1340 $transient = get_transient( 'bnfw-async-notifications' );
1341 if ( ! is_array( $transient ) ) {
1342 $transient = array();
1343 }
1344
1345 $notification_data = array(
1346 'ref_id' => $ref_id,
1347 'notification_id' => $notification->ID,
1348 'notification_type' => $type,
1349 );
1350
1351 if ( ! in_array( $notification_data, $transient, true ) ) {
1352 $transient[] = $notification_data;
1353 set_transient( 'bnfw-async-notifications', $transient, 600 );
1354 }
1355 }
1356 }
1357
1358 /**
1359 * Can send comment notification or not.
1360 *
1361 * @since 1.0
1362 * @param WP_Comment $comment Comment data.
1363 * @return bool
1364 */
1365 private function can_send_comment_notification( $comment ) {
1366 // Returns false if the comment is marked as spam AND admin has enabled suppression of spam.
1367 $suppress_spam = get_option( 'bnfw_suppress_spam' );
1368 if ( '1' === $suppress_spam && ( 0 === strcmp( $comment->comment_approved, 'spam' ) ) ) {
1369 return false;
1370 }
1371 return true;
1372 }
1373
1374 /**
1375 * Handle user request email content.
1376 *
1377 * @param string $content Content.
1378 * @param array $email_data Email data.
1379 *
1380 * @return string Modified content.
1381 */
1382 public function handle_user_request_email_content( $content, $email_data ) {
1383 $field = 'message';
1384 $new_content = '';
1385
1386 switch ( $email_data['description'] ) {
1387 case 'Export Personal Data':
1388 $notification_name = 'ca-export-data';
1389 $new_content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1390 break;
1391 case 'Erase Personal Data':
1392 $notification_name = 'ca-erase-data';
1393 $new_content = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1394 break;
1395 }
1396
1397 if ( ! empty( $new_content ) ) {
1398 return $new_content;
1399 } else {
1400 return $content;
1401 }
1402 }
1403
1404 /**
1405 * Handle user request email subject.
1406 *
1407 * @param string $subject Subject.
1408 * @param string $blogname Blog name.
1409 * @param array $email_data Email data.
1410 *
1411 * @return string Modified subject.
1412 */
1413 public function handle_user_request_email_subject( $subject, $blogname, $email_data ) {
1414 $field = 'subject';
1415 $new_subject = '';
1416
1417 switch ( $email_data['description'] ) {
1418 case 'Export Personal Data':
1419 $notification_name = 'ca-export-data';
1420 $new_subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1421 break;
1422 case 'Erase Personal Data':
1423 $notification_name = 'ca-erase-data';
1424 $new_subject = $this->handle_user_request_notification( $notification_name, $field, $email_data );
1425 break;
1426 }
1427 if ( ! empty( $new_subject ) ) {
1428 return $new_subject;
1429 } else {
1430 return $subject;
1431 }
1432 }
1433
1434 /**
1435 * Handle user confirmed action email content.
1436 *
1437 * @param string $content Content.
1438 * @param array $email_data Email data.
1439 *
1440 * @return string Modified content.
1441 */
1442 public function handle_user_confirmed_action_email_content( $content, $email_data ) {
1443 $field = 'message';
1444 $new_content = '';
1445
1446 switch ( $email_data['description'] ) {
1447 case 'Export Personal Data':
1448 $notification_name = 'uc-export-data';
1449 $new_content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
1450 break;
1451 case 'Erase Personal Data':
1452 $notification_name = 'uc-erase-data';
1453 $new_content = $this->handle_user_confirmed_action_notification( $notification_name, $field, $email_data );
1454 break;
1455 }
1456
1457 if ( ! empty( $new_content ) ) {
1458 return $new_content;
1459 } else {
1460 return $content;
1461 }
1462 }
1463
1464 /**
1465 * Handle data exported email content.
1466 *
1467 * @param string $content Text in the email.
1468 * @param int $request_id The request ID for this personal data export.
1469 * @param array $email_data Data relating to the account action email.
1470 *
1471 * @return string Modified content.
1472 */
1473 public function handle_data_export_email_content( $content, $request_id, $email_data ) {
1474
1475 $field = 'message';
1476 $notification_name = 'data-export';
1477 $new_content = '';
1478
1479 $notifications = $this->notifier->get_notifications( $notification_name );
1480 if ( count( $notifications ) > 0 ) {
1481 // Ideally there should be only one notification for this type.
1482 // If there are multiple notification then we will read data about only the last one.
1483 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1484
1485 $new_content = $this->engine->handle_data_export_email_shortcodes( $setting[ $field ], $setting, $request_id );
1486 $new_content = $this->engine->handle_global_user_shortcodes( $new_content, $email_data['message_recipient'] );
1487 }
1488
1489 if ( ! empty( $new_content ) ) {
1490 return $new_content;
1491 } else {
1492 return $content;
1493 }
1494 }
1495 /**
1496 * Filters the subject of the email sent when an erasure request is completed.
1497 *
1498 * @param string $subject The email subject.
1499 * @param string $sitename The name of the site.
1500 * @param array $email_data Data relating to the account action email.
1501 */
1502 public function handle_erasure_complete_email_subject( $subject, $sitename, $email_data ) {
1503 return $this->handle_erasure_complete_email_notification( 'subject', $subject, $email_data );
1504 }
1505 /**
1506 * Filters the body of the data erasure fulfillment notification.
1507 *
1508 * @param string $content The email content.
1509 * @param array $email_data Data relating to the account action email.
1510 */
1511 public function handle_erasure_complete_email_content( $content, $email_data ) {
1512 if ( isset( $email_data['privacy_policy_url'] ) ) {
1513 return $this->handle_erasure_complete_email_notification( 'message', $content, $email_data );
1514 }
1515
1516 return $content;
1517 }
1518 /**
1519 * Handles erasure fulfillment notification.
1520 *
1521 * @param string $field Field name.
1522 * @param string $content The email content.
1523 * @param array $email_data Data relating to the account action email.
1524 */
1525 protected function handle_erasure_complete_email_notification( $field, $content, $email_data ) {
1526 $notification_name = 'data-erased';
1527 $new_content = '';
1528 $notifications = $this->notifier->get_notifications( $notification_name );
1529 if ( count( $notifications ) > 0 ) {
1530 // Ideally there should be only one notification for this type.
1531 // If there are multiple notification then we will read data about only the last one.
1532 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1533 $new_content = $this->engine->handle_shortcodes( $setting[ $field ], $notification_name, $email_data );
1534 }
1535 if ( ! empty( $new_content ) ) {
1536 return $new_content;
1537 } else {
1538 return $content;
1539 }
1540 }
1541
1542 /**
1543 * Send notification emails on shutdown.
1544 */
1545 public function on_shutdown() {
1546 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
1547 return;
1548 }
1549
1550 $transient = get_transient( 'bnfw-async-notifications' );
1551 if ( is_array( $transient ) ) {
1552 delete_transient( 'bnfw-async-notifications' );
1553 foreach ( $transient as $id_pairs ) {
1554 $this->engine->send_notification( $this->notifier->read_settings( $id_pairs['notification_id'] ), $id_pairs['ref_id'] );
1555 }
1556 }
1557 }
1558
1559 /**
1560 * Handle user request notification.
1561 *
1562 * @param string $notification_name Notification name.
1563 * @param string $field Field name.
1564 * @param array $email_data Email data.
1565 *
1566 * @return string Content.
1567 */
1568 protected function handle_user_request_notification( $notification_name, $field, $email_data ) {
1569 $notifications = $this->notifier->get_notifications( $notification_name );
1570 if ( count( $notifications ) > 0 ) {
1571 // Ideally there should be only one notification for this type.
1572 // If there are multiple notification then we will read data about only the last one.
1573 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1574
1575 return $this->engine->handle_user_request_email_shortcodes( $setting[ $field ], $setting, $email_data );
1576 }
1577
1578 return '';
1579 }
1580
1581 /**
1582 * Handle user confirmed action notification.
1583 *
1584 * @param string $notification_name Notification name.
1585 * @param string $field Field name.
1586 * @param array $email_data Email data.
1587 *
1588 * @return string Content.
1589 */
1590 protected function handle_user_confirmed_action_notification( $notification_name, $field, $email_data ) {
1591 $notifications = $this->notifier->get_notifications( $notification_name );
1592 if ( count( $notifications ) > 0 ) {
1593 // Ideally there should be only one notification for this type.
1594 // If there are multiple notification then we will read data about only the last one.
1595 $setting = $this->notifier->read_settings( end( $notifications )->ID );
1596
1597 return $this->engine->handle_user_confirmed_action_email_shortcodes( $setting[ $field ], $setting, $email_data );
1598 }
1599
1600 return '';
1601 }
1602
1603 /**
1604 * Is this a metabox request?
1605 *
1606 * Block editor sends duplicate requests on post update.
1607 *
1608 * @return bool True if metabox request, False otherwise.
1609 */
1610 protected function is_metabox_request() {
1611 return ( isset( $_GET['meta-box-loader'] ) || isset( $_GET['meta_box'] ) );
1612 }
1613
1614 /**
1615 * Check if Gutenberg is active.
1616 *
1617 * @return bool
1618 * @since 1.3
1619 */
1620 public function is_gutenberg_active() {
1621 $gutenberg = false;
1622 $block_editor = false;
1623
1624 if ( has_filter( 'replace_editor', 'gutenberg_init' ) ) {
1625 // Gutenberg is installed and activated.
1626 $gutenberg = true;
1627 }
1628
1629 if ( version_compare( $GLOBALS['wp_version'], '5.0-beta', '>' ) ) {
1630 // Block editor.
1631 $block_editor = true;
1632 }
1633
1634 if ( ! $gutenberg && ! $block_editor ) {
1635 return false;
1636 }
1637
1638 include_once ABSPATH . 'wp-admin/includes/plugin.php';
1639
1640 if ( ! is_plugin_active( 'classic-editor/classic-editor.php' ) ) {
1641 return true;
1642 }
1643
1644 $use_block_editor = ( get_option( 'classic-editor-replace' ) === 'no-replace' );
1645
1646 return $use_block_editor;
1647 }
1648
1649 }
1650 /**
1651 * Fire up the plugin.
1652 */
1653 BNFW::factory();
1654 }
1655