Skip to:
Content

BuddyPress.org

Changeset 9753


Ignore:
Timestamp:
04/15/2015 10:44:55 PM (11 years ago)
Author:
r-a-y
Message:

Messages: Cache calls to BP_Messages_Thread class.

This commit:

  • Introduces static method - BP_Messages_Thread::get_messages() - caches fetching messages by thread ID and introduces the 'bp_messages_threads' cache group.
  • Converts BP_Messages_Thread::check_access() and BP_Messages_Thread::is_valid() methods from using direct DB queries to reference the cache.
  • Includes unit tests.
  • Consolidates cache clearing functions in bp-messages-cache.php.

This handles the majority of uncached message DB queries. For the inbox
page, if there are 10 message threads in the loop, we save 20 DB queries.
On a single message thread, we save 5 DB queries.

Fixes #6221.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-messages/bp-messages-cache.php

    r9482 r9753  
    4747
    4848/**
    49  * Clear unread count cache for each recipient after a message is sent.
     49 * Clear message cache after a message is saved.
    5050 *
    5151 * @since BuddyPress (2.0.0)
     
    5353 * @param BP_Messages_Message $message
    5454 */
    55 function bp_messages_clear_unread_count_cache_on_message_save( BP_Messages_Message $message ) {
     55function bp_messages_clear_cache_on_message_save( BP_Messages_Message $message ) {
     56        // Delete thread cache
     57        wp_cache_delete( $message->thread_id, 'bp_messages_threads' );
     58
     59        // Delete unread count for each recipient
    5660        foreach ( (array) $message->recipients as $recipient ) {
    5761                wp_cache_delete( $recipient->user_id, 'bp_messages_unread_count' );
    5862        }
     63
     64        // Delete thread recipient cache
     65        wp_cache_delete( 'thread_recipients_' . $message->thread_id, 'bp_messages' );
    5966}
    60 add_action( 'messages_message_after_save', 'bp_messages_clear_unread_count_cache_on_message_save' );
     67add_action( 'messages_message_after_save', 'bp_messages_clear_cache_on_message_save' );
    6168
    6269/**
    63  * Clear unread count cache for the logged-in user after a message is deleted.
     70 * Clear message cache after a message thread is deleted.
    6471 *
    6572 * @since BuddyPress (2.0.0)
     
    6875 *  array of thread IDs
    6976 */
    70 function bp_messages_clear_unread_count_cache_on_message_delete( $thread_ids ) {
     77function bp_messages_clear_cache_on_message_delete( $thread_ids ) {
     78        // Delete thread and thread recipient cache
     79        foreach( (array) $thread_ids as $thread_id ) {
     80                wp_cache_delete( $thread_id, 'bp_messages_threads' );
     81                wp_cache_delete( "thread_recipients_{$thread_id}", 'bp_messages' );
     82        }
     83
     84        // Delete unread count for logged-in user
    7185        wp_cache_delete( bp_loggedin_user_id(), 'bp_messages_unread_count' );
    7286}
    73 add_action( 'messages_before_delete_thread', 'bp_messages_clear_unread_count_cache_on_message_delete' );
     87add_action( 'messages_delete_thread', 'bp_messages_clear_cache_on_message_delete' );
    7488
    7589/**
     
    8599add_action( 'messages_notice_after_save',    'bp_notices_clear_cache' );
    86100add_action( 'messages_notice_before_delete', 'bp_notices_clear_cache' );
    87 
    88 /**
    89  * Invalidate thread recipient cache on message update.
    90  *
    91  * @since BuddyPress (2.3.0)
    92  *
    93  * @param BP_Messages_Message $message Message object.
    94  */
    95 function bp_messages_clear_message_thread_recipient_cache_on_message_sent( BP_Messages_Message $message ) {
    96         wp_cache_delete( 'thread_recipients_' . $message->thread_id, 'bp_messages' );
    97 }
    98 add_action( 'messages_message_sent', 'bp_messages_clear_message_thread_recipient_cache_on_message_sent' );
    99 
    100 /**
    101  * Invalidate thread recipient cache on thread deletion.
    102  *
    103  * @since BuddyPress (2.3.0)
    104  *
    105  * @param int|array $thread_ids IDs of deleted threads.
    106  */
    107 function bp_messages_clear_message_thread_recipient_cache_on_thread_delete( $thread_ids ) {
    108         foreach ( (array) $thread_ids as $thread_id ) {
    109                 wp_cache_delete( 'thread_recipients_' . $thread_id, 'bp_messages' );
    110         }
    111 }
    112 add_action( 'messages_delete_thread', 'bp_messages_clear_message_thread_recipient_cache_on_thread_delete' );
  • trunk/src/bp-messages/bp-messages-loader.php

    r9351 r9753  
    304304                wp_cache_add_global_groups( array(
    305305                        'bp_messages',
     306                        'bp_messages_threads',
    306307                        'bp_messages_unread_count',
    307308                        'message_meta'
  • trunk/src/bp-messages/classes/class-bp_messages-thread.php

    r9752 r9753  
    148148                $this->thread_id      = $thread_id;
    149149
    150                 $bp = buddypress();
    151 
    152                 if ( !$this->messages = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_messages} WHERE thread_id = %d ORDER BY date_sent " . $order, $this->thread_id ) ) ) {
     150                // get messages for thread
     151                $this->messages = self::get_messages( $thread_id );
     152
     153                if ( empty( $this->messages ) || is_wp_error( $this->messages ) ) {
    153154                        return false;
     155                }
     156
     157                // flip if order is DESC
     158                if ( 'DESC' === $order ) {
     159                        $this->messages = array_reverse( $this->messages );
    154160                }
    155161
     
    245251
    246252        /** Static Functions ******************************************************/
     253
     254        /**
     255         * Get all messages associated with a thread.
     256         *
     257         * @since BuddyPress (2.3.0)
     258         *
     259         * @param int $thread_id The message thread ID
     260         * @return array
     261         */
     262        public static function get_messages( $thread_id = 0 ) {
     263                $messages = wp_cache_get( $thread_id, 'bp_messages_threads' );
     264
     265                if ( false === $messages ) {
     266                        global $wpdb;
     267
     268                        $bp = buddypress();
     269
     270                        // always sort by ASC by default
     271                        $messages = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_messages} WHERE thread_id = %d ORDER BY date_sent ASC", $thread_id ) );
     272
     273                        wp_cache_set( $thread_id, (array) $messages, 'bp_messages_threads' );
     274                }
     275
     276                return $messages;
     277        }
    247278
    248279        /**
     
    664695         * @param int $thread_id The message thread ID.
    665696         * @param int $user_id The user ID.
    666          * @return int The message ID on success.
     697         * @return int|null The recorded recipient ID on success, null on failure
    667698         */
    668699        public static function check_access( $thread_id, $user_id = 0 ) {
    669                 global $wpdb;
    670 
    671                 if ( empty( $user_id ) )
     700                if ( empty( $user_id ) ) {
    672701                        $user_id = bp_loggedin_user_id();
    673 
    674                 $bp = buddypress();
    675 
    676                 return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND is_deleted = 0 AND user_id = %d", $thread_id, $user_id ) );
     702                }
     703
     704                $recipients = self::get_recipients_for_thread( $thread_id );
     705
     706                if ( isset( $recipients[$user_id] ) && 0 == $recipients[$user_id]->is_deleted ) {
     707                        return $recipients[$user_id]->id;
     708                } else {
     709                        return null;
     710                }
    677711        }
    678712
     
    683717         *
    684718         * @param int $thread_id The message thread ID.
    685          * @return int The message thread ID on success.
     719         * @return int|null The message thread ID on success, null on failure
    686720         */
    687721        public static function is_valid( $thread_id = 0 ) {
    688                 global $wpdb;
    689 
    690722                // Bail if no thread ID is passed
    691723                if ( empty( $thread_id ) ) {
     
    693725                }
    694726
    695                 $bp = buddypress();
    696 
    697                 return $wpdb->get_var( $wpdb->prepare( "SELECT thread_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d LIMIT 1", $thread_id ) );
     727                $thread = self::get_messages( $thread_id );
     728
     729                if ( ! empty( $thread ) ) {
     730                        return $thread_id;
     731                } else {
     732                        return null;
     733                }
    698734        }
    699735
  • trunk/tests/phpunit/testcases/messages/class.bp-messages-thread.php

    r9714 r9753  
    55 */
    66class BP_Tests_BP_Messages_Thread extends BP_UnitTestCase {
     7
     8        /**
     9         * @group cache
     10         */
     11        public function test_construct_cache() {
     12                $u1 = $this->factory->user->create();
     13                $u2 = $this->factory->user->create();
     14
     15                $t1 = $this->factory->message->create( array(
     16                        'sender_id' => $u1,
     17                        'recipients' => array( $u2 ),
     18                        'subject' => 'Foo',
     19                ) );
     20
     21                // prime cache
     22                new BP_Messages_Thread( $t1 );
     23
     24                // Cache should exist
     25                $this->assertThat(
     26                        wp_cache_get( $t1, 'bp_messages_threads' ),
     27                        $this->logicalNot( $this->equalTo( false ) ),
     28                        'Message thread cache should exist.'
     29                );
     30        }
     31
     32        /**
     33         * @group order
     34         */
     35        public function test_construct_order_desc() {
     36                $u1 = $this->factory->user->create();
     37                $u2 = $this->factory->user->create();
     38
     39                // create thread
     40                $t1 = $this->factory->message->create( array(
     41                        'sender_id' => $u1,
     42                        'recipients' => array( $u2 ),
     43                        'subject' => 'Foo',
     44                ) );
     45                // save message ID
     46                $thread = new BP_Messages_Thread( $t1 );
     47                $m1 = wp_list_pluck( $thread->messages, 'id' );
     48                $m1 = array_pop( $m1 );
     49
     50                // create reply
     51                $t2 = $this->factory->message->create( array(
     52                        'thread_id' => $t1,
     53                        'sender_id' => $u1,
     54                        'recipients' => array( $u2 ),
     55                        'content' => 'Bar'
     56                ) );
     57                // save message ID
     58                $thread = new BP_Messages_Thread( $t1 );
     59                $m2 = wp_list_pluck( $thread->messages, 'id' );
     60                $m2 = array_pop( $m2 );
     61
     62                // now get thread by DESC
     63                $thread = new BP_Messages_Thread( $t1, 'DESC' );
     64
     65                // assert!
     66                $this->assertEquals(
     67                        array( $m2, $m1 ),
     68                        wp_list_pluck( $thread->messages, 'id' )
     69                );
     70        }
     71
    772        /**
    873         * @group get_current_threads_for_user
     
    287352                $this->set_current_user( $current_user );
    288353        }
     354
     355        /**
     356         * @group check_access
     357         */
     358        public function test_check_access_valid_thread() {
     359                $u1 = $this->factory->user->create();
     360                $u2 = $this->factory->user->create();
     361
     362                $t1 = $this->factory->message->create( array(
     363                        'sender_id' => $u1,
     364                        'recipients' => array( $u2 ),
     365                        'subject' => 'Foo',
     366                ) );
     367
     368                // save recipient ID
     369                $thread = new BP_Messages_Thread( $t1 );
     370                $r1 = wp_list_pluck( $thread->recipients, 'id' );
     371                $r1 = array_pop( $r1 );
     372
     373                $this->assertEquals( $r1, BP_Messages_Thread::check_access( $t1, $u1 ) );
     374        }
     375
     376        /**
     377         * @group check_access
     378         */
     379        public function test_check_access_invalid_thread() {
     380                $this->assertEquals( null, BP_Messages_Thread::check_access( 999, 1 ) );
     381        }
     382
     383        /**
     384         * @group is_valid
     385         */
     386        public function test_is_valid_valid_thread() {
     387                $u1 = $this->factory->user->create();
     388                $u2 = $this->factory->user->create();
     389
     390                $t1 = $this->factory->message->create( array(
     391                        'sender_id' => $u1,
     392                        'recipients' => array( $u2 ),
     393                        'subject' => 'Foo',
     394                ) );
     395
     396                $this->assertEquals( $t1, BP_Messages_Thread::is_valid( $t1 ) );
     397        }
     398
     399        /**
     400         * @group is_valid
     401         */
     402        public function test_is_valid_invalid_thread() {
     403                $this->assertEquals( null, BP_Messages_Thread::is_valid( 999 ) );
     404        }
    289405}
Note: See TracChangeset for help on using the changeset viewer.