Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
09/09/2021 04:10:21 AM (4 years ago)
Author:
espellcaste
Message:

Adding support to the offset pagination to Messages and Recipients in a thread.

Previously, the BP_Messages_Thread query class would grab ALL messages created for a thread and ALL its recipients. This commit introduces support to the offset pagination
allowing one to paginate both messages and recipients using parameters with a specific limit and offset.

Props imath
Fixes #8508

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-messages/classes/class-bp-messages-thread.php

    r13096 r13102  
    110110     *
    111111     * @since 1.0.0
    112      *
    113      * @see BP_Messages_Thread::populate() for full description of parameters.
    114      *
    115      * @param bool   $thread_id ID for the message thread.
    116      * @param string $order     Order to display the messages in.
    117      * @param array  $args      Array of arguments for thread querying.
    118      */
    119     public function __construct( $thread_id = false, $order = 'ASC', $args = array() ) {
    120         if ( $thread_id ) {
     112     * @since 10.0.0 Updated the `$args` with new paremeters.
     113     *
     114     * @param int    $thread_id          The message thread ID.
     115     * @param string $order              The order to sort the messages. Either 'ASC' or 'DESC'.
     116     *                                   Defaults to 'ASC'.
     117     * @param array  $args               {
     118     *     Array of arguments.
     119     *     @type int         $user_id             ID of the user to get the unread count.
     120     *     @type bool        $update_meta_cache   Whether to pre-fetch metadata for
     121     *                                            queried message items. Default: true.
     122     *     @type int|null    $page                Page of messages being requested. Default to null, meaning all.
     123     *     @type int|null    $per_page            Messages to return per page. Default to null, meaning all.
     124     *     @type string      $order               The order to sort the messages. Either 'ASC' or 'DESC'.
     125     *                                            Defaults to 'ASC'.
     126     *     @type int|null    $recipients_page     Page of recipients being requested. Default to null, meaning all.
     127     *     @type int|null    $recipients_per_page Recipients to return per page. Defaults to null, meaning all.
     128     * }
     129     */
     130    public function __construct( $thread_id = 0, $order = 'ASC', $args = array() ) {
     131        if ( ! empty( $thread_id ) ) {
    121132            $this->populate( $thread_id, $order, $args );
    122133        }
     
    126137     * Populate method.
    127138     *
    128      * Used in constructor.
    129      *
    130      * @since 1.0.0
    131      *
    132      * @param int    $thread_id The message thread ID.
    133      * @param string $order     The order to sort the messages. Either 'ASC' or 'DESC'.
    134      * @param array  $args {
     139     * Used in the constructor.
     140     *
     141     * @since 1.0.0
     142     * @since 10.0.0 Updated the `$args` with new paremeters.
     143     *
     144     * @param int    $thread_id                   The message thread ID.
     145     * @param string $order                       The order to sort the messages. Either 'ASC' or 'DESC'.
     146     *                                            Defaults to 'ASC'.
     147     * @param array  $args                        {
    135148     *     Array of arguments.
    136      *     @type bool $update_meta_cache Whether to pre-fetch metadata for
    137      *                                   queried message items. Default: true.
     149     *     @type int         $user_id             ID of the user to get the unread count.
     150     *     @type bool        $update_meta_cache   Whether to pre-fetch metadata for
     151     *                                            queried message items. Default: true.
     152     *     @type int|null    $page                Page of messages being requested. Default to null, meaning all.
     153     *     @type int|null    $per_page            Messages to return per page. Default to null, meaning all.
     154     *     @type string      $order               The order to sort the messages. Either 'ASC' or 'DESC'.
     155     *                                            Defaults to 'ASC'.
     156     *     @type int|null    $recipients_page     Page of recipients being requested. Default to null, meaning all.
     157     *     @type int|null    $recipients_per_page Recipients to return per page. Defaults to null, meaning all.
    138158     * }
    139      * @return bool False on failure.
     159     * @return bool False if there are no messages.
    140160     */
    141161    public function populate( $thread_id = 0, $order = 'ASC', $args = array() ) {
    142162
    143         if ( 'ASC' !== $order && 'DESC' !== $order ) {
     163        if ( ! in_array( strtoupper( $order ), array( 'ASC', 'DESC' ), true ) ) {
    144164            $order = 'ASC';
    145165        }
     
    151171
    152172        // Merge $args with our defaults.
    153         $r = wp_parse_args( $args, array(
    154             'user_id'           => $user_id,
    155             'update_meta_cache' => true
    156         ) );
     173        $r = wp_parse_args(
     174            $args,
     175            array(
     176                'user_id'             => $user_id,
     177                'update_meta_cache'   => true,
     178                'page'                => null,
     179                'per_page'            => null,
     180                'order'               => $order,
     181                'recipients_page'     => null,
     182                'recipients_per_page' => null,
     183            )
     184        );
    157185
    158186        $this->messages_order = $order;
     
    160188
    161189        // Get messages for thread.
    162         $this->messages = self::get_messages( $this->thread_id );
    163 
    164         if ( empty( $this->messages ) || is_wp_error( $this->messages ) ) {
     190        $this->messages = self::get_messages( $this->thread_id, $r );
     191
     192        if ( empty( $this->messages ) ) {
    165193            return false;
    166         }
    167 
    168         // Flip if order is DESC.
    169         if ( 'DESC' === $order ) {
    170             $this->messages = array_reverse( $this->messages );
    171194        }
    172195
     
    183206
    184207        // Fetch the recipients.
    185         $this->recipients = $this->get_recipients();
    186 
    187         // Get the unread count for the logged in user.
     208        $this->recipients = $this->get_recipients( $thread_id, $r );
     209
     210        // Get the unread count for the user.
    188211        if ( isset( $this->recipients[ $r['user_id'] ] ) ) {
    189212            $this->unread_count = $this->recipients[ $r['user_id'] ]->unread_count;
     
    199222         *
    200223         * @since 2.2.0
     224         * @since 10.0.0 Added `$r` as a parameter.
    201225         *
    202226         * @param BP_Messages_Thread $this Message thread object.
     227         * @param array              $r    Array of paremeters.
    203228         */
    204         do_action( 'bp_messages_thread_post_populate', $this );
     229        do_action( 'bp_messages_thread_post_populate', $this, $r );
    205230    }
    206231
     
    231256     *
    232257     * @since 1.0.0
    233      * @since 2.3.0 Added $thread_id as a parameter.
     258     * @since 2.3.0  Added `$thread_id` as a parameter.
     259     * @since 10.0.0 Added `$args` as a parameter.
    234260     *
    235261     * @global BuddyPress $bp The one true BuddyPress instance.
    236262     * @global wpdb $wpdb WordPress database object.
    237263     *
    238      * @param int $thread_id The thread ID.
     264     * @param int   $thread_id Message thread ID.
     265     * @param array $args      {
     266     *     Array of arguments.
     267     *     @type int|null $recipients_page     Page of recipients being requested. Default to all.
     268     *     @type int|null $recipients_per_page Recipients to return per page. Defaults to all.
     269     * }
    239270     * @return array
    240271     */
    241     public function get_recipients( $thread_id = 0 ) {
     272    public function get_recipients( $thread_id = 0, $args = array() ) {
    242273        global $wpdb;
    243274
     
    248279        $thread_id = (int) $thread_id;
    249280
     281        if ( empty( $thread_id ) ) {
     282            return array();
     283        }
     284
     285        $bp = buddypress();
     286        $r  = wp_parse_args(
     287            $args,
     288            array(
     289                'recipients_page'     => null,
     290                'recipients_per_page' => null,
     291            )
     292        );
     293
     294        // Get recipients from cache if available.
    250295        $recipients = wp_cache_get( 'thread_recipients_' . $thread_id, 'bp_messages' );
    251         if ( false === $recipients ) {
    252             $bp = buddypress();
     296
     297        // Get recipients and cache it.
     298        if ( empty( $recipients ) ) {
     299
     300            // Query recipients.
     301            $results = $wpdb->get_results(
     302                $wpdb->prepare(
     303                    "SELECT * FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d",
     304                    $thread_id
     305                )
     306            );
    253307
    254308            $recipients = array();
    255             $sql        = $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d", $thread_id );
    256             $results    = $wpdb->get_results( $sql );
    257 
    258309            foreach ( (array) $results as $recipient ) {
    259                 $recipients[ $recipient->user_id ] = $recipient;
     310                $recipient_properties              = get_object_vars( $recipient );
     311                $recipients[ $recipient->user_id ] = (object) array_map( 'intval', $recipient_properties );
    260312            }
    261313
    262             wp_cache_set( 'thread_recipients_' . $thread_id, $recipients, 'bp_messages' );
    263         }
    264 
    265         // Cast all items from the messages DB table as integers.
    266         foreach ( (array) $recipients as $key => $data ) {
    267             $recipients[ $key ] = (object) array_map( 'intval', (array) $data );
     314            // Cache recipients.
     315            wp_cache_set( 'thread_recipients_' . $thread_id, (array) $recipients, 'bp_messages' );
     316        }
     317
     318        // Paginate the results.
     319        if ( ! empty( $recipients ) && $r['recipients_per_page'] && $r['recipients_page'] ) {
     320            $start      = ( $r['recipients_page'] - 1 ) * ( $r['recipients_per_page'] );
     321            $recipients = array_slice( $recipients, $start, $r['recipients_per_page'] );
    268322        }
    269323
     
    272326         *
    273327         * @since 2.2.0
     328         * @since 10.0.0 Added `$r` as a parameter.
    274329         *
    275330         * @param array $recipients Array of recipient objects.
    276          * @param int   $thread_id  ID of the current thread.
     331         * @param int   $thread_id  ID of the thread.
     332         * @param array $r          An array of parameters.
    277333         */
    278         return apply_filters( 'bp_messages_thread_get_recipients', $recipients, $thread_id );
     334        return apply_filters( 'bp_messages_thread_get_recipients', (array) $recipients, (int) $thread_id, (array) $r );
    279335    }
    280336
     
    282338
    283339    /**
    284      * Get all messages associated with a thread.
     340     * Get messages associated with a thread.
    285341     *
    286342     * @since 2.3.0
     343     * @since 10.0.0 Added `$args` as a parameter.
    287344     *
    288345     * @global BuddyPress $bp The one true BuddyPress instance.
    289346     * @global wpdb $wpdb WordPress database object.
    290347     *
    291      * @param int $thread_id The message thread ID.
    292      *
    293      * @return array List of messages associated with a thread.
    294      */
    295     public static function get_messages( $thread_id = 0 ) {
     348     * @param int   $thread_id The message thread ID.
     349     * @param array $args      {
     350     *     Array of arguments.
     351     *     @type int|null    $page     Page of messages being requested. Default to all.
     352     *     @type int|null    $per_page Messages to return per page. Default to all.
     353     *     @type string      $order    The order to sort the messages. Either 'ASC' or 'DESC'.
     354     *                                 Defaults to 'ASC'.
     355     * }
     356     * @return array
     357     */
     358    public static function get_messages( $thread_id = 0, $args = array() ) {
     359        global $wpdb;
     360
    296361        $thread_id = (int) $thread_id;
    297         $messages  = wp_cache_get( $thread_id, 'bp_messages_threads' );
    298 
    299         if ( false === $messages ) {
    300             global $wpdb;
    301 
    302             $bp = buddypress();
    303 
    304             // Always sort by ASC by default.
    305             $messages = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_messages} WHERE thread_id = %d ORDER BY date_sent ASC", $thread_id ) );
    306 
     362        if ( empty( $thread_id ) ) {
     363            return array();
     364        }
     365
     366        $bp = buddypress();
     367        $r  = wp_parse_args(
     368            $args,
     369            array(
     370                'page'     => null,
     371                'per_page' => null,
     372                'order'    => 'ASC',
     373            )
     374        );
     375
     376        // Fallback.
     377        if ( ! in_array( strtoupper( $r['order'] ), array( 'ASC', 'DESC' ), true ) ) {
     378            $r['order'] = 'ASC';
     379        }
     380
     381        // Get messages from cache if available.
     382        $messages = wp_cache_get( $thread_id, 'bp_messages_threads' );
     383
     384        // Get messages and cache it.
     385        if ( empty( $messages ) ) {
     386
     387            // Query messages.
     388            $messages = $wpdb->get_results(
     389                $wpdb->prepare(
     390                    "SELECT * FROM {$bp->messages->table_name_messages} WHERE thread_id = %d ORDER BY date_sent ASC",
     391                    $thread_id
     392                )
     393            );
     394
     395            foreach ( $messages as $key => $data ) {
     396                $messages[ $key ]->id        = (int) $messages[ $key ]->id;
     397                $messages[ $key ]->thread_id = (int) $messages[ $key ]->thread_id;
     398                $messages[ $key ]->sender_id = (int) $messages[ $key ]->sender_id;
     399            }
     400
     401            // Cache messages.
    307402            wp_cache_set( $thread_id, (array) $messages, 'bp_messages_threads' );
    308403        }
    309404
    310         // Integer casting.
    311         foreach ( $messages as $key => $data ) {
    312             $messages[ $key ]->id        = (int) $messages[ $key ]->id;
    313             $messages[ $key ]->thread_id = (int) $messages[ $key ]->thread_id;
    314             $messages[ $key ]->sender_id = (int) $messages[ $key ]->sender_id;
    315         }
    316 
    317         return $messages;
     405        // Flip if order is DESC.
     406        if ( 'DESC' === strtoupper( $r['order'] ) ) {
     407            $messages = array_reverse( $messages );
     408        }
     409
     410        // Paginate the results.
     411        if ( ! empty( $messages ) && $r['per_page'] && $r['page'] ) {
     412            $start    = ( $r['page'] - 1 ) * ( $r['per_page'] );
     413            $messages = array_slice( $messages, $start, $r['per_page'] );
     414        }
     415
     416        /**
     417         * Filters the messages associated with a thread.
     418         *
     419         * @since 10.0.0
     420         *
     421         * @param array $messages   Array of message objects.
     422         * @param int   $thread_id  ID of the thread.
     423         * @param array $r          An array of parameters.
     424         */
     425        return apply_filters( 'bp_messages_thread_get_messages', (array) $messages, (int) $thread_id, (array) $r );
    318426    }
    319427
     
    846954     *
    847955     * @param int $thread_id The message thread ID.
    848      * @param int $user_id   The user ID.
     956     * @param int $user_id   The user ID. Default: ID of the logged-in user.
    849957     * @return int|null The recorded recipient ID on success, null on failure.
    850958     */
     
    857965        $recipients = self::get_recipients_for_thread( $thread_id );
    858966
    859         if ( isset( $recipients[ $user_id ] ) && 0 == $recipients[ $user_id ]->is_deleted ) {
     967        if ( isset( $recipients[ $user_id ] ) && 0 === $recipients[ $user_id ]->is_deleted ) {
    860968            return $recipients[ $user_id ]->id;
    861         } else {
    862             return null;
    863         }
     969        }
     970
     971        return null;
    864972    }
    865973
Note: See TracChangeset for help on using the changeset viewer.