| 1 | <?php |
|---|
| 2 | |
|---|
| 3 | /** |
|---|
| 4 | * bbPress BuddyPress Notifications. |
|---|
| 5 | * |
|---|
| 6 | * @package bbPress |
|---|
| 7 | * @subpackage BuddyPress |
|---|
| 8 | */ |
|---|
| 9 | |
|---|
| 10 | // Exit if accessed directly |
|---|
| 11 | defined( 'ABSPATH' ) || exit; |
|---|
| 12 | |
|---|
| 13 | // Hooks |
|---|
| 14 | add_filter( 'bp_notifications_get_registered_components', 'bbp_filter_notifications_get_registered_components', 10 ); |
|---|
| 15 | add_filter( 'bp_notifications_get_notifications_for_user', 'bbp_format_buddypress_notifications', 10, 8 ); |
|---|
| 16 | add_action( 'bbp_new_reply', 'bbp_buddypress_add_notification', 10, 7 ); |
|---|
| 17 | add_action( 'bbp_get_request', 'bbp_buddypress_mark_notifications', 1 ); |
|---|
| 18 | |
|---|
| 19 | /** BuddyPress Helpers ********************************************************/ |
|---|
| 20 | |
|---|
| 21 | /** |
|---|
| 22 | * Filter registered notifications components, and add 'forums' to the queried |
|---|
| 23 | * 'component_name' array. |
|---|
| 24 | * |
|---|
| 25 | * @since 2.6.0 bbPress (r5232) |
|---|
| 26 | * |
|---|
| 27 | * @see BP_Notifications_Notification::get() |
|---|
| 28 | * @param array $component_names |
|---|
| 29 | * @return array |
|---|
| 30 | */ |
|---|
| 31 | function bbp_filter_notifications_get_registered_components( $component_names = array() ) { |
|---|
| 32 | |
|---|
| 33 | // Force $component_names to be an array |
|---|
| 34 | if ( ! is_array( $component_names ) ) { |
|---|
| 35 | $component_names = array(); |
|---|
| 36 | } |
|---|
| 37 | |
|---|
| 38 | // Add 'forums' component to registered components array |
|---|
| 39 | array_push( $component_names, bbp_get_component_name() ); |
|---|
| 40 | |
|---|
| 41 | // Return component's with 'forums' appended |
|---|
| 42 | return $component_names; |
|---|
| 43 | } |
|---|
| 44 | |
|---|
| 45 | /** |
|---|
| 46 | * Format the BuddyBar/Toolbar notifications. |
|---|
| 47 | * |
|---|
| 48 | * @since 2.5.0 bbPress (r5155) |
|---|
| 49 | * |
|---|
| 50 | * @package bbPress |
|---|
| 51 | * |
|---|
| 52 | * @param string $content Component action. Deprecated. Do not do checks against this! Use |
|---|
| 53 | * the 6th parameter instead - $component_action_name. |
|---|
| 54 | * @param int $item_id Notification item ID. |
|---|
| 55 | * @param int $secondary_item_id Notification secondary item ID. |
|---|
| 56 | * @param int $action_item_count Number of notifications with the same action. |
|---|
| 57 | * @param string $format Format of return. Either 'string' or 'object'. |
|---|
| 58 | * @param string $component_action_name Canonical notification action. |
|---|
| 59 | * @param string $component_name Notification component ID. |
|---|
| 60 | * @param int $id Notification ID. |
|---|
| 61 | */ |
|---|
| 62 | function bbp_format_buddypress_notifications( $content, $item_id, $secondary_item_id, $action_item_count, $format, $component_action_name, $component_name, $id ) { |
|---|
| 63 | |
|---|
| 64 | // Bail if not the notification action we are looking for |
|---|
| 65 | if ( 0 !== strpos( $component_action_name, 'bbp_new_reply' ) ) { |
|---|
| 66 | return $content; |
|---|
| 67 | } |
|---|
| 68 | |
|---|
| 69 | // New reply notifications |
|---|
| 70 | $topic_id = bbp_get_reply_topic_id( $item_id ); |
|---|
| 71 | $topic_title = bbp_get_topic_title( $topic_id ); |
|---|
| 72 | $topic_link = wp_nonce_url( |
|---|
| 73 | add_query_arg( |
|---|
| 74 | array( |
|---|
| 75 | 'action' => 'bbp_mark_read', |
|---|
| 76 | 'topic_id' => $topic_id |
|---|
| 77 | ), |
|---|
| 78 | bbp_get_reply_url( $item_id ) |
|---|
| 79 | ), |
|---|
| 80 | 'bbp_mark_topic_' . $topic_id |
|---|
| 81 | ); |
|---|
| 82 | |
|---|
| 83 | // Cast to int |
|---|
| 84 | $action_item_count = (int) $action_item_count; |
|---|
| 85 | |
|---|
| 86 | // Multiple replies |
|---|
| 87 | if ( $action_item_count > 1 ) { |
|---|
| 88 | $filter = 'bbp_multiple_new_subscription_notification'; |
|---|
| 89 | $text = sprintf( |
|---|
| 90 | /* translators: 1: Number of replies, 2: Topic title */ |
|---|
| 91 | esc_html__( 'You have %1$d new replies to %2$s', 'bbpress' ), |
|---|
| 92 | $action_item_count, |
|---|
| 93 | $topic_title |
|---|
| 94 | ); |
|---|
| 95 | |
|---|
| 96 | // Single reply |
|---|
| 97 | } else { |
|---|
| 98 | $filter = 'bbp_single_new_subscription_notification'; |
|---|
| 99 | |
|---|
| 100 | if ( ! empty( $secondary_item_id ) ) { |
|---|
| 101 | $text = sprintf( |
|---|
| 102 | /* translators: 1: Number of replies, 2: Topic title, 3: Reply author name */ |
|---|
| 103 | esc_html__( 'You have %1$d new reply to %2$s from %3$s', 'bbpress' ), |
|---|
| 104 | $action_item_count, |
|---|
| 105 | $topic_title, |
|---|
| 106 | bp_core_get_user_displayname( $secondary_item_id ) |
|---|
| 107 | ); |
|---|
| 108 | } else { |
|---|
| 109 | $text = sprintf( |
|---|
| 110 | /* translators: 1: Number of replies, 2: Topic title */ |
|---|
| 111 | esc_html__( 'You have %1$d new reply to %2$s', 'bbpress' ), |
|---|
| 112 | $action_item_count, |
|---|
| 113 | $topic_title |
|---|
| 114 | ); |
|---|
| 115 | } |
|---|
| 116 | } |
|---|
| 117 | |
|---|
| 118 | // WordPress Toolbar |
|---|
| 119 | if ( 'string' === $format ) { |
|---|
| 120 | $value = '<a href="' . esc_url( $topic_link ) . '" title="' . esc_attr__( 'Topic Replies', 'bbpress' ) . '">' . esc_html( $text ) . '</a>'; |
|---|
| 121 | |
|---|
| 122 | // Deprecated BuddyBar |
|---|
| 123 | } else { |
|---|
| 124 | $value = array( |
|---|
| 125 | 'text' => $text, |
|---|
| 126 | 'link' => $topic_link |
|---|
| 127 | ); |
|---|
| 128 | } |
|---|
| 129 | |
|---|
| 130 | // Filter the return value |
|---|
| 131 | $retval = apply_filters( $filter, $value, $action_item_count, $text, $topic_link ); |
|---|
| 132 | |
|---|
| 133 | do_action( 'bbp_format_buddypress_notifications', $component_action_name, $item_id, $secondary_item_id, $action_item_count, $format, $component_action_name, $component_name, $id ); |
|---|
| 134 | |
|---|
| 135 | // Return |
|---|
| 136 | return $retval; |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | /** |
|---|
| 140 | * Hooked into the new reply function, this notification action is responsible |
|---|
| 141 | * for notifying topic and hierarchical reply authors of topic replies. |
|---|
| 142 | * |
|---|
| 143 | * @since 2.5.0 bbPress (r5156) |
|---|
| 144 | * |
|---|
| 145 | * @param int $reply_id |
|---|
| 146 | * @param int $topic_id |
|---|
| 147 | * @param int $forum_id (not used) |
|---|
| 148 | * @param array $anonymous_data (not used) |
|---|
| 149 | * @param int $author_id |
|---|
| 150 | * @param bool $is_edit Used to bail if this gets hooked to an edit action |
|---|
| 151 | * @param int $reply_to |
|---|
| 152 | */ |
|---|
| 153 | function bbp_buddypress_add_notification( $reply_id = 0, $topic_id = 0, $forum_id = 0, $anonymous_data = array(), $author_id = 0, $is_edit = false, $reply_to = 0 ) { |
|---|
| 154 | |
|---|
| 155 | // Bail if somehow this is hooked to an edit action |
|---|
| 156 | if ( ! empty( $is_edit ) ) { |
|---|
| 157 | return; |
|---|
| 158 | } |
|---|
| 159 | |
|---|
| 160 | // Get author information |
|---|
| 161 | $topic_author_id = bbp_get_topic_author_id( $topic_id ); |
|---|
| 162 | $secondary_item_id = $author_id; |
|---|
| 163 | |
|---|
| 164 | // Hierarchical replies |
|---|
| 165 | if ( ! empty( $reply_to ) ) { |
|---|
| 166 | $reply_to_item_id = bbp_get_topic_author_id( $reply_to ); |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | // Get some reply information |
|---|
| 170 | $args = array( |
|---|
| 171 | 'user_id' => $topic_author_id, |
|---|
| 172 | 'item_id' => $reply_id, |
|---|
| 173 | 'component_name' => bbp_get_component_name(), |
|---|
| 174 | 'component_action' => 'bbp_new_reply_' . $topic_id, |
|---|
| 175 | 'date_notified' => get_post( $reply_id )->post_date, |
|---|
| 176 | ); |
|---|
| 177 | |
|---|
| 178 | // Notify the topic author if not the current reply author |
|---|
| 179 | if ( $author_id !== $topic_author_id ) { |
|---|
| 180 | $args['secondary_item_id'] = $secondary_item_id; |
|---|
| 181 | |
|---|
| 182 | bp_notifications_add_notification( $args ); |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 185 | // Notify the immediate reply author if not the current reply author |
|---|
| 186 | if ( ! empty( $reply_to ) && ( $author_id !== $reply_to_item_id ) ) { |
|---|
| 187 | $args['user_id'] = $reply_to_item_id; |
|---|
| 188 | $args['secondary_item_id'] = $topic_author_id; |
|---|
| 189 | |
|---|
| 190 | bp_notifications_add_notification( $args ); |
|---|
| 191 | } |
|---|
| 192 | } |
|---|
| 193 | |
|---|
| 194 | /** |
|---|
| 195 | * Mark notifications as read when reading a topic. |
|---|
| 196 | * |
|---|
| 197 | * @since 2.5.0 bbPress (r5155) |
|---|
| 198 | * |
|---|
| 199 | * @return If not trying to mark a notification as read. |
|---|
| 200 | */ |
|---|
| 201 | function bbp_buddypress_mark_notifications( $action = '' ) { |
|---|
| 202 | |
|---|
| 203 | // Bail if no topic ID is passed |
|---|
| 204 | if ( empty( $_GET['topic_id'] ) ) { |
|---|
| 205 | return; |
|---|
| 206 | } |
|---|
| 207 | |
|---|
| 208 | // Bail if action is not for this function |
|---|
| 209 | if ( 'bbp_mark_read' !== $action ) { |
|---|
| 210 | return; |
|---|
| 211 | } |
|---|
| 212 | |
|---|
| 213 | // Get required data |
|---|
| 214 | $user_id = bp_loggedin_user_id(); |
|---|
| 215 | $topic_id = absint( $_GET['topic_id'] ); |
|---|
| 216 | |
|---|
| 217 | // By default, Redirect to this topic ID |
|---|
| 218 | $redirect_id = $topic_id; |
|---|
| 219 | |
|---|
| 220 | // Check nonce |
|---|
| 221 | if ( ! bbp_verify_nonce_request( 'bbp_mark_topic_' . $topic_id ) ) { |
|---|
| 222 | bbp_add_error( 'bbp_notification_topic_id', __( '<strong>Error</strong>: Are you sure you wanted to do that?', 'bbpress' ) ); |
|---|
| 223 | |
|---|
| 224 | // Check current user's ability to edit the user |
|---|
| 225 | } elseif ( ! current_user_can( 'edit_user', $user_id ) ) { |
|---|
| 226 | bbp_add_error( 'bbp_notification_permission', __( '<strong>Error</strong>: You do not have permission to mark notifications for that user.', 'bbpress' ) ); |
|---|
| 227 | } |
|---|
| 228 | |
|---|
| 229 | // Bail if we have errors |
|---|
| 230 | if ( ! bbp_has_errors() ) { |
|---|
| 231 | |
|---|
| 232 | // Default to nothing marked |
|---|
| 233 | $reply_marked = $topic_marked = $marked = false; |
|---|
| 234 | |
|---|
| 235 | // Get these once |
|---|
| 236 | $post_type = bbp_get_reply_post_type(); |
|---|
| 237 | $component = bbp_get_component_name(); |
|---|
| 238 | $c_action = 'bbp_new_reply_' . $topic_id; |
|---|
| 239 | |
|---|
| 240 | // Get all reply IDs for the topic |
|---|
| 241 | $replies = bbp_get_all_child_ids( $topic_id, $post_type ); |
|---|
| 242 | |
|---|
| 243 | // If topic has replies |
|---|
| 244 | if ( ! empty( $replies ) ) { |
|---|
| 245 | |
|---|
| 246 | // Loop through each reply and attempt to mark it |
|---|
| 247 | foreach ( $replies as $reply_id ) { |
|---|
| 248 | |
|---|
| 249 | // Attempt to clear notification for this user & reply ID |
|---|
| 250 | $reply_marked = bp_notifications_mark_notifications_by_item_id( $user_id, $reply_id, $component, $c_action ); |
|---|
| 251 | |
|---|
| 252 | // If marked, redirect to this reply ID |
|---|
| 253 | if ( ! empty( $reply_marked ) ) { |
|---|
| 254 | $redirect_id = $reply_id; |
|---|
| 255 | } |
|---|
| 256 | } |
|---|
| 257 | } |
|---|
| 258 | |
|---|
| 259 | // Attempt to clear notifications for this user & topic |
|---|
| 260 | $topic_marked = bp_notifications_mark_notifications_by_type( $user_id, $component, $c_action ); |
|---|
| 261 | |
|---|
| 262 | // Maybe combine updated/marked rows |
|---|
| 263 | if ( is_numeric( $topic_marked ) || is_numeric( $reply_marked ) ) { |
|---|
| 264 | $marked = (int) $topic_marked + (int) $reply_marked; |
|---|
| 265 | } |
|---|
| 266 | |
|---|
| 267 | // Do additional subscriptions actions |
|---|
| 268 | do_action( 'bbp_notifications_handler', $marked, $user_id, $topic_id, $action ); |
|---|
| 269 | } |
|---|
| 270 | |
|---|
| 271 | // Redirect to the topic |
|---|
| 272 | $redirect = bbp_get_reply_url( $redirect_id ); |
|---|
| 273 | |
|---|
| 274 | // Redirect |
|---|
| 275 | bbp_redirect( $redirect ); |
|---|
| 276 | } |
|---|