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

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