| 1 | <?php |
|---|
| 2 | /* |
|---|
| 3 | Plugin Name: MJJ BBP Subscription |
|---|
| 4 | Description: Custom subscribe to topic email with unsubscribe link |
|---|
| 5 | Author: Mary (JJ) Jay |
|---|
| 6 | Version: 1 |
|---|
| 7 | */ |
|---|
| 8 | |
|---|
| 9 | //this makes the salt for the check if needed. If there is one, it will not make one. |
|---|
| 10 | register_activation_hook( __FILE__, 'mjj_salt_activate' ); |
|---|
| 11 | |
|---|
| 12 | //custom topic subscription emails |
|---|
| 13 | remove_action( 'bbp_new_reply', 'bbp_notify_subscribers', 11, 5 ); |
|---|
| 14 | add_action( 'bbp_new_reply', 'mjj_bbp_notify_subscribers', 11, 5 ); |
|---|
| 15 | |
|---|
| 16 | //add the one click unsubscribe on the topic itself |
|---|
| 17 | add_action( 'bbp_template_before_single_topic', 'mjj_bbp_unsubscribe_notice' ); |
|---|
| 18 | |
|---|
| 19 | //I don't think activation hooks are allowed return values? |
|---|
| 20 | function mjj_salt_activate(){ |
|---|
| 21 | mjj_get_salt(); |
|---|
| 22 | return; |
|---|
| 23 | } |
|---|
| 24 | |
|---|
| 25 | //let's make a random value and add it to the database so it doesn't change and the links will always work |
|---|
| 26 | function mjj_get_salt() { |
|---|
| 27 | |
|---|
| 28 | $salt = get_option( 'mjj_bbp_unsub_salt' ); |
|---|
| 29 | if( !$salt ){ |
|---|
| 30 | $salt = base64_encode( mcrypt_create_iv(12, MCRYPT_DEV_URANDOM) ); |
|---|
| 31 | //add the salt to the options table, it should not change |
|---|
| 32 | add_option( 'mjj_bbp_unsub_salt', $salt ); |
|---|
| 33 | } |
|---|
| 34 | return $salt; |
|---|
| 35 | |
|---|
| 36 | } |
|---|
| 37 | |
|---|
| 38 | |
|---|
| 39 | function not_a_nonce( $uid, $tid ){ |
|---|
| 40 | //this is used for a quick check that the url hasn't been tampered with. It's not dependent on time or whether or not a user is logged in. |
|---|
| 41 | $salt = mjj_get_salt(); |
|---|
| 42 | //because why not add a little string to it |
|---|
| 43 | $string = $uid . $tid . "user and topic ids"; |
|---|
| 44 | $encrypted = crypt( $string, $salt ); |
|---|
| 45 | return $encrypted; |
|---|
| 46 | |
|---|
| 47 | } |
|---|
| 48 | |
|---|
| 49 | /** |
|---|
| 50 | * from bbpress / includes / common / functions.php |
|---|
| 51 | * this is taken from 2.5.3, except for the unsubsribe stuff |
|---|
| 52 | **/ |
|---|
| 53 | function mjj_bbp_notify_subscribers( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymous_data = false, $reply_author = 0 ) { |
|---|
| 54 | |
|---|
| 55 | // Bail if subscriptions are turned off |
|---|
| 56 | if ( !bbp_is_subscriptions_active() ) |
|---|
| 57 | return false; |
|---|
| 58 | |
|---|
| 59 | /** Validation ************************************************************/ |
|---|
| 60 | |
|---|
| 61 | $reply_id = bbp_get_reply_id( $reply_id ); |
|---|
| 62 | $topic_id = bbp_get_topic_id( $topic_id ); |
|---|
| 63 | $forum_id = bbp_get_forum_id( $forum_id ); |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | /** Reply *****************************************************************/ |
|---|
| 67 | |
|---|
| 68 | // Bail if reply is not published |
|---|
| 69 | if ( !bbp_is_reply_published( $reply_id ) ) |
|---|
| 70 | return false; |
|---|
| 71 | |
|---|
| 72 | /** Topic *****************************************************************/ |
|---|
| 73 | |
|---|
| 74 | // Bail if topic is not published |
|---|
| 75 | if ( !bbp_is_topic_published( $topic_id ) ){ |
|---|
| 76 | return false; |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | $topic_url = bbp_get_topic_permalink( $topic_id ); |
|---|
| 80 | |
|---|
| 81 | /** User ******************************************************************/ |
|---|
| 82 | |
|---|
| 83 | // Get topic subscribers and bail if empty |
|---|
| 84 | $user_ids = bbp_get_topic_subscribers( $topic_id, true ); |
|---|
| 85 | if ( empty( $user_ids ) ) |
|---|
| 86 | return false; |
|---|
| 87 | |
|---|
| 88 | // Poster name |
|---|
| 89 | $reply_author_name = bbp_get_reply_author_display_name( $reply_id ); |
|---|
| 90 | |
|---|
| 91 | /** Mail ******************************************************************/ |
|---|
| 92 | |
|---|
| 93 | do_action( 'bbp_pre_notify_subscribers', $reply_id, $topic_id, $user_ids ); |
|---|
| 94 | |
|---|
| 95 | // Remove filters from reply content and topic title to prevent content |
|---|
| 96 | // from being encoded with HTML entities, wrapped in paragraph tags, etc... |
|---|
| 97 | remove_all_filters( 'bbp_get_reply_content' ); |
|---|
| 98 | remove_all_filters( 'bbp_get_topic_title' ); |
|---|
| 99 | |
|---|
| 100 | // Strip tags from text |
|---|
| 101 | $topic_title = strip_tags( bbp_get_topic_title( $topic_id ) ); |
|---|
| 102 | $reply_content = strip_tags( bbp_get_reply_content( $reply_id ) ); |
|---|
| 103 | $reply_url = $topic_url . '#the-reply-form'; |
|---|
| 104 | $blog_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); |
|---|
| 105 | $admin_email = get_bloginfo( 'admin_email' ); |
|---|
| 106 | |
|---|
| 107 | // Loop through users |
|---|
| 108 | foreach ( (array) $user_ids as $user_id ) { |
|---|
| 109 | |
|---|
| 110 | $nn_link = not_a_nonce( $user_id, $topic_id ); |
|---|
| 111 | $unsubscribe_link = $topic_url . '?uid=' . $user_id . '&tid=' . $topic_id . '&nn=' . $nn_link; |
|---|
| 112 | |
|---|
| 113 | $user_sub_link = bbp_get_user_profile_url( $user_id ) . 'subscriptions/'; |
|---|
| 114 | |
|---|
| 115 | // Don't send notifications to the person who made the post |
|---|
| 116 | if ( !empty( $reply_author ) && (int) $user_id === (int) $reply_author ) |
|---|
| 117 | continue; |
|---|
| 118 | |
|---|
| 119 | // For plugins to filter messages per reply/topic/user |
|---|
| 120 | $message = sprintf( __( 'Hi, |
|---|
| 121 | |
|---|
| 122 | You are receiving this email because you have subscribed to the topic "%6$s." Links to unsubscribe are below. |
|---|
| 123 | |
|---|
| 124 | Please note that unfortunately, you can\'t reply to the topics via email, so you\'ll need to go to the topic on the website here: |
|---|
| 125 | %3$s |
|---|
| 126 | ====== |
|---|
| 127 | |
|---|
| 128 | %1$s wrote on %6$s: |
|---|
| 129 | |
|---|
| 130 | %2$s |
|---|
| 131 | |
|---|
| 132 | ====== |
|---|
| 133 | |
|---|
| 134 | Unsubscribe in one click here: %4$s |
|---|
| 135 | Manage all your subscriptions: %5$s |
|---|
| 136 | If you have any issues, please email %7$s |
|---|
| 137 | ', 'bbpress' ), |
|---|
| 138 | |
|---|
| 139 | $reply_author_name, |
|---|
| 140 | $reply_content, |
|---|
| 141 | $reply_url, |
|---|
| 142 | $unsubscribe_link, |
|---|
| 143 | $user_sub_link, |
|---|
| 144 | $topic_title, |
|---|
| 145 | $admin_email |
|---|
| 146 | ); |
|---|
| 147 | |
|---|
| 148 | $message = apply_filters( 'bbp_subscription_mail_message', $message, $reply_id, $topic_id, $user_id ); |
|---|
| 149 | if ( empty( $message ) ) |
|---|
| 150 | continue; |
|---|
| 151 | |
|---|
| 152 | // For plugins to filter titles per reply/topic/user |
|---|
| 153 | $subject = apply_filters( 'bbp_subscription_mail_title', '[' . $blog_name . '] ' . $topic_title, $reply_id, $topic_id, $user_id ); |
|---|
| 154 | if ( empty( $subject ) ) |
|---|
| 155 | continue; |
|---|
| 156 | |
|---|
| 157 | // Custom headers |
|---|
| 158 | $headers = apply_filters( 'bbp_subscription_mail_headers', array() ); |
|---|
| 159 | |
|---|
| 160 | // Get user data of this user |
|---|
| 161 | $user = get_userdata( $user_id ); |
|---|
| 162 | |
|---|
| 163 | // Send notification email |
|---|
| 164 | wp_mail( $user->user_email, $subject, $message, $headers ); |
|---|
| 165 | } |
|---|
| 166 | |
|---|
| 167 | do_action( 'bbp_post_notify_subscribers', $reply_id, $topic_id, $user_ids ); |
|---|
| 168 | |
|---|
| 169 | return true; |
|---|
| 170 | } |
|---|
| 171 | |
|---|
| 172 | //this function does the work of the unsubscribing and also gives a little template notice. It's on the topic in question - I thought about putting it on the user profile page but don't want to give out that info if the url is shared |
|---|
| 173 | function mjj_bbp_unsubscribe_notice(){ |
|---|
| 174 | |
|---|
| 175 | global $post; |
|---|
| 176 | |
|---|
| 177 | $topic_id = ( isset( $_GET['tid'] ) && !empty($_GET['tid'] ) ? $_GET['tid'] : '' ); |
|---|
| 178 | $user_id = ( isset( $_GET['uid'] ) && !empty($_GET['uid'] ) ? $_GET['uid'] : '' ); |
|---|
| 179 | $to_check = ( isset( $_GET['nn'] ) && !empty($_GET['nn'] ) ? $_GET['nn'] : '' ); |
|---|
| 180 | $check = not_a_nonce( $user_id, $topic_id ); |
|---|
| 181 | |
|---|
| 182 | $current_user = wp_get_current_user(); |
|---|
| 183 | |
|---|
| 184 | //are there any of the query vars? If not, return |
|---|
| 185 | if( !$topic_id && !$user_id && !$to_check ){ |
|---|
| 186 | return; |
|---|
| 187 | } |
|---|
| 188 | //if you fail the check, it doesn't work. Also it has to be on the right topic. |
|---|
| 189 | elseif( $to_check != $check || $post->ID != $topic_id ){ |
|---|
| 190 | $message = 'Something has gone wrong. You can manage your subscriptions from your profile.'; |
|---|
| 191 | } |
|---|
| 192 | //if you are logged in and using someone else's link, it won't work for you (or unsubscribe them) so you get a link to your subscriptions page |
|---|
| 193 | elseif( $current_user && $current_user-> ID != $user_id ){ |
|---|
| 194 | |
|---|
| 195 | $subscriptions_link = bbp_get_user_profile_url( $current_user->ID ) . 'subscriptions/'; |
|---|
| 196 | $message = 'Unsubscribe links are unique to each user of the forum.<br />This link can’t be used for you to unsubscribe, but you can manage all your subscriptions <a href="' . $subscriptions_link . '">here</a>'; |
|---|
| 197 | |
|---|
| 198 | } |
|---|
| 199 | //what else haven't I thought about? add anything I've forgotten here. If you are not logged in, you can still unsubscribe. That's ok. Better accidental unsubscriptions than people not being able to unsubscribe. |
|---|
| 200 | else{ |
|---|
| 201 | |
|---|
| 202 | bbp_remove_user_subscription( $user_id, $topic_id ); |
|---|
| 203 | $message = 'You have been unsubscribed from this topic.'; |
|---|
| 204 | |
|---|
| 205 | } |
|---|
| 206 | |
|---|
| 207 | echo '<div class="bbp-template-notice">'; |
|---|
| 208 | echo $message; |
|---|
| 209 | echo '</div>'; |
|---|
| 210 | |
|---|
| 211 | return; |
|---|
| 212 | |
|---|
| 213 | } |
|---|