Skip to:
Content

BuddyPress.org

Changeset 9257


Ignore:
Timestamp:
12/22/2014 09:46:50 PM (11 years ago)
Author:
r-a-y
Message:

Activity: Support multiple scopes in bp_has_activities().

This commit:

  • Allows the 'scope' parameter to support multiple scopes. For example, scope=friends,mentions. This can be a comma-delimited string or an array.
  • Makes the 'scope' parameter available across the bp_has_activities() stack. Previously, 'scope' was only available for use in the bp_has_activities() loop.
  • Parses scopes using the BP_Activity_Query class to handle complex conditions.
  • Allows components to declare their own custom activity scopes. Components can also override existing activity arguments by setting the 'override' key in their scope callback. For an example, see how the friends component declares the 'friends' scope in bp_friends_filter_activity_scope(). Previously, it was not possible for components or third-party plugins to declare their own scopes without doing a fair bit of workarounds.

See #4988.

Location:
trunk/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-activity/bp-activity-classes.php

    r9256 r9257  
    261261     *     An array of arguments. All items are optional.
    262262     *
    263      *     @type int         $page              Which page of results to fetch. Using page=1 without per_page will result
    264      *                                          in no pagination. Default: 1.
    265      *     @type int|bool    $per_page          Number of results per page. Default: 25.
    266      *     @type int|bool    $max               Maximum number of results to return. Default: false (unlimited).
    267      *     @type string      $sort              ASC or DESC. Default: 'DESC'.
    268      *     @type array       $exclude           Array of activity IDs to exclude. Default: false.
    269      *     @type array       $in                Array of ids to limit query by (IN). Default: false.
    270      *     @type array       $meta_query        Array of meta_query conditions. See WP_Meta_Query::queries.
    271      *     @type array       $date_query        Array of date_query conditions. See first parameter of
    272      *                                          WP_Date_Query::__construct().
    273      *     @type array       $filter_query      Array of advanced query conditions. See BP_Activity_Query::__construct().
    274      *     @type array       $filter            See BP_Activity_Activity::get_filter_sql().
    275      *     @type string      $search_terms      Limit results by a search term. Default: false.
    276      *     @type bool        $display_comments  Whether to include activity comments. Default: false.
    277      *     @type bool        $show_hidden       Whether to show items marked hide_sitewide. Default: false.
    278      *     @type string      $spam              Spam status. Default: 'ham_only'.
    279      *     @type bool        $update_meta_cache Whether to pre-fetch metadata for queried activity items. Default: true.
    280      *     @type string|bool $count_total       If true, an additional DB query is run to count the total activity items
    281      *                                          for the query. Default: false.
     263     *     @type int          $page              Which page of results to fetch. Using page=1 without per_page will result
     264     *                                           in no pagination. Default: 1.
     265     *     @type int|bool     $per_page          Number of results per page. Default: 25.
     266     *     @type int|bool     $max               Maximum number of results to return. Default: false (unlimited).
     267     *     @type string       $sort              ASC or DESC. Default: 'DESC'.
     268     *     @type array        $exclude           Array of activity IDs to exclude. Default: false.
     269     *     @type array        $in                Array of ids to limit query by (IN). Default: false.
     270     *     @type array        $meta_query        Array of meta_query conditions. See WP_Meta_Query::queries.
     271     *     @type array        $date_query        Array of date_query conditions. See first parameter of
     272     *                                           WP_Date_Query::__construct().
     273     *     @type array        $filter_query      Array of advanced query conditions. See BP_Activity_Query::__construct().
     274     *     @type string|array $scope             Pre-determined set of activity arguments.
     275     *     @type array        $filter            See BP_Activity_Activity::get_filter_sql().
     276     *     @type string       $search_terms      Limit results by a search term. Default: false.
     277     *     @type bool         $display_comments  Whether to include activity comments. Default: false.
     278     *     @type bool         $show_hidden       Whether to show items marked hide_sitewide. Default: false.
     279     *     @type string       $spam              Spam status. Default: 'ham_only'.
     280     *     @type bool         $update_meta_cache Whether to pre-fetch metadata for queried activity items. Default: true.
     281     *     @type string|bool  $count_total       If true, an additional DB query is run to count the total activity items
     282     *                                           for the query. Default: false.
    282283     * }
    283284     * @return array The array returned has two keys:
     
    321322            'filter_query'      => false,      // Advanced filtering - see BP_Activity_Query
    322323            'filter'            => false,      // See self::get_filter_sql()
     324            'scope'             => false,      // Preset activity arguments
    323325            'search_terms'      => false,      // Terms to search by
    324326            'display_comments'  => false,      // Whether to include activity comments
     
    343345        $excluded_types = array();
    344346
     347        // Scope takes precedence
     348        if ( ! empty( $r['scope'] ) ) {
     349            $scope_query = self::get_scope_query_sql( $r['scope'], $r );
     350
     351            if ( ! empty( $scope_query['sql'] ) ) {
     352                $where_conditions['scope_query_sql'] = $scope_query['sql'];
     353            }
     354
     355            // override some arguments if needed
     356            if ( ! empty( $scope_query['override'] ) ) {
     357                $r = array_replace_recursive( $r, $scope_query['override'] );
     358            }
    345359        // Advanced filtering
    346         if ( ! empty( $r['filter_query'] ) ) {
     360        } elseif ( ! empty( $r['filter_query'] ) ) {
    347361            $filter_query = new BP_Activity_Query( $r['filter_query'] );
    348362            if ( $sql = $filter_query->get_sql() ) {
     
    521535
    522536        } else {
    523 
    524537            // Query first for activity IDs
    525538            $activity_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}";
     
    819832
    820833        return $sql;
     834    }
     835
     836    /**
     837     * Get the SQL for the 'scope' param in BP_Activity_Activity::get().
     838     *
     839     * A scope is a predetermined set of activity arguments.  This method is used
     840     * to grab these activity arguments and override any existing args if needed.
     841     *
     842     * Can handle multple scopes.
     843     *
     844     * @since BuddyPress (2.2.0)
     845     *
     846     * @param  string $scope The activity scope
     847     * @param  array  $r     Current activity arguments. Same as those of BP_Activity_Activity::get(),
     848     *                       but merged with defaults.
     849     * @return array 'sql' WHERE SQL string and 'override' activity args
     850     */
     851    public static function get_scope_query_sql( $scope = '', $r = array() ) {
     852        $query_args = array();
     853        $override   = array();
     854        $retval     = array();
     855
     856        if ( ! is_array( $scope ) ) {
     857            $scopes = explode( ',', $scope );
     858        } else {
     859            $scopes = $scope;
     860        }
     861
     862        if ( empty( $scopes ) ) {
     863            return $sql;
     864        }
     865
     866        // helper to easily grab the 'user_id'
     867        if ( ! empty( $r['filter']['user_id'] ) ) {
     868            $r['user_id'] = $r['filter']['user_id'];
     869        }
     870
     871        // parse each scope; yes! we handle multiples!
     872        foreach ( $scopes as $scope ) {
     873            $scope_args = array();
     874
     875            switch ( $scope ) {
     876                case 'just-me' :
     877                    $scope_args = array(
     878                        'column' => 'user_id',
     879                        'value'  => $r['user_id']
     880                    );
     881
     882                    $scope_args['override']['display_comments'] = 'stream';
     883
     884                    // wipe out the user ID
     885                    $scope_args['override']['filter']['user_id'] = 0;
     886
     887                    break;
     888
     889                case 'favorites':
     890                    $favs = bp_activity_get_user_favorites( $r['user_id'] );
     891                    if ( empty( $favs ) ) {
     892                        return $scope_args;
     893                    }
     894
     895                    $scope_args = array(
     896                        'column'  => 'id',
     897                        'compare' => 'IN',
     898                        'value'   => (array) $favs
     899                    );
     900                    $scope_args['override']['display_comments']  = true;
     901
     902                    // wipe out the user ID
     903                    $scope_args['override']['filter']['user_id'] = 0;
     904
     905                    break;
     906
     907                case 'mentions':
     908                    // Are mentions disabled?
     909                    if ( ! bp_activity_do_mentions() ) {
     910                        return $scope_args;
     911                    }
     912
     913                    $scope_args = array(
     914                        'column'  => 'content',
     915                        'compare' => 'LIKE',
     916
     917                        // Start search at @ symbol and stop search at closing tag delimiter.
     918                        'value'   => '@' . bp_activity_get_user_mentionname( $r['user_id'] ) . '<'
     919                    );
     920
     921                    // wipe out current search terms if any
     922                    // this is so the 'mentions' scope can be combined with other scopes
     923                    $scope_args['override']['search_terms'] = false;
     924
     925                    $scope_args['override']['display_comments'] = 'stream';
     926                    $scope_args['override']['filter']['user_id'] = 0;
     927
     928                    break;
     929
     930                default :
     931                    /**
     932                     * Plugins can hook here to set their activity arguments for custom scopes.
     933                     *
     934                     * This is a dynamic filter based on the activity scope. eg:
     935                     *   - 'bp_activity_set_groups_scope_args'
     936                     *   - 'bp_activity_set_friends_scope_args'
     937                     *
     938                     * To see how this filter is used, plugin devs should check out:
     939                     *   - bp_groups_filter_activity_scope() - used for 'groups' scope
     940                     *   - bp_friends_filter_activity_scope() - used for 'friends' scope
     941                     *
     942                     * @since BuddyPress (2.2.0)
     943                     *
     944                     *  @param array {
     945                     *     Activity query clauses.
     946                     *
     947                     *     @type array {
     948                     *         Activity arguments for your custom scope.
     949                     *         See {@link BP_Activity_Query::_construct()} for more details.
     950                     *     }
     951                     *     @type array $override Optional. Override existing activity arguments passed by $r.
     952                     * }
     953                     * @param array $r Current activity arguments passed in BP_Activity_Activity::get()
     954                     */
     955                    $scope_args = apply_filters( "bp_activity_set_{$scope}_scope_args", array(), $r );
     956                    break;
     957            }
     958
     959            if ( ! empty( $scope_args ) ) {
     960                // merge override properties from other scopes
     961                // this might be a problem...
     962                if ( ! empty( $scope_args['override'] ) ) {
     963                    $override = array_merge( $override, $scope_args['override'] );
     964                    unset( $scope_args['override'] );
     965                }
     966
     967                // save scope args
     968                if ( ! empty( $scope_args ) ) {
     969                    $query_args[] = $scope_args;
     970                }
     971            }
     972        }
     973
     974        if ( ! empty( $query_args ) ) {
     975            // set relation to OR
     976            $query_args['relation'] = 'OR';
     977
     978            $query = new BP_Activity_Query( $query_args );
     979            if ( $sql = $query->get_sql() ) {
     980                $retval['sql'] = $sql;
     981            }
     982        }
     983
     984        if ( ! empty( $override ) ) {
     985            $retval['override'] = $override;
     986        }
     987
     988        return $retval;
    821989    }
    822990
  • trunk/src/bp-activity/bp-activity-functions.php

    r9256 r9257  
    14241424        'update_meta_cache' => true,
    14251425        'count_total'       => false,
     1426        'scope'             => false,
    14261427
    14271428        /**
     
    14391440
    14401441    // Attempt to return a cached copy of the first page of sitewide activity.
    1441     if ( ( 1 === (int) $r['page'] ) && empty( $r['max'] ) && empty( $r['search_terms'] ) && empty( $r['meta_query'] ) && empty( $r['date_query'] ) && empty( $r['filter_query'] ) && empty( $r['filter'] ) && empty( $r['exclude'] ) && empty( $r['in'] ) && ( 'DESC' === $r['sort'] ) && empty( $r['exclude'] ) && ( 'ham_only' === $r['spam'] ) ) {
     1442    if ( ( 1 === (int) $r['page'] ) && empty( $r['max'] ) && empty( $r['search_terms'] ) && empty( $r['meta_query'] ) && empty( $r['date_query'] ) && empty( $r['filter_query'] ) && empty( $r['filter'] ) && empty( $r['scope'] )&& empty( $r['exclude'] ) && empty( $r['in'] ) && ( 'DESC' === $r['sort'] ) && empty( $r['exclude'] ) && ( 'ham_only' === $r['spam'] ) ) {
    14421443
    14431444        $activity = wp_cache_get( 'bp_activity_sitewide_front', 'bp' );
     
    14541455                'filter_query'      => $r['filter_query'],
    14551456                'filter'            => $r['filter'],
     1457                'scope'             => $r['scope'],
    14561458                'display_comments'  => $r['display_comments'],
    14571459                'show_hidden'       => $r['show_hidden'],
     
    14751477            'filter_query'     => $r['filter_query'],
    14761478            'filter'           => $r['filter'],
     1479            'scope'            => $r['scope'],
    14771480            'display_comments' => $r['display_comments'],
    14781481            'show_hidden'      => $r['show_hidden'],
  • trunk/src/bp-activity/bp-activity-template.php

    r9256 r9257  
    202202            'in'                => false,
    203203            'filter'            => false,
     204            'scope'             => false,
    204205            'search_terms'      => false,
    205206            'meta_query'        => false,
     
    253254                'filter_query'      => $filter_query,
    254255                'filter'            => $filter,
     256                'scope'             => $scope,
    255257                'show_hidden'       => $show_hidden,
    256258                'exclude'           => $exclude,
     
    614616    }
    615617
     618    // Search terms
    616619    if ( empty( $search_terms ) && ! empty( $_REQUEST['s'] ) )
    617620        $search_terms = $_REQUEST['s'];
    618621
    619     // If you have passed a "scope" then this will override any filters you have passed.
    620     if ( 'just-me' == $scope || 'friends' == $scope || 'groups' == $scope || 'favorites' == $scope || 'mentions' == $scope ) {
    621         if ( 'just-me' == $scope )
    622             $display_comments = 'stream';
    623 
    624         // determine which user_id applies
    625         if ( empty( $user_id ) )
     622    // Set some default arguments when using a scope
     623    if ( ! empty( $scope ) ) {
     624        // Determine which user ID applies
     625        if ( empty( $user_id ) ) {
    626626            $user_id = bp_displayed_user_id() ? bp_displayed_user_id() : bp_loggedin_user_id();
    627 
    628         // are we displaying user specific activity?
    629         if ( is_numeric( $user_id ) ) {
    630             $show_hidden = ( $user_id == bp_loggedin_user_id() && $scope != 'friends' ) ? 1 : 0;
    631 
    632             switch ( $scope ) {
    633                 case 'friends':
    634                     if ( bp_is_active( 'friends' ) )
    635                         $friends = friends_get_friend_user_ids( $user_id );
    636                         if ( empty( $friends ) )
    637                             return false;
    638 
    639                         $user_id = implode( ',', (array) $friends );
    640                     break;
    641                 case 'groups':
    642                     if ( bp_is_active( 'groups' ) ) {
    643                         $groups = groups_get_user_groups( $user_id );
    644                         if ( empty( $groups['groups'] ) )
    645                             return false;
    646 
    647                         $object = $bp->groups->id;
    648                         $primary_id = implode( ',', (array) $groups['groups'] );
    649 
    650                         $user_id = 0;
    651                     }
    652                     break;
    653                 case 'favorites':
    654                     $favs = bp_activity_get_user_favorites( $user_id );
    655                     if ( empty( $favs ) )
    656                         return false;
    657 
    658                     $in = implode( ',', (array) $favs );
    659                     $display_comments = true;
    660                     $user_id = 0;
    661                     break;
    662                 case 'mentions':
    663 
    664                     // Are mentions disabled?
    665                     if ( ! bp_activity_do_mentions() ) {
    666                         return false;
    667                     }
    668 
    669                     // Start search at @ symbol and stop search at closing tag delimiter.
    670                     $search_terms     = '@' . bp_activity_get_user_mentionname( $user_id ) . '<';
    671                     $display_comments = 'stream';
    672                     $user_id = 0;
    673                     break;
    674             }
     627        }
     628
     629        // Should we show all items regardless of sitewide visibility?
     630        if ( ! empty( $user_id ) ) {
     631            $show_hidden = ( $user_id == bp_loggedin_user_id() ) ? 1 : 0;
    675632        }
    676633    }
     
    713670        'in'                => $in,
    714671        'filter'            => $filter,
     672        'scope'             => $scope,
    715673        'search_terms'      => $search_terms,
    716674        'meta_query'        => $meta_query,
  • trunk/src/bp-friends/bp-friends-activity.php

    r9154 r9257  
    229229
    230230/**
     231 * Set up activity arguments for use with the 'friends' scope.
     232 *
     233 * For details on the syntax, see {@link BP_Activity_Query}.
     234 *
     235 * @since BuddyPress (2.2.0)
     236 *
     237 * @param array $retval Empty array by default
     238 * @param array $filter Current activity arguments
     239 * @return array
     240 */
     241function bp_friends_filter_activity_scope( $retval, $filter ) {
     242    $friends = friends_get_friend_user_ids( $filter['user_id'] );
     243
     244    if ( empty( $friends ) ) {
     245        return $retval;
     246    }
     247
     248    $retval= array(
     249        'relation' => 'AND',
     250        array(
     251            'column'  => 'user_id',
     252            'compare' => 'IN',
     253            'value'   => (array) $friends
     254        ),
     255        // we should only be able to view sitewide activity content for friends
     256        array(
     257            'column' => 'hide_sitewide',
     258            'value'  => 0
     259        ),
     260    );
     261
     262    // wipe out the user ID
     263    $retval['override']['filter']['user_id'] = 0;
     264
     265    // make sure we aren't limiting items by 'hide_sitewide' since we're already
     266    // limiting it above
     267    $scope_args['override']['show_hidden'] = true;
     268
     269    return $retval;
     270}
     271add_filter( 'bp_activity_set_friends_scope_args', 'bp_friends_filter_activity_scope', 10, 2 );
     272
     273/**
    231274 * Add activity stream items when one members accepts another members request
    232275 * for virtual friendship.
  • trunk/src/bp-groups/bp-groups-activity.php

    r9204 r9257  
    235235
    236236/**
     237 * Set up activity arguments for use with the 'groups' scope.
     238 *
     239 * @since BuddyPress (2.2.0)
     240 *
     241 * @param array $retval Empty array by default
     242 * @param array $filter Current activity arguments
     243 * @return array
     244 */
     245function bp_groups_filter_activity_scope( $retval, $filter ) {
     246    $groups = groups_get_user_groups( $filter['user_id'] );
     247
     248    if ( empty( $groups['groups'] ) ) {
     249        return $retval;
     250    }
     251
     252    $retval= array(
     253        'relation' => 'AND',
     254        array(
     255            'column' => 'component',
     256            'value'  => buddypress()->groups->id
     257        ),
     258        array(
     259            'column'  => 'item_id',
     260            'compare' => 'IN',
     261            'value'   => (array) $groups['groups']
     262        ),
     263    );
     264
     265    // wipe out the user ID
     266    $retval['override']['filter']['user_id'] = 0;
     267
     268    return $retval;
     269}
     270add_filter( 'bp_activity_set_groups_scope_args', 'bp_groups_filter_activity_scope', 10, 2 );
     271
     272/**
    237273 * Record an activity item related to the Groups component.
    238274 *
Note: See TracChangeset for help on using the changeset viewer.