BuddyPress - Version 2.2.5

Version Description

See: https://codex.buddypress.org/releases/version-2-2-5/

Download this release

Release Info

Developer DJPaul
Plugin Icon 128x128 BuddyPress
Version 2.2.5
Comparing to
See all releases

Code changes from version 2.1.3 to 2.2.5

Files changed (139) hide show
  1. bp-activity/admin/js/admin.js +4 -2
  2. bp-activity/admin/js/admin.min.js +2 -2
  3. bp-activity/bp-activity-actions.php +173 -17
  4. bp-activity/bp-activity-admin.php +147 -21
  5. bp-activity/bp-activity-akismet.php +57 -4
  6. bp-activity/bp-activity-cache.php +2 -1
  7. bp-activity/bp-activity-classes.php +769 -140
  8. bp-activity/bp-activity-cssjs.php +9 -2
  9. bp-activity/bp-activity-filters.php +248 -19
  10. bp-activity/bp-activity-functions.php +937 -48
  11. bp-activity/bp-activity-loader.php +20 -1
  12. bp-activity/bp-activity-notifications.php +170 -12
  13. bp-activity/bp-activity-screens.php +161 -29
  14. bp-activity/bp-activity-template.php +1014 -374
  15. bp-activity/css/mentions-rtl.css +17 -4
  16. bp-activity/css/mentions-rtl.min.css +1 -1
  17. bp-activity/css/mentions.css +17 -4
  18. bp-activity/css/mentions.min.css +1 -1
  19. bp-activity/js/mentions.js +70 -13
  20. bp-activity/js/mentions.min.js +2 -2
  21. bp-blogs/bp-blogs-actions.php +1 -1
  22. bp-blogs/bp-blogs-activity.php +120 -26
  23. bp-blogs/bp-blogs-cache.php +8 -16
  24. bp-blogs/bp-blogs-classes.php +53 -8
  25. bp-blogs/bp-blogs-filters.php +71 -3
  26. bp-blogs/bp-blogs-functions.php +174 -182
  27. bp-blogs/bp-blogs-loader.php +65 -2
  28. bp-blogs/bp-blogs-screens.php +43 -10
  29. bp-blogs/bp-blogs-template.php +344 -15
  30. bp-blogs/bp-blogs-widgets.php +10 -1
  31. bp-core/admin/bp-core-actions.php +1 -1
  32. bp-core/admin/bp-core-components.php +6 -6
  33. bp-core/admin/bp-core-functions.php +75 -56
  34. bp-core/admin/bp-core-schema.php +19 -10
  35. bp-core/admin/bp-core-settings.php +2 -2
  36. bp-core/admin/bp-core-slugs.php +2 -8
  37. bp-core/admin/bp-core-tools.php +1 -1
  38. bp-core/admin/css/common-rtl.css +20 -0
  39. bp-core/admin/css/common-rtl.min.css +1 -1
  40. bp-core/admin/css/common.css +20 -0
  41. bp-core/admin/css/common.min.css +1 -1
  42. bp-core/admin/images/member-types.png +0 -0
  43. bp-core/admin/images/mentions.gif +0 -0
  44. bp-core/bp-core-actions.php +3 -1
  45. bp-core/bp-core-admin.php +212 -166
  46. bp-core/bp-core-adminbar.php +2 -2
  47. bp-core/bp-core-avatars.php +165 -113
  48. bp-core/bp-core-buddybar.php +27 -21
  49. bp-core/bp-core-cache.php +2 -12
  50. bp-core/bp-core-caps.php +3 -3
  51. bp-core/bp-core-catchuri.php +14 -36
  52. bp-core/bp-core-classes.php +332 -56
  53. bp-core/bp-core-component.php +16 -2
  54. bp-core/bp-core-cssjs.php +3 -3
  55. bp-core/bp-core-dependency.php +37 -9
  56. bp-core/bp-core-filters.php +268 -46
  57. bp-core/bp-core-functions.php +138 -39
  58. bp-core/bp-core-loader.php +17 -2
  59. bp-core/bp-core-moderation.php +82 -62
  60. bp-core/bp-core-options.php +2 -2
  61. bp-core/bp-core-taxonomy.php +81 -0
  62. bp-core/bp-core-template-loader.php +24 -15
  63. bp-core/bp-core-template.php +98 -26
  64. bp-core/bp-core-theme-compatibility.php +20 -16
  65. bp-core/bp-core-update.php +80 -1
  66. bp-core/bp-core-widgets.php +3 -441
  67. bp-core/bp-core-wpabstraction.php +4 -4
  68. bp-core/deprecated/1.5.php +2 -2
  69. bp-core/deprecated/1.6.php +1 -1
  70. bp-core/deprecated/1.7.php +1 -1
  71. bp-core/deprecated/1.9.php +2 -2
  72. bp-core/deprecated/2.0.php +1 -1
  73. bp-core/deprecated/2.1.php +2 -2
  74. bp-core/deprecated/2.2.php +116 -0
  75. bp-core/deprecated/js/autocomplete/jquery.autocomplete.js +25 -2
  76. bp-core/deprecated/js/autocomplete/jquery.autocomplete.min.js +2 -2
  77. bp-core/deprecated/js/autocomplete/jquery.autocompletefb.min.js +1 -1
  78. bp-core/deprecated/js/autocomplete/jquery.bgiframe.min.js +1 -1
  79. bp-core/deprecated/js/autocomplete/jquery.dimensions.min.js +1 -1
  80. bp-core/deprecated/js/jquery-scroll-to.min.js +1 -1
  81. bp-core/js/confirm.min.js +1 -1
  82. bp-core/js/jquery-cookie.min.js +1 -1
  83. bp-core/js/jquery-query.min.js +1 -1
  84. bp-core/js/jquery.atwho.js +117 -66
  85. bp-core/js/jquery.atwho.min.js +2 -2
  86. bp-core/js/jquery.caret.js +36 -23
  87. bp-core/js/jquery.caret.min.js +2 -2
  88. bp-core/js/widget-members.js +2 -2
  89. bp-core/js/widget-members.min.js +2 -2
  90. bp-forums/bp-forums-actions.php +1 -1
  91. bp-forums/bp-forums-bbpress-sa.php +27 -5
  92. bp-forums/bp-forums-bbpress.php +1 -1
  93. bp-forums/bp-forums-filters.php +15 -1
  94. bp-forums/bp-forums-functions.php +116 -5
  95. bp-forums/bp-forums-loader.php +1 -1
  96. bp-forums/bp-forums-screens.php +84 -4
  97. bp-forums/bp-forums-template.php +582 -21
  98. bp-forums/deprecated/1.6.php +2 -2
  99. bp-forums/deprecated/1.7.php +1 -1
  100. bp-friends/bp-friends-actions.php +3 -3
  101. bp-friends/bp-friends-activity.php +152 -16
  102. bp-friends/bp-friends-cache.php +1 -1
  103. bp-friends/bp-friends-classes.php +16 -2
  104. bp-friends/bp-friends-functions.php +168 -20
  105. bp-friends/bp-friends-loader.php +16 -1
  106. bp-friends/bp-friends-notifications.php +123 -11
  107. bp-friends/bp-friends-screens.php +33 -2
  108. bp-friends/bp-friends-template.php +105 -7
  109. bp-friends/bp-friends-widgets.php +8 -1
  110. bp-friends/js/widget-friends.js +2 -2
  111. bp-friends/js/widget-friends.min.js +2 -2
  112. bp-groups/admin/js/admin.min.js +1 -1
  113. bp-groups/bp-groups-actions.php +9 -6
  114. bp-groups/bp-groups-activity.php +189 -1
  115. bp-groups/bp-groups-admin.php +51 -17
  116. bp-groups/bp-groups-adminbar.php +34 -59
  117. bp-groups/bp-groups-cache.php +1 -1
  118. bp-groups/bp-groups-classes.php +75 -30
  119. bp-groups/bp-groups-filters.php +23 -1
  120. bp-groups/bp-groups-forums.php +1 -1
  121. bp-groups/bp-groups-functions.php +39 -12
  122. bp-groups/bp-groups-loader.php +72 -3
  123. bp-groups/bp-groups-notifications.php +394 -40
  124. bp-groups/bp-groups-screens.php +31 -34
  125. bp-groups/bp-groups-template.php +562 -145
  126. bp-groups/bp-groups-widgets.php +4 -4
  127. bp-groups/js/widget-groups.js +2 -2
  128. bp-groups/js/widget-groups.min.js +2 -2
  129. bp-loader.php +32 -19
  130. bp-members/admin/bp-members-classes.php +49 -6
  131. bp-members/admin/js/admin.min.js +1 -1
  132. bp-members/bp-members-actions.php +4 -4
  133. bp-members/bp-members-activity.php +96 -0
  134. bp-members/bp-members-admin.php +205 -41
  135. bp-members/bp-members-adminbar.php +1 -1
  136. bp-members/bp-members-cache.php +59 -0
  137. bp-members/bp-members-classes.php +133 -7
  138. bp-members/bp-members-filters.php +10 -1
  139. bp-members/bp-members-functions.php +199 -35
bp-activity/admin/js/admin.js CHANGED
@@ -165,9 +165,11 @@ $(document).ready( function () {
165
  $( '#bp_activity_action h3, #bp_activity_content h3' ).unbind( 'click' );
166
 
167
  // redo the post box toggles to reset the one made by comment.js in favor
168
- // of activity administration page id so that metaboxes are still collapsible
169
  // in single Activity Administration screen.
170
- postboxes.add_postbox_toggles( bp_activity_admin_vars.page );
 
 
171
  });
172
 
173
  })(jQuery);
165
  $( '#bp_activity_action h3, #bp_activity_content h3' ).unbind( 'click' );
166
 
167
  // redo the post box toggles to reset the one made by comment.js in favor
168
+ // of activity administration page id so that metaboxes are still collapsible
169
  // in single Activity Administration screen.
170
+ if ( typeof postboxes !== 'undefined' ) {
171
+ postboxes.add_postbox_toggles( bp_activity_admin_vars.page );
172
+ }
173
  });
174
 
175
  })(jQuery);
