Skip to:
Content

BuddyPress.org

Changeset 7521


Ignore:
Timestamp:
11/07/2013 05:15:51 PM (11 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.