Skip to:
Content

BuddyPress.org

Changeset 7521


Ignore:
Timestamp:
11/07/2013 05:15:51 PM (13 years ago)
Author:
johnjamesjacoby
Message:

First pass at bp-notifications component. Includes:

  • Backwards compatibility for old core functions.
  • Screens, functions, classes, and actions for Notifications.
  • Improved class methods for getting, updating, and deleting notifications.
  • Template parts in bp-legacy for theme compatibility.
  • A few basic unit tests.

@todo's:

  • Improve template output with dedicated functions, markup, classes, et all.
  • More unit tests.
  • Pagination links.
  • Auto-activate on update, so existing installations do not lose previously core functionality.

See #5148. Props johnjamesjacoby, boonebgorges, r-a-y.

Location:
trunk
Files:
13 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-core/admin/bp-core-components.php

    r7228 r7521  
    5959                        'title'       => __( 'Extended Profiles', 'buddypress' ),
    6060                        'description' => __( 'Customize your community with fully editable profile fields that allow your users to describe themselves.', 'buddypress' )
    61                 )
     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' )
     69                ),
    6270        );
    6371
    6472        $optional_components = bp_core_admin_get_components( 'optional' );
    6573        $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' );
    6775
    6876        // Don't show Forums component in optional components if it's disabled
    … …  
    372380                        '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' )
    373381                ),
     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                ),
    374386                'groups'   => array(
    375387                        'title'       => __( 'User Groups', 'buddypress' ),
  • trunk/bp-core/admin/bp-core-schema.php

    r7298 r7521  
    2424                $active_components = apply_filters( 'bp_active_components', bp_get_option( 'bp-active-components' ) );
    2525
    26         // Core DB Tables
    27         bp_core_install_notifications();
     26        // Notifications
     27        if ( !empty( $active_components['notifications'] ) )
     28                bp_core_install_notifications();
    2829
    2930        // Activity Streams
  • trunk/bp-core/bp-core-classes.php

    r7444 r7521  
    12921292
    12931293/**
    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.
    12961297 *
    12971298 * @package BuddyPress Core
     1299 * @deprecated since BuddyPress (1.9)
    12981300 */
    1299 
    13001301class BP_Core_Notification {
    13011302
  • trunk/bp-core/bp-core-loader.php

    r7451 r7521  
    5555
    5656                // 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' ) );
    5858
    5959                // Set the required components
    … …  
    178178                $bp->grav_default->blog  = apply_filters( 'bp_blog_gravatar_default',  $bp->grav_default->user );
    179179
    180                 // Notifications Table
     180                // Notifications table. Included here for legacy purposes. Use
     181                // bp-notifications instead.
    181182                $bp->core->table_name_notifications = $bp->table_prefix . 'bp_notifications';
    182183
  • trunk/bp-core/bp-core-template.php

    r7520 r7521  
    14371437
    14381438/**
     1439 * Check whether the current page is part of the Notifications component.
     1440 *
     1441 * @since BuddyPress (1.9.0)
     1442 *
     1443 * @return bool True if the current page is part of the Notifications component.
     1444 */
     1445function bp_is_notifications_component() {
     1446        if ( bp_is_current_component( 'notifications' ) ) {
     1447                return true;
     1448        }
     1449
     1450        return false;
     1451}
     1452
     1453/**
    14391454 * Check whether the current page is part of the Settings component.
    14401455 *
    … …  
    17461761        if ( bp_is_user_friends() && bp_is_current_action( 'requests' ) )
    17471762                return true;
     1763
     1764        return false;
     1765}
     1766
     1767/**
     1768 * Is this a user's notifications page?
     1769 *
     1770 * Eg http://example.com/members/joe/notifications/ (or a subpage thereof).
     1771 *
     1772 * @since BuddyPress (1.9.0)
     1773 *
     1774 * @return bool True if the current page is a user's Notifications page.
     1775 */
     1776function bp_is_user_notifications() {
     1777        if ( bp_is_user() && bp_is_notifications_component() ) {
     1778                return true;
     1779        }
    17481780
    17491781        return false;
  • trunk/bp-core/bp-core-update.php

    r7480 r7521  
    188188
    189189        $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,
    194195        ) );
    195196
  • trunk/bp-friends/bp-friends-classes.php

    r7507 r7521  
    364364                $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->friends->table_name} WHERE friend_user_id = %d OR initiator_user_id = %d", $user_id, $user_id ) );
    365365
    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                }
    368371
    369372                // Loop through friend_ids and update their counts
  • trunk/bp-members/bp-members-adminbar.php

    r7418 r7521  
    140140 */
    141141function bp_members_admin_bar_notifications_menu() {
    142         global $wp_admin_bar;
    143142
    144         if ( !is_user_logged_in() )
     143        // Bail if notifications is not active
     144        if ( ! bp_is_active( 'notifications' ) ) {
    145145                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 button
    153         $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->href
    167                         ) );
    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                 ) );
    176146        }
    177147
    178         return;
     148        bp_notifications_toolbar_menu();
    179149}
    180150add_action( 'admin_bar_menu', 'bp_members_admin_bar_notifications_menu', 90 );
  • trunk/bp-members/bp-members-buddybar.php

    r6760 r7521  
    1818function bp_adminbar_notifications_menu() {
    1919
    20         if ( !is_user_logged_in() )
     20        // Bail if notifications is not active
     21        if ( ! bp_is_active( 'notifications' ) ) {
    2122                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
    2923        }
    3024
    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();
    5226}
    5327add_action( 'bp_adminbar_menus', 'bp_adminbar_notifications_menu', 8 );
  • trunk/bp-members/bp-members-notifications.php

    r7173 r7521  
    44 * BuddyPress Member Notifications
    55 *
    6  * Functions and filters used for member notification
     6 * Backwards compatibility functions and filters used for member notifications.
     7 * Use bp-notifications instead.
    78 *
    89 * @package BuddyPress
    … …  
    2728function bp_core_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false ) {
    2829
    29         if ( empty( $date_notified ) )
    30                 $date_notified = bp_core_current_time();
     30        // Bail if notifications is not active
     31        if ( ! bp_is_active( 'notifications' ) ) {
     32                return false;
     33        }
    3134
    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;
     35        return bp_notifications_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false );
    4736}
    4837
    … …  
    5544 */
    5645function bp_core_delete_notification( $id ) {
    57         if ( !bp_core_check_notification_access( bp_loggedin_user_id(), $id ) )
     46
     47        // Bail if notifications is not active
     48        if ( ! bp_is_active( 'notifications' ) ) {
    5849                return false;
     50        }
    5951
    60         return BP_Core_Notification::delete( $id );
     52        return bp_notifications_delete_notification( $id );
    6153}
    6254
    … …  
    6961 */
    7062function bp_core_get_notification( $id ) {
    71         return new BP_Core_Notification( $id );
     63
     64        // Bail if notifications is not active
     65        if ( ! bp_is_active( 'notifications' ) ) {
     66                return false;
     67        }
     68
     69        return bp_notifications_get_notification( $id );
    7270}
    7371
    … …  
    8280 */
    8381function bp_core_get_notifications_for_user( $user_id, $format = 'simple' ) {
    84         global $bp;
    8582
    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;
     83        // Bail if notifications is not active
     84        if ( ! bp_is_active( 'notifications' ) ) {
     85                return false;
    9486        }
    9587
    96         // Bail if no notification groups
    97         if ( empty( $grouped_notifications ) )
    98                 return false;
     88        $renderable = bp_notifications_get_notifications_for_user( $user_id, $format );
    9989
    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                 // Skip inactive components
    108                 if ( !bp_is_active( $component_name ) )
    109                         continue;
    110 
    111                 // Loop through each actionable item and try to map it to a component
    112                 foreach ( (array) $action_arrays as $component_action_name => $component_action_items ) {
    113 
    114                         // Get the number of actionable items
    115                         $action_item_count = count( $component_action_items );
    116 
    117                         // Skip if the count is less than 1
    118                         if ( $action_item_count < 1 )
    119                                 continue;
    120 
    121                         // Callback function exists
    122                         if ( isset( $bp->{$component_name}->notification_callback ) && is_callable( $bp->{$component_name}->notification_callback ) ) {
    123 
    124                                 // Function should return an object
    125                                 if ( 'object' == $format ) {
    126 
    127                                         // Retrieve the content of the notification using the callback
    128                                         $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 returned
    138                                         $notification_object = new stdClass;
    139 
    140                                         // Minimal backpat with non-compatible notification
    141                                         // callback functions
    142                                         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 strings
    154                                 } 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.5
    160                         } 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         }
    165 
    166         // If renderable is empty array, set to false
    167         if ( empty( $renderable ) )
    168                 $renderable = false;
    169 
    170         // Filter and return
    17190        return apply_filters( 'bp_core_get_notifications_for_user', $renderable, $user_id, $format );
    17291}
    … …  
    185104 */
    186105function 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 );
     106
     107        // Bail if notifications is not active
     108        if ( ! bp_is_active( 'notifications' ) ) {
     109                return false;
     110        }
     111
     112        return bp_notifications_delete_notifications_by_type( $user_id, $component_name, $component_action );
    188113}
    189114
    … …  
    201126 */
    202127function 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 );
     128
     129        // Bail if notifications is not active
     130        if ( ! bp_is_active( 'notifications' ) ) {
     131                return false;
     132        }
     133
     134        return bp_notifications_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id );
    204135}
    205136
    … …  
    216147 */
    217148function 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 );
     149
     150        // Bail if notifications is not active
     151        if ( ! bp_is_active( 'notifications' ) ) {
     152                return false;
     153        }
     154
     155        bp_notifications_delete_all_notifications_by_type( $item_id, $component_name, $component_action, $secondary_item_id );
    219156}
    220157
    … …  
    231168 */
    232169function 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 );
     170
     171        // Bail if notifications is not active
     172        if ( ! bp_is_active( 'notifications' ) ) {
     173                return false;
     174        }
     175
     176        return bp_notifications_delete_notifications_from_user( $user_id, $component_name, $component_action );
    234177}
    235178
    … …  
    245188 */
    246189function bp_core_check_notification_access( $user_id, $notification_id ) {
    247         if ( !BP_Core_Notification::check_access( $user_id, $notification_id ) )
     190
     191        // Bail if notifications is not active
     192        if ( ! bp_is_active( 'notifications' ) ) {
    248193                return false;
     194        }
    249195
    250         return true;
     196        return bp_notifications_check_notification_access( $user_id, $notification_id );
    251197}
  • trunk/bp-templates/bp-legacy/buddypress/members/single/home.php

    r7202 r7521  
    4646                        bp_get_template_part( 'members/single/forums'   );
    4747
     48                elseif ( bp_is_user_notifications() ) :
     49                        bp_get_template_part( 'members/single/notifications' );
     50
    4851                elseif ( bp_is_user_settings() ) :
    4952                        bp_get_template_part( 'members/single/settings' );
  • trunk/tests/includes/factory.php

    r7107 r7521  
    1010                $this->xprofile_group = new BP_UnitTest_Factory_For_XProfileGroup( $this );
    1111                $this->xprofile_field = new BP_UnitTest_Factory_For_XProfileField( $this );
     12                $this->notification = new BP_UnitTest_Factory_For_Notification( $this );
    1213        }
    1314}
    … …  
    147148        }
    148149}
     150
     151class BP_UnitTest_Factory_For_Notification extends WP_UnitTest_Factory_For_Thing {
     152        public function __construct( $factory = null ) {
     153                parent::__construct( $factory );
     154        }
     155
     156        public function create_object( $args ) {
     157                return bp_notifications_add_notification( $args );
     158        }
     159
     160        public function update_object( $id, $fields ) {}
     161
     162        public function get_object_by_id( $id ) {
     163                return new BP_Notifications_Notification( $id );
     164        }
     165}
  • trunk/tests/includes/install.php

    r7421 r7521  
    2727
    2828function wp_test_bp_install( $value ) {
    29         return array( 'activity' => 1, 'blogs' => 1, 'friends' => 1, 'groups' => 1, 'members' => 1, 'messages' => 1, 'settings' => 1, 'xprofile' => 1, );
     29        return array( 'activity' => 1, 'blogs' => 1, 'friends' => 1, 'groups' => 1, 'members' => 1, 'messages' => 1, 'notifications' => 1, 'settings' => 1, 'xprofile' => 1, );
    3030}
    3131tests_add_filter( 'bp_new_install_default_components', 'wp_test_bp_install' );
Note: See TracChangeset for help on using the changeset viewer.