BuddyPress - Version 2.0-beta1

Version Description

= 1.9.2 = See: http://codex.buddypress.org/releases/version-1-9-2/

= 1.9.1 = See: http://codex.buddypress.org/releases/version-1-9-1/

= 1.9 = See: http://codex.buddypress.org/releases/version-1-9/

= 1.8.1 = See: http://codex.buddypress.org/releases/version-1-8-1/

= 1.8 = See: http://codex.buddypress.org/releases/version-1-8/

= 1.7.3 = See: http://codex.buddypress.org/releases/version-1-7-3/

= 1.7.2 = See: http://codex.buddypress.org/releases/version-1-7-2/

= 1.7.1 = See: http://codex.buddypress.org/releases/version-1-7-1/

= 1.7 = See: http://codex.buddypress.org/releases/version-1-7/

= 1.6.5 = See: http://codex.buddypress.org/releases/version-1-6-5/

= 1.6.4 = See: http://codex.buddypress.org/releases/version-1-6-4/

= 1.6.3 = See: http://codex.buddypress.org/releases/version-1-6-3/

= 1.6.2 = Compatibility with WordPress 3.5

= 1.6.1 = Fixes 4 bugs

= 1.6 = See: http://codex.buddypress.org/releases/version-1-6/

= 1.5 = See: http://codex.buddypress.org/releases/version-1-5/

= 1.2.9 = Compatibility with WordPress 3.2

= 1.2.8 = Compatibility with WordPress 3.1

= 1.2.7 = Fixes over 10 bugs.

Download this release

Release Info

Developer boonebgorges
Plugin Icon 128x128 BuddyPress
Version 2.0-beta1
Comparing to
See all releases

Code changes from version 1.9.2 to 2.0-beta1

Files changed (201) hide show
  1. .travis.yml +0 -54
  2. bp-activity/admin/css/admin.css +3 -0
  3. bp-activity/admin/css/admin.min.css +1 -1
  4. bp-activity/admin/js/admin.js +5 -0
  5. bp-activity/admin/js/admin.min.js +1 -1
  6. bp-activity/bp-activity-admin.php +139 -18
  7. bp-activity/bp-activity-cache.php +21 -15
  8. bp-activity/bp-activity-classes.php +306 -77
  9. bp-activity/bp-activity-filters.php +183 -14
  10. bp-activity/bp-activity-functions.php +292 -209
  11. bp-activity/bp-activity-loader.php +10 -3
  12. bp-activity/bp-activity-notifications.php +48 -6
  13. bp-activity/bp-activity-screens.php +2 -2
  14. bp-activity/bp-activity-template.php +156 -60
  15. bp-blogs/bp-blogs-activity.php +712 -3
  16. bp-blogs/bp-blogs-cache.php +21 -0
  17. bp-blogs/bp-blogs-classes.php +43 -6
  18. bp-blogs/bp-blogs-functions.php +427 -125
  19. bp-blogs/bp-blogs-loader.php +7 -2
  20. bp-blogs/bp-blogs-screens.php +2 -7
  21. bp-blogs/bp-blogs-template.php +121 -15
  22. bp-core/admin/bp-core-components.php +3 -3
  23. bp-core/admin/bp-core-functions.php +145 -8
  24. bp-core/admin/bp-core-schema.php +51 -4
  25. bp-core/admin/bp-core-settings.php +16 -2
  26. bp-core/admin/bp-core-slugs.php +3 -3
  27. bp-core/admin/bp-core-tools.php +349 -0
  28. bp-core/admin/css/common.css +13 -9
  29. bp-core/admin/images/badge-2x.png +0 -0
  30. bp-core/admin/images/badge.png +0 -0
  31. bp-core/bp-core-admin.php +89 -18
  32. bp-core/bp-core-adminbar.php +2 -2
  33. bp-core/bp-core-avatars.php +76 -17
  34. bp-core/bp-core-buddybar.php +4 -3
  35. bp-core/bp-core-cache.php +123 -25
  36. bp-core/bp-core-caps.php +0 -2
  37. bp-core/bp-core-classes.php +233 -42
  38. bp-core/bp-core-component.php +92 -10
  39. bp-core/bp-core-cssjs.php +9 -18
  40. bp-core/bp-core-filters.php +76 -3
  41. bp-core/bp-core-functions.php +173 -78
  42. bp-core/bp-core-loader.php +15 -9
  43. bp-core/bp-core-options.php +124 -69
  44. bp-core/bp-core-template-loader.php +13 -1
  45. bp-core/bp-core-template.php +99 -28
  46. bp-core/bp-core-update.php +76 -1
  47. bp-core/bp-core-widgets.php +54 -13
  48. bp-core/bp-core-wpabstraction.php +9 -0
  49. bp-core/deprecated/1.5.php +1 -1
  50. bp-core/deprecated/2.0.php +32 -0
  51. bp-core/js/confirm.js +7 -0
  52. bp-core/js/confirm.min.js +7 -0
  53. bp-forums/bp-forums-bbpress-sa.php +7 -5
  54. bp-forums/bp-forums-loader.php +2 -2
  55. bp-forums/bp-forums-template.php +2 -2
  56. bp-forums/deprecated/1.6.php +3 -3
  57. bp-forums/deprecated/1.7.php +5 -3
  58. bp-friends/bp-friends-activity.php +100 -4
  59. bp-friends/bp-friends-cache.php +44 -0
  60. bp-friends/bp-friends-classes.php +30 -4
  61. bp-friends/bp-friends-filters.php +9 -1
  62. bp-friends/bp-friends-functions.php +8 -3
  63. bp-friends/bp-friends-loader.php +6 -3
  64. bp-friends/bp-friends-notifications.php +2 -2
  65. bp-friends/bp-friends-template.php +54 -0
  66. bp-friends/bp-friends-widgets.php +1 -1
  67. bp-groups/admin/css/admin.css +0 -1
  68. bp-groups/admin/css/admin.min.css +1 -1
  69. bp-groups/bp-groups-actions.php +31 -4
  70. bp-groups/bp-groups-activity.php +119 -4
  71. bp-groups/bp-groups-admin.php +47 -30
  72. bp-groups/bp-groups-adminbar.php +1 -1
  73. bp-groups/bp-groups-cache.php +61 -4
  74. bp-groups/bp-groups-classes.php +238 -68
  75. bp-groups/bp-groups-functions.php +269 -173
  76. bp-groups/bp-groups-loader.php +34 -10
  77. bp-groups/bp-groups-notifications.php +25 -6
  78. bp-groups/bp-groups-screens.php +49 -17
  79. bp-groups/bp-groups-template.php +702 -130
  80. bp-groups/bp-groups-widgets.php +11 -2
  81. bp-languages/buddypress.pot +1575 -997
  82. bp-loader.php +98 -92
  83. bp-members/admin/bp-members-classes.php +666 -0
  84. bp-members/admin/css/admin.css +164 -0
  85. bp-members/admin/css/admin.min.css +1 -0
  86. bp-members/admin/js/admin.js +53 -0
  87. bp-members/admin/js/admin.min.js +1 -0
  88. bp-members/bp-members-admin.php +1440 -0
  89. bp-members/bp-members-adminbar.php +11 -8
  90. bp-members/bp-members-classes.php +657 -0
  91. bp-members/bp-members-functions.php +469 -169
  92. bp-members/bp-members-loader.php +20 -4
  93. bp-members/bp-members-screens.php +8 -14
  94. bp-members/bp-members-template.php +86 -25
  95. bp-messages/bp-messages-cache.php +40 -0
  96. bp-messages/bp-messages-classes.php +368 -47
  97. bp-messages/bp-messages-cssjs.php +6 -5
  98. bp-messages/bp-messages-loader.php +11 -4
  99. bp-messages/bp-messages-notifications.php +43 -13
  100. bp-messages/bp-messages-template.php +86 -25
  101. bp-notifications/bp-notifications-buddybar.php +3 -3
  102. bp-notifications/bp-notifications-cache.php +41 -0
  103. bp-notifications/bp-notifications-classes.php +29 -6
  104. bp-notifications/bp-notifications-functions.php +37 -8
  105. bp-notifications/bp-notifications-loader.php +13 -4
  106. bp-notifications/bp-notifications-template.php +4 -4
  107. bp-settings/bp-settings-loader.php +1 -1
  108. bp-templates/bp-legacy/buddypress-functions.php +149 -47
  109. bp-templates/bp-legacy/buddypress/activity/activity-loop.php +7 -3
  110. bp-templates/bp-legacy/buddypress/activity/entry.php +2 -2
  111. bp-templates/bp-legacy/buddypress/activity/index.php +6 -6
  112. bp-templates/bp-legacy/buddypress/activity/post-form.php +3 -3
  113. bp-templates/bp-legacy/buddypress/forums/forums-loop.php +1 -1
  114. bp-templates/bp-legacy/buddypress/forums/index.php +2 -2
  115. bp-templates/bp-legacy/buddypress/groups/create.php +8 -8
  116. bp-templates/bp-legacy/buddypress/groups/single/activity.php +1 -1
  117. bp-templates/bp-legacy/buddypress/groups/single/admin.php +15 -43
  118. bp-templates/bp-legacy/buddypress/groups/single/forum.php +1 -1
  119. bp-templates/bp-legacy/buddypress/groups/single/forum/edit.php +2 -2
  120. bp-templates/bp-legacy/buddypress/groups/single/forum/topic.php +2 -2
  121. bp-templates/bp-legacy/buddypress/groups/single/home.php +5 -2
  122. bp-templates/bp-legacy/buddypress/groups/single/invites-loop.php +93 -0
  123. bp-templates/bp-legacy/buddypress/groups/single/members.php +3 -11
  124. bp-templates/bp-legacy/buddypress/groups/single/request-membership.php +1 -1
  125. bp-templates/bp-legacy/buddypress/groups/single/requests-loop.php +65 -0
  126. bp-templates/bp-legacy/buddypress/groups/single/send-invites.php +3 -60
  127. bp-templates/bp-legacy/buddypress/members/activate.php +1 -1
  128. bp-templates/bp-legacy/buddypress/members/register.php +6 -85
  129. bp-templates/bp-legacy/buddypress/members/single/friends.php +1 -1
  130. bp-templates/bp-legacy/buddypress/members/single/messages.php +3 -3
  131. bp-templates/bp-legacy/buddypress/members/single/messages/compose.php +1 -1
  132. bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php +2 -2
  133. bp-templates/bp-legacy/buddypress/members/single/messages/notices-loop.php +1 -1
  134. bp-templates/bp-legacy/buddypress/members/single/messages/single.php +2 -2
  135. bp-templates/bp-legacy/buddypress/members/single/profile/change-avatar.php +5 -5
  136. bp-templates/bp-legacy/buddypress/members/single/profile/edit.php +6 -93
  137. bp-templates/bp-legacy/buddypress/members/single/settings.php +4 -1
  138. bp-templates/bp-legacy/buddypress/members/single/settings/capabilities.php +1 -1
  139. bp-templates/bp-legacy/buddypress/members/single/settings/delete-account.php +1 -1
  140. bp-templates/bp-legacy/buddypress/members/single/settings/general.php +2 -2
  141. bp-templates/bp-legacy/buddypress/members/single/settings/notifications.php +1 -1
  142. bp-templates/bp-legacy/buddypress/members/single/settings/profile.php +49 -0
  143. bp-templates/bp-legacy/css/buddypress.css +18 -7
  144. bp-templates/bp-legacy/js/buddypress.js +271 -84
  145. bp-themes/bp-default/_inc/ajax.php +1 -1
  146. bp-themes/bp-default/_inc/css/default.css +4 -2
  147. bp-themes/bp-default/activity/activity-loop.php +7 -3
  148. bp-themes/bp-default/activity/entry.php +2 -2
  149. bp-themes/bp-default/activity/index.php +6 -6
  150. bp-themes/bp-default/activity/post-form.php +2 -2
  151. bp-themes/bp-default/archive.php +1 -1
  152. bp-themes/bp-default/attachment.php +1 -1
  153. bp-themes/bp-default/forums/forums-loop.php +1 -1
  154. bp-themes/bp-default/forums/index.php +2 -2
  155. bp-themes/bp-default/groups/create.php +8 -8
  156. bp-themes/bp-default/groups/single/activity.php +1 -1
  157. bp-themes/bp-default/groups/single/admin.php +13 -13
  158. bp-themes/bp-default/groups/single/forum.php +1 -1
  159. bp-themes/bp-default/groups/single/forum/edit.php +2 -2
  160. bp-themes/bp-default/groups/single/forum/topic.php +2 -2
  161. bp-themes/bp-default/groups/single/request-membership.php +1 -1
  162. bp-themes/bp-default/groups/single/send-invites.php +1 -1
  163. bp-themes/bp-default/header.php +2 -2
  164. bp-themes/bp-default/index.php +1 -1
  165. bp-themes/bp-default/members/single/friends.php +1 -1
  166. bp-themes/bp-default/members/single/messages/compose.php +1 -1
  167. bp-themes/bp-default/members/single/messages/messages-loop.php +2 -2
  168. bp-themes/bp-default/members/single/messages/notices-loop.php +1 -1
  169. bp-themes/bp-default/members/single/messages/single.php +2 -2
  170. bp-themes/bp-default/members/single/profile/change-avatar.php +5 -5
  171. bp-themes/bp-default/members/single/profile/edit.php +1 -1
  172. bp-themes/bp-default/members/single/settings.php +3 -2
  173. bp-themes/bp-default/members/single/settings/capabilities.php +1 -1
  174. bp-themes/bp-default/members/single/settings/delete-account.php +1 -1
  175. bp-themes/bp-default/members/single/settings/general.php +2 -2
  176. bp-themes/bp-default/members/single/settings/notifications.php +1 -1
  177. bp-themes/bp-default/members/single/settings/profile.php +108 -0
  178. bp-themes/bp-default/registration/activate.php +1 -1
  179. bp-themes/bp-default/registration/register.php +1 -1
  180. bp-themes/bp-default/rtl.css +1 -1
  181. bp-themes/bp-default/search.php +1 -1
  182. bp-themes/bp-default/searchform.php +1 -1
  183. bp-themes/bp-default/sidebar.php +1 -1
  184. bp-themes/bp-default/style.css +1 -1
  185. bp-xprofile/admin/css/admin.css +0 -1
  186. bp-xprofile/admin/css/admin.min.css +1 -1
  187. bp-xprofile/admin/js/admin.js +3 -1
  188. bp-xprofile/admin/js/admin.min.js +1 -1
  189. bp-xprofile/bp-xprofile-actions.php +63 -0
  190. bp-xprofile/bp-xprofile-activity.php +183 -4
  191. bp-xprofile/bp-xprofile-admin.php +388 -43
  192. bp-xprofile/bp-xprofile-cache.php +179 -6
  193. bp-xprofile/bp-xprofile-classes.php +1756 -208
  194. bp-xprofile/bp-xprofile-cssjs.php +2 -2
  195. bp-xprofile/bp-xprofile-filters.php +111 -15
  196. bp-xprofile/bp-xprofile-functions.php +265 -125
  197. bp-xprofile/bp-xprofile-loader.php +64 -28
  198. bp-xprofile/bp-xprofile-screens.php +33 -7
  199. bp-xprofile/bp-xprofile-settings.php +53 -0
  200. bp-xprofile/bp-xprofile-template.php +97 -279
  201. readme.txt +1 -1
