Ticket #5148: 5148.patch
File 5148.patch, 69.9 KB (added by , 11 years ago) |
---|
-
plugins/buddypress/bp-core/admin/bp-core-components.php
diff --git a/plugins/buddypress/bp-core/admin/bp-core-components.php b/plugins/buddypress/bp-core/admin/bp-core-components.php index e15ed3f..8330fa1 100644
a b 58 58 'xprofile' => array( 59 59 'title' => __( 'Extended Profiles', 'buddypress' ), 60 60 'description' => __( 'Customize your community with fully editable profile fields that allow your users to describe themselves.', 'buddypress' ) 61 ), 62 'settings' => array( 63 'title' => __( 'Account Settings', 'buddypress' ), 64 'description' => __( 'Allow your users to modify their account and notification settings directly from within their profiles.', 'buddypress' ) 65 ), 66 'notifications' => array( 67 'title' => __( 'Notifications', 'buddypress' ), 68 'description' => __( 'Notify members of relevant activity with a toolbar bubble and/or via email, and allow them to customize their notification settings.', 'buddypress' ) 61 69 ) 62 70 ); 63 71 64 72 $optional_components = bp_core_admin_get_components( 'optional' ); 65 73 $required_components = bp_core_admin_get_components( 'required' ); 66 $retired_components = bp_core_admin_get_components( 'retired');74 $retired_components = bp_core_admin_get_components( 'retired' ); 67 75 68 76 // Don't show Forums component in optional components if it's disabled 69 77 if ( ! bp_is_active( 'forums' ) ) { … … 371 379 'title' => __( 'Activity Streams', 'buddypress' ), 372 380 'description' => __( 'Global, personal, and group activity streams with threaded commenting, direct posting, favoriting and @mentions, all with full RSS feed and email notification support.', 'buddypress' ) 373 381 ), 382 'notifications' => array( 383 'title' => __( 'Notifications', 'buddypress' ), 384 'description' => __( 'Notify members of relevant activity with a toolbar bubble and/or via email, and allow them to customize their notification settings.', 'buddypress' ) 385 ), 374 386 'groups' => array( 375 387 'title' => __( 'User Groups', 'buddypress' ), 376 388 'description' => __( 'Groups allow your users to organize themselves into specific public, private or hidden sections with separate activity streams and member listings.', 'buddypress' ) -
plugins/buddypress/bp-core/admin/bp-core-schema.php
diff --git a/plugins/buddypress/bp-core/admin/bp-core-schema.php b/plugins/buddypress/bp-core/admin/bp-core-schema.php index 3b0e891..6001979 100644
a b 23 23 if ( empty( $active_components ) ) 24 24 $active_components = apply_filters( 'bp_active_components', bp_get_option( 'bp-active-components' ) ); 25 25 26 // Core DB Tables 27 bp_core_install_notifications(); 26 // Notifications 27 if ( !empty( $active_components['notifications'] ) ) 28 bp_core_install_notifications(); 28 29 29 30 // Activity Streams 30 31 if ( !empty( $active_components['activity'] ) ) -
plugins/buddypress/bp-core/bp-core-classes.php
diff --git a/plugins/buddypress/bp-core/bp-core-classes.php b/plugins/buddypress/bp-core/bp-core-classes.php index 38ba997..0688035 100644
a b 1291 1291 1292 1292 1293 1293 /** 1294 * BP_Core_Notification class can be used by any component. 1295 * It will handle the fetching, saving and deleting of a user notification. 1294 * BP_Core_Notification is deprecated. 1295 * 1296 * Use BP_Notifications_Notification instead. 1296 1297 * 1297 1298 * @package BuddyPress Core 1299 * @deprecated since BuddyPress (1.9) 1298 1300 */ 1299 1300 1301 class BP_Core_Notification { 1301 1302 1302 1303 /** -
plugins/buddypress/bp-core/bp-core-loader.php
diff --git a/plugins/buddypress/bp-core/bp-core-loader.php b/plugins/buddypress/bp-core/bp-core-loader.php index 0877c0a..510329a 100644
a b 54 54 /** Components ********************************************************/ 55 55 56 56 // Set the included and optional components. 57 $bp->optional_components = apply_filters( 'bp_optional_components', array( 'activity', 'blogs', 'forums', 'friends', 'groups', 'messages', ' settings', 'xprofile' ) );57 $bp->optional_components = apply_filters( 'bp_optional_components', array( 'activity', 'blogs', 'forums', 'friends', 'groups', 'messages', 'notifications', 'settings', 'xprofile' ) ); 58 58 59 59 // Set the required components 60 60 $bp->required_components = apply_filters( 'bp_required_components', array( 'members' ) ); … … 176 176 $bp->grav_default->user = apply_filters( 'bp_user_gravatar_default', $bp->site_options['avatar_default'] ); 177 177 $bp->grav_default->group = apply_filters( 'bp_group_gravatar_default', $bp->grav_default->user ); 178 178 $bp->grav_default->blog = apply_filters( 'bp_blog_gravatar_default', $bp->grav_default->user ); 179 180 // Notifications Table181 $bp->core->table_name_notifications = $bp->table_prefix . 'bp_notifications';182 179 183 180 /** 184 181 * Used to determine if user has admin rights on current content. If the -
plugins/buddypress/bp-core/bp-core-template.php
diff --git a/plugins/buddypress/bp-core/bp-core-template.php b/plugins/buddypress/bp-core/bp-core-template.php index 4c0dfa8..7a15761 100644
a b 1436 1436 } 1437 1437 1438 1438 /** 1439 * Check whether the current page is part of the Notifications component. 1440 * 1441 * @return bool True if the current page is part of the Notifications component. 1442 */ 1443 function bp_is_notifications_component() { 1444 if ( bp_is_current_component( 'notifications' ) ) 1445 return true; 1446 1447 return false; 1448 } 1449 1450 /** 1439 1451 * Check whether the current page is part of the Settings component. 1440 1452 * 1441 1453 * @return bool True if the current page is part of the Settings component. … … 1750 1762 } 1751 1763 1752 1764 /** 1765 * Is this a user's notifications page? 1766 * 1767 * Eg http://example.com/members/joe/notification/ (or a subpage thereof). 1768 * 1769 * @return bool True if the current page is a user's Notifications page. 1770 */ 1771 function bp_is_user_notifications() { 1772 if ( bp_is_user() && bp_is_notifications_component() ) 1773 return true; 1774 1775 return false; 1776 } 1777 1778 /** 1753 1779 * Is this a user's settings page? 1754 1780 * 1755 1781 * Eg http://example.com/members/joe/settings/ (or a subpage thereof). -
plugins/buddypress/bp-core/bp-core-update.php
diff --git a/plugins/buddypress/bp-core/bp-core-update.php b/plugins/buddypress/bp-core/bp-core-update.php index e565334..03363dc 100644
a b 187 187 $raw_db_version = (int) bp_get_db_version_raw(); 188 188 189 189 $default_components = apply_filters( 'bp_new_install_default_components', array( 190 'activity' => 1, 191 'members' => 1, 192 'settings' => 1, 193 'xprofile' => 1, 190 'activity' => 1, 191 'members' => 1, 192 'settings' => 1, 193 'xprofile' => 1, 194 'notifications' => 1 194 195 ) ); 195 196 196 197 require_once( BP_PLUGIN_DIR . '/bp-core/admin/bp-core-schema.php' ); -
plugins/buddypress/bp-friends/bp-friends-classes.php
diff --git a/plugins/buddypress/bp-friends/bp-friends-classes.php b/plugins/buddypress/bp-friends/bp-friends-classes.php index c895d14..085d0d1 100644
a b 363 363 // Delete all friendships related to $user_id 364 364 $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->friends->table_name} WHERE friend_user_id = %d OR initiator_user_id = %d", $user_id, $user_id ) ); 365 365 366 // Delete friend request notifications for members who have a notification from this user. 367 $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->core->table_name_notifications} WHERE component_name = 'friends' AND ( component_action = 'friendship_request' OR component_action = 'friendship_accepted' ) AND item_id = %d", $user_id ) ); 366 // Delete friend request notifications for members who have a 367 // notification from this user. 368 if ( bp_is_active( 'notifications' ) ) { 369 $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->notifications->table_name} WHERE component_name = 'friends' AND ( component_action = 'friendship_request' OR component_action = 'friendship_accepted' ) AND item_id = %d", $user_id ) ); 370 } 368 371 369 372 // Loop through friend_ids and update their counts 370 373 foreach ( (array) $friend_ids as $friend_id ) { -
plugins/buddypress/bp-members/bp-members-adminbar.php
diff --git a/plugins/buddypress/bp-members/bp-members-adminbar.php b/plugins/buddypress/bp-members/bp-members-adminbar.php index 2a29ddc..9c4662c 100644
a b 139 139 * @since BuddyPress (1.5) 140 140 */ 141 141 function bp_members_admin_bar_notifications_menu() { 142 global $wp_admin_bar;143 142 144 if ( !is_user_logged_in() ) 143 // Bail if notifications is not active 144 if ( ! bp_is_active( 'notifications' ) ) { 145 145 return false; 146 147 $notifications = bp_core_get_notifications_for_user( bp_loggedin_user_id(), 'object' );148 $count = !empty( $notifications ) ? count( $notifications ) : 0;149 $alert_class = (int) $count > 0 ? 'pending-count alert' : 'count no-alert';150 $menu_title = '<span id="ab-pending-notifications" class="' . $alert_class . '">' . $count . '</span>';151 152 // Add the top-level Notifications button153 $wp_admin_bar->add_menu( array(154 'parent' => 'top-secondary',155 'id' => 'bp-notifications',156 'title' => $menu_title,157 'href' => bp_loggedin_user_domain(),158 ) );159 160 if ( !empty( $notifications ) ) {161 foreach ( (array) $notifications as $notification ) {162 $wp_admin_bar->add_menu( array(163 'parent' => 'bp-notifications',164 'id' => 'notification-' . $notification->id,165 'title' => $notification->content,166 'href' => $notification->href167 ) );168 }169 } else {170 $wp_admin_bar->add_menu( array(171 'parent' => 'bp-notifications',172 'id' => 'no-notifications',173 'title' => __( 'No new notifications', 'buddypress' ),174 'href' => bp_loggedin_user_domain()175 ) );176 146 } 177 147 178 return;148 bp_notifications_toolbar_menu(); 179 149 } 180 150 add_action( 'admin_bar_menu', 'bp_members_admin_bar_notifications_menu', 90 ); 181 151 -
plugins/buddypress/bp-members/bp-members-buddybar.php
diff --git a/plugins/buddypress/bp-members/bp-members-buddybar.php b/plugins/buddypress/bp-members/bp-members-buddybar.php index 613d087..f3c08c2 100644
a b 17 17 */ 18 18 function bp_adminbar_notifications_menu() { 19 19 20 if ( !is_user_logged_in() ) 20 // Bail if notifications is not active 21 if ( ! bp_is_active( 'notifications' ) ) { 21 22 return false; 22 23 echo '<li id="bp-adminbar-notifications-menu"><a href="' . bp_loggedin_user_domain() . '">';24 _e( 'Notifications', 'buddypress' );25 26 if ( $notifications = bp_core_get_notifications_for_user( bp_loggedin_user_id() ) ) { ?>27 <span><?php echo count( $notifications ) ?></span>28 <?php29 23 } 30 24 31 echo '</a>'; 32 echo '<ul>'; 33 34 if ( $notifications ) { 35 $counter = 0; 36 for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) { 37 $alt = ( 0 == $counter % 2 ) ? ' class="alt"' : ''; ?> 38 39 <li<?php echo $alt ?>><?php echo $notifications[$i] ?></li> 40 41 <?php $counter++; 42 } 43 } else { ?> 44 45 <li><a href="<?php echo bp_loggedin_user_domain() ?>"><?php _e( 'No new notifications.', 'buddypress' ); ?></a></li> 46 47 <?php 48 } 49 50 echo '</ul>'; 51 echo '</li>'; 25 bp_notifications_buddybar_menu(); 52 26 } 53 27 add_action( 'bp_adminbar_menus', 'bp_adminbar_notifications_menu', 8 ); 54 28 -
plugins/buddypress/bp-members/bp-members-notifications.php
diff --git a/plugins/buddypress/bp-members/bp-members-notifications.php b/plugins/buddypress/bp-members/bp-members-notifications.php index 5e670b7..0e56829 100644
a b 3 3 /** 4 4 * BuddyPress Member Notifications 5 5 * 6 * Functions and filters used for member notification6 * Backwards compatibility functions and filters used for member notification 7 7 * 8 8 * @package BuddyPress 9 9 * @subpackage MembersNotifications … … 26 26 */ 27 27 function bp_core_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false ) { 28 28 29 if ( empty( $date_notified ) ) 30 $date_notified = bp_core_current_time(); 29 // Bail if notifications is not active 30 if ( ! bp_is_active( 'notifications' ) ) { 31 return false; 32 } 31 33 32 $notification = new BP_Core_Notification; 33 $notification->item_id = $item_id; 34 $notification->user_id = $user_id; 35 $notification->component_name = $component_name; 36 $notification->component_action = $component_action; 37 $notification->date_notified = $date_notified; 38 $notification->is_new = 1; 39 40 if ( !empty( $secondary_item_id ) ) 41 $notification->secondary_item_id = $secondary_item_id; 42 43 if ( $notification->save() ) 44 return true; 45 46 return false; 34 return bp_notifications_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false ); 47 35 } 48 36 49 37 /** … … 54 42 * @return boolean True on success, false on fail 55 43 */ 56 44 function bp_core_delete_notification( $id ) { 57 if ( !bp_core_check_notification_access( bp_loggedin_user_id(), $id ) )58 return false;59 45 60 return BP_Core_Notification::delete( $id ); 46 // Bail if notifications is not active 47 if ( ! bp_is_active( 'notifications' ) ) { 48 return false; 49 } 50 51 return bp_notifications_delete_notification( $id ); 61 52 } 62 53 63 54 /** … … 68 59 * @return BP_Core_Notification 69 60 */ 70 61 function bp_core_get_notification( $id ) { 71 return new BP_Core_Notification( $id ); 62 63 // Bail if notifications is not active 64 if ( ! bp_is_active( 'notifications' ) ) { 65 return false; 66 } 67 68 return bp_notifications_get_notification( $id ); 72 69 } 73 70 74 71 /** … … 81 78 * @return boolean Object or array on success, false on fail 82 79 */ 83 80 function bp_core_get_notifications_for_user( $user_id, $format = 'simple' ) { 84 global $bp;85 81 86 $notifications = BP_Core_Notification::get_all_for_user( $user_id ); 87 $grouped_notifications = array(); // Notification groups 88 $renderable = array(); // Renderable notifications 89 90 // Group notifications by component and component_action and provide totals 91 for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) { 92 $notification = $notifications[$i]; 93 $grouped_notifications[$notification->component_name][$notification->component_action][] = $notification; 94 } 95 96 // Bail if no notification groups 97 if ( empty( $grouped_notifications ) ) 82 // Bail if notifications is not active 83 if ( ! bp_is_active( 'notifications' ) ) { 98 84 return false; 99 100 // Calculate a renderable output for each notification type101 foreach ( $grouped_notifications as $component_name => $action_arrays ) {102 103 // Skip if group is empty104 if ( empty( $action_arrays ) )105 continue;106 107 // Skip inactive components108 if ( !bp_is_active( $component_name ) )109 continue;110 111 // Loop through each actionable item and try to map it to a component112 foreach ( (array) $action_arrays as $component_action_name => $component_action_items ) {113 114 // Get the number of actionable items115 $action_item_count = count( $component_action_items );116 117 // Skip if the count is less than 1118 if ( $action_item_count < 1 )119 continue;120 121 // Callback function exists122 if ( isset( $bp->{$component_name}->notification_callback ) && is_callable( $bp->{$component_name}->notification_callback ) ) {123 124 // Function should return an object125 if ( 'object' == $format ) {126 127 // Retrieve the content of the notification using the callback128 $content = call_user_func(129 $bp->{$component_name}->notification_callback,130 $component_action_name,131 $component_action_items[0]->item_id,132 $component_action_items[0]->secondary_item_id,133 $action_item_count,134 'array'135 );136 137 // Create the object to be returned138 $notification_object = new stdClass;139 140 // Minimal backpat with non-compatible notification141 // callback functions142 if ( is_string( $content ) ) {143 $notification_object->content = $content;144 $notification_object->href = bp_loggedin_user_domain();145 } else {146 $notification_object->content = $content['text'];147 $notification_object->href = $content['link'];148 }149 150 $notification_object->id = $component_action_items[0]->id;151 $renderable[] = $notification_object;152 153 // Return an array of content strings154 } else {155 $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 );156 $renderable[] = $content;157 }158 159 // @deprecated format_notification_function - 1.5160 } elseif ( isset( $bp->{$component_name}->format_notification_function ) && function_exists( $bp->{$component_name}->format_notification_function ) ) {161 $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 );162 }163 }164 85 } 165 86 166 // If renderable is empty array, set to false 167 if ( empty( $renderable ) ) 168 $renderable = false; 87 $renderable = bp_notifications_get_notifications_for_user( $user_id, $format ); 169 88 170 // Filter and return171 89 return apply_filters( 'bp_core_get_notifications_for_user', $renderable, $user_id, $format ); 172 90 } 173 91 … … 184 102 * @return boolean True on success, false on fail 185 103 */ 186 104 function bp_core_delete_notifications_by_type( $user_id, $component_name, $component_action ) { 187 return BP_Core_Notification::delete_for_user_by_type( $user_id, $component_name, $component_action ); 105 106 // Bail if notifications is not active 107 if ( ! bp_is_active( 'notifications' ) ) { 108 return false; 109 } 110 111 return bp_notifications_delete_notifications_by_type( $user_id, $component_name, $component_action ); 188 112 } 189 113 190 114 /** … … 200 124 * @return boolean True on success, false on fail 201 125 */ 202 126 function bp_core_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false ) { 203 return BP_Core_Notification::delete_for_user_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id ); 127 128 // Bail if notifications is not active 129 if ( ! bp_is_active( 'notifications' ) ) { 130 return false; 131 } 132 133 return bp_notifications_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id ); 204 134 } 205 135 206 136 /** … … 215 145 * @return boolean True on success, false on fail 216 146 */ 217 147 function bp_core_delete_all_notifications_by_type( $item_id, $component_name, $component_action = false, $secondary_item_id = false ) { 218 return BP_Core_Notification::delete_all_by_type( $item_id, $component_name, $component_action, $secondary_item_id ); 148 149 // Bail if notifications is not active 150 if ( ! bp_is_active( 'notifications' ) ) { 151 return false; 152 } 153 154 bp_notifications_delete_all_notifications_by_type( $item_id, $component_name, $component_action, $secondary_item_id ); 219 155 } 220 156 221 157 /** … … 230 166 * @return boolean True on success, false on fail 231 167 */ 232 168 function bp_core_delete_notifications_from_user( $user_id, $component_name, $component_action ) { 233 return BP_Core_Notification::delete_from_user_by_type( $user_id, $component_name, $component_action ); 169 170 // Bail if notifications is not active 171 if ( ! bp_is_active( 'notifications' ) ) { 172 return false; 173 } 174 175 return bp_notifications_delete_notifications_from_user( $user_id, $component_name, $component_action ); 234 176 } 235 177 236 178 /** … … 244 186 * @return boolean True on success, false on fail 245 187 */ 246 188 function bp_core_check_notification_access( $user_id, $notification_id ) { 247 if ( !BP_Core_Notification::check_access( $user_id, $notification_id ) )248 return false;249 189 250 return true; 190 // Bail if notifications is not active 191 if ( ! bp_is_active( 'notifications' ) ) { 192 return false; 193 } 194 195 return bp_notifications_check_notification_access( $user_id, $notification_id ); 251 196 } -
new file plugins/buddypress/bp-notifications/bp-notifications-adminbar.php
diff --git a/plugins/buddypress/bp-notifications/bp-notifications-adminbar.php b/plugins/buddypress/bp-notifications/bp-notifications-adminbar.php new file mode 100644 index 0000000..3021cdd
- + 1 <?php 2 3 /** 4 * BuddyPress Notifications Toolbar 5 * 6 * Toolbar functions for the notifications component 7 * 8 * @package BuddyPress 9 * @subpackage NotificationsToolbar 10 */ 11 12 // Exit if accessed directly 13 if ( !defined( 'ABSPATH' ) ) exit; 14 15 /** 16 * Build the "Notifications" dropdown 17 * 18 * @package BuddyPress 19 * @since BuddyPress (1.5) 20 */ 21 function bp_notifications_toolbar_menu() { 22 global $wp_admin_bar; 23 24 if ( !is_user_logged_in() ) 25 return false; 26 27 $notifications = bp_core_get_notifications_for_user( bp_loggedin_user_id(), 'object' ); 28 $count = !empty( $notifications ) ? count( $notifications ) : 0; 29 $alert_class = (int) $count > 0 ? 'pending-count alert' : 'count no-alert'; 30 $menu_title = '<span id="ab-pending-notifications" class="' . $alert_class . '">' . $count . '</span>'; 31 32 // Add the top-level Notifications button 33 $wp_admin_bar->add_menu( array( 34 'parent' => 'top-secondary', 35 'id' => 'bp-notifications', 36 'title' => $menu_title, 37 'href' => bp_loggedin_user_domain(), 38 ) ); 39 40 if ( !empty( $notifications ) ) { 41 foreach ( (array) $notifications as $notification ) { 42 $wp_admin_bar->add_menu( array( 43 'parent' => 'bp-notifications', 44 'id' => 'notification-' . $notification->id, 45 'title' => $notification->content, 46 'href' => $notification->href 47 ) ); 48 } 49 } else { 50 $wp_admin_bar->add_menu( array( 51 'parent' => 'bp-notifications', 52 'id' => 'no-notifications', 53 'title' => __( 'No new notifications', 'buddypress' ), 54 'href' => bp_loggedin_user_domain() 55 ) ); 56 } 57 58 return; 59 } 60 add_action( 'admin_bar_menu', 'bp_members_admin_bar_notifications_menu', 90 ); 61 No newline at end of file -
new file plugins/buddypress/bp-notifications/bp-notifications-buddybar.php
diff --git a/plugins/buddypress/bp-notifications/bp-notifications-buddybar.php b/plugins/buddypress/bp-notifications/bp-notifications-buddybar.php new file mode 100644 index 0000000..e469ee0
- + 1 <?php 2 3 /** 4 * BuddyPress Notifications BuddyBar 5 * 6 * Handles the notifications functions related to the BuddyBar 7 * 8 * @package BuddyPress 9 * @subpackage NotificationsBuddyBar 10 */ 11 12 // Exit if accessed directly 13 if ( !defined( 'ABSPATH' ) ) exit; 14 15 /** 16 * Notifications Menu 17 */ 18 function bp_notifications_buddybar_menu() { 19 20 if ( !is_user_logged_in() ) 21 return false; 22 23 echo '<li id="bp-adminbar-notifications-menu"><a href="' . bp_loggedin_user_domain() . '">'; 24 _e( 'Notifications', 'buddypress' ); 25 26 if ( $notifications = bp_core_get_notifications_for_user( bp_loggedin_user_id() ) ) { ?> 27 <span><?php echo count( $notifications ) ?></span> 28 <?php 29 } 30 31 echo '</a>'; 32 echo '<ul>'; 33 34 if ( $notifications ) { 35 $counter = 0; 36 for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) { 37 $alt = ( 0 == $counter % 2 ) ? ' class="alt"' : ''; ?> 38 39 <li<?php echo $alt ?>><?php echo $notifications[$i] ?></li> 40 41 <?php $counter++; 42 } 43 } else { ?> 44 45 <li><a href="<?php echo bp_loggedin_user_domain() ?>"><?php _e( 'No new notifications.', 'buddypress' ); ?></a></li> 46 47 <?php 48 } 49 50 echo '</ul>'; 51 echo '</li>'; 52 } 53 add_action( 'bp_adminbar_menus', 'bp_adminbar_notifications_menu', 8 ); 54 No newline at end of file -
new file plugins/buddypress/bp-notifications/bp-notifications-classes.php
diff --git a/plugins/buddypress/bp-notifications/bp-notifications-classes.php b/plugins/buddypress/bp-notifications/bp-notifications-classes.php new file mode 100644 index 0000000..edf3286
- + 1 <?php 2 3 /** 4 * BuddyPress Notifications Classes 5 * 6 * Classes used for notifications 7 * 8 * @package BuddyPress 9 * @subpackage NotificationsClasses 10 */ 11 12 // Exit if accessed directly 13 if ( !defined( 'ABSPATH' ) ) exit; 14 15 /** 16 * BP_Core_Notification class can be used by any component. 17 * 18 * It will handle the fetching, saving and deleting of a member notification. 19 * 20 * @package BuddyPress Notifications 21 */ 22 class BP_Notifications_Notification { 23 24 /** 25 * The notification id 26 * 27 * @var integer 28 */ 29 public $id; 30 31 /** 32 * The ID to which the notification relates to within the component. 33 * 34 * @var integer 35 */ 36 public $item_id; 37 38 /** 39 * The secondary ID to which the notification relates to within the component. 40 * 41 * @var integer 42 */ 43 public $secondary_item_id = null; 44 45 /** 46 * The user ID for who the notification is for. 47 * 48 * @var integer 49 */ 50 public $user_id; 51 52 /** 53 * The name of the component that the notification is for. 54 * 55 * @var string 56 */ 57 public $component_name; 58 59 /** 60 * The action within the component which the notification is related to. 61 * 62 * @var string 63 */ 64 public $component_action; 65 66 /** 67 * The date the notification was created. 68 * 69 * @var string 70 */ 71 public $date_notified; 72 73 /** 74 * Is the notification new or has it already been read. 75 * 76 * @var boolean 77 */ 78 public $is_new; 79 80 /** Public Methods ********************************************************/ 81 82 /** 83 * Constructor 84 * 85 * @param integer $id 86 */ 87 public function __construct( $id = 0 ) { 88 if ( !empty( $id ) ) { 89 $this->id = $id; 90 $this->populate(); 91 } 92 } 93 94 /** 95 * Update or insert notification details into the database. 96 * 97 * @global wpdb $wpdb WordPress database object 98 * @return bool Success or failure 99 */ 100 public function save() { 101 102 // Return value 103 $retval = false; 104 105 // Default data and format 106 $data = array( 107 'user_id' => $this->user_id, 108 'item_id' => $this->item_id, 109 'secondary_item_id' => $this->secondary_item_id, 110 'component_name' => $this->component_name, 111 'component_action' => $this->component_action, 112 'date_notified' => $this->date_notified, 113 'is_new' => $this->is_new, 114 ); 115 $data_format = array( '%d', '%d', '%d', '%s', '%s', '%s', '%d' ); 116 117 // Update 118 if ( !empty( $this->id ) ) { 119 $result = self::update( $data, $data_format, array( 'ID' => $this->id ), array( '%d' ) ); 120 121 // Insert 122 } else { 123 $result = self::insert( $data, $data_format ); 124 } 125 126 // Set the notification ID if successful 127 if ( ! empty( $result ) && ! is_wp_error( $result ) ) { 128 global $wpdb; 129 130 $this->id = $wpdb->insert_id; 131 $retval = true; 132 } 133 134 // Return the result 135 return (bool) $retval; 136 } 137 138 /** 139 * Fetches the notification data from the database. 140 * 141 * @global BuddyPress $bp The one true BuddyPress instance 142 * @global wpdb $wpdb WordPress database object 143 */ 144 public function populate() { 145 global $wpdb; 146 147 $bp = buddypress(); 148 149 // Look for a notification 150 $notification = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->notifications->table_name} WHERE id = %d", $this->id ) ); 151 152 // Setup the notification data 153 if ( !empty( $notification ) && ! is_wp_error( $notification ) ) { 154 $this->item_id = $notification->item_id; 155 $this->secondary_item_id = $notification->secondary_item_id; 156 $this->user_id = $notification->user_id; 157 $this->component_name = $notification->component_name; 158 $this->component_action = $notification->component_action; 159 $this->date_notified = $notification->date_notified; 160 $this->is_new = $notification->is_new; 161 } 162 } 163 164 /** Private Static Methods ************************************************/ 165 166 /** 167 * Update a notification entry, usually intended for marking read/unread. 168 * 169 * @since BuddyPress (1.9) 170 */ 171 private static function insert( $data = array(), $data_format = array() ) { 172 global $wpdb; 173 174 $bp = buddypress(); 175 176 return $wpdb->insert( $bp->notifications->table_name, $data, $data_format ); 177 } 178 179 /** 180 * Update a notification entry, usually intended for marking read/unread. 181 * 182 * @since BuddyPress (1.9) 183 */ 184 private static function update( $data = array(), $where = array(), $data_format = array(), $where_format = array() ) { 185 global $wpdb; 186 187 $bp = buddypress(); 188 189 return $wpdb->update( $bp->notifications->table_name, $data, $where, $data_format, $where_format ); 190 } 191 192 /** 193 * Delete a notification entry. 194 * 195 * @since BuddyPress (1.9) 196 */ 197 private static function delete( $where = array(), $where_format = array() ) { 198 global $wpdb; 199 200 $bp = buddypress(); 201 202 return $wpdb->delete( $bp->notifications->table_name, $where, $where_format ); 203 } 204 205 /** Public Static Methods *************************************************/ 206 207 /** 208 * Check that a specific notification is for a specific user. 209 * 210 * @since BuddyPress (1.9) 211 * @param int $user_id 212 * @param int $notification_id 213 * @return bool 214 */ 215 public static function check_access( $user_id, $notification_id ) { 216 global $wpdb; 217 218 $bp = buddypress(); 219 220 return $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->core->table_name_notifications} WHERE id = %d AND user_id = %d", $notification_id, $user_id ) ); 221 } 222 223 /** 224 * Fetches all the notifications in the database for a specific user. 225 * 226 * @global BuddyPress $bp The one true BuddyPress instance 227 * @global wpdb $wpdb WordPress database object 228 * @param integer $user_id User ID 229 * @param string $status 'is_new' or 'all' 230 * @return array Associative array 231 * @static 232 */ 233 public static function get_all_for_user( $user_id, $status = 'is_new' ) { 234 global $wpdb; 235 236 $bp = buddypress(); 237 238 $is_new = ( 'is_new' == $status ) ? ' AND is_new = 1 ' : ''; 239 240 return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->notifications->table_name} WHERE user_id = %d {$is_new}", $user_id ) ); 241 } 242 243 /** 244 * Fetches all the notifications in the database for a specific user. 245 * 246 * @since BuddyPress (1.9) 247 * 248 * @global wpdb $wpdb WordPress database object 249 * @param integer $user_id User ID 250 * @param string $status 'is_new' or 'all' 251 * @return array Associative array 252 * @static 253 */ 254 public static function get_unread_for_user( $user_id = 0 ) { 255 global $wpdb; 256 257 $bp = buddypress(); 258 259 return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->notifications->table_name} WHERE user_id = %d AND is_new = 1", $user_id ) ); 260 } 261 262 /** 263 * Fetches all the notifications in the database for a specific user. 264 * 265 * @since BuddyPress (1.9) 266 * 267 * @global wpdb $wpdb WordPress database object 268 * @param integer $user_id User ID 269 * @param string $status 'is_new' or 'all' 270 * @return array Associative array 271 * @static 272 */ 273 public static function get_read_for_user( $user_id = 0 ) { 274 global $wpdb; 275 276 $bp = buddypress(); 277 278 return $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->notifications->table_name} WHERE user_id = %d AND is_new = 0", $user_id ) ); 279 } 280 281 public static function get_current_notifications_for_user( $user_id, $is_new = 1, $limit = null, $page = null, $search_terms = '' ) { 282 global $wpdb; 283 284 $bp = buddypress(); 285 $pag_sql = $is_new_sql = $search_sql = ''; 286 287 // Pagination 288 if ( !empty( $limit ) && !empty( $page ) ) { 289 $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $page - 1 ) * $limit), intval( $limit ) ); 290 } 291 292 // Unread or read? 293 if ( !empty( $is_new ) ) { 294 $is_new_sql = " AND is_new = {$is_new} "; 295 } 296 297 // Search? 298 if ( !empty( $search_terms ) ) { 299 $search_terms = like_escape( esc_sql( $search_terms ) ); 300 $search_sql = "AND ( component_name LIKE '%%$search_terms%%' OR component_action LIKE '%%$search_terms%%' )"; 301 } 302 303 $notifications_query = "SELECT * FROM {$bp->notifications->table_name} WHERE user_id = %d {$is_new_sql} {$search_sql} ORDER BY date_notified DESC {$pag_sql}"; 304 $notifications_count_query = "SELECT COUNT( DISTINCT id ) FROM {$bp->notifications->table_name} WHERE user_id = %d {$is_new_sql} {$search_sql}"; 305 306 // Get the notifications and count 307 $notifications = $wpdb->get_results( $wpdb->prepare( $notifications_query, $user_id ) ); 308 $total_notifications = $wpdb->get_var( $wpdb->prepare( $notifications_count_query, $user_id ) ); 309 310 // Bail if no notifications 311 if ( empty( $notifications ) ) { 312 return false; 313 } 314 315 return array( 'notifications' => &$notifications, 'total' => (int) $total_notifications ); 316 } 317 318 /** Mark Read *************************************************************/ 319 320 /** 321 * Mark all user notifications as read. 322 * 323 * @since BuddyPress (1.9) 324 * 325 * @param integer $user_id The ID of the user who the notifications are for. 326 * @param integer $is_new Mark as read (1) or unread (0). 327 * @static 328 */ 329 public static function mark_all_for_user( $user_id, $is_new = 0, $item_id = 0, $component_name = '', $component_action = '', $secondary_item_id = 0 ) { 330 331 // Update is_new 332 $data = array( 'is_new' => $is_new ); 333 $data_format = array( '%d' ); 334 335 // Where clause 336 $where = array( 'user_id' => $user_id ); 337 $where_format = array( '%d' ); 338 339 // Check the item ID 340 if ( !empty( $item_id ) ) { 341 $where['item_id'] = $item_id; 342 $where_format[] = '%d'; 343 } 344 345 // Check the component name 346 if ( !empty( $component_name ) ) { 347 $where['component_name'] = $component_name; 348 $where_format[] = '%s'; 349 } 350 351 // Check the component action 352 if ( !empty( $component_action ) ) { 353 $where['component_action'] = $component_action; 354 $where_format[] = '%s'; 355 } 356 357 // Possibly check the secondary item ID 358 if ( !empty( $secondary_item_id ) ) { 359 $where['secondary_item_id'] = $secondary_item_id; 360 $where_format[] = '%d'; 361 } 362 363 return self::update( $data, $where, $data_format, $where_format ); 364 } 365 366 /** 367 * Mark all notifications from a user as read. 368 * 369 * @since BuddyPress (1.9) 370 * 371 * @param integer $user_id The ID of the user who the notifications are for. 372 * @param integer $is_new Mark as read (1) or unread (0). 373 * @static 374 */ 375 public static function mark_all_from_user( $user_id, $is_new = 0, $component_name = '', $component_action = '', $secondary_item_id = 0 ) { 376 377 // Update is_new 378 $data = array( 'is_new' => $is_new ); 379 $data_format = array( '%d' ); 380 381 // Where clause 382 $where = array( 'item_id' => $user_id ); 383 $where_format = array( '%d' ); 384 385 // Check the component name 386 if ( !empty( $component_name ) ) { 387 $where['component_name'] = $component_name; 388 $where_format[] = '%s'; 389 } 390 391 // Check the component action 392 if ( !empty( $component_action ) ) { 393 $where['component_action'] = $component_action; 394 $where_format[] = '%s'; 395 } 396 397 // Possibly check the secondary item ID 398 if ( !empty( $secondary_item_id ) ) { 399 $where['secondary_item_id'] = $secondary_item_id; 400 $where_format[] = '%d'; 401 } 402 403 return self::update( $data, $where, $data_format, $where_format ); 404 } 405 406 /** 407 * Mark all notifications for all users as read by item id, and optional 408 * secondary item id, and component name and action. 409 * 410 * @since BuddyPress (1.9) 411 * 412 * @global wpdb $wpdb WordPress database object 413 * @param string $item_id The item id that they notifications are to be for. 414 * @param string $component_name The component that the notifications are to be from. 415 * @param string $component_action The action that the notificationsa are to be from. 416 * @param string $secondary_item_id Optional secondary item id that the notifications are to have. 417 * @static 418 */ 419 public static function mark_all_by_type( $item_id, $is_new = 0, $component_name = '', $component_action = '', $secondary_item_id = 0 ) { 420 421 // Update is_new 422 $data = array( 'is_new' => $is_new ); 423 $data_format = array( '%d' ); 424 425 // Check the item ID 426 if ( !empty( $item_id ) ) { 427 $where['item_id'] = $item_id; 428 $where_format[] = '%d'; 429 } 430 431 // Check the component name 432 if ( !empty( $component_name ) ) { 433 $where['component_name'] = $component_name; 434 $where_format[] = '%s'; 435 } 436 437 // Check the component action 438 if ( !empty( $component_action ) ) { 439 $where['component_action'] = $component_action; 440 $where_format[] = '%s'; 441 } 442 443 // Check the secondary item ID 444 if ( !empty( $secondary_item_id ) ) { 445 $where['secondary_item_id'] = $secondary_item_id; 446 $where_format[] = '%d'; 447 } 448 449 return self::update( $data, $where, $data_format, $where_format ); 450 } 451 452 /** Delete ****************************************************************/ 453 454 /** 455 * Delete all the notifications for a user based on the component name and action. 456 * 457 * @param integer $user_id 458 * @param string $component_name 459 * @param string $component_action 460 * @static 461 */ 462 public static function delete_for_user_by_type( $user_id, $component_name = '', $component_action = '' ) { 463 464 // Use user ID 465 $where = array( 'user_id' => $user_id ); 466 $where_format = array( '%d' ); 467 468 // Check the component name 469 if ( !empty( $component_name ) ) { 470 $where['component_name'] = $component_name; 471 $where_format[] = '%s'; 472 } 473 474 // Check the component action 475 if ( !empty( $component_action ) ) { 476 $where['component_action'] = $component_action; 477 $where_format[] = '%s'; 478 } 479 480 return self::delete( $where, $where_format ); 481 } 482 483 /** 484 * Delete all the notifications that have a specific item id, component name and action. 485 * 486 * @param integer $user_id The ID of the user who the notifications are for. 487 * @param integer $item_id The item ID of the notifications we wish to delete. 488 * @param string $component_name The name of the component that the notifications we wish to delete. 489 * @param string $component_action The action of the component that the notifications we wish to delete. 490 * @param integer $secondary_item_id The secondary item id of the notifications that we wish to use to delete. 491 * @static 492 */ 493 public static function delete_for_user_by_item_id( $user_id, $item_id = 0, $component_name = '', $component_action = '', $secondary_item_id = 0 ) { 494 495 // Use user ID 496 $where = array( 'user_id' => $user_id ); 497 $where_format = array( '%d' ); 498 499 // Check the item ID 500 if ( !empty( $item_id ) ) { 501 $where['item_id'] = $item_id; 502 $where_format[] = '%d'; 503 } 504 505 // Check the component name 506 if ( !empty( $component_name ) ) { 507 $where['component_name'] = $component_name; 508 $where_format[] = '%s'; 509 } 510 511 // Check the component action 512 if ( !empty( $component_action ) ) { 513 $where['component_action'] = $component_action; 514 $where_format[] = '%s'; 515 } 516 517 // Check the secondary item ID 518 if ( !empty( $secondary_item_id ) ) { 519 $where['secondary_item_id'] = $secondary_item_id; 520 $where_format[] = '%d'; 521 } 522 523 return self::delete( $where, $where_format ); 524 } 525 526 /** 527 * Deletes all the notifications sent by a specific user, by component and action. 528 * 529 * @param integer $user_id The ID of the user whose sent notifications we wish to delete. 530 * @param string $component_name The name of the component the notification was sent from. 531 * @param string $component_action The action of the component the notification was sent from. 532 * @static 533 */ 534 public static function delete_from_user_by_type( $user_id, $component_name = '', $component_action = '' ) { 535 536 // Use item ID 537 $where = array( 'item_id' => $user_id ); 538 $where_format = array( '%d' ); 539 540 // Check the component name 541 if ( !empty( $component_name ) ) { 542 $where['component_name'] = $component_name; 543 $where_format[] = '%s'; 544 } 545 546 // Check the component action 547 if ( !empty( $component_action ) ) { 548 $where['component_action'] = $component_action; 549 $where_format[] = '%s'; 550 } 551 552 return self::delete( $where, $where_format ); 553 } 554 555 /** 556 * Deletes all the notifications for all users by item id, and optional secondary item id, and component name and action. 557 * 558 * @param string $item_id The item id that they notifications are to be for. 559 * @param string $component_name The component that the notifications are to be from. 560 * @param string $component_action The action that the notificationsa are to be from. 561 * @param string $secondary_item_id Optional secondary item id that the notifications are to have. 562 * @static 563 */ 564 public static function delete_all_by_type( $item_id, $component_name = '', $component_action = '', $secondary_item_id = 0 ) { 565 566 // Use item ID 567 $where = array( 'item_id' => $item_id ); 568 $where_format = array( '%d' ); 569 570 // Check the component name 571 if ( !empty( $component_name ) ) { 572 $where['component_name'] = $component_name; 573 $where_format[] = '%s'; 574 } 575 576 // Check the component action 577 if ( !empty( $component_action ) ) { 578 $where['component_action'] = $component_action; 579 $where_format[] = '%s'; 580 } 581 582 // Check the secondary item ID 583 if ( !empty( $secondary_item_id ) ) { 584 $where['secondary_item_id'] = $secondary_item_id; 585 $where_format[] = '%d'; 586 } 587 588 return self::delete( $where, $where_format ); 589 } 590 } -
new file plugins/buddypress/bp-notifications/bp-notifications-functions.php
diff --git a/plugins/buddypress/bp-notifications/bp-notifications-functions.php b/plugins/buddypress/bp-notifications/bp-notifications-functions.php new file mode 100644 index 0000000..054f6bc
- + 1 <?php 2 3 /** 4 * BuddyPress Member Notifications 5 * 6 * Functions and filters used for member notification 7 * 8 * @package BuddyPress 9 * @subpackage NotificationsFunctions 10 */ 11 12 // Exit if accessed directly 13 if ( !defined( 'ABSPATH' ) ) exit; 14 15 /** 16 * Add a notification for a specific user, from a specific component 17 * 18 * @since BuddyPress (1.9) 19 * @param string $item_id 20 * @param int $user_id 21 * @param string $component_name 22 * @param string $component_action 23 * @param string $secondary_item_id 24 * @param string $date_notified 25 * @return boolean True on success, false on fail 26 */ 27 function bp_notifications_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false ) { 28 29 if ( empty( $date_notified ) ) { 30 $date_notified = bp_core_current_time(); 31 } 32 33 // Setup the new notification 34 $notification = new BP_Notifications_Notification; 35 $notification->item_id = $item_id; 36 $notification->user_id = $user_id; 37 $notification->component_name = $component_name; 38 $notification->component_action = $component_action; 39 $notification->date_notified = $date_notified; 40 $notification->is_new = 1; 41 $notification->secondary_item_id = $secondary_item_id; 42 43 // Save the new notification 44 return (bool) $notification->save(); 45 } 46 47 /** 48 * Get a specific notification by its ID 49 * 50 * @since BuddyPress (1.9) 51 * @param int $id 52 * @return BP_Notifications_Notification 53 */ 54 function bp_notifications_get_notification( $id ) { 55 return new BP_Notifications_Notification( $id ); 56 } 57 58 /** 59 * Delete a specific notification by its ID 60 * 61 * @since BuddyPress (1.9) 62 * @param int $id 63 * @return boolean True on success, false on fail 64 */ 65 function bp_notifications_delete_notification( $id ) { 66 if ( ! bp_notifications_check_notification_access( bp_loggedin_user_id(), $id ) ) { 67 return false; 68 } 69 70 return BP_Notifications_Notification::delete( $id ); 71 } 72 73 /** 74 * Get notifications for a specific user 75 * 76 * @since BuddyPress (1.9) 77 * @param int $user_id 78 * @param string $format 79 * @return boolean Object or array on success, false on fail 80 */ 81 function bp_notifications_get_notifications_for_user( $user_id, $format = 'simple' ) { 82 83 // Setup local variables 84 $bp = buddypress(); 85 $notifications = BP_Notifications_Notification::get_all_for_user( $user_id ); 86 $grouped_notifications = array(); // Notification groups 87 $renderable = array(); // Renderable notifications 88 89 // Group notifications by component and component_action and provide totals 90 for ( $i = 0, $count = count( $notifications ); $i < $count; ++$i ) { 91 $notification = $notifications[$i]; 92 $grouped_notifications[$notification->component_name][$notification->component_action][] = $notification; 93 } 94 95 // Bail if no notification groups 96 if ( empty( $grouped_notifications ) ) { 97 return false; 98 } 99 100 // Calculate a renderable output for each notification type 101 foreach ( $grouped_notifications as $component_name => $action_arrays ) { 102 103 // Skip if group is empty 104 if ( empty( $action_arrays ) ) { 105 continue; 106 } 107 108 // Skip inactive components 109 if ( !bp_is_active( $component_name ) ) { 110 continue; 111 } 112 113 // Loop through each actionable item and try to map it to a component 114 foreach ( (array) $action_arrays as $component_action_name => $component_action_items ) { 115 116 // Get the number of actionable items 117 $action_item_count = count( $component_action_items ); 118 119 // Skip if the count is less than 1 120 if ( $action_item_count < 1 ) { 121 continue; 122 } 123 124 // Callback function exists 125 if ( isset( $bp->{$component_name}->notification_callback ) && is_callable( $bp->{$component_name}->notification_callback ) ) { 126 127 // Function should return an object 128 if ( 'object' == $format ) { 129 130 // Retrieve the content of the notification using the callback 131 $content = call_user_func( 132 $bp->{$component_name}->notification_callback, 133 $component_action_name, 134 $component_action_items[0]->item_id, 135 $component_action_items[0]->secondary_item_id, 136 $action_item_count, 137 'array' 138 ); 139 140 // Create the object to be returned 141 $notification_object = new stdClass; 142 143 // Minimal backpat with non-compatible notification 144 // callback functions 145 if ( is_string( $content ) ) { 146 $notification_object->content = $content; 147 $notification_object->href = bp_loggedin_user_domain(); 148 } else { 149 $notification_object->content = $content['text']; 150 $notification_object->href = $content['link']; 151 } 152 153 $notification_object->id = $component_action_items[0]->id; 154 $renderable[] = $notification_object; 155 156 // Return an array of content strings 157 } else { 158 $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 ); 159 $renderable[] = $content; 160 } 161 162 // @deprecated format_notification_function - 1.5 163 } elseif ( isset( $bp->{$component_name}->format_notification_function ) && function_exists( $bp->{$component_name}->format_notification_function ) ) { 164 $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 ); 165 } 166 } 167 } 168 169 // If renderable is empty array, set to false 170 if ( empty( $renderable ) ) { 171 $renderable = false; 172 } 173 174 // Filter and return 175 return apply_filters( 'bp_core_get_notifications_for_user', $renderable, $user_id, $format ); 176 } 177 178 /** 179 * Delete notifications for a user by type 180 * 181 * Used when clearing out notifications for a specific component when the user 182 * has visited that component. 183 * 184 * @since BuddyPress (1.9) 185 * @param int $user_id 186 * @param string $component_name 187 * @param string $component_action 188 * @return boolean True on success, false on fail 189 */ 190 function bp_notifications_delete_notifications_by_type( $user_id, $component_name, $component_action ) { 191 return BP_Notifications_Notification::delete_for_user_by_type( $user_id, $component_name, $component_action ); 192 } 193 194 /** 195 * Delete notifications for an item ID 196 * 197 * Used when clearing out notifications for a specific component when the user 198 * has visited that component. 199 * 200 * @since BuddyPress (1.9) 201 * @param int $user_id 202 * @param string $component_name 203 * @param string $component_action 204 * @return boolean True on success, false on fail 205 */ 206 function bp_notifications_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false ) { 207 return BP_Notifications_Notification::delete_for_user_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id ); 208 } 209 210 /** 211 * Delete all notifications for by type 212 * 213 * Used when clearing out notifications for an entire component 214 * 215 * @since BuddyPress (1.9) 216 * @param int $user_id 217 * @param string $component_name 218 * @param string $component_action 219 * @return boolean True on success, false on fail 220 */ 221 function bp_notifications_delete_all_notifications_by_type( $item_id, $component_name, $component_action = false, $secondary_item_id = false ) { 222 return BP_Notifications_Notification::delete_all_by_type( $item_id, $component_name, $component_action, $secondary_item_id ); 223 } 224 225 /** 226 * Delete all notifications for a user 227 * 228 * Used when clearing out all notifications for a user, whene deleted or spammed 229 * 230 * @since BuddyPress (1.9) 231 * @param int $user_id 232 * @param string $component_name 233 * @param string $component_action 234 * @return boolean True on success, false on fail 235 */ 236 function bp_notifications_delete_notifications_from_user( $user_id, $component_name, $component_action ) { 237 return BP_Notifications_Notification::delete_from_user_by_type( $user_id, $component_name, $component_action ); 238 } 239 240 /** 241 * Check if a user has access to a specific notification 242 * 243 * Used before deleting a notification for a user 244 * 245 * @since BuddyPress (1.9) 246 * @param int $user_id 247 * @param int $notification_id 248 * @return boolean True on success, false on fail 249 */ 250 function bp_notifications_check_notification_access( $user_id, $notification_id ) { 251 return (bool) BP_Notifications_Notification::check_access( $user_id, $notification_id ); 252 } 253 254 /** 255 * Get the 256 * 257 * @since BuddyPress (1.9) 258 * @param int $user_id 259 * @return int 260 */ 261 function bp_notifications_get_unread_notification_count( $user_id = 0 ) { 262 263 // Default to displayed user if no ID is passed 264 if ( empty( $user_id ) ) { 265 $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id(); 266 } 267 268 // Get the notifications, and count them 269 $notifications = BP_Notifications_Notification::get_unread_for_user( $user_id ); 270 $count = !empty( $notifications ) ? count( $notifications ) : 0; 271 272 return apply_filters( 'bp_notifications_get_total_notification_count', $count ); 273 } -
new file plugins/buddypress/bp-notifications/bp-notifications-loader.php
diff --git a/plugins/buddypress/bp-notifications/bp-notifications-loader.php b/plugins/buddypress/bp-notifications/bp-notifications-loader.php new file mode 100644 index 0000000..b74238b
- + 1 <?php 2 3 /** 4 * BuddyPress Member Notifications Loader 5 * 6 * Functions and filters used for member notification 7 * 8 * @package BuddyPress 9 * @subpackage NotificationsLoader 10 */ 11 12 // Exit if accessed directly 13 if ( !defined( 'ABSPATH' ) ) exit; 14 15 class BP_Notifications_Component extends BP_Component { 16 17 /** 18 * Start the notifications component creation process 19 * 20 * @since BuddyPress (1.9) 21 */ 22 function __construct() { 23 parent::start( 24 'notifications', 25 __( 'Notifications', 'buddypress' ), 26 BP_PLUGIN_DIR, 27 array( 28 'adminbar_myaccount_order' => 100 29 ) 30 ); 31 } 32 33 /** 34 * Include files 35 */ 36 public function includes( $includes = array() ) { 37 $includes = array( 38 'classes', 39 'screens', 40 'adminbar', 41 'buddybar', 42 'template', 43 'functions', 44 ); 45 46 parent::includes( $includes ); 47 } 48 49 /** 50 * Setup globals 51 * 52 * The BP_FRIENDS_SLUG constant is deprecated, and only used here for 53 * backwards compatibility. 54 * 55 * @since BuddyPress (1.5) 56 */ 57 public function setup_globals( $args = array() ) { 58 $bp = buddypress(); 59 60 // Deprecated. Do not use. 61 // Defined conditionally to support unit tests. 62 if ( ! defined( 'BP_NOTIFICATIONS_DB_VERSION' ) ) { 63 define( 'BP_NOTIFICATIONS_DB_VERSION', '1900' ); 64 } 65 66 // Define a slug, if necessary 67 if ( !defined( 'BP_NOTIFICATIONS_SLUG' ) ) { 68 define( 'BP_NOTIFICATIONS_SLUG', $this->id ); 69 } 70 71 // Global tables for the notifications component 72 $global_tables = array( 73 'table_name' => $bp->table_prefix . 'bp_notifications' 74 ); 75 76 // All globals for the notifications component. 77 // Note that global_tables is included in this array. 78 $args = array( 79 'slug' => BP_NOTIFICATIONS_SLUG, 80 'has_directory' => false, 81 'search_string' => __( 'Search Notifications...', 'buddypress' ), 82 'global_tables' => $global_tables 83 ); 84 85 parent::setup_globals( $args ); 86 } 87 88 /** 89 * Setup BuddyBar navigation 90 */ 91 public function setup_nav( $main_nav = array(), $sub_nav = array() ) { 92 $bp = buddypress(); 93 94 // Add 'Notifications' to the main navigation 95 $count = bp_notifications_get_unread_notification_count( bp_loggedin_user_id() ); 96 $main_nav = array( 97 'name' => sprintf( __( 'Notifications <span>%d</span>', 'buddypress' ), number_format_i18n( $count ) ), 98 'slug' => $this->slug, 99 'position' => 60, 100 'screen_function' => 'bp_notifications_screen_unread', 101 'default_subnav_slug' => 'unread', 102 'item_css_id' => $this->id 103 ); 104 105 // Determine user to use 106 if ( bp_displayed_user_domain() ) { 107 $user_domain = bp_displayed_user_domain(); 108 } elseif ( bp_loggedin_user_domain() ) { 109 $user_domain = bp_loggedin_user_domain(); 110 } else { 111 return; 112 } 113 114 $notifications_link = trailingslashit( $user_domain . bp_get_notifications_slug() ); 115 116 // Add the subnav items to the notifications nav item 117 $sub_nav[] = array( 118 'name' => __( 'Unread', 'buddypress' ), 119 'slug' => 'unread', 120 'parent_url' => $notifications_link, 121 'parent_slug' => bp_get_notifications_slug(), 122 'screen_function' => 'bp_notifications_screen_unread', 123 'position' => 10, 124 'item_css_id' => 'notifications-my-notifications' 125 ); 126 127 $sub_nav[] = array( 128 'name' => __( 'Read', 'buddypress' ), 129 'slug' => 'read', 130 'parent_url' => $notifications_link, 131 'parent_slug' => bp_get_notifications_slug(), 132 'screen_function' => 'bp_notifications_screen_read', 133 'position' => 20, 134 'user_has_access' => bp_core_can_edit_settings() 135 ); 136 137 parent::setup_nav( $main_nav, $sub_nav ); 138 } 139 140 /** 141 * Set up the Toolbar 142 */ 143 public function setup_admin_bar( $wp_admin_nav = array() ) { 144 $bp = buddypress(); 145 146 // Menus for logged in user 147 if ( is_user_logged_in() ) { 148 149 // Setup the logged in user variables 150 $user_domain = bp_loggedin_user_domain(); 151 $notifications_link = trailingslashit( $user_domain . $this->slug ); 152 153 // Pending notification requests 154 $count = bp_notifications_get_unread_notification_count( bp_loggedin_user_id() ); 155 if ( !empty( $count ) ) { 156 $unread = sprintf( __( 'Notifications <span class="count">%s</span>', 'buddypress' ), number_format_i18n( $count ) ); 157 } else { 158 $unread = __( 'Notifications', 'buddypress' ); 159 } 160 161 // Add the "My Account" sub menus 162 $wp_admin_nav[] = array( 163 'parent' => $bp->my_account_menu_id, 164 'id' => 'my-account-' . $this->id, 165 'title' => $unread, 166 'href' => trailingslashit( $notifications_link ) 167 ); 168 169 // Unread 170 $wp_admin_nav[] = array( 171 'parent' => 'my-account-' . $this->id, 172 'id' => 'my-account-' . $this->id . '-unread', 173 'title' => __( 'Unread', 'buddypress' ), 174 'href' => trailingslashit( $notifications_link ) 175 ); 176 177 // Read 178 $wp_admin_nav[] = array( 179 'parent' => 'my-account-' . $this->id, 180 'id' => 'my-account-' . $this->id . '-read', 181 'title' => __( 'Read', 'buddypress' ), 182 'href' => trailingslashit( $notifications_link . 'read' ) 183 ); 184 } 185 186 parent::setup_admin_bar( $wp_admin_nav ); 187 } 188 189 /** 190 * Sets up the title for pages and <title> 191 */ 192 function setup_title() { 193 $bp = buddypress(); 194 195 // Adjust title 196 if ( bp_is_notifications_component() ) { 197 if ( bp_is_my_profile() ) { 198 $bp->bp_options_title = __( 'Friendships', 'buddypress' ); 199 } else { 200 $bp->bp_options_avatar = bp_core_fetch_avatar( array( 201 'item_id' => bp_displayed_user_id(), 202 'type' => 'thumb', 203 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() ) 204 ) ); 205 $bp->bp_options_title = bp_get_displayed_user_fullname(); 206 } 207 } 208 209 parent::setup_title(); 210 } 211 } 212 213 function bp_setup_notifications() { 214 buddypress()->notifications = new BP_Notifications_Component(); 215 } 216 add_action( 'bp_setup_components', 'bp_setup_notifications', 6 ); -
new file plugins/buddypress/bp-notifications/bp-notifications-screens.php
diff --git a/plugins/buddypress/bp-notifications/bp-notifications-screens.php b/plugins/buddypress/bp-notifications/bp-notifications-screens.php new file mode 100644 index 0000000..9718eff
- + 1 <?php 2 3 /** 4 * BuddyPress Notifications Screen Functions 5 * 6 * Screen functions are the controllers of BuddyPress. They will execute when their 7 * specific URL is caught. They will first save or manipulate data using business 8 * functions, then pass on the user to a template file. 9 * 10 * @package BuddyPress 11 * @subpackage NotificationsScreens 12 */ 13 14 // Exit if accessed directly 15 if ( !defined( 'ABSPATH' ) ) exit; 16 17 function bp_notifications_screen_unread() { 18 do_action( 'bp_notifications_screen_unread' ); 19 20 bp_core_load_template( apply_filters( 'bp_notifications_template_unread', 'members/single/home' ) ); 21 } 22 23 function bp_notifications_screen_read() { 24 do_action( 'bp_notifications_screen_read' ); 25 26 bp_core_load_template( apply_filters( 'bp_notifications_template_read', 'members/single/home' ) ); 27 } 28 29 function bp_notifications_screen_settings() { 30 31 } -
new file plugins/buddypress/bp-notifications/bp-notifications-template.php
diff --git a/plugins/buddypress/bp-notifications/bp-notifications-template.php b/plugins/buddypress/bp-notifications/bp-notifications-template.php new file mode 100644 index 0000000..973e469
- + 1 <?php 2 3 /** 4 * BuddyPress Notifications Template Functions 5 * 6 * @package BuddyPress 7 * @subpackage TonificationsTemplate 8 */ 9 10 // Exit if accessed directly 11 if ( !defined( 'ABSPATH' ) ) exit; 12 13 /** 14 * Output the notifications component slug 15 * 16 * @package BuddyPress 17 * @subpackage Notifications Template 18 * @since BuddyPress (1.9) 19 * 20 * @uses bp_get_notifications_slug() 21 */ 22 function bp_notifications_slug() { 23 echo bp_get_notifications_slug(); 24 } 25 /** 26 * Return the notifications component slug 27 * 28 * @package BuddyPress 29 * @subpackage Notifications Template 30 * @since BuddyPress (1.9) 31 */ 32 function bp_get_notifications_slug() { 33 return apply_filters( 'bp_get_notifications_slug', buddypress()->notifications->slug ); 34 } 35 36 /** 37 * Output the notifications component root slug 38 * 39 * @package BuddyPress 40 * @subpackage Notifications Template 41 * @since BuddyPress (1.9) 42 * 43 * @uses bp_get_notifications_root_slug() 44 */ 45 function bp_notifications_root_slug() { 46 echo bp_get_notifications_root_slug(); 47 } 48 /** 49 * Return the notifications component root slug 50 * 51 * @package BuddyPress 52 * @subpackage Notifications Template 53 * @since BuddyPress (1.9) 54 */ 55 function bp_get_notifications_root_slug() { 56 return apply_filters( 'bp_get_notifications_root_slug', buddypress()->notifications->root_slug ); 57 } 58 59 /** Main Loop *****************************************************************/ 60 61 /** 62 * Message Box Template Class 63 */ 64 class BP_Notifications_Template { 65 var $current_notification = -1; 66 var $current_notification_count; 67 var $total_notification_count; 68 var $notifications; 69 var $notification; 70 71 var $in_the_loop; 72 var $user_id; 73 74 var $pag_page; 75 var $pag_num; 76 var $pag_links; 77 var $search_terms; 78 79 public function __construct( $user_id, $is_new = 1, $per_page = 25, $max = null, $search_terms = '', $page_arg = 'npage' ) { 80 81 // Setup variables 82 $this->pag_page = isset( $_GET[$page_arg] ) ? intval( $_GET[$page_arg] ) : 1; 83 $this->pag_num = isset( $_GET['num'] ) ? intval( $_GET['num'] ) : $per_page; 84 $this->user_id = $user_id; 85 $this->is_new = $is_new; 86 $this->search_terms = $search_terms; 87 88 // Get the notifications 89 $notifications = BP_Notifications_Notification::get_current_notifications_for_user( $this->user_id, $this->is_new, $max, $this->pag_num, $this->search_terms ); 90 91 // Setup the notifications to loop through 92 $this->notifications = $notifications['notifications']; 93 $this->total_notification_count = count( $notifications['total'] ); 94 95 if ( empty( $this->notifications ) ) { 96 $this->notification_count = 0; 97 $this->total_notification_count = 0; 98 99 } else { 100 if ( !empty( $max ) ) { 101 if ( $max >= count( $this->notifications ) ) { 102 $this->notification_count = count( $this->notifications ); 103 } else { 104 $this->notification_count = (int) $max; 105 } 106 } else { 107 $this->notification_count = count( $this->notifications ); 108 } 109 } 110 111 if ( (int) $this->total_notification_count && (int) $this->pag_num ) { 112 $this->pag_links = paginate_links( array( 113 'base' => add_query_arg( $page_arg, '%#%' ), 114 'format' => '', 115 'total' => ceil( (int) $this->total_notification_count / (int) $this->pag_num ), 116 'current' => $this->pag_page, 117 'prev_text' => _x( '←', 'Notifications pagination previous text', 'buddypress' ), 118 'next_text' => _x( '→', 'Notifications pagination next text', 'buddypress' ), 119 'mid_size' => 1 120 ) ); 121 } 122 } 123 124 public function has_notifications() { 125 if ( $this->notification_count ) { 126 return true; 127 } 128 129 return false; 130 } 131 132 public function next_notification() { 133 134 $this->current_notification++; 135 136 $this->notification = $this->notifications[ $this->current_notification ]; 137 138 return $this->notification; 139 } 140 141 public function rewind_notifications() { 142 143 $this->current_notification = -1; 144 145 if ( $this->notification_count > 0 ) { 146 $this->notification = $this->notifications[0]; 147 } 148 } 149 150 public function notifications() { 151 152 if ( $this->current_notification + 1 < $this->notification_count ) { 153 return true; 154 155 } elseif ( $this->current_notification + 1 == $this->notification_count ) { 156 do_action( 'notifications_loop_end'); 157 158 $this->rewind_notifications(); 159 } 160 161 $this->in_the_loop = false; 162 return false; 163 } 164 165 public function the_notification() { 166 $this->in_the_loop = true; 167 $this->notification = $this->next_notification(); 168 169 // loop has just started 170 if ( 0 === $this->current_notification ) { 171 do_action( 'notifications_loop_start' ); 172 } 173 } 174 } 175 176 177 function bp_has_notifications( $args = '' ) { 178 179 // Get the default is_new argument 180 if ( bp_is_current_action( 'unread' ) ) { 181 $is_new = 1; 182 } elseif ( bp_is_current_action( 'read' ) ) { 183 $is_new = 0; 184 } 185 186 // Parse the args 187 $r = wp_parse_args( $args, array( 188 'user_id' => bp_loggedin_user_id(), 189 'is_new' => $is_new, 190 'per_page' => 25, 191 'max' => false, 192 'search_terms' => isset( $_REQUEST['s'] ) ? stripslashes( $_REQUEST['s'] ) : '', 193 'page_arg' => 'npage' 194 ) ); 195 196 // Get the notifications 197 $query_loop = new BP_Notifications_Template( $r['user_id'], $r['is_new'], $r['per_page'], $r['max'], $r['search_terms'], $r['page_arg'] ); 198 199 // Setup the global query loop 200 buddypress()->notifications->query_loop = $query_loop; 201 202 return apply_filters( 'bp_has_notificationss', $query_loop->has_notifications(), $query_loop ); 203 } 204 205 function bp_the_notifications() { 206 return buddypress()->notifications->query_loop->notifications(); 207 } 208 209 function bp_the_notification() { 210 return buddypress()->notifications->query_loop->the_notification(); 211 } 212 213 function bp_the_notification_id() { 214 echo bp_get_the_notification_id(); 215 } 216 function bp_get_the_notification_id() { 217 return apply_filters( 'bp_get_the_notification_id', buddypress()->notifications->query_loop->notification->id ); 218 } 219 220 function bp_the_notification_item_id() { 221 echo bp_get_the_notification_item_id(); 222 } 223 function bp_get_the_notification_item_id() { 224 return apply_filters( 'bp_get_the_notification_item_id', stripslashes_deep( buddypress()->notifications->query_loop->notification->item_id ) ); 225 } 226 227 function bp_the_notification_secondary_item_id() { 228 echo bp_get_the_notification_secondary_item_id(); 229 } 230 function bp_get_the_notification_secondary_item_id() { 231 return apply_filters( 'bp_get_the_notification_secondary_item_id', stripslashes_deep( buddypress()->notifications->query_loop->notification->secondary_item_id ) ); 232 } 233 234 function bp_the_notification_component_name() { 235 echo bp_get_the_notification_component_name(); 236 } 237 function bp_get_the_notification_component_name() { 238 return apply_filters( 'bp_get_the_notification_component_name', stripslashes_deep( buddypress()->notifications->query_loop->notification->component_name ) ); 239 } 240 241 function bp_the_notification_component_action() { 242 echo bp_get_the_notification_component_action(); 243 } 244 function bp_get_the_notification_component_action() { 245 return apply_filters( 'bp_get_the_notification_component_action', stripslashes_deep( buddypress()->notifications->query_loop->notification->component_action ) ); 246 } 247 248 function bp_the_notification_date_notified() { 249 echo bp_get_the_notification_date_notified(); 250 } 251 function bp_get_the_notification_date_notified() { 252 return apply_filters( 'bp_get_the_notification_date_notified', stripslashes_deep( buddypress()->notifications->query_loop->notification->date_notified ) ); 253 } -
plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/home.php
diff --git a/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/home.php b/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/home.php index 72b6d5a..0022cb3 100644
a b 45 45 elseif ( bp_is_user_forums() ) : 46 46 bp_get_template_part( 'members/single/forums' ); 47 47 48 elseif ( bp_is_user_notifications() ) : 49 bp_get_template_part( 'members/single/notifications' ); 50 48 51 elseif ( bp_is_user_settings() ) : 49 52 bp_get_template_part( 'members/single/settings' ); 50 53 -
new file plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications.php
diff --git a/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications.php b/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications.php new file mode 100644 index 0000000..082c2ea
- + 1 <?php 2 3 /** 4 * BuddyPress - Users Notifications 5 * 6 * @package BuddyPress 7 * @subpackage bp-legacy 8 */ 9 10 ?> 11 12 <div class="item-list-tabs no-ajax" id="subnav" role="navigation"> 13 <ul> 14 <?php if ( bp_is_my_profile() ) bp_get_options_nav(); ?> 15 16 <li id="members-order-select" class="last filter"> 17 18 <label for="members-friends"><?php _e( 'Order By:', 'buddypress' ); ?></label> 19 <select id="members-friends"> 20 <option value="newest"><?php _e( 'Newest First', 'buddypress' ); ?></option> 21 <option value="oldest"><?php _e( 'Oldest First', 'buddypress' ); ?></option> 22 </select> 23 </li> 24 </ul> 25 </div> 26 27 <?php 28 switch ( bp_current_action() ) : 29 30 // Unread 31 case 'unread' : 32 bp_get_template_part( 'members/single/notifications/unread' ); 33 break; 34 35 // Read 36 case 'read' : 37 bp_get_template_part( 'members/single/notifications/read' ); 38 break; 39 40 // Any other 41 default : 42 bp_get_template_part( 'members/single/plugins' ); 43 break; 44 endswitch; -
new file plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php
diff --git a/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php b/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/notifications-loop.php new file mode 100644 index 0000000..ee3986b
- + 1 <?php while ( bp_the_notifications() ) : bp_the_notification(); ?> 2 3 <tr> 4 <td></td> 5 <td><?php bp_the_notification_component_action(); ?></td> 6 <td><?php echo bp_core_get_userlink( bp_get_the_notification_item_id() ); ?></td> 7 <td><?php echo bp_core_time_since( bp_get_the_notification_date_notified() ); ?></td> 8 </tr> 9 10 <?php endwhile; -
new file plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/read.php
diff --git a/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/read.php b/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/read.php new file mode 100644 index 0000000..e55d6db
- + 1 <?php if ( bp_has_notifications() ) : ?> 2 3 <table class="notification-settings"> 4 <thead> 5 <tr> 6 <th class="icon"></th> 7 <th class="title"><?php _e( 'Notification', 'buddypress' ) ?></th> 8 <th class="title"><?php _e( 'Member', 'buddypress' ) ?></th> 9 <th class="date"><?php _e( 'Date Received', 'buddypress' ) ?></th> 10 </tr> 11 </thead> 12 13 <tbody> 14 <?php bp_get_template_part( 'members/single/notifications/notifications-loop' ); ?> 15 </tbody> 16 </table> 17 18 <?php else : ?> 19 20 <div id="message" class="info"> 21 <p><?php _e( 'You have no notifications.', 'buddypress' ); ?></p> 22 </div> 23 24 <?php endif; 25 No newline at end of file -
new file plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/unread.php
diff --git a/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/unread.php b/plugins/buddypress/bp-templates/bp-legacy/buddypress/members/single/notifications/unread.php new file mode 100644 index 0000000..df83326
- + 1 <?php if ( bp_has_notifications() ) : ?> 2 3 <table class="notification-settings"> 4 <thead> 5 <tr> 6 <th class="icon"></th> 7 <th class="title"><?php _e( 'Notification', 'buddypress' ) ?></th> 8 <th class="title"><?php _e( 'Member', 'buddypress' ) ?></th> 9 <th class="date"><?php _e( 'Date Received', 'buddypress' ) ?></th> 10 </tr> 11 </thead> 12 13 <tbody> 14 <?php bp_get_template_part( 'members/single/notifications/notifications-loop' ); ?> 15 </tbody> 16 </table> 17 18 <?php else : ?> 19 20 <div id="message" class="info"> 21 <p><?php _e( 'You have no new notifications.', 'buddypress' ); ?></p> 22 </div> 23 24 <?php endif; 25 No newline at end of file