Ticket #7130: 7130.diff
File 7130.diff, 17.0 KB (added by , 8 years ago) |
---|
-
src/bp-notifications/bp-notifications-cache.php
38 38 * Clear all notifications cache for a given user ID. 39 39 * 40 40 * @since 2.3.0 41 * @since 2.9.0 cleans unread_notification cache and grouped_notifications 41 42 * 42 43 * @param int $user_id The user ID's cache to clear. 43 44 */ 44 45 function bp_notifications_clear_all_for_user_cache( $user_id = 0 ) { 45 46 wp_cache_delete( 'all_for_user_' . $user_id, 'bp_notifications' ); 47 wp_cache_delete( 'grouped_notifications_for_user_' . $user_id, 'bp_notifications' ); 48 wp_cache_delete( 'unread_notification_count_for_user_' . $user_id, 'bp_notifications' ); 46 49 } 47 50 48 51 /** -
src/bp-notifications/bp-notifications-functions.php
163 163 } 164 164 165 165 /** 166 * Get latest notifications based on component_action 167 * 168 * @since 2.9.0 169 * 170 * @param int $user_id 171 * 172 * @return array $notifications 173 */ 174 function bp_notifications_get_grouped_notifications_for_user( $user_id = 0 ) { 175 176 if ( empty( $user_id ) ) { 177 $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id(); 178 } 179 180 $notifications = wp_cache_get( 'grouped_notifications_for_user_' . $user_id, 'bp_notifications' ); 181 if ( false === $notifications ) { 182 $notifications = BP_Notifications_Notification::get_grouped_notifications_for_user( $user_id ); 183 wp_cache_set( 'grouped_notifications_for_user_' . $user_id, $notifications, 'bp_notifications' ); 184 } 185 186 return $notifications; 187 } 188 189 /** 166 190 * Get notifications for a specific user. 167 191 * 168 192 * @since 1.9.0 … … 173 197 * @return mixed Object or array on success, false on failure. 174 198 */ 175 199 function bp_notifications_get_notifications_for_user( $user_id, $format = 'string' ) { 176 177 // Setup local variables.178 200 $bp = buddypress(); 179 201 180 // Get notifications (out of the cache, or query if necessary). 181 $notifications = bp_notifications_get_all_notifications_for_user( $user_id ); 182 $grouped_notifications = array(); // Notification groups. 183 $renderable = array(); // Renderable notifications. 202 $notifications = bp_notifications_get_grouped_notifications_for_user( $user_id ); 184 203 185 // Group notifications by component and component_action and provide totals.186 for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) {187 $notification = $notifications[$i];188 $grouped_notifications[$notification->component_name][$notification->component_action][] = $notification;189 }190 191 // Bail if no notification groups.192 if ( empty( $grouped_notifications ) ) {193 return false;194 }195 196 204 // Calculate a renderable output for each notification type. 197 foreach ( $ grouped_notifications as $component_name => $action_arrays) {205 foreach ( $notifications as $notification_item ) { 198 206 207 $component_name = $notification_item->component_name; 199 208 // We prefer that extended profile component-related notifications use 200 209 // the component_name of 'xprofile'. However, the extended profile child 201 210 // object in the $bp object is keyed as 'profile', which is where we need 202 211 // to look for the registered notification callback. 203 if ( 'xprofile' == $ component_name ) {212 if ( 'xprofile' == $notification_item->component_name ) { 204 213 $component_name = 'profile'; 205 214 } 206 215 207 // Skip if group is empty. 208 if ( empty( $action_arrays ) ) { 209 continue; 210 } 216 // Callback function exists. 217 if ( isset( $bp->{$component_name}->notification_callback ) && is_callable( $bp->{$component_name}->notification_callback ) ) { 211 218 212 // Loop through each actionable item and try to map it to a component.213 foreach ( (array) $action_arrays as $component_action_name => $component_action_items) {219 // Function should return an object. 220 if ( 'object' === $format ) { 214 221 215 // Get the number of actionable items.216 $action_item_count = count( $component_action_items);222 // Retrieve the content of the notification using the callback. 223 $content = call_user_func( $bp->{$component_name}->notification_callback, $notification_item->component_action, $notification_item->item_id, $notification_item->secondary_item_id, $notification_item->total_count, 'array', $notification_item->id ); 217 224 218 // Skip if the count is less than 1. 219 if ( $action_item_count < 1 ) { 220 continue; 221 } 225 // Create the object to be returned. 226 $notification_object = $notification_item; 222 227 223 // Callback function exists. 224 if ( isset( $bp->{$component_name}->notification_callback ) && is_callable( $bp->{$component_name}->notification_callback ) ) { 228 // Minimal backpat with non-compatible notification 229 // callback functions. 230 if ( is_string( $content ) ) { 231 $notification_object->content = $content; 232 $notification_object->href = bp_loggedin_user_domain(); 233 } else { 234 $notification_object->content = $content['text']; 235 $notification_object->href = $content['link']; 236 } 225 237 226 // Function should return an object. 227 if ( 'object' === $format ) { 238 $renderable[] = $notification_object; 228 239 229 // Retrieve the content of the notification using the callback.230 $content = call_user_func(231 $bp->{$component_name}->notification_callback,232 $component_action_name,233 $component_action_items[0]->item_id,234 $component_action_items[0]->secondary_item_id,235 $action_item_count,236 'array',237 $component_action_items[0]->id238 );239 240 // Create the object to be returned.241 $notification_object = $component_action_items[0];242 243 // Minimal backpat with non-compatible notification244 // callback functions.245 if ( is_string( $content ) ) {246 $notification_object->content = $content;247 $notification_object->href = bp_loggedin_user_domain();248 } else {249 $notification_object->content = $content['text'];250 $notification_object->href = $content['link'];251 }252 253 $renderable[] = $notification_object;254 255 240 // Return an array of content strings. 256 257 $content = call_user_func( $bp->{$component_name}->notification_callback, $component_action_name, $component_action_items[0]->item_id, $component_action_items[0]->secondary_item_id, $action_item_count, 'string', $component_action_items[0]->id );258 259 241 } else { 242 $content = call_user_func( $bp->{$component_name}->notification_callback, $notification_item->component_action, $notification_item->item_id, $notification_item->secondary_item_id, $notification_item->total_count, 'string', $notification_item->id ); 243 $renderable[] = $content; 244 } 260 245 261 246 // @deprecated format_notification_function - 1.5 262 263 $renderable[] = call_user_func( $bp->{$component_name}->format_notification_function, $component_action_name, $component_action_items[0]->item_id, $component_action_items[0]->secondary_item_id, $action_item_count );247 } elseif ( isset( $bp->{$component_name}->format_notification_function ) && function_exists( $bp->{$component_name}->format_notification_function ) ) { 248 $renderable[] = call_user_func( $bp->{$component_name}->notification_callback, $notification_item->component_action, $notification_item->item_id, $notification_item->secondary_item_id, $notification_item->total_count ); 264 249 265 250 // Allow non BuddyPress components to hook in. 266 251 } else { 267 252 268 269 270 $component_action_name,271 $component_action_items[0]->item_id,272 $component_action_items[0]->secondary_item_id,273 $action_item_count,274 275 $component_action_name, // Duplicated so plugins can check the canonical action name.276 277 $component_action_items[0]->id278 253 // The array to reference with apply_filters_ref_array(). 254 $ref_array = array( 255 $notification_item->component_action, 256 $notification_item->item_id, 257 $notification_item->secondary_item_id, 258 $notification_item->total_count, 259 $format, 260 $notification_item->component_action, // Duplicated so plugins can check the canonical action name. 261 $component_name, 262 $notification_item->id, 263 ); 279 264 280 281 265 // Function should return an object. 266 if ( 'object' === $format ) { 282 267 283 /** 284 * Filters the notification content for notifications created by plugins. 285 * 286 * If your plugin extends the {@link BP_Component} class, you should use the 287 * 'notification_callback' parameter in your extended 288 * {@link BP_Component::setup_globals()} method instead. 289 * 290 * @since 1.9.0 291 * @since 2.6.0 Added $component_action_name, $component_name, $id as parameters. 292 * 293 * @param string $content Component action. Deprecated. Do not do checks against this! Use 294 * the 6th parameter instead - $component_action_name. 295 * @param int $item_id Notification item ID. 296 * @param int $secondary_item_id Notification secondary item ID. 297 * @param int $action_item_count Number of notifications with the same action. 298 * @param string $format Format of return. Either 'string' or 'object'. 299 * @param string $component_action_name Canonical notification action. 300 * @param string $component_name Notification component ID. 301 * @param int $id Notification ID. 302 * 303 * @return string|array If $format is 'string', return a string of the notification content. 304 * If $format is 'object', return an array formatted like: 305 * array( 'text' => 'CONTENT', 'link' => 'LINK' ) 306 */ 307 $content = apply_filters_ref_array( 'bp_notifications_get_notifications_for_user', $ref_array ); 268 /** 269 * Filters the notification content for notifications created by plugins. 270 * If your plugin extends the {@link BP_Component} class, you should use the 271 * 'notification_callback' parameter in your extended 272 * {@link BP_Component::setup_globals()} method instead. 273 * 274 * @since 1.9.0 275 * @since 2.6.0 Added $component_action_name, $component_name, $id as parameters. 276 * 277 * @param string $content Component action. Deprecated. Do not do checks against this! Use 278 * the 6th parameter instead - $component_action_name. 279 * @param int $item_id Notification item ID. 280 * @param int $secondary_item_id Notification secondary item ID. 281 * @param int $action_item_count Number of notifications with the same action. 282 * @param string $format Format of return. Either 'string' or 'object'. 283 * @param string $component_action_name Canonical notification action. 284 * @param string $component_name Notification component ID. 285 * @param int $id Notification ID. 286 * 287 * @return string|array If $format is 'string', return a string of the notification content. 288 * If $format is 'object', return an array formatted like: 289 * array( 'text' => 'CONTENT', 'link' => 'LINK' ) 290 */ 291 $content = apply_filters_ref_array( 'bp_notifications_get_notifications_for_user', $ref_array ); 308 292 309 310 $notification_object = $component_action_items[0];293 // Create the object to be returned. 294 $notification_object = $notification_item; 311 295 312 313 314 315 316 317 318 319 320 296 // Minimal backpat with non-compatible notification 297 // callback functions. 298 if ( is_string( $content ) ) { 299 $notification_object->content = $content; 300 $notification_object->href = bp_loggedin_user_domain(); 301 } else { 302 $notification_object->content = $content['text']; 303 $notification_object->href = $content['link']; 304 } 321 305 322 306 $renderable[] = $notification_object; 323 307 324 308 // Return an array of content strings. 325 309 } else { 326 310 327 /** This filters is documented in bp-notifications/bp-notifications-functions.php */ 328 $renderable[] = apply_filters_ref_array( 'bp_notifications_get_notifications_for_user', $ref_array ); 329 } 311 /** This filters is documented in bp-notifications/bp-notifications-functions.php */ 312 $renderable[] = apply_filters_ref_array( 'bp_notifications_get_notifications_for_user', $ref_array ); 330 313 } 331 314 } 332 315 } … … 607 590 * @return int Unread notification count. 608 591 */ 609 592 function bp_notifications_get_unread_notification_count( $user_id = 0 ) { 610 $notifications = bp_notifications_get_all_notifications_for_user( $user_id ); 611 $count = ! empty( $notifications ) ? count( $notifications ) : 0; 593 if ( empty( $user_id ) ) { 594 $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id(); 595 } 612 596 597 $count = wp_cache_get( 'unread_notification_count_for_user_' . $user_id, 'bp_notifications' ); 598 599 if ( false === $count ) { 600 $count = BP_Notifications_Notification::get_total_count( array( 601 'user_id' => $user_id, 602 'is_new' => 1, 603 ) ); 604 wp_cache_set( 'unread_notification_count_for_user_' . $user_id, 'bp_notifications' ); 605 } 606 613 607 /** 614 608 * Filters the count of unread notification items for a user. 615 609 * -
src/bp-notifications/classes/class-bp-notifications-notification.php
1131 1131 1132 1132 return self::update( $update_args, $where_args ); 1133 1133 } 1134 1135 /** 1136 * Get latest unread notifications and total count based on component_action 1137 * 1138 * @since 2.9.0 1139 * 1140 * @return array list of latest unread notifications 1141 */ 1142 public static function get_grouped_notifications_for_user( $user_id ) { 1143 global $wpdb; 1144 1145 // Load BuddyPress. 1146 $bp = buddypress(); 1147 1148 // SELECT. 1149 $select_sql = "SELECT id,user_id,item_id, secondary_item_id,component_name,component_action,date_notified,is_new,COUNT(id) as total_count "; 1150 1151 // FROM. 1152 $from_sql = "FROM {$bp->notifications->table_name} n "; 1153 1154 // WHERE. 1155 $where_sql = self::get_where_sql( array( 1156 'user_id' => $user_id, 1157 'is_new' => 1, 1158 'component_name' => bp_notifications_get_registered_components(), 1159 ), $select_sql, $from_sql ); 1160 1161 // GROUP 1162 $group_sql = "GROUP BY user_id,component_name,component_action"; 1163 1164 // SORT 1165 $order_sql = "ORDER BY date_notified desc"; 1166 1167 // Concatenate query parts. 1168 $sql = "{$select_sql} {$from_sql} {$where_sql} {$group_sql} {$order_sql}"; 1169 1170 // Return the queried results. 1171 return $wpdb->get_results( $sql ); 1172 } 1173 1134 1174 } -
tests/phpunit/testcases/notifications/functions.php
35 35 ) ); 36 36 37 37 $this->assertFalse( wp_cache_get( 'all_for_user_' . $u, 'bp_notifications' ) ); 38 $this->assertFalse( wp_cache_get( 'grouped_notifications_for_user_' . $u, 'bp_notifications' ) ); 39 $this->assertFalse( wp_cache_get( 'unread_notification_count_for_user_' . $u, 'bp_notifications' ) ); 38 40 } 39 41 40 42 /** … … 61 63 BP_Notifications_Notification::delete( array( 'id' => $n1, ) ); 62 64 63 65 $this->assertFalse( wp_cache_get( 'all_for_user_' . $u, 'bp_notifications' ) ); 66 $this->assertFalse( wp_cache_get( 'grouped_notifications_for_user_' . $u, 'bp_notifications' ) ); 67 $this->assertFalse( wp_cache_get( 'unread_notification_count_for_user_' . $u, 'bp_notifications' ) ); 64 68 } 65 69 66 70 /** … … 91 95 ); 92 96 93 97 $this->assertFalse( wp_cache_get( 'all_for_user_' . $u, 'bp_notifications' ) ); 98 $this->assertFalse( wp_cache_get( 'grouped_notifications_for_user_' . $u, 'bp_notifications' ) ); 99 $this->assertFalse( wp_cache_get( 'unread_notification_count_for_user_' . $u, 'bp_notifications' ) ); 94 100 } 95 101 96 102 /** … … 121 127 ); 122 128 123 129 $this->assertFalse( wp_cache_get( 'all_for_user_' . $u, 'bp_notifications' ) ); 130 $this->assertFalse( wp_cache_get( 'grouped_notifications_for_user_' . $u, 'bp_notifications' ) ); 131 $this->assertFalse( wp_cache_get( 'unread_notification_count_for_user_' . $u, 'bp_notifications' ) ); 124 132 } 125 133 126 134 /**