Guest User

buddypress/bp-messages/classes/class-bp-messages-thread.php

a guest
Nov 23rd, 2015
69
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <?php
  2. /**
  3.  * BuddyPress Messages Classes.
  4.  *
  5.  * @package BuddyPress
  6.  * @subpackage MessagesClasses
  7.  */
  8.  
  9. // Exit if accessed directly.
  10. defined( 'ABSPATH' ) || exit;
  11.  
  12. /**
  13.  * BuddyPress Message Thread class.
  14.  *
  15.  * @since 1.0.0
  16.  */
  17. class BP_Messages_Thread {
  18.  
  19.     /**
  20.      * The message thread ID.
  21.      *
  22.      * @since 1.0.0
  23.      * @var int
  24.      */
  25.     public $thread_id;
  26.  
  27.     /**
  28.      * The current messages.
  29.      *
  30.      * @since 1.0.0
  31.      * @var array
  32.      */
  33.     public $messages;
  34.  
  35.     /**
  36.      * The current recipients in the message thread.
  37.      *
  38.      * @since 1.0.0
  39.      * @var array
  40.      */
  41.     public $recipients;
  42.  
  43.     /**
  44.      * The user IDs of all messages in the message thread.
  45.      *
  46.      * @since 1.2.0
  47.      * @var array
  48.      */
  49.     public $sender_ids;
  50.  
  51.     /**
  52.      * The unread count for the logged-in user.
  53.      *
  54.      * @since 1.2.0
  55.      * @var int
  56.      */
  57.     public $unread_count;
  58.  
  59.     /**
  60.      * The content of the last message in this thread.
  61.      *
  62.      * @since 1.2.0
  63.      * @var string
  64.      */
  65.     public $last_message_content;
  66.  
  67.     /**
  68.      * The date of the last message in this thread.
  69.      *
  70.      * @since 1.2.0
  71.      * @var string
  72.      */
  73.     public $last_message_date;
  74.  
  75.     /**
  76.      * The ID of the last message in this thread.
  77.      *
  78.      * @since 1.2.0
  79.      * @var int
  80.      */
  81.     public $last_message_id;
  82.  
  83.     /**
  84.      * The subject of the last message in this thread.
  85.      *
  86.      * @since 1.2.0
  87.      * @var string
  88.      */
  89.     public $last_message_subject;
  90.  
  91.     /**
  92.      * The user ID of the author of the last message in this thread.
  93.      *
  94.      * @since 1.2.0
  95.      * @var int
  96.      */
  97.     public $last_sender_id;
  98.  
  99.     /**
  100.      * Sort order of the messages in this thread (ASC or DESC).
  101.      *
  102.      * @since 1.5.0
  103.      * @var string
  104.      */
  105.     public $messages_order;
  106.  
  107.     /**
  108.      * Constructor.
  109.      *
  110.      * @since 1.0.0
  111.      *
  112.      * @see BP_Messages_Thread::populate() for full description of parameters.
  113.      *
  114.      * @param bool   $thread_id ID for the message thread.
  115.      * @param string $order     Order to display the messages in.
  116.      * @param array  $args      Array of arguments for thread querying.
  117.      */
  118.     public function __construct( $thread_id = false, $order = 'DESC', $args = array() ) {
  119.         if ( $thread_id ) {
  120.             $this->populate( $thread_id, $order, $args );
  121.         }
  122.     }
  123.  
  124.     /**
  125.      * Populate method.
  126.      *
  127.      * Used in constructor.
  128.      *
  129.      * @since 1.0.0
  130.      *
  131.      * @param int    $thread_id The message thread ID.
  132.      * @param string $order     The order to sort the messages. Either 'ASC' or 'DESC'.
  133.      * @param array  $args {
  134.      *     Array of arguments.
  135.      *     @type bool $update_meta_cache Whether to pre-fetch metadata for
  136.      *                                   queried message items. Default: true.
  137.      * }
  138.      * @return bool False on failure.
  139.      */
  140.     public function populate( $thread_id = 0, $order = 'DESC', $args = array() ) {
  141.  
  142.         if ( 'ASC' !== $order && 'DESC' !== $order ) {
  143.             $order = 'ASC';
  144.         }
  145.  
  146.         // Merge $args with our defaults.
  147.         $r = wp_parse_args( $args, array(
  148.             'user_id'           => bp_loggedin_user_id(),
  149.             'update_meta_cache' => true
  150.         ) );
  151.  
  152.         $this->messages_order = $order;
  153.         $this->thread_id      = (int) $thread_id;
  154.  
  155.         // Get messages for thread.
  156.         $this->messages = self::get_messages( $this->thread_id );
  157.  
  158.         if ( empty( $this->messages ) || is_wp_error( $this->messages ) ) {
  159.             return false;
  160.         }
  161.  
  162.         // Flip if order is DESC.
  163.         if ( 'DESC' === $order ) {
  164.             $this->messages = array_reverse( $this->messages );
  165.         }
  166.  
  167.         $last_message_index         = count( $this->messages ) - 1;
  168.         $this->last_message_id      = $this->messages[ $last_message_index ]->id;
  169.         $this->last_message_date    = $this->messages[ $last_message_index ]->date_sent;
  170.         $this->last_sender_id       = $this->messages[ $last_message_index ]->sender_id;
  171.         $this->last_message_subject = $this->messages[ $last_message_index ]->subject;
  172.         $this->last_message_content = $this->messages[ $last_message_index ]->message;
  173.  
  174.         foreach ( (array) $this->messages as $key => $message ) {
  175.             $this->sender_ids[ $message->sender_id ] = $message->sender_id;
  176.         }
  177.  
  178.         // Fetch the recipients.
  179.         $this->recipients = $this->get_recipients();
  180.  
  181.         // Get the unread count for the logged in user.
  182.         if ( isset( $this->recipients[ $r['user_id'] ] ) ) {
  183.             $this->unread_count = $this->recipients[ $r['user_id'] ]->unread_count;
  184.         }
  185.  
  186.         // Grab all message meta.
  187.         if ( true === (bool) $r['update_meta_cache'] ) {
  188.             bp_messages_update_meta_cache( wp_list_pluck( $this->messages, 'id' ) );
  189.         }
  190.  
  191.         /**
  192.          * Fires after a BP_Messages_Thread object has been populated.
  193.          *
  194.          * @since 2.2.0
  195.          *
  196.          * @param BP_Messages_Thread $this Message thread object.
  197.          */
  198.         do_action( 'bp_messages_thread_post_populate', $this );
  199.     }
  200.  
  201.     /**
  202.      * Mark a thread initialized in this class as read.
  203.      *
  204.      * @since 1.0.0
  205.      *
  206.      * @see BP_Messages_Thread::mark_as_read()
  207.      */
  208.     public function mark_read() {
  209.         BP_Messages_Thread::mark_as_read( $this->thread_id );
  210.     }
  211.  
  212.     /**
  213.      * Mark a thread initialized in this class as unread.
  214.      *
  215.      * @since 1.0.0
  216.      *
  217.      * @see BP_Messages_Thread::mark_as_unread()
  218.      */
  219.     public function mark_unread() {
  220.         BP_Messages_Thread::mark_as_unread( $this->thread_id );
  221.     }
  222.  
  223.     /**
  224.      * Returns recipients for a message thread.
  225.      *
  226.      * @since 1.0.0
  227.      * @since 2.3.0 Added $thread_id as a parameter.
  228.      *
  229.      * @param int $thread_id The thread ID.
  230.      * @return array
  231.      */
  232.     public function get_recipients( $thread_id = 0 ) {
  233.         global $wpdb;
  234.  
  235.         if ( empty( $thread_id ) ) {
  236.             $thread_id = $this->thread_id;
  237.         }
  238.  
  239.         $thread_id = (int) $thread_id;
  240.  
  241.         $recipients = wp_cache_get( 'thread_recipients_' . $thread_id, 'bp_messages' );
  242.         if ( false === $recipients ) {
  243.             $bp = buddypress();
  244.  
  245.             $recipients = array();
  246.             $sql        = $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d", $thread_id );
  247.             $results    = $wpdb->get_results( $sql );
  248.  
  249.             foreach ( (array) $results as $recipient ) {
  250.                 $recipients[ $recipient->user_id ] = $recipient;
  251.             }
  252.  
  253.             wp_cache_set( 'thread_recipients_' . $thread_id, $recipients, 'bp_messages' );
  254.         }
  255.  
  256.         /**
  257.          * Filters the recipients of a message thread.
  258.          *
  259.          * @since 2.2.0
  260.          *
  261.          * @param array $recipients Array of recipient objects.
  262.          * @param int   $thread_id  ID of the current thread.
  263.          */
  264.         return apply_filters( 'bp_messages_thread_get_recipients', $recipients, $thread_id );
  265.     }
  266.  
  267.     /** Static Functions ******************************************************/
  268.  
  269.     /**
  270.      * Get all messages associated with a thread.
  271.      *
  272.      * @since 2.3.0
  273.      *
  274.      * @param int $thread_id The message thread ID.
  275.      *
  276.      * @return object List of messages associated with a thread.
  277.      */
  278.     public static function get_messages( $thread_id = 0 ) {
  279.         $thread_id = (int) $thread_id;
  280.         $messages  = wp_cache_get( $thread_id, 'bp_messages_threads' );
  281.  
  282.         if ( false === $messages ) {
  283.             global $wpdb;
  284.  
  285.             $bp = buddypress();
  286.  
  287.             // Always sort by ASC by default.
  288.             $messages = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$bp->messages->table_name_messages} WHERE thread_id = %d ORDER BY date_sent DESC", $thread_id ) );
  289.  
  290.             wp_cache_set( $thread_id, (array) $messages, 'bp_messages_threads' );
  291.         }
  292.  
  293.         return $messages;
  294.     }
  295.  
  296.     /**
  297.      * Static method to get message recipients by thread ID.
  298.      *
  299.      * @since 2.3.0
  300.      *
  301.      * @param int $thread_id The thread ID.
  302.      * @return array
  303.      */
  304.     public static function get_recipients_for_thread( $thread_id = 0 ) {
  305.         $thread = new self( false );
  306.         return $thread->get_recipients( $thread_id );
  307.     }
  308.  
  309.     /**
  310.      * Mark messages in a thread as deleted or delete all messages in a thread.
  311.      *
  312.      * Note: All messages in a thread are deleted once every recipient in a thread
  313.      * has marked the thread as deleted.
  314.      *
  315.      * @since 1.0.0
  316.      *
  317.      * @param int $thread_id The message thread ID.
  318.      * @return bool
  319.      */
  320.     public static function delete( $thread_id = 0 ) {
  321.         global $wpdb;
  322.  
  323.         $thread_id = (int) $thread_id;
  324.  
  325.         /**
  326.          * Fires before a message thread is marked as deleted.
  327.          *
  328.          * @since 2.2.0
  329.          *
  330.          * @param int $thread_id ID of the thread being deleted.
  331.          */
  332.         do_action( 'bp_messages_thread_before_mark_delete', $thread_id );
  333.  
  334.         $bp = buddypress();
  335.  
  336.         // Mark messages as deleted
  337.         //
  338.         // @todo the reliance on bp_loggedin_user_id() sucks for plugins
  339.         // refactor this method to accept a $user_id parameter.
  340.         $wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET is_deleted = 1 WHERE thread_id = %d AND user_id = %d", $thread_id, bp_loggedin_user_id() ) );
  341.  
  342.         // Get the message ids in order to pass to the action.
  343.         $message_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) );
  344.  
  345.         // Check to see if any more recipients remain for this message.
  346.         $recipients = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d AND is_deleted = 0", $thread_id ) );
  347.  
  348.         // No more recipients so delete all messages associated with the thread.
  349.         if ( empty( $recipients ) ) {
  350.  
  351.             /**
  352.              * Fires before an entire message thread is deleted.
  353.              *
  354.              * @since 2.2.0
  355.              *
  356.              * @param int   $thread_id   ID of the thread being deleted.
  357.              * @param array $message_ids IDs of messages being deleted.
  358.              */
  359.             do_action( 'bp_messages_thread_before_delete', $thread_id, $message_ids );
  360.  
  361.             // Delete all the messages.
  362.             $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) );
  363.  
  364.             // Do something for each message ID.
  365.             foreach ( $message_ids as $message_id ) {
  366.  
  367.                 // Delete message meta.
  368.                 bp_messages_delete_meta( $message_id );
  369.  
  370.                 /**
  371.                  * Fires after a message is deleted. This hook is poorly named.
  372.                  *
  373.                  * @since 1.0.0
  374.                  *
  375.                  * @param int $message_id ID of the message.
  376.                  */
  377.                 do_action( 'messages_thread_deleted_thread', $message_id );
  378.             }
  379.  
  380.             // Delete all the recipients.
  381.             $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->messages->table_name_recipients} WHERE thread_id = %d", $thread_id ) );
  382.         }
  383.  
  384.         /**
  385.          * Fires after a message thread is either marked as deleted or deleted.
  386.          *
  387.          * @since 2.2.0
  388.          *
  389.          * @param int   $thread_id   ID of the thread being deleted.
  390.          * @param array $message_ids IDs of messages being deleted.
  391.          */
  392.         do_action( 'bp_messages_thread_after_delete', $thread_id, $message_ids );
  393.  
  394.         return true;
  395.     }
  396.  
  397.     /**
  398.      * Get current message threads for a user.
  399.      *
  400.      * @since 1.0.0
  401.      *
  402.      * @param array $args {
  403.      *     Array of arguments.
  404.      *     @type int    $user_id      The user ID.
  405.      *     @type string $box          The type of mailbox to get. Either 'inbox' or 'sentbox'.
  406.      *                                Defaults to 'inbox'.
  407.      *     @type string $type         The type of messages to get. Either 'all' or 'unread'
  408.      *                                or 'read'. Defaults to 'all'.
  409.      *     @type int    $limit        The number of messages to get. Defaults to null.
  410.      *     @type int    $page         The page number to get. Defaults to null.
  411.      *     @type string $search_terms The search term to use. Defaults to ''.
  412.      *     @type array  $meta_query   Meta query arguments. See WP_Meta_Query for more details.
  413.      * }
  414.      * @return array|bool Array on success. Boolean false on failure.
  415.      */
  416.     public static function get_current_threads_for_user( $args = array() ) {
  417.         global $wpdb;
  418.  
  419.         // Backward compatibility with old method of passing arguments.
  420.         if ( ! is_array( $args ) || func_num_args() > 1 ) {
  421.             _deprecated_argument( __METHOD__, '2.2.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
  422.  
  423.             $old_args_keys = array(
  424.                 0 => 'user_id',
  425.                 1 => 'box',
  426.                 2 => 'type',
  427.                 3 => 'limit',
  428.                 4 => 'page',
  429.                 5 => 'search_terms',
  430.             );
  431.  
  432.             $func_args = func_get_args();
  433.             $args      = bp_core_parse_args_array( $old_args_keys, $func_args );
  434.         }
  435.  
  436.         $r = bp_parse_args( $args, array(
  437.             'user_id'      => false,
  438.             'box'          => 'inbox',
  439.             'type'         => 'all',
  440.             'limit'        => null,
  441.             'page'         => null,
  442.             'search_terms' => '',
  443.             'meta_query'   => array()
  444.         ) );
  445.  
  446.         $pag_sql = $type_sql = $search_sql = $user_id_sql = $sender_sql = '';
  447.         $meta_query_sql = array(
  448.             'join'  => '',
  449.             'where' => ''
  450.         );
  451.  
  452.         if ( $r['limit'] && $r['page'] ) {
  453.             $pag_sql = $wpdb->prepare( " LIMIT %d, %d", intval( ( $r['page'] - 1 ) * $r['limit'] ), intval( $r['limit'] ) );
  454.         }
  455.  
  456.         if ( $r['type'] == 'unread' ) {
  457.             $type_sql = " AND r.unread_count != 0 ";
  458.         } elseif ( $r['type'] == 'read' ) {
  459.             $type_sql = " AND r.unread_count = 0 ";
  460.         }
  461.  
  462.         if ( ! empty( $r['search_terms'] ) ) {
  463.             $search_terms_like = '%' . bp_esc_like( $r['search_terms'] ) . '%';
  464.             $search_sql        = $wpdb->prepare( "AND ( subject LIKE %s OR message LIKE %s )", $search_terms_like, $search_terms_like );
  465.         }
  466.  
  467.         $r['user_id'] = (int) $r['user_id'];
  468.  
  469.         // Default deleted SQL.
  470.         $deleted_sql = 'r.is_deleted = 0';
  471.  
  472.         switch ( $r['box'] ) {
  473.             case 'sentbox' :
  474.                 $user_id_sql = 'AND ' . $wpdb->prepare( 'm.sender_id = %d', $r['user_id'] );
  475.                 $sender_sql  = 'AND m.sender_id = r.user_id';
  476.                 break;
  477.  
  478.             case 'inbox' :
  479.                 $user_id_sql = 'AND ' . $wpdb->prepare( 'r.user_id = %d', $r['user_id'] );
  480.                 $sender_sql  = 'AND r.sender_only = 0';
  481.                 break;
  482.  
  483.             default :
  484.                 // Omit user-deleted threads from all other custom message boxes.
  485.                 $deleted_sql = $wpdb->prepare( '( r.user_id = %d AND r.is_deleted = 0 )', $r['user_id'] );
  486.                 break;
  487.         }
  488.  
  489.         // Process meta query into SQL.
  490.         $meta_query = self::get_meta_query_sql( $r['meta_query'] );
  491.         if ( ! empty( $meta_query['join'] ) ) {
  492.             $meta_query_sql['join'] = $meta_query['join'];
  493.         }
  494.         if ( ! empty( $meta_query['where'] ) ) {
  495.             $meta_query_sql['where'] = $meta_query['where'];
  496.         }
  497.  
  498.         $bp = buddypress();
  499.  
  500.         // Set up SQL array.
  501.         $sql = array();
  502.         $sql['select'] = 'SELECT m.thread_id, MAX(m.date_sent) AS date_sent';
  503.         $sql['from']   = "FROM {$bp->messages->table_name_recipients} r INNER JOIN {$bp->messages->table_name_messages} m ON m.thread_id = r.thread_id {$meta_query_sql['join']}";
  504.         $sql['where']  = "WHERE {$deleted_sql} {$user_id_sql} {$sender_sql} {$type_sql} {$search_sql} {$meta_query_sql['where']}";
  505.         $sql['misc']   = "GROUP BY m.thread_id ORDER BY date_sent DESC {$pag_sql}";
  506.  
  507.         // Get thread IDs.
  508.         $thread_ids = $wpdb->get_results( implode( ' ', $sql ) );
  509.         if ( empty( $thread_ids ) ) {
  510.             return false;
  511.         }
  512.  
  513.         // Adjust $sql to work for thread total.
  514.         $sql['select'] = 'SELECT COUNT( DISTINCT m.thread_id )';
  515.         unset( $sql['misc'] );
  516.         $total_threads = $wpdb->get_var( implode( ' ', $sql ) );
  517.  
  518.         // Sort threads by date_sent.
  519.         foreach( (array) $thread_ids as $thread ) {
  520.             $sorted_threads[ $thread->thread_id ] = strtotime( $thread->date_sent );
  521.         }
  522.  
  523.         arsort( $sorted_threads );
  524.  
  525.         $threads = array();
  526.         foreach ( (array) $sorted_threads as $thread_id => $date_sent ) {
  527.             $threads[] = new BP_Messages_Thread( $thread_id, 'DESC', array(
  528.                 'update_meta_cache' => false
  529.             ) );
  530.         }
  531.  
  532.         /**
  533.          * Filters the results of the query for a user's message threads.
  534.          *
  535.          * @since 2.2.0
  536.          *
  537.          * @param array $value {
  538.          *     @type array $threads       Array of threads. Passed by reference.
  539.          *     @type int   $total_threads Number of threads found by the query.
  540.          * }
  541.          */
  542.         return apply_filters( 'bp_messages_thread_current_threads', array(
  543.             'threads' => &$threads,
  544.             'total'   => (int) $total_threads
  545.         ) );
  546.     }
  547.  
  548.     /**
  549.      * Get the SQL for the 'meta_query' param in BP_Messages_Thread::get_current_threads_for_user().
  550.      *
  551.      * We use WP_Meta_Query to do the heavy lifting of parsing the meta_query array
  552.      * and creating the necessary SQL clauses.
  553.      *
  554.      * @since 2.2.0
  555.      *
  556.      * @param array $meta_query An array of meta_query filters. See the
  557.      *                          documentation for WP_Meta_Query for details.
  558.      * @return array $sql_array 'join' and 'where' clauses.
  559.      */
  560.     public static function get_meta_query_sql( $meta_query = array() ) {
  561.         global $wpdb;
  562.  
  563.         $sql_array = array(
  564.             'join'  => '',
  565.             'where' => '',
  566.         );
  567.  
  568.         if ( ! empty( $meta_query ) ) {
  569.             $meta_query = new WP_Meta_Query( $meta_query );
  570.  
  571.             // WP_Meta_Query expects the table name at
  572.             // $wpdb->messagemeta.
  573.             $wpdb->messagemeta = buddypress()->messages->table_name_meta;
  574.  
  575.             return $meta_query->get_sql( 'message', 'm', 'id' );
  576.         }
  577.  
  578.         return $sql_array;
  579.     }
  580.  
  581.     /**
  582.      * Mark a thread as read.
  583.      *
  584.      * @since 1.0.0
  585.      *
  586.      * @param int $thread_id The message thread ID.
  587.      */
  588.     public static function mark_as_read( $thread_id = 0 ) {
  589.         global $wpdb;
  590.  
  591.         $bp  = buddypress();
  592.         $sql = $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET unread_count = 0 WHERE user_id = %d AND thread_id = %d", bp_loggedin_user_id(), $thread_id );
  593.         $wpdb->query( $sql );
  594.  
  595.         wp_cache_delete( 'thread_recipients_' . $thread_id, 'bp_messages' );
  596.         wp_cache_delete( bp_loggedin_user_id(), 'bp_messages_unread_count' );
  597.     }
  598.  
  599.     /**
  600.      * Mark a thread as unread.
  601.      *
  602.      * @since 1.0.0
  603.      *
  604.      * @param int $thread_id The message thread ID.
  605.      */
  606.     public static function mark_as_unread( $thread_id = 0 ) {
  607.         global $wpdb;
  608.  
  609.         $bp  = buddypress();
  610.         $sql = $wpdb->prepare( "UPDATE {$bp->messages->table_name_recipients} SET unread_count = 1 WHERE user_id = %d AND thread_id = %d", bp_loggedin_user_id(), $thread_id );
  611.         $wpdb->query( $sql );
  612.  
  613.         wp_cache_delete( 'thread_recipients_' . $thread_id, 'bp_messages' );
  614.         wp_cache_delete( bp_loggedin_user_id(), 'bp_messages_unread_count' );
  615.     }
  616.  
  617.     /**
  618.      * Returns the total number of message threads for a user.
  619.      *
  620.      * @since 1.0.0
  621.      *
  622.      * @param int    $user_id The user ID.
  623.      * @param string $box     The type of mailbox to get. Either 'inbox' or 'sentbox'.
  624.      *                        Defaults to 'inbox'.
  625.      * @param string $type    The type of messages to get. Either 'all' or 'unread'.
  626.      *                        or 'read'. Defaults to 'all'.
  627.      * @return int $value Total thread count for the provided user.
  628.      */
  629.     public static function get_total_threads_for_user( $user_id, $box = 'inbox', $type = 'all' ) {
  630.         global $wpdb;
  631.  
  632.         $exclude_sender = $type_sql = '';
  633.         if ( $box !== 'sentbox' ) {
  634.             $exclude_sender = 'AND sender_only != 1';
  635.         }
  636.  
  637.         if ( $type === 'unread' ) {
  638.             $type_sql = 'AND unread_count != 0';
  639.         } elseif ( $type === 'read' ) {
  640.             $type_sql = 'AND unread_count = 0';
  641.         }
  642.  
  643.         $bp = buddypress();
  644.  
  645.         return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(thread_id) FROM {$bp->messages->table_name_recipients} WHERE user_id = %d AND is_deleted = 0 {$exclude_sender} {$type_sql}", $user_id ) );
  646.     }
  647.  
  648.     /**
  649.      * Determine if the logged-in user is a sender of any message in a thread.
  650.      *
  651.      * @since 1.0.0
  652.      *
  653.      * @param int $thread_id The message thread ID.
  654.      * @return bool
  655.      */
  656.     public static function user_is_sender( $thread_id ) {
  657.         global $wpdb;
  658.  
  659.         $bp = buddypress();
  660.  
  661.         $sender_ids = $wpdb->get_col( $wpdb->prepare( "SELECT sender_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d", $thread_id ) );
  662.  
  663.         if ( empty( $sender_ids ) ) {
  664.             return false;
  665.         }
  666.  
  667.         return in_array( bp_loggedin_user_id(), $sender_ids );
  668.     }
  669.  
  670.     /**
  671.      * Returns the userlink of the last sender in a message thread.
  672.      *
  673.      * @since 1.0.0
  674.      *
  675.      * @param int $thread_id The message thread ID.
  676.      * @return string|bool The user link on success. Boolean false on failure.
  677.      */
  678.     public static function get_last_sender( $thread_id ) {
  679.         global $wpdb;
  680.  
  681.         $bp = buddypress();
  682.  
  683.         if ( ! $sender_id = $wpdb->get_var( $wpdb->prepare( "SELECT sender_id FROM {$bp->messages->table_name_messages} WHERE thread_id = %d GROUP BY sender_id ORDER BY date_sent LIMIT 1", $thread_id ) ) ) {
  684.             return false;
  685.         }
  686.  
  687.         return bp_core_get_userlink( $sender_id, true );
  688.     }
  689.  
  690.     /**
  691.      * Gets the unread message count for a user.
  692.      *
  693.      * @since 1.0.0
  694.      *
  695.      * @param int $user_id The user ID.
  696.      * @return int $unread_count Total inbox unread count for user.
  697.      */
  698.     public static function get_inbox_count( $user_id = 0 ) {
  699.         global $wpdb;
  700.  
  701.         if ( empty( $user_id ) ) {
  702.             $user_id = bp_loggedin_user_id();
  703.         }
  704.  
  705.         $unread_count = wp_cache_get( $user_id, 'bp_messages_unread_count' );
  706.  
  707.         if ( false === $unread_count ) {
  708.             $bp = buddypress();
  709.  
  710.             $unread_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT SUM(unread_count) FROM {$bp->messages->table_name_recipients} WHERE user_id = %d AND is_deleted = 0 AND sender_only = 0", $user_id ) );
  711.  
  712.             wp_cache_set( $user_id, $unread_count, 'bp_messages_unread_count' );
  713.         }
  714.  
  715.         /**
  716.          * Filters a user's unread message count.
  717.          *
  718.          * @since 2.2.0
  719.          *
  720.          * @param int $unread_count Unread message count.
  721.          * @param int $user_id      ID of the user.
  722.          */
  723.         return apply_filters( 'messages_thread_get_inbox_count', (int) $unread_count, $user_id );
  724.     }
  725.  
  726.     /**
  727.      * Checks whether a user is a part of a message thread discussion.
  728.      *
  729.      * @since 1.0.0
  730.      *
  731.      * @param int $thread_id The message thread ID.
  732.      * @param int $user_id   The user ID.
  733.      * @return int|null The recorded recipient ID on success, null on failure.
  734.      */
  735.     public static function check_access( $thread_id, $user_id = 0 ) {
  736.  
  737.         if ( empty( $user_id ) ) {
  738.             $user_id = bp_loggedin_user_id();
  739.         }
  740.  
  741.         $recipients = self::get_recipients_for_thread( $thread_id );
  742.  
  743.         if ( isset( $recipients[ $user_id ] ) && 0 == $recipients[ $user_id ]->is_deleted ) {
  744.             return $recipients[ $user_id ]->id;
  745.         } else {
  746.             return null;
  747.         }
  748.     }
  749.  
  750.     /**
  751.      * Checks whether a message thread exists.
  752.      *
  753.      * @since 1.0.0
  754.      *
  755.      * @param int $thread_id The message thread ID.
  756.      * @return int|null The message thread ID on success, null on failure.
  757.      */
  758.     public static function is_valid( $thread_id = 0 ) {
  759.  
  760.         // Bail if no thread ID is passed.
  761.         if ( empty( $thread_id ) ) {
  762.             return false;
  763.         }
  764.  
  765.         $thread = self::get_messages( $thread_id );
  766.  
  767.         if ( ! empty( $thread ) ) {
  768.             return $thread_id;
  769.         } else {
  770.             return null;
  771.         }
  772.     }
  773.  
  774.     /**
  775.      * Returns a string containing all the message recipient userlinks.
  776.      *
  777.      * String is comma-delimited.
  778.      *
  779.      * If a message thread has more than four users, the returned string is simply
  780.      * "X Recipients" where "X" is the number of recipients in the message thread.
  781.      *
  782.      * @since 1.0.0
  783.      *
  784.      * @param array $recipients Array containing the message recipients (array of objects).
  785.      * @return string $value String of message recipent userlinks.
  786.      */
  787.     public static function get_recipient_links( $recipients ) {
  788.  
  789.         if ( count( $recipients ) >= 5 ) {
  790.             return sprintf( __( '%s Recipients', 'buddypress' ), number_format_i18n( count( $recipients ) ) );
  791.         }
  792.  
  793.         $recipient_links = array();
  794.  
  795.         foreach ( (array) $recipients as $recipient ) {
  796.             $recipient_link = bp_core_get_userlink( $recipient->user_id );
  797.  
  798.             if ( empty( $recipient_link ) ) {
  799.                 $recipient_link = __( 'Deleted User', 'buddypress' );
  800.             }
  801.  
  802.             $recipient_links[] = $recipient_link;
  803.         }
  804.  
  805.         return implode( ', ', (array) $recipient_links );
  806.     }
  807.  
  808.     /**
  809.      * Upgrade method for the older BP message thread DB table.
  810.      *
  811.      * @since 1.2.0
  812.      *
  813.      * @todo We should remove this.  No one is going to upgrade from v1.1, right?
  814.      * @return bool
  815.      */
  816.     public static function update_tables() {
  817.         global $wpdb;
  818.  
  819.         $bp_prefix = bp_core_get_table_prefix();
  820.         $errors    = false;
  821.         $threads   = $wpdb->get_results( "SELECT * FROM {$bp_prefix}bp_messages_threads" );
  822.  
  823.         // Nothing to update, just return true to remove the table.
  824.         if ( empty( $threads ) ) {
  825.             return true;
  826.         }
  827.  
  828.         $bp = buddypress();
  829.  
  830.         foreach( (array) $threads as $thread ) {
  831.             $message_ids = maybe_unserialize( $thread->message_ids );
  832.  
  833.             if ( ! empty( $message_ids ) ) {
  834.                 $message_ids = implode( ',', $message_ids );
  835.  
  836.                 // Add the thread_id to the messages table.
  837.                 if ( ! $wpdb->query( $wpdb->prepare( "UPDATE {$bp->messages->table_name_messages} SET thread_id = %d WHERE id IN ({$message_ids})", $thread->id ) ) ) {
  838.                     $errors = true;
  839.                 }
  840.             }
  841.         }
  842.  
  843.         return (bool) ! $errors;
  844.     }
  845. }
RAW Paste Data