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

528 lines 15.2 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 WordPress
4 * Plugin URI: http://wordpress.org/plugins/bnfw/
5 * Description: Send customisable emails to your users for different WordPress notifications.
6 * Version: 1.4
7 * Author: Voltronik
8 * Author URI: https://betternotificationsforwp.com/
9 * Author Email: hello@betternotificationsforwp.com
10 * License: GPLv2 or later
11 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
12 * Text Domain: bnfw
13 * Domain Path: /languages
14 */
15
16 /**
17 * Copyright © 2015 Voltronik (plugins@voltronik.co.uk)
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License, version 2, as
20 * published by the Free Software Foundation.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29 class BNFW {
30
31 /**
32 * Constructor.
33 *
34 * @since 1.0
35 */
36 function __construct() {
37 $this->load_textdomain();
38 $this->includes();
39 $this->hooks();
40
41 $this->notifier = new BNFW_Notification;
42 $this->engine = new BNFW_Engine;
43 }
44
45 /**
46 * Factory method to return the instance of the class.
47 *
48 * Makes sure that only one instance is created.
49 *
50 * @return object Instance of the class
51 */
52 public static function factory() {
53 static $instance = false;
54 if ( ! $instance ) {
55 $instance = new self();
56 }
57 return $instance;
58 }
59
60 /**
61 * Loads the plugin language files
62 *
63 * @since 1.0
64 */
65 public function load_textdomain() {
66 // Load localization domain
67 $this->translations = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
68 load_plugin_textdomain( 'bnfw', false, $this->translations );
69 }
70
71 /**
72 * Include required files.
73 *
74 * @since 1.0
75 */
76 public function includes() {
77
78 // Load license related classes
79 if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
80 require_once 'includes/libraries/EDD_SL_Plugin_Updater.php';
81 }
82 require_once 'includes/license/class-bnfw-license.php';
83 require_once 'includes/license/class-bnfw-license-setting.php';
84
85 // Load Engine
86 require_once 'includes/engine/class-bnfw-engine.php';
87 require_once 'includes/overrides.php';
88
89 // Load notification post type and notification helpers
90 require_once 'includes/admin/class-bnfw-notification.php';
91 require_once 'includes/notification/post-notification.php';
92
93 // Helpers
94 require_once 'includes/helpers/helpers.php';
95 require_once 'includes/helpers/ajax-helpers.php';
96
97 // Load Admin Pages
98 if ( is_admin() ) {
99 require_once 'includes/admin/bnfw-settings.php';
100 }
101 }
102
103 /**
104 * Register Hooks.
105 *
106 * @since 1.0
107 */
108 public function hooks() {
109 global $wp_version;
110
111 register_activation_hook( __FILE__ , array( $this, 'activate' ) );
112
113 // Some themes like P2, directly insert posts into DB.
114 $insert_post_themes = apply_filters( 'bnfw_insert_post_themes', array( 'P2', 'Syncope' ) );
115 $current_theme = wp_get_theme();
116
117 /**
118 * Whether to trigger insert post hook.
119 *
120 * @since 1.4
121 */
122 $trigger_insert_post = apply_filters( 'bnfw_trigger_insert_post', false );
123
124 if ( in_array( $current_theme, $insert_post_themes ) || $trigger_insert_post ) {
125 add_action( 'wp_insert_post' , array( $this, 'insert_post' ), 10, 3 );
126 }
127
128 add_action( 'draft_to_publish' , array( $this, 'publish_post' ) );
129 add_action( 'future_to_publish' , array( $this, 'publish_post' ) );
130 add_action( 'pending_to_publish' , array( $this, 'publish_post' ) );
131 add_action( 'private_to_publish' , array( $this, 'publish_post' ) );
132 add_action( 'publish_to_publish' , array( $this, 'update_post' ) );
133 add_action( 'init' , array( $this, 'custom_post_type_hooks' ), 100 );
134 add_action( 'create_term' , array( $this, 'create_term' ), 10, 3 );
135
136 add_action( 'comment_post' , array( $this, 'comment_post' ) );
137 add_action( 'trackback_post' , array( $this, 'trackback_post' ) );
138 add_action( 'pingback_post' , array( $this, 'pingback_post' ) );
139
140 add_action( 'user_register' , array( $this, 'user_register' ) );
141 add_action( 'user_register' , array( $this, 'welcome_email' ) );
142 add_action( 'set_user_role' , array( $this, 'user_role_changed' ), 10, 3 );
143
144 if ( version_compare( $wp_version, '4.4', '>=' ) ) {
145 add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ), 10, 3 );
146 } else {
147 add_filter( 'retrieve_password_title', array( $this, 'change_password_email_title' ) );
148 }
149 add_action( 'lostpassword_post' , array( $this, 'on_lost_password' ) );
150 add_filter( 'retrieve_password_message' , array( $this, 'change_password_email_message' ), 10, 4 );
151
152 add_filter( 'plugin_action_links' , array( $this, 'plugin_action_links' ), 10, 4 );
153 add_action( 'shutdown' , array( $this, 'on_shutdown' ) );
154 }
155
156 /**
157 * Setup hooks for custom post types.
158 *
159 * @since 1.2
160 */
161 function custom_post_type_hooks() {
162 $post_types = get_post_types( array( 'public' => true ), 'names' );
163 $post_types = array_diff( $post_types, array( BNFW_Notification::POST_TYPE ) );
164
165 foreach ( $post_types as $post_type ) {
166 add_action( 'pending_' . $post_type, array( $this, 'on_post_pending' ), 10, 2 );
167 add_action( 'future_' . $post_type, array( $this, 'on_post_scheduled' ), 10, 2 );
168 }
169 }
170
171 /**
172 * importer
173 */
174 public function activate() {
175 require_once dirname( __FILE__ ) . '/includes/import.php';
176 $importer = new BNFW_Import;
177 $importer->import();
178 }
179
180 /**
181 * Add 'Settings' link below BNFW in Plugins list.
182 *
183 * @since 1.0
184 * @param unknown $links
185 * @param unknown $file
186 * @return unknown
187 */
188 public function plugin_action_links( $links, $file ) {
189 $plugin_file = 'bnfw/bnfw.php';
190 if ( $file == $plugin_file ) {
191 $settings_link = '<a href="' . admin_url( 'edit.php?post_type=bnfw_notification&page=bnfw-settings' ) . '">' . 'Settings' . '</a>';
192 array_unshift( $links, $settings_link );
193 }
194 return $links;
195 }
196
197 /**
198 * When a new term is created.
199 *
200 * @since 1.0
201 * @param int $term_id
202 * @param int $tt_id
203 * @param string $taxonomy
204 */
205 public function create_term( $term_id, $tt_id, $taxonomy ) {
206 $this->send_notification( 'newterm-' . $taxonomy, $term_id );
207 }
208
209 /**
210 * Fires when a post is created for the first time.
211 *
212 * @since 1.3.1
213 * @param int $post_id Post ID
214 * @param object $post Post object
215 * @param bool $update Whether it was an update
216 */
217 public function insert_post( $post_id, $post, $update ) {
218 $this->publish_post( $post );
219 }
220
221 /**
222 * Fires when a post is created for the first time.
223 *
224 * @since 1.0
225 * @param object $post Post Object
226 */
227 function publish_post( $post ) {
228 $post_id = $post->ID;
229 $post_type = $post->post_type;
230
231 if ( BNFW_Notification::POST_TYPE != $post_type ) {
232 $this->send_notification_async( 'new-' . $post_type, $post_id );
233 }
234 }
235
236 /**
237 * Fires when a post is updated.
238 *
239 * @since 1.0
240 * @param unknown $post
241 */
242 function update_post( $post ) {
243 $post_id = $post->ID;
244 $post_type = $post->post_type;
245
246 if ( BNFW_Notification::POST_TYPE != $post_type ) {
247 $this->send_notification_async( 'update-' . $post_type, $post_id );
248 }
249 }
250
251 /**
252 * Fires when a post is pending for review.
253 *
254 * @since 1.1
255 * @param int $post_id Post ID
256 * @param object $post Post object
257 */
258 function on_post_pending( $post_id, $post ) {
259 $post_type = $post->post_type;
260
261 if ( BNFW_Notification::POST_TYPE != $post_type ) {
262 $this->send_notification_async( 'pending-' . $post_type, $post_id );
263 }
264 }
265
266 /**
267 * Fires when a post is scheduled.
268 *
269 * @since 1.1.5
270 * @param int $post_id Post ID
271 * @param object $post Post object
272 */
273 function on_post_scheduled( $post_id, $post ) {
274 $post_type = $post->post_type;
275
276 if ( BNFW_Notification::POST_TYPE != $post_type ) {
277 $this->send_notification_async( 'future-' . $post_type, $post_id );
278 }
279 }
280
281 /**
282 * Send notification for new comments
283 *
284 * @since 1.0
285 * @param int $comment_id
286 */
287 function comment_post( $comment_id ) {
288 $the_comment = get_comment( $comment_id );
289 if ( $this->can_send_comment_notification( $the_comment ) ) {
290 $post = get_post( $the_comment->comment_post_ID );
291 $notification_type = 'new-comment'; // old notification name
292 if ( 'post' != $post->post_type ) {
293 $notification_type = 'comment-' . $post->post_type;
294 }
295 $this->send_notification( $notification_type, $comment_id );
296
297 // comment reply notification.
298 if ( $the_comment->comment_parent > 0 ) {
299 $notifications = $this->notifier->get_notifications( 'reply-comment' );
300 if ( count( $notifications ) > 0 ) {
301 $parent = get_comment( $the_comment->comment_parent );
302 if ( $parent->comment_author_email != $the_comment->comment_author_email ) {
303 foreach ( $notifications as $notification ) {
304 $this->engine->send_comment_reply_email( $this->notifier->read_settings( $notification->ID ), $the_comment, $parent );
305 }
306 }
307 }
308 }
309 }
310 }
311
312 /**
313 * Send notification for new trackback
314 *
315 * @since 1.0
316 * @param unknown $comment_id
317 */
318 function trackback_post( $comment_id ) {
319 $the_comment = get_comment( $comment_id );
320 if ( $this->can_send_comment_notification( $the_comment ) ) {
321 $this->send_notification( 'new-trackback', $comment_id );
322 }
323 }
324
325 /**
326 * Send notification for new pingbacks
327 *
328 * @since 1.0
329 * @param unknown $comment_id
330 */
331 function pingback_post( $comment_id ) {
332 $the_comment = get_comment( $comment_id );
333 if ( $this->can_send_comment_notification( $the_comment ) ) {
334 $this->send_notification( 'new-pingback', $comment_id );
335 }
336 }
337
338 /**
339 * Send notification for lost password.
340 *
341 * @since 1.0
342 */
343 function on_lost_password() {
344 $user = get_user_by( 'login', trim( $_POST['user_login'] ) );
345 if ( $user ) {
346 $this->send_notification( 'admin-password', $user->ID );
347 }
348 }
349
350 /**
351 * Change the title of the password reset email that is sent to the user.
352 *
353 * @since 1.1
354 */
355 public function change_password_email_title( $title, $user_login = '', $user_data = '' ) {
356 $notifications = $this->notifier->get_notifications( 'user-password' );
357 if ( count( $notifications ) > 0 ) {
358 // Ideally there should be only one notification for this type.
359 // If there are multiple notification then we will read data about only the last one
360 $setting = $this->notifier->read_settings( end( $notifications )->ID );
361
362 if ( '' === $user_data ) {
363 return $this->engine->user_shortcodes( $setting['subject'], $user_data->ID );
364
365 } else {
366 return $setting['subject'];
367 }
368 }
369
370 return $title;
371 }
372
373 /**
374 * Change the message of the password reset email.
375 *
376 * @since 1.1
377 */
378 public function change_password_email_message( $message, $key, $user_login = '', $user_data = '' ) {
379 $notifications = $this->notifier->get_notifications( 'user-password' );
380 if ( count( $notifications ) > 0 ) {
381 // Ideally there should be only one notification for this type.
382 // If there are multiple notification then we will read data about only the last one
383 $setting = $this->notifier->read_settings( end( $notifications )->ID );
384
385 if ( 'html' == $setting['email-formatting'] ) {
386 add_filter( 'wp_mail_content_type', array( $this, 'set_html_content_type' ) );
387 } else {
388 add_filter( 'wp_mail_content_type', array( $this, 'set_text_content_type' ) );
389 }
390
391 return $this->engine->handle_password_reset_shortcodes( $setting, $key, $user_login, $user_data );
392 }
393
394 return $message;
395 }
396
397 /**
398 * Set the email formatting to HTML.
399 *
400 * @since 1.4
401 */
402 public function set_html_content_type() {
403 return 'text/html';
404 }
405
406 /**
407 * Set the email formatting to text.
408 *
409 * @since 1.4
410 */
411 public function set_text_content_type() {
412 return 'text/plain';
413 }
414
415 /**
416 * Send notification for new users.
417 *
418 * @since 1.0
419 * @param int $user_id
420 */
421 function user_register( $user_id ) {
422 $this->send_notification( 'admin-user', $user_id );
423 }
424
425 /**
426 * New User - Post-registration Email
427 *
428 * @since 1.1
429 * @param int $user_id New user id
430 */
431 function welcome_email( $user_id ) {
432 $notifications = $this->notifier->get_notifications( 'welcome-email' );
433 foreach ( $notifications as $notification ) {
434 $this->engine->send_registration_email( $this->notifier->read_settings( $notification->ID ), get_userdata( $user_id ) );
435 }
436 }
437
438 /**
439 * Send notification when a user role changes.
440 *
441 * @since 1.3.9
442 * @param int $user_id User ID
443 * @param string $new_role New User role
444 * @param string $old_role Old User role
445 */
446 public function user_role_changed( $user_id, $new_role, $old_role ) {
447 if ( ! empty( $old_role ) ) {
448 $notifications = $this->notifier->get_notifications( 'user-role' );
449 foreach ( $notifications as $notification ) {
450 $this->engine->send_user_role_changed_email( $this->notifier->read_settings( $notification->ID ), $user_id );
451 }
452 }
453 }
454
455 /**
456 * Send notification based on type and ref id
457 *
458 * @access private
459 * @since 1.0
460 * @param string $type Notification type.
461 * @param int $ref_id Reference id.
462 */
463 private function send_notification( $type, $ref_id ) {
464 $notifications = $this->notifier->get_notifications( $type );
465 foreach ( $notifications as $notification ) {
466 $this->engine->send_notification( $this->notifier->read_settings( $notification->ID ), $ref_id );
467 }
468 }
469
470 /**
471 * Send notification async based on type and ref id.
472 *
473 * @access private
474 * @param string $type Notification type.
475 * @param int $ref_id Reference id.
476 */
477 private function send_notification_async( $type, $ref_id ) {
478 $notifications = $this->notifier->get_notifications( $type );
479 foreach ( $notifications as $notification ) {
480 $transient = get_transient( 'bnfw-async-notifications' );
481 if ( ! is_array( $transient ) ) {
482 $transient = array();
483 }
484
485 $transient[] = array( 'ref_id' => $ref_id, 'notification_id' => $notification->ID, 'notification_type' => $type );
486 set_transient( 'bnfw-async-notifications', $transient, 600 );
487 }
488 }
489
490 /**
491 * Can send comment notification or not
492 *
493 * @since 1.0
494 * @param unknown $comment
495 * @return unknown
496 */
497 private function can_send_comment_notification( $comment ) {
498 // Returns false if the comment is marked as spam AND admin has enabled suppression of spam
499 $suppress_spam = get_option( 'bnfw_suppress_spam' );
500 if ( '1' === $suppress_spam && ( 0 === strcmp( $comment->comment_approved, 'spam' ) ) ) {
501 return false;
502 }
503 return true;
504 }
505
506 /**
507 * Send notification emails on shutdown.
508 */
509 public function on_shutdown() {
510 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
511 return;
512 }
513
514 $transient = get_transient( 'bnfw-async-notifications' );
515 if ( is_array( $transient ) ) {
516 foreach ( $transient as $id_pairs ) {
517 $this->engine->send_notification( $this->notifier->read_settings( $id_pairs['notification_id'] ), $id_pairs['ref_id'] );
518 }
519 delete_transient( 'bnfw-async-notifications' );
520 }
521 }
522 }
523
524 /* ------------------------------------------------------------------------ *
525 * Fire up the plugin
526 * ------------------------------------------------------------------------ */
527 BNFW::factory();
528