bp-activity/admin/js/admin.min.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! buddypress - v2.1.2 - 2015-11-11 4:43:05 AM UTC - https://wordpress.org/plugins/buddypress/ */
2
- !function(a){var b={init:function(){a(document).on("click",".row-actions a.reply",b.open),a(document).on("click","#bp-activities-container a.cancel",b.close),a(document).on("click","#bp-activities-container a.save",b.send),a(document).on("keyup","#bp-activities:visible",function(a){27===a.which&&b.close()})},open:function(){var b=a("#bp-activities-container").hide();return a(this).parents("tr").after(b),b.fadeIn("300"),a("#bp-activities").focus(),!1},close:function(){return a("#bp-activities-container").fadeOut("200",function(){a("#bp-activities").val("").blur(),a("#bp-replysubmit .error").html("").hide(),a("#bp-replysubmit .waiting").hide()}),!1},send:function(){a("#bp-replysubmit .error").hide(),a("#bp-replysubmit .waiting").show();var c={};return c["_ajax_nonce-bp-activity-admin-reply"]=a('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val(),c.action="bp-activity-admin-reply",c.content=a("#bp-activities").val(),c.parent_id=a("#bp-activities-container").prev().data("parent_id"),c.root_id=a("#bp-activities-container").prev().data("root_id"),a.ajax({data:c,type:"POST",url:ajaxurl,error:function(a){b.error(a)},success:function(a){b.show(a)}}),!1},error:function(b){var c=b.statusText;a("#bp-replysubmit .waiting").hide(),b.responseText&&(c=b.responseText.replace(/<.[^<>]*?>/g,"")),c&&a("#bp-replysubmit .error").html(c).show()},show:function(c){var d,e,f;return"string"==typeof c?(b.error({responseText:c}),!1):(f=wpAjax.parseAjaxResponse(c),f.errors?(b.error({responseText:wpAjax.broken}),!1):(f=f.responses[0],void a("#bp-activities-container").fadeOut("200",function(){a("#bp-activities").val("").blur(),a("#bp-replysubmit .error").html("").hide(),a("#bp-replysubmit .waiting").hide(),a("#bp-activities-container").before(f.data),e=a("#activity-"+f.id),d=e.closest(".widefat").css("backgroundColor"),e.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:d},300)})))}};a(document).ready(function(){b.init(),a("#bp_activity_action h3, #bp_activity_content h3").unbind("click"),postboxes.add_postbox_toggles(bp_activity_admin_vars.page)})}(jQuery);
1
+ /*! buddypress - v2.2.4 - 2015-11-11 5:04:26 AM UTC - https://wordpress.org/plugins/buddypress/ */
2
+ !function(a){var b={init:function(){a(document).on("click",".row-actions a.reply",b.open),a(document).on("click","#bp-activities-container a.cancel",b.close),a(document).on("click","#bp-activities-container a.save",b.send),a(document).on("keyup","#bp-activities:visible",function(a){27===a.which&&b.close()})},open:function(){var b=a("#bp-activities-container").hide();return a(this).parents("tr").after(b),b.fadeIn("300"),a("#bp-activities").focus(),!1},close:function(){return a("#bp-activities-container").fadeOut("200",function(){a("#bp-activities").val("").blur(),a("#bp-replysubmit .error").html("").hide(),a("#bp-replysubmit .waiting").hide()}),!1},send:function(){a("#bp-replysubmit .error").hide(),a("#bp-replysubmit .waiting").show();var c={};return c["_ajax_nonce-bp-activity-admin-reply"]=a('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val(),c.action="bp-activity-admin-reply",c.content=a("#bp-activities").val(),c.parent_id=a("#bp-activities-container").prev().data("parent_id"),c.root_id=a("#bp-activities-container").prev().data("root_id"),a.ajax({data:c,type:"POST",url:ajaxurl,error:function(a){b.error(a)},success:function(a){b.show(a)}}),!1},error:function(b){var c=b.statusText;a("#bp-replysubmit .waiting").hide(),b.responseText&&(c=b.responseText.replace(/<.[^<>]*?>/g,"")),c&&a("#bp-replysubmit .error").html(c).show()},show:function(c){var d,e,f;return"string"==typeof c?(b.error({responseText:c}),!1):(f=wpAjax.parseAjaxResponse(c),f.errors?(b.error({responseText:wpAjax.broken}),!1):(f=f.responses[0],void a("#bp-activities-container").fadeOut("200",function(){a("#bp-activities").val("").blur(),a("#bp-replysubmit .error").html("").hide(),a("#bp-replysubmit .waiting").hide(),a("#bp-activities-container").before(f.data),e=a("#activity-"+f.id),d=e.closest(".widefat").css("backgroundColor"),e.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:d},300)})))}};a(document).ready(function(){b.init(),a("#bp_activity_action h3, #bp_activity_content h3").unbind("click"),"undefined"!=typeof postboxes&&postboxes.add_postbox_toggles(bp_activity_admin_vars.page)})}(jQuery);
bp-activity/bp-activity-actions.php CHANGED
@@ -10,16 +10,22 @@
10
  */
11
 
12
  // Exit if accessed directly
13
- if ( !defined( 'ABSPATH' ) ) exit;
14
 
15
  /**
16
  * Allow core components and dependent plugins to register activity actions.
17
  *
18
- * @since BuddyPress (1.2)
19
  *
20
  * @uses do_action() To call 'bp_register_activity_actions' hook.
21
  */
22
  function bp_register_activity_actions() {
 
 
 
 
 
 
23
  do_action( 'bp_register_activity_actions' );
24
  }
25
  add_action( 'bp_init', 'bp_register_activity_actions', 8 );
@@ -85,7 +91,7 @@ function bp_activity_action_permalink_router() {
85
  }
86
 
87
  // Set redirect to users' activity stream
88
- } else if ( ! empty( $activity->user_id ) ) {
89
  $redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . bp_get_activity_slug() . '/' . $activity->id . '/';
90
  }
91
 
@@ -96,7 +102,13 @@ function bp_activity_action_permalink_router() {
96
  $redirect = add_query_arg( urlencode_deep( $query_frags ), $redirect );
97
  }
98
 
99
- // Allow redirect to be filtered
 
 
 
 
 
 
100
  if ( ! $redirect = apply_filters_ref_array( 'bp_activity_permalink_redirect_url', array( $redirect, &$activity ) ) ) {
101
  bp_core_redirect( bp_get_root_domain() );
102
  }
@@ -149,7 +161,14 @@ function bp_activity_action_delete_activity( $activity_id = 0 ) {
149
  if ( ! bp_activity_user_can_delete( $activity ) )
150
  return false;
151
 
152
- // Call the action before the delete so plugins can still fetch information about it
 
 
 
 
 
 
 
153
  do_action( 'bp_activity_before_action_delete_activity', $activity_id, $activity->user_id );
154
 
155
  // Delete the activity item and provide user feedback
@@ -158,6 +177,14 @@ function bp_activity_action_delete_activity( $activity_id = 0 ) {
158
  else
159
  bp_core_add_message( __( 'There was an error when deleting that activity', 'buddypress' ), 'error' );
160
 
 
 
 
 
 
 
 
 
161
  do_action( 'bp_activity_action_delete_activity', $activity_id, $activity->user_id );
162
 
163
  // Check for the redirect query arg, otherwise let WP handle things
@@ -203,16 +230,31 @@ function bp_activity_action_spam_activity( $activity_id = 0 ) {
203
  // Check nonce
204
  check_admin_referer( 'bp_activity_akismet_spam_' . $activity->id );
205
 
206
- // Call an action before the spamming so plugins can modify things if they want to
 
 
 
 
 
 
 
207
  do_action( 'bp_activity_before_action_spam_activity', $activity->id, $activity );
208
 
209
  // Mark as spam
210
  bp_activity_mark_as_spam( $activity );
211
  $activity->save();
212
 
213
- // Tell the user the spamming has been succesful
214
  bp_core_add_message( __( 'The activity item has been marked as spam and is no longer visible.', 'buddypress' ) );
215
 
 
 
 
 
 
 
 
 
216
  do_action( 'bp_activity_action_spam_activity', $activity_id, $activity->user_id );
217
 
218
  // Check for the redirect query arg, otherwise let WP handle things
@@ -253,14 +295,36 @@ function bp_activity_action_post_update() {
253
  // Check the nonce
254
  check_admin_referer( 'post_update', '_wpnonce_post_update' );
255
 
256
- // Get activity info
 
 
 
 
 
 
257
  $content = apply_filters( 'bp_activity_post_update_content', $_POST['whats-new'] );
258
 
259
  if ( ! empty( $_POST['whats-new-post-object'] ) ) {
 
 
 
 
 
 
 
 
260
  $object = apply_filters( 'bp_activity_post_update_object', $_POST['whats-new-post-object'] );
261
  }
262
 
263
  if ( ! empty( $_POST['whats-new-post-in'] ) ) {
 
 
 
 
 
 
 
 
264
  $item_id = apply_filters( 'bp_activity_post_update_item_id', $_POST['whats-new-post-in'] );
265
  }
266
 
@@ -275,13 +339,22 @@ function bp_activity_action_post_update() {
275
  $activity_id = bp_activity_post_update( array( 'content' => $content ) );
276
 
277
  // Post to groups object
278
- } else if ( 'groups' == $object && bp_is_active( 'groups' ) ) {
279
  if ( (int) $item_id ) {
280
  $activity_id = groups_post_update( array( 'content' => $content, 'group_id' => $item_id ) );
281
  }
282
 
283
- // Special circumstance so let filters handle it
284
  } else {
 
 
 
 
 
 
 
 
 
 
285
  $activity_id = apply_filters( 'bp_activity_custom_update', $object, $item_id, $content );
286
  }
287
 
@@ -289,7 +362,7 @@ function bp_activity_action_post_update() {
289
  if ( !empty( $activity_id ) )
290
  bp_core_add_message( __( 'Update Posted!', 'buddypress' ) );
291
  else
292
- bp_core_add_message( __( 'There was an error when posting your update, please try again.', 'buddypress' ), 'error' );
293
 
294
  // Redirect
295
  bp_core_redirect( wp_get_referer() );
@@ -322,7 +395,22 @@ function bp_activity_action_post_comment() {
322
  // Check the nonce
323
  check_admin_referer( 'new_activity_comment', '_wpnonce_new_activity_comment' );
324
 
 
 
 
 
 
 
 
325
  $activity_id = apply_filters( 'bp_activity_post_comment_activity_id', $_POST['comment_form_id'] );
 
 
 
 
 
 
 
 
326
  $content = apply_filters( 'bp_activity_post_comment_content', $_POST['ac_input_' . $activity_id] );
327
 
328
  if ( empty( $content ) ) {
@@ -339,7 +427,7 @@ function bp_activity_action_post_comment() {
339
  if ( !empty( $comment_id ) )
340
  bp_core_add_message( __( 'Reply Posted!', 'buddypress' ) );
341
  else
342
- bp_core_add_message( __( 'There was an error posting that reply, please try again.', 'buddypress' ), 'error' );
343
 
344
  bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id );
345
  }
@@ -373,7 +461,7 @@ function bp_activity_action_mark_favorite() {
373
  if ( bp_activity_add_user_favorite( bp_action_variable( 0 ) ) )
374
  bp_core_add_message( __( 'Activity marked as favorite.', 'buddypress' ) );
375
  else
376
- bp_core_add_message( __( 'There was an error marking that activity as a favorite, please try again.', 'buddypress' ), 'error' );
377
 
378
  bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) );
379
  }
@@ -407,7 +495,7 @@ function bp_activity_action_remove_favorite() {
407
  if ( bp_activity_remove_user_favorite( bp_action_variable( 0 ) ) )
408
  bp_core_add_message( __( 'Activity removed as favorite.', 'buddypress' ) );
409
  else
410
- bp_core_add_message( __( 'There was an error removing that activity as a favorite, please try again.', 'buddypress' ), 'error' );
411
 
412
  bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) );
413
  }
@@ -640,7 +728,13 @@ function bp_activity_setup_akismet() {
640
  if ( ! bp_get_option( 'wordpress_api_key' ) && ! defined( 'WPCOM_API_KEY' ) )
641
  return;
642
 
643
- // Bail if BuddyPress Activity Akismet support has been disabled by another plugin
 
 
 
 
 
 
644
  if ( ! apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) )
645
  return;
646
 
@@ -659,10 +753,17 @@ function bp_ajax_get_suggestions() {
659
  exit;
660
  }
661
 
662
- $results = bp_core_get_suggestions( array(
663
  'term' => sanitize_text_field( $_GET['term'] ),
664
  'type' => sanitize_text_field( $_GET['type'] ),
665
- ) );
 
 
 
 
 
 
 
666
 
667
  if ( is_wp_error( $results ) ) {
668
  wp_send_json_error( $results->get_error_message() );
@@ -672,3 +773,58 @@ function bp_ajax_get_suggestions() {
672
  wp_send_json_success( $results );
673
  }
674
  add_action( 'wp_ajax_bp_get_suggestions', 'bp_ajax_get_suggestions' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 BuddyPress (1.2.0)
19
  *
20
  * @uses do_action() To call 'bp_register_activity_actions' hook.
21
  */
22
  function bp_register_activity_actions() {
23
+
24
+ /**
25
+ * Fires on bp_init to allow core components and dependent plugins to register activity actions.
26
+ *
27
+ * @since BuddyPress (1.2.0)
28
+ */
29
  do_action( 'bp_register_activity_actions' );
30
  }
31
  add_action( 'bp_init', 'bp_register_activity_actions', 8 );
91
  }
92
 
93
  // Set redirect to users' activity stream
94
+ } elseif ( ! empty( $activity->user_id ) ) {
95
  $redirect = bp_core_get_user_domain( $activity->user_id, $activity->user_nicename, $activity->user_login ) . bp_get_activity_slug() . '/' . $activity->id . '/';
96
  }
97
 
102
  $redirect = add_query_arg( urlencode_deep( $query_frags ), $redirect );
103
  }
104
 
105
+ /**
106
+ * Filter the intended redirect url before the redirect occurs for the single activity item.
107
+ *
108
+ * @since BuddyPress (1.2.2)
109
+ *
110
+ * @param array Array with url to redirect to and activity related to the redirect.
111
+ */
112
  if ( ! $redirect = apply_filters_ref_array( 'bp_activity_permalink_redirect_url', array( $redirect, &$activity ) ) ) {
113
  bp_core_redirect( bp_get_root_domain() );
114
  }
161
  if ( ! bp_activity_user_can_delete( $activity ) )
162
  return false;
163
 
164
+ /**
165
+ * Fires before the deletion so plugins can still fetch information about it.
166
+ *
167
+ * @since BuddyPress (1.5.0)
168
+ *
169
+ * @param int $activity_id The activity ID.
170
+ * @param int $user_id The user associated with the activity.
171
+ */
172
  do_action( 'bp_activity_before_action_delete_activity', $activity_id, $activity->user_id );
173
 
174
  // Delete the activity item and provide user feedback
177
  else
178
  bp_core_add_message( __( 'There was an error when deleting that activity', 'buddypress' ), 'error' );
179
 
180
+ /**
181
+ * Fires after the deletion so plugins can act afterwards based on the activity.
182
+ *
183
+ * @since BuddyPress (1.1.0)
184
+ *
185
+ * @param int $activity_id The activity ID.
186
+ * @param int $user_id The user associated with the activity.
187
+ */
188
  do_action( 'bp_activity_action_delete_activity', $activity_id, $activity->user_id );
189
 
190
  // Check for the redirect query arg, otherwise let WP handle things
230
  // Check nonce
231
  check_admin_referer( 'bp_activity_akismet_spam_' . $activity->id );
232
 
233
+ /**
234
+ * Fires before the marking activity as spam so plugins can modify things if they want to.
235
+ *
236
+ * @since BuddyPress (1.6.0)
237
+ *
238
+ * @param int $activity_id Activity ID to be marked as spam.
239
+ * @param object $activity Activity object for the ID to be marked as spam.
240
+ */
241
  do_action( 'bp_activity_before_action_spam_activity', $activity->id, $activity );
242
 
243
  // Mark as spam
244
  bp_activity_mark_as_spam( $activity );
245
  $activity->save();
246
 
247
+ // Tell the user the spamming has been successful
248
  bp_core_add_message( __( 'The activity item has been marked as spam and is no longer visible.', 'buddypress' ) );
249
 
250
+ /**
251
+ * Fires after the marking activity as spam so plugins can act afterwards based on the activity.
252
+ *
253
+ * @since BuddyPress (1.6.0)
254
+ *
255
+ * @param int $activity_id Activity ID that was marked as spam.
256
+ * @param int $user_id User ID associated with activity.
257
+ */
258
  do_action( 'bp_activity_action_spam_activity', $activity_id, $activity->user_id );
259
 
260
  // Check for the redirect query arg, otherwise let WP handle things
295
  // Check the nonce
296
  check_admin_referer( 'post_update', '_wpnonce_post_update' );
297
 
298
+ /**
299
+ * Filters the content provided in the activity input field.
300
+ *
301
+ * @since BuddyPress (1.2.0)
302
+ *
303
+ * @param string $whats-new Activity message being posted.
304
+ */
305
  $content = apply_filters( 'bp_activity_post_update_content', $_POST['whats-new'] );
306
 
307
  if ( ! empty( $_POST['whats-new-post-object'] ) ) {
308
+
309
+ /**
310
+ * Filters the item type that the activity update should be associated with.
311
+ *
312
+ * @since BuddyPress (1.2.0)
313
+ *
314
+ * @param string $whats-new-post-object Item type to associate with.
315
+ */
316
  $object = apply_filters( 'bp_activity_post_update_object', $_POST['whats-new-post-object'] );
317
  }
318
 
319
  if ( ! empty( $_POST['whats-new-post-in'] ) ) {
320
+
321
+ /**
322
+ * Filters what component the activity is being to.
323
+ *
324
+ * @since BuddyPress (1.2.0)
325
+ *
326
+ * @param string $whats-new-post-in Chosen component to post activity to.
327
+ */
328
  $item_id = apply_filters( 'bp_activity_post_update_item_id', $_POST['whats-new-post-in'] );
329
  }
330
 
339
  $activity_id = bp_activity_post_update( array( 'content' => $content ) );
340
 
341
  // Post to groups object
342
+ } elseif ( 'groups' == $object && bp_is_active( 'groups' ) ) {
343
  if ( (int) $item_id ) {
344
  $activity_id = groups_post_update( array( 'content' => $content, 'group_id' => $item_id ) );
345
  }
346
 
 
347
  } else {
348
+
349
+ /**
350
+ * Filters activity object for BuddyPress core and plugin authors before posting activity update.
351
+ *
352
+ * @since BuddyPress (1.2.0)
353
+ *
354
+ * @param string $object Activity item being associated to.
355
+ * @param string $item_id Component ID being posted to.
356
+ * @param string $content Activity content being posted.
357
+ */
358
  $activity_id = apply_filters( 'bp_activity_custom_update', $object, $item_id, $content );
359
  }
360
 
362
  if ( !empty( $activity_id ) )
363
  bp_core_add_message( __( 'Update Posted!', 'buddypress' ) );
364
  else
365
+ bp_core_add_message( __( 'There was an error when posting your update. Please try again.', 'buddypress' ), 'error' );
366
 
367
  // Redirect
368
  bp_core_redirect( wp_get_referer() );
395
  // Check the nonce
396
  check_admin_referer( 'new_activity_comment', '_wpnonce_new_activity_comment' );
397
 
398
+ /**
399
+ * Filters the activity ID a comment will be in reply to.
400
+ *
401
+ * @since BuddyPress (1.2.0)
402
+ *
403
+ * @param string $comment_form_id ID of the activity being replied to.
404
+ */
405
  $activity_id = apply_filters( 'bp_activity_post_comment_activity_id', $_POST['comment_form_id'] );
406
+
407
+ /**
408
+ * Filters the comment content for a comment reply.
409
+ *
410
+ * @since BuddyPress (1.2.0)
411
+ *
412
+ * @param string $ac_input_activity_id Comment content being posted.
413
+ */
414
  $content = apply_filters( 'bp_activity_post_comment_content', $_POST['ac_input_' . $activity_id] );
415
 
416
  if ( empty( $content ) ) {
427
  if ( !empty( $comment_id ) )
428
  bp_core_add_message( __( 'Reply Posted!', 'buddypress' ) );
429
  else
430
+ bp_core_add_message( __( 'There was an error posting that reply. Please try again.', 'buddypress' ), 'error' );
431
 
432
  bp_core_redirect( wp_get_referer() . '#ac-form-' . $activity_id );
433
  }
461
  if ( bp_activity_add_user_favorite( bp_action_variable( 0 ) ) )
462
  bp_core_add_message( __( 'Activity marked as favorite.', 'buddypress' ) );
463
  else
464
+ bp_core_add_message( __( 'There was an error marking that activity as a favorite. Please try again.', 'buddypress' ), 'error' );
465
 
466
  bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) );
467
  }
495
  if ( bp_activity_remove_user_favorite( bp_action_variable( 0 ) ) )
496
  bp_core_add_message( __( 'Activity removed as favorite.', 'buddypress' ) );
497
  else
498
+ bp_core_add_message( __( 'There was an error removing that activity as a favorite. Please try again.', 'buddypress' ), 'error' );
499
 
500
  bp_core_redirect( wp_get_referer() . '#activity-' . bp_action_variable( 0 ) );
501
  }
728
  if ( ! bp_get_option( 'wordpress_api_key' ) && ! defined( 'WPCOM_API_KEY' ) )
729
  return;
730
 
731
+ /**
732
+ * Filters if BuddyPress Activity Akismet support has been disabled by another plugin.
733
+ *
734
+ * @since BuddyPress (1.6.0)
735
+ *
736
+ * @param bool bp_is_akismet_active Return value of bp_is_akismet_active boolean function.
737
+ */
738
  if ( ! apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) )
739
  return;
740
 
753
  exit;
754
  }
755
 
756
+ $args = array(
757
  'term' => sanitize_text_field( $_GET['term'] ),
758
  'type' => sanitize_text_field( $_GET['type'] ),
759
+ );
760
+
761
+ // Support per-Group suggestions.
762
+ if ( ! empty( $_GET['group-id'] ) ) {
763
+ $args['group_id'] = absint( $_GET['group-id'] );
764
+ }
765
+
766
+ $results = bp_core_get_suggestions( $args );
767
 
768
  if ( is_wp_error( $results ) ) {
769
  wp_send_json_error( $results->get_error_message() );
773
  wp_send_json_success( $results );
774
  }
775
  add_action( 'wp_ajax_bp_get_suggestions', 'bp_ajax_get_suggestions' );
776
+
777
+ /**
778
+ * Detect a change in post type status, and initiate an activity update if necessary.
779
+ *
780
+ * @since BuddyPress (2.2.0)
781
+ *
782
+ * @todo Support untrashing better.
783
+ *
784
+ * @param string $new_status New status for the post.
785
+ * @param string $old_status Old status for the post.
786
+ * @param object $post Post data.
787
+ */
788
+ function bp_activity_catch_transition_post_type_status( $new_status, $old_status, $post ) {
789
+ if ( ! post_type_supports( $post->post_type, 'buddypress-activity' ) ) {
790
+ return;
791
+ }
792
+
793
+ // This is an edit.
794
+ if ( $new_status === $old_status ) {
795
+ // An edit of an existing post should update the existing activity item.
796
+ if ( $new_status == 'publish' ) {
797
+ bp_activity_post_type_update( $post );
798
+ }
799
+
800
+ return;
801
+ }
802
+
803
+ // Publishing a previously unpublished post.
804
+ if ( 'publish' === $new_status ) {
805
+ // Untrashing the post type - nothing here yet.
806
+ if ( 'trash' == $old_status ) {
807
+
808
+ /**
809
+ * Fires if untrashing post in a post type.
810
+ *
811
+ * This is a variable filter that is dependent on the post type
812
+ * being untrashed.
813
+ *
814
+ * @since BuddyPress (2.2.0)
815
+ *
816
+ * @param WP_Post $post Post data.
817
+ */
818
+ do_action( 'bp_activity_post_type_untrash_' . $post->post_type, $post );
819
+ } else {
820
+ // Record the post.
821
+ bp_activity_post_type_publish( $post->ID, $post );
822
+ }
823
+
824
+ // Unpublishing a previously published post.
825
+ } elseif ( 'publish' === $old_status ) {
826
+ // Some form of pending status - only remove the activity entry
827
+ bp_activity_post_type_unpublish( $post->ID, $post );
828
+ }
829
+ }
830
+ add_action( 'transition_post_status', 'bp_activity_catch_transition_post_type_status', 10, 3 );
bp-activity/bp-activity-admin.php CHANGED
@@ -11,7 +11,7 @@
11
  */
12
 
13
  // Exit if accessed directly
14
- if ( !defined( 'ABSPATH' ) ) exit;
15
 
16
  // Include WP's list table class
17
  if ( !class_exists( 'WP_List_Table' ) ) require( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
@@ -171,6 +171,14 @@ function bp_activity_admin_edit_hidden_metaboxes( $hidden, $screen ) {
171
  // Hide the primary link meta box by default
172
  $hidden = array_merge( (array) $hidden, array( 'bp_activity_itemids', 'bp_activity_link', 'bp_activity_type', 'bp_activity_userid', ) );
173
 
 
 
 
 
 
 
 
 
174
  return apply_filters( 'bp_hide_meta_boxes', array_unique( $hidden ), $screen );
175
  }
176
  add_filter( 'default_hidden_meta_boxes', 'bp_activity_admin_edit_hidden_metaboxes', 10, 2 );
@@ -198,7 +206,13 @@ function bp_activity_admin_load() {
198
 
199
  $doaction = bp_admin_list_table_current_bulk_action();
200
 
201
- // Call an action for plugins to hook in early
 
 
 
 
 
 
202
  do_action( 'bp_activity_admin_load', $doaction );
203
 
204
  // Edit screen
@@ -300,7 +314,13 @@ function bp_activity_admin_load() {
300
  // Get activity IDs
301
  $activity_ids = array_map( 'absint', (array) $_REQUEST['aid'] );
302
 
303
- // Call a filter for plugins to modify the requested activities to load
 
 
 
 
 
 
304
  $activity_ids = apply_filters( 'bp_activity_admin_action_activity_ids', $activity_ids );
305
 
306
  // Is this a bulk request?
@@ -384,7 +404,17 @@ function bp_activity_admin_load() {
384
  unset( $activity );
385
  }
386
 
387
- // Call actions for plugins to do something before we redirect
 
 
 
 
 
 
 
 
 
 
388
  do_action( 'bp_activity_admin_action_after', array( $spammed, $unspammed, $deleted, $errors ), $redirect_to, $activity_ids );
389
 
390
  // Add arguments to the redirect URL so that on page reload, we can easily display what we've just done.
@@ -401,7 +431,13 @@ function bp_activity_admin_load() {
401
  if ( ! empty( $errors ) )
402
  $redirect_to = add_query_arg( 'error', implode ( ',', array_map( 'absint', $errors ) ), $redirect_to );
403
 
404
- // Redirect
 
 
 
 
 
 
405
  wp_redirect( apply_filters( 'bp_activity_admin_action_redirect', $redirect_to ) );
406
  exit;
407
 
@@ -512,7 +548,13 @@ function bp_activity_admin_load() {
512
  if ( false === $result )
513
  $error = $activity->id;
514
 
515
- // Call actions for plugins to do something before we redirect
 
 
 
 
 
 
516
  do_action_ref_array( 'bp_activity_admin_edit_after', array( &$activity, $error ) );
517
 
518
  // If an error occurred, pass back the activity ID that failed
@@ -521,7 +563,13 @@ function bp_activity_admin_load() {
521
  else
522
  $redirect_to = add_query_arg( 'updated', (int) $activity->id, $redirect_to );
523
 
524
- // Redirect
 
 
 
 
 
 
525
  wp_redirect( apply_filters( 'bp_activity_admin_edit_redirect', $redirect_to ) );
526
  exit;
527
 
@@ -586,7 +634,13 @@ function bp_activity_admin_edit() {
586
  $form_url = remove_query_arg( array( 'action', 'deleted', 'error', 'spammed', 'unspammed', ), $_SERVER['REQUEST_URI'] );
587
  $form_url = add_query_arg( 'action', 'save', $form_url );
588
 
589
- // Call an action for plugins to modify the activity before we display the edit form
 
 
 
 
 
 
590
  do_action_ref_array( 'bp_activity_admin_edit', array( &$activity ) ); ?>
591
 
592
  <div class="wrap">
@@ -595,7 +649,7 @@ function bp_activity_admin_edit() {
595
 
596
  <?php if ( ! empty( $activity ) ) : ?>
597
 
598
- <form action="<?php echo esc_attr( $form_url ); ?>" id="bp-activities-edit-form" method="post">
599
  <div id="poststuff">
600
 
601
  <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
@@ -744,7 +798,7 @@ function bp_activity_admin_get_activity_actions() {
744
  $actions = array();
745
 
746
  // Walk through the registered actions, and build an array of actions/values.
747
- foreach ( buddypress()->activity->actions as $action ) {
748
  $action = array_values( (array) $action );
749
 
750
  for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
@@ -777,7 +831,7 @@ function bp_activity_admin_edit_metabox_type( $item ) {
777
  $selected = $item->type;
778
 
779
  // Walk through the registered actions, and build an array of actions/values.
780
- foreach ( $bp->activity->actions as $action ) {
781
  $action = array_values( (array) $action );
782
 
783
  for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ )
@@ -894,13 +948,19 @@ function bp_activity_admin_index() {
894
  $messages[] = sprintf( _n( '%s activity item has been successfully unspammed.', '%s activity items have been successfully unspammed.', $unspammed, 'buddypress' ), number_format_i18n( $unspammed ) );
895
 
896
  if ( $updated > 0 )
897
- $messages[] = __( 'The activity item has been updated succesfully.', 'buddypress' );
898
  }
899
 
900
  // Prepare the activity items for display
901
  $bp_activity_list_table->prepare_items();
902
 
903
- // Call an action for plugins to modify the activity before we display the edit form
 
 
 
 
 
 
904
  do_action( 'bp_activity_admin_index', $messages ); ?>
905
 
906
  <div class="wrap">
@@ -993,6 +1053,17 @@ class BP_Activity_List_Table extends WP_List_Table {
993
  */
994
  protected $activity_user_id = array();
995
 
 
 
 
 
 
 
 
 
 
 
 
996
  /**
997
  * Constructor.
998
  *
@@ -1082,7 +1153,7 @@ class BP_Activity_List_Table extends WP_List_Table {
1082
  'count_total' => 'count_query',
1083
  ) );
1084
 
1085
- // If we're viewing a specific activity, flatten all activites into a single array.
1086
  if ( $include_id ) {
1087
  $activities['activities'] = BP_Activity_List_Table::flatten_activity_array( $activities['activities'] );
1088
  $activities['total'] = count( $activities['activities'] );
@@ -1096,7 +1167,7 @@ class BP_Activity_List_Table extends WP_List_Table {
1096
  foreach ( $activities['activities'] as $activity_item ) {
1097
  $new_activities[] = (array) $activity_item;
1098
 
1099
- // Build an array of activity-to-user ID mappings for better efficency in the In Response To column
1100
  $this->activity_user_id[$activity_item->id] = $activity_item->user_id;
1101
  }
1102
 
@@ -1208,10 +1279,20 @@ class BP_Activity_List_Table extends WP_List_Table {
1208
  $url_base = bp_get_admin_url( 'admin.php?page=bp-activity' ); ?>
1209
 
1210
  <ul class="subsubsub">
1211
- <li class="all"><a href="<?php echo esc_attr( esc_url( $url_base ) ); ?>" class="<?php if ( 'spam' != $this->view ) echo 'current'; ?>"><?php _e( 'All', 'buddypress' ); ?></a> |</li>
1212
- <li class="spam"><a href="<?php echo esc_attr( esc_url( add_query_arg( 'activity_status', 'spam', $url_base ) ) ); ?>" class="<?php if ( 'spam' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Spam <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->spam_count ) ); ?></a></li>
 
 
1213
 
1214
- <?php do_action( 'bp_activity_list_table_get_views', $url_base, $this->view ); ?>
 
 
 
 
 
 
 
 
1215
  </ul>
1216
  <?php
1217
  }
@@ -1229,6 +1310,13 @@ class BP_Activity_List_Table extends WP_List_Table {
1229
  $actions['bulk_ham'] = __( 'Not Spam', 'buddypress' );
1230
  $actions['bulk_delete'] = __( 'Delete Permanently', 'buddypress' );
1231
 
 
 
 
 
 
 
 
1232
  return apply_filters( 'bp_activity_list_table_get_bulk_actions', $actions );
1233
  }
1234
 
@@ -1288,7 +1376,7 @@ class BP_Activity_List_Table extends WP_List_Table {
1288
  $selected = ( ! empty( $_REQUEST['activity_type'] ) ) ? $_REQUEST['activity_type'] : '';
1289
 
1290
  // Get the actions
1291
- $activity_actions = buddypress()->activity->actions; ?>
1292
 
1293
  <div class="alignleft actions">
1294
  <select name="activity_type">
@@ -1429,7 +1517,14 @@ class BP_Activity_List_Table extends WP_List_Table {
1429
  // Start timestamp
1430
  echo '<div class="submitted-on">';
1431
 
1432
- // Other plugins can filter which actions are shown
 
 
 
 
 
 
 
1433
  $actions = apply_filters( 'bp_activity_admin_comment_row_actions', array_filter( $actions ), $item );
1434
 
1435
  /* translators: 2: activity admin ui date/time */
@@ -1440,8 +1535,23 @@ class BP_Activity_List_Table extends WP_List_Table {
1440
 
1441
  // Get activity content - if not set, use the action
1442
  if ( ! empty( $item['content'] ) ) {
 
 
 
 
 
 
 
 
1443
  $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'] ) );
1444
  } else {
 
 
 
 
 
 
 
1445
  $content = apply_filters_ref_array( 'bp_get_activity_action', array( $item['action'] ) );
1446
  }
1447
 
@@ -1459,6 +1569,15 @@ class BP_Activity_List_Table extends WP_List_Table {
1459
  */
1460
  function column_response( $item ) {
1461
  // Is $item is a root activity?
 
 
 
 
 
 
 
 
 
1462
  if ( empty( $item['item_id'] ) || ! in_array( $item['type'], apply_filters( 'bp_activity_admin_root_activity_types', array( 'activity_comment' ), $item ) ) ) {
1463
  $comment_count = !empty( $item['children'] ) ? bp_activity_recurse_comment_count( (object) $item ) : 0;
1464
  $root_activity_url = bp_get_admin_url( 'admin.php?page=bp-activity&amp;aid=' . $item['id'] );
@@ -1504,7 +1623,7 @@ class BP_Activity_List_Table extends WP_List_Table {
1504
 
1505
  /**
1506
  * If, somehow, the referenced activity has been deleted, leaving its associated
1507
- * activites as orphans, use the logged in user's ID to avoid errors.
1508
  */
1509
  if ( empty( $activity['activities'] ) )
1510
  return bp_loggedin_user_id();
@@ -1573,6 +1692,13 @@ class BP_Activity_List_Table extends WP_List_Table {
1573
  }
1574
  }
1575
 
 
 
 
 
 
 
 
1576
  return apply_filters( 'bp_activity_list_table_can_comment', $can_comment );
1577
  }
1578
 
11
  */
12
 
13
  // Exit if accessed directly
14
+ defined( 'ABSPATH' ) || exit;
15
 
16
  // Include WP's list table class
17
  if ( !class_exists( 'WP_List_Table' ) ) require( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
171
  // Hide the primary link meta box by default
172
  $hidden = array_merge( (array) $hidden, array( 'bp_activity_itemids', 'bp_activity_link', 'bp_activity_type', 'bp_activity_userid', ) );
173
 
174
+ /**
175
+ * Filters default hidden metaboxes so plugins can alter list.
176
+ *
177
+ * @since BuddyPress (1.6.0)
178
+ *
179
+ * @param array $hidden Default metaboxes to hide.
180
+ * @param WP_Screen $screen Screen identifier.
181
+ */
182
  return apply_filters( 'bp_hide_meta_boxes', array_unique( $hidden ), $screen );
183
  }
184
  add_filter( 'default_hidden_meta_boxes', 'bp_activity_admin_edit_hidden_metaboxes', 10, 2 );
206
 
207
  $doaction = bp_admin_list_table_current_bulk_action();
208
 
209
+ /**
210
+ * Fires at top of Activity admin page.
211
+ *
212
+ * @since BuddyPress (1.6.0)
213
+ *
214
+ * @param string $doaction Current $_GET action being performed in admin screen.
215
+ */
216
  do_action( 'bp_activity_admin_load', $doaction );
217
 
218
  // Edit screen
314
  // Get activity IDs
315
  $activity_ids = array_map( 'absint', (array) $_REQUEST['aid'] );
316
 
317
+ /**
318
+ * Filters list of IDs being spammed/un-spammed/deleted.
319
+ *
320
+ * @since BuddyPress (1.6.0)
321
+ *
322
+ * @param array $activity_ids Activity IDs to spam/un-spam/delete.
323
+ */
324
  $activity_ids = apply_filters( 'bp_activity_admin_action_activity_ids', $activity_ids );
325
 
326
  // Is this a bulk request?
404
  unset( $activity );
405
  }
406
 
407
+ /**
408
+ * Fires before redirect for plugins to do something with activity.
409
+ *
410
+ * Passes an activity array counts how many were spam, not spam, deleted, and IDs that were errors.
411
+ *
412
+ * @since BuddyPress (1.6.0)
413
+ *
414
+ * @param array Array holding spam, not spam, deleted counts, error IDs.
415
+ * @param string $redirect_to URL to redirect to.
416
+ * @param array $activity_ids Original array of activity IDs.
417
+ */
418
  do_action( 'bp_activity_admin_action_after', array( $spammed, $unspammed, $deleted, $errors ), $redirect_to, $activity_ids );
419
 
420
  // Add arguments to the redirect URL so that on page reload, we can easily display what we've just done.
431
  if ( ! empty( $errors ) )
432
  $redirect_to = add_query_arg( 'error', implode ( ',', array_map( 'absint', $errors ) ), $redirect_to );
433
 
434
+ /**
435
+ * Filters redirect URL after activity spamming/un-spamming/deletion occurs.
436
+ *
437
+ * @since BuddyPress (1.6.0)
438
+ *
439
+ * @param string $redirect_to URL to redirect to.
440
+ */
441
  wp_redirect( apply_filters( 'bp_activity_admin_action_redirect', $redirect_to ) );
442
  exit;
443
 
548
  if ( false === $result )
549
  $error = $activity->id;
550
 
551
+ /**
552
+ * Fires before redirect so plugins can do something first on save action.
553
+ *
554
+ * @since BuddyPress (1.6.0)
555
+ *
556
+ * @param array Array holding activity object and ID that holds error.
557
+ */
558
  do_action_ref_array( 'bp_activity_admin_edit_after', array( &$activity, $error ) );
559
 
560
  // If an error occurred, pass back the activity ID that failed
563
  else
564
  $redirect_to = add_query_arg( 'updated', (int) $activity->id, $redirect_to );
565
 
566
+ /**
567
+ * Filters URL to redirect to after saving.
568
+ *
569
+ * @since BuddyPress (1.6.0)
570
+ *
571
+ * @param string $redirect_to URL to redirect to.
572
+ */
573
  wp_redirect( apply_filters( 'bp_activity_admin_edit_redirect', $redirect_to ) );
574
  exit;
575
 
634
  $form_url = remove_query_arg( array( 'action', 'deleted', 'error', 'spammed', 'unspammed', ), $_SERVER['REQUEST_URI'] );
635
  $form_url = add_query_arg( 'action', 'save', $form_url );
636
 
637
+ /**
638
+ * Fires before activity edit form is displays so plugins can modify the activity.
639
+ *
640
+ * @since BuddyPress (1.6.0)
641
+ *
642
+ * @param array Array holding single activity object.
643
+ */
644
  do_action_ref_array( 'bp_activity_admin_edit', array( &$activity ) ); ?>
645
 
646
  <div class="wrap">
649
 
650
  <?php if ( ! empty( $activity ) ) : ?>
651
 
652
+ <form action="<?php echo esc_url( $form_url ); ?>" id="bp-activities-edit-form" method="post">
653
  <div id="poststuff">
654
 
655
  <div id="post-body" class="metabox-holder columns-<?php echo 1 == get_current_screen()->get_columns() ? '1' : '2'; ?>">
798
  $actions = array();
799
 
800
  // Walk through the registered actions, and build an array of actions/values.
801
+ foreach ( bp_activity_get_actions() as $action ) {
802
  $action = array_values( (array) $action );
803
 
804
  for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
831
  $selected = $item->type;
832
 
833
  // Walk through the registered actions, and build an array of actions/values.
834
+ foreach ( bp_activity_get_actions() as $action ) {
835
  $action = array_values( (array) $action );
836
 
837
  for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ )
948
  $messages[] = sprintf( _n( '%s activity item has been successfully unspammed.', '%s activity items have been successfully unspammed.', $unspammed, 'buddypress' ), number_format_i18n( $unspammed ) );
949
 
950
  if ( $updated > 0 )
951
+ $messages[] = __( 'The activity item has been updated successfully.', 'buddypress' );
952
  }
953
 
954
  // Prepare the activity items for display
955
  $bp_activity_list_table->prepare_items();
956
 
957
+ /**
958
+ * Fires before edit form is displayed so plugins can modify the activity messages.
959
+ *
960
+ * @since BuddyPress (1.6.0)
961
+ *
962
+ * @param array $messages Array of messages to display at top of page.
963
+ */
964
  do_action( 'bp_activity_admin_index', $messages ); ?>
965
 
966
  <div class="wrap">
1053
  */
1054
  protected $activity_user_id = array();
1055
 
1056
+ /**
1057
+ * If users can comment on blog & forum activity items
1058
+ *
1059
+ * @since BuddyPress (2.2.2)
1060
+ *
1061
+ * @link https://buddypress.trac.wordpress.org/ticket/6277
1062
+ *
1063
+ * @var bool
1064
+ */
1065
+ public $disable_blogforum_comments = false;
1066
+
1067
  /**
1068
  * Constructor.
1069
  *
1153
  'count_total' => 'count_query',
1154
  ) );
1155
 
1156
+ // If we're viewing a specific activity, flatten all activities into a single array.
1157
  if ( $include_id ) {
1158
  $activities['activities'] = BP_Activity_List_Table::flatten_activity_array( $activities['activities'] );
1159
  $activities['total'] = count( $activities['activities'] );
1167
  foreach ( $activities['activities'] as $activity_item ) {
1168
  $new_activities[] = (array) $activity_item;
1169
 
1170
+ // Build an array of activity-to-user ID mappings for better efficiency in the In Response To column
1171
  $this->activity_user_id[$activity_item->id] = $activity_item->user_id;
1172
  }
1173
 
1279
  $url_base = bp_get_admin_url( 'admin.php?page=bp-activity' ); ?>
1280
 
1281
  <ul class="subsubsub">
1282
+ <li class="all"><a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( 'spam' != $this->view ) echo 'current'; ?>"><?php _e( 'All', 'buddypress' ); ?></a> |</li>
1283
+ <li class="spam"><a href="<?php echo esc_url( add_query_arg( 'activity_status', 'spam', $url_base ) ); ?>" class="<?php if ( 'spam' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Spam <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->spam_count ) ); ?></a></li>
1284
+
1285
+ <?php
1286
 
1287
+ /**
1288
+ * Fires inside listing of views so plugins can add their own.
1289
+ *
1290
+ * @since BuddyPress (1.6.0)
1291
+ *
1292
+ * @param string $url_base Current URL base for view.
1293
+ * @param string $view Current view being displayed.
1294
+ */
1295
+ do_action( 'bp_activity_list_table_get_views', $url_base, $this->view ); ?>
1296
  </ul>
1297
  <?php
1298
  }
1310
  $actions['bulk_ham'] = __( 'Not Spam', 'buddypress' );
1311
  $actions['bulk_delete'] = __( 'Delete Permanently', 'buddypress' );
1312
 
1313
+ /**
1314
+ * Filters the default bulk actions so plugins can add custom actions.
1315
+ *
1316
+ * @since BuddyPress (1.6.0)
1317
+ *
1318
+ * @param array $actions Default available actions for bulk operations.
1319
+ */
1320
  return apply_filters( 'bp_activity_list_table_get_bulk_actions', $actions );
1321
  }
1322
 
1376
  $selected = ( ! empty( $_REQUEST['activity_type'] ) ) ? $_REQUEST['activity_type'] : '';
1377
 
1378
  // Get the actions
1379
+ $activity_actions = bp_activity_get_actions(); ?>
1380
 
1381
  <div class="alignleft actions">
1382
  <select name="activity_type">
1517
  // Start timestamp
1518
  echo '<div class="submitted-on">';
1519
 
1520
+ /**
1521
+ * Filters available actions for plugins to alter.
1522
+ *
1523
+ * @since BuddyPress (1.6.0)
1524
+ *
1525
+ * @param array $actions Array of available actions user could use.
1526
+ * @param array $item Current item being added to page.
1527
+ */
1528
  $actions = apply_filters( 'bp_activity_admin_comment_row_actions', array_filter( $actions ), $item );
1529
 
1530
  /* translators: 2: activity admin ui date/time */
1535
 
1536
  // Get activity content - if not set, use the action
1537
  if ( ! empty( $item['content'] ) ) {
1538
+
1539
+ /**
1540
+ * Filters current activity item content.
1541
+ *
1542
+ * @since BuddyPress (1.2.0)
1543
+ *
1544
+ * @param array $item Array index holding current activity item content.
1545
+ */
1546
  $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'] ) );
1547
  } else {
1548
+ /**
1549
+ * Filters current activity item action.
1550
+ *
1551
+ * @since BuddyPress (1.2.0)
1552
+ *
1553
+ * @var array $item Array index holding current activity item action.
1554
+ */
1555
  $content = apply_filters_ref_array( 'bp_get_activity_action', array( $item['action'] ) );
1556
  }
1557
 
1569
  */
1570
  function column_response( $item ) {
1571
  // Is $item is a root activity?
1572
+
1573
+ /**
1574
+ * Filters default list of default root activity types.
1575
+ *
1576
+ * @since BuddyPress (1.6.0)
1577
+ *
1578
+ * @param array Array of default activity types.
1579
+ * @param array $item Current item being displayed.
1580
+ */
1581
  if ( empty( $item['item_id'] ) || ! in_array( $item['type'], apply_filters( 'bp_activity_admin_root_activity_types', array( 'activity_comment' ), $item ) ) ) {
1582
  $comment_count = !empty( $item['children'] ) ? bp_activity_recurse_comment_count( (object) $item ) : 0;
1583
  $root_activity_url = bp_get_admin_url( 'admin.php?page=bp-activity&amp;aid=' . $item['id'] );
1623
 
1624
  /**
1625
  * If, somehow, the referenced activity has been deleted, leaving its associated
1626
+ * activities as orphans, use the logged in user's ID to avoid errors.
1627
  */
1628
  if ( empty( $activity['activities'] ) )
1629
  return bp_loggedin_user_id();
1692
  }
1693
  }
1694
 
1695
+ /**
1696
+ * Filters if an activity item can be commented on or not.
1697
+ *
1698
+ * @since BuddyPress (2.0.0)
1699
+ *
1700
+ * @param bool $can_comment Whether an activity item can be commented on or not.
1701
+ */
1702
  return apply_filters( 'bp_activity_list_table_can_comment', $can_comment );
1703
  }
1704
 
bp-activity/bp-activity-akismet.php CHANGED
@@ -8,7 +8,7 @@
8
  */
9
 
10
  // Exit if accessed directly
11
- if ( !defined( 'ABSPATH' ) ) exit;
12
 
13
  /**
14
  * Akismet support for the Activity component.
@@ -112,6 +112,13 @@ class BP_Akismet {
112
  if ( $desc )
113
  echo '<span class="akismet-status"><a href="' . esc_url( bp_get_admin_url( 'admin.php?page=bp-activity&amp;action=edit&aid=' . $activity['id'] ) ) . '#bp_activity_history">' . htmlspecialchars( $desc ) . '</a></span>';
114
 
 
 
 
 
 
 
 
115
  return apply_filters( 'bp_akismet_comment_row_action', $actions );
116
  }
117
 
@@ -239,6 +246,14 @@ class BP_Akismet {
239
  * @return array List of activity types.
240
  */
241
  public static function get_activity_types() {
 
 
 
 
 
 
 
 
242
  return apply_filters( 'bp_akismet_get_activity_types', array( 'activity_comment', 'activity_update' ) );
243
  }
244
 
@@ -254,6 +269,14 @@ class BP_Akismet {
254
  // Record this item so we can do some tidyup in BP_Akismet::check_member_activity_update()
255
  $this->last_activity = $activity;
256
 
 
 
 
 
 
 
 
 
257
  do_action( 'bp_activity_akismet_mark_as_spam', $activity, $source );
258
  }
259
 
@@ -270,6 +293,14 @@ class BP_Akismet {
270
  if ( 'true' == bp_activity_get_meta( $activity->id, '_bp_akismet_result' ) && !bp_activity_get_meta( $activity->id, '_bp_akismet_user_result' ) )
271
  $activity->content = bp_activity_at_name_filter( $activity->content, $activity->id );
272
 
 
 
 
 
 
 
 
 
273
  do_action( 'bp_activity_akismet_mark_as_ham', $activity, $source );
274
  }
275
 
@@ -311,6 +342,14 @@ class BP_Akismet {
311
  elseif ( !empty( $activity->secondary_item_id ) && !empty( $_POST['_bp_as_nonce_' . $activity->secondary_item_id] ) )
312
  $activity_data['akismet_comment_nonce'] = wp_verify_nonce( $_POST["_bp_as_nonce_{$activity->secondary_item_id}"], "_bp_as_nonce_{$userdata->ID}_{$activity->secondary_item_id}" ) ? 'passed' : 'failed';
313
 
 
 
 
 
 
 
 
 
314
  return apply_filters( 'bp_akismet_build_akismet_data_package', $activity_data, $activity );
315
  }
316
 
@@ -347,7 +386,14 @@ class BP_Akismet {
347
 
348
  // Spam
349
  if ( 'true' == $activity_data['bp_as_result'] ) {
350
- // Action for plugin authors
 
 
 
 
 
 
 
351
  do_action_ref_array( 'bp_activity_akismet_spam_caught', array( &$activity, $activity_data ) );
352
 
353
  // Mark as spam
@@ -431,7 +477,7 @@ class BP_Akismet {
431
  /**
432
  * Contact Akismet to check if this is spam or ham.
433
  *
434
- * Props to WordPress core Akismet plugin for alot of this.
435
  *
436
  * @since BuddyPress (1.6)
437
  *
@@ -450,7 +496,7 @@ class BP_Akismet {
450
  if ( function_exists( 'akismet_init' ) && ( empty( $akismet_api_host ) || empty( $akismet_api_port ) ) )
451
  akismet_init();
452
 
453
- $query_string = $path = $response = '';
454
 
455
  $activity_data['blog'] = bp_get_option( 'home' );
456
  $activity_data['blog_charset'] = bp_get_option( 'blog_charset' );
@@ -614,6 +660,13 @@ class BP_Akismet {
614
  function bp_activity_akismet_delete_old_metadata() {
615
  global $bp, $wpdb;
616
 
 
 
 
 
 
 
 
617
  $interval = apply_filters( 'bp_activity_akismet_delete_meta_interval', 15 );
618
 
619
  // Enforce a minimum of 1 day
8
  */
9
 
10
  // Exit if accessed directly
11
+ defined( 'ABSPATH' ) || exit;
12
 
13
  /**
14
  * Akismet support for the Activity component.
112
  if ( $desc )
113
  echo '<span class="akismet-status"><a href="' . esc_url( bp_get_admin_url( 'admin.php?page=bp-activity&amp;action=edit&aid=' . $activity['id'] ) ) . '#bp_activity_history">' . htmlspecialchars( $desc ) . '</a></span>';
114
 
115
+ /**
116
+ * Filters the list of actions for the current activity's row.
117
+ *
118
+ * @since BuddyPress (1.6.0)
119
+ *
120
+ * @param array $actions Array of available actions for the current activity item's row.
121
+ */
122
  return apply_filters( 'bp_akismet_comment_row_action', $actions );
123
  }
124
 
246
  * @return array List of activity types.
247
  */
248
  public static function get_activity_types() {
249
+
250
+ /**
251
+ * Filters the list of activity types that Akismet should automatically check for spam.
252
+ *
253
+ * @since BuddyPress (1.6.0)
254
+ *
255
+ * @param array Array of default activity types for Akismet to check.
256
+ */
257
  return apply_filters( 'bp_akismet_get_activity_types', array( 'activity_comment', 'activity_update' ) );
258
  }
259
 
269
  // Record this item so we can do some tidyup in BP_Akismet::check_member_activity_update()
270
  $this->last_activity = $activity;
271
 
272
+ /**
273
+ * Fires after marking an activity item has been marked as spam.
274
+ *
275
+ * @since BuddyPress (1.6.0)
276
+ *
277
+ * @param BP_Activity_Activity $activity Activity object being marked as spam.
278
+ * @param string $source Source of the whom marked as spam. Either "by_a_person" (e.g. a person has manually marked the activity as spam) or "by_akismet".
279
+ */
280
  do_action( 'bp_activity_akismet_mark_as_spam', $activity, $source );
281
  }
282
 
293
  if ( 'true' == bp_activity_get_meta( $activity->id, '_bp_akismet_result' ) && !bp_activity_get_meta( $activity->id, '_bp_akismet_user_result' ) )
294
  $activity->content = bp_activity_at_name_filter( $activity->content, $activity->id );
295
 
296
+ /**
297
+ * Fires after marking an activity item has been marked as ham.
298
+ *
299
+ * @since BuddyPress (1.6.0)
300
+ *
301
+ * @param BP_Activity_Activity $activity Activity object being marked as ham.
302
+ * @param string $source Source of the whom marked as ham. Either "by_a_person" (e.g. a person has manually marked the activity as ham) or "by_akismet" (automatically hammed).
303
+ */
304
  do_action( 'bp_activity_akismet_mark_as_ham', $activity, $source );
305
  }
306
 
342
  elseif ( !empty( $activity->secondary_item_id ) && !empty( $_POST['_bp_as_nonce_' . $activity->secondary_item_id] ) )
343
  $activity_data['akismet_comment_nonce'] = wp_verify_nonce( $_POST["_bp_as_nonce_{$activity->secondary_item_id}"], "_bp_as_nonce_{$userdata->ID}_{$activity->secondary_item_id}" ) ? 'passed' : 'failed';
344
 
345
+ /**
346
+ * Filters activity data before being sent to Akismet to inspect.
347
+ *
348
+ * @since BuddyPress (1.6.0)
349
+ *
350
+ * @param array $activity_data Array of activity data for Akismet to inspect.
351
+ * @param BP_Activity_Activity $activity Activity item data.
352
+ */
353
  return apply_filters( 'bp_akismet_build_akismet_data_package', $activity_data, $activity );
354
  }
355
 
386
 
387
  // Spam
388
  if ( 'true' == $activity_data['bp_as_result'] ) {
389
+ /**
390
+ * Fires after an activity item has been proven to be spam, but before officially being marked as spam.
391
+ *
392
+ * @since BuddyPress (1.6.0)
393
+ *
394
+ * @param BP_Activity_Activity $activity The activity item proven to be spam.
395
+ * @param array $activity_data Array of activity data for item including Akismet check results data.
396
+ */
397
  do_action_ref_array( 'bp_activity_akismet_spam_caught', array( &$activity, $activity_data ) );
398
 
399
  // Mark as spam
477
  /**
478
  * Contact Akismet to check if this is spam or ham.
479
  *
480
+ * Props to WordPress core Akismet plugin for a lot of this.
481
  *
482
  * @since BuddyPress (1.6)
483
  *
496
  if ( function_exists( 'akismet_init' ) && ( empty( $akismet_api_host ) || empty( $akismet_api_port ) ) )
497
  akismet_init();
498
 
499
+ $query_string = $path = '';
500
 
501
  $activity_data['blog'] = bp_get_option( 'home' );
502
  $activity_data['blog_charset'] = bp_get_option( 'blog_charset' );
660
  function bp_activity_akismet_delete_old_metadata() {
661
  global $bp, $wpdb;
662
 
663
+ /**
664
+ * Filters the threshold for how many days old Akismet metadata needs to be before being automatically deleted.
665
+ *
666
+ * @since BuddyPress (1.6.0)
667
+ *
668
+ * @param integer 15 How many days old metadata needs to be.
669
+ */
670
  $interval = apply_filters( 'bp_activity_akismet_delete_meta_interval', 15 );
671
 
672
  // Enforce a minimum of 1 day
bp-activity/bp-activity-cache.php CHANGED
@@ -7,7 +7,7 @@
7
  */
8
 
9
  // Exit if accessed directly
10
- if ( !defined( 'ABSPATH' ) ) exit;
11
 
12
  /**
13
  * Slurp up activitymeta for a specified set of activity items.
@@ -43,6 +43,7 @@ function bp_activity_update_meta_cache( $activity_ids = false ) {
43
  */
44
  function bp_activity_clear_cache_for_activity( $activity ) {
45
  wp_cache_delete( $activity->id, 'bp_activity' );
 
46
  }
47
  add_action( 'bp_activity_after_save', 'bp_activity_clear_cache_for_activity' );
48
 
7
  */
8
 
9
  // Exit if accessed directly
10
+ defined( 'ABSPATH' ) || exit;
11
 
12
  /**
13
  * Slurp up activitymeta for a specified set of activity items.
43
  */
44
  function bp_activity_clear_cache_for_activity( $activity ) {
45
  wp_cache_delete( $activity->id, 'bp_activity' );
46
+ wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
47
  }
48
  add_action( 'bp_activity_after_save', 'bp_activity_clear_cache_for_activity' );
49
 
bp-activity/bp-activity-classes.php CHANGED
</
@@ -7,7 +7,7 @@
7
  */
8
 
9
  // Exit if accessed directly
10
- if ( !defined( 'ABSPATH' ) ) exit;
11
 
12
  /**
13
  * Database interaction class for the BuddyPress activity component.
@@ -135,11 +135,12 @@ class BP_Activity_Activity {
135
  * Populate the object with data about the specific activity item.
136
  */
137
  public function populate() {
138
- global $wpdb, $bp;
139
 
140
  $row = wp_cache_get( $this->id, 'bp_activity' );
141
 
142
  if ( false === $row ) {
 
143
  $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id = %d", $this->id ) );
144
 
145
  wp_cache_set( $this->id, $row, 'bp_activity' );
@@ -169,7 +170,7 @@ class BP_Activity_Activity {
169
 
170
  // If no callback is available, use the literal string from
171
  // the database row
172
- } else if ( ! empty( $row->action ) ) {
173
  $this->action = $row->action;
174
 
175
  // Provide a fallback to avoid PHP notices
@@ -184,7 +185,9 @@ class BP_Activity_Activity {
184
  * @return bool True on success.
185
  */
186
  public function save() {
187
- global $wpdb, $bp;
 
 
188
 
189
  $this->id = apply_filters_ref_array( 'bp_activity_id_before_save', array( $this->id, &$this ) );
190
  $this->item_id = apply_filters_ref_array( 'bp_activity_item_id_before_save', array( $this->item_id, &$this ) );
@@ -201,32 +204,52 @@ class BP_Activity_Activity {
201
  $this->mptt_right = apply_filters_ref_array( 'bp_activity_mptt_right_before_save', array( $this->mptt_right, &$this ) );
202
  $this->is_spam = apply_filters_ref_array( 'bp_activity_is_spam_before_save', array( $this->is_spam, &$this ) );
203
 
204
- // Use this, not the filters above
 
 
 
 
 
 
 
 
205
  do_action_ref_array( 'bp_activity_before_save', array( &$this ) );
206
 
207
- if ( !$this->component || !$this->type )
208
  return false;
 
209
 
210
- if ( !$this->primary_link )
211
  $this->primary_link = bp_loggedin_user_domain();
 
212
 
213
  // If we have an existing ID, update the activity item, otherwise insert it.
214
- if ( $this->id )
215
  $q = $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET user_id = %d, component = %s, type = %s, action = %s, content = %s, primary_link = %s, date_recorded = %s, item_id = %d, secondary_item_id = %d, hide_sitewide = %d, is_spam = %d WHERE id = %d", $this->user_id, $this->component, $this->type, $this->action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide, $this->is_spam, $this->id );
216
- else
217
  $q = $wpdb->prepare( "INSERT INTO {$bp->activity->table_name} ( user_id, component, type, action, content, primary_link, date_recorded, item_id, secondary_item_id, hide_sitewide, is_spam ) VALUES ( %d, %s, %s, %s, %s, %s, %s, %d, %d, %d, %d )", $this->user_id, $this->component, $this->type, $this->action, $this->content, $this->primary_link, $this->date_recorded, $this->item_id, $this->secondary_item_id, $this->hide_sitewide, $this->is_spam );
 
218
 
219
- if ( false === $wpdb->query( $q ) )
220
  return false;
 
221
 
222
  // If this is a new activity item, set the $id property
223
- if ( empty( $this->id ) )
224
  $this->id = $wpdb->insert_id;
225
 
226
  // If an existing activity item, prevent any changes to the content generating new @mention notifications.
227
- else
228
  add_filter( 'bp_activity_at_name_do_notifications', '__return_false' );
 
229
 
 
 
 
 
 
 
 
230
  do_action_ref_array( 'bp_activity_after_save', array( &$this ) );
231
 
232
  return true;
@@ -244,42 +267,34 @@ class BP_Activity_Activity {
244
  *
245
  * @param array $args {
246
  * An array of arguments. All items are optional.
247
- * @type int $page Which page of results to fetch. Using page=1
248
- * without per_page will result in no pagination.
249
- * Default: 1.
250
- * @type int|bool $per_page Number of results per page. Default: 25.
251
- * @type int|bool $max Maximum number of results to return.
252
- * Default: false (unlimited).
253
- * @type string $sort ASC or DESC. Default: 'DESC'.
254
- * @type array $exclude Array of activity IDs to exclude.
255
- * Default: false.
256
- * @type array $in Array of ids to limit query by (IN).
257
- * Default: false.
258
- * @type array $meta_query An array of meta_query conditions.
259
- * See WP_Meta_Query::queries for description.
260
- * @type array $date_query An array of date_query conditions.
261
- * See first parameter of WP_Date_Query::__construct()
262
- * for description.
263
- * @type array $filter See BP_Activity_Activity::get_filter_sql().
264
- * @type string $search_terms Limit results by a search term.
265
- * Default: false.
266
- * @type bool $display_comments Whether to include activity comments.
267
- * Default: false.
268
- * @type bool $show_hidden Whether to show items marked hide_sitewide.
269
- * Default: false.
270
- * @type string $spam Spam status. Default: 'ham_only'.
271
- * @type bool $update_meta_cache Whether to pre-fetch metadata for
272
- * queried activity items. Default: true.
273
- * @type string|bool $count_total If true, an additional DB query
274
- * is run to count the total activity items for the query.
275
- * Default: false.
276
  * }
277
  * @return array The array returned has two keys:
278
  * - 'total' is the count of located activities
279
  * - 'activities' is an array of the located activities
280
  */
281
  public static function get( $args = array() ) {
282
- global $wpdb, $bp;
283
 
284
  // Backward compatibility with old method of passing arguments
285
  if ( !is_array( $args ) || func_num_args() > 1 ) {
@@ -303,7 +318,8 @@ class BP_Activity_Activity {
303
  $args = bp_core_parse_args_array( $old_args_keys, $func_args );
304
  }
305
 
306
- $defaults = array(
 
307
  'page' => 1, // The current page
308
  'per_page' => 25, // Activity items per page
309
  'max' => false, // Max number of items to return
@@ -312,16 +328,16 @@ class BP_Activity_Activity {
312
  'in' => false, // Array of ids to limit query by (IN)
313
  'meta_query' => false, // Filter by activitymeta
314
  'date_query' => false, // Filter by date
 
315
  'filter' => false, // See self::get_filter_sql()
 
316
  'search_terms' => false, // Terms to search by
317
  'display_comments' => false, // Whether to include activity comments
318
  'show_hidden' => false, // Show items marked hide_sitewide
319
  'spam' => 'ham_only', // Spam status
320
  'update_meta_cache' => true,
321
  'count_total' => false,
322
- );
323
- $r = wp_parse_args( $args, $defaults );
324
- extract( $r );
325
 
326
  // Select conditions
327
  $select_sql = "SELECT DISTINCT a.id";
@@ -336,44 +352,72 @@ class BP_Activity_Activity {
336
  // Excluded types
337
  $excluded_types = array();
338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  // Spam
340
- if ( 'ham_only' == $spam )
341
  $where_conditions['spam_sql'] = 'a.is_spam = 0';
342
- elseif ( 'spam_only' == $spam )
343
  $where_conditions['spam_sql'] = 'a.is_spam = 1';
 
344
 
345
  // Searching
346
- if ( $search_terms ) {
347
- $search_terms_like = '%' . bp_esc_like( $search_terms ) . '%';
348
  $where_conditions['search_sql'] = $wpdb->prepare( 'a.content LIKE %s', $search_terms_like );
349
  }
350
 
351
- // Filtering
352
- if ( $filter && $filter_sql = BP_Activity_Activity::get_filter_sql( $filter ) )
353
- $where_conditions['filter_sql'] = $filter_sql;
354
-
355
  // Sorting
356
- if ( $sort != 'ASC' && $sort != 'DESC' )
 
357
  $sort = 'DESC';
 
358
 
359
  // Hide Hidden Items?
360
- if ( !$show_hidden )
361
  $where_conditions['hidden_sql'] = "a.hide_sitewide = 0";
 
362
 
363
  // Exclude specified items
364
- if ( !empty( $exclude ) ) {
365
- $exclude = implode( ',', wp_parse_id_list( $exclude ) );
366
  $where_conditions['exclude'] = "a.id NOT IN ({$exclude})";
367
  }
368
 
369
  // The specific ids to which you want to limit the query
370
- if ( !empty( $in ) ) {
371
- $in = implode( ',', wp_parse_id_list( $in ) );
372
  $where_conditions['in'] = "a.id IN ({$in})";
373
  }
374
 
375
  // Process meta_query into SQL
376
- $meta_query_sql = self::get_meta_query_sql( $meta_query );
377
 
378
  if ( ! empty( $meta_query_sql['join'] ) ) {
379
  $join_sql .= $meta_query_sql['join'];
@@ -384,7 +428,7 @@ class BP_Activity_Activity {
384
  }
385
 
386
  // Process date_query into SQL
387
- $date_query_sql = self::get_date_query_sql( $date_query );
388
 
389
  if ( ! empty( $date_query_sql ) ) {
390
  $where_conditions['date'] = $date_query_sql;
@@ -393,34 +437,45 @@ class BP_Activity_Activity {
393
  // Alter the query based on whether we want to show activity item
394
  // comments in the stream like normal comments or threaded below
395
  // the activity.
396
- if ( false === $display_comments || 'threaded' === $display_comments ) {
397
  $excluded_types[] = 'activity_comment';
398
  }
399
 
400
  // Exclude 'last_activity' items unless the 'action' filter has
401
  // been explicitly set
402
- if ( empty( $filter['object'] ) ) {
403
  $excluded_types[] = 'last_activity';
404
  }
405
 
406
- // Exclude 'new_member' items if xprofile component is not active
407
- if ( ! bp_is_active( 'xprofile' ) ) {
408
- $excluded_types[] = 'new_member';
409
- }
410
-
411
  // Build the excluded type sql part
412
  if ( ! empty( $excluded_types ) ) {
413
  $not_in = "'" . implode( "', '", esc_sql( $excluded_types ) ) . "'";
414
  $where_conditions['excluded_types'] = "a.type NOT IN ({$not_in})";
415
  }
416
 
417
- // Filter the where conditions
 
 
 
 
 
 
 
 
 
 
418
  $where_conditions = apply_filters( 'bp_activity_get_where_conditions', $where_conditions, $r, $select_sql, $from_sql, $join_sql );
419
 
420
  // Join the where conditions together
421
  $where_sql = 'WHERE ' . join( ' AND ', $where_conditions );
422
 
423
- // Define the preferred order for indexes
 
 
 
 
 
 
424
  $indexes = apply_filters( 'bp_activity_preferred_index_order', array( 'user_id', 'item_id', 'secondary_item_id', 'date_recorded', 'component', 'type', 'hide_sitewide', 'is_spam' ) );
425
 
426
  foreach( $indexes as $key => $index ) {
@@ -437,8 +492,8 @@ class BP_Activity_Activity {
437
  }
438
 
439
  // Sanitize page and per_page parameters
440
- $page = absint( $page );
441
- $per_page = absint( $per_page );
442
 
443
  $retval = array(
444
  'activities' => null,
@@ -446,7 +501,17 @@ class BP_Activity_Activity {
446
  'has_more_items' => null,
447
  );
448
 
449
- // Filter and return true to use the legacy query structure (not recommended)
 
 
 
 
 
 
 
 
 
 
450
  if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $r ) ) {
451
 
452
  // Legacy queries joined against the user table
@@ -455,13 +520,27 @@ class BP_Activity_Activity {
455
 
456
  if ( ! empty( $page ) && ! empty( $per_page ) ) {
457
  $pag_sql = $wpdb->prepare( "LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page );
 
 
458
  $activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort} {$pag_sql}", $select_sql, $from_sql, $where_sql, $sort, $pag_sql ) );
459
  } else {
460
- $activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}", $select_sql, $from_sql, $where_sql, $sort ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  }
462
 
463
  } else {
464
-
465
  // Query first for activity IDs
466
  $activity_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}";
467
 
@@ -471,6 +550,14 @@ class BP_Activity_Activity {
471
  $activity_ids_sql .= $wpdb->prepare( " LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page + 1 );
472
  }
473
 
 
 
 
 
 
 
 
 
474
  $activity_ids_sql = apply_filters( 'bp_activity_paged_activities_sql', $activity_ids_sql, $r );
475
 
476
  $activity_ids = $wpdb->get_col( $activity_ids_sql );
@@ -495,12 +582,13 @@ class BP_Activity_Activity {
495
  $activity_ids[] = $activity->id;
496
  }
497
 
498
- if ( ! empty( $activity_ids ) && $update_meta_cache ) {
499
  bp_activity_update_meta_cache( $activity_ids );
500
  }
501
 
502
- if ( $activities && $display_comments )
503
- $activities = BP_Activity_Activity::append_comments( $activities, $spam );
 
504
 
505
  // Pre-fetch data associated with activity users and other objects
506
  BP_Activity_Activity::prefetch_object_data( $activities );
@@ -513,12 +601,22 @@ class BP_Activity_Activity {
513
  // If $max is set, only return up to the max results
514
  if ( ! empty( $r['count_total'] ) ) {
515
 
 
 
 
 
 
 
 
 
 
516
  $total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$join_sql} {$where_sql}", $where_sql, $sort );
517
  $total_activities = $wpdb->get_var( $total_activities_sql );
518
 
519
- if ( !empty( $max ) ) {
520
- if ( (int) $total_activities > (int) $max )
521
- $total_activities = $max;
 
522
  }
523
 
524
  $retval['total'] = $total_activities;
@@ -639,6 +737,14 @@ class BP_Activity_Activity {
639
  * @param array $activities Array of activities.
640
  */
641
  protected static function prefetch_object_data( $activities ) {
 
 
 
 
 
 
 
 
642
  return apply_filters( 'bp_activity_prefetch_object_data', $activities );
643
  }
644
 
@@ -735,6 +841,110 @@ class BP_Activity_Activity {
735
  return $sql;
736
  }
737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
738
  /**
739
  * In BuddyPress 1.2.x, this was used to retrieve specific activity stream items (for example, on an activity's permalink page).
740
  *
@@ -761,51 +971,64 @@ class BP_Activity_Activity {
761
  /**
762
  * Get the first activity ID that matches a set of criteria.
763
  *
764
- * @param int $user_id The user ID to filter by.
765
- * @param string $component The component to filter by.
766
- * @param string $type The activity type to filter by.
767
- * @param int $item_id The associated item to filter by.
768
- * @param int $secondary_item_id The secondary associated item to filter by.
769
- * @param string $action The action to filter by.
770
- * @param string $content The content to filter by.
771
- * @param string $date_recorded The date to filter by.
 
 
 
772
  * @return int|bool Activity ID on success, false if none is found.
773
  */
774
  public static function get_id( $user_id, $component, $type, $item_id, $secondary_item_id, $action, $content, $date_recorded ) {
775
- global $bp, $wpdb;
 
 
776
 
777
  $where_args = false;
778
 
779
- if ( !empty( $user_id ) )
780
  $where_args[] = $wpdb->prepare( "user_id = %d", $user_id );
 
781
 
782
- if ( !empty( $component ) )
783
  $where_args[] = $wpdb->prepare( "component = %s", $component );
 
784
 
785
- if ( !empty( $type ) )
786
  $where_args[] = $wpdb->prepare( "type = %s", $type );
 
787
 
788
- if ( !empty( $item_id ) )
789
  $where_args[] = $wpdb->prepare( "item_id = %d", $item_id );
 
790
 
791
- if ( !empty( $secondary_item_id ) )
792
  $where_args[] = $wpdb->prepare( "secondary_item_id = %d", $secondary_item_id );
 
793
 
794
- if ( !empty( $action ) )
795
  $where_args[] = $wpdb->prepare( "action = %s", $action );
 
796
 
797
- if ( !empty( $content ) )
798
  $where_args[] = $wpdb->prepare( "content = %s", $content );
 
799
 
800
- if ( !empty( $date_recorded ) )
801
  $where_args[] = $wpdb->prepare( "date_recorded = %s", $date_recorded );
 
802
 
803
- if ( !empty( $where_args ) )
804
  $where_sql = 'WHERE ' . join( ' AND ', $where_args );
805
- else
806
- return false;
807
 
808
- return $wpdb->get_var( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
809
  }
810
 
811
  /**
@@ -832,7 +1055,9 @@ class BP_Activity_Activity {
832
  * @return array|bool An array of deleted activity IDs on success, false on failure.
833
  */
834
  public static function delete( $args = array() ) {
835
- global $wpdb, $bp;
 
 
836
 
837
  $defaults = array(
838
  'id' => false,
@@ -933,10 +1158,11 @@ class BP_Activity_Activity {
933
  * @return bool True on success.
934
  */
935
  public static function delete_activity_item_comments( $activity_ids = array(), $delete_meta = true ) {
936
- global $bp, $wpdb;
937
 
938
- $delete_meta = (bool) $delete_meta;
939
 
 
940
  $activity_ids = implode( ',', wp_parse_id_list( $activity_ids ) );
941
 
942
  if ( $delete_meta ) {
@@ -1004,7 +1230,6 @@ class BP_Activity_Activity {
1004
  *
1005
  * @since BuddyPress (1.2)
1006
  *
1007
- * @global BuddyPress $bp The one true BuddyPress instance.
1008
  * @global wpdb $wpdb WordPress database object.
1009
  *
1010
  * @param int $activity_id Activity ID to fetch comments for.
@@ -1015,7 +1240,7 @@ class BP_Activity_Activity {
1015
  * @return array The updated activities with nested comments.
1016
  */
1017
  public static function get_activity_comments( $activity_id, $left, $right, $spam = 'ham_only', $top_level_parent_id = 0 ) {
1018
- global $wpdb, $bp;
1019
 
1020
  if ( empty( $top_level_parent_id ) ) {
1021
  $top_level_parent_id = $activity_id;
@@ -1029,7 +1254,9 @@ class BP_Activity_Activity {
1029
  $comments = false;
1030
 
1031
  // A true cache miss
1032
- } else if ( empty( $comments ) ) {
 
 
1033
 
1034
  // Select the user's fullname with the query
1035
  if ( bp_is_active( 'xprofile' ) ) {
@@ -1053,7 +1280,29 @@ class BP_Activity_Activity {
1053
 
1054
  // Legacy query - not recommended
1055
  $func_args = func_get_args();
 
 
 
 
 
 
 
 
 
 
1056
  if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $func_args ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
1057
  $sql = apply_filters( 'bp_activity_comments_user_join_filter', $wpdb->prepare( "SELECT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name{$fullname_select} FROM {$bp->activity->table_name} a, {$wpdb->users} u{$fullname_from} WHERE u.ID = a.user_id {$fullname_where} AND a.type = 'activity_comment' {$spam_sql} AND a.item_id = %d AND a.mptt_left > %d AND a.mptt_left < %d ORDER BY a.date_recorded ASC", $top_level_parent_id, $left, $right ), $activity_id, $left, $right, $spam_sql );
1058
 
1059
  $descendants = $wpdb->get_results( $sql );
@@ -1135,35 +1384,39 @@ class BP_Activity_Activity {
1135
  *
1136
  * @since BuddyPress (1.2)
1137
  *
1138
- * @global BuddyPress $bp The one true BuddyPress instance.
1139
- * @global wpdb $wpdb WordPress database object.
1140
  *
1141
- * @param int $parent_id ID of an activty or activity comment.
1142
- * @param int $left Node boundary start for activity or activity comment.
1143
- * @return int Right node boundary of activity or activity comment.
1144
  */
1145
  public static function rebuild_activity_comment_tree( $parent_id, $left = 1 ) {
1146
- global $wpdb, $bp;
 
 
1147
 
1148
  // The right value of this node is the left value + 1
1149
- $right = $left + 1;
1150
 
1151
  // Get all descendants of this node
1152
- $descendants = BP_Activity_Activity::get_child_comments( $parent_id );
 
1153
 
1154
  // Loop the descendants and recalculate the left and right values
1155
- foreach ( (array) $descendants as $descendant )
1156
- $right = BP_Activity_Activity::rebuild_activity_comment_tree( $descendant->id, $right );
 
1157
 
1158
  // We've got the left value, and now that we've processed the children
1159
  // of this node we also know the right value
1160
- if ( 1 == $left )
1161
  $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET mptt_left = %d, mptt_right = %d WHERE id = %d", $left, $right, $parent_id ) );
1162
- else
1163
  $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET mptt_left = %d, mptt_right = %d WHERE type = 'activity_comment' AND id = %d", $left, $right, $parent_id ) );
 
1164
 
1165
  // Return the right value of this node + 1
1166
- return $right + 1;
1167
  }
1168
 
1169
  /**
@@ -1171,14 +1424,15 @@ class BP_Activity_Activity {
1171
  *
1172
  * @since BuddyPress (1.2)
1173
  *
1174
- * @global BuddyPress $bp The one true BuddyPress instance.
1175
  * @global wpdb $wpdb WordPress database object.
1176
  *
1177
- * @param int $parent_id ID of an activty or activity comment.
1178
  * @return object Numerically indexed array of child comments.
1179
  */
1180
  public static function get_child_comments( $parent_id ) {
1181
- global $bp, $wpdb;
 
 
1182
 
1183
  return $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE type = 'activity_comment' AND secondary_item_id = %d", $parent_id ) );
1184
  }
@@ -1194,9 +1448,11 @@ class BP_Activity_Activity {
1194
  * @return array List of component names.
1195
  */
1196
  public static function get_recorded_components( $skip_last_activity = true ) {
1197
- global $wpdb, $bp;
 
 
1198
 
1199
- if ( $skip_last_activity ) {
1200
  $components = $wpdb->get_col( "SELECT DISTINCT component FROM {$bp->activity->table_name} WHERE action != '' AND action != 'last_activity' ORDER BY component ASC" );
1201
  } else {
1202
  $components = $wpdb->get_col( "SELECT DISTINCT component FROM {$bp->activity->table_name} ORDER BY component ASC" );
@@ -1348,7 +1604,9 @@ class BP_Activity_Activity {
1348
  * @return string ISO timestamp.
1349
  */
1350
  public static function get_last_updated() {
1351
- global $bp, $wpdb;
 
 
1352
 
1353
  return $wpdb->get_var( "SELECT date_recorded FROM {$bp->activity->table_name} ORDER BY date_recorded DESC LIMIT 1" );
1354
  }
@@ -1362,10 +1620,15 @@ class BP_Activity_Activity {
1362
  * @return int A count of the user's favorites.
1363
  */
1364
  public static function total_favorite_count( $user_id ) {
1365
- if ( !$favorite_activity_entries = bp_get_user_meta( $user_id, 'bp_favorite_activities', true ) )
1366
- return 0;
1367
 
1368
- return count( maybe_unserialize( $favorite_activity_entries ) );
 
 
 
 
 
 
 
1369
  }
1370
 
1371
  /**
@@ -1375,7 +1638,9 @@ class BP_Activity_Activity {
1375
  * @return int|bool The ID of the first matching item if found, otherwise false.
1376
  */
1377
  public static function check_exists_by_content( $content ) {
1378
- global $wpdb, $bp;
 
 
1379
 
1380
  return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE content = %s", $content ) );
1381
  }
@@ -1387,10 +1652,309 @@ class BP_Activity_Activity {
1387
  * @param int
1388
  */
1389
  public static function hide_all_for_user( $user_id ) {
1390
- global $wpdb, $bp;
 
 
1391
 
1392
  return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) );
1393
  }