.travis.yml DELETED
@@ -1,54 +0,0 @@
1
- language: php
2
-
3
- php:
4
- - 5.2
5
- - 5.3
6
- - 5.4
7
- - 5.5
8
-
9
- env:
10
- - WP_VERSION=master WP_MULTISITE=0
11
- - WP_VERSION=3.8 WP_MULTISITE=0
12
- - WP_VERSION=3.7.1 WP_MULTISITE=0
13
- - WP_VERSION=3.6.1 WP_MULTISITE=0
14
- - WP_VERSION=3.5.2 WP_MULTISITE=0
15
- - WP_VERSION=master WP_MULTISITE=1
16
- - WP_VERSION=3.8 WP_MULTISITE=1
17
- - WP_VERSION=3.7.1 WP_MULTISITE=1
18
- - WP_VERSION=3.6.1 WP_MULTISITE=1
19
- - WP_VERSION=3.5.2 WP_MULTISITE=1
20
-
21
- before_script:
22
- # set up WP install
23
- - WP_CORE_DIR=/tmp/wordpress/
24
- - wget -nv -O /tmp/wordpress.tar.gz https://github.com/WordPress/WordPress/tarball/$WP_VERSION
25
- - mkdir -p $WP_CORE_DIR
26
- - tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
27
- - plugin_slug=$(basename $(pwd))
28
- - plugin_dir=$WP_CORE_DIR/wp-content/plugins/$plugin_slug
29
- - cd ..
30
- - mv $plugin_slug $plugin_dir
31
- # set up testing suite
32
- - export WP_TESTS_DIR=/tmp/wordpress-tests/
33
- - svn co --ignore-externals http://unit-tests.svn.wordpress.org/trunk/ $WP_TESTS_DIR
34
- - cd $WP_TESTS_DIR
35
- - cp wp-tests-config-sample.php wp-tests-config.php
36
- - sed -i "s:dirname( __FILE__ ) . '/wordpress/':'$WP_CORE_DIR':" wp-tests-config.php
37
- - sed -i "s/yourdbnamehere/wordpress_test/" wp-tests-config.php
38
- - sed -i "s/yourusernamehere/root/" wp-tests-config.php
39
- - sed -i "s/yourpasswordhere//" wp-tests-config.php
40
- # set up database
41
- - mysql -e 'CREATE DATABASE wordpress_test;' -uroot
42
- # prepare for running the tests
43
- - cd $plugin_dir/tests
44
-
45
- script: phpunit
46
-
47
- notifications:
48
- email: false
49
-
50
- irc:
51
- channels:
52
- - "irc.freenode.net#buddypress-dev"
53
- template:
54
- - "Build %{build_number} (%{branch} - %{commit}): %{message} %{build_url}"
bp-activity/admin/css/admin.css CHANGED
@@ -74,4 +74,7 @@
74
}
75
#bp-activities-primaryid {
76
margin-bottom: 1em;
77
}
74
}
75
#bp-activities-primaryid {
76
margin-bottom: 1em;
77
+ }
78
+ .column-action {
79
+ width: 12%;
80
}
bp-activity/admin/css/admin.min.css CHANGED
@@ -1 +1 @@
1
- .akismet-status{float:right}.akismet-status a{color:#AAA;font-style:italic}.akismet-history{margin:13px}.akismet-history div{margin-bottom:13px}.akismet-history span{color:#999}#wp-bp-activities-wrap{padding:5px 0}#bp-activities{height:120px}#bp-replyhead{font-size:1em;line-height:1.4em;margin:0}#bp-replysubmit{margin:0;padding:0 0 3px;text-align:center}#bp-replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center}#bp-replysubmit img.waiting{float:right;padding:4px 10px 0;vertical-align:top}#bp-activities-form .column-response img{float:left;margin-right:10px;margin-top:1px}.activity-errors{list-style-type:disc;margin-left:2em}#bp_activity_action div.inside,#bp_activity_content div.inside{line-height:0}#bp_activity_action h3,#bp_activity_content h3{cursor:auto}#bp_activity_action td.mceIframeContainer,#bp_activity_content td.mceIframeContainer{background-color:white}#post-body #bp-activities-action_resize,#post-body #bp-activities-content_resize{position:inherit;margin-top:-2px}#bp_activity_link input{width:99%}#bp-activities-primaryid{margin-bottom:1em}
1
+ .akismet-status{float:right}.akismet-status a{color:#AAA;font-style:italic}.akismet-history{margin:13px}.akismet-history div{margin-bottom:13px}.akismet-history span{color:#999}#wp-bp-activities-wrap{padding:5px 0}#bp-activities{height:120px}#bp-replyhead{font-size:1em;line-height:1.4em;margin:0}#bp-replysubmit{margin:0;padding:0 0 3px;text-align:center}#bp-replysubmit .error{color:red;line-height:21px;text-align:center;vertical-align:center}#bp-replysubmit img.waiting{float:right;padding:4px 10px 0;vertical-align:top}#bp-activities-form .column-response img{float:left;margin-right:10px;margin-top:1px}.activity-errors{list-style-type:disc;margin-left:2em}#bp_activity_action div.inside,#bp_activity_content div.inside{line-height:0}#bp_activity_action h3,#bp_activity_content h3{cursor:auto}#bp_activity_action td.mceIframeContainer,#bp_activity_content td.mceIframeContainer{background-color:white}#post-body #bp-activities-action_resize,#post-body #bp-activities-content_resize{position:inherit;margin-top:-2px}#bp_activity_link input{width:99%}#bp-activities-primaryid{margin-bottom:1em}.column-action{width:12%;}
bp-activity/admin/js/admin.js CHANGED
@@ -162,6 +162,11 @@ $(document).ready( function () {
162
163
// On the edit screen, unload the close/open toggle js for the action & content metaboxes
164
$( '#bp_activity_action h3, #bp_activity_content h3' ).unbind( 'click' );
165
});
166
167
})(jQuery);
162
163
// On the edit screen, unload the close/open toggle js for the action & content metaboxes
164
$( '#bp_activity_action h3, #bp_activity_content h3' ).unbind( 'click' );
165
+
166
+ // redo the post box toggles to reset the one made by comment.js in favor
167
+ // of activity administration page id so that metaboxes are still collapsible
168
+ // in single Activity Administration screen.
169
+ postboxes.add_postbox_toggles( bp_activity_admin_vars.page );
170
});
171
172
})(jQuery);
bp-activity/admin/js/admin.min.js CHANGED
@@ -1 +1 @@
1
- (function(b){var a={init:function(){b(document).on("click",".row-actions a.reply",a.open);b(document).on("click","#bp-activities-container a.cancel",a.close);b(document).on("click","#bp-activities-container a.save",a.send);b(document).on("keyup","#bp-activities:visible",function(c){if(27==c.which){a.close()}})},open:function(d){var c=b("#bp-activities-container").hide();b(this).parents("tr").after(c);c.fadeIn("300");b("#bp-activities").focus();return false},close:function(c){b("#bp-activities-container").fadeOut("200",function(){b("#bp-activities").val("").blur();b("#bp-replysubmit .error").html("").hide();b("#bp-replysubmit .waiting").hide()});return false},send:function(d){b("#bp-replysubmit .error").hide();b("#bp-replysubmit .waiting").show();var c={};c["_ajax_nonce-bp-activity-admin-reply"]=b('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val();c.action="bp-activity-admin-reply";c.content=b("#bp-activities").val();c.parent_id=b("#bp-activities-container").prev().data("parent_id");c.root_id=b("#bp-activities-container").prev().data("root_id");b.ajax({data:c,type:"POST",url:ajaxurl,error:function(e){a.error(e)},success:function(e){a.show(e)}});return false},error:function(c){var d=c.statusText;b("#bp-replysubmit .waiting").hide();if(c.responseText){d=c.responseText.replace(/<.[^<>]*?>/g,"")}if(d){b("#bp-replysubmit .error").html(d).show()}},show:function(d){var e,f,c;if(typeof(d)=="string"){a.error({responseText:d});return false}c=wpAjax.parseAjaxResponse(d);if(c.errors){a.error({responseText:wpAjax.broken});return false}c=c.responses[0];b("#bp-activities-container").fadeOut("200",function(){b("#bp-activities").val("").blur();b("#bp-replysubmit .error").html("").hide();b("#bp-replysubmit .waiting").hide();b("#bp-activities-container").before(c.data);f=b("#activity-"+c.id);e=f.closest(".widefat").css("backgroundColor");f.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:e},300)})}};b(document).ready(function(){a.init();b("#bp_activity_action h3, #bp_activity_content h3").unbind("click")})})(jQuery);
1
+ (function(e){var t={init:function(){e(document).on("click",".row-actions a.reply",t.open);e(document).on("click","#bp-activities-container a.cancel",t.close);e(document).on("click","#bp-activities-container a.save",t.send);e(document).on("keyup","#bp-activities:visible",function(e){if(27==e.which){t.close()}})},open:function(t){var n=e("#bp-activities-container").hide();e(this).parents("tr").after(n);n.fadeIn("300");e("#bp-activities").focus();return false},close:function(t){e("#bp-activities-container").fadeOut("200",function(){e("#bp-activities").val("").blur();e("#bp-replysubmit .error").html("").hide();e("#bp-replysubmit .waiting").hide()});return false},send:function(n){e("#bp-replysubmit .error").hide();e("#bp-replysubmit .waiting").show();var r={};r["_ajax_nonce-bp-activity-admin-reply"]=e('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val();r.action="bp-activity-admin-reply";r.content=e("#bp-activities").val();r.parent_id=e("#bp-activities-container").prev().data("parent_id");r.root_id=e("#bp-activities-container").prev().data("root_id");e.ajax({data:r,type:"POST",url:ajaxurl,error:function(e){t.error(e)},success:function(e){t.show(e)}});return false},error:function(t){var n=t.statusText;e("#bp-replysubmit .waiting").hide();if(t.responseText){n=t.responseText.replace(/<.[^<>]*?>/g,"")}if(n){e("#bp-replysubmit .error").html(n).show()}},show:function(n){var r,i,s;if(typeof n=="string"){t.error({responseText:n});return false}s=wpAjax.parseAjaxResponse(n);if(s.errors){t.error({responseText:wpAjax.broken});return false}s=s.responses[0];e("#bp-activities-container").fadeOut("200",function(){e("#bp-activities").val("").blur();e("#bp-replysubmit .error").html("").hide();e("#bp-replysubmit .waiting").hide();e("#bp-activities-container").before(s.data);i=e("#activity-"+s.id);r=i.closest(".widefat").css("backgroundColor");i.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:r},300)})}};e(document).ready(function(){t.init();e("#bp_activity_action h3, #bp_activity_content h3").unbind("click");postboxes.add_postbox_toggles(bp_activity_admin_vars.page)})})(jQuery)
bp-activity/bp-activity-admin.php CHANGED
@@ -189,7 +189,9 @@ add_filter( 'default_hidden_meta_boxes', 'bp_activity_admin_edit_hidden_metaboxe
189
* @global BP_Activity_List_Table $bp_activity_list_table Activity screen list table.
190
*/
191
function bp_activity_admin_load() {
192
- global $bp, $bp_activity_list_table;
193
194
// Decide whether to load the dev version of the CSS and JavaScript
195
$min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : 'min.';
@@ -276,8 +278,11 @@ function bp_activity_admin_load() {
276
}
277
278
// Enqueue CSS and JavaScript
279
- wp_enqueue_script( 'bp_activity_admin_js', BP_PLUGIN_URL . "bp-activity/admin/js/admin.{$min}js", array( 'jquery', 'wp-ajax-response' ), bp_get_version(), true );
280
- wp_enqueue_style( 'bp_activity_admin_css', BP_PLUGIN_URL . "bp-activity/admin/css/admin.{$min}css", array(), bp_get_version() );
281
282
// Handle spam/un-spam/delete of activities
283
if ( !empty( $doaction ) && ! in_array( $doaction, array( '-1', 'edit', 'save', ) ) ) {
@@ -453,22 +458,12 @@ function bp_activity_admin_load() {
453
454
// Activity type
455
if ( ! empty( $_POST['bp-activities-type'] ) ) {
456
- $actions = array();
457
-
458
- // Walk through the registered actions, and build an array of actions/values.
459
- foreach ( $bp->activity->actions as $action ) {
460
- $action = array_values( (array) $action );
461
-
462
- for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ )
463
- $actions[] = $action[$i]['key'];
464
- }
465
-
466
- // This was a mis-named activity type from before BP 1.6
467
- unset( $actions['friends_register_activity_action'] );
468
469
// Check that the new type is a registered activity type
470
- if ( in_array( $_POST['bp-activities-type'], $actions ) )
471
$activity->type = $_POST['bp-activities-type'];
472
}
473
474
// Activity timestamp
@@ -730,6 +725,36 @@ function bp_activity_admin_edit_metabox_userid( $item ) {
730
<?php
731
}
732
733
/**
734
* Activity type metabox for the Activity admin edit screen
735
*
@@ -757,7 +782,17 @@ function bp_activity_admin_edit_metabox_type( $item ) {
757
unset( $actions['friends_register_activity_action'] );
758
759
// Sort array by the human-readable value
760
- natsort( $actions ); ?>
761
762
<select name="bp-activities-type">
763
<?php foreach ( $actions as $k => $v ) : ?>
@@ -959,6 +994,9 @@ class BP_Activity_List_Table extends WP_List_Table {
959
*/
960
public function __construct() {
961
962
// Define singular and plural labels, as well as whether we support AJAX.
963
parent::__construct( array(
964
'ajax' => false,
@@ -1202,6 +1240,7 @@ class BP_Activity_List_Table extends WP_List_Table {
1202
'cb' => '<input name type="checkbox" />',
1203
'author' => __( 'Author', 'buddypress' ),
1204
'comment' => __( 'Activity', 'buddypress' ),
1205
'response' => __( 'In Response To', 'buddypress' ),
1206
);
1207
}
@@ -1284,6 +1323,25 @@ class BP_Activity_List_Table extends WP_List_Table {
1284
echo '<strong>' . get_avatar( $item['user_id'], '32' ) . ' ' . bp_core_get_userlink( $item['user_id'] ) . '</strong>';
1285
}
1286
1287
/**
1288
* Content column, and "quick admin" rollover actions.
1289
*
@@ -1323,7 +1381,11 @@ class BP_Activity_List_Table extends WP_List_Table {
1323
1324
// Reply - javascript only; implemented by AJAX.
1325
if ( 'spam' != $item_status ) {
1326
- $actions['reply'] = sprintf( '<a href="#" class="reply hide-if-no-js">%s</a>', __( 'Reply', 'buddypress' ) );
1327
1328
// Edit
1329
$actions['edit'] = sprintf( '<a href="%s">%s</a>', $edit_url, __( 'Edit', 'buddypress' ) );
@@ -1429,6 +1491,65 @@ class BP_Activity_List_Table extends WP_List_Table {
1429
}
1430
}
1431
1432
/**
1433
* Flatten the activity array.
1434
*
189
* @global BP_Activity_List_Table $bp_activity_list_table Activity screen list table.
190
*/
191
function bp_activity_admin_load() {
192
+ global $bp_activity_list_table;
193
+
194
+ $bp = buddypress();
195
196
// Decide whether to load the dev version of the CSS and JavaScript
197
$min = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : 'min.';
278
}
279
280
// Enqueue CSS and JavaScript
281
+ wp_enqueue_script( 'bp_activity_admin_js', $bp->plugin_url . "bp-activity/admin/js/admin.{$min}js", array( 'jquery', 'wp-ajax-response' ), bp_get_version(), true );
282
+ wp_localize_script( 'bp_activity_admin_js', 'bp_activity_admin_vars', array(
283
+ 'page' => get_current_screen()->id
284
+ ) );
285
+ wp_enqueue_style( 'bp_activity_admin_css', $bp->plugin_url . "bp-activity/admin/css/admin.{$min}css", array(), bp_get_version() );
286
287
// Handle spam/un-spam/delete of activities
288
if ( !empty( $doaction ) && ! in_array( $doaction, array( '-1', 'edit', 'save', ) ) ) {
458
459
// Activity type
460
if ( ! empty( $_POST['bp-activities-type'] ) ) {
461
+ $actions = bp_activity_admin_get_activity_actions();
462
463
// Check that the new type is a registered activity type
464
+ if ( in_array( $_POST['bp-activities-type'], $actions ) ) {
465
$activity->type = $_POST['bp-activities-type'];
466
+ }
467
}
468
469
// Activity timestamp
725
<?php
726
}
727
728
+ /**
729
+ * Get flattened array of all registered activity actions.
730
+ *
731
+ * Format is [activity_type] => Pretty name for activity type.
732
+ *
733
+ * @since BuddyPress (2.0.0)
734
+ *
735
+ * @return array
736
+ */
737
+ function bp_activity_admin_get_activity_actions() {
738
+ $actions = array();
739
+
740
+ // Walk through the registered actions, and build an array of actions/values.
741
+ foreach ( buddypress()->activity->actions as $action ) {
742
+ $action = array_values( (array) $action );
743
+
744
+ for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
745
+ $actions[ $action[$i]['key'] ] = $action[$i]['value'];
746
+ }
747
+ }
748
+
749
+ // This was a mis-named activity type from before BP 1.6
750
+ unset( $actions['friends_register_activity_action'] );
751
+
752
+ // Sort array by the human-readable value
753
+ natsort( $actions );
754
+
755
+ return $actions;
756
+ }
757
+
758
/**
759
* Activity type metabox for the Activity admin edit screen
760
*
782
unset( $actions['friends_register_activity_action'] );
783
784
// Sort array by the human-readable value
785
+ natsort( $actions );
786
+
787
+ // If the activity type is not registered properly (eg, a plugin has
788
+ // not called bp_activity_set_action()), add the raw type to the end
789
+ // of the list
790
+ if ( ! isset( $actions[ $selected ] ) ) {
791
+ _doing_it_wrong( __FUNCTION__, sprintf( __( 'This activity item has a type (%s) that is not registered using bp_activity_set_action(), so no label is available.', 'buddypress' ), $selected ), '2.0.0' );
792
+ $actions[ $selected ] = $selected;
793
+ }
794
+
795
+ ?>
796
797
<select name="bp-activities-type">
798
<?php foreach ( $actions as $k => $v ) : ?>
994
*/
995
public function __construct() {
996
997
+ // See if activity commenting is enabled for blog / forum activity items
998
+ $this->disable_blogforum_comments = bp_disable_blogforum_comments();
999
+
1000
// Define singular and plural labels, as well as whether we support AJAX.
1001
parent::__construct( array(
1002
'ajax' => false,
1240
'cb' => '<input name type="checkbox" />',
1241
'author' => __( 'Author', 'buddypress' ),
1242
'comment' => __( 'Activity', 'buddypress' ),
1243
+ 'action' => __( 'Action', 'buddypress' ),
1244
'response' => __( 'In Response To', 'buddypress' ),
1245
);
1246
}
1323
echo '<strong>' . get_avatar( $item['user_id'], '32' ) . ' ' . bp_core_get_userlink( $item['user_id'] ) . '</strong>';
1324
}
1325
1326
+ /**
1327
+ * Action column markup.
1328
+ *
1329
+ * @since BuddyPress (2.0.0)
1330
+ *
1331
+ * @see WP_List_Table::single_row_columns()
1332
+ *
1333
+ * @param array $item A singular item (one full row).
1334
+ */
1335
+ function column_action( $item ) {
1336
+ $actions = bp_activity_admin_get_activity_actions();
1337
+
1338
+ if ( isset( $actions[ $item['type'] ] ) ) {
1339
+ echo $actions[ $item['type'] ];
1340
+ } else {
1341
+ printf( __( 'Unregistered action - %s', 'buddypress' ), $item['type'] );
1342
+ }
1343
+ }
1344
+
1345
/**
1346
* Content column, and "quick admin" rollover actions.
1347
*
1381
1382
// Reply - javascript only; implemented by AJAX.
1383
if ( 'spam' != $item_status ) {
1384
+ if ( $this->can_comment( $item ) ) {
1385
+ $actions['reply'] = sprintf( '<a href="#" class="reply hide-if-no-js">%s</a>', __( 'Reply', 'buddypress' ) );
1386
+ } else {
1387
+ $actions['reply'] = sprintf( '<span class="form-input-tip" title="%s">%s</span>', __( 'Replies are disabled for this activity item', 'buddypress' ), __( 'Replies disabled', 'buddypress' ) );
1388
+ }
1389
1390
// Edit
1391
$actions['edit'] = sprintf( '<a href="%s">%s</a>', $edit_url, __( 'Edit', 'buddypress' ) );
1491
}
1492
}
1493
1494
+ /**
1495
+ * Checks if an activity item can be replied to.
1496
+ *
1497
+ * This method merges functionality from {@link bp_activity_can_comment()} and
1498
+ * {@link bp_blogs_disable_activity_commenting()}. This is done because the activity
1499
+ * list table doesn't use a BuddyPress activity loop, which prevents those
1500
+ * functions from working as intended.
1501
+ *
1502
+ * @since BuddyPress (2.0.0)
1503
+ *
1504
+ * @param array $item An array version of the BP_Activity_Activity object.
1505
+ * @return bool
1506
+ */
1507
+ protected function can_comment( $item ) {
1508
+ $can_comment = true;
1509
+
1510
+ if ( $this->disable_blogforum_comments ) {
1511
+ switch ( $item['type'] ) {
1512
+ case 'new_blog_post' :
1513
+ case 'new_blog_comment' :
1514
+ case 'new_forum_topic' :
1515
+ case 'new_forum_post' :
1516
+ $can_comment = false;
1517
+ break;
1518
+ }
1519
+
1520
+ // activity comments supported
1521
+ } else {
1522
+ // activity comment
1523
+ if ( 'activity_comment' == $item['type'] ) {
1524
+ // blogs
1525
+ if ( bp_is_active( 'blogs' ) ) {
1526
+ // grab the parent activity entry
1527
+ $parent_activity = new BP_Activity_Activity( $item['item_id'] );
1528
+
1529
+ // fetch blog post comment depth and if the blog post's comments are open
1530
+ bp_blogs_setup_activity_loop_globals( $parent_activity );
1531
+
1532
+ // check if the activity item can be replied to
1533
+ if ( false === bp_blogs_can_comment_reply( true, $item ) ) {
1534
+ $can_comment = false;
1535
+ }
1536
+ }
1537
+
1538
+ // blog post
1539
+ } elseif ( 'new_blog_post' == $item['type'] ) {
1540
+ if ( bp_is_active( 'blogs' ) ) {
1541
+ bp_blogs_setup_activity_loop_globals( (object) $item );
1542
+
1543
+ if ( empty( buddypress()->blogs->allow_comments[$item['id']] ) ) {
1544
+ $can_comment = false;
1545
+ }
1546
+ }
1547
+ }
1548
+ }
1549
+
1550
+ return apply_filters( 'bp_activity_list_table_can_comment', $can_comment );
1551
+ }
1552
+
1553
/**
1554
* Flatten the activity array.
1555
*
bp-activity/bp-activity-cache.php CHANGED
@@ -12,16 +12,12 @@ if ( !defined( 'ABSPATH' ) ) exit;
12
/**
13
* Slurp up activitymeta for a specified set of activity items.
14
*
15
- * This function is called in two places in the BP_Activity_Activity class:
16
- * - in the populate() method, when single activity objects are populated
17
- * - in the get() method, when multiple groups are queried
18
- *
19
* It grabs all activitymeta associated with all of the activity items passed
20
* in $activity_ids and adds it to the WP cache. This improves efficiency when
21
* using querying activitymeta inline.
22
*
23
* @param int|str|array $activity_ids Accepts a single activity ID, or a comma-
24
- * separated list or array of activity ids
25
*/
26
function bp_activity_update_meta_cache( $activity_ids = false ) {
27
global $bp;
@@ -30,6 +26,7 @@ function bp_activity_update_meta_cache( $activity_ids = false ) {
30
'object_ids' => $activity_ids,
31
'object_type' => $bp->activity->id,
32
'object_column' => 'activity_id',
33
'meta_table' => $bp->activity->table_name_meta,
34
'cache_key_prefix' => 'bp_activity_meta'
35
);
@@ -38,18 +35,27 @@ function bp_activity_update_meta_cache( $activity_ids = false ) {
38
}
39
40
/**
41
- * Clear the cache for all metadata of a given activity.
42
*
43
- * @param int $activity_id
44
*/
45
- function bp_activity_clear_meta_cache_for_activity( $activity_id ) {
46
- global $wp_object_cache;
47
48
- if ( is_object( $wp_object_cache ) && ! empty( $wp_object_cache->cache['bp'] ) ) {
49
- foreach ( $wp_object_cache->cache['bp'] as $ckey => $cvalue ) {
50
- if ( 0 === strpos( $ckey, 'bp_activity_meta_' . $activity_id ) ) {
51
- wp_cache_delete( $ckey, 'bp' );
52
- }
53
- }
54
}
55
}
12
/**
13
* Slurp up activitymeta for a specified set of activity items.
14
*
15
* It grabs all activitymeta associated with all of the activity items passed
16
* in $activity_ids and adds it to the WP cache. This improves efficiency when
17
* using querying activitymeta inline.
18
*
19
* @param int|str|array $activity_ids Accepts a single activity ID, or a comma-
20
+ * separated list or array of activity ids
21
*/
22
function bp_activity_update_meta_cache( $activity_ids = false ) {
23
global $bp;
26
'object_ids' => $activity_ids,
27
'object_type' => $bp->activity->id,
28
'object_column' => 'activity_id',
29
+ 'cache_group' => 'activity_meta',
30
'meta_table' => $bp->activity->table_name_meta,
31
'cache_key_prefix' => 'bp_activity_meta'
32
);
35
}
36
37
/**
38
+ * Clear a cached activity item when that item is updated.
39
+ *
40
+ * @since 2.0
41
*
42
+ * @param BP_Activity_Activity $activity
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
49
+ /**
50
+ * Clear cached data for deleted activity items.
51
+ *
52
+ * @since 2.0
53
+ *
54
+ * @param array $deleted_ids IDs of deleted activity items.
55
+ */
56
+ function bp_activity_clear_cache_for_deleted_activity( $deleted_ids ) {
57
+ foreach ( (array) $deleted_ids as $deleted_id ) {
58
+ wp_cache_delete( $deleted_id, 'bp_activity' );
59
}
60
}
61
+ add_action( 'bp_activity_deleted_activities', 'bp_activity_clear_cache_for_deleted_activity' );
bp-activity/bp-activity-classes.php CHANGED
@@ -137,7 +137,15 @@ class BP_Activity_Activity {
137
public function populate() {
138
global $wpdb, $bp;
139
140
- if ( $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name} WHERE id = %d", $this->id ) ) ) {
141
$this->id = $row->id;
142
$this->item_id = $row->item_id;
143
$this->secondary_item_id = $row->secondary_item_id;
@@ -152,8 +160,21 @@ class BP_Activity_Activity {
152
$this->mptt_left = $row->mptt_left;
153
$this->mptt_right = $row->mptt_right;
154
$this->is_spam = $row->is_spam;
155
156
- bp_activity_update_meta_cache( $this->id );
157
}
158
}
159
@@ -244,6 +265,8 @@ class BP_Activity_Activity {
244
* @type bool $show_hidden Whether to show items marked hide_sitewide.
245
* Default: false.
246
* @type string $spam Spam status. Default: 'ham_only'.
247
* }
248
* @return array The array returned has two keys:
249
* - 'total' is the count of located activities
@@ -275,28 +298,29 @@ class BP_Activity_Activity {
275
}
276
277
$defaults = array(
278
- 'page' => 1, // The current page
279
- 'per_page' => 25, // Activity items per page
280
- 'max' => false, // Max number of items to return
281
- 'sort' => 'DESC', // ASC or DESC
282
- 'exclude' => false, // Array of ids to exclude
283
- 'in' => false, // Array of ids to limit query by (IN)
284
- 'meta_query' => false, // Filter by activitymeta
285
- 'filter' => false, // See self::get_filter_sql()
286
- 'search_terms' => false, // Terms to search by
287
- 'display_comments' => false, // Whether to include activity comments
288
- 'show_hidden' => false, // Show items marked hide_sitewide
289
- 'spam' => 'ham_only', // Spam status
290
);
291
$r = wp_parse_args( $args, $defaults );
292
extract( $r );
293
294
// Select conditions
295
- $select_sql = "SELECT DISTINCT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name";
296
297
- $from_sql = " FROM {$bp->activity->table_name} a LEFT JOIN {$wpdb->users} u ON a.user_id = u.ID";
298
299
- $join_sql = '';
300
301
// Where conditions
302
$where_conditions = array();
@@ -355,6 +379,12 @@ class BP_Activity_Activity {
355
$where_conditions[] = "a.type != 'activity_comment'";
356
}
357
358
// Filter the where conditions
359
$where_conditions = apply_filters( 'bp_activity_get_where_conditions', $where_conditions, $r, $select_sql, $from_sql, $join_sql );
360
@@ -377,56 +407,64 @@ class BP_Activity_Activity {
377
$index_hint_sql = '';
378
}
379
380
- if ( !empty( $per_page ) && !empty( $page ) ) {
381
382
- // Make sure page values are absolute integers
383
- $page = absint( $page );
384
- $per_page = absint( $per_page );
385
386
- $pag_sql = $wpdb->prepare( "LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page );
387
- $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 ) );
388
- } else {
389
- $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 ) );
390
- }
391
392
- $total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$index_hint_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}", $where_sql, $sort );
393
394
- $total_activities = $wpdb->get_var( $total_activities_sql );
395
396
- // Get the fullnames of users so we don't have to query in the loop
397
- if ( bp_is_active( 'xprofile' ) && !empty( $activities ) ) {
398
- $activity_user_ids = wp_list_pluck( $activities, 'user_id' );
399
- $activity_user_ids = implode( ',', wp_parse_id_list( $activity_user_ids ) );
400
401
- if ( !empty( $activity_user_ids ) ) {
402
- if ( $names = $wpdb->get_results( "SELECT user_id, value AS user_fullname FROM {$bp->profile->table_name_data} WHERE field_id = 1 AND user_id IN ({$activity_user_ids})" ) ) {
403
- foreach ( (array) $names as $name )
404
- $tmp_names[$name->user_id] = $name->user_fullname;
405
406
- foreach ( (array) $activities as $i => $activity ) {
407
- if ( !empty( $tmp_names[$activity->user_id] ) )
408
- $activities[$i]->user_fullname = $tmp_names[$activity->user_id];
409
- }
410
411
- unset( $names );
412
- unset( $tmp_names );
413
- }
414
- }
415
}
416
417
// Get activity meta
418
$activity_ids = array();
419
foreach ( (array) $activities as $activity ) {
420
$activity_ids[] = $activity->id;
421
}
422
423
- if ( !empty( $activity_ids ) ) {
424
bp_activity_update_meta_cache( $activity_ids );
425
}
426
427
if ( $activities && $display_comments )
428
$activities = BP_Activity_Activity::append_comments( $activities, $spam );
429
430
// If $max is set, only return up to the max results
431
if ( !empty( $max ) ) {
432
if ( (int) $total_activities > (int) $max )
@@ -436,6 +474,148 @@ class BP_Activity_Activity {
436
return array( 'activities' => $activities, 'total' => (int) $total_activities );
437
}
438
439
/**
440
* Get the SQL for the 'meta_query' param in BP_Activity_Activity::get().
441
*
@@ -701,15 +881,13 @@ class BP_Activity_Activity {
701
* @return bool True on success.
702
*/
703
public static function delete_activity_meta_entries( $activity_ids = array() ) {
704
- global $bp, $wpdb;
705
706
- $activity_ids = implode( ',', wp_parse_id_list( $activity_ids ) );
707
-
708
- foreach ( (array) $activity_ids as $activity_id ) {
709
- bp_activity_clear_meta_cache_for_activity( $activity_id );
710
}
711
712
- return $wpdb->query( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id IN ({$activity_ids})" );
713
}
714
715
/**
@@ -727,15 +905,17 @@ class BP_Activity_Activity {
727
$activity_comments = array();
728
729
// Now fetch the activity comments and parse them into the correct position in the activities array.
730
- foreach( (array) $activities as $activity ) {
731
$top_level_parent_id = 'activity_comment' == $activity->type ? $activity->item_id : 0;
732
$activity_comments[$activity->id] = BP_Activity_Activity::get_activity_comments( $activity->id, $activity->mptt_left, $activity->mptt_right, $spam, $top_level_parent_id );
733
}
734
735
// Merge the comments with the activity items
736
- foreach( (array) $activities as $key => $activity )
737
- if ( isset( $activity_comments[$activity->id] ) )
738
$activities[$key]->children = $activity_comments[$activity->id];
739
740
return $activities;
741
}
@@ -762,7 +942,15 @@ class BP_Activity_Activity {
762
$top_level_parent_id = $activity_id;
763
}
764
765
- if ( !$comments = wp_cache_get( 'bp_activity_comments_' . $activity_id ) ) {
766
767
// Select the user's fullname with the query
768
if ( bp_is_active( 'xprofile' ) ) {
@@ -784,12 +972,24 @@ class BP_Activity_Activity {
784
$spam_sql = '';
785
}
786
787
- // The mptt BETWEEN clause allows us to limit returned descendants to the right part of the tree
788
- $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 );
789
790
- // Retrieve all descendants of the $root node
791
- $descendants = $wpdb->get_results( $sql );
792
- $ref = array();
793
794
// Loop descendants and build an assoc array
795
foreach ( (array) $descendants as $d ) {
@@ -806,7 +1006,29 @@ class BP_Activity_Activity {
806
$ref[ $d->id ] =& $comments[ $d->id ];
807
}
808
}
809
- wp_cache_set( 'bp_activity_comments_' . $activity_id, $comments, 'bp' );
810
}
811
812
return $comments;
@@ -910,13 +1132,15 @@ class BP_Activity_Activity {
910
global $wpdb;
911
912
// split items at the comma
913
- $items_dirty = explode( ',', $items );
914
915
// array of prepared integers or quoted strings
916
$items_prepared = array();
917
918
// clean up and format each item
919
- foreach ( $items_dirty as $item ) {
920
// clean up the string
921
$item = trim( $item );
922
// pass everything through prepare for security and to safely quote strings
@@ -933,21 +1157,21 @@ class BP_Activity_Activity {
933
/**
934
* Create filter SQL clauses.
935
*
936
- * @since BuddyPress (1.5)
937
*
938
- * @param array $filter_array Fields and values to filter by. Should be
939
- * in the format:
940
- * $filter_array = array(
941
- * 'filter1' => $value,
942
- * 'filter2' => $value,
943
- * )
944
- * Possible filters are as follows. Each can be either a single
945
* string, a comma-separated list, or an array of values.
946
- * - 'user_id' User ID(s)
947
- * - 'object' Corresponds to the 'component' column in the database.
948
- * - 'action' Corresponds to the 'type' column in the database.
949
- * - 'primary_id' Corresponds to the 'item_id' column in the database.
950
- * - 'secondary_id' Corresponds to the 'secondary_item_id' column in the database.
951
* @return string The filter clause, for use in a SQL query.
952
*/
953
public static function get_filter_sql( $filter_array ) {
@@ -968,7 +1192,7 @@ class BP_Activity_Activity {
968
969
if ( !empty( $filter_array['action'] ) ) {
970
$action_sql = BP_Activity_Activity::get_in_operator_sql( 'a.type', $filter_array['action'] );
971
- if ( !empty( $action_sql ) )
972
$filter_sql[] = $action_sql;
973
}
974
@@ -984,6 +1208,11 @@ class BP_Activity_Activity {
984
$filter_sql[] = $sid_sql;
985
}
986
987
if ( empty( $filter_sql ) )
988
return false;
989
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' );
146
+ }
147
+
148
+ if ( ! empty( $row ) ) {
149
$this->id = $row->id;
150
$this->item_id = $row->item_id;
151
$this->secondary_item_id = $row->secondary_item_id;
160
$this->mptt_left = $row->mptt_left;
161
$this->mptt_right = $row->mptt_right;
162
$this->is_spam = $row->is_spam;
163
+ }
164
+
165
+ // Generate dynamic 'action' when possible
166
+ $action = bp_activity_generate_action_string( $this );
167
+ if ( false !== $action ) {
168
+ $this->action = $action;
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
176
+ } else {
177
+ $this->action = '';
178
}
179
}
180
265
* @type bool $show_hidden Whether to show items marked hide_sitewide.
266
* Default: false.
267
* @type string $spam Spam status. Default: 'ham_only'.
268
+ * @type bool $update_meta_cache Whether to pre-fetch metadata for
269
+ * queried activity items. Default: true.
270
* }
271
* @return array The array returned has two keys:
272
* - 'total' is the count of located activities
298
}
299
300
$defaults = array(
301
+ 'page' => 1, // The current page
302
+ 'per_page' => 25, // Activity items per page
303
+ 'max' => false, // Max number of items to return
304
+ 'sort' => 'DESC', // ASC or DESC
305
+ 'exclude' => false, // Array of ids to exclude
306
+ 'in' => false, // Array of ids to limit query by (IN)
307
+ 'meta_query' => false, // Filter by activitymeta
308
+ 'filter' => false, // See self::get_filter_sql()
309
+ 'search_terms' => false, // Terms to search by
310
+ 'display_comments' => false, // Whether to include activity comments
311
+ 'show_hidden' => false, // Show items marked hide_sitewide
312
+ 'spam' => 'ham_only', // Spam status
313
+ 'update_meta_cache' => true,
314
);
315
$r = wp_parse_args( $args, $defaults );
316
extract( $r );
317
318
// Select conditions
319
+ $select_sql = "SELECT DISTINCT a.id";
320
321
+ $from_sql = " FROM {$bp->activity->table_name} a";
322
323
+ $join_sql = '';
324
325
// Where conditions
326
$where_conditions = array();
379
$where_conditions[] = "a.type != 'activity_comment'";
380
}
381
382
+ // Exclude 'last_activity' items unless the 'action' filter has
383
+ // been explicitly set
384
+ if ( empty( $filter['object'] ) ) {
385
+ $where_conditions[] = "a.type != 'last_activity'";
386
+ }
387
+
388
// Filter the where conditions
389
$where_conditions = apply_filters( 'bp_activity_get_where_conditions', $where_conditions, $r, $select_sql, $from_sql, $join_sql );
390
407
$index_hint_sql = '';
408
}
409
410
+ // Sanitize page and per_page parameters
411
+ $page = absint( $page );
412
+ $per_page = absint( $per_page );
413
414
+ // Filter and return true to use the legacy query structure (not recommended)
415
+ if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $r ) ) {
416
417
+ // Legacy queries joined against the user table
418
+ $select_sql = "SELECT DISTINCT a.*, u.user_email, u.user_nicename, u.user_login, u.display_name";
419
+ $from_sql = " FROM {$bp->activity->table_name} a LEFT JOIN {$wpdb->users} u ON a.user_id = u.ID";
420
421
+ if ( ! empty( $page ) && ! empty( $per_page ) ) {
422
+ $pag_sql = $wpdb->prepare( "LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page );
423
+ $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 ) );
424
+ } else {
425
+ $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 ) );
426
+ }
427
428
+ } else {
429
430
+ // Query first for activity IDs
431
+ $activity_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}";
432
433
+ if ( ! empty( $per_page ) && ! empty( $page ) ) {
434
+ $activity_ids_sql .= $wpdb->prepare( " LIMIT %d, %d", absint( ( $page - 1 ) * $per_page ), $per_page );
435
+ }
436
437
+ $activity_ids_sql = apply_filters( 'bp_activity_paged_activities_sql', $activity_ids_sql, $r );
438
439
+ $activity_ids = $wpdb->get_col( $activity_ids_sql );
440
+ $activities = self::get_activity_data( $activity_ids );
441
}
442
443
+ $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 );
444
+ $total_activities = $wpdb->get_var( $total_activities_sql );
445
+
446
+ // Get the fullnames of users so we don't have to query in the loop
447
+ $activities = self::append_user_fullnames( $activities );
448
+
449
// Get activity meta
450
$activity_ids = array();
451
foreach ( (array) $activities as $activity ) {
452
$activity_ids[] = $activity->id;
453
}
454
455
+ if ( ! empty( $activity_ids ) && $update_meta_cache ) {
456
bp_activity_update_meta_cache( $activity_ids );
457
}
458
459
if ( $activities && $display_comments )
460
$activities = BP_Activity_Activity::append_comments( $activities, $spam );
461
462
+ // Pre-fetch data associated with activity users and other objects
463
+ BP_Activity_Activity::prefetch_object_data( $activities );
464
+
465
+ // Generate action strings
466
+ $activities = BP_Activity_Activity::generate_action_strings( $activities );
467
+
468
// If $max is set, only return up to the max results
469
if ( !empty( $max ) ) {
470
if ( (int) $total_activities > (int) $max )
474
return array( 'activities' => $activities, 'total' => (int) $total_activities );
475
}
476
477
+ /**
478
+ * Convert activity IDs to activity objects, as expected in template loop.
479
+ *
480
+ * @since 2.0
481
+ *
482
+ * @param array $activity_ids Array of activity IDs.
483
+ * @return array
484
+ */
485
+ protected static function get_activity_data( $activity_ids = array() ) {
486
+ global $wpdb;
487
+
488
+ // Bail if no activity ID's passed
489
+ if ( empty( $activity_ids ) ) {
490
+ return array();
491
+ }
492
+
493
+ // Get BuddyPress
494
+ $bp = buddypress();
495
+
496
+ $activities = array();
497
+ $uncached_ids = bp_get_non_cached_ids( $activity_ids, 'bp_activity' );
498
+
499
+ // Prime caches as necessary
500
+ if ( ! empty( $uncached_ids ) ) {
501
+ // Format the activity ID's for use in the query below
502
+ $uncached_ids_sql = implode( ',', wp_parse_id_list( $uncached_ids ) );
503
+
504
+ // Fetch data from activity table, preserving order
505
+ $queried_adata = $wpdb->get_results( "SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$uncached_ids_sql})");
506
+
507
+ // Put that data into the placeholders created earlier,
508
+ // and add it to the cache
509
+ foreach ( (array) $queried_adata as $adata ) {
510
+ wp_cache_set( $adata->id, $adata, 'bp_activity' );
511
+ }
512
+ }
513
+
514
+ // Now fetch data from the cache
515
+ foreach ( $activity_ids as $activity_id ) {
516
+ $activities[] = wp_cache_get( $activity_id, 'bp_activity' );
517
+ }
518
+
519
+ // Then fetch user data
520
+ $user_query = new BP_User_Query( array(
521
+ 'user_ids' => wp_list_pluck( $activities, 'user_id' ),
522
+ 'populate_extras' => false,
523
+ ) );
524
+
525
+ // Associated located user data with activity items
526
+ foreach ( $activities as $a_index => $a_item ) {
527
+ $a_user_id = intval( $a_item->user_id );
528
+ $a_user = isset( $user_query->results[ $a_user_id ] ) ? $user_query->results[ $a_user_id ] : '';
529
+
530
+ if ( !empty( $a_user ) ) {
531
+ $activities[ $a_index ]->user_email = $a_user->user_email;
532
+ $activities[ $a_index ]->user_nicename = $a_user->user_nicename;
533
+ $activities[ $a_index ]->user_login = $a_user->user_login;
534
+ $activities[ $a_index ]->display_name = $a_user->display_name;
535
+ }
536
+ }
537
+
538
+ return $activities;
539
+ }
540
+
541
+ /**
542
+ * Append xProfile fullnames to an activity array.
543
+ *
544
+ * @since BuddyPress (2.0.0)
545
+ *
546
+ * @param array $activities Activities array.
547
+ * @return array
548
+ */
549
+ protected static function append_user_fullnames( $activities ) {
550
+ global $wpdb;
551
+
552
+ if ( bp_is_active( 'xprofile' ) && ! empty( $activities ) ) {
553
+ $activity_user_ids = wp_list_pluck( $activities, 'user_id' );
554
+
555
+ if ( ! empty( $activity_user_ids ) ) {
556
+ $fullnames = bp_core_get_user_displaynames( $activity_user_ids );
557
+ if ( ! empty( $fullnames ) ) {
558
+ foreach ( (array) $activities as $i => $activity ) {
559
+ if ( ! empty( $fullnames[ $activity->user_id ] ) ) {
560
+ $activities[ $i ]->user_fullname = $fullnames[ $activity->user_id ];
561
+ }
562
+ }
563
+ }
564
+ }
565
+ }
566
+
567
+ return $activities;
568
+ }
569
+
570
+ /**
571
+ * Pre-fetch data for objects associated with activity items.
572
+ *
573
+ * Activity items are associated with users, and often with other
574
+ * BuddyPress data objects. Here, we pre-fetch data about these
575
+ * associated objects, so that inline lookups - done primarily when
576
+ * building action strings - do not result in excess database queries.
577
+ *
578
+ * The only object data required for activity component activity types
579
+ * (activity_update and activity_comment) is related to users, and that
580
+ * info is fetched separately in BP_Activity_Activity::get_activity_data().
581
+ * So this method contains nothing but a filter that allows other
582
+ * components, such as bp-friends and bp-groups, to hook in and prime
583
+ * their own caches at the beginning of an activity loop.
584
+ *
585
+ * @since BuddyPress (2.0.0)
586
+ *
587
+ * @param array $activities Array of activities.
588
+ */
589
+ protected static function prefetch_object_data( $activities ) {
590
+ return apply_filters( 'bp_activity_prefetch_object_data', $activities );
591
+ }
592
+
593
+ /**
594
+ * Generate action strings for the activities located in BP_Activity_Activity::get().
595
+ *
596
+ * If no string can be dynamically generated for a given item
597
+ * (typically because the activity type has not been properly
598
+ * registered), the static 'action' value pulled from the database will
599
+ * be left in place.
600
+ *
601
+ * @since BuddyPress (2.0.0)
602
+ *
603
+ * @param array $activities Array of activities.
604
+ * @return array
605
+ */
606
+ protected static function generate_action_strings( $activities ) {
607
+ foreach ( $activities as $key => $activity ) {
608
+ $generated_action = bp_activity_generate_action_string( $activity );
609
+ if ( false !== $generated_action ) {
610
+ $activity->action = $generated_action;
611
+ }
612
+
613
+ $activities[ $key ] = $activity;
614
+ }
615
+
616
+ return $activities;
617
+ }
618
+
619
/**
620
* Get the SQL for the 'meta_query' param in BP_Activity_Activity::get().
621
*
881
* @return bool True on success.
882
*/
883
public static function delete_activity_meta_entries( $activity_ids = array() ) {
884
+ $activity_ids = wp_parse_id_list( $activity_ids );
885
886
+ foreach ( $activity_ids as $activity_id ) {
887
+ bp_activity_delete_meta( $activity_id );
888
}
889
890
+ return true;
891
}
892
893
/**
905
$activity_comments = array();
906
907
// Now fetch the activity comments and parse them into the correct position in the activities array.
908
+ foreach ( (array) $activities as $activity ) {
909
$top_level_parent_id = 'activity_comment' == $activity->type ? $activity->item_id : 0;
910
$activity_comments[$activity->id] = BP_Activity_Activity::get_activity_comments( $activity->id, $activity->mptt_left, $activity->mptt_right, $spam, $top_level_parent_id );
911
}
912
913
// Merge the comments with the activity items
914
+ foreach ( (array) $activities as $key => $activity ) {
915
+ if ( isset( $activity_comments[$activity->id] ) ) {
916
$activities[$key]->children = $activity_comments[$activity->id];
917
+ }
918
+ }
919
920
return $activities;
921
}
942
$top_level_parent_id = $activity_id;
943
}
944
945
+ $comments = wp_cache_get( $activity_id, 'bp_activity_comments' );
946
+
947
+ // We store the string 'none' to cache the fact that the
948
+ // activity item has no comments
949
+ if ( 'none' === $comments ) {
950
+ $comments = false;
951
+
952
+ // A true cache miss
953
+ } else if ( empty( $comments ) ) {
954
955
// Select the user's fullname with the query
956
if ( bp_is_active( 'xprofile' ) ) {
972
$spam_sql = '';
973
}
974
975
+ // Legacy query - not recommended
976
+ $func_args = func_get_args();
977
+ if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $func_args ) ) {
978
+ $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 );
979
+
980
+ $descendants = $wpdb->get_results( $sql );
981
+
982
+ // We use the mptt BETWEEN clause to limit returned
983
+ // descendants to the correct part of the tree.
984
+ } else {
985
+ $sql = $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} a WHERE 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 );
986
+
987
+ $descendant_ids = $wpdb->get_col( $sql );
988
+ $descendants = self::get_activity_data( $descendant_ids );
989
+ $descendants = self::append_user_fullnames( $descendants );
990
+ }
991
992
+ $ref = array();
993
994
// Loop descendants and build an assoc array
995
foreach ( (array) $descendants as $d ) {
1006
$ref[ $d->id ] =& $comments[ $d->id ];
1007
}
1008
}
1009
+
1010
+ // Calculate depth for each item
1011
+ foreach ( $ref as &$r ) {
1012
+ $depth = 1;
1013
+ $parent_id = $r->secondary_item_id;
1014
+ while ( $parent_id !== $r->item_id ) {
1015
+ $depth++;
1016
+ $parent_id = $ref[ $parent_id ]->secondary_item_id;
1017
+ }
1018
+ $r->depth = $depth;
1019
+ }
1020
+
1021
+ // If we cache a value of false, it'll count as a cache
1022
+ // miss the next time the activity comments are fetched.
1023
+ // Storing the string 'none' is a hack workaround to
1024
+ // avoid unnecessary queries.
1025
+ if ( false === $comments ) {
1026
+ $cache_value = 'none';
1027
+ } else {
1028
+ $cache_value = $comments;
1029
+ }
1030
+
1031
+ wp_cache_set( $activity_id, $cache_value, 'bp_activity_comments' );
1032
}
1033
1034
return $comments;
1132
global $wpdb;
1133
1134
// split items at the comma
1135
+ if ( ! is_array( $items ) ) {
1136
+ $items = explode( ',', $items );
1137
+ }
1138
1139
// array of prepared integers or quoted strings
1140
$items_prepared = array();
1141
1142
// clean up and format each item
1143
+ foreach ( $items as $item ) {
1144
// clean up the string
1145
$item = trim( $item );
1146
// pass everything through prepare for security and to safely quote strings
1157
/**
1158
* Create filter SQL clauses.
1159
*
1160
+ * @since BuddyPress (1.5.0)
1161
*
1162
+ * @param array $filter_array {
1163
+ * Fields and values to filter by. Each can be either a single
1164
* string, a comma-separated list, or an array of values.
1165
+ * @type array|string|id $user_id User ID(s).
1166
+ * @type array|string $object Corresponds to the 'component'
1167
+ * column in the database.
1168
+ * @type array|string $action Corresponds to the 'type' column
1169
+ * in the database.
1170
+ * @type array|string|int $primary_id Corresponds to the 'item_id'
1171
+ * column in the database.
1172
+ * @type array|string|int $secondary_id Corresponds to the
1173
+ * 'secondary_item_id' column in the database.
1174
+ * }
1175
* @return string The filter clause, for use in a SQL query.
1176
*/
1177
public static function get_filter_sql( $filter_array ) {
1192
1193
if ( !empty( $filter_array['action'] ) ) {
1194
$action_sql = BP_Activity_Activity::get_in_operator_sql( 'a.type', $filter_array['action'] );
1195
+ if ( ! empty( $action_sql ) )
1196
$filter_sql[] = $action_sql;
1197
}
1198
1208
$filter_sql[] = $sid_sql;
1209
}
1210
1211
+ if ( ! empty( $filter_array['offset'] ) ) {
1212
+ $sid_sql = absint( $filter_array['offset'] );
1213
+ $filter_sql[] = "a.id >= {$sid_sql}";
1214
+ }
1215
+
1216
if ( empty( $filter_sql ) )
1217
return false;
1218
bp-activity/bp-activity-filters.php CHANGED
@@ -67,14 +67,14 @@ add_filter( 'bp_get_activity_latest_update', 'make_clickable', 9 );
67
add_filter( 'bp_get_activity_latest_update_excerpt', 'make_clickable', 9 );
68
add_filter( 'bp_get_activity_feed_item_description', 'make_clickable', 9 );
69
70
- add_filter( 'bp_acomment_name', 'stripslashes_deep' );
71
- add_filter( 'bp_get_activity_action', 'stripslashes_deep' );
72
- add_filter( 'bp_get_activity_content', 'stripslashes_deep' );
73
- add_filter( 'bp_get_activity_content_body', 'stripslashes_deep' );
74
- add_filter( 'bp_get_activity_parent_content', 'stripslashes_deep' );
75
- add_filter( 'bp_get_activity_latest_update', 'stripslashes_deep' );
76
- add_filter( 'bp_get_activity_latest_update_excerpt', 'stripslashes_deep' );
77
- add_filter( 'bp_get_activity_feed_item_description', 'stripslashes_deep' );
78
79
add_filter( 'bp_activity_primary_link_before_save', 'esc_url_raw' );
80
@@ -195,12 +195,9 @@ function bp_activity_filter_kses( $content ) {
195
}
196
197
/**
198
- * Finds and links @-mentioned users in the contents of a given item.
199
*
200
- * @since BuddyPress (1.2)
201
- *
202
- * @uses bp_activity_find_mentions()
203
- * @uses bp_core_get_user_domain()
204
*
205
* @param string $content The contents of a given item.
206
* @param int $activity_id The activity id. Deprecated.
@@ -220,11 +217,34 @@ function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
220
if ( empty( $usernames ) )
221
return $content;
222
223
// Linkify the mentions with the username
224
- foreach( (array) $usernames as $user_id => $username ) {
225
$content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $content );
226
}
227
228
// Return the content
229
return $content;
230
}
@@ -376,3 +396,152 @@ function bp_activity_truncate_entry( $text ) {
376
377
return apply_filters( 'bp_activity_truncate_entry', $excerpt, $text, $append_text );
378
}
67
add_filter( 'bp_get_activity_latest_update_excerpt', 'make_clickable', 9 );
68
add_filter( 'bp_get_activity_feed_item_description', 'make_clickable', 9 );
69
70
+ add_filter( 'bp_acomment_name', 'stripslashes_deep', 5 );
71
+ add_filter( 'bp_get_activity_action', 'stripslashes_deep', 5 );
72
+ add_filter( 'bp_get_activity_content', 'stripslashes_deep', 5 );
73
+ add_filter( 'bp_get_activity_content_body', 'stripslashes_deep', 5 );
74
+ add_filter( 'bp_get_activity_parent_content', 'stripslashes_deep', 5 );
75
+ add_filter( 'bp_get_activity_latest_update', 'stripslashes_deep', 5 );
76
+ add_filter( 'bp_get_activity_latest_update_excerpt', 'stripslashes_deep', 5 );
77
+ add_filter( 'bp_get_activity_feed_item_description', 'stripslashes_deep', 5 );
78
79
add_filter( 'bp_activity_primary_link_before_save', 'esc_url_raw' );
80
195
}
196
197
/**
198
+ * Find and link @-mentioned users in the contents of a given item.
199
*
200
+ * @since BuddyPress (1.2.0)
201
*
202
* @param string $content The contents of a given item.
203
* @param int $activity_id The activity id. Deprecated.
217
if ( empty( $usernames ) )
218
return $content;
219
220
+ // We don't want to link @mentions that are inside of links, so we
221
+ // temporarily remove them
222
+ $replace_count = 0;
223
+ $replacements = array();
224
+ foreach ( $usernames as $username ) {
225
+ // prevent @ name linking inside <a> tags
226
+ preg_match_all( '/(<a.*?(?!<\/a>)@' . $username . '.*?<\/a>)/', $content, $content_matches );
227
+ if ( ! empty( $content_matches[1] ) ) {
228
+ foreach ( $content_matches[1] as $replacement ) {
229
+ $replacements[ '#BPAN' . $replace_count ] = $replacement;
230
+ $content = str_replace( $replacement, '#BPAN' . $replace_count, $content );
231
+ $replace_count++;
232
+ }
233
+ }
234
+ }
235
+
236
// Linkify the mentions with the username
237
+ foreach ( (array) $usernames as $user_id => $username ) {
238
$content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $content );
239
}
240
241
+ // put everything back
242
+ if ( ! empty( $replacements ) ) {
243
+ foreach ( $replacements as $placeholder => $original ) {
244
+ $content = str_replace( $placeholder, $original, $content );
245
+ }
246
+ }
247
+
248
// Return the content
249
return $content;
250
}
396
397
return apply_filters( 'bp_activity_truncate_entry', $excerpt, $text, $append_text );
398
}
399
+
400
+ /**
401
+ * Include extra javascript dependencies for activity component.
402
+ *
403
+ * @since BuddyPress (2.0.0)
404
+ *
405
+ * @uses bp_activity_do_heartbeat() to check if heartbeat is required.
406
+ *
407
+ * @param array $js_handles The original dependencies.
408
+ * @return array $js_handles The new dependencies.
409
+ */
410
+ function bp_activity_get_js_dependencies( $js_handles = array() ) {
411
+ if ( bp_activity_do_heartbeat() ) {
412
+ $js_handles[] = 'heartbeat';
413
+ }
414
+
415
+ return $js_handles;
416
+ }
417
+ add_filter( 'bp_core_get_js_dependencies', 'bp_activity_get_js_dependencies', 10, 1 );
418
+
419
+ /**
420
+ * Add a just-posted classes to the most recent activity item.
421
+ *
422
+ * We use these classes to avoid pagination issues when items are loaded
423
+ * dynamically into the activity stream.
424
+ *
425
+ * @since BuddyPress (2.0.0)
426
+ *
427
+ * @param string $classes
428
+ * @return string $classes
429
+ */
430
+ function bp_activity_newest_class( $classes = '' ) {
431
+ $bp = buddypress();
432
+
433
+ if ( ! empty( $bp->activity->new_update_id ) && $bp->activity->new_update_id == bp_get_activity_id() ) {
434
+ $classes .= ' new-update';
435
+ }
436
+
437
+ $classes .= ' just-posted';
438
+ return $classes;
439
+ }
440
+
441
+ /**
442
+ * Use WordPress Heartbeat API to check for latest activity update.
443
+ *
444
+ * @since BuddyPress (2.0.0)
445
+ *
446
+ * @uses bp_activity_get_last_updated() to get the recorded date of the last activity
447
+
448
+ * @param array $response
449
+ * @param array $data
450
+ * @return array $response
451
+ */
452
+ function bp_activity_heartbeat_last_recorded( $response = array(), $data = array() ) {
453
+ $bp = buddypress();
454
+
455
+ if ( empty( $data['bp_activity_last_id'] ) ) {
456
+ return $response;
457
+ }
458
+
459
+ // Use the querystring argument stored in the cookie (to preserve
460
+ // filters), but force the offset to get only new items
461
+ $activity_latest_args = bp_parse_args(
462
+ bp_ajax_querystring( 'activity' ),
463
+ array( 'offset' => absint( $data['bp_activity_last_id'] ) + 1 ),
464
+ 'activity_latest_args'
465
+ );
466
+
467
+ $newest_activities = array();
468
+ $last_activity_id = 0;
469
+
470
+ // Temporarly add a just-posted class for new activity items
471
+ add_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
472
+
473
+ ob_start();
474
+ if ( bp_has_activities( $activity_latest_args ) ) {
475
+ while ( bp_activities() ) {
476
+ bp_the_activity();
477
+
478
+ if ( $last_activity_id < bp_get_activity_id() ) {
479
+ $last_activity_id = bp_get_activity_id();
480
+ }
481
+
482
+ bp_get_template_part( 'activity/entry' );
483
+ }
484
+ }
485
+
486
+ $newest_activities['activities'] = ob_get_contents();
487
+ $newest_activities['last_id'] = $last_activity_id;
488
+ ob_end_clean();
489
+
490
+ // Remove the temporary filter
491
+ remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
492
+
493
+ if ( ! empty( $newest_activities['last_id'] ) ) {
494
+ $response['bp_activity_newest_activities'] = $newest_activities;
495
+ }
496
+
497
+ return $response;
498
+ }
499
+ add_filter( 'heartbeat_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
500
+ add_filter( 'heartbeat_nopriv_received', 'bp_activity_heartbeat_last_recorded', 10, 2 );
501
+
502
+ /**
503
+ * Set the strings for WP HeartBeat API where needed.
504
+ *
505
+ * @since BuddyPress (2.0.0)
506
+ *
507
+ * @param array $strings Localized strings.
508
+ * @return array $strings
509
+ */
510
+ function bp_activity_heartbeat_strings( $strings = array() ) {
511
+
512
+ if ( ! bp_activity_do_heartbeat() ) {
513
+ return $strings;
514
+ }
515
+
516
+ $global_pulse = 0;
517
+
518
+ // Check whether the global heartbeat settings already exist.
519
+ $heartbeat_settings = apply_filters( 'heartbeat_settings', array() );
520
+ if ( ! empty( $heartbeat_settings['interval'] ) ) {
521
+ // 'Fast' is 5
522
+ $global_pulse = is_numeric( $heartbeat_settings['interval'] ) ? absint( $heartbeat_settings['interval'] ) : 5;
523
+ }
524
+
525
+ // Filter here to specify a BP-specific pulse frequency
526
+ $bp_activity_pulse = apply_filters( 'bp_activity_heartbeat_pulse', 15 );
527
+
528
+ /**
529
+ * Use the global pulse value unless:
530
+ * a. the BP-specific value has been specifically filtered, or
531
+ * b. it doesn't exist (ie, BP will be the only one using the heartbeat,
532
+ * so we're responsible for enabling it)
533
+ */
534
+ if ( has_filter( 'bp_activity_heartbeat_pulse' ) || empty( $global_pulse ) ) {
535
+ $pulse = $bp_activity_pulse;
536
+ } else {
537
+ $pulse = $global_pulse;
538
+ }
539
+
540
+ $strings = array_merge( $strings, array(
541
+ 'newest' => __( 'Load Newest', 'buddypress' ),
542
+ 'pulse' => absint( $pulse ),
543
+ ) );
544
+
545
+ return $strings;
546
+ }
547
+ add_filter( 'bp_core_get_js_strings', 'bp_activity_heartbeat_strings', 10, 1 );
bp-activity/bp-activity-functions.php CHANGED
@@ -256,38 +256,54 @@ function bp_activity_get_userid_from_mentionname( $mentionname ) {
256
/** Actions ******************************************************************/
257
258
/**
259
- * Set the current action for a given activity stream location.
260
*
261
- * @since BuddyPress (1.1)
262
*
263
- * @global object $bp BuddyPress global settings
264
- * @uses apply_filters() To call the 'bp_activity_set_action' hook
265
*
266
* @param string $component_id The unique string ID of the component.
267
- * @param string $key The action key.
268
- * @param string $value The action value.
269
* @return bool False if any param is empty, otherwise true.
270
*/
271
- function bp_activity_set_action( $component_id, $key, $value ) {
272
- global $bp;
273
274
// Return false if any of the above values are not set
275
- if ( empty( $component_id ) || empty( $key ) || empty( $value ) )
276
return false;
277
278
// Set activity action
279
- if ( !isset( $bp->activity->actions ) || !is_object( $bp->activity->actions ) ) {
280
$bp->activity->actions = new stdClass;
281
}
282
283
- if ( !isset( $bp->activity->actions->{$component_id} ) || !is_object( $bp->activity->actions->{$component_id} ) ) {
284
$bp->activity->actions->{$component_id} = new stdClass;
285
}
286
287
- $bp->activity->actions->{$component_id}->{$key} = apply_filters( 'bp_activity_set_action', array(
288
- 'key' => $key,
289
- 'value' => $value
290
- ), $component_id, $key, $value );
291
292
return true;
293
}
@@ -335,9 +351,6 @@ function bp_activity_get_types() {
335
// This was a mis-named activity type from before BP 1.6
336
unset( $actions['friends_register_activity_action'] );
337
338
- // This type has not been used since BP 1.0.3. It will be re-instated in a future version.
339
- unset( $actions['updated_profile'] );
340
-
341
return apply_filters( 'bp_activity_get_types', $actions );
342
}
343
@@ -393,8 +406,17 @@ function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
393
if ( empty( $user_id ) )
394
$user_id = bp_loggedin_user_id();
395
396
- // Update the user's personal favorites
397
- $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
398
$my_favs[] = $activity_id;
399
400
// Update the total number of users who have favorited this activity
@@ -448,9 +470,15 @@ function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
448
if ( empty( $user_id ) )
449
$user_id = bp_loggedin_user_id();
450
451
- // Remove the fav from the user's favs
452
$my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
453
$my_favs = array_flip( (array) $my_favs );
454
unset( $my_favs[$activity_id] );
455
$my_favs = array_unique( array_flip( $my_favs ) );
456
@@ -538,59 +566,46 @@ function bp_activity_total_favorites_for_user( $user_id = 0 ) {
538
/**
539
* Delete a meta entry from the DB for an activity stream item.
540
*
541
- * @since BuddyPress (1.2)
542
*
543
* @global object $wpdb WordPress database access object.
544
* @global object $bp BuddyPress global settings.
545
- * @uses wp_cache_delete()
546
- * @uses is_wp_error()
547
*
548
* @param int $activity_id ID of the activity item whose metadata is being deleted.
549
* @param string $meta_key Optional. The key of the metadata being deleted. If
550
- * omitted, all metadata associated with the activity
551
- * item will be deleted.
552
* @param string $meta_value Optional. If present, the metadata will only be
553
- * deleted if the meta_value matches this parameter.
554
* @return bool True on success, false on failure.
555
*/
556
- function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = '' ) {
557
global $wpdb, $bp;
558
559
- // Return false if any of the above values are not set
560
- if ( !is_numeric( $activity_id ) )
561
- return false;
562
-
563
- // Sanitize key
564
- $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
565
-
566
- if ( is_array( $meta_value ) || is_object( $meta_value ) )
567
- $meta_value = serialize( $meta_value );
568
-
569
- // Trim off whitespace
570
- $meta_value = trim( $meta_value );
571
-
572
- // Delete all for activity_id
573
- if ( empty( $meta_key ) )
574
- $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
575
576
- // Delete only when all match
577
- else if ( $meta_value )
578
- $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s AND meta_value = %s", $activity_id, $meta_key, $meta_value ) );
579
-
580
- // Delete only when activity_id and meta_key match
581
- else
582
- $retval = $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
583
584
- // Delete cache entry
585
- wp_cache_delete( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, 'bp' );
586
587
- // Success
588
- if ( !is_wp_error( $retval ) )
589
- return true;
590
591
- // Fail
592
- else
593
- return false;
594
}
595
596
/**
@@ -598,65 +613,24 @@ function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = ''
598
*
599
* @since BuddyPress (1.2)
600
*
601
- * @global object $wpdb WordPress database access object.
602
- * @global object $bp BuddyPress global settings.
603
- * @uses wp_cache_get()
604
- * @uses wp_cache_set()
605
* @uses apply_filters() To call the 'bp_activity_get_meta' hook.
606
*
607
- * @param int $activity_id ID of the activity item whose metadata is being requseted.
608
* @param string $meta_key Optional. If present, only the metadata matching
609
- * that meta key will be returned. Otherwise, all
610
- * metadata for the activity item will be fetched.
611
* @return mixed The meta value(s) being requested.
612
*/
613
- function bp_activity_get_meta( $activity_id = 0, $meta_key = '' ) {
614
- global $wpdb, $bp;
615
-
616
- // Make sure activity_id is valid
617
- if ( empty( $activity_id ) || !is_numeric( $activity_id ) )
618
- return false;
619
-
620
- // We have a key to look for
621
- if ( !empty( $meta_key ) ) {
622
-
623
- // Sanitize key
624
- $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
625
-
626
- // Check cache
627
- if ( !$metas = wp_cache_get( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, 'bp' ) ) {
628
- // No cache so hit the DB
629
- $metas = $wpdb->get_col( $wpdb->prepare("SELECT meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
630
-
631
- // Set cache
632
- wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, $metas, 'bp' );
633
- }
634
-
635
- // No key so get all for activity_id
636
- } else {
637
- $metas = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value FROM {$bp->activity->table_name_meta} WHERE activity_id = %d", $activity_id ) );
638
-
639
- if ( !empty( $metas ) ) {
640
- $metas = array_map( 'maybe_unserialize', (array) $metas );
641
-
642
- foreach( $metas as $mkey => $mvalue ) {
643
- wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $mkey, $mvalue, 'bp' );
644
- }
645
- }
646
- }
647
-
648
- // No result so return false
649
- if ( empty( $metas ) )
650
- return false;
651
-
652
- // Maybe, just maybe... unserialize
653
- $metas = array_map( 'maybe_unserialize', (array) $metas );
654
-
655
- // Return first item in array if only 1, else return all metas found
656
- $retval = ( 1 == count( $metas ) ? $metas[0] : $metas );
657
658
// Filter result before returning
659
- return apply_filters( 'bp_activity_get_meta', $retval, $activity_id, $meta_key );
660
}
661
662
/**
@@ -664,59 +638,44 @@ function bp_activity_get_meta( $activity_id = 0, $meta_key = '' ) {
664
*
665
* @since BuddyPress (1.2)
666
*
667
- * @global object $wpdb WordPress database access object.
668
- * @global object $bp BuddyPress global settings.
669
- * @uses maybe_serialize()
670
- * @uses bp_activity_delete_meta()
671
- * @uses wp_cache_set()
672
- *
673
- * @param int $activity_id ID of the activity item whose metadata is being updated.
674
* @param string $meta_key Key of the metadata being updated.
675
* @param mixed $meta_value Value to be set.
676
- * @return bool True on success, false on failure.
677
*/
678
- function bp_activity_update_meta( $activity_id, $meta_key, $meta_value ) {
679
- global $wpdb, $bp;
680
681
- // Make sure activity_id is valid
682
- if ( !is_numeric( $activity_id ) )
683
- return false;
684
-
685
- // Sanitize key
686
- $meta_key = preg_replace( '|[^a-z0-9_]|i', '', $meta_key );
687
-
688
- // Sanitize value
689
- if ( is_string( $meta_value ) ) {
690
- $meta_value = stripslashes( $meta_value );
691
- }
692
-
693
- // Maybe, just maybe... serialize
694
- $meta_value = maybe_serialize( $meta_value );
695
-
696
- // If value is false, delete the meta key
697
- if ( false === $meta_value )
698
- return bp_activity_delete_meta( $activity_id, $meta_key );
699
-
700
- // See if meta key exists for activity_id
701
- $cur = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->activity->table_name_meta} WHERE activity_id = %d AND meta_key = %s", $activity_id, $meta_key ) );
702
-
703
- // Meta key does not exist so INSERT
704
- if ( empty( $cur ) )
705
- $wpdb->query( $wpdb->prepare( "INSERT INTO {$bp->activity->table_name_meta} ( activity_id, meta_key, meta_value ) VALUES ( %d, %s, %s )", $activity_id, $meta_key, $meta_value ) );
706
-
707
- // Meta key exists, so UPDATE
708
- else if ( $cur->meta_value != $meta_value )
709
- $wpdb->query( $wpdb->prepare( "UPDATE {$bp->activity->table_name_meta} SET meta_value = %s WHERE activity_id = %d AND meta_key = %s", $meta_value, $activity_id, $meta_key ) );
710
-
711
- // Weirdness, so return false
712
- else
713
- return false;
714
715
- // Set cache
716
- wp_cache_set( 'bp_activity_meta_' . $activity_id . '_' . $meta_key, $meta_value, 'bp' );
717
718
- // Victory is ours!
719
- return true;
720
}
721
722
/** Clean up *****************************************************************/
@@ -872,8 +831,19 @@ add_action( 'bp_make_ham_user', 'bp_activity_ham_all_user_data' );
872
function bp_activity_register_activity_actions() {
873
global $bp;
874
875
- bp_activity_set_action( $bp->activity->id, 'activity_update', __( 'Posted a status update', 'buddypress' ) );
876
- bp_activity_set_action( $bp->activity->id, 'activity_comment', __( 'Replied to a status update', 'buddypress' ) );
877
878
do_action( 'bp_activity_register_activity_actions' );
879
@@ -882,6 +852,64 @@ function bp_activity_register_activity_actions() {
882
}
883
add_action( 'bp_register_activity_actions', 'bp_activity_register_activity_actions' );
884
885
/******************************************************************************
886
* Business functions are where all the magic happens in BuddyPress. They will
887
* handle the actual saving or manipulation of information. Usually they will
@@ -913,18 +941,19 @@ add_action( 'bp_register_activity_actions', 'bp_activity_register_activity_actio
913
*/
914
function bp_activity_get( $args = '' ) {
915
$defaults = array(
916
- 'max' => false, // Maximum number of results to return
917
- 'page' => 1, // page 1 without a per_page will result in no pagination.
918
- 'per_page' => false, // results per page
919
- 'sort' => 'DESC', // sort ASC or DESC
920
- 'display_comments' => false, // false for no comments. 'stream' for within stream display, 'threaded' for below each activity item
921
-
922
- 'search_terms' => false, // Pass search terms as a string
923
- 'meta_query' => false, // Filter by activity meta. See WP_Meta_Query for format
924
- 'show_hidden' => false, // Show activity items that are hidden site-wide?
925
- 'exclude' => false, // Comma-separated list of activity IDs to exclude
926
- 'in' => false, // Comma-separated list or array of activity IDs to which you want to limit the query
927
- 'spam' => 'ham_only', // 'ham_only' (default), 'spam_only' or 'all'.
928
929
/**
930
* Pass filters as an array -- all filter items can be multiple values comma separated:
@@ -945,16 +974,17 @@ function bp_activity_get( $args = '' ) {
945
if ( 1 == (int) $page && empty( $max ) && empty( $search_terms ) && empty( $meta_query ) && empty( $filter ) && empty( $exclude ) && empty( $in ) && 'DESC' == $sort && empty( $exclude ) && 'ham_only' == $spam ) {
946
if ( !$activity = wp_cache_get( 'bp_activity_sitewide_front', 'bp' ) ) {
947
$args = array(
948
- 'page' => $page,
949
- 'per_page' => $per_page,
950
- 'max' => $max,
951
- 'sort' => $sort,
952
- 'search_terms' => $search_terms,
953
- 'meta_query' => $meta_query,
954
- 'filter' => $filter,
955
- 'display_comments' => $display_comments,
956
- 'show_hidden' => $show_hidden,
957
- 'spam' => $spam
958
);
959
$activity = BP_Activity_Activity::get( $args );
960
wp_cache_set( 'bp_activity_sitewide_front', $activity, 'bp' );
@@ -995,33 +1025,35 @@ function bp_activity_get( $args = '' ) {
995
* All arguments and defaults are shared with BP_Activity_Activity::get(),
996
* except for the following:
997
* @type string|int|array Single activity ID, comma-separated list of IDs,
998
- * or array of IDs.
999
* }
1000
* @return array $activity See BP_Activity_Activity::get() for description.
1001
*/
1002
function bp_activity_get_specific( $args = '' ) {
1003
$defaults = array(
1004
- 'activity_ids' => false, // A single activity_id or array of IDs.
1005
- 'display_comments' => false, // true or false to display threaded comments for these specific activity items
1006
- 'max' => false, // Maximum number of results to return
1007
- 'page' => 1, // page 1 without a per_page will result in no pagination.
1008
- 'per_page' => false, // results per page
1009
- 'show_hidden' => true, // When fetching specific items, show all
1010
- 'sort' => 'DESC', // sort ASC or DESC
1011
- 'spam' => 'ham_only', // Retrieve items marked as spam
1012
);
1013
$r = wp_parse_args( $args, $defaults );
1014
extract( $r, EXTR_SKIP );
1015
1016
$get_args = array(
1017
- 'page' => $page,
1018
- 'per_page' => $per_page,
1019
- 'max' => $max,
1020
- 'sort' => $sort,
1021
- 'display_comments' => $display_comments,
1022
- 'show_hidden' => $show_hidden,
1023
- 'in' => $activity_ids,
1024
- 'spam' => $spam
1025
);
1026
return apply_filters( 'bp_activity_get_specific', BP_Activity_Activity::get( $get_args ), $args, $get_args );
1027
}
@@ -1042,7 +1074,13 @@ function bp_activity_get_specific( $args = '' ) {
1042
* @type int|bool $id Pass an activity ID to update an existing item, or
1043
* false to create a new item. Default: false.
1044
* @type string $action Optional. The activity action/description, typically
1045
- * something like "Joe posted an update".
1046
* @type string $content Optional. The content of the activity item.
1047
* @type string $component The unique name of the component associated with
1048
* the activity item - 'groups', 'profile', etc.
@@ -1098,7 +1136,6 @@ function bp_activity_add( $args = '' ) {
1098
$activity->user_id = $user_id;
1099
$activity->component = $component;
1100
$activity->type = $type;
1101
- $activity->action = $action;
1102
$activity->content = $content;
1103
$activity->primary_link = $primary_link;
1104
$activity->item_id = $item_id;
@@ -1106,6 +1143,7 @@ function bp_activity_add( $args = '' ) {
1106
$activity->date_recorded = $recorded_time;
1107
$activity->hide_sitewide = $hide_sitewide;
1108
$activity->is_spam = $is_spam;
1109
1110
if ( !$activity->save() )
1111
return false;
@@ -1161,18 +1199,16 @@ function bp_activity_post_update( $args = '' ) {
1161
1162
// Record this on the user's profile
1163
$from_user_link = bp_core_get_userlink( $user_id );
1164
- $activity_action = sprintf( __( '%s posted an update', 'buddypress' ), $from_user_link );
1165
$activity_content = $content;
1166
$primary_link = bp_core_get_userlink( $user_id, false, true );
1167
1168
// Now write the values
1169
$activity_id = bp_activity_add( array(
1170
'user_id' => $user_id,
1171
- 'action' => apply_filters( 'bp_activity_new_update_action', $activity_action ),
1172
'content' => apply_filters( 'bp_activity_new_update_content', $activity_content ),
1173
'primary_link' => apply_filters( 'bp_activity_new_update_primary_link', $primary_link ),
1174
'component' => $bp->activity->id,
1175
- 'type' => 'activity_update'
1176
) );
1177
1178
$activity_content = apply_filters( 'bp_activity_latest_update_content', $content, $activity_content );
@@ -1241,7 +1277,6 @@ function bp_activity_new_comment( $args = '' ) {
1241
// Insert the activity comment
1242
$comment_id = bp_activity_add( array(
1243
'id' => $id,
1244
- 'action' => apply_filters( 'bp_activity_comment_action', sprintf( __( '%s posted a new activity comment', 'buddypress' ), bp_core_get_userlink( $user_id ) ) ),
1245
'content' => apply_filters( 'bp_activity_comment_content', $content ),
1246
'component' => buddypress()->activity->id,
1247
'type' => 'activity_comment',
@@ -1251,8 +1286,17 @@ function bp_activity_new_comment( $args = '' ) {
1251
'hide_sitewide' => $is_hidden
1252
) );
1253
1254
- // Clear the comment cache for this activity
1255
- wp_cache_delete( 'bp_activity_comments_' . $parent_id );
1256
1257
do_action( 'bp_activity_comment_posted', $comment_id, $params, $activity );
1258
@@ -1669,7 +1713,7 @@ function bp_activity_mark_as_spam( &$activity, $source = 'by_a_person' ) {
1669
wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
1670
1671
// Clear the activity comment cache for this activity item
1672
- wp_cache_delete( 'bp_activity_comments_' . $activity->id, 'bp' );
1673
1674
// If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity
1675
if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
@@ -1709,7 +1753,7 @@ function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
1709
wp_cache_delete( 'bp_activity_sitewide_front', 'bp' );
1710
1711
// Clear the activity comment cache for this activity item
1712
- wp_cache_delete( 'bp_activity_comments_' . $activity->id, 'bp' );
1713
1714
// If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity
1715
if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
@@ -1860,3 +1904,42 @@ function bp_embed_activity_cache( $cache, $id, $cachekey ) {
1860
function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
1861
bp_activity_update_meta( $id, $cachekey, $cache );
1862
}
256
/** Actions ******************************************************************/
257
258
/**
259
+ * Register an activity 'type' and its action description/callback.
260
*
261
+ * Activity actions are strings used to describe items in the activity stream,
262
+ * such as 'Joe became a registered member' or 'Bill and Susie are now
263
+ * friends'. Each activity type (such as 'new_member' or 'friendship_created')
264
+ * used by a component should be registered using this function.
265
*
266
+ * While it's possible to post items to the activity stream whose types are
267
+ * not registered using bp_activity_set_action(), it is not recommended;
268
+ * unregistered types will not be displayed properly in the activity admin
269
+ * panel, and dynamic action generation (which is essential for multilingual
270
+ * sites, etc) will not work.
271
+ *
272
+ * @since BuddyPress (1.1.0)
273
*
274
* @param string $component_id The unique string ID of the component.
275
+ * @param string $type The action type.
276
+ * @param string $description The action description.
277
+ * @param callable $format_callback Callback for formatting the action string.
278
* @return bool False if any param is empty, otherwise true.
279
*/
280
+ function bp_activity_set_action( $component_id, $type, $description, $format_callback = false ) {
281
+ $bp = buddypress();
282
283
// Return false if any of the above values are not set
284
+ if ( empty( $component_id ) || empty( $type ) || empty( $description ) ) {
285
return false;
286
+ }
287
288
// Set activity action
289
+ if ( ! isset( $bp->activity->actions ) || ! is_object( $bp->activity->actions ) ) {
290
$bp->activity->actions = new stdClass;
291
}
292
293
+ // Verify callback
294
+ if ( ! is_callable( $format_callback ) ) {
295
+ $format_callback = '';
296
+ }
297
+
298
+ if ( ! isset( $bp->activity->actions->{$component_id} ) || ! is_object( $bp->activity->actions->{$component_id} ) ) {
299
$bp->activity->actions->{$component_id} = new stdClass;
300
}
301
302
+ $bp->activity->actions->{$component_id}->{$type} = apply_filters( 'bp_activity_set_action', array(
303
+ 'key' => $type,
304
+ 'value' => $description,
305
+ 'format_callback' => $format_callback,
306
+ ), $component_id, $type, $description, $format_callback );
307
308
return true;
309
}
351
// This was a mis-named activity type from before BP 1.6
352
unset( $actions['friends_register_activity_action'] );
353
354
return apply_filters( 'bp_activity_get_types', $actions );
355
}
356
406
if ( empty( $user_id ) )
407
$user_id = bp_loggedin_user_id();
408
409
+ $my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
410
+ if ( empty( $my_favs ) || ! is_array( $my_favs ) ) {
411
+ $my_favs = array();
412
+ }
413
+
414
+ // Bail if the user has already favorited this activity item
415
+ if ( in_array( $activity_id, $my_favs ) ) {
416
+ return false;
417
+ }
418
+
419
+ // Add to user's favorites
420
$my_favs[] = $activity_id;
421
422
// Update the total number of users who have favorited this activity
470
if ( empty( $user_id ) )
471
$user_id = bp_loggedin_user_id();
472
473
$my_favs = bp_get_user_meta( $user_id, 'bp_favorite_activities', true );
474
$my_favs = array_flip( (array) $my_favs );
475
+
476
+ // Bail if the user has not previously favorited the item
477
+ if ( ! isset( $my_favs[ $activity_id ] ) ) {
478
+ return false;
479
+ }
480
+
481
+ // Remove the fav from the user's favs
482
unset( $my_favs[$activity_id] );
483
$my_favs = array_unique( array_flip( $my_favs ) );
484
566
/**
567
* Delete a meta entry from the DB for an activity stream item.
568
*
569
+ * @since BuddyPress (1.2.0)
570
*
571
* @global object $wpdb WordPress database access object.
572
* @global object $bp BuddyPress global settings.
573
*
574
* @param int $activity_id ID of the activity item whose metadata is being deleted.
575
* @param string $meta_key Optional. The key of the metadata being deleted. If
576
+ * omitted, all metadata associated with the activity
577
+ * item will be deleted.
578
* @param string $meta_value Optional. If present, the metadata will only be
579
+ * deleted if the meta_value matches this parameter.
580
+ * @param bool $delete_all Optional. If true, delete matching metadata entries
581
+ * for all objects, ignoring the specified object_id. Otherwise,
582
+ * only delete matching metadata entries for the specified
583
+ * activity item. Default: false.
584
* @return bool True on success, false on failure.
585
*/
586
+ function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = '', $delete_all = false ) {
587
global $wpdb, $bp;
588
589
+ // Legacy - if no meta_key is passed, delete all for the item
590
+ if ( empty( $meta_key ) ) {
591
+ $all_meta = bp_activity_get_meta( $activity_id );
592
+ $keys = ! empty( $all_meta ) ? array_keys( $all_meta ) : array();
593
594
+ // With no meta_key, ignore $delete_all
595
+ $delete_all = false;
596
+ } else {
597
+ $keys = array( $meta_key );
598
+ }
599
600
+ $retval = true;
601
602
+ add_filter( 'query', 'bp_filter_metaid_column_name' );
603
+ foreach ( $keys as $key ) {
604
+ $retval = delete_metadata( 'activity', $activity_id, $key, $meta_value, $delete_all );
605
+ }
606
+ remove_filter( 'query', 'bp_filter_metaid_column_name' );
607
608
+ return $retval;
609
}
610
611
/**
613
*
614
* @since BuddyPress (1.2)
615
*
616
* @uses apply_filters() To call the 'bp_activity_get_meta' hook.
617
*
618
+ * @param int $activity_id ID of the activity item whose metadata is being requested.
619
* @param string $meta_key Optional. If present, only the metadata matching
620
+ * that meta key will be returned. Otherwise, all metadata for the
621
+ * activity item will be fetched.
622
+ * @param bool $single Optional. If true, return only the first value of the
623
+ * specified meta_key. This parameter has no effect if meta_key is not
624
+ * specified. Default: true.
625
* @return mixed The meta value(s) being requested.
626
*/
627
+ function bp_activity_get_meta( $activity_id = 0, $meta_key = '', $single = true ) {
628
+ add_filter( 'query', 'bp_filter_metaid_column_name' );
629
+ $retval = get_metadata( 'activity', $activity_id, $meta_key, $single );
630
+ remove_filter( 'query', 'bp_filter_metaid_column_name' );
631
632
// Filter result before returning
633
+ return apply_filters( 'bp_activity_get_meta', $retval, $activity_id, $meta_key, $single );
634
}
635
636
/**
638
*
639
* @since BuddyPress (1.2)
640
*
641
+ * @param int $activity_id ID of the activity item whose metadata is being
642
+ * updated.
643
* @param string $meta_key Key of the metadata being updated.
644
* @param mixed $meta_value Value to be set.
645
+ * @param mixed $prev_value Optional. If specified, only update existing
646
+ * metadata entries with the specified value. Otherwise, update all
647
+ * entries.
648
+ * @return bool|int Returns false on failure. On successful update of existing
649
+ * metadata, returns true. On successful creation of new metadata,
650
+ * returns the integer ID of the new metadata row.
651
*/
652
+ function bp_activity_update_meta( $activity_id, $meta_key, $meta_value, $prev_value = '' ) {
653
+ add_filter( 'query', 'bp_filter_metaid_column_name' );
654
+ $retval = update_metadata( 'activity', $activity_id, $meta_key, $meta_value, $prev_value );
655
+ remove_filter( 'query', 'bp_filter_metaid_column_name' );
656
657
+ return $retval;
658
+ }
659
660
+ /**
661
+ * Add a piece of activity metadata.
662
+ *
663
+ * @since BuddyPress (2.0.0)
664
+ *
665
+ * @param int $activity_id ID of the activity item.
666
+ * @param string $meta_key Metadata key.
667
+ * @param mixed $meta_value Metadata value.
668
+ * @param bool $unique. Optional. Whether to enforce a single metadata value
669
+ * for the given key. If true, and the object already has a value for
670
+ * the key, no change will be made. Default: false.
671
+ * @return int|bool The meta ID on successful update, false on failure.
672
+ */
673
+ function bp_activity_add_meta( $activity_id, $meta_key, $meta_value, $unique = false ) {
674
+ add_filter( 'query', 'bp_filter_metaid_column_name' );
675
+ $retval = add_metadata( 'activity', $activity_id, $meta_key, $meta_value, $unique );
676
+ remove_filter( 'query', 'bp_filter_metaid_column_name' );
677
678
+ return $retval;
679
}
680
681
/** Clean up *****************************************************************/
831
function bp_activity_register_activity_actions() {
832
global $bp;
833
834
+ bp_activity_set_action(
835
+ $bp->activity->id,
836
+ 'activity_update',
837
+ __( 'Posted a status update', 'buddypress' ),
838
+ 'bp_activity_format_activity_action_activity_update'
839
+ );
840
+
841
+ bp_activity_set_action(
842
+ $bp->activity->id,
843