/bp-activity/bp-activity-actions.php

  1. <?php 
  2. /** 
  3. * Action functions are exactly the same as screen functions, however they do 
  4. * not have a template screen associated with them. Usually they will send the 
  5. * user back to the default screen after execution. 
  6. * 
  7. * @package BuddyPress 
  8. * @subpackage ActivityActions 
  9. * @since 1.5.0 
  10. */ 
  11.  
  12. // Exit if accessed directly. 
  13. defined( 'ABSPATH' ) || exit; 
  14.  
  15. /** 
  16. * Allow core components and dependent plugins to register activity actions. 
  17. * 
  18. * @since 1.2.0 
  19. * 
  20. */ 
  21. function bp_register_activity_actions() { 
  22.  
  23. /** 
  24. * Fires on bp_init to allow core components and dependent plugins to register activity actions. 
  25. * 
  26. * @since 1.2.0 
  27. */ 
  28. do_action( 'bp_register_activity_actions' ); 
  29. add_action( 'bp_init', 'bp_register_activity_actions', 8 ); 
  30.  
  31. /** 
  32. * Catch and route requests for single activity item permalinks. 
  33. * 
  34. * @since 1.2.0 
  35. * 
  36. * @return bool False on failure. 
  37. */ 
  38. function bp_activity_action_permalink_router() { 
  39.  
  40. // Not viewing activity. 
  41. if ( ! bp_is_activity_component() || ! bp_is_current_action( 'p' ) ) 
  42. return false; 
  43.  
  44. // No activity to display. 
  45. if ( ! bp_action_variable( 0 ) || ! is_numeric( bp_action_variable( 0 ) ) ) 
  46. return false; 
  47.  
  48. // Get the activity details. 
  49. $activity = bp_activity_get_specific( array( 'activity_ids' => bp_action_variable( 0 ), 'show_hidden' => true ) ); 
  50.  
  51. // 404 if activity does not exist 
  52. if ( empty( $activity['activities'][0] ) ) { 
  53. bp_do_404(); 
  54. return; 
  55. } else { 
  56. $activity = $activity['activities'][0]; 
  57.  
  58. // Do not redirect at default. 
  59. $redirect = false; 
  60.  
  61. // Redirect based on the type of activity. 
  62. if ( bp_is_active( 'groups' ) && $activity->component == buddypress()->groups->id ) { 
  63.  
  64. // Activity is a user update. 
  65. if ( ! empty( $activity->user_id ) ) { 
  66. $redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . bp_get_activity_slug() . '/' . $activity->id . '/'; 
  67.  
  68. // Activity is something else. 
  69. } else { 
  70.  
  71. // Set redirect to group activity stream. 
  72. if ( $group = groups_get_group( $activity->item_id ) ) { 
  73. $redirect = bp_get_group_permalink( $group ) . bp_get_activity_slug() . '/' . $activity->id . '/'; 
  74.  
  75. // Set redirect to users' activity stream. 
  76. } elseif ( ! empty( $activity->user_id ) ) { 
  77. $redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . bp_get_activity_slug() . '/' . $activity->id . '/'; 
  78.  
  79. // If set, add the original query string back onto the redirect URL. 
  80. if ( ! empty( $_SERVER['QUERY_STRING'] ) ) { 
  81. $query_frags = array(); 
  82. wp_parse_str( $_SERVER['QUERY_STRING'], $query_frags ); 
  83. $redirect = add_query_arg( urlencode_deep( $query_frags ), $redirect ); 
  84.  
  85. /** 
  86. * Filter the intended redirect url before the redirect occurs for the single activity item. 
  87. * 
  88. * @since 1.2.2 
  89. * 
  90. * @param array $value Array with url to redirect to and activity related to the redirect. 
  91. */ 
  92. if ( ! $redirect = apply_filters_ref_array( 'bp_activity_permalink_redirect_url', array( $redirect, &$activity ) ) ) { 
  93. bp_core_redirect( bp_get_root_domain() ); 
  94.  
  95. // Redirect to the actual activity permalink page. 
  96. bp_core_redirect( $redirect ); 
  97. add_action( 'bp_actions', 'bp_activity_action_permalink_router' ); 
  98.  
  99. /** 
  100. * Delete specific activity item and redirect to previous page. 
  101. * 
  102. * @since 1.1.0 
  103. * 
  104. * @param int $activity_id Activity id to be deleted. Defaults to 0. 
  105. * @return bool False on failure. 
  106. */ 
  107. function bp_activity_action_delete_activity( $activity_id = 0 ) { 
  108.  
  109. // Not viewing activity or action is not delete. 
  110. if ( !bp_is_activity_component() || !bp_is_current_action( 'delete' ) ) 
  111. return false; 
  112.  
  113. if ( empty( $activity_id ) && bp_action_variable( 0 ) ) 
  114. $activity_id = (int) bp_action_variable( 0 ); 
  115.  
  116. // Not viewing a specific activity item. 
  117. if ( empty( $activity_id ) ) 
  118. return false; 
  119.  
  120. // Check the nonce. 
  121. check_admin_referer( 'bp_activity_delete_link' ); 
  122.  
  123. // Load up the activity item. 
  124. $activity = new BP_Activity_Activity( $activity_id ); 
  125.  
  126. // Check access. 
  127. if ( ! bp_activity_user_can_delete( $activity ) ) 
  128. return false; 
  129.  
  130. /** 
  131. * Fires before the deletion so plugins can still fetch information about it. 
  132. * 
  133. * @since 1.5.0 
  134. * 
  135. * @param int $activity_id The activity ID. 
  136. * @param int $user_id The user associated with the activity. 
  137. */ 
  138. do_action( 'bp_activity_before_action_delete_activity', $activity_id, $activity->user_id ); 
  139.  
  140. // Delete the activity item and provide user feedback. 
  141. if ( bp_activity_delete( array( 'id' => $activity_id, 'user_id' => $activity->user_id ) ) ) 
  142. bp_core_add_message( __( 'Activity deleted successfully', 'buddypress' ) ); 
  143. else 
  144. bp_core_add_message( __( 'There was an error when deleting that activity', 'buddypress' ), 'error' ); 
  145.  
  146. /** 
  147. * Fires after the deletion so plugins can act afterwards based on the activity. 
  148. * 
  149. * @since 1.1.0 
  150. * 
  151. * @param int $activity_id The activity ID. 
  152. * @param int $user_id The user associated with the activity. 
  153. */ 
  154. do_action( 'bp_activity_action_delete_activity', $activity_id, $activity->user_id ); 
  155.  
  156. // Check for the redirect query arg, otherwise let WP handle things. 
  157. if ( !empty( $_GET['redirect_to'] ) ) 
  158. bp_core_redirect( esc_url( $_GET['redirect_to'] ) ); 
  159. else 
  160. bp_core_redirect( wp_get_referer() ); 
  161. add_action( 'bp_actions', 'bp_activity_action_delete_activity' ); 
  162.  
  163. /** 
  164. * Mark specific activity item as spam and redirect to previous page. 
  165. * 
  166. * @since 1.6.0 
  167. * 
  168. * @param int $activity_id Activity id to be deleted. Defaults to 0. 
  169. * @return bool False on failure. 
  170. */ 
  171. function bp_activity_action_spam_activity( $activity_id = 0 ) { 
  172. $bp = buddypress(); 
  173.  
  174. // Not viewing activity, or action is not spam, or Akismet isn't present. 
  175. if ( !bp_is_activity_component() || !bp_is_current_action( 'spam' ) || empty( $bp->activity->akismet ) ) 
  176. return false; 
  177.  
  178. if ( empty( $activity_id ) && bp_action_variable( 0 ) ) 
  179. $activity_id = (int) bp_action_variable( 0 ); 
  180.  
  181. // Not viewing a specific activity item. 
  182. if ( empty( $activity_id ) ) 
  183. return false; 
  184.  
  185. // Is the current user allowed to spam items? 
  186. if ( !bp_activity_user_can_mark_spam() ) 
  187. return false; 
  188.  
  189. // Load up the activity item. 
  190. $activity = new BP_Activity_Activity( $activity_id ); 
  191. if ( empty( $activity->id ) ) 
  192. return false; 
  193.  
  194. // Check nonce. 
  195. check_admin_referer( 'bp_activity_akismet_spam_' . $activity->id ); 
  196.  
  197. /** 
  198. * Fires before the marking activity as spam so plugins can modify things if they want to. 
  199. * 
  200. * @since 1.6.0 
  201. * 
  202. * @param int $activity_id Activity ID to be marked as spam. 
  203. * @param object $activity Activity object for the ID to be marked as spam. 
  204. */ 
  205. do_action( 'bp_activity_before_action_spam_activity', $activity->id, $activity ); 
  206.  
  207. // Mark as spam. 
  208. bp_activity_mark_as_spam( $activity ); 
  209. $activity->save(); 
  210.  
  211. // Tell the user the spamming has been successful. 
  212. bp_core_add_message( __( 'The activity item has been marked as spam and is no longer visible.', 'buddypress' ) ); 
  213.  
  214. /** 
  215. * Fires after the marking activity as spam so plugins can act afterwards based on the activity. 
  216. * 
  217. * @since 1.6.0 
  218. * 
  219. * @param int $activity_id Activity ID that was marked as spam. 
  220. * @param int $user_id User ID associated with activity. 
  221. */ 
  222. do_action( 'bp_activity_action_spam_activity', $activity_id, $activity->user_id ); 
  223.  
  224. // Check for the redirect query arg, otherwise let WP handle things. 
  225. if ( !empty( $_GET['redirect_to'] ) ) 
  226. bp_core_redirect( esc_url( $_GET['redirect_to'] ) ); 
  227. else 
  228. bp_core_redirect( wp_get_referer() ); 
  229. add_action( 'bp_actions', 'bp_activity_action_spam_activity' ); 
  230.  
  231. /** 
  232. * Post user/group activity update. 
  233. * 
  234. * @since 1.2.0 
  235. * 
  236. * @return bool False on failure. 
  237. */ 
  238. function bp_activity_action_post_update() { 
  239.  
  240. // Do not proceed if user is not logged in, not viewing activity, or not posting. 
  241. if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'post' ) ) 
  242. return false; 
  243.  
  244. // Check the nonce. 
  245. check_admin_referer( 'post_update', '_wpnonce_post_update' ); 
  246.  
  247. /** 
  248. * Filters the content provided in the activity input field. 
  249. * 
  250. * @since 1.2.0 
  251. * 
  252. * @param string $value Activity message being posted. 
  253. */ 
  254. $content = apply_filters( 'bp_activity_post_update_content', $_POST['whats-new'] ); 
  255.  
  256. if ( ! empty( $_POST['whats-new-post-object'] ) ) { 
  257.  
  258. /** 
  259. * Filters the item type that the activity update should be associated with. 
  260. * 
  261. * @since 1.2.0 
  262. * 
  263. * @param string $value Item type to associate with. 
  264. */ 
  265. $object = apply_filters( 'bp_activity_post_update_object', $_POST['whats-new-post-object'] ); 
  266.  
  267. if ( ! empty( $_POST['whats-new-post-in'] ) ) { 
  268.  
  269. /** 
  270. * Filters what component the activity is being to. 
  271. * 
  272. * @since 1.2.0 
  273. * 
  274. * @param string $value Chosen component to post activity to. 
  275. */ 
  276. $item_id = apply_filters( 'bp_activity_post_update_item_id', $_POST['whats-new-post-in'] ); 
  277.  
  278. // No activity content so provide feedback and redirect. 
  279. if ( empty( $content ) ) { 
  280. bp_core_add_message( __( 'Please enter some content to post.', 'buddypress' ), 'error' ); 
  281. bp_core_redirect( wp_get_referer() ); 
  282.  
  283. // No existing item_id. 
  284. if ( empty( $item_id ) ) { 
  285. $activity_id = bp_activity_post_update( array( 'content' => $content ) ); 
  286.  
  287. // Post to groups object. 
  288. } elseif ( 'groups' == $object && bp_is_active( 'groups' ) ) { 
  289. if ( (int) $item_id ) { 
  290. $activity_id = groups_post_update( array( 'content' => $content, 'group_id' => $item_id ) ); 
  291.  
  292. } else { 
  293.  
  294. /** 
  295. * Filters activity object for BuddyPress core and plugin authors before posting activity update. 
  296. * 
  297. * @since 1.2.0 
  298. * 
  299. * @param string $object Activity item being associated to. 
  300. * @param string $item_id Component ID being posted to. 
  301. * @param string $content Activity content being posted. 
  302. */ 
  303. $activity_id = apply_filters( 'bp_activity_custom_update', $object, $item_id, $content ); 
  304.  
  305. // Provide user feedback. 
  306. if ( !empty( $activity_id ) ) 
  307. bp_core_add_message( __( 'Update Posted!', 'buddypress' ) ); 
  308. else 
  309. bp_core_add_message( __( 'There was an error when posting your update. Please try again.', 'buddypress' ), 'error' ); 
  310.  
  311. // Redirect. 
  312. bp_core_redirect( wp_get_referer() ); 
  313. add_action( 'bp_actions', 'bp_activity_action_post_update' ); 
  314.  
  315. /** 
  316. * Post new activity comment. 
  317. * 
  318. * @since 1.2.0 
  319. * 
  320. * @return bool False on failure. 
  321. */ 
  322. function bp_activity_action_post_comment() { 
  323.  
  324. if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'reply' ) ) 
  325. return false; 
  326.  
  327. // Check the nonce. 
  328. check_admin_referer( 'new_activity_comment', '_wpnonce_new_activity_comment' ); 
  329.  
  330. /** 
  331. * Filters the activity ID a comment will be in reply to. 
  332. * 
  333. * @since 1.2.0 
  334. * 
  335. * @param string $value ID of the activity being replied to. 
  336. */ 
  337. $activity_id = apply_filters( 'bp_activity_post_comment_activity_id', $_POST['comment_form_id'] ); 
  338.  
  339. /** 
  340. * Filters the comment content for a comment reply. 
  341. * 
  342. * @since 1.2.0 
  343. * 
  344. * @param string $value Comment content being posted. 
  345. */ 
  346. $content = apply_filters( 'bp_activity_post_comment_content', $_POST['ac_input_' . $activity_id] ); 
  347.  
  348. if ( empty( $content ) ) { 
  349. bp_core_add_message( __( 'Please do not leave the comment area blank.', 'buddypress' ), 'error' ); 
  350. bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id ); 
  351.  
  352. $comment_id = bp_activity_new_comment( array( 
  353. 'content' => $content,  
  354. 'activity_id' => $activity_id,  
  355. 'parent_id' => false 
  356. )); 
  357.  
  358. if ( !empty( $comment_id ) ) 
  359. bp_core_add_message( __( 'Reply Posted!', 'buddypress' ) ); 
  360. else 
  361. bp_core_add_message( __( 'There was an error posting that reply. Please try again.', 'buddypress' ), 'error' ); 
  362.  
  363. bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id ); 
  364. add_action( 'bp_actions', 'bp_activity_action_post_comment' ); 
  365.  
  366. /** 
  367. * Mark activity as favorite. 
  368. * 
  369. * @since 1.2.0 
  370. * 
  371. * @return bool False on failure. 
  372. */ 
  373. function bp_activity_action_mark_favorite() { 
  374.  
  375. if ( !is_user_logged_in() || !bp_is_activity_component() || !bp_is_current_action( 'favorite' ) ) 
  376. return false; 
  377.  
  378. // Check the nonce. 
  379. check_admin_referer( 'mark_favorite' ); 
  380.  
  381. if ( bp_activity_add_user_favorite( bp_action_variable( 0 ) ) ) 
  382. bp_core_add_message( __( 'Activity marked as favorite.', 'buddypress' ) ); 
  383. else 
  384. bp_core_add_message( __( 'There was an error marking that activity as a favorite. Please try again.', 'buddypress' ), 'error' ); 
  385.  
  386. bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) ); 
  387. add_action( 'bp_actions', 'bp_activity_action_mark_favorite' ); 
  388.  
  389. /** 
  390. * Remove activity from favorites. 
  391. * 
  392. * @since 1.2.0 
  393. * 
  394. * @return bool False on failure. 
  395. */ 
  396. function bp_activity_action_remove_favorite() { 
  397.  
  398. if ( ! is_user_logged_in() || ! bp_is_activity_component() || ! bp_is_current_action( 'unfavorite' ) ) 
  399. return false; 
  400.  
  401. // Check the nonce. 
  402. check_admin_referer( 'unmark_favorite' ); 
  403.  
  404. if ( bp_activity_remove_user_favorite( bp_action_variable( 0 ) ) ) 
  405. bp_core_add_message( __( 'Activity removed as favorite.', 'buddypress' ) ); 
  406. else 
  407. bp_core_add_message( __( 'There was an error removing that activity as a favorite. Please try again.', 'buddypress' ), 'error' ); 
  408.  
  409. bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) ); 
  410. add_action( 'bp_actions', 'bp_activity_action_remove_favorite' ); 
  411.  
  412. /** 
  413. * Load the sitewide activity feed. 
  414. * 
  415. * @since 1.0.0 
  416. * 
  417. * @return bool False on failure. 
  418. */ 
  419. function bp_activity_action_sitewide_feed() { 
  420. $bp = buddypress(); 
  421.  
  422. if ( ! bp_is_activity_component() || ! bp_is_current_action( 'feed' ) || bp_is_user() || ! empty( $bp->groups->current_group ) ) 
  423. return false; 
  424.  
  425. // Setup the feed. 
  426. buddypress()->activity->feed = new BP_Activity_Feed( array( 
  427. 'id' => 'sitewide',  
  428.  
  429. /** translators: Sitewide activity RSS title - "[Site Name] | Site Wide Activity" */ 
  430. 'title' => sprintf( __( '%s | Site-Wide Activity', 'buddypress' ), bp_get_site_name() ),  
  431.  
  432. 'link' => bp_get_activity_directory_permalink(),  
  433. 'description' => __( 'Activity feed for the entire site.', 'buddypress' ),  
  434. 'activity_args' => 'display_comments=threaded' 
  435. ) ); 
  436. add_action( 'bp_actions', 'bp_activity_action_sitewide_feed' ); 
  437.  
  438. /** 
  439. * Load a user's personal activity feed. 
  440. * 
  441. * @since 1.0.0 
  442. * 
  443. * @return bool False on failure. 
  444. */ 
  445. function bp_activity_action_personal_feed() { 
  446. if ( ! bp_is_user_activity() || ! bp_is_current_action( 'feed' ) ) { 
  447. return false; 
  448.  
  449. // Setup the feed. 
  450. buddypress()->activity->feed = new BP_Activity_Feed( array( 
  451. 'id' => 'personal',  
  452.  
  453. /** translators: Personal activity RSS title - "[Site Name] | [User Display Name] | Activity" */ 
  454. 'title' => sprintf( __( '%1$s | %2$s | Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),  
  455.  
  456. 'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() ),  
  457. 'description' => sprintf( __( 'Activity feed for %s.', 'buddypress' ), bp_get_displayed_user_fullname() ),  
  458. 'activity_args' => 'user_id=' . bp_displayed_user_id() 
  459. ) ); 
  460. add_action( 'bp_actions', 'bp_activity_action_personal_feed' ); 
  461.  
  462. /** 
  463. * Load a user's friends' activity feed. 
  464. * 
  465. * @since 1.0.0 
  466. * 
  467. * @return bool False on failure. 
  468. */ 
  469. function bp_activity_action_friends_feed() { 
  470. if ( ! bp_is_active( 'friends' ) || ! bp_is_user_activity() || ! bp_is_current_action( bp_get_friends_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) { 
  471. return false; 
  472.  
  473. // Setup the feed. 
  474. buddypress()->activity->feed = new BP_Activity_Feed( array( 
  475. 'id' => 'friends',  
  476.  
  477. /** translators: Friends activity RSS title - "[Site Name] | [User Display Name] | Friends Activity" */ 
  478. 'title' => sprintf( __( '%1$s | %2$s | Friends Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),  
  479.  
  480. 'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() ),  
  481. 'description' => sprintf( __( "Activity feed for %s's friends.", 'buddypress' ), bp_get_displayed_user_fullname() ),  
  482. 'activity_args' => 'scope=friends' 
  483. ) ); 
  484. add_action( 'bp_actions', 'bp_activity_action_friends_feed' ); 
  485.  
  486. /** 
  487. * Load the activity feed for a user's groups. 
  488. * 
  489. * @since 1.2.0 
  490. * 
  491. * @return bool False on failure. 
  492. */ 
  493. function bp_activity_action_my_groups_feed() { 
  494. if ( ! bp_is_active( 'groups' ) || ! bp_is_user_activity() || ! bp_is_current_action( bp_get_groups_slug() ) || ! bp_is_action_variable( 'feed', 0 ) ) { 
  495. return false; 
  496.  
  497. // Get displayed user's group IDs. 
  498. $groups = groups_get_user_groups(); 
  499. $group_ids = implode( ', ', $groups['groups'] ); 
  500.  
  501. // Setup the feed. 
  502. buddypress()->activity->feed = new BP_Activity_Feed( array( 
  503. 'id' => 'mygroups',  
  504.  
  505. /** translators: Member groups activity RSS title - "[Site Name] | [User Display Name] | Groups Activity" */ 
  506. 'title' => sprintf( __( '%1$s | %2$s | Group Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),  
  507.  
  508. 'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() ),  
  509. 'description' => sprintf( __( "Public group activity feed of which %s is a member.", 'buddypress' ), bp_get_displayed_user_fullname() ),  
  510. 'activity_args' => array( 
  511. 'object' => buddypress()->groups->id,  
  512. 'primary_id' => $group_ids,  
  513. 'display_comments' => 'threaded' 
  514. ) ); 
  515. add_action( 'bp_actions', 'bp_activity_action_my_groups_feed' ); 
  516.  
  517. /** 
  518. * Load a user's @mentions feed. 
  519. * 
  520. * @since 1.2.0 
  521. * 
  522. * @return bool False on failure. 
  523. */ 
  524. function bp_activity_action_mentions_feed() { 
  525. if ( ! bp_activity_do_mentions() ) { 
  526. return false; 
  527.  
  528. if ( !bp_is_user_activity() || ! bp_is_current_action( 'mentions' ) || ! bp_is_action_variable( 'feed', 0 ) ) { 
  529. return false; 
  530.  
  531. // Setup the feed. 
  532. buddypress()->activity->feed = new BP_Activity_Feed( array( 
  533. 'id' => 'mentions',  
  534.  
  535. /** translators: User mentions activity RSS title - "[Site Name] | [User Display Name] | Mentions" */ 
  536. 'title' => sprintf( __( '%1$s | %2$s | Mentions', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),  
  537.  
  538. 'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/mentions/',  
  539. 'description' => sprintf( __( "Activity feed mentioning %s.", 'buddypress' ), bp_get_displayed_user_fullname() ),  
  540. 'activity_args' => array( 
  541. 'search_terms' => '@' . bp_core_get_username( bp_displayed_user_id() ) 
  542. ) ); 
  543. add_action( 'bp_actions', 'bp_activity_action_mentions_feed' ); 
  544.  
  545. /** 
  546. * Load a user's favorites feed. 
  547. * 
  548. * @since 1.2.0 
  549. * 
  550. * @return bool False on failure. 
  551. */ 
  552. function bp_activity_action_favorites_feed() { 
  553. if ( ! bp_is_user_activity() || ! bp_is_current_action( 'favorites' ) || ! bp_is_action_variable( 'feed', 0 ) ) { 
  554. return false; 
  555.  
  556. // Get displayed user's favorite activity IDs. 
  557. $favs = bp_activity_get_user_favorites( bp_displayed_user_id() ); 
  558. $fav_ids = implode( ', ', (array) $favs ); 
  559.  
  560. // Setup the feed. 
  561. buddypress()->activity->feed = new BP_Activity_Feed( array( 
  562. 'id' => 'favorites',  
  563.  
  564. /** translators: User activity favorites RSS title - "[Site Name] | [User Display Name] | Favorites" */ 
  565. 'title' => sprintf( __( '%1$s | %2$s | Favorites', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),  
  566.  
  567. 'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/',  
  568. 'description' => sprintf( __( "Activity feed of %s's favorites.", 'buddypress' ), bp_get_displayed_user_fullname() ),  
  569. 'activity_args' => 'include=' . $fav_ids 
  570. ) ); 
  571. add_action( 'bp_actions', 'bp_activity_action_favorites_feed' ); 
  572.  
  573. /** 
  574. * AJAX endpoint for Suggestions API lookups. 
  575. * 
  576. * @since 2.1.0 
  577. */ 
  578. function bp_ajax_get_suggestions() { 
  579. if ( ! bp_is_user_active() || empty( $_GET['term'] ) || empty( $_GET['type'] ) ) { 
  580. wp_send_json_error( 'missing_parameter' ); 
  581. exit; 
  582.  
  583. $args = array( 
  584. 'term' => sanitize_text_field( $_GET['term'] ),  
  585. 'type' => sanitize_text_field( $_GET['type'] ),  
  586. ); 
  587.  
  588. // Support per-Group suggestions. 
  589. if ( ! empty( $_GET['group-id'] ) ) { 
  590. $args['group_id'] = absint( $_GET['group-id'] ); 
  591.  
  592. $results = bp_core_get_suggestions( $args ); 
  593.  
  594. if ( is_wp_error( $results ) ) { 
  595. wp_send_json_error( $results->get_error_message() ); 
  596. exit; 
  597.  
  598. wp_send_json_success( $results ); 
  599. add_action( 'wp_ajax_bp_get_suggestions', 'bp_ajax_get_suggestions' ); 
  600.  
  601. /** 
  602. * Detect a change in post type status, and initiate an activity update if necessary. 
  603. * 
  604. * @since 2.2.0 
  605. * 
  606. * @todo Support untrashing better. 
  607. * 
  608. * @param string $new_status New status for the post. 
  609. * @param string $old_status Old status for the post. 
  610. * @param object $post Post data. 
  611. */ 
  612. function bp_activity_catch_transition_post_type_status( $new_status, $old_status, $post ) { 
  613. if ( ! post_type_supports( $post->post_type, 'buddypress-activity' ) ) { 
  614. return; 
  615.  
  616. // This is an edit. 
  617. if ( $new_status === $old_status ) { 
  618. // An edit of an existing post should update the existing activity item. 
  619. if ( $new_status == 'publish' ) { 
  620. $edit = bp_activity_post_type_update( $post ); 
  621.  
  622. // Post was never recorded into activity stream, so record it now! 
  623. if ( null === $edit ) { 
  624. bp_activity_post_type_publish( $post->ID, $post ); 
  625.  
  626. // Allow plugins to eventually deal with other post statuses. 
  627. } else { 
  628. /** 
  629. * Fires when editing the post and the new status is not 'publish'. 
  630. * 
  631. * This is a variable filter that is dependent on the post type 
  632. * being untrashed. 
  633. * 
  634. * @since 2.5.0 
  635. * 
  636. * @param WP_Post $post Post data. 
  637. * @param string $new_status New status for the post. 
  638. * @param string $old_status Old status for the post. 
  639. */ 
  640. do_action( 'bp_activity_post_type_edit_' . $post->post_type, $post, $new_status, $old_status ); 
  641.  
  642. return; 
  643.  
  644. // Publishing a previously unpublished post. 
  645. if ( 'publish' === $new_status ) { 
  646. // Untrashing the post type - nothing here yet. 
  647. if ( 'trash' == $old_status ) { 
  648.  
  649. /** 
  650. * Fires if untrashing post in a post type. 
  651. * 
  652. * This is a variable filter that is dependent on the post type 
  653. * being untrashed. 
  654. * 
  655. * @since 2.2.0 
  656. * 
  657. * @param WP_Post $post Post data. 
  658. */ 
  659. do_action( 'bp_activity_post_type_untrash_' . $post->post_type, $post ); 
  660. } else { 
  661. // Record the post. 
  662. bp_activity_post_type_publish( $post->ID, $post ); 
  663.  
  664. // Unpublishing a previously published post. 
  665. } elseif ( 'publish' === $old_status ) { 
  666. // Some form of pending status - only remove the activity entry. 
  667. bp_activity_post_type_unpublish( $post->ID, $post ); 
  668.  
  669. // For any other cases, allow plugins to eventually deal with it. 
  670. } else { 
  671. /** 
  672. * Fires when the old and the new post status are not 'publish'. 
  673. * 
  674. * This is a variable filter that is dependent on the post type 
  675. * being untrashed. 
  676. * 
  677. * @since 2.5.0 
  678. * 
  679. * @param WP_Post $post Post data. 
  680. * @param string $new_status New status for the post. 
  681. * @param string $old_status Old status for the post. 
  682. */ 
  683. do_action( 'bp_activity_post_type_transition_status_' . $post->post_type, $post, $new_status, $old_status ); 
  684. add_action( 'transition_post_status', 'bp_activity_catch_transition_post_type_status', 10, 3 ); 
  685.  
  686. /** 
  687. * When a post type comment status transition occurs, update the relevant activity's status. 
  688. * 
  689. * @since 2.5.0 
  690. * 
  691. * @param string $new_status New comment status. 
  692. * @param string $old_status Previous comment status. 
  693. * @param WP_Comment $comment Comment data. 
  694. */ 
  695. function bp_activity_transition_post_type_comment_status( $new_status, $old_status, $comment ) { 
  696. $post_type = get_post_type( $comment->comment_post_ID ); 
  697. if ( ! $post_type ) { 
  698. return; 
  699.  
  700. // Get the post type tracking args. 
  701. $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type ); 
  702.  
  703. // Bail if the activity type does not exist 
  704. if ( empty( $activity_post_object->comments_tracking->action_id ) ) { 
  705. return false; 
  706.  
  707. // Set the $activity_comment_object 
  708. } else { 
  709. $activity_comment_object = $activity_post_object->comments_tracking; 
  710.  
  711. // Init an empty activity ID 
  712. $activity_id = 0; 
  713.  
  714. /** 
  715. * Activity currently doesn't have any concept of a trash, or an unapproved/approved state. 
  716. * 
  717. * If a blog comment transitions to a "delete" or "hold" status, delete the activity item. 
  718. * If a blog comment transitions to trashed, or spammed, mark the activity as spam. 
  719. * If a blog comment transitions to approved (and the activity exists), mark the activity as ham. 
  720. * If a blog comment transitions to unapproved (and the activity exists), mark the activity as spam. 
  721. * Otherwise, record the comment into the activity stream. 
  722. */ 
  723.  
  724. // This clause handles delete/hold. 
  725. if ( in_array( $new_status, array( 'delete', 'hold' ) ) ) { 
  726. return bp_activity_post_type_remove_comment( $comment->comment_ID, $activity_post_object ); 
  727.  
  728. // These clauses handle trash, spam, and un-spams. 
  729. } elseif ( in_array( $new_status, array( 'trash', 'spam', 'unapproved' ) ) ) { 
  730. $action = 'spam_activity'; 
  731. } elseif ( 'approved' == $new_status ) { 
  732. $action = 'ham_activity'; 
  733.  
  734. // Get the activity 
  735. if ( bp_disable_blogforum_comments() ) { 
  736. $activity_id = bp_activity_get_activity_id( array( 
  737. 'component' => $activity_comment_object->component_id,  
  738. 'item_id' => get_current_blog_id(),  
  739. 'secondary_item_id' => $comment->comment_ID,  
  740. 'type' => $activity_comment_object->action_id,  
  741. ) ); 
  742. } else { 
  743. $activity_id = get_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', true ); 
  744.  
  745. /** 
  746. * Leave a chance to plugins to manage activity comments differently. 
  747. * 
  748. * @since 2.5.0 
  749. * 
  750. * @param bool $value True to override BuddyPress management. 
  751. * @param string $post_type The post type name. 
  752. * @param int $activity_id The post type activity (0 if not found). 
  753. * @param string $new_status The new status of the post type comment. 
  754. * @param string $old_status The old status of the post type comment. 
  755. * @param WP_Comment $comment Comment data. 
  756. */ 
  757. if ( true === apply_filters( 'bp_activity_pre_transition_post_type_comment_status', false, $post_type, $activity_id, $new_status, $old_status, $comment ) ) { 
  758. return false; 
  759.  
  760. // Check activity item exists 
  761. if ( empty( $activity_id ) ) { 
  762. // If no activity exists, but the comment has been approved, record it into the activity table. 
  763. if ( 'approved' == $new_status ) { 
  764. return bp_activity_post_type_comment( $comment->comment_ID, true, $activity_post_object ); 
  765.  
  766. return; 
  767.  
  768. // Create an activity object 
  769. $activity = new BP_Activity_Activity( $activity_id ); 
  770. if ( empty( $activity->component ) ) { 
  771. return; 
  772.  
  773. // Spam/ham the activity if it's not already in that state 
  774. if ( 'spam_activity' === $action && ! $activity->is_spam ) { 
  775. bp_activity_mark_as_spam( $activity ); 
  776. } elseif ( 'ham_activity' == $action) { 
  777. bp_activity_mark_as_ham( $activity ); 
  778.  
  779. // Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated 
  780. $post_type_comment_action = $activity_comment_object->action_id; 
  781. $comment_akismet_history = function ( $activity_types ) use ( $post_type_comment_action ) { 
  782. $activity_types[] = $post_type_comment_action; 
  783.  
  784. return $activity_types; 
  785. }; 
  786. add_filter( 'bp_akismet_get_activity_types', $comment_akismet_history ); 
  787.  
  788. // Make sure the activity change won't edit the comment if sync is on 
  789. remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 ); 
  790.  
  791. // Save the updated activity 
  792. $activity->save(); 
  793.  
  794. // Restore the action 
  795. add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 ); 
  796.  
  797. // Remove the "new_blog_comment" activity type whitelist so we don't break anything 
  798. remove_filter( 'bp_akismet_get_activity_types', $comment_akismet_history ); 
  799. add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 ); 
.