Skip to:
Content

BuddyPress.org

Changeset 13988


Ignore:
Timestamp:
07/27/2024 07:58:27 PM (2 years ago)
Author:
espellcaste
Message:

Activity: Add cache_results flag to the BP_Activity_Activity::get getter.

When performing a request with cache_results, it stops the activity information retrieved from being added to the cache.

See #8552
Closes https://github.com/buddypress/buddypress/pull/343/

Location:
trunk
Files:
3 edited

Legend:

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

    r13927 r13988  
    18711871 * @since 1.2.0
    18721872 * @since 2.4.0 Introduced the `$fields` parameter.
     1873 * @since 15.0.0 Introduced the `cache_results` parameter.
    18731874 *
    18741875 * @see BP_Activity_Activity::get() For more information on accepted arguments
     
    18991900                        'in'                => false,        // Comma-separated list or array of activity IDs to which you want to limit the query.
    19001901                        'spam'              => 'ham_only',   // 'ham_only' (default), 'spam_only' or 'all'.
     1902                        'cache_results'     => true,
    19011903                        'update_meta_cache' => true,
    19021904                        'count_total'       => false,
     
    19381940                        'in'                => $r['in'],
    19391941                        'spam'              => $r['spam'],
     1942                        'cache_results'     => $r['cache_results'],
    19401943                        'update_meta_cache' => $r['update_meta_cache'],
    19411944                        'count_total'       => $r['count_total'],
     
    19601963 *
    19611964 * @since 1.2.0
     1965 * @since 15.0.0 Introduced the `cache_results` parameter.
    19621966 *
    19631967 * @see BP_Activity_Activity::get() For more information on accepted arguments.
     
    19851989                        'sort'              => 'DESC',     // Sort ASC or DESC.
    19861990                        'spam'              => 'ham_only', // Retrieve items marked as spam.
     1991                        'cache_results'     => true,
    19871992                        'update_meta_cache' => true,
    19881993                ),
     
    19992004                'sort'              => $r['sort'],
    20002005                'spam'              => $r['spam'],
     2006                'cache_results'     => $r['cache_results'],
    20012007                'update_meta_cache' => $r['update_meta_cache'],
    20022008        );
  • trunk/src/bp-activity/classes/class-bp-activity-activity.php

    r13897 r13988  
    383383         *     @type bool         $show_hidden       Whether to show items marked hide_sitewide. Default: false.
    384384         *     @type string       $spam              Spam status. Default: 'ham_only'.
     385         *     @type bool         $cache_results     Optional. Whether to cache activity information. Default true.
    385386         *     @type bool         $update_meta_cache Whether to pre-fetch metadata for queried activity items. Default: true.
    386387         *     @type string|bool  $count_total       If true, an additional DB query is run to count the total activity items
     
    451452                                'show_hidden'       => false,           // Show items marked hide_sitewide.
    452453                                'spam'              => 'ham_only',      // Spam status.
    453                                 'update_meta_cache' => true,            // Whether or not to update meta cache.
    454                                 'count_total'       => false,           // Whether or not to use count_total.
     454                                'cache_results'     => true,            // Whether to cache activity information.
     455                                'update_meta_cache' => true,            // Whether to update meta cache.
     456                                'count_total'       => false,           // Whether to use count_total.
    455457                                'count_total_only'  => false,           // Whether to only get the total count.
    456458                        )
     
    494496
    495497                // Regular filtering.
    496                 if ( $r['filter'] && $filter_sql = BP_Activity_Activity::get_filter_sql( $r['filter'] ) ) {
     498                if ( $r['filter'] && $filter_sql = self::get_filter_sql( $r['filter'] ) ) {
    497499                        $where_conditions['filter_sql'] = $filter_sql;
    498500                }
     
    735737                        }
    736738
    737                         /*
    738                          * Queries that include 'last_activity' are cached separately,
    739                          * since they are generally much less long-lived.
    740                          */
    741                         if ( preg_match( '/a\.type NOT IN \([^\)]*\'last_activity\'[^\)]*\)/', $activity_sql ) ) {
    742                                 $cache_group = 'bp_activity';
    743                         } else {
    744                                 $cache_group = 'bp_activity_with_last_activity';
    745                         }
    746 
    747739                        $activities = $wpdb->get_results( $activity_sql );
    748740
     
    758750                                $activities[ $i ]->is_spam           = (int) $ac->is_spam;
    759751                        }
    760 
    761752                } elseif ( ! $only_get_count ) {
    762753                        // Query first for activity IDs.
     
    779770                        $activity_ids_sql = apply_filters( 'bp_activity_paged_activities_sql', $activity_ids_sql, $r );
    780771
    781                         /*
    782                          * Queries that include 'last_activity' are cached separately,
    783                          * since they are generally much less long-lived.
    784                          */
    785                         if ( preg_match( '/a\.type NOT IN \([^\)]*\'last_activity\'[^\)]*\)/', $activity_ids_sql ) ) {
    786                                 $cache_group = 'bp_activity';
     772                        if ( $r['cache_results'] ) {
     773                                /*
     774                                 * Queries that include 'last_activity' are cached separately,
     775                                 * since they are generally much less long-lived.
     776                                 */
     777                                $cache_group = ( preg_match( '/a\.type NOT IN \([^\)]*\'last_activity\'[^\)]*\)/', $activity_ids_sql ) )
     778                                        ? 'bp_activity'
     779                                        : 'bp_activity_with_last_activity';
     780
     781                                $cached = bp_core_get_incremented_cache( $activity_ids_sql, $cache_group );
     782                                if ( false === $cached ) {
     783                                        $activity_ids = $wpdb->get_col( $activity_ids_sql );
     784                                        bp_core_set_incremented_cache( $activity_ids_sql, $cache_group, $activity_ids );
     785                                } else {
     786                                        $activity_ids = $cached;
     787                                }
    787788                        } else {
    788                                 $cache_group = 'bp_activity_with_last_activity';
    789                         }
    790 
    791                         $cached = bp_core_get_incremented_cache( $activity_ids_sql, $cache_group );
    792                         if ( false === $cached ) {
    793789                                $activity_ids = $wpdb->get_col( $activity_ids_sql );
    794                                 bp_core_set_incremented_cache( $activity_ids_sql, $cache_group, $activity_ids );
    795                         } else {
    796                                 $activity_ids = $cached;
    797790                        }
    798791
     
    808801                                $activities = array_map( 'intval', $activity_ids );
    809802                        } else {
    810                                 $activities = self::get_activity_data( $activity_ids );
     803                                $activities = self::get_activity_data( $activity_ids, $r['cache_results'] );
    811804                        }
    812805                }
     
    818811                        // Get activity meta.
    819812                        $activity_ids = array();
    820                         foreach ( (array) $activities as $activity ) {
     813                        foreach ( $activities as $activity ) {
    821814                                $activity_ids[] = $activity->id;
    822815                        }
     
    826819                        }
    827820
    828                         if ( $activities && $r['display_comments'] ) {
    829                                 $activities = BP_Activity_Activity::append_comments( $activities, $r['spam'] );
     821                        if ( $r['display_comments'] ) {
     822                                $activities = self::append_comments( $activities, $r['spam'] );
    830823                        }
    831824
    832825                        // Pre-fetch data associated with activity users and other objects.
    833                         BP_Activity_Activity::prefetch_object_data( $activities );
     826                        self::prefetch_object_data( $activities );
    834827
    835828                        // Generate action strings.
    836                         $activities = BP_Activity_Activity::generate_action_strings( $activities );
     829                        $activities = self::generate_action_strings( $activities );
    837830                }
    838831
     
    841834                // Only query the count total if requested.
    842835                if ( ! empty( $r['count_total'] ) || $only_get_count ) {
     836                        $total_activities_sql = "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$join_sql} {$where_sql}";
     837
    843838                        /**
    844839                         * Filters the total activities MySQL statement.
     
    846841                         * @since 1.5.0
    847842                         *
    848                          * @param string $value    MySQL statement used to query for total activities.
    849                          * @param string $where_sql MySQL WHERE statement portion.
    850                          * @param string $sort      Sort direction for query.
     843                         * @param string $total_activities_sql MySQL statement used to query for total activities.
     844                         * @param string $where_sql            MySQL WHERE statement portion.
     845                         * @param string $sort                 Sort direction for query.
    851846                         */
    852                         $total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$join_sql} {$where_sql}", $where_sql, $sort );
     847                        $total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', $total_activities_sql, $where_sql, $sort );
    853848
    854849                        /*
     
    856851                         * since they are generally much less long-lived.
    857852                         */
    858                         if ( preg_match( '/a\.type NOT IN \([^\)]*\'last_activity\'[^\)]*\)/', $total_activities_sql ) ) {
    859                                 $cache_group = 'bp_activity';
     853                        $cache_group = ( preg_match( '/a\.type NOT IN \([^\)]*\'last_activity\'[^\)]*\)/', $total_activities_sql ) )
     854                                ? 'bp_activity'
     855                                : 'bp_activity_with_last_activity';
     856
     857                        if ( $r['cache_results'] ) {
     858                                $cached = bp_core_get_incremented_cache( $total_activities_sql, $cache_group );
     859                                if ( false === $cached ) {
     860                                        $total_activities = $wpdb->get_var( $total_activities_sql );
     861                                        bp_core_set_incremented_cache( $total_activities_sql, $cache_group, $total_activities );
     862                                } else {
     863                                        $total_activities = $cached;
     864                                }
    860865                        } else {
    861                                 $cache_group = 'bp_activity_with_last_activity';
    862                         }
    863 
    864                         $cached = bp_core_get_incremented_cache( $total_activities_sql, $cache_group );
    865                         if ( false === $cached ) {
    866866                                $total_activities = $wpdb->get_var( $total_activities_sql );
    867                                 bp_core_set_incremented_cache( $total_activities_sql, $cache_group, $total_activities );
    868                         } else {
    869                                 $total_activities = $cached;
    870867                        }
    871868
    872869                        // If $max is set, only return up to the max results.
    873                         if ( ! empty( $r['max'] ) ) {
    874                                 if ( (int) $total_activities > (int) $r['max'] ) {
    875                                         $total_activities = $r['max'];
    876                                 }
     870                        if ( ! empty( $r['max'] ) && ( (int) $total_activities > (int) $r['max'] ) ) {
     871                                $total_activities = $r['max'];
    877872                        }
    878873
     
    887882         *
    888883         * @since 2.0.0
     884         * @since 15.0.0 Added the `$cache_results` parameter.
    889885         *
    890886         * @global wpdb $wpdb WordPress database object.
    891887         *
    892888         * @param array $activity_ids Array of activity IDs.
     889         * @param bool  $cache_results Optional. Whether to cache activity information. Default true.
    893890         * @return array
    894891         */
    895         protected static function get_activity_data( $activity_ids = array() ) {
     892        protected static function get_activity_data( $activity_ids = array(), $cache_results = true ) {
    896893                global $wpdb;
    897894
    898895                // Bail if no activity ID's passed.
    899                 if ( empty( $activity_ids ) ) {
     896                if ( empty( $activity_ids ) || ! is_array( $activity_ids ) ) {
    900897                        return array();
    901898                }
     
    904901                $bp = buddypress();
    905902
    906                 $activities   = array();
    907                 $uncached_ids = bp_get_non_cached_ids( $activity_ids, 'bp_activity' );
    908 
    909                 // Prime caches as necessary.
    910                 if ( ! empty( $uncached_ids ) ) {
    911                         // Format the activity ID's for use in the query below.
    912                         $uncached_ids_sql = implode( ',', wp_parse_id_list( $uncached_ids ) );
     903                $activities = array();
     904
     905                if ( $cache_results ) {
     906                        $uncached_ids = bp_get_non_cached_ids( $activity_ids, 'bp_activity' );
     907
     908                        // Prime caches as necessary.
     909                        if ( ! empty( $uncached_ids ) ) {
     910                                // Format the activity ID's for use in the query below.
     911                                $uncached_ids_sql = implode( ',', wp_parse_id_list( $uncached_ids ) );
     912
     913                                // Fetch data from activity table.
     914                                $queried_activity_data = $wpdb->get_results( "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$uncached_ids_sql})" );
     915
     916                                // Put that data into the placeholders created earlier,
     917                                // and add it to the cache.
     918                                foreach ( (array) $queried_activity_data as $activity_data ) {
     919                                        wp_cache_set( $activity_data->id, $activity_data, 'bp_activity' );
     920                                }
     921                        }
     922
     923                        // Now fetch data from the cache.
     924                        foreach ( $activity_ids as $activity_id ) {
     925                                // Integer casting.
     926                                $activity = wp_cache_get( $activity_id, 'bp_activity' );
     927                                if ( ! empty( $activity ) ) {
     928                                        $activity->id                = (int) $activity->id;
     929                                        $activity->user_id           = (int) $activity->user_id;
     930                                        $activity->item_id           = (int) $activity->item_id;
     931                                        $activity->secondary_item_id = (int) $activity->secondary_item_id;
     932                                        $activity->hide_sitewide     = (int) $activity->hide_sitewide;
     933                                        $activity->mptt_left         = (int) $activity->mptt_left;
     934                                        $activity->mptt_right        = (int) $activity->mptt_right;
     935                                        $activity->is_spam           = (int) $activity->is_spam;
     936                                }
     937
     938                                $activities[] = $activity;
     939                        }
     940                } else {
     941                        $activity_ids = implode( ',', wp_parse_id_list( $activity_ids ) );
    913942
    914943                        // Fetch data from activity table, preserving order.
    915                         $queried_adata = $wpdb->get_results( "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$uncached_ids_sql})");
    916 
    917                         // Put that data into the placeholders created earlier,
    918                         // and add it to the cache.
    919                         foreach ( (array) $queried_adata as $adata ) {
    920                                 wp_cache_set( $adata->id, $adata, 'bp_activity' );
    921                         }
    922                 }
    923 
    924                 // Now fetch data from the cache.
    925                 foreach ( $activity_ids as $activity_id ) {
    926                         // Integer casting.
    927                         $activity = wp_cache_get( $activity_id, 'bp_activity' );
    928                         if ( ! empty( $activity ) ) {
     944                        $uncached_queried_activity_data = $wpdb->get_results(
     945                                "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$activity_ids}) ORDER BY FIELD( {$bp->activity->table_name}.id, {$activity_ids} )"
     946                        );
     947
     948                        foreach ( $uncached_queried_activity_data as $activity ) {
    929949                                $activity->id                = (int) $activity->id;
    930950                                $activity->user_id           = (int) $activity->user_id;
     
    935955                                $activity->mptt_right        = (int) $activity->mptt_right;
    936956                                $activity->is_spam           = (int) $activity->is_spam;
    937                         }
    938 
    939                         $activities[] = $activity;
     957
     958                                $activities[] = $activity;
     959                        }
    940960                }
    941961
    942962                // Then fetch user data.
    943                 $user_query = new BP_User_Query( array(
    944                         'user_ids'        => wp_list_pluck( $activities, 'user_id' ),
    945                         'populate_extras' => false,
    946                 ) );
     963                $user_query = new BP_User_Query(
     964                        array(
     965                                'user_ids'        => wp_list_pluck( $activities, 'user_id' ),
     966                                'populate_extras' => false,
     967                        )
     968                );
    947969
    948970                // Associated located user data with activity items.
     
    951973                        $a_user    = isset( $user_query->results[ $a_user_id ] ) ? $user_query->results[ $a_user_id ] : '';
    952974
    953                         if ( !empty( $a_user ) ) {
     975                        if ( ! empty( $a_user ) ) {
    954976                                $activities[ $a_index ]->user_email    = $a_user->user_email;
    955977                                $activities[ $a_index ]->user_nicename = $a_user->user_nicename;
     
    971993         */
    972994        protected static function append_user_fullnames( $activities ) {
    973 
    974995                if ( bp_is_active( 'xprofile' ) && ! empty( $activities ) ) {
    975996                        $activity_user_ids = wp_list_pluck( $activities, 'user_id' );
  • trunk/tests/phpunit/testcases/activity/cache.php

    r13149 r13988  
    66 */
    77class BP_Tests_Activity_Cache extends BP_UnitTestCase {
     8
     9        /**
     10         * @ticket BP8552
     11         */
     12        public function test_activity_query_with_ids_cache_results() {
     13                global $wpdb;
     14
     15                self::factory()->activity->create_many( 2 );
     16
     17                // Reset.
     18                $wpdb->num_queries = 0;
     19
     20                $first_query = BP_Activity_Activity::get(
     21                        array(
     22                                'cache_results' => true,
     23                                'fields'        => 'ids',
     24                        )
     25                );
     26
     27                $queries_before = get_num_queries();
     28
     29                $second_query = BP_Activity_Activity::get(
     30                        array(
     31                                'cache_results' => false,
     32                                'fields'        => 'ids',
     33                        )
     34                );
     35
     36                $queries_after = get_num_queries();
     37
     38                $this->assertNotSame( $queries_before, $queries_after, 'Assert that queries are run' );
     39                $this->assertSame( 2, $queries_after, 'Assert that the uncached query was run' );
     40                $this->assertSameSets( $first_query['activities'], $second_query['activities'], 'Results of the query are expected to match.' );
     41        }
     42
     43        /**
     44         * @ticket BP8552
     45         */
     46        public function test_activity_query_with_count_total_cache_results() {
     47                global $wpdb;
     48
     49                self::factory()->activity->create_many( 2 );
     50
     51                // Reset.
     52                $wpdb->num_queries = 0;
     53
     54                $first_query = BP_Activity_Activity::get(
     55                        array(
     56                                'cache_results' => true,
     57                                'count_total'   => true,
     58                        )
     59                );
     60
     61                $queries_before = get_num_queries();
     62
     63                $second_query = BP_Activity_Activity::get(
     64                        array(
     65                                'cache_results' => false,
     66                                'count_total'   => true,
     67                        )
     68                );
     69
     70                $queries_after = get_num_queries();
     71
     72                $this->assertNotSame( $queries_before, $queries_after, 'Assert that queries are run' );
     73                $this->assertSame( 9, $queries_after, 'Assert that the uncached query was run' );
     74                $this->assertSame( $first_query['total'], $second_query['total'], 'Results of the query are expected to match.' );
     75        }
     76
     77        /**
     78         * @ticket BP8552
     79         */
     80        public function test_activity_query_with_all_cache_results() {
     81                global $wpdb;
     82
     83                self::factory()->activity->create_many( 2 );
     84
     85                // Reset.
     86                $wpdb->num_queries = 0;
     87
     88                $first_query = BP_Activity_Activity::get(
     89                        array( 'cache_results' => true )
     90                );
     91
     92                $queries_before = get_num_queries();
     93
     94                $second_query = BP_Activity_Activity::get(
     95                        array( 'cache_results' => false )
     96                );
     97
     98                $queries_after = get_num_queries();
     99
     100                $this->assertNotSame( $queries_before, $queries_after, 'Assert that queries are run' );
     101                $this->assertSame( 7, $queries_after, 'Assert that the uncached query was run' );
     102                $this->assertSameSets(
     103                        array_map(
     104                                function ( $a ) {
     105                                        return $a->id;
     106                                },
     107                                $first_query['activities']
     108                        ),
     109                        array_map(
     110                                function ( $a ) {
     111                                        return $a->id;
     112                                },
     113                                $second_query['activities']
     114                        ),
     115                        'Results of the query are expected to match.'
     116                );
     117        }
     118
    8119        /**
    9120         * @group bp_activity_update_meta_cache
Note: See TracChangeset for help on using the changeset viewer.