BP_Messages_Thread

BuddyPress Message Thread class.

Defined (1)

The class is defined in the following location(s).

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