/bp-blogs/bp-blogs-activity.php

  1. <?php 
  2. /** 
  3. * BuddyPress Blogs Activity. 
  4. * 
  5. * @package BuddyPress 
  6. * @subpackage BlogsActivity 
  7. * @since 1.5.0 
  8. */ 
  9.  
  10. // Exit if accessed directly. 
  11. defined( 'ABSPATH' ) || exit; 
  12.  
  13. /** 
  14. * Register activity actions for the blogs component. 
  15. * 
  16. * @since 1.0.0 
  17. * 
  18. * @return bool|null Returns false if activity component is not active. 
  19. */ 
  20. function bp_blogs_register_activity_actions() { 
  21. if ( is_multisite() ) { 
  22. bp_activity_set_action( 
  23. buddypress()->blogs->id,  
  24. 'new_blog',  
  25. __( 'New site created', 'buddypress' ),  
  26. 'bp_blogs_format_activity_action_new_blog',  
  27. __( 'New Sites', 'buddypress' ),  
  28. array( 'activity', 'member' ),  
  29. ); 
  30.  
  31. /** 
  32. * Fires after the registry of the default blog component activity actions. 
  33. * 
  34. * @since 1.1.0 
  35. */ 
  36. do_action( 'bp_blogs_register_activity_actions' ); 
  37. add_action( 'bp_register_activity_actions', 'bp_blogs_register_activity_actions' ); 
  38.  
  39. /** 
  40. * Set up the tracking arguments for the 'post' post type. 
  41. * 
  42. * @since 2.5.0 This was moved out of the BP_Blogs_Component class. 
  43. * 
  44. * @see bp_activity_get_post_type_tracking_args() for information on parameters. 
  45. * 
  46. * @param object|null $params Tracking arguments. 
  47. * @param string|int $post_type Post type to track. 
  48. * @return object 
  49. */ 
  50. function bp_blogs_register_post_tracking_args( $params = null, $post_type = 0 ) { 
  51.  
  52. /** 
  53. * Filters the post types to track for the Blogs component. 
  54. * 
  55. * @since 1.5.0 
  56. * @deprecated 2.3.0 
  57. * 
  58. * Make sure plugins still using 'bp_blogs_record_post_post_types' 
  59. * to track their post types will generate new_blog_post activities 
  60. * See https://buddypress.trac.wordpress.org/ticket/6306 
  61. * 
  62. * @param array $value Array of post types to track. 
  63. */ 
  64. $post_types = apply_filters( 'bp_blogs_record_post_post_types', array( 'post' ) ); 
  65. $post_types_array = array_flip( $post_types ); 
  66.  
  67. if ( ! isset( $post_types_array[ $post_type ] ) ) { 
  68. return $params; 
  69.  
  70. // Set specific params for the 'post' post type. 
  71. $params->component_id = buddypress()->blogs->id; 
  72. $params->action_id = 'new_blog_post'; 
  73. $params->admin_filter = __( 'New post published', 'buddypress' ); 
  74. $params->format_callback = 'bp_blogs_format_activity_action_new_blog_post'; 
  75. $params->front_filter = __( 'Posts', 'buddypress' ); 
  76. $params->contexts = array( 'activity', 'member' ); 
  77. $params->position = 5; 
  78.  
  79. if ( post_type_supports( $post_type, 'comments' ) ) { 
  80. $params->comment_action_id = 'new_blog_comment'; 
  81.  
  82. /** 
  83. * Filters the post types to track for the Blogs component. 
  84. * 
  85. * @since 1.5.0 
  86. * @deprecated 2.5.0 
  87. * 
  88. * Make sure plugins still using 'bp_blogs_record_comment_post_types' 
  89. * to track comment about their post types will generate new_blog_comment activities 
  90. * See https://buddypress.trac.wordpress.org/ticket/6306 
  91. * 
  92. * @param array $value Array of post types to track. 
  93. */ 
  94. $comment_post_types = apply_filters( 'bp_blogs_record_comment_post_types', array( 'post' ) ); 
  95. $comment_post_types_array = array_flip( $comment_post_types ); 
  96.  
  97. if ( isset( $comment_post_types_array[ $post_type ] ) ) { 
  98. $params->comments_tracking = new stdClass(); 
  99. $params->comments_tracking->component_id = buddypress()->blogs->id; 
  100. $params->comments_tracking->action_id = 'new_blog_comment'; 
  101. $params->comments_tracking->admin_filter = __( 'New post comment posted', 'buddypress' ); 
  102. $params->comments_tracking->format_callback = 'bp_blogs_format_activity_action_new_blog_comment'; 
  103. $params->comments_tracking->front_filter = __( 'Comments', 'buddypress' ); 
  104. $params->comments_tracking->contexts = array( 'activity', 'member' ); 
  105. $params->comments_tracking->position = 10; 
  106.  
  107. return $params; 
  108. add_filter( 'bp_activity_get_post_type_tracking_args', 'bp_blogs_register_post_tracking_args', 10, 2 ); 
  109.  
  110. /** 
  111. * Format 'new_blog' activity actions. 
  112. * 
  113. * @since 2.0.0 
  114. * 
  115. * @param string $action Static activity action. 
  116. * @param object $activity Activity data object. 
  117. * @return string 
  118. */ 
  119. function bp_blogs_format_activity_action_new_blog( $action, $activity ) { 
  120. $blog_url = bp_blogs_get_blogmeta( $activity->item_id, 'url' ); 
  121. $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' ); 
  122.  
  123. $action = sprintf( __( '%s created the site %s', 'buddypress' ), bp_core_get_userlink( $activity->user_id ), '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' ); 
  124.  
  125. // Legacy filter - requires the BP_Blogs_Blog object. 
  126. if ( has_filter( 'bp_blogs_activity_created_blog_action' ) ) { 
  127. $user_blog = BP_Blogs_Blog::get_user_blog( $activity->user_id, $activity->item_id ); 
  128. if ( $user_blog ) { 
  129. $recorded_blog = new BP_Blogs_Blog( $user_blog ); 
  130.  
  131. if ( isset( $recorded_blog ) ) { 
  132. $action = apply_filters( 'bp_blogs_activity_created_blog_action', $action, $recorded_blog, $blog_name, bp_blogs_get_blogmeta( $activity->item_id, 'description' ) ); 
  133.  
  134. /** 
  135. * Filters the new blog activity action for the new blog. 
  136. * 
  137. * @since 2.0.0 
  138. * 
  139. * @param string $action Constructed activity action. 
  140. * @param object $activity Activity data object. 
  141. */ 
  142. return apply_filters( 'bp_blogs_format_activity_action_new_blog', $action, $activity ); 
  143.  
  144. /** 
  145. * Format 'new_blog_post' activity actions. 
  146. * 
  147. * @since 2.0.0 
  148. * 
  149. * @param string $action Static activity action. 
  150. * @param object $activity Activity data object. 
  151. * @return string Constructed activity action. 
  152. */ 
  153. function bp_blogs_format_activity_action_new_blog_post( $action, $activity ) { 
  154. $blog_url = bp_blogs_get_blogmeta( $activity->item_id, 'url' ); 
  155. $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' ); 
  156.  
  157. if ( empty( $blog_url ) || empty( $blog_name ) ) { 
  158. $blog_url = get_home_url( $activity->item_id ); 
  159. $blog_name = get_blog_option( $activity->item_id, 'blogname' ); 
  160.  
  161. bp_blogs_update_blogmeta( $activity->item_id, 'url', $blog_url ); 
  162. bp_blogs_update_blogmeta( $activity->item_id, 'name', $blog_name ); 
  163.  
  164. /** 
  165. * When the post is published we are faking an activity object 
  166. * to which we add 2 properties : 
  167. * - the post url 
  168. * - the post title 
  169. * This is done to build the 'post link' part of the activity 
  170. * action string. 
  171. * NB: in this case the activity has not yet been created. 
  172. */ 
  173. if ( isset( $activity->post_url ) ) { 
  174. $post_url = $activity->post_url; 
  175.  
  176. /** 
  177. * The post_url property is not set, we need to build the url 
  178. * thanks to the post id which is also saved as the secondary 
  179. * item id property of the activity object. 
  180. */ 
  181. } else { 
  182. $post_url = add_query_arg( 'p', $activity->secondary_item_id, trailingslashit( $blog_url ) ); 
  183.  
  184. // Should be the case when the post has just been published. 
  185. if ( isset( $activity->post_title ) ) { 
  186. $post_title = $activity->post_title; 
  187.  
  188. // If activity already exists try to get the post title from activity meta. 
  189. } else if ( ! empty( $activity->id ) ) { 
  190. $post_title = bp_activity_get_meta( $activity->id, 'post_title' ); 
  191.  
  192. /** 
  193. * In case the post was published without a title 
  194. * or the activity meta was not found. 
  195. */ 
  196. if ( empty( $post_title ) ) { 
  197. // Defaults to no title. 
  198. $post_title = esc_html__( '(no title)', 'buddypress' ); 
  199.  
  200. switch_to_blog( $activity->item_id ); 
  201.  
  202. $post = get_post( $activity->secondary_item_id ); 
  203. if ( is_a( $post, 'WP_Post' ) ) { 
  204. // Does the post have a title ? 
  205. if ( ! empty( $post->post_title ) ) { 
  206. $post_title = $post->post_title; 
  207.  
  208. // Make sure the activity exists before saving the post title in activity meta. 
  209. if ( ! empty( $activity->id ) ) { 
  210. bp_activity_update_meta( $activity->id, 'post_title', $post_title ); 
  211.  
  212. restore_current_blog(); 
  213.  
  214. // Build the 'post link' part of the activity action string. 
  215. $post_link = '<a href="' . esc_url( $post_url ) . '">' . $post_title . '</a>'; 
  216.  
  217. $user_link = bp_core_get_userlink( $activity->user_id ); 
  218.  
  219. // Build the complete activity action string. 
  220. if ( is_multisite() ) { 
  221. $action = sprintf( __( '%1$s wrote a new post, %2$s, on the site %3$s', 'buddypress' ), $user_link, $post_link, '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' ); 
  222. } else { 
  223. $action = sprintf( __( '%1$s wrote a new post, %2$s', 'buddypress' ), $user_link, $post_link ); 
  224.  
  225. // Legacy filter - requires the post object. 
  226. if ( has_filter( 'bp_blogs_activity_new_post_action' ) ) { 
  227. switch_to_blog( $activity->item_id ); 
  228. $post = get_post( $activity->secondary_item_id ); 
  229. restore_current_blog(); 
  230.  
  231. if ( ! empty( $post ) && ! is_wp_error( $post ) ) { 
  232. $action = apply_filters( 'bp_blogs_activity_new_post_action', $action, $post, $post_url ); 
  233.  
  234. /** 
  235. * Filters the new blog post action for the new blog. 
  236. * 
  237. * @since 2.0.0 
  238. * 
  239. * @param string $action Constructed activity action. 
  240. * @param object $activity Activity data object. 
  241. */ 
  242. return apply_filters( 'bp_blogs_format_activity_action_new_blog_post', $action, $activity ); 
  243.  
  244. /** 
  245. * Format 'new_blog_comment' activity actions. 
  246. * 
  247. * @since 2.0.0 
  248. * 
  249. * @param string $action Static activity action. 
  250. * @param object $activity Activity data object. 
  251. * @return string Constructed activity action. 
  252. */ 
  253. function bp_blogs_format_activity_action_new_blog_comment( $action, $activity ) { 
  254. /** 
  255. * When the comment is published we are faking an activity object 
  256. * to which we add 4 properties : 
  257. * - the post url 
  258. * - the post title 
  259. * - the blog url 
  260. * - the blog name 
  261. * This is done to build the 'post link' part of the activity 
  262. * action string. 
  263. * NB: in this case the activity has not yet been created. 
  264. */ 
  265.  
  266. $blog_url = false; 
  267.  
  268. // Try to get the blog url from the activity object 
  269. if ( isset( $activity->blog_url ) ) { 
  270. $blog_url = $activity->blog_url; 
  271. } else { 
  272. $blog_url = bp_blogs_get_blogmeta( $activity->item_id, 'url' ); 
  273.  
  274. $blog_name = false; 
  275.  
  276. // Try to get the blog name from the activity object 
  277. if ( isset( $activity->blog_name ) ) { 
  278. $blog_name = $activity->blog_name; 
  279. } else { 
  280. $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' ); 
  281.  
  282. if ( empty( $blog_url ) || empty( $blog_name ) ) { 
  283. $blog_url = get_home_url( $activity->item_id ); 
  284. $blog_name = get_blog_option( $activity->item_id, 'blogname' ); 
  285.  
  286. bp_blogs_update_blogmeta( $activity->item_id, 'url', $blog_url ); 
  287. bp_blogs_update_blogmeta( $activity->item_id, 'name', $blog_name ); 
  288.  
  289. $post_url = false; 
  290.  
  291. // Try to get the post url from the activity object 
  292. if ( isset( $activity->post_url ) ) { 
  293. $post_url = $activity->post_url; 
  294.  
  295. /** 
  296. * The post_url property is not set, we need to build the url 
  297. * thanks to the post id which is also saved as the secondary 
  298. * item id property of the activity object. 
  299. */ 
  300. } elseif ( ! empty( $activity->id ) ) { 
  301. $post_url = bp_activity_get_meta( $activity->id, 'post_url' ); 
  302.  
  303. $post_title = false; 
  304.  
  305. // Should be the case when the comment has just been published 
  306. if ( isset( $activity->post_title ) ) { 
  307. $post_title = $activity->post_title; 
  308.  
  309. // If activity already exists try to get the post title from activity meta 
  310. } elseif ( ! empty( $activity->id ) ) { 
  311. $post_title = bp_activity_get_meta( $activity->id, 'post_title' ); 
  312.  
  313. // Should only be empty at the time of post creation. 
  314. if ( empty( $post_url ) || empty( $post_title ) ) { 
  315. switch_to_blog( $activity->item_id ); 
  316.  
  317. $comment = get_comment( $activity->secondary_item_id ); 
  318.  
  319. if ( ! empty( $comment->comment_post_ID ) ) { 
  320. $post_url = add_query_arg( 'p', $comment->comment_post_ID, trailingslashit( $blog_url ) ); 
  321. bp_activity_update_meta( $activity->id, 'post_url', $post_url ); 
  322.  
  323. $post = get_post( $comment->comment_post_ID ); 
  324.  
  325. if ( is_a( $post, 'WP_Post' ) ) { 
  326. $post_title = $post->post_title; 
  327. bp_activity_update_meta( $activity->id, 'post_title', $post_title ); 
  328.  
  329. restore_current_blog(); 
  330.  
  331. $post_link = '<a href="' . esc_url( $post_url ) . '">' . $post_title . '</a>'; 
  332. $user_link = bp_core_get_userlink( $activity->user_id ); 
  333.  
  334. if ( is_multisite() ) { 
  335. $action = sprintf( __( '%1$s commented on the post, %2$s, on the site %3$s', 'buddypress' ), $user_link, $post_link, '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' ); 
  336. } else { 
  337. $action = sprintf( __( '%1$s commented on the post, %2$s', 'buddypress' ), $user_link, $post_link ); 
  338.  
  339. // Legacy filter - requires the comment object. 
  340. if ( has_filter( 'bp_blogs_activity_new_comment_action' ) ) { 
  341. switch_to_blog( $activity->item_id ); 
  342. $comment = get_comment( $activity->secondary_item_id ); 
  343. restore_current_blog(); 
  344.  
  345. if ( ! empty( $comment ) && ! is_wp_error( $comment ) ) { 
  346. $action = apply_filters( 'bp_blogs_activity_new_comment_action', $action, $comment, $post_url . '#' . $activity->secondary_item_id ); 
  347.  
  348. /** 
  349. * Filters the new blog comment action for the new blog. 
  350. * 
  351. * @since 2.0.0 
  352. * 
  353. * @param string $action Constructed activity action. 
  354. * @param object $activity Activity data object. 
  355. */ 
  356. return apply_filters( 'bp_blogs_format_activity_action_new_blog_comment', $action, $activity ); 
  357.  
  358. /** 
  359. * Fetch data related to blogs at the beginning of an activity loop. 
  360. * 
  361. * This reduces database overhead during the activity loop. 
  362. * 
  363. * @since 2.0.0 
  364. * 
  365. * @param array $activities Array of activity items. 
  366. * @return array 
  367. */ 
  368. function bp_blogs_prefetch_activity_object_data( $activities ) { 
  369. if ( empty( $activities ) ) { 
  370. return $activities; 
  371.  
  372. $blog_ids = array(); 
  373.  
  374. foreach ( $activities as $activity ) { 
  375. if ( buddypress()->blogs->id !== $activity->component ) { 
  376. continue; 
  377.  
  378. $blog_ids[] = $activity->item_id; 
  379.  
  380. if ( ! empty( $blog_ids ) ) { 
  381. bp_blogs_update_meta_cache( $blog_ids ); 
  382.  
  383. return $activities; 
  384. add_filter( 'bp_activity_prefetch_object_data', 'bp_blogs_prefetch_activity_object_data' ); 
  385.  
  386. /** 
  387. * Record blog-related activity to the activity stream. 
  388. * 
  389. * @since 1.0.0 
  390. * 
  391. * @see bp_activity_add() for description of parameters. 
  392. * 
  393. * @param array|string $args { 
  394. * See {@link bp_activity_add()} for complete description of arguments. 
  395. * The arguments listed here have different default values from 
  396. * bp_activity_add(). 
  397. * @type string $component Default: 'blogs'. 
  398. * } 
  399. * @return int|bool On success, returns the activity ID. False on failure. 
  400. */ 
  401. function bp_blogs_record_activity( $args = '' ) { 
  402. $defaults = array( 
  403. 'user_id' => bp_loggedin_user_id(),  
  404. 'action' => '',  
  405. 'content' => '',  
  406. 'primary_link' => '',  
  407. 'component' => buddypress()->blogs->id,  
  408. 'type' => false,  
  409. 'item_id' => false,  
  410. 'secondary_item_id' => false,  
  411. 'recorded_time' => bp_core_current_time(),  
  412. 'hide_sitewide' => false 
  413. ); 
  414.  
  415. $r = wp_parse_args( $args, $defaults ); 
  416.  
  417. if ( ! empty( $r['action'] ) ) { 
  418.  
  419. /** 
  420. * Filters the action associated with activity for activity stream. 
  421. * 
  422. * @since 1.2.0 
  423. * 
  424. * @param string $value Action for the activity stream. 
  425. */ 
  426. $r['action'] = apply_filters( 'bp_blogs_record_activity_action', $r['action'] ); 
  427.  
  428. if ( ! empty( $r['content'] ) ) { 
  429.  
  430. /** 
  431. * Filters the content associated with activity for activity stream. 
  432. * 
  433. * @since 1.2.0 
  434. * 
  435. * @param string $value Generated summary from content for the activity stream. 
  436. * @param string $value Content for the activity stream. 
  437. * @param array $r Array of arguments used for the activity stream item. 
  438. */ 
  439. $r['content'] = apply_filters( 'bp_blogs_record_activity_content', bp_activity_create_summary( $r['content'], $r ), $r['content'], $r ); 
  440.  
  441. // Check for an existing entry and update if one exists. 
  442. $id = bp_activity_get_activity_id( array( 
  443. 'user_id' => $r['user_id'],  
  444. 'component' => $r['component'],  
  445. 'type' => $r['type'],  
  446. 'item_id' => $r['item_id'],  
  447. 'secondary_item_id' => $r['secondary_item_id'],  
  448. ) ); 
  449.  
  450. return bp_activity_add( array( 'id' => $id, 'user_id' => $r['user_id'], 'action' => $r['action'], 'content' => $r['content'], 'primary_link' => $r['primary_link'], 'component' => $r['component'], 'type' => $r['type'], 'item_id' => $r['item_id'], 'secondary_item_id' => $r['secondary_item_id'], 'recorded_time' => $r['recorded_time'], 'hide_sitewide' => $r['hide_sitewide'] ) ); 
  451.  
  452. /** 
  453. * Delete a blog-related activity stream item. 
  454. * 
  455. * @since 1.0.0 
  456. * 
  457. * @see bp_activity_delete() for description of parameters. 
  458. * 
  459. * @param array|string $args { 
  460. * See {@link bp_activity_delete()} for complete description of arguments. 
  461. * The arguments listed here have different default values from 
  462. * bp_activity_add(). 
  463. * @type string $component Default: 'blogs'. 
  464. * } 
  465. * @return bool True on success, false on failure. 
  466. */ 
  467. function bp_blogs_delete_activity( $args = '' ) { 
  468. $r = bp_parse_args( $args, array( 
  469. 'item_id' => false,  
  470. 'component' => buddypress()->blogs->id,  
  471. 'type' => false,  
  472. 'user_id' => false,  
  473. 'secondary_item_id' => false 
  474. ) ); 
  475.  
  476. bp_activity_delete_by_item_id( $r ); 
  477.  
  478. /** 
  479. * Check if a blog post's activity item should be closed from commenting. 
  480. * 
  481. * This mirrors the {@link comments_open()} and {@link _close_comments_for_old_post()} 
  482. * functions, but for use with the BuddyPress activity stream to be as 
  483. * lightweight as possible. 
  484. * 
  485. * By lightweight, we actually mirror a few of the blog's commenting settings 
  486. * to blogmeta and checks the values in blogmeta instead. This is to prevent 
  487. * multiple {@link switch_to_blog()} calls in the activity stream. 
  488. * 
  489. * @since 2.0.0 
  490. * 
  491. * @param object $activity The BP_Activity_Activity object. 
  492. * @return bool 
  493. */ 
  494. function bp_blogs_comments_open( $activity ) { 
  495. $open = true; 
  496.  
  497. $blog_id = $activity->item_id; 
  498.  
  499. // See if we've mirrored the close comments option before. 
  500. $days_old = bp_blogs_get_blogmeta( $blog_id, 'close_comments_days_old' ); 
  501.  
  502. // We've never cached these items before, so do it now. 
  503. if ( '' === $days_old ) { 
  504. switch_to_blog( $blog_id ); 
  505.  
  506. // Use comments_open(). 
  507. remove_filter( 'comments_open', 'bp_comments_open', 10, 2 ); 
  508. $open = comments_open( $activity->secondary_item_id ); 
  509. add_filter( 'comments_open', 'bp_comments_open', 10, 2 ); 
  510.  
  511. // Might as well mirror values to blogmeta since we're here! 
  512. $thread_depth = get_option( 'thread_comments' ); 
  513. if ( ! empty( $thread_depth ) ) { 
  514. $thread_depth = get_option( 'thread_comments_depth' ); 
  515. } else { 
  516. // Perhaps filter this? 
  517. $thread_depth = 1; 
  518.  
  519. bp_blogs_update_blogmeta( $blog_id, 'close_comments_for_old_posts', get_option( 'close_comments_for_old_posts' ) ); 
  520. bp_blogs_update_blogmeta( $blog_id, 'close_comments_days_old', get_option( 'close_comments_days_old' ) ); 
  521. bp_blogs_update_blogmeta( $blog_id, 'thread_comments_depth', $thread_depth ); 
  522.  
  523. restore_current_blog(); 
  524.  
  525. // Check blogmeta and manually check activity item. 
  526. // Basically a copy of _close_comments_for_old_post(). 
  527. } else { 
  528.  
  529. // Comments are closed. 
  530. if ( 'closed' == bp_activity_get_meta( $activity->id, 'post_comment_status' ) ) { 
  531. return false; 
  532.  
  533. if ( ! bp_blogs_get_blogmeta( $blog_id, 'close_comments_for_old_posts' ) ) { 
  534. return $open; 
  535.  
  536. $days_old = (int) $days_old; 
  537. if ( ! $days_old ) { 
  538. return $open; 
  539.  
  540. /** 
  541. Commenting out for now - needs some more thought... 
  542. should we add the post type to activity meta? 
  543.   
  544. $post = get_post($post_id); 
  545.   
  546. // This filter is documented in wp-includes/comment.php 
  547. $post_types = apply_filters( 'close_comments_for_post_types', array( 'post' ) ); 
  548. if ( ! in_array( $post->post_type, $post_types ) ) 
  549. return $open; 
  550. */ 
  551.  
  552. if ( time() - strtotime( $activity->date_recorded ) > ( $days_old * DAY_IN_SECONDS ) ) { 
  553. return false; 
  554.  
  555. return $open; 
  556.  
  557. return $open; 
  558.  
  559. /** SITE TRACKING *******************************************************/ 
  560.  
  561. /** 
  562. * Add an activity entry for a newly-created site. 
  563. * 
  564. * Hooked to the 'bp_blogs_new_blog' action. 
  565. * 
  566. * @since 2.6.0 
  567. * 
  568. * @param BP_Blogs_Blog $recorded_blog Current site being recorded. Passed by reference. 
  569. * @param bool $is_private Whether the current site being recorded is private. 
  570. * @param bool $is_recorded Whether the current site was recorded. 
  571. */ 
  572. function bp_blogs_record_activity_on_site_creation( $recorded_blog, $is_private, $is_recorded, $no_activity ) { 
  573. // Only record this activity if the blog is public. 
  574. if ( ! $is_private && ! $no_activity && bp_blogs_is_blog_trackable( $recorded_blog->blog_id, $recorded_blog->user_id ) ) { 
  575. bp_blogs_record_activity( array( 
  576. 'user_id' => $recorded_blog->user_id,  
  577. 'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', bp_blogs_get_blogmeta( $recorded_blog->blog_id, 'url' ), $recorded_blog->blog_id ),  
  578. 'type' => 'new_blog',  
  579. 'item_id' => $recorded_blog->blog_id 
  580. ) ); 
  581. add_action( 'bp_blogs_new_blog', 'bp_blogs_record_activity_on_site_creation', 10, 4 ); 
  582.  
  583. /** 
  584. * Deletes the 'new_blog' activity entry when a site is deleted. 
  585. * 
  586. * @since 2.6.0 
  587. * 
  588. * @param int $blog_id Site ID. 
  589. */ 
  590. function bp_blogs_delete_new_blog_activity_for_site( $blog_id, $user_id = 0 ) { 
  591. $args = array( 
  592. 'item_id' => $blog_id,  
  593. 'component' => buddypress()->blogs->id,  
  594. 'type' => 'new_blog' 
  595. ); 
  596.  
  597. /** 
  598. * In the case a user is removed, make sure he is the author of the 'new_blog' activity 
  599. * when trying to delete it. 
  600. */ 
  601. if ( ! empty( $user_id ) ) { 
  602. $args['user_id'] = $user_id; 
  603.  
  604. bp_blogs_delete_activity( $args ); 
  605. add_action( 'bp_blogs_remove_blog', 'bp_blogs_delete_new_blog_activity_for_site', 10, 1 ); 
  606. add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_delete_new_blog_activity_for_site', 10, 2 ); 
  607.  
  608. /** 
  609. * Delete all 'blogs' activity items for a site when the site is deleted. 
  610. * 
  611. * @since 2.6.0 
  612. * 
  613. * @param int $blog_id Site ID. 
  614. */ 
  615. function bp_blogs_delete_activity_for_site( $blog_id ) { 
  616. bp_blogs_delete_activity( array( 
  617. 'item_id' => $blog_id,  
  618. 'component' => buddypress()->blogs->id,  
  619. 'type' => false 
  620. ) ); 
  621. add_action( 'bp_blogs_remove_data_for_blog', 'bp_blogs_delete_activity_for_site' ); 
  622.  
  623. /** 
  624. * Remove a blog post activity item from the activity stream. 
  625. * 
  626. * @since 1.0.0 
  627. * 
  628. * @param int $post_id ID of the post to be removed. 
  629. * @param int $blog_id Optional. Defaults to current blog ID. 
  630. * @param int $user_id Optional. Defaults to the logged-in user ID. This param 
  631. * is currently unused in the function (but is passed to hooks). 
  632. * @return bool 
  633. */ 
  634. function bp_blogs_remove_post( $post_id, $blog_id = 0, $user_id = 0 ) { 
  635. global $wpdb; 
  636.  
  637. if ( empty( $wpdb->blogid ) ) { 
  638. return false; 
  639.  
  640. $post_id = (int) $post_id; 
  641.  
  642. if ( ! $blog_id ) { 
  643. $blog_id = (int) $wpdb->blogid; 
  644.  
  645. if ( ! $user_id ) { 
  646. $user_id = bp_loggedin_user_id(); 
  647.  
  648. /** 
  649. * Fires before removal of a blog post activity item from the activity stream. 
  650. * 
  651. * @since 1.5.0 
  652. * 
  653. * @param int $blog_id ID of the blog associated with the post that was removed. 
  654. * @param int $post_id ID of the post that was removed. 
  655. * @param int $user_id ID of the user having the blog removed for. 
  656. */ 
  657. do_action( 'bp_blogs_before_remove_post', $blog_id, $post_id, $user_id ); 
  658.  
  659. bp_blogs_delete_activity( array( 
  660. 'item_id' => $blog_id,  
  661. 'secondary_item_id' => $post_id,  
  662. 'component' => buddypress()->blogs->id,  
  663. 'type' => 'new_blog_post' 
  664. ) ); 
  665.  
  666. /** 
  667. * Fires after removal of a blog post activity item from the activity stream. 
  668. * 
  669. * @since 1.0.0 
  670. * 
  671. * @param int $blog_id ID of the blog associated with the post that was removed. 
  672. * @param int $post_id ID of the post that was removed. 
  673. * @param int $user_id ID of the user having the blog removed for. 
  674. */ 
  675. do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $user_id ); 
  676. add_action( 'delete_post', 'bp_blogs_remove_post' ); 
  677.  
  678. /** POST COMMENT SYNCHRONIZATION ****************************************/ 
  679.  
  680. /** 
  681. * Syncs activity comments and posts them back as blog comments. 
  682. * 
  683. * Note: This is only a one-way sync - activity comments -> blog comment. 
  684. * 
  685. * For blog post -> activity comment, see {@link bp_activity_post_type_comment()}. 
  686. * 
  687. * @since 2.0.0 
  688. * @since 2.5.0 Allow custom post types to sync their comments with activity ones 
  689. * 
  690. * @param int $comment_id The activity ID for the posted activity comment. 
  691. * @param array $params Parameters for the activity comment. 
  692. * @param object $parent_activity Parameters of the parent activity item (in this case, the blog post). 
  693. */ 
  694. function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_activity ) { 
  695. // if parent activity isn't a post type having the buddypress-activity support, stop now! 
  696. if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) { 
  697. return; 
  698.  
  699. // If activity comments are disabled for blog posts, stop now! 
  700. if ( bp_disable_blogforum_comments() ) { 
  701. return; 
  702.  
  703. // Do not sync if the activity comment was marked as spam. 
  704. $activity = new BP_Activity_Activity( $comment_id ); 
  705. if ( $activity->is_spam ) { 
  706. return; 
  707.  
  708. // Get userdata. 
  709. if ( $params['user_id'] == bp_loggedin_user_id() ) { 
  710. $user = buddypress()->loggedin_user->userdata; 
  711. } else { 
  712. $user = bp_core_get_core_userdata( $params['user_id'] ); 
  713.  
  714. // Get associated post type and set default comment parent 
  715. $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ); 
  716. $comment_parent = 0; 
  717.  
  718. // See if a parent WP comment ID exists. 
  719. if ( ! empty( $params['parent_id'] ) && ! empty( $post_type ) ) { 
  720. $comment_parent = bp_activity_get_meta( $params['parent_id'], "bp_blogs_{$post_type}_comment_id" ); 
  721.  
  722. // Comment args. 
  723. $args = array( 
  724. 'comment_post_ID' => $parent_activity->secondary_item_id,  
  725. 'comment_author' => bp_core_get_user_displayname( $params['user_id'] ),  
  726. 'comment_author_email' => $user->user_email,  
  727. 'comment_author_url' => bp_core_get_user_domain( $params['user_id'], $user->user_nicename, $user->user_login ),  
  728. 'comment_content' => $params['content'],  
  729. 'comment_type' => '', // Could be interesting to add 'buddypress' here... 
  730. 'comment_parent' => (int) $comment_parent,  
  731. 'user_id' => $params['user_id'],  
  732. 'comment_approved' => 1 
  733. ); 
  734.  
  735. // Prevent separate activity entry being made. 
  736. remove_action( 'comment_post', 'bp_activity_post_type_comment', 10, 2 ); 
  737.  
  738. // Handle multisite. 
  739. switch_to_blog( $parent_activity->item_id ); 
  740.  
  741. // Handle timestamps for the WP comment after we've switched to the blog. 
  742. $args['comment_date'] = current_time( 'mysql' ); 
  743. $args['comment_date_gmt'] = current_time( 'mysql', 1 ); 
  744.  
  745. // Post the comment. 
  746. $post_comment_id = wp_insert_comment( $args ); 
  747.  
  748. // Add meta to comment. 
  749. add_comment_meta( $post_comment_id, 'bp_activity_comment_id', $comment_id ); 
  750.  
  751. // Add meta to activity comment. 
  752. if ( ! empty( $post_type ) ) { 
  753. bp_activity_update_meta( $comment_id, "bp_blogs_{$post_type}_comment_id", $post_comment_id ); 
  754.  
  755. // Resave activity comment with WP comment permalink. 
  756. // 
  757. // in bp_blogs_activity_comment_permalink(), we change activity comment 
  758. // permalinks to use the post comment link 
  759. // 
  760. // @todo since this is done after AJAX posting, the activity comment permalink 
  761. // doesn't change on the frontend until the next page refresh. 
  762. $resave_activity = new BP_Activity_Activity( $comment_id ); 
  763. $resave_activity->primary_link = get_comment_link( $post_comment_id ); 
  764.  
  765. /** 
  766. * Now that the activity id exists and the post comment was created, we don't need to update 
  767. * the content of the comment as there are no chances it has evolved. 
  768. */ 
  769. remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 ); 
  770.  
  771. $resave_activity->save(); 
  772.  
  773. // Add the edit activity comment hook back. 
  774. add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 ); 
  775.  
  776. // Multisite again! 
  777. restore_current_blog(); 
  778.  
  779. // Add the comment hook back. 
  780. add_action( 'comment_post', 'bp_activity_post_type_comment', 10, 2 ); 
  781.  
  782. /** 
  783. * Fires after activity comments have been synced and posted as blog comments. 
  784. * 
  785. * @since 2.0.0 
  786. * 
  787. * @param int $comment_id The activity ID for the posted activity comment. 
  788. * @param array $args Array of args used for the comment syncing. 
  789. * @param object $parent_activity Parameters of the blog post parent activity item. 
  790. * @param object $user User data object for the blog comment. 
  791. */ 
  792. do_action( 'bp_blogs_sync_add_from_activity_comment', $comment_id, $args, $parent_activity, $user ); 
  793. add_action( 'bp_activity_comment_posted', 'bp_blogs_sync_add_from_activity_comment', 10, 3 ); 
  794.  
  795. /** 
  796. * Deletes the blog comment when the associated activity comment is deleted. 
  797. * 
  798. * Note: This is hooked on the 'bp_activity_delete_comment_pre' filter instead 
  799. * of the 'bp_activity_delete_comment' action because we need to fetch the 
  800. * activity comment children before they are deleted. 
  801. * 
  802. * @since 2.0.0 
  803. * @since 2.5.0 Add the $delected parameter 
  804. * 
  805. * @param bool $retval Whether BuddyPress should continue or not. 
  806. * @param int $parent_activity_id The parent activity ID for the activity comment. 
  807. * @param int $activity_id The activity ID for the pending deleted activity comment. 
  808. * @param bool $deleted Whether the comment was deleted or not. 
  809. * @return bool 
  810. */ 
  811. function bp_blogs_sync_delete_from_activity_comment( $retval, $parent_activity_id, $activity_id, &$deleted ) { 
  812. // Check if parent activity is a blog post. 
  813. $parent_activity = new BP_Activity_Activity( $parent_activity_id ); 
  814.  
  815. // if parent activity isn't a post type having the buddypress-activity support, stop now! 
  816. if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) { 
  817. return $retval; 
  818.  
  819. // Fetch the activity comments for the activity item. 
  820. $activity = bp_activity_get( array( 
  821. 'in' => $activity_id,  
  822. 'display_comments' => 'stream',  
  823. 'spam' => 'all',  
  824. ) ); 
  825.  
  826. // Get all activity comment IDs for the pending deleted item. 
  827. $activity_ids = bp_activity_recurse_comments_activity_ids( $activity ); 
  828. $activity_ids[] = $activity_id; 
  829.  
  830. // Handle multisite 
  831. // switch to the blog where the comment was made. 
  832. switch_to_blog( $parent_activity->item_id ); 
  833.  
  834. // Remove associated blog comments. 
  835. bp_blogs_remove_associated_blog_comments( $activity_ids, current_user_can( 'moderate_comments' ) ); 
  836.  
  837. // Multisite again! 
  838. restore_current_blog(); 
  839.  
  840. // Rebuild activity comment tree 
  841. // emulate bp_activity_delete_comment(). 
  842. BP_Activity_Activity::rebuild_activity_comment_tree( $parent_activity_id ); 
  843.  
  844. // Avoid the error message although the comments were successfully deleted 
  845. $deleted = true; 
  846.  
  847. // We're overriding the default bp_activity_delete_comment() functionality 
  848. // so we need to return false. 
  849. return false; 
  850. add_filter( 'bp_activity_delete_comment_pre', 'bp_blogs_sync_delete_from_activity_comment', 10, 4 ); 
  851.  
  852. /** 
  853. * Updates the blog comment when the associated activity comment is edited. 
  854. * 
  855. * @since 2.0.0 
  856. * 
  857. * @param BP_Activity_Activity $activity The activity object. 
  858. */ 
  859. function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $activity ) { 
  860. // This is a new entry, so stop! 
  861. // We only want edits! 
  862. if ( empty( $activity->id ) || bp_disable_blogforum_comments() ) { 
  863. return; 
  864.  
  865. // fetch parent activity item 
  866. $parent_activity = new BP_Activity_Activity( $activity->item_id ); 
  867.  
  868. // if parent activity isn't a post type having the buddypress-activity support for comments, stop now! 
  869. if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) { 
  870. return; 
  871.  
  872. $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ); 
  873.  
  874. // No associated post type for this activity comment, stop. 
  875. if ( ! $post_type ) { 
  876. return; 
  877.  
  878. // Try to see if a corresponding blog comment exists. 
  879. $post_comment_id = bp_activity_get_meta( $activity->id, "bp_blogs_{$post_type}_comment_id" ); 
  880.  
  881. if ( empty( $post_comment_id ) ) { 
  882. return; 
  883.  
  884. // Handle multisite. 
  885. switch_to_blog( $parent_activity->item_id ); 
  886.  
  887. // Get the comment status 
  888. $post_comment_status = wp_get_comment_status( $post_comment_id ); 
  889. $old_comment_status = $post_comment_status; 
  890.  
  891. // No need to edit the activity, as it's the activity who's updating the comment 
  892. remove_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 ); 
  893. remove_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10, 4 ); 
  894.  
  895. if ( 1 === $activity->is_spam && 'spam' !== $post_comment_status ) { 
  896. wp_spam_comment( $post_comment_id ); 
  897. } elseif ( ! $activity->is_spam ) { 
  898. if ( 'spam' === $post_comment_status ) { 
  899. wp_unspam_comment( $post_comment_id ); 
  900. } elseif ( 'trash' === $post_comment_status ) { 
  901. wp_untrash_comment( $post_comment_id ); 
  902. } else { 
  903. // Update the blog post comment. 
  904. wp_update_comment( array( 
  905. 'comment_ID' => $post_comment_id,  
  906. 'comment_content' => $activity->content,  
  907. ) ); 
  908.  
  909. // Restore actions 
  910. add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 ); 
  911. add_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10, 4 ); 
  912.  
  913. restore_current_blog(); 
  914. add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 ); 
  915.  
  916. /** 
  917. * When a post is trashed, remove each comment's associated activity meta. 
  918. * 
  919. * When a post is trashed and later untrashed, we currently don't reinstate 
  920. * activity items for these comments since their activity entries are already 
  921. * deleted when initially trashed. 
  922. * 
  923. * Since these activity entries are deleted, we need to remove the deleted 
  924. * activity comment IDs from each comment's meta when a post is trashed. 
  925. * 
  926. * @since 2.0.0 
  927. * 
  928. * @param int $post_id The post ID. 
  929. * @param array $comments Array of comment statuses. The key is comment ID, the 
  930. * value is the $comment->comment_approved value. 
  931. */ 
  932. function bp_blogs_remove_activity_meta_for_trashed_comments( $post_id = 0, $comments = array() ) { 
  933. if ( ! empty( $comments ) ) { 
  934. foreach ( array_keys( $comments ) as $comment_id ) { 
  935. delete_comment_meta( $comment_id, 'bp_activity_comment_id' ); 
  936. add_action( 'trashed_post_comments', 'bp_blogs_remove_activity_meta_for_trashed_comments', 10, 2 ); 
  937.  
  938. /** 
  939. * Filter 'new_blog_comment' bp_has_activities() loop to include new- and old-style blog activity comment items. 
  940. * 
  941. * In BuddyPress 2.0, the schema for storing activity items related to blog 
  942. * posts changed. Instead creating new top-level 'new_blog_comment' activity 
  943. * items, blog comments are recorded in the activity stream as comments on the 
  944. * 'new_blog_post' activity items corresponding to the parent post. This filter 
  945. * ensures that the 'new_blog_comment' filter in bp_has_activities() (which 
  946. * powers the 'Comments' filter in the activity directory dropdown) includes 
  947. * both old-style and new-style activity comments. 
  948. * 
  949. * @since 2.1.0 
  950. * @since 2.5.0 Used for any synced Post type comments, in wp-admin or front-end contexts. 
  951. * 
  952. * @param array $args Arguments passed from bp_parse_args() in bp_has_activities(). 
  953. * @return array $args 
  954. */ 
  955. function bp_blogs_new_blog_comment_query_backpat( $args ) { 
  956. global $wpdb; 
  957. $bp = buddypress(); 
  958.  
  959. // If activity comments are disabled for blog posts, stop now! 
  960. if ( bp_disable_blogforum_comments() ) { 
  961. return $args; 
  962.  
  963. // Get the associated post type 
  964. $post_type = bp_activity_post_type_get_tracking_arg( $args['action'], 'post_type' ); 
  965.  
  966. // Bail if this is not an activity associated with a post type 
  967. if ( empty( $post_type ) ) { 
  968. return $args; 
  969.  
  970. // Bail if this is an activity about posts and not comments 
  971. if ( bp_activity_post_type_get_tracking_arg( $args['action'], 'comment_action_id' ) ) { 
  972. return $args; 
  973.  
  974. // Comment synced ? 
  975. $activity_ids = $wpdb->get_col( $wpdb->prepare( "SELECT activity_id FROM {$bp->activity->table_name_meta} WHERE meta_key = %s", "bp_blogs_{$post_type}_comment_id" ) ); 
  976.  
  977. if ( empty( $activity_ids ) ) { 
  978. return $args; 
  979.  
  980. // Init the filter query. 
  981. $filter_query = array(); 
  982.  
  983. if ( ! isset( $args['scope'] ) || 'null' === $args['scope'] ) { 
  984. $args['scope'] = ''; 
  985. } elseif ( 'just-me' === $args['scope'] ) { 
  986. $filter_query = array( 
  987. 'relation' => 'AND',  
  988. array( 
  989. 'column' => 'user_id',  
  990. 'value' => bp_displayed_user_id(),  
  991. ),  
  992. ); 
  993. $args['scope'] = ''; 
  994.  
  995. $filter_query[] = array( 
  996. 'relation' => 'OR',  
  997. array( 
  998. 'column' => 'type',  
  999. 'value' => $args['action'],  
  1000. ),  
  1001. array( 
  1002. 'column' => 'id',  
  1003. 'value' => $activity_ids,  
  1004. 'compare' => 'IN' 
  1005. ),  
  1006. ); 
  1007.  
  1008. $args['filter_query'] = $filter_query; 
  1009.  
  1010. // Make sure to have comment in stream mode && avoid duplicate content. 
  1011. $args['display_comments'] = 'stream'; 
  1012.  
  1013. // Finally reset the action. 
  1014. $args['action'] = ''; 
  1015. $args['type'] = ''; 
  1016.  
  1017. // Return the original arguments. 
  1018. return $args; 
  1019. add_filter( 'bp_after_has_activities_parse_args', 'bp_blogs_new_blog_comment_query_backpat' ); 
  1020. add_filter( 'bp_activity_list_table_filter_activity_type_items', 'bp_blogs_new_blog_comment_query_backpat' ); 
  1021.  
  1022. /** 
  1023. * Utility function to set up some variables for use in the activity loop. 
  1024. * 
  1025. * Grabs the blog's comment depth and the post's open comment status options 
  1026. * for later use in the activity and activity comment loops. 
  1027. * 
  1028. * This is to prevent having to requery these items later on. 
  1029. * 
  1030. * @since 2.0.0 
  1031. * 
  1032. * @see bp_blogs_disable_activity_commenting() 
  1033. * @see bp_blogs_setup_comment_loop_globals_on_ajax() 
  1034. * 
  1035. * @param object $activity The BP_Activity_Activity object. 
  1036. */ 
  1037. function bp_blogs_setup_activity_loop_globals( $activity ) { 
  1038. if ( ! is_object( $activity ) ) { 
  1039. return; 
  1040.  
  1041. // The activity type does not support comments or replies ? stop now! 
  1042. if ( ! bp_activity_type_supports( $activity->type, 'post-type-comment-reply' ) ) { 
  1043. return; 
  1044.  
  1045. if ( empty( $activity->id ) ) { 
  1046. return; 
  1047.  
  1048. // If we've already done this before, stop now! 
  1049. if ( isset( buddypress()->blogs->allow_comments[ $activity->id ] ) ) { 
  1050. return; 
  1051.  
  1052. $allow_comments = bp_blogs_comments_open( $activity ); 
  1053. $thread_depth = bp_blogs_get_blogmeta( $activity->item_id, 'thread_comments_depth' ); 
  1054.  
  1055. // Initialize a local object so we won't have to query this again in the 
  1056. // comment loop. 
  1057. if ( empty( buddypress()->blogs->allow_comments ) ) { 
  1058. buddypress()->blogs->allow_comments = array(); 
  1059. if ( empty( buddypress()->blogs->thread_depth ) ) { 
  1060. buddypress()->blogs->thread_depth = array(); 
  1061.  
  1062. // Cache comment settings in the buddypress() singleton to reference later in 
  1063. // the activity comment loop 
  1064. // @see bp_blogs_disable_activity_replies() 
  1065. // 
  1066. // thread_depth is keyed by activity ID instead of blog ID because when we're 
  1067. // in a comment loop, we don't have access to the blog ID... 
  1068. // should probably object cache these values instead... 
  1069. buddypress()->blogs->allow_comments[ $activity->id ] = $allow_comments; 
  1070. buddypress()->blogs->thread_depth[ $activity->id ] = $thread_depth; 
  1071.  
  1072. /** 
  1073. * Set up some globals used in the activity comment loop when AJAX is used. 
  1074. * 
  1075. * @since 2.0.0 
  1076. * 
  1077. * @see bp_blogs_setup_activity_loop_globals() 
  1078. */ 
  1079. function bp_blogs_setup_comment_loop_globals_on_ajax() { 
  1080. // Not AJAX? stop now! 
  1081. if ( ! defined( 'DOING_AJAX' ) ) { 
  1082. return; 
  1083. if ( false === (bool) constant( 'DOING_AJAX' ) ) { 
  1084. return; 
  1085.  
  1086. // Get the parent activity item. 
  1087. $comment = bp_activity_current_comment(); 
  1088. $parent_activity = new BP_Activity_Activity( $comment->item_id ); 
  1089.  
  1090. // Setup the globals. 
  1091. bp_blogs_setup_activity_loop_globals( $parent_activity ); 
  1092. add_action( 'bp_before_activity_comment', 'bp_blogs_setup_comment_loop_globals_on_ajax' ); 
  1093.  
  1094. /** 
  1095. * Disable activity commenting for blog posts based on certain criteria. 
  1096. * 
  1097. * If activity commenting is enabled for blog posts, we still need to disable 
  1098. * commenting if: 
  1099. * - comments are disabled for the WP blog post from the admin dashboard 
  1100. * - the WP blog post is supposed to be automatically closed from comments 
  1101. * based on a certain age 
  1102. * - the activity entry is a 'new_blog_comment' type 
  1103. * 
  1104. * @since 2.0.0 
  1105. * 
  1106. * @param bool $retval Is activity commenting enabled for this activity entry. 
  1107. * @return bool 
  1108. */ 
  1109. function bp_blogs_disable_activity_commenting( $retval ) { 
  1110. global $activities_template; 
  1111.  
  1112. // If activity commenting is disabled, return current value. 
  1113. if ( bp_disable_blogforum_comments() || ! isset( $activities_template->in_the_loop ) ) { 
  1114. return $retval; 
  1115.  
  1116. $type = bp_get_activity_type(); 
  1117.  
  1118. // It's a post type supporting comment tracking. 
  1119. if ( bp_activity_type_supports( $type, 'post-type-comment-tracking' ) ) { 
  1120. // The activity type is supporting comments or replies 
  1121. if ( bp_activity_type_supports( $type, 'post-type-comment-reply' ) ) { 
  1122. // Setup some globals we'll need to reference later. 
  1123. bp_blogs_setup_activity_loop_globals( $activities_template->activity ); 
  1124.  
  1125. // If comments are closed for the WP blog post, we should disable 
  1126. // activity comments for this activity entry. 
  1127. if ( empty( buddypress()->blogs->allow_comments[ bp_get_activity_id() ] ) ) { 
  1128. $retval = false; 
  1129. // The activity type does not support comments or replies 
  1130. } else { 
  1131. $retval = false; 
  1132.  
  1133. return $retval; 
  1134. add_filter( 'bp_activity_can_comment', 'bp_blogs_disable_activity_commenting' ); 
  1135.  
  1136. /** 
  1137. * Limit the display of post type synced comments. 
  1138. * 
  1139. * @since 2.5.0 
  1140. * 
  1141. * When viewing the synced comments in stream mode, this prevents comments to 
  1142. * be displayed twice, and avoids a Javascript error as the form to add replies 
  1143. * is not available. 
  1144. * 
  1145. * @param int $retval The comment count for the activity. 
  1146. * @return int The comment count, or 0 to hide activity comment replies. 
  1147. */ 
  1148. function bp_blogs_post_type_comments_avoid_duplicates( $retval ) { 
  1149. /** 
  1150. * Only limit the display when Post type comments are synced with 
  1151. * activity comments. 
  1152. */ 
  1153. if ( bp_disable_blogforum_comments() ) { 
  1154. return $retval; 
  1155.  
  1156. if ( 'activity_comment' !== bp_get_activity_type() ) { 
  1157. return $retval; 
  1158.  
  1159. // Check the parent activity 
  1160. $parent_activity = new BP_Activity_Activity( bp_get_activity_item_id() ); 
  1161.  
  1162. if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) { 
  1163. $retval = 0; 
  1164.  
  1165. return $retval; 
  1166. add_filter( 'bp_activity_get_comment_count', 'bp_blogs_post_type_comments_avoid_duplicates' ); 
  1167.  
  1168. /** 
  1169. * Check if an activity comment associated with a blog post can be replied to. 
  1170. * 
  1171. * By default, disables replying to activity comments if the corresponding WP 
  1172. * blog post no longer accepts comments. 
  1173. * 
  1174. * This check uses a locally-cached value set in {@link bp_blogs_disable_activity_commenting()} 
  1175. * via {@link bp_blogs_setup_activity_loop_globals()}. 
  1176. * 
  1177. * @since 2.0.0 
  1178. * 
  1179. * @param bool $retval Are replies allowed for this activity reply. 
  1180. * @param object|array $comment The activity comment object. 
  1181. * 
  1182. * @return bool 
  1183. */ 
  1184. function bp_blogs_can_comment_reply( $retval, $comment ) { 
  1185. if ( is_array( $comment ) ) { 
  1186. $comment = (object) $comment; 
  1187.  
  1188. // Check comment depth and disable if depth is too large. 
  1189. if ( isset( buddypress()->blogs->thread_depth[$comment->item_id] ) ) { 
  1190. if ( bp_activity_get_comment_depth() > buddypress()->blogs->thread_depth[$comment->item_id] ) { 
  1191. $retval = false; 
  1192.  
  1193. // Check if we should disable activity replies based on the parent activity. 
  1194. if ( isset( buddypress()->blogs->allow_comments[$comment->item_id] ) ) { 
  1195. // The blog post has closed off commenting, so we should disable all activity 
  1196. // comments under the parent 'new_blog_post' activity entry. 
  1197. if ( empty( buddypress()->blogs->allow_comments[$comment->item_id] ) ) { 
  1198. $retval = false; 
  1199.  
  1200. return $retval; 
  1201. add_filter( 'bp_activity_can_comment_reply', 'bp_blogs_can_comment_reply', 10, 2 ); 
  1202.  
  1203. /** 
  1204. * Changes activity comment permalinks to use the blog comment permalink 
  1205. * instead of the activity permalink. 
  1206. * 
  1207. * This is only done if activity commenting is allowed and whether the parent 
  1208. * activity item is a 'new_blog_post' entry. 
  1209. * 
  1210. * @since 2.0.0 
  1211. * 
  1212. * @param string $retval The activity comment permalink. 
  1213. * @return string 
  1214. */ 
  1215. function bp_blogs_activity_comment_permalink( $retval = '' ) { 
  1216. global $activities_template; 
  1217.  
  1218. // Get the current comment ID. 
  1219. $item_id = isset( $activities_template->activity->current_comment->item_id ) 
  1220. ? $activities_template->activity->current_comment->item_id 
  1221. : false; 
  1222.  
  1223. // Maybe adjust the link if item ID exists. 
  1224. if ( ( false !== $item_id ) && isset( buddypress()->blogs->allow_comments[ $item_id ] ) ) { 
  1225. $retval = $activities_template->activity->current_comment->primary_link; 
  1226.  
  1227. return $retval; 
  1228. add_filter( 'bp_get_activity_comment_permalink', 'bp_blogs_activity_comment_permalink' ); 
  1229.  
  1230. /** 
  1231. * Changes single activity comment entries to use the blog comment permalink. 
  1232. * 
  1233. * This is only done if the activity comment is associated with a blog comment. 
  1234. * 
  1235. * @since 2.0.1 
  1236. * 
  1237. * @param string $retval The activity permalink. 
  1238. * @param BP_Activity_Activity $activity Activity object. 
  1239. * @return string 
  1240. */ 
  1241. function bp_blogs_activity_comment_single_permalink( $retval, $activity ) { 
  1242. if ( 'activity_comment' !== $activity->type ) { 
  1243. return $retval; 
  1244.  
  1245. if ( bp_disable_blogforum_comments() ) { 
  1246. return $retval; 
  1247.  
  1248. $parent_activity = new BP_Activity_Activity( $activity->item_id ); 
  1249.  
  1250. if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) { 
  1251. $retval = $activity->primary_link; 
  1252.  
  1253. return $retval; 
  1254. add_filter( 'bp_activity_get_permalink', 'bp_blogs_activity_comment_single_permalink', 10, 2 ); 
  1255.  
  1256. /** 
  1257. * Formats single activity comment entries to use the blog comment action. 
  1258. * 
  1259. * This is only done if the activity comment is associated with a blog comment. 
  1260. * 
  1261. * @since 2.0.1 
  1262. * 
  1263. * @param string $retval The activity action. 
  1264. * @param BP_Activity_Activity $activity Activity object. 
  1265. * @return string 
  1266. */ 
  1267. function bp_blogs_activity_comment_single_action( $retval, $activity ) { 
  1268. if ( 'activity_comment' !== $activity->type ) { 
  1269. return $retval; 
  1270.  
  1271. if ( bp_disable_blogforum_comments() ) { 
  1272. return $retval; 
  1273.  
  1274. $parent_activity = new BP_Activity_Activity( $activity->item_id ); 
  1275.  
  1276. if ( ! isset( $parent_activity->type ) ) { 
  1277. return $retval; 
  1278.  
  1279. $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ); 
  1280.  
  1281. if ( ! $post_type ) { 
  1282. return $retval; 
  1283.  
  1284. $blog_comment_id = bp_activity_get_meta( $activity->id, "bp_blogs_{$post_type}_comment_id" ); 
  1285.  
  1286. if ( ! empty( $blog_comment_id ) ) { 
  1287. $bp = buddypress(); 
  1288.  
  1289. // Check if a comment action id is set for the parent activity 
  1290. $comment_action_id = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'comment_action_id' ); 
  1291.  
  1292. // Use the action string callback for the activity type 
  1293. if ( ! empty( $comment_action_id ) ) { 
  1294. // Fake a 'new_{post_type}_comment' by cloning the activity object. 
  1295. $object = clone $activity; 
  1296.  
  1297. // Set the type of the activity to be a comment about a post type 
  1298. $object->type = $comment_action_id; 
  1299.  
  1300. // Use the blog ID as the item_id. 
  1301. $object->item_id = $parent_activity->item_id; 
  1302.  
  1303. // Use comment ID as the secondary_item_id. 
  1304. $object->secondary_item_id = $blog_comment_id; 
  1305.  
  1306. // Get the format callback for this activity comment 
  1307. $format_callback = bp_activity_post_type_get_tracking_arg( $comment_action_id, 'format_callback' ); 
  1308.  
  1309. // now format the activity action using the 'new_{post_type}_comment' action callback 
  1310. if ( is_callable( $format_callback ) ) { 
  1311. $retval = call_user_func_array( $format_callback, array( '', $object ) ); 
  1312.  
  1313. return $retval; 
  1314. add_filter( 'bp_get_activity_action_pre_meta', 'bp_blogs_activity_comment_single_action', 10, 2 ); 
.