BuddyPress - Version 2.5.0-beta1

Version Description

= 2.4.2 = See: https://codex.buddypress.org/releases/version-2-4-2/

= 2.4.1 = See: https://codex.buddypress.org/releases/version-2-4-1/

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

= 2.3.4 = See: https://codex.buddypress.org/releases/version-2-3-4/

= 2.3.3 = See: https://codex.buddypress.org/releases/version-2-3-3/

= 2.3.2 = See: https://codex.buddypress.org/releases/version-2-3-2/

= 2.3.1 = See: https://codex.buddypress.org/releases/version-2-3-1/

= 2.3.0 = See: https://codex.buddypress.org/releases/version-2-3-0/

= 2.2.3.1 = See: https://codex.buddypress.org/releases/version-2-2-3-1/

= 2.2.3 = See: https://codex.buddypress.org/releases/version-2-2-3/

= 2.2.2.1 = See: https://codex.buddypress.org/releases/version-2-2-2-1/

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

= 2.2.1 = See: https://codex.buddypress.org/releases/version-2-2-1/

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

= 2.1 = See: https://codex.buddypress.org/releases/version-2-1/

= 2.0.3 = See: https://codex.buddypress.org/releases/version-2-0-3/

= 2.0.2 = See: https://codex.buddypress.org/releases/version-2-0-2/

= 2.0.1 = See: https://codex.buddypress.org/releases/version-2-0-1/

= 2.0 = See: https://codex.buddypress.org/releases/version-2-0/

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

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

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

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

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

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

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

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

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

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

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

= 1.6.3 = See: https://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: https://codex.buddypress.org/releases/version-1-6/

= 1.5 = See: https://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.5.0-beta1
Comparing to
See all releases

Code changes from version 2.4.3 to 2.5.0-beta1

Files changed (339) hide show
  1. bp-activity/admin/js/admin.min.js +1 -1
  2. bp-activity/bp-activity-actions.php +163 -4
  3. bp-activity/bp-activity-admin.php +19 -820
  4. bp-activity/bp-activity-akismet.php +1 -640
  5. bp-activity/bp-activity-cache.php +4 -2
  6. bp-activity/bp-activity-classes.php +1 -0
  7. bp-activity/bp-activity-cssjs.php +1 -0
  8. bp-activity/bp-activity-filters.php +13 -9
  9. bp-activity/bp-activity-functions.php +615 -65
  10. bp-activity/bp-activity-loader.php +4 -374
  11. bp-activity/bp-activity-notifications.php +83 -244
  12. bp-activity/bp-activity-screens.php +3 -169
  13. bp-activity/bp-activity-template.php +15 -419
  14. bp-activity/classes/class-bp-activity-activity.php +18 -4
  15. bp-activity/classes/class-bp-activity-component.php +393 -0
  16. bp-activity/classes/class-bp-activity-feed.php +24 -3
  17. bp-activity/classes/class-bp-activity-list-table.php +827 -0
  18. bp-activity/classes/class-bp-activity-query.php +1 -0
  19. bp-activity/classes/class-bp-activity-template.php +409 -0
  20. bp-activity/classes/class-bp-activity-theme-compat.php +180 -0
  21. bp-activity/classes/class-bp-akismet.php +651 -0
  22. bp-activity/js/mentions.min.js +1 -1
  23. bp-blogs/bp-blogs-actions.php +5 -4
  24. bp-blogs/bp-blogs-activity.php +392 -206
  25. bp-blogs/bp-blogs-cache.php +6 -5
  26. bp-blogs/bp-blogs-classes.php +1 -0
  27. bp-blogs/bp-blogs-filters.php +6 -8
  28. bp-blogs/bp-blogs-functions.php +238 -385
  29. bp-blogs/bp-blogs-loader.php +3 -331
  30. bp-blogs/bp-blogs-screens.php +4 -192
  31. bp-blogs/bp-blogs-template.php +42 -275
  32. bp-blogs/bp-blogs-widgets.php +4 -146
  33. bp-blogs/classes/class-bp-blogs-blog.php +49 -43
  34. bp-blogs/classes/class-bp-blogs-component.php +305 -0
  35. bp-blogs/classes/class-bp-blogs-recent-posts-widget.php +163 -0
  36. bp-blogs/classes/class-bp-blogs-template.php +246 -0
  37. bp-blogs/classes/class-bp-blogs-theme-compat.php +201 -0
  38. bp-core/admin/bp-core-admin-actions.php +32 -23
  39. bp-core/admin/bp-core-admin-classes.php +13 -0
  40. bp-core/admin/bp-core-admin-components.php +55 -51
  41. bp-core/admin/bp-core-admin-functions.php +175 -84
  42. bp-core/admin/bp-core-admin-schema.php +205 -19
  43. bp-core/admin/bp-core-admin-settings.php +19 -17
  44. bp-core/admin/bp-core-admin-slugs.php +9 -6
  45. bp-core/admin/bp-core-admin-tools.php +80 -34
  46. bp-core/admin/css/common-rtl.css +26 -4
  47. bp-core/admin/css/common-rtl.min.css +1 -1
  48. bp-core/admin/css/common.css +26 -4
  49. bp-core/admin/css/common.min.css +1 -1
  50. bp-core/admin/css/customizer-controls-rtl.css +10 -0
  51. bp-core/admin/css/customizer-controls-rtl.min.css +1 -0
  52. bp-core/admin/css/customizer-controls.css +10 -0
  53. bp-core/admin/css/customizer-controls.min.css +1 -0
  54. bp-core/admin/js/customizer-controls.js +22 -0
  55. bp-core/admin/js/customizer-controls.min.js +2 -0
  56. bp-core/admin/js/customizer-receiver-emails.js +115 -0
  57. bp-core/admin/js/customizer-receiver-emails.min.js +2 -0
  58. bp-core/bp-core-actions.php +9 -6
  59. bp-core/bp-core-admin.php +2 -879
  60. bp-core/bp-core-adminbar.php +13 -12
  61. bp-core/bp-core-attachments.php +195 -195
  62. bp-core/bp-core-avatars.php +134 -125
  63. bp-core/bp-core-buddybar.php +94 -78
  64. bp-core/bp-core-cache.php +25 -19
  65. bp-core/bp-core-caps.php +21 -23
  66. bp-core/bp-core-catchuri.php +94 -88
  67. bp-core/bp-core-classes.php +6 -0
  68. bp-core/bp-core-component.php +2 -813
  69. bp-core/bp-core-cssjs.php +29 -23
  70. bp-core/bp-core-customizer-email.php +438 -0
  71. bp-core/bp-core-dependency.php +84 -13
  72. bp-core/bp-core-filters.php +293 -241
  73. bp-core/bp-core-functions.php +669 -168
  74. bp-core/bp-core-loader.php +2 -267
  75. bp-core/bp-core-moderation.php +50 -47
  76. bp-core/bp-core-options.php +61 -80
  77. bp-core/bp-core-taxonomy.php +20 -5
  78. bp-core/bp-core-template-loader.php +48 -58
  79. bp-core/bp-core-template.php +303 -136
  80. bp-core/bp-core-theme-compatibility.php +77 -195
  81. bp-core/bp-core-update.php +371 -358
  82. bp-core/bp-core-widgets.php +3 -168
  83. bp-core/bp-core-wpabstraction.php +99 -9
  84. bp-core/classes/class-bp-admin.php +1045 -0
  85. bp-core/classes/class-bp-attachment-avatar.php +36 -39
  86. bp-core/classes/class-bp-attachment-cover-image.php +47 -39
  87. bp-core/classes/class-bp-attachment.php +56 -58
  88. bp-core/classes/class-bp-button.php +18 -15
  89. bp-core/classes/class-bp-component.php +858 -0
  90. bp-core/classes/class-bp-core-login-widget.php +185 -0
  91. bp-core/classes/class-bp-core-notification.php +16 -18
  92. bp-core/classes/class-bp-core-sort-by-key-callback.php +83 -0
  93. bp-core/classes/class-bp-core-user.php +56 -63
  94. bp-core/classes/class-bp-core.php +321 -0
  95. bp-core/classes/class-bp-customizer-control-range.php +57 -0
  96. bp-core/classes/class-bp-date-query.php +4 -3
  97. bp-core/classes/class-bp-email-delivery.php +31 -0
  98. bp-core/classes/class-bp-email-recipient.php +172 -0
  99. bp-core/classes/class-bp-email.php +951 -0
  100. bp-core/classes/class-bp-embed.php +27 -17
  101. bp-core/classes/class-bp-media-extractor.php +12 -22
  102. bp-core/classes/class-bp-members-suggestions.php +2 -1
  103. bp-core/classes/class-bp-phpmailer.php +153 -0
  104. bp-core/classes/class-bp-recursive-query.php +1 -0
  105. bp-core/classes/class-bp-suggestions.php +5 -2
  106. bp-core/classes/class-bp-theme-compat.php +120 -0
  107. bp-core/classes/class-bp-user-query.php +51 -53
  108. bp-core/classes/class-bp-walker-category-checklist.php +109 -0
  109. bp-core/classes/class-bp-walker-nav-menu-checklist.php +2 -1
  110. bp-core/classes/class-bp-walker-nav-menu.php +10 -10
  111. bp-core/css/admin-bar-rtl.css +1 -1
  112. bp-core/css/admin-bar.css +1 -1
  113. bp-core/css/avatar-rtl.css +10 -1
  114. bp-core/css/avatar-rtl.min.css +1 -1
  115. bp-core/css/avatar.css +10 -1
  116. bp-core/css/avatar.min.css +1 -1
  117. bp-core/deprecated/1.5.php +0 -2
  118. bp-core/deprecated/1.6.php +1 -1
  119. bp-core/deprecated/2.1.php +3 -52
  120. bp-core/deprecated/2.5.php +919 -0
  121. bp-core/js/avatar.js +22 -12
  122. bp-core/js/avatar.min.js +2 -2
  123. bp-core/js/bp-plupload.min.js +1 -1
  124. bp-core/js/confirm.min.js +1 -1
  125. bp-core/js/cover-image.min.js +1 -1
  126. bp-core/js/jquery-cookie.min.js +1 -1
  127. bp-core/js/jquery-query.min.js +1 -1
  128. bp-core/js/jquery-scroll-to.min.js +1 -1
  129. bp-core/js/jquery.atwho.min.js +1 -1
  130. bp-core/js/jquery.caret.min.js +1 -1
  131. bp-core/js/webcam.js +3 -1
  132. bp-core/js/webcam.min.js +2 -2
  133. bp-core/js/widget-members.min.js +1 -1
  134. bp-forums/bb-config.php +1 -0
  135. bp-forums/bp-forums-actions.php +1 -0
  136. bp-forums/bp-forums-bbpress-sa.php +1 -0
  137. bp-forums/bp-forums-bbpress.php +1 -0
  138. bp-forums/bp-forums-filters.php +1 -0
  139. bp-forums/bp-forums-functions.php +1 -0
  140. bp-forums/bp-forums-loader.php +1 -0
  141. bp-forums/bp-forums-screens.php +1 -0
  142. bp-forums/bp-forums-template.php +1 -0
  143. bp-friends/bp-friends-actions.php +1 -0
  144. bp-friends/bp-friends-activity.php +21 -0
  145. bp-friends/bp-friends-cache.php +1 -0
  146. bp-friends/bp-friends-classes.php +1 -0
  147. bp-friends/bp-friends-filters.php +1 -0
  148. bp-friends/bp-friends-functions.php +1 -0
  149. bp-friends/bp-friends-loader.php +2 -248
  150. bp-friends/bp-friends-notifications.php +31 -147
  151. bp-friends/bp-friends-screens.php +1 -0
  152. bp-friends/bp-friends-template.php +5 -0
  153. bp-friends/bp-friends-widgets.php +3 -174
  154. bp-friends/classes/class-bp-core-friends-widget.php +189 -0
  155. bp-friends/classes/class-bp-friends-component.php +264 -0
  156. bp-friends/classes/class-bp-friends-friendship.php +14 -13
  157. bp-friends/js/widget-friends.min.js +1 -1
  158. bp-groups/admin/js/admin.min.js +1 -1
  159. bp-groups/bp-groups-actions.php +50 -37
  160. bp-groups/bp-groups-activity.php +24 -25
  161. bp-groups/bp-groups-admin.php +78 -701
  162. bp-groups/bp-groups-adminbar.php +9 -8
  163. bp-groups/bp-groups-cache.php +11 -5
  164. bp-groups/bp-groups-classes.php +1 -0
  165. bp-groups/bp-groups-filters.php +66 -23
  166. bp-groups/bp-groups-forums.php +8 -16
  167. bp-groups/bp-groups-functions.php +170 -106
  168. bp-groups/bp-groups-loader.php +2 -790
  169. bp-groups/bp-groups-notifications.php +93 -423
  170. bp-groups/bp-groups-screens.php +94 -310
  171. bp-groups/bp-groups-template.php +850 -1143
  172. bp-groups/bp-groups-widgets.php +15 -177
  173. bp-groups/classes/class-bp-group-extension.php +107 -99
  174. bp-groups/classes/class-bp-group-member-query.php +25 -24
  175. bp-groups/classes/class-bp-groups-component.php +814 -0
  176. bp-groups/classes/class-bp-groups-group-members-template.php +278 -0
  177. bp-groups/classes/class-bp-groups-group.php +112 -69
  178. bp-groups/classes/class-bp-groups-invite-template.php +270 -0
  179. bp-groups/classes/class-bp-groups-list-table.php +641 -0
  180. bp-groups/classes/class-bp-groups-member-suggestions.php +3 -2
  181. bp-groups/classes/class-bp-groups-member.php +101 -51
  182. bp-groups/classes/class-bp-groups-membership-requests-template.php +255 -0
  183. bp-groups/classes/class-bp-groups-template.php +397 -0
  184. bp-groups/classes/class-bp-groups-theme-compat.php +263 -0
  185. bp-groups/classes/class-bp-groups-widget.php +221 -0
  186. bp-groups/js/widget-groups.min.js +1 -1
  187. bp-loader.php +32 -25
  188. bp-members/admin/bp-members-admin-classes.php +5 -764
  189. bp-members/admin/js/admin.min.js +1 -1
  190. bp-members/bp-members-actions.php +1 -0
  191. bp-members/bp-members-activity.php +1 -0
  192. bp-members/bp-members-admin.php +2 -1969
  193. bp-members/bp-members-adminbar.php +1 -0
  194. bp-members/bp-members-cache.php +1 -2
  195. bp-members/bp-members-classes.php +1 -0
  196. bp-members/bp-members-filters.php +1 -0
  197. bp-members/bp-members-functions.php +17 -55
  198. bp-members/bp-members-loader.php +2 -301
  199. bp-members/bp-members-screens.php +5 -331
  200. bp-members/bp-members-template.php +81 -275
  201. bp-members/bp-members-widgets.php +6 -518
  202. bp-members/classes/class-bp-core-members-template.php +276 -0
  203. bp-members/classes/class-bp-core-members-widget.php +244 -0
  204. bp-members/classes/class-bp-core-recently-active-widget.php +167 -0
  205. bp-members/classes/class-bp-core-whos-online-widget.php +167 -0
  206. bp-members/classes/class-bp-members-admin.php +2020 -0
  207. bp-members/classes/class-bp-members-component.php +315 -0
  208. bp-members/classes/class-bp-members-list-table.php +387 -0
  209. bp-members/classes/class-bp-members-ms-list-table.php +389 -0
  210. bp-members/classes/class-bp-members-theme-compat.php +215 -0
  211. bp-members/classes/class-bp-registration-theme-compat.php +140 -0
  212. bp-members/classes/class-bp-signup.php +1 -2
  213. bp-messages/bp-messages-actions.php +1 -0
  214. bp-messages/bp-messages-cache.php +1 -0
  215. bp-messages/bp-messages-classes.php +1 -0
  216. bp-messages/bp-messages-cssjs.php +18 -5
  217. bp-messages/bp-messages-filters.php +8 -0
  218. bp-messages/bp-messages-functions.php +1 -0
  219. bp-messages/bp-messages-loader.php +2 -328
  220. bp-messages/bp-messages-notifications.php +30 -90
  221. bp-messages/bp-messages-screens.php +1 -0
  222. bp-messages/bp-messages-star.php +1 -2
  223. bp-messages/bp-messages-template.php +6 -510
  224. bp-messages/bp-messages-widgets.php +3 -110
  225. bp-messages/classes/class-bp-messages-box-template.php +347 -0
  226. bp-messages/classes/class-bp-messages-component.php +347 -0
  227. bp-messages/classes/class-bp-messages-message.php +2 -1
  228. bp-messages/classes/class-bp-messages-notice.php +2 -1
  229. bp-messages/classes/class-bp-messages-sitewide-notices-widget.php +121 -0
  230. bp-messages/classes/class-bp-messages-thread-template.php +186 -0
  231. bp-messages/classes/class-bp-messages-thread.php +1 -0
  232. {bp-core/deprecated → bp-messages}/css/autocomplete/jquery.autocompletefb-rtl.css +0 -0
  233. {bp-core/deprecated → bp-messages}/css/autocomplete/jquery.autocompletefb-rtl.min.css +0 -0
  234. {bp-core/deprecated → bp-messages}/css/autocomplete/jquery.autocompletefb.css +0 -0
  235. {bp-core/deprecated → bp-messages}/css/autocomplete/jquery.autocompletefb.min.css +0 -0
  236. {bp-core/deprecated → bp-messages}/js/autocomplete/jquery.autocomplete.js +0 -0
  237. {bp-core/deprecated → bp-messages}/js/autocomplete/jquery.autocomplete.min.js +1 -1
  238. {bp-core/deprecated → bp-messages}/js/autocomplete/jquery.autocompletefb.js +7 -8
  239. {bp-core/deprecated → bp-messages}/js/autocomplete/jquery.autocompletefb.min.js +2 -2
  240. {bp-core/deprecated → bp-messages}/js/autocomplete/jquery.bgiframe.js +0 -0
  241. {bp-core/deprecated → bp-messages}/js/autocomplete/jquery.bgiframe.min.js +1 -1
  242. {bp-core/deprecated → bp-messages}/js/autocomplete/jquery.dimensions.js +0 -0
  243. {bp-core/deprecated → bp-messages}/js/autocomplete/jquery.dimensions.min.js +1 -1
  244. {bp-core/deprecated → bp-messages}/js/autocomplete/license.bgiframe.txt +0 -0
  245. bp-notifications/bp-notifications-actions.php +1 -0
  246. bp-notifications/bp-notifications-adminbar.php +1 -0
  247. bp-notifications/bp-notifications-cache.php +3 -3
  248. bp-notifications/bp-notifications-functions.php +21 -0
  249. bp-notifications/bp-notifications-loader.php +1 -250
  250. bp-notifications/bp-notifications-screens.php +1 -0
  251. bp-notifications/bp-notifications-template.php +15 -347
  252. bp-notifications/classes/class-bp-notifications-component.php +266 -0
  253. bp-notifications/classes/class-bp-notifications-template.php +356 -0
  254. bp-settings/bp-settings-actions.php +79 -97
  255. bp-settings/bp-settings-functions.php +1 -0
  256. bp-settings/bp-settings-loader.php +7 -192
  257. bp-settings/bp-settings-screens.php +1 -0
  258. bp-settings/bp-settings-template.php +5 -8
  259. bp-settings/classes/class-bp-settings-component.php +218 -0
  260. bp-templates/bp-legacy/buddypress-functions.php +2 -2
  261. bp-templates/bp-legacy/buddypress/assets/emails/single-bp-email.php +192 -0
  262. bp-templates/bp-legacy/buddypress/groups/index.php +12 -12
  263. bp-templates/bp-legacy/buddypress/groups/single/admin.php +2 -2
  264. bp-templates/bp-legacy/buddypress/groups/single/request-membership.php +1 -1
  265. bp-templates/bp-legacy/buddypress/members/index.php +4 -4
  266. bp-templates/bp-legacy/buddypress/members/single/messages/compose.php +1 -1
  267. bp-templates/bp-legacy/buddypress/members/single/messages/messages-loop.php +10 -1
  268. bp-templates/bp-legacy/buddypress/members/single/messages/notices-loop.php +1 -1
  269. bp-templates/bp-legacy/buddypress/members/single/messages/single.php +10 -1
  270. bp-templates/bp-legacy/buddypress/members/single/profile/edit.php +1 -1
  271. bp-templates/bp-legacy/css/buddypress-rtl.css +33 -33
  272. bp-templates/bp-legacy/css/buddypress-rtl.min.css +1 -1
  273. bp-templates/bp-legacy/css/buddypress.css +33 -33
  274. bp-templates/bp-legacy/css/buddypress.min.css +1 -1
  275. bp-templates/bp-legacy/css/twentyfifteen-rtl.css +39 -14
  276. bp-templates/bp-legacy/css/twentyfifteen-rtl.min.css +1 -1
  277. bp-templates/bp-legacy/css/twentyfifteen.css +39 -14
  278. bp-templates/bp-legacy/css/twentyfifteen.min.css +1 -1
  279. bp-templates/bp-legacy/css/twentyfifteen.scss +68 -41
  280. bp-templates/bp-legacy/css/twentyfourteen-rtl.css +54 -13
  281. bp-templates/bp-legacy/css/twentyfourteen-rtl.min.css +1 -1
  282. bp-templates/bp-legacy/css/twentyfourteen.css +54 -13
  283. bp-templates/bp-legacy/css/twentyfourteen.min.css +1 -1
  284. bp-templates/bp-legacy/css/twentyfourteen.scss +73 -22
  285. bp-templates/bp-legacy/css/twentysixteen-rtl.css +53 -8
  286. bp-templates/bp-legacy/css/twentysixteen-rtl.min.css +1 -1
  287. bp-templates/bp-legacy/css/twentysixteen.css +53 -8
  288. bp-templates/bp-legacy/css/twentysixteen.min.css +1 -1
  289. bp-templates/bp-legacy/css/twentysixteen.scss +77 -12
  290. bp-templates/bp-legacy/css/twentythirteen-rtl.css +43 -14
  291. bp-templates/bp-legacy/css/twentythirteen-rtl.min.css +1 -1
  292. bp-templates/bp-legacy/css/twentythirteen.css +43 -14
  293. bp-templates/bp-legacy/css/twentythirteen.min.css +1 -1
  294. bp-templates/bp-legacy/css/twentythirteen.scss +71 -28
  295. bp-templates/bp-legacy/css/twentytwelve-rtl.css +1991 -0
  296. bp-templates/bp-legacy/css/twentytwelve-rtl.min.css +1 -0
  297. bp-templates/bp-legacy/css/twentytwelve.css +1991 -0
  298. bp-templates/bp-legacy/css/twentytwelve.min.css +1 -0
  299. bp-templates/bp-legacy/css/twentytwelve.scss +2491 -0
  300. bp-templates/bp-legacy/js/buddypress.min.js +1 -1
  301. bp-templates/bp-legacy/js/password-verify.min.js +1 -1
  302. bp-xprofile/admin/js/admin.js +11 -0
  303. bp-xprofile/admin/js/admin.min.js +2 -2
  304. bp-xprofile/bp-xprofile-actions.php +3 -2
  305. bp-xprofile/bp-xprofile-activity.php +1 -7
  306. bp-xprofile/bp-xprofile-admin.php +20 -471
  307. bp-xprofile/bp-xprofile-cache.php +3 -4
  308. bp-xprofile/bp-xprofile-caps.php +0 -1
  309. bp-xprofile/bp-xprofile-classes.php +1 -0
  310. bp-xprofile/bp-xprofile-cssjs.php +10 -0
  311. bp-xprofile/bp-xprofile-filters.php +22 -16
  312. bp-xprofile/bp-xprofile-functions.php +56 -27
  313. bp-xprofile/bp-xprofile-loader.php +5 -415
  314. bp-xprofile/bp-xprofile-notifications.php +9 -3
  315. bp-xprofile/bp-xprofile-screens.php +2 -1
  316. bp-xprofile/bp-xprofile-settings.php +1 -1
  317. bp-xprofile/bp-xprofile-template.php +264 -309
  318. bp-xprofile/classes/class-bp-xprofile-component.php +436 -0
  319. bp-xprofile/classes/class-bp-xprofile-data-template.php +344 -0
  320. bp-xprofile/classes/class-bp-xprofile-field-type-checkbox.php +17 -1
  321. bp-xprofile/classes/class-bp-xprofile-field-type-datebox.php +7 -4
  322. bp-xprofile/classes/class-bp-xprofile-field-type-multiselectbox.php +1 -0
  323. bp-xprofile/classes/class-bp-xprofile-field-type-number.php +1 -0
  324. bp-xprofile/classes/class-bp-xprofile-field-type-placeholder.php +1 -0
  325. bp-xprofile/classes/class-bp-xprofile-field-type-radiobutton.php +1 -0
  326. bp-xprofile/classes/class-bp-xprofile-field-type-selectbox.php +1 -0
  327. bp-xprofile/classes/class-bp-xprofile-field-type-textarea.php +1 -0
  328. bp-xprofile/classes/class-bp-xprofile-field-type-textbox.php +1 -0
  329. bp-xprofile/classes/class-bp-xprofile-field-type-url.php +9 -9
  330. bp-xprofile/classes/class-bp-xprofile-field-type.php +10 -11
  331. bp-xprofile/classes/class-bp-xprofile-field.php +97 -40
  332. bp-xprofile/classes/class-bp-xprofile-group.php +10 -15
  333. bp-xprofile/classes/class-bp-xprofile-meta-query.php +5 -4
  334. bp-xprofile/classes/class-bp-xprofile-profiledata.php +91 -4
  335. bp-xprofile/classes/class-bp-xprofile-query.php +6 -12
  336. bp-xprofile/classes/class-bp-xprofile-user-admin.php +479 -0
  337. buddypress.pot +3478 -2825
  338. composer.json +31 -31
  339. readme.txt +3 -18
bp-activity/admin/js/admin.min.js CHANGED
@@ -1,2 +1,2 @@
1
- /*! buddypress - v2.4.3 - 2015-12-14 7:03:28 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
!function(a){var b={init:function(){a(document).on("click",".row-actions a.reply",b.open),a(document).on("click","#bp-activities-container a.cancel",b.close),a(document).on("click","#bp-activities-container a.save",b.send),a(document).on("keyup","#bp-activities:visible",function(a){27===a.which&&b.close()})},open:function(){var b=a("#bp-activities-container").hide();return a(this).parents("tr").after(b),b.fadeIn("300"),a("#bp-activities").focus(),!1},close:function(){return a("#bp-activities-container").fadeOut("200",function(){a("#bp-activities").val("").blur(),a("#bp-replysubmit .error").html("").hide(),a("#bp-replysubmit .waiting").hide()}),!1},send:function(){a("#bp-replysubmit .error").hide(),a("#bp-replysubmit .waiting").show();var c={};return c["_ajax_nonce-bp-activity-admin-reply"]=a('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val(),c.action="bp-activity-admin-reply",c.content=a("#bp-activities").val(),c.parent_id=a("#bp-activities-container").prev().data("parent_id"),c.root_id=a("#bp-activities-container").prev().data("root_id"),a.ajax({data:c,type:"POST",url:ajaxurl,error:function(a){b.error(a)},success:function(a){b.show(a)}}),!1},error:function(b){var c=b.statusText;a("#bp-replysubmit .waiting").hide(),b.responseText&&(c=b.responseText.replace(/<.[^<>]*?>/g,"")),c&&a("#bp-replysubmit .error").html(c).show()},show:function(c){var d,e,f;return"string"==typeof c?(b.error({responseText:c}),!1):(f=wpAjax.parseAjaxResponse(c),f.errors?(b.error({responseText:wpAjax.broken}),!1):(f=f.responses[0],void a("#bp-activities-container").fadeOut("200",function(){a("#bp-activities").val("").blur(),a("#bp-replysubmit .error").html("").hide(),a("#bp-replysubmit .waiting").hide(),a("#bp-activities-container").before(f.data),e=a("#activity-"+f.id),d=e.closest(".widefat").css("backgroundColor"),e.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:d},300)})))}};a(document).ready(function(){b.init(),a("#bp_activity_action h3, #bp_activity_content h3").unbind("click"),"undefined"!=typeof postboxes&&postboxes.add_postbox_toggles(bp_activity_admin_vars.page)})}(jQuery);
1
+ /*! buddypress - v2.4.0 - 2016-02-09 3:32:09 AM UTC - https://wordpress.org/plugins/buddypress/ */
2
!function(a){var b={init:function(){a(document).on("click",".row-actions a.reply",b.open),a(document).on("click","#bp-activities-container a.cancel",b.close),a(document).on("click","#bp-activities-container a.save",b.send),a(document).on("keyup","#bp-activities:visible",function(a){27===a.which&&b.close()})},open:function(){var b=a("#bp-activities-container").hide();return a(this).parents("tr").after(b),b.fadeIn("300"),a("#bp-activities").focus(),!1},close:function(){return a("#bp-activities-container").fadeOut("200",function(){a("#bp-activities").val("").blur(),a("#bp-replysubmit .error").html("").hide(),a("#bp-replysubmit .waiting").hide()}),!1},send:function(){a("#bp-replysubmit .error").hide(),a("#bp-replysubmit .waiting").show();var c={};return c["_ajax_nonce-bp-activity-admin-reply"]=a('#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]').val(),c.action="bp-activity-admin-reply",c.content=a("#bp-activities").val(),c.parent_id=a("#bp-activities-container").prev().data("parent_id"),c.root_id=a("#bp-activities-container").prev().data("root_id"),a.ajax({data:c,type:"POST",url:ajaxurl,error:function(a){b.error(a)},success:function(a){b.show(a)}}),!1},error:function(b){var c=b.statusText;a("#bp-replysubmit .waiting").hide(),b.responseText&&(c=b.responseText.replace(/<.[^<>]*?>/g,"")),c&&a("#bp-replysubmit .error").html(c).show()},show:function(c){var d,e,f;return"string"==typeof c?(b.error({responseText:c}),!1):(f=wpAjax.parseAjaxResponse(c),f.errors?(b.error({responseText:wpAjax.broken}),!1):(f=f.responses[0],void a("#bp-activities-container").fadeOut("200",function(){a("#bp-activities").val("").blur(),a("#bp-replysubmit .error").html("").hide(),a("#bp-replysubmit .waiting").hide(),a("#bp-activities-container").before(f.data),e=a("#activity-"+f.id),d=e.closest(".widefat").css("backgroundColor"),e.animate({backgroundColor:"#CEB"},300).animate({backgroundColor:d},300)})))}};a(document).ready(function(){b.init(),a("#bp_activity_action h3, #bp_activity_content h3").unbind("click"),"undefined"!=typeof postboxes&&postboxes.add_postbox_toggles(bp_activity_admin_vars.page)})}(jQuery);
bp-activity/bp-activity-actions.php CHANGED
@@ -6,6 +6,7 @@
6
*
7
* @package BuddyPress
8
* @subpackage ActivityActions
9
*/
10
11
// Exit if accessed directly.
@@ -105,7 +106,7 @@ function bp_activity_action_permalink_router() {
105
*
106
* @since 1.2.2
107
*
108
- * @param array Array with url to redirect to and activity related to the redirect.
109
*/
110
if ( ! $redirect = apply_filters_ref_array( 'bp_activity_permalink_redirect_url', array( $redirect, &$activity ) ) ) {
111
bp_core_redirect( bp_get_root_domain() );
@@ -185,7 +186,7 @@ function bp_activity_action_delete_activity( $activity_id = 0 ) {
185
do_action( 'bp_activity_action_delete_activity', $activity_id, $activity->user_id );
186
187
// Check for the redirect query arg, otherwise let WP handle things.
188
- if ( !empty( $_GET['redirect_to'] ) )
189
bp_core_redirect( esc_url( $_GET['redirect_to'] ) );
190
else
191
bp_core_redirect( wp_get_referer() );
@@ -254,7 +255,7 @@ function bp_activity_action_spam_activity( $activity_id = 0 ) {
254
do_action( 'bp_activity_action_spam_activity', $activity_id, $activity->user_id );
255
256
// Check for the redirect query arg, otherwise let WP handle things.
257
- if ( !empty( $_GET['redirect_to'] ) )
258
bp_core_redirect( esc_url( $_GET['redirect_to'] ) );
259
else
260
bp_core_redirect( wp_get_referer() );
@@ -796,7 +797,28 @@ function bp_activity_catch_transition_post_type_status( $new_status, $old_status
796
if ( $new_status === $old_status ) {
797
// An edit of an existing post should update the existing activity item.
798
if ( $new_status == 'publish' ) {
799
- bp_activity_post_type_update( $post );
800
}
801
802
return;
@@ -827,6 +849,143 @@ function bp_activity_catch_transition_post_type_status( $new_status, $old_status
827
} elseif ( 'publish' === $old_status ) {
828
// Some form of pending status - only remove the activity entry.
829
bp_activity_post_type_unpublish( $post->ID, $post );
830
}
831
}
832
add_action( 'transition_post_status', 'bp_activity_catch_transition_post_type_status', 10, 3 );
6
*
7
* @package BuddyPress
8
* @subpackage ActivityActions
9
+ * @since 1.5.0
10
*/
11
12
// Exit if accessed directly.
106
*
107
* @since 1.2.2
108
*
109
+ * @param array $value Array with url to redirect to and activity related to the redirect.
110
*/
111
if ( ! $redirect = apply_filters_ref_array( 'bp_activity_permalink_redirect_url', array( $redirect, &$activity ) ) ) {
112
bp_core_redirect( bp_get_root_domain() );
186
do_action( 'bp_activity_action_delete_activity', $activity_id, $activity->user_id );
187
188
// Check for the redirect query arg, otherwise let WP handle things.
189
+ if ( !empty( $_GET['redirect_to'] ) )
190
bp_core_redirect( esc_url( $_GET['redirect_to'] ) );
191
else
192
bp_core_redirect( wp_get_referer() );
255
do_action( 'bp_activity_action_spam_activity', $activity_id, $activity->user_id );
256
257
// Check for the redirect query arg, otherwise let WP handle things.
258
+ if ( !empty( $_GET['redirect_to'] ) )
259
bp_core_redirect( esc_url( $_GET['redirect_to'] ) );
260
else
261
bp_core_redirect( wp_get_referer() );
797
if ( $new_status === $old_status ) {
798
// An edit of an existing post should update the existing activity item.
799
if ( $new_status == 'publish' ) {
800
+ $edit = bp_activity_post_type_update( $post );
801
+
802
+ // Post was never recorded into activity stream, so record it now!
803
+ if ( null === $edit ) {
804
+ bp_activity_post_type_publish( $post->ID, $post );
805
+ }
806
+
807
+ // Allow plugins to eventually deal with other post statuses.
808
+ } else {
809
+ /**
810
+ * Fires when editing the post and the new status is not 'publish'.
811
+ *
812
+ * This is a variable filter that is dependent on the post type
813
+ * being untrashed.
814
+ *
815
+ * @since 2.5.0
816
+ *
817
+ * @param WP_Post $post Post data.
818
+ * @param string $new_status New status for the post.
819
+ * @param string $old_status Old status for the post.
820
+ */
821
+ do_action( 'bp_activity_post_type_edit_' . $post->post_type, $post, $new_status, $old_status );
822
}
823
824
return;
849
} elseif ( 'publish' === $old_status ) {
850
// Some form of pending status - only remove the activity entry.
851
bp_activity_post_type_unpublish( $post->ID, $post );
852
+
853
+ // For any other cases, allow plugins to eventually deal with it.
854
+ } else {
855
+ /**
856
+ * Fires when the old and the new post status are not 'publish'.
857
+ *
858
+ * This is a variable filter that is dependent on the post type
859
+ * being untrashed.
860
+ *
861
+ * @since 2.5.0
862
+ *
863
+ * @param WP_Post $post Post data.
864
+ * @param string $new_status New status for the post.
865
+ * @param string $old_status Old status for the post.
866
+ */
867
+ do_action( 'bp_activity_post_type_transition_status_' . $post->post_type, $post, $new_status, $old_status );
868
}
869
}
870
add_action( 'transition_post_status', 'bp_activity_catch_transition_post_type_status', 10, 3 );
871
+
872
+ /**
873
+ * When a post type comment status transition occurs, update the relevant activity's status.
874
+ *
875
+ * @since 2.5.0
876
+ *
877
+ * @param string $new_status New comment status.
878
+ * @param string $old_status Previous comment status.
879
+ * @param WP_Comment $comment Comment data.
880
+ */
881
+ function bp_activity_transition_post_type_comment_status( $new_status, $old_status, $comment ) {
882
+ $post_type = get_post_type( $comment->comment_post_ID );
883
+ if ( ! $post_type ) {
884
+ return;
885
+ }
886
+
887
+ // Get the post type tracking args.
888
+ $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
889
+
890
+ // Bail if the activity type does not exist
891
+ if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
892
+ return false;
893
+
894
+ // Set the $activity_comment_object
895
+ } else {
896
+ $activity_comment_object = $activity_post_object->comments_tracking;
897
+ }
898
+
899
+ // Init an empty activity ID
900
+ $activity_id = 0;
901
+
902
+ /**
903
+ * Activity currently doesn't have any concept of a trash, or an unapproved/approved state.
904
+ *
905
+ * If a blog comment transitions to a "delete" or "hold" status, delete the activity item.
906
+ * If a blog comment transitions to trashed, or spammed, mark the activity as spam.
907
+ * If a blog comment transitions to approved (and the activity exists), mark the activity as ham.
908
+ * If a blog comment transitions to unapproved (and the activity exists), mark the activity as spam.
909
+ * Otherwise, record the comment into the activity stream.
910
+ */
911
+
912
+ // This clause handles delete/hold.
913
+ if ( in_array( $new_status, array( 'delete', 'hold' ) ) ) {
914
+ return bp_activity_post_type_remove_comment( $comment->comment_ID, $activity_post_object );
915
+
916
+ // These clauses handle trash, spam, and un-spams.
917
+ } elseif ( in_array( $new_status, array( 'trash', 'spam', 'unapproved' ) ) ) {
918
+ $action = 'spam_activity';
919
+ } elseif ( 'approved' == $new_status ) {
920
+ $action = 'ham_activity';
921
+ }
922
+
923
+ // Get the activity
924
+ if ( bp_disable_blogforum_comments() ) {
925
+ $activity_id = bp_activity_get_activity_id( array(
926
+ 'component' => $activity_comment_object->component_id,
927
+ 'item_id' => get_current_blog_id(),
928
+ 'secondary_item_id' => $comment->comment_ID,
929
+ 'type' => $activity_comment_object->action_id,
930
+ ) );
931
+ } else {
932
+ $activity_id = get_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', true );
933
+ }
934
+
935
+ /**
936
+ * Leave a chance to plugins to manage activity comments differently.
937
+ *
938
+ * @since 2.5.0
939
+ *
940
+ * @param bool $value True to override BuddyPress management.
941
+ * @param string $post_type The post type name.
942
+ * @param int $activity_id The post type activity (0 if not found).
943
+ * @param string $new_status The new status of the post type comment.
944
+ * @param string $old_status The old status of the post type comment.
945
+ * @param WP_Comment $comment Comment data.
946
+ */
947
+ if ( true === apply_filters( 'bp_activity_pre_transition_post_type_comment_status', false, $post_type, $activity_id, $new_status, $old_status, $comment ) ) {
948
+ return false;
949
+ }
950
+
951
+ // Check activity item exists
952
+ if ( empty( $activity_id ) ) {
953
+ // If no activity exists, but the comment has been approved, record it into the activity table.
954
+ if ( 'approved' == $new_status ) {
955
+ return bp_activity_post_type_comment( $comment->comment_ID, true, $activity_post_object );
956
+ }
957
+
958
+ return;
959
+ }
960
+
961
+ // Create an activity object
962
+ $activity = new BP_Activity_Activity( $activity_id );
963
+ if ( empty( $activity->component ) ) {
964
+ return;
965
+ }
966
+
967
+ // Spam/ham the activity if it's not already in that state
968
+ if ( 'spam_activity' === $action && ! $activity->is_spam ) {
969
+ bp_activity_mark_as_spam( $activity );
970
+ } elseif ( 'ham_activity' == $action) {
971
+ bp_activity_mark_as_ham( $activity );
972
+ }
973
+
974
+ // Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated
975
+ $post_type_comment_action = $activity_comment_object->action_id;
976
+ $comment_akismet_history = create_function( '$t', '$t[] = $post_type_comment_action; return $t;' );
977
+ add_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
978
+
979
+ // Make sure the activity change won't edit the comment if sync is on
980
+ remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
981
+
982
+ // Save the updated activity
983
+ $activity->save();
984
+
985
+ // Restore the action
986
+ add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
987
+
988
+ // Remove the "new_blog_comment" activity type whitelist so we don't break anything
989
+ remove_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
990
+ }
991
+ add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
bp-activity/bp-activity-admin.php CHANGED
@@ -16,6 +16,8 @@ defined( 'ABSPATH' ) || exit;
16
// Include WP's list table class.
17
if ( !class_exists( 'WP_List_Table' ) ) require( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
18
19
// Per_page screen option. Has to be hooked in extremely early.
20
if ( is_admin() && ! empty( $_REQUEST['page'] ) && 'bp-activity' == $_REQUEST['page'] )
21
add_filter( 'set-screen-option', 'bp_activity_admin_screen_options', 10, 3 );
@@ -296,13 +298,20 @@ function bp_activity_admin_load() {
296
'<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
297
'<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
298
);
299
}
300
301
// Enqueue CSS and JavaScript.
302
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 );
303
wp_localize_script( 'bp_activity_admin_js', 'bp_activity_admin_vars', array(
304
- 'page' => get_current_screen()->id
305
- ) );
306
wp_enqueue_style( 'bp_activity_admin_css', $bp->plugin_url . "bp-activity/admin/css/admin.{$min}css", array(), bp_get_version() );
307
308
wp_style_add_data( 'bp_activity_admin_css', 'rtl', true );
@@ -360,9 +369,8 @@ function bp_activity_admin_load() {
360
// "We'd like to shoot the monster, could you move, please?"
361
foreach ( $activity_ids as $activity_id ) {
362
// @todo: Check the permissions on each
363
- //if ( ! current_user_can( 'bp_edit_activity', $activity_id ) )
364
// continue;
365
-
366
// Get the activity from the database.
367
$activity = new BP_Activity_Activity( $activity_id );
368
if ( empty( $activity->component ) ) {
@@ -565,7 +573,7 @@ function bp_activity_admin_load() {
565
*
566
* @since 1.6.0
567
*
568
- * @param array Array holding activity object and ID that holds error.
569
*/
570
do_action_ref_array( 'bp_activity_admin_edit_after', array( &$activity, $error ) );
571
@@ -656,7 +664,7 @@ function bp_activity_admin_edit() {
656
do_action_ref_array( 'bp_activity_admin_edit', array( &$activity ) ); ?>
657
658
<div class="wrap">
659
- <h2><?php printf( __( 'Editing Activity (ID #%s)', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) ); ?></h2>
660
661
<?php if ( ! empty( $activity ) ) : ?>
662
@@ -667,14 +675,14 @@ function bp_activity_admin_edit() {
667
<div id="post-body-content">
668
<div id="postdiv">
669
<div id="bp_activity_action" class="postbox">
670
- <h3><?php _e( 'Action', 'buddypress' ); ?></h3>
671
<div class="inside">
672
<?php wp_editor( stripslashes( $activity->action ), 'bp-activities-action', array( 'media_buttons' => false, 'textarea_rows' => 7, 'teeny' => true, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ) ) ); ?>
673
</div>
674
</div>
675
676
<div id="bp_activity_content" class="postbox">
677
- <h3><?php _e( 'Content', 'buddypress' ); ?></h3>
678
<div class="inside">
679
<?php wp_editor( stripslashes( $activity->content ), 'bp-activities-content', array( 'media_buttons' => false, 'teeny' => true, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ) ) ); ?>
680
</div>
@@ -978,7 +986,7 @@ function bp_activity_admin_index() {
978
do_action( 'bp_activity_admin_index', $messages ); ?>
979
980
<div class="wrap">
981
- <h2>
982
<?php if ( !empty( $_REQUEST['aid'] ) ) : ?>
983
<?php printf( __( 'Activity related to ID #%s', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) ); ?>
984
<?php else : ?>
@@ -988,7 +996,7 @@ function bp_activity_admin_index() {
988
<?php if ( !empty( $_REQUEST['s'] ) ) : ?>
989
<span class="subtitle"><?php printf( __( 'Search results for &#8220;%s&#8221;', 'buddypress' ), wp_html_excerpt( esc_html( stripslashes( $_REQUEST['s'] ) ), 50 ) ); ?></span>
990
<?php endif; ?>
991
- </h2>
992
993
<?php // If the user has just made a change to an activity item, display the status messages. ?>
994
<?php if ( !empty( $messages ) ) : ?>
@@ -1010,7 +1018,7 @@ function bp_activity_admin_index() {
1010
<td colspan="4">
1011
<form method="get" action="">
1012
1013
- <h5 id="bp-replyhead"><?php _e( 'Reply to Activity', 'buddypress' ); ?></h5>
1014
<?php wp_editor( '', 'bp-activities', array( 'dfw' => false, 'media_buttons' => false, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ), 'tinymce' => false, ) ); ?>
1015
1016
<p id="bp-replysubmit" class="submit">
@@ -1032,812 +1040,3 @@ function bp_activity_admin_index() {
1032
1033
<?php
1034
}
1035
-
1036
- /**
1037
- * List table class for the Activity component admin page.
1038
- *
1039
- * @since 1.6.0
1040
- */
1041
- class BP_Activity_List_Table extends WP_List_Table {
1042
-
1043
- /**
1044
- * What type of view is being displayed?
1045
- *
1046
- * E.g. "all", "pending", "approved", "spam"...
1047
- *
1048
- * @since 1.6.0
1049
- * @var string $view
1050
- */
1051
- public $view = 'all';
1052
-
1053
- /**
1054
- * How many activity items have been marked as spam.
1055
- *
1056
- * @since 1.6.0
1057
- * @var int $spam_count
1058
- */
1059
- public $spam_count = 0;
1060
-
1061
- /**
1062
- * Store activity-to-user-ID mappings for use in the In Response To column.
1063
- *
1064
- * @since 1.6.0
1065
- * @var array $activity_user_id
1066
- */
1067
- protected $activity_user_id = array();
1068
-
1069
- /**
1070
- * If users can comment on blog & forum activity items.
1071
- *
1072
- * @link https://buddypress.trac.wordpress.org/ticket/6277
1073
- *
1074
- * @since 2.2.2
1075
- * @var bool $disable_blogforum_comments
1076
- */
1077
- public $disable_blogforum_comments = false;
1078
-
1079
- /**
1080
- * Constructor.
1081
- *
1082
- * @since 1.6.0
1083
- */
1084
- public function __construct() {
1085
-
1086
- // See if activity commenting is enabled for blog / forum activity items.
1087
- $this->disable_blogforum_comments = bp_disable_blogforum_comments();
1088
-
1089
- // Define singular and plural labels, as well as whether we support AJAX.
1090
- parent::__construct( array(
1091
- 'ajax' => false,
1092
- 'plural' => 'activities',
1093
- 'singular' => 'activity',
1094
- 'screen' => get_current_screen(),
1095
- ) );
1096
- }
1097
-
1098
- /**
1099
- * Handle filtering of data, sorting, pagination, and any other data manipulation prior to rendering.
1100
- *
1101
- * @since 1.6.0
1102
- */
1103
- function prepare_items() {
1104
-
1105
- // Option defaults.
1106
- $filter = array();
1107
- $include_id = false;
1108
- $search_terms = false;
1109
- $sort = 'DESC';
1110
- $spam = 'ham_only';
1111
-
1112
- // Set current page.
1113
- $page = $this->get_pagenum();
1114
-
1115
- // Set per page from the screen options.
1116
- $per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) );
1117
-
1118
- // Check if we're on the "Spam" view.
1119
- if ( !empty( $_REQUEST['activity_status'] ) && 'spam' == $_REQUEST['activity_status'] ) {
1120
- $spam = 'spam_only';
1121
- $this->view = 'spam';
1122
- }
1123
-
1124
- // Sort order.
1125
- if ( !empty( $_REQUEST['order'] ) && 'desc' != $_REQUEST['order'] )
1126
- $sort = 'ASC';
1127
-
1128
- // Order by.
1129
- /*if ( !empty( $_REQUEST['orderby'] ) ) {
1130
- }*/
1131
-
1132
- // Filter.
1133
- if ( !empty( $_REQUEST['activity_type'] ) )
1134
- $filter = array( 'action' => $_REQUEST['activity_type'] );
1135
-
1136
- // Are we doing a search?
1137
- if ( !empty( $_REQUEST['s'] ) )
1138
- $search_terms = $_REQUEST['s'];
1139
-
1140
- // Check if user has clicked on a specific activity (if so, fetch only that, and any related, activity).
1141
- if ( !empty( $_REQUEST['aid'] ) )
1142
- $include_id = (int) $_REQUEST['aid'];
1143
-
1144
- // Get the spam total (ignoring any search query or filter).
1145
- $spams = bp_activity_get( array(
1146
- 'display_comments' => 'stream',
1147
- 'show_hidden' => true,
1148
- 'spam' => 'spam_only',
1149
- 'count_total' => 'count_query',
1150
- ) );
1151
- $this->spam_count = $spams['total'];
1152
- unset( $spams );
1153
-
1154
- // Get the activities from the database.
1155
- $activities = bp_activity_get( array(
1156
- 'display_comments' => 'stream',
1157
- 'filter' => $filter,
1158
- 'in' => $include_id,
1159
- 'page' => $page,
1160
- 'per_page' => $per_page,
1161
- 'search_terms' => $search_terms,
1162
- 'show_hidden' => true,
1163
- // 'sort' => $sort,
1164
- 'spam' => $spam,
1165
- 'count_total' => 'count_query',
1166
- ) );
1167
-
1168
- // If we're viewing a specific activity, flatten all activities into a single array.
1169
- if ( $include_id ) {
1170
- $activities['activities'] = BP_Activity_List_Table::flatten_activity_array( $activities['activities'] );
1171
- $activities['total'] = count( $activities['activities'] );
1172
-
1173
- // Sort the array by the activity object's date_recorded value.
1174
- usort( $activities['activities'], create_function( '$a, $b', 'return $a->date_recorded > $b->date_recorded;' ) );
1175
- }
1176
-
1177
- // The bp_activity_get function returns an array of objects; cast these to arrays for WP_List_Table.
1178
- $new_activities = array();
1179
- foreach ( $activities['activities'] as $activity_item ) {
1180
- $new_activities[] = (array) $activity_item;
1181
-
1182
- // Build an array of activity-to-user ID mappings for better efficiency in the In Response To column.
1183
- $this->activity_user_id[$activity_item->id] = $activity_item->user_id;
1184
- }
1185
-
1186
- // Set raw data to display.
1187
- $this->items = $new_activities;
1188
-
1189
- // Store information needed for handling table pagination.
1190
- $this->set_pagination_args( array(
1191
- 'per_page' => $per_page,
1192
- 'total_items' => $activities['total'],
1193
- 'total_pages' => ceil( $activities['total'] / $per_page )
1194
- ) );
1195
-
1196
- // Don't truncate activity items; bp_activity_truncate_entry() needs to be used inside a BP_Activity_Template loop.
1197
- remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
1198
- }
1199
-
1200
- /**
1201
- * Get an array of all the columns on the page.
1202
- *
1203
- * @since 1.6.0
1204
- *
1205
- * @return array Column headers.
1206
- */
1207
- function get_column_info() {
1208
- $this->_column_headers = array(
1209
- $this->get_columns(),
1210
- array(),
1211
- $this->get_sortable_columns(),
1212
- $this->get_default_primary_column_name(),
1213
- );
1214
-
1215
- return $this->_column_headers;
1216
- }
1217
-
1218
- /**
1219
- * Get name of default primary column
1220
- *
1221
- * @since 2.3.3
1222
- *
1223
- * @return string
1224
- */
1225
- protected function get_default_primary_column_name() {
1226
- return 'author';
1227
- }
1228
-
1229
- /**
1230
- * Display a message on screen when no items are found (e.g. no search matches).
1231
- *
1232
- * @since 1.6.0
1233
- */
1234
- function no_items() {
1235
- _e( 'No activities found.', 'buddypress' );
1236
- }
1237
-
1238
- /**
1239
- * Output the Activity data table.
1240
- *
1241
- * @since 1.6.0
1242
- */
1243
- function display() {
1244
- $this->display_tablenav( 'top' ); ?>
1245
-
1246
- <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
1247
- <thead>
1248
- <tr>
1249
- <?php $this->print_column_headers(); ?>
1250
- </tr>
1251
- </thead>
1252
-
1253
- <tfoot>
1254
- <tr>
1255
- <?php $this->print_column_headers( false ); ?>
1256
- </tr>
1257
- </tfoot>
1258
-
1259
- <tbody id="the-comment-list">
1260
- <?php $this->display_rows_or_placeholder(); ?>
1261
- </tbody>
1262
- </table>
1263
- <?php
1264
-
1265
- $this->display_tablenav( 'bottom' );
1266
- }
1267
-
1268
- /**
1269
- * Generate content for a single row of the table.
1270
- *
1271
- * @since 1.6.0
1272
- *
1273
- * @param object $item The current item.
1274
- */
1275
- function single_row( $item ) {
1276
- static $even = false;
1277
-
1278
- if ( $even ) {
1279
- $row_class = ' class="even"';
1280
- } else {
1281
- $row_class = ' class="alternate odd"';
1282
- }
1283
-
1284
- if ( 'activity_comment' === $item['type'] ) {
1285
- $root_id = $item['item_id'];
1286
- } else {
1287
- $root_id = $item['id'];
1288
- }
1289
-
1290
- echo '<tr' . $row_class . ' id="activity-' . esc_attr( $item['id'] ) . '" data-parent_id="' . esc_attr( $item['id'] ) . '" data-root_id="' . esc_attr( $root_id ) . '">';
1291
- echo $this->single_row_columns( $item );
1292
- echo '</tr>';
1293
-
1294
- $even = ! $even;
1295
- }
1296
-
1297
- /**
1298
- * Get the list of views available on this table (e.g. "all", "spam").
1299
- *
1300
- * @since 1.6.0
1301
- */
1302
- function get_views() {
1303
- $url_base = add_query_arg( array( 'page' => 'bp-activity' ), bp_get_admin_url( 'admin.php' ) ); ?>
1304
-
1305
- <ul class="subsubsub">
1306
- <li class="all"><a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( 'spam' != $this->view ) echo 'current'; ?>"><?php _e( 'All', 'buddypress' ); ?></a> |</li>
1307
- <li class="spam"><a href="<?php echo esc_url( add_query_arg( array( 'activity_status' => 'spam' ), $url_base ) ); ?>" class="<?php if ( 'spam' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Spam <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->spam_count ) ); ?></a></li>
1308
-
1309
- <?php
1310
-
1311
- /**
1312
- * Fires inside listing of views so plugins can add their own.
1313
- *
1314
- * @since 1.6.0
1315
- *
1316
- * @param string $url_base Current URL base for view.
1317
- * @param string $view Current view being displayed.
1318
- */
1319
- do_action( 'bp_activity_list_table_get_views', $url_base, $this->view ); ?>
1320
- </ul>
1321
- <?php
1322
- }
1323
-
1324
- /**
1325
- * Get bulk actions.
1326
- *
1327
- * @since 1.6.0
1328
- *
1329
- * @return array Key/value pairs for the bulk actions dropdown.
1330
- */
1331
- function get_bulk_actions() {
1332
- $actions = array();
1333
- $actions['bulk_spam'] = __( 'Mark as Spam', 'buddypress' );
1334
- $actions['bulk_ham'] = __( 'Not Spam', 'buddypress' );
1335
- $actions['bulk_delete'] = __( 'Delete Permanently', 'buddypress' );
1336
-
1337
- /**
1338
- * Filters the default bulk actions so plugins can add custom actions.
1339
- *
1340
- * @since 1.6.0
1341
- *
1342
- * @param array $actions Default available actions for bulk operations.
1343
- */
1344
- return apply_filters( 'bp_activity_list_table_get_bulk_actions', $actions );
1345
- }
1346
-
1347
- /**
1348
- * Get the table column titles.
1349
- *
1350
- * @since 1.6.0
1351
- *
1352
- * @see WP_List_Table::single_row_columns()
1353
- *
1354
- * @return array The columns to appear in the Activity list table.
1355
- */
1356
- function get_columns() {
1357
- /**
1358
- * Filters the titles for the columns for the activity list table.
1359
- *
1360
- * @since 2.4.0
1361
- *
1362
- * @param array $value Array of slugs and titles for the columns.
1363
- */
1364
- return apply_filters( 'bp_activity_list_table_get_columns', array(
1365
- 'cb' => '<input name type="checkbox" />',
1366
- 'author' => _x('Author', 'Admin SWA column header', 'buddypress' ),
1367
- 'comment' => _x( 'Activity', 'Admin SWA column header', 'buddypress' ),
1368
- 'action' => _x( 'Action', 'Admin SWA column header', 'buddypress' ),
1369
- 'response' => _x( 'In Response To', 'Admin SWA column header', 'buddypress' ),
1370
- ) );
1371
- }
1372
-
1373
- /**
1374
- * Get the column names for sortable columns.
1375
- *
1376
- * Currently, returns an empty array (no columns are sortable).
1377
- *
1378
- * @since 1.6.0
1379
- * @todo For this to work, BP_Activity_Activity::get() needs updating
1380
- * to support ordering by specific fields.
1381
- *
1382
- * @return array The columns that can be sorted on the Activity screen.
1383
- */
1384
- function get_sortable_columns() {
1385
- return array();
1386
-
1387
- /*return array(
1388
- 'author' => array( 'activity_author', false ), // Intentionally not using "=>"
1389
- );*/
1390
- }
1391
-
1392
- /**
1393
- * Markup for the "filter" part of the form (i.e. which activity type to display).
1394
- *
1395
- * @since 1.6.0
1396
- *
1397
- * @param string $which 'top' or 'bottom'.
1398
- */
1399
- function extra_tablenav( $which ) {
1400
-
1401
- // Bail on bottom table nav.
1402
- if ( 'bottom' === $which ) {
1403
- return;
1404
- }
1405
-
1406
- // Is any filter currently selected?
1407
- $selected = ( ! empty( $_REQUEST['activity_type'] ) ) ? $_REQUEST['activity_type'] : '';
1408
-
1409
- // Get the actions.
1410
- $activity_actions = bp_activity_get_actions(); ?>
1411
-
1412
- <div class="alignleft actions">
1413
- <label for="activity-type" class="screen-reader-text"><?php _e( 'Filter by activity type', 'buddypress' ); ?></label>
1414
- <select name="activity_type" id="activity-type">
1415
- <option value="" <?php selected( ! $selected ); ?>><?php _e( 'View all actions', 'buddypress' ); ?></option>
1416
-
1417
- <?php foreach ( $activity_actions as $component => $actions ) : ?>
1418
-
1419
- <optgroup label="<?php echo ucfirst( $component ); ?>">
1420
-
1421
- <?php foreach ( $actions as $action_key => $action_values ) : ?>
1422
-
1423
- <?php
1424
-
1425
- // Skip the incorrectly named pre-1.6 action.
1426
- if ( 'friends_register_activity_action' !== $action_key ) : ?>
1427
-
1428
- <option value="<?php echo esc_attr( $action_key ); ?>" <?php selected( $action_key, $selected ); ?>><?php echo esc_html( $action_values[ 'value' ] ); ?></option>
1429
-
1430
- <?php endif; ?>
1431
-
1432
- <?php endforeach; ?>
1433
-
1434
- </optgroup>
1435
-
1436
- <?php endforeach; ?>
1437
-
1438
- </select>
1439
-
1440
- <?php submit_button( __( 'Filter', 'buddypress' ), 'secondary', false, false, array( 'id' => 'post-query-submit' ) ); ?>
1441
- </div>
1442
-
1443
- <?php
1444
- }
1445
-
1446
- /**
1447
- * Override WP_List_Table::row_actions().
1448
- *
1449
- * Basically a duplicate of the row_actions() method, but removes the
1450
- * unnecessary <button> addition.
1451
- *
1452
- * @since 2.3.3
1453
- * @since 2.3.4 Visibility set to public for compatibility with WP < 4.0.0.
1454
- *
1455
- * @param array $actions The list of actions.
1456
- * @param bool $always_visible Whether the actions should be always visible.
1457
- * @return string
1458
- */
1459
- public function row_actions( $actions, $always_visible = false ) {
1460
- $action_count = count( $actions );
1461
- $i = 0;
1462
-
1463
- if ( !$action_count )
1464
- return '';
1465
-
1466
- $out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
1467
- foreach ( $actions as $action => $link ) {
1468
- ++$i;
1469
- ( $i == $action_count ) ? $sep = '' : $sep = ' | ';
1470
- $out .= "<span class='$action'>$link$sep</span>";
1471
- }
1472
- $out .= '</div>';
1473
-
1474
- return $out;
1475
- }
1476
-
1477
- /**
1478
- * Checkbox column markup.
1479
- *
1480
- * @since 1.6.0
1481
- *
1482
- * @see WP_List_Table::single_row_columns()
1483
- *
1484
- * @param array $item A singular item (one full row).
1485
- */
1486
- function column_cb( $item ) {
1487
- printf( '<label class="screen-reader-text" for="aid-%1$d">' . __( 'Select activity item %1$d', 'buddypress' ) . '</label><input type="checkbox" name="aid[]" value="%1$d" id="aid-%1$d" />', $item['id'] );
1488
- }
1489
-
1490
- /**
1491
- * Author column markup.
1492
- *
1493
- * @since 1.6.0
1494
- *
1495
- * @see WP_List_Table::single_row_columns()
1496
- *
1497
- * @param array $item A singular item (one full row).
1498
- */
1499
- function column_author( $item ) {
1500
- echo '<strong>' . get_avatar( $item['user_id'], '32' ) . ' ' . bp_core_get_userlink( $item['user_id'] ) . '</strong>';
1501
- }
1502
-
1503
- /**
1504
- * Action column markup.
1505
- *
1506
- * @since 2.0.0
1507
- *
1508
- * @see WP_List_Table::single_row_columns()
1509
- *
1510
- * @param array $item A singular item (one full row).
1511
- */
1512
- function column_action( $item ) {
1513
- $actions = bp_activity_admin_get_activity_actions();
1514
-
1515
- if ( isset( $actions[ $item['type'] ] ) ) {
1516
- echo $actions[ $item['type'] ];
1517
- } else {
1518
- printf( __( 'Unregistered action - %s', 'buddypress' ), $item['type'] );
1519
- }
1520
- }
1521
-
1522
- /**
1523
- * Content column, and "quick admin" rollover actions.
1524
- *
1525
- * Called "comment" in the CSS so we can re-use some WP core CSS.
1526
- *
1527
- * @since 1.6.0
1528
- *
1529
- * @see WP_List_Table::single_row_columns()
1530
- *
1531
- * @param array $item A singular item (one full row).
1532
- */
1533
- function column_comment( $item ) {
1534
- // Determine what type of item (row) we're dealing with.
1535
- if ( $item['is_spam'] )
1536
- $item_status = 'spam';
1537
- else
1538
- $item_status = 'all';
1539
-
1540
- // Preorder items: Reply | Edit | Spam | Delete Permanently.
1541
- $actions = array(
1542
- 'reply' => '',
1543
- 'edit' => '',
1544
- 'spam' => '', 'unspam' => '',
1545
- 'delete' => '',
1546
- );
1547
-
1548
- // Build actions URLs.
1549
- $base_url = bp_get_admin_url( 'admin.php?page=bp-activity&amp;aid=' . $item['id'] );
1550
- $spam_nonce = esc_html( '_wpnonce=' . wp_create_nonce( 'spam-activity_' . $item['id'] ) );
1551
-
1552
- $delete_url = $base_url . "&amp;action=delete&amp;$spam_nonce";
1553
- $edit_url = $base_url . '&amp;action=edit';
1554
- $ham_url = $base_url . "&amp;action=ham&amp;$spam_nonce";
1555
- $spam_url = $base_url . "&amp;action=spam&amp;$spam_nonce";
1556
-
1557
- // Rollover actions.
1558
- // Reply - JavaScript only; implemented by AJAX.
1559
- if ( 'spam' != $item_status ) {
1560
- if ( $this->can_comment( $item ) ) {
1561
- $actions['reply'] = sprintf( '<a href="#" class="reply hide-if-no-js">%s</a>', __( 'Reply', 'buddypress' ) );
1562
- } else {
1563
- $actions['reply'] = sprintf( '<span class="form-input-tip" title="%s">%s</span>', __( 'Replies are disabled for this activity item', 'buddypress' ), __( 'Replies disabled', 'buddypress' ) );
1564
- }
1565
-
1566
- // Edit.
1567
- $actions['edit'] = sprintf( '<a href="%s">%s</a>', $edit_url, __( 'Edit', 'buddypress' ) );
1568
- }
1569
-
1570
- // Spam/unspam.
1571
- if ( 'spam' == $item_status )
1572
- $actions['unspam'] = sprintf( '<a href="%s">%s</a>', $ham_url, __( 'Not Spam', 'buddypress' ) );
1573
- else
1574
- $actions['spam'] = sprintf( '<a href="%s">%s</a>', $spam_url, __( 'Spam', 'buddypress' ) );
1575
-
1576
- // Delete.
1577
- $actions['delete'] = sprintf( '<a href="%s" onclick="%s">%s</a>', $delete_url, "javascript:return confirm('" . esc_js( __( 'Are you sure?', 'buddypress' ) ) . "'); ", __( 'Delete Permanently', 'buddypress' ) );
1578
-
1579
- // Start timestamp.
1580
- echo '<div class="submitted-on">';
1581
-
1582
- /**
1583
- * Filters available actions for plugins to alter.
1584
- *
1585
- * @since 1.6.0
1586
- *
1587
- * @param array $actions Array of available actions user could use.
1588
- * @param array $item Current item being added to page.
1589
- */
1590
- $actions = apply_filters( 'bp_activity_admin_comment_row_actions', array_filter( $actions ), $item );
1591
-
1592
- /* translators: 2: activity admin ui date/time */
1593
- printf(
1594
- __( 'Submitted on <a href="%1$s">%2$s at %3$s</a>', 'buddypress' ),
1595
- bp_activity_get_permalink( $item['id'] ),
1596
- date_i18n( bp_get_option( 'date_format' ), strtotime( $item['date_recorded'] ) ),
1597
- get_date_from_gmt( $item['date_recorded'], bp_get_option( 'time_format' ) )
1598
- );
1599
-
1600
- // End timestamp.
1601
- echo '</div>';
1602
-
1603
- // Get activity content - if not set, use the action.
1604
- if ( ! empty( $item['content'] ) ) {
1605
-
1606
- /**
1607
- * Filters current activity item content.
1608
- *
1609
- * @since 1.2.0
1610
- *
1611
- * @param array $item Array index holding current activity item content.
1612
- */
1613
- $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'] ) );
1614
- } else {
1615
- /**
1616
- * Filters current activity item action.
1617
- *
1618
- * @since 1.2.0
1619
- *
1620
- * @var array $item Array index holding current activity item action.
1621
- */
1622
- $content = apply_filters_ref_array( 'bp_get_activity_action', array( $item['action'] ) );
1623
- }
1624
-
1625
- /**
1626
- * Filter here to add extra output to the activity content into the Administration.
1627
- *
1628
- * @since 2.4.0
1629
- *
1630
- * @param string $content The activity content.
1631
- * @param array $item The activity object converted into an array.
1632
- */
1633
- echo apply_filters( 'bp_activity_admin_comment_content', $content, $item ) . ' ' . $this->row_actions( $actions );
1634
- }
1635
-
1636
- /**
1637
- * "In response to" column markup.
1638
- *
1639
- * @since 1.6.0
1640
- *
1641
- * @see WP_List_Table::single_row_columns()
1642
- *
1643
- * @param array $item A singular item (one full row).
1644
- */
1645
- function column_response( $item ) {
1646
-
1647
- // Is $item is a root activity?
1648
- ?>
1649
-
1650
- <div class="response-links">
1651
-
1652
- <?php
1653
- // Activity permalink
1654
- $activity_permalink = '';
1655
- if ( ! $item['is_spam'] ) {
1656
- $activity_permalink = '<a href="' . bp_activity_get_permalink( $item['id'], (object) $item ) . '" class="comments-view-item-link">' . __( 'View Activity', 'buddypress' ) . '</a>';
1657
- }
1658
-
1659
- /**
1660
- * Filters default list of default root activity types.
1661
- *
1662
- * @since 1.6.0
1663
- *
1664
- * @param array $value Array of default activity types.
1665
- * @param array $item Current item being displayed.
1666
- */
1667
- if ( empty( $item['item_id'] ) || ! in_array( $item['type'], apply_filters( 'bp_activity_admin_root_activity_types', array( 'activity_comment' ), $item ) ) ) {
1668
- echo $activity_permalink;
1669
-
1670
- $comment_count = !empty( $item['children'] ) ? bp_activity_recurse_comment_count( (object) $item ) : 0;
1671
- $root_activity_url = bp_get_admin_url( 'admin.php?page=bp-activity&amp;aid=' . $item['id'] );
1672
-
1673
- // If the activity has comments, display a link to the activity's permalink, with its comment count in a speech bubble.
1674
- if ( $comment_count ) {
1675
- $title_attr = sprintf( _n( '%s related activity', '%s related activities', $comment_count, 'buddypress' ), number_format_i18n( $comment_count ) );
1676
- printf( '<a href="%1$s" title="%2$s" class="post-com-count post-com-count-approved"><span class="comment-count comment-count-approved">%3$s</span></a>', esc_url( $root_activity_url ), esc_attr( $title_attr ), number_format_i18n( $comment_count ) );
1677
- }
1678
-
1679
- // For non-root activities, display a link to the replied-to activity's author's profile.
1680
- } else {
1681
- echo '<strong>' . get_avatar( $this->get_activity_user_id( $item['item_id'] ), '32' ) . ' ' . bp_core_get_userlink( $this->get_activity_user_id( $item['item_id'] ) ) . '</strong><br />';
1682
- echo $activity_permalink;
1683
- }
1684
- ?>
1685
-
1686
- </div>
1687
-
1688
- <?php
1689
- }
1690
-
1691
- /**
1692
- * Allow plugins to add their custom column.
1693
- *
1694
- * @since 2.4.0
1695
- *
1696
- * @param array $item Information about the current row.
1697
- * @param string $column_name The column name.
1698
- * @return string
1699
- */
1700
- public function column_default( $item = array(), $column_name = '' ) {
1701
-
1702
- /**
1703
- * Filters a string to allow plugins to add custom column content.
1704
- *
1705
- * @since 2.4.0
1706
- *
1707
- * @param string $value Empty string.
1708
- * @param string $column_name Name of the column being rendered.
1709
- * @param array $item The current activity item in the loop.
1710
- */
1711
- return apply_filters( 'bp_activity_admin_get_custom_column', '', $column_name, $item );
1712
- }
1713
-
1714
- /**
1715
- * Get the user id associated with a given activity item.
1716
- *
1717
- * Wraps bp_activity_get_specific(), with some additional logic for
1718
- * avoiding duplicate queries.
1719
- *
1720
- * @since 1.6.0
1721
- *
1722
- * @param int $activity_id Activity ID to retrieve User ID for.
1723
- * @return int User ID of the activity item in question.
1724
- */
1725
- protected function get_activity_user_id( $activity_id ) {
1726
- // If there is an existing activity/user ID mapping, just return the user ID.
1727
- if ( ! empty( $this->activity_user_id[$activity_id] ) ) {
1728
- return $this->activity_user_id[$activity_id];
1729
-
1730
- /*
1731
- * We don't have a mapping. This means the $activity_id is not on the current
1732
- * page of results, so fetch its details from the database.
1733
- */
1734
- } else {
1735
- $activity = bp_activity_get_specific( array( 'activity_ids' => $activity_id, 'show_hidden' => true, 'spam' => 'all', ) );
1736
-
1737
- /*
1738
- * If, somehow, the referenced activity has been deleted, leaving its associated
1739
- * activities as orphans, use the logged in user's ID to avoid errors.
1740
- */
1741
- if ( empty( $activity['activities'] ) )
1742
- return bp_loggedin_user_id();
1743
-
1744
- // Store the new activity/user ID mapping for any later re-use.
1745
- $this->activity_user_id[ $activity['activities'][0]->id ] = $activity['activities'][0]->user_id;
1746
-
1747
- // Return the user ID.
1748
- return $activity['activities'][0]->user_id;
1749
- }
1750
- }
1751
-
1752
- /**
1753
- * Checks if an activity item can be replied to.
1754
- *
1755
- * This method merges functionality from {@link bp_activity_can_comment()} and
1756
- * {@link bp_blogs_disable_activity_commenting()}. This is done because the activity
1757
- * list table doesn't use a BuddyPress activity loop, which prevents those
1758
- * functions from working as intended.
1759
- *
1760
- * @since 2.0.0
1761
- *
1762
- * @param array $item An array version of the BP_Activity_Activity object.
1763
- * @return bool $can_comment
1764
- */
1765
- protected function can_comment( $item ) {
1766
- $can_comment = true;
1767
-
1768
- if ( $this->disable_blogforum_comments ) {
1769
- switch ( $item['type'] ) {
1770
- case 'new_blog_post' :
1771
- case 'new_blog_comment' :
1772
- case 'new_forum_topic' :
1773
- case 'new_forum_post' :
1774
- $can_comment = false;
1775
- break;
1776
- }
1777
-
1778
- // Activity comments supported.
1779
- } else {
1780
- // Activity comment.
1781
- if ( 'activity_comment' == $item['type'] ) {
1782
- // Blogs.
1783
- if ( bp_is_active( 'blogs' ) ) {
1784
- // Grab the parent activity entry.
1785
- $parent_activity = new BP_Activity_Activity( $item['item_id'] );
1786
-
1787
- // Fetch blog post comment depth and if the blog post's comments are open.
1788
- bp_blogs_setup_activity_loop_globals( $parent_activity );
1789
-
1790
- // Check if the activity item can be replied to.
1791
- if ( false === bp_blogs_can_comment_reply( true, $item ) ) {
1792
- $can_comment = false;
1793
- }
1794
- }
1795
-
1796
- // Blog post.
1797
- } elseif ( 'new_blog_post' == $item['type'] ) {
1798
- if ( bp_is_active( 'blogs' ) ) {
1799
- bp_blogs_setup_activity_loop_globals( (object) $item );
1800
-
1801
- if ( empty( buddypress()->blogs->allow_comments[$item['id']] ) ) {
1802
- $can_comment = false;
1803
- }
1804
- }
1805
- }
1806
- }
1807
-
1808
- /**
1809
- * Filters if an activity item can be commented on or not.
1810
- *
1811
- * @since 2.0.0
1812
- *
1813
- * @param bool $can_comment Whether an activity item can be commented on or not.
1814
- */
1815
- return apply_filters( 'bp_activity_list_table_can_comment', $can_comment );
1816
- }
1817
-
1818
- /**
1819
- * Flatten the activity array.
1820
- *
1821
- * In some cases, BuddyPress gives us a structured tree of activity
1822
- * items plus their comments. This method converts it to a flat array.
1823
- *
1824
- * @since 1.6.0
1825
- *
1826
- * @param array $tree Source array.
1827
- * @return array Flattened array.
1828
- */
1829
- public static function flatten_activity_array( $tree ){
1830
- foreach ( (array) $tree as $node ) {
1831
- if ( isset( $node->children ) ) {
1832
-
1833
- foreach ( BP_Activity_List_Table::flatten_activity_array( $node->children ) as $child ) {
1834
- $tree[] = $child;
1835
- }
1836
-
1837
- unset( $node->children );
1838
- }
1839
- }
1840
-
1841
- return $tree;
1842
- }
1843
- }
16
// Include WP's list table class.
17
if ( !class_exists( 'WP_List_Table' ) ) require( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
18
19
+ require dirname( __FILE__ ) . '/classes/class-bp-activity-list-table.php';
20
+
21
// Per_page screen option. Has to be hooked in extremely early.
22
if ( is_admin() && ! empty( $_REQUEST['page'] ) && 'bp-activity' == $_REQUEST['page'] )
23
add_filter( 'set-screen-option', 'bp_activity_admin_screen_options', 10, 3 );
298
'<p><strong>' . __( 'For more information:', 'buddypress' ) . '</strong></p>' .
299
'<p>' . __( '<a href="https://buddypress.org/support/">Support Forums</a>', 'buddypress' ) . '</p>'
300
);
301
+
302
+ // Add accessible hidden heading and text for Activity screen pagination.
303
+ if ( bp_get_major_wp_version() >= 4.4 ) {
304
+ get_current_screen()->set_screen_reader_content( array(
305
+ 'heading_pagination' => __( 'Activity list navigation', 'buddypress' ),
306
+ ) );
307
+ }
308
}
309
310
// Enqueue CSS and JavaScript.
311
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 );
312
wp_localize_script( 'bp_activity_admin_js', 'bp_activity_admin_vars', array(
313
+ 'page' => get_current_screen()->id
314
+ ) );
315
wp_enqueue_style( 'bp_activity_admin_css', $bp->plugin_url . "bp-activity/admin/css/admin.{$min}css", array(), bp_get_version() );
316
317
wp_style_add_data( 'bp_activity_admin_css', 'rtl', true );
369
// "We'd like to shoot the monster, could you move, please?"
370
foreach ( $activity_ids as $activity_id ) {
371
// @todo: Check the permissions on each
372
+ // if ( ! current_user_can( 'bp_edit_activity', $activity_id ) )
373
// continue;
374
// Get the activity from the database.
375
$activity = new BP_Activity_Activity( $activity_id );
376
if ( empty( $activity->component ) ) {
573
*
574
* @since 1.6.0
575
*
576
+ * @param array $value Array holding activity object and ID that holds error.
577
*/
578
do_action_ref_array( 'bp_activity_admin_edit_after', array( &$activity, $error ) );
579
664
do_action_ref_array( 'bp_activity_admin_edit', array( &$activity ) ); ?>
665
666
<div class="wrap">
667
+ <h1><?php printf( __( 'Editing Activity (ID #%s)', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) ); ?></h1>
668
669
<?php if ( ! empty( $activity ) ) : ?>
670
675
<div id="post-body-content">
676
<div id="postdiv">
677
<div id="bp_activity_action" class="postbox">
678
+ <h2><?php _e( 'Action', 'buddypress' ); ?></h2>
679
<div class="inside">
680
<?php wp_editor( stripslashes( $activity->action ), 'bp-activities-action', array( 'media_buttons' => false, 'textarea_rows' => 7, 'teeny' => true, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ) ) ); ?>
681
</div>
682
</div>
683
684
<div id="bp_activity_content" class="postbox">
685
+ <h2><?php _e( 'Content', 'buddypress' ); ?></h2>
686
<div class="inside">
687
<?php wp_editor( stripslashes( $activity->content ), 'bp-activities-content', array( 'media_buttons' => false, 'teeny' => true, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ) ) ); ?>
688
</div>
986
do_action( 'bp_activity_admin_index', $messages ); ?>
987
988
<div class="wrap">
989
+ <h1>
990
<?php if ( !empty( $_REQUEST['aid'] ) ) : ?>
991
<?php printf( __( 'Activity related to ID #%s', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) ); ?>
992
<?php else : ?>
996
<?php if ( !empty( $_REQUEST['s'] ) ) : ?>
997
<span class="subtitle"><?php printf( __( 'Search results for &#8220;%s&#8221;', 'buddypress' ), wp_html_excerpt( esc_html( stripslashes( $_REQUEST['s'] ) ), 50 ) ); ?></span>
998
<?php endif; ?>
999
+ </h1>
1000
1001
<?php // If the user has just made a change to an activity item, display the status messages. ?>
1002
<?php if ( !empty( $messages ) ) : ?>
1018
<td colspan="4">
1019
<form method="get" action="">
1020
1021
+ <h3 id="bp-replyhead"><?php _e( 'Reply to Activity', 'buddypress' ); ?></h3>
1022
<?php wp_editor( '', 'bp-activities', array( 'dfw' => false, 'media_buttons' => false, 'quicktags' => array( 'buttons' => 'strong,em,link,block,del,ins,img,code,spell,close' ), 'tinymce' => false, ) ); ?>
1023
1024
<p id="bp-replysubmit" class="submit">
1040
1041
<?php
1042
}
bp-activity/bp-activity-akismet.php CHANGED
@@ -10,646 +10,7 @@
10
// Exit if accessed directly.
11
defined( 'ABSPATH' ) || exit;
12
13
- /**
14
- * Akismet support for the Activity component.
15
- *
16
- * @since 1.6.0
17
- * @since 2.3.0 We only support Akismet 3+.
18
- */
19
- class BP_Akismet {
20
-
21
- /**
22
- * The activity last marked as spam.
23
- *
24
- * @since 1.6.0
25
- *
26
- * @var BP_Activity_Activity
27
- */
28
- protected $last_activity = null;
29
-
30
- /**
31
- * Constructor.
32
- *
33
- * @since 1.6.0
34
- */
35
- public function __construct() {
36
- $this->setup_actions();
37
- }
38
-
39
- /**
40
- * Hook Akismet into the activity stream.
41
- *
42
- * @since 1.6.0
43
- */
44
- protected function setup_actions() {
45
- // Add nonces to activity stream lists.
46
- add_action( 'bp_after_activity_post_form', array( $this, 'add_activity_stream_nonce' ) );
47
- add_action( 'bp_activity_entry_comments', array( $this, 'add_activity_stream_nonce' ) );
48
-
49
- // Add a "mark as spam" button to individual activity items.
50
- add_action( 'bp_activity_entry_meta', array( $this, 'add_activity_spam_button' ) );
51
- add_action( 'bp_activity_comment_options', array( $this, 'add_activity_comment_spam_button' ) );
52
-
53
- // Check activity for spam.
54
- add_action( 'bp_activity_before_save', array( $this, 'check_activity' ), 4, 1 );
55
-
56
- // Tidy up member's latest (activity) update.
57
- add_action( 'bp_activity_posted_update', array( $this, 'check_member_activity_update' ), 1, 3 );
58
-
59
- // Hooks to extend Activity core spam/ham functions for Akismet.
60
- add_action( 'bp_activity_mark_as_spam', array( $this, 'mark_as_spam' ), 10, 2 );
61
- add_action( 'bp_activity_mark_as_ham', array( $this, 'mark_as_ham' ), 10, 2 );
62
-
63
- // Hook into the Activity wp-admin screen.
64
- add_action( 'bp_activity_admin_comment_row_actions', array( $this, 'comment_row_action' ), 10, 2 );
65
- add_action( 'bp_activity_admin_load', array( $this, 'add_history_metabox' ) );
66
- }
67
-
68
- /**
69
- * Add a history item to the hover links in an activity's row.
70
- *
71
- * This function lifted with love from the Akismet WordPress plugin's
72
- * akismet_comment_row_action() function. Thanks!
73
- *
74
- * @since 1.6.0
75
- *
76
- * @param array $actions The hover links.
77
- * @param array $activity The activity for the current row being processed.
78
- * @return array The hover links.
79
- */
80
- function comment_row_action( $actions, $activity ) {
81
- $akismet_result = bp_activity_get_meta( $activity['id'], '_bp_akismet_result' );
82
- $user_result = bp_activity_get_meta( $activity['id'], '_bp_akismet_user_result' );
83
- $desc = '';
84
-
85
- if ( !$user_result || $user_result == $akismet_result ) {
86
- // Show the original Akismet result if the user hasn't overridden it, or if their decision was the same.
87
- if ( 'true' == $akismet_result && $activity['is_spam'] )
88
- $desc = __( 'Flagged as spam by Akismet', 'buddypress' );
89
-
90
- elseif ( 'false' == $akismet_result && !$activity['is_spam'] )
91
- $desc = __( 'Cleared by Akismet', 'buddypress' );
92
-
93
- } else {
94
- $who = bp_activity_get_meta( $activity['id'], '_bp_akismet_user' );
95
-
96
- if ( 'true' == $user_result )
97
- $desc = sprintf( __( 'Flagged as spam by %s', 'buddypress' ), $who );
98
- else
99
- $desc = sprintf( __( 'Un-spammed by %s', 'buddypress' ), $who );
100
- }
101
-
102
- // Add a History item to the hover links, just after Edit.
103
- if ( $akismet_result ) {
104
- $b = array();
105
- foreach ( $actions as $k => $item ) {
106
- $b[ $k ] = $item;
107
- if ( $k == 'edit' )
108
- $b['history'] = '<a href="' . esc_url( bp_get_admin_url( 'admin.php?page=bp-activity&amp;action=edit&aid=' . $activity['id'] ) ) . '#bp_activity_history"> '. __( 'History', 'buddypress' ) . '</a>';
109
- }
110
-
111
- $actions = $b;
112
- }
113
-
114
- if ( $desc )
115
- echo '<span class="akismet-status"><a href="' . esc_url( bp_get_admin_url( 'admin.php?page=bp-activity&amp;action=edit&aid=' . $activity['id'] ) ) . '#bp_activity_history">' . htmlspecialchars( $desc ) . '</a></span>';
116
-
117
- /**
118
- * Filters the list of actions for the current activity's row.
119
- *
120
- * @since 1.6.0
121
- *
122
- * @param array $actions Array of available actions for the current activity item's row.
123
- */
124
- return apply_filters( 'bp_akismet_comment_row_action', $actions );
125
- }
126
-
127
- /**
128
- * Generate nonces for activity forms.
129
- *
130
- * These nonces appear in the member profile status form, as well as in
131
- * the reply form of each activity item. The nonces are, in turn, used
132
- * by Akismet to help detect spam activity.
133
- *
134
- * @since 1.6.0
135
- *
136
- * @see https://plugins.trac.wordpress.org/ticket/1232
137
- */
138
- public function add_activity_stream_nonce() {
139
- $form_id = '_bp_as_nonce';
140
- $value = '_bp_as_nonce_' . bp_loggedin_user_id();
141
-
142
- // If we're in the activity stream loop, we can use the current item's ID to make the nonce unique.
143
- if ( 'bp_activity_entry_comments' == current_filter() ) {
144
- $form_id .= '_' . bp_get_activity_id();
145
- $value .= '_' . bp_get_activity_id();
146
- }
147
-
148
- wp_nonce_field( $value, $form_id, false );
149
- }
150
-
151
- /**
152
- * Clean up the bp_latest_update usermeta in case of spamming.
153
- *
154
- * Run just after an update is posted, this method check to see whether
155
- * the newly created update has been marked as spam by Akismet. If so,
156
- * the cached update is cleared from the user's 'bp_latest_update'
157
- * usermeta, ensuring that it won't appear in the member header and
158
- * elsewhere in the theme.
159
- *
160
- * This can't be done in BP_Akismet::check_activity() due to the
161
- * default AJAX implementation; see bp_dtheme_post_update().
162
- *
163
- * @since 1.6.0
164
- *
165
- * @see bp_dtheme_post_update()
166
- *
167
- * @param string $content Activity update text.
168
- * @param int $user_id User ID.
169
- * @param int $activity_id Activity ID.
170
- */
171
- public function check_member_activity_update( $content, $user_id, $activity_id ) {
172
- // By default, only handle activity updates and activity comments.
173
- if ( empty( $this->last_activity ) || !in_array( $this->last_activity->type, BP_Akismet::get_activity_types() ) )
174
- return;
175
-
176
- // Was this $activity_id just marked as spam? If not, bail out.
177
- if ( !$this->last_activity->id || $activity_id != $this->last_activity->id || 'false' == $this->last_activity->akismet_submission['bp_as_result'] )
178
- return;
179
-
180
- // It was, so delete the member's latest activity update.
181
- bp_delete_user_meta( $user_id, 'bp_latest_update' );
182
- }
183
-
184
- /**
185
- * Adds a "mark as spam" button to each activity item for site admins.
186
- *
187
- * This function is intended to be used inside the activity stream loop.
188
- *
189
- * @since 1.6.0
190
- */
191
- public function add_activity_spam_button() {
192
- if ( !bp_activity_user_can_mark_spam() )
193
- return;
194
-
195
- // By default, only handle activity updates and activity comments.
196
- if ( !in_array( bp_get_activity_type(), BP_Akismet::get_activity_types() ) )
197
- return;
198
-
199
- bp_button(
200
- array(
201
- 'block_self' => false,
202
- 'component' => 'activity',
203
- 'id' => 'activity_make_spam_' . bp_get_activity_id(),
204
- 'link_class' => 'bp-secondary-action spam-activity confirm button item-button',
205
- 'link_href' => wp_nonce_url( bp_get_root_domain() . '/' . bp_get_activity_slug() . '/spam/' . bp_get_activity_id() . '/', 'bp_activity_akismet_spam_' . bp_get_activity_id() ),
206
- 'link_text' => __( 'Spam', 'buddypress' ),
207
- 'wrapper' => false,
208
- )
209
- );
210
- }
211
-
212
- /**
213
- * Adds a "mark as spam" button to each activity COMMENT item for site admins.
214
- *
215
- * This function is intended to be used inside the activity stream loop.
216
- *
217
- * @since 1.6.0
218
- */
219
- public function add_activity_comment_spam_button() {
220
- if ( !bp_activity_user_can_mark_spam() )
221
- return;
222
-
223
- // By default, only handle activity updates and activity comments.
224
- $current_comment = bp_activity_current_comment();
225
- if ( empty( $current_comment ) || !in_array( $current_comment->type, BP_Akismet::get_activity_types() ) )
226
- return;
227
-
228
- bp_button(
229
- array(
230
- 'block_self' => false,
231
- 'component' => 'activity',
232
- 'id' => 'activity_make_spam_' . bp_get_activity_comment_id(),
233
- 'link_class' => 'bp-secondary-action spam-activity-comment confirm',
234
- 'link_href' => wp_nonce_url( bp_get_root_domain() . '/' . bp_get_activity_slug() . '/spam/' . bp_get_activity_comment_id() . '/?cid=' . bp_get_activity_comment_id(), 'bp_activity_akismet_spam_' . bp_get_activity_comment_id() ),
235
- 'link_text' => __( 'Spam', 'buddypress' ),
236
- 'wrapper' => false,
237
- )
238
- );
239
- }
240
-
241
- /**
242
- * Get a filterable list of activity types that Akismet should automatically check for spam.
243
- *
244
- * @since 1.6.0
245
- *
246
- * @static
247
- *
248
- * @return array $value List of activity types.
249
- */
250
- public static function get_activity_types() {
251
-
252
- /**
253
- * Filters the list of activity types that Akismet should automatically check for spam.
254
- *
255
- * @since 1.6.0
256
- *
257
- * @param array Array of default activity types for Akismet to check.
258
- */
259
- return apply_filters( 'bp_akismet_get_activity_types', array( 'activity_comment', 'activity_update' ) );
260
- }
261
-
262
- /**
263
- * Mark activity item as spam.
264
- *
265
- * @since 1.6.0
266
- *
267
- * @param BP_Activity_Activity $activity Activity item being spammed.
268
- * @param string $source Either "by_a_person" (e.g. a person has
269
- * manually marked the activity as spam) or
270
- * "by_akismet" (automatically spammed).
271
- */
272
- public function mark_as_spam( $activity, $source ) {
273
- // Record this item so we can do some tidyup in BP_Akismet::check_member_activity_update().
274
- $this->last_activity = $activity;
275
-
276
- /**
277
- * Fires after marking an activity item has been marked as spam.
278
- *
279
- * @since 1.6.0
280
- *
281
- * @param BP_Activity_Activity $activity Activity object being marked as spam.
282
- * @param string $source Source of the whom marked as spam.
283
- * Either "by_a_person" (e.g. a person has
284
- * manually marked the activity as spam)
285
- * or "by_akismet".
286
- */
287
- do_action( 'bp_activity_akismet_mark_as_spam', $activity, $source );
288
- }
289
-
290
- /**
291
- * Mark activity item as ham.
292
- *
293
- * @since 1.6.0
294
- *
295
- * @param BP_Activity_Activity $activity Activity item being hammed.
296
- * @param string $source Either "by_a_person" (e.g. a person has
297
- * manually marked the activity as ham) or
298
- * "by_akismet" (automatically hammed).
299
- */
300
- public function mark_as_ham( $activity, $source ) {
301
- // If the activity was, originally, automatically marked as spam by Akismet, run the @mentions filter as it would have been skipped.
302
- if ( 'true' == bp_activity_get_meta( $activity->id, '_bp_akismet_result' ) && !bp_activity_get_meta( $activity->id, '_bp_akismet_user_result' ) )
303
- $activity->content = bp_activity_at_name_filter( $activity->content, $activity->id );
304
-
305
- /**
306
- * Fires after marking an activity item has been marked as ham.
307
- *
308
- * @since 1.6.0
309
- *
310
- * @param BP_Activity_Activity $activity Activity object being marked as ham.
311
- * @param string $source Source of the whom marked as ham.
312
- * Either "by_a_person" (e.g. a person has
313
- * manually marked the activity as ham) or
314
- * "by_akismet" (automatically hammed).
315
- */
316
- do_action( 'bp_activity_akismet_mark_as_ham', $activity, $source );
317
- }
318
-
319
- /**
320
- * Build a data package for the Akismet service to inspect.
321
- *
322
- * @since 1.6.0
323
- *
324
- * @see http://akismet.com/development/api/#comment-check
325
- * @static
326
- *
327
- * @param BP_Activity_Activity $activity Activity item data.
328
- * @return array $activity_data
329
- */
330
- public static function build_akismet_data_package( $activity ) {
331
- $userdata = get_userdata( $activity->user_id );
332
-
333
- $activity_data = array();
334
- $activity_data['akismet_comment_nonce'] = 'inactive';
335
- $activity_data['comment_author'] = $userdata->display_name;
336
- $activity_data['comment_author_email'] = $userdata->user_email;
337
- $activity_data['comment_author_url'] = bp_core_get_userlink( $userdata->ID, false, true);
338
- $activity_data['comment_content'] = $activity->content;
339
- $activity_data['comment_type'] = $activity->type;
340
- $activity_data['permalink'] = bp_activity_get_permalink( $activity->id, $activity );
341
- $activity_data['user_ID'] = $userdata->ID;
342
- $activity_data['user_role'] = Akismet::get_user_roles( $userdata->ID );
343
-
344
- /**
345
- * Get the nonce if the new activity was submitted through the "what's up, Paul?" form.
346
- * This helps Akismet ensure that the update was a valid form submission.
347
- */
348
- if ( !empty( $_POST['_bp_as_nonce'] ) )
349
- $activity_data['akismet_comment_nonce'] = wp_verify_nonce( $_POST['_bp_as_nonce'], "_bp_as_nonce_{$userdata->ID}" ) ? 'passed' : 'failed';
350
-
351
- /**
352
- * If the new activity was a reply to an existing item, check the nonce with the activity parent ID.
353
- * This helps Akismet ensure that the update was a valid form submission.
354
- */
355
- elseif ( !empty( $activity->secondary_item_id ) && !empty( $_POST['_bp_as_nonce_' . $activity->secondary_item_id] ) )
356
- $activity_data['akismet_comment_nonce'] = wp_verify_nonce( $_POST["_bp_as_nonce_{$activity->secondary_item_id}"], "_bp_as_nonce_{$userdata->ID}_{$activity->secondary_item_id}" ) ? 'passed' : 'failed';
357
-
358
- /**
359
- * Filters activity data before being sent to Akismet to inspect.
360
- *
361
- * @since 1.6.0
362
- *
363
- * @param array $activity_data Array of activity data for Akismet to inspect.
364
- * @param BP_Activity_Activity $activity Activity item data.
365
- */
366
- return apply_filters( 'bp_akismet_build_akismet_data_package', $activity_data, $activity );
367
- }
368
-
369
- /**
370
- * Check if the activity item is spam or ham.
371
- *
372
- * @since 1.6.0
373
- *
374
- * @see http://akismet.com/development/api/
375
- * @todo Spam counter?
376
- * @todo Auto-delete old spam?
377
- *
378
- * @param BP_Activity_Activity $activity The activity item to check.
379
- */
380
- public function check_activity( $activity ) {
381
- // By default, only handle activity updates and activity comments.
382
- if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
383
- return;
384
-
385
- // Make sure last_activity is clear to avoid any confusion.
386
- $this->last_activity = null;
387
-
388
- // Build data package for Akismet.
389
- $activity_data = BP_Akismet::build_akismet_data_package( $activity );
390
-
391
- // Check with Akismet to see if this is spam.
392
- $activity_data = $this->send_akismet_request( $activity_data, 'check', 'spam' );
393
-
394
- // Record this item.
395
- $this->last_activity = $activity;
396
-
397
- // Store a copy of the data that was submitted to Akismet.
398
- $this->last_activity->akismet_submission = $activity_data;
399
-
400
- // Spam.
401
- if ( 'true' == $activity_data['bp_as_result'] ) {
402
- /**
403
- * Fires after an activity item has been proven to be spam, but before officially being marked as spam.
404
- *
405
- * @since 1.6.0
406
- *
407
- * @param BP_Activity_Activity $activity The activity item proven to be spam.
408
- * @param array $activity_data Array of activity data for item including
409
- * Akismet check results data.
410
- */
411
- do_action_ref_array( 'bp_activity_akismet_spam_caught', array( &$activity, $activity_data ) );
412
-
413
- // Mark as spam.
414
- bp_activity_mark_as_spam( $activity, 'by_akismet' );
415
- }
416
-
417
- // Update activity meta after a spam check.
418
- add_action( 'bp_activity_after_save', array( $this, 'update_activity_akismet_meta' ), 1, 1 );
419
- }
420
-
421
- /**
422
- * Update activity meta after a manual spam change (user-initiated).
423
- *
424
- * @since 1.6.0
425
- *
426
- * @param BP_Activity_Activity $activity The activity to check.
427
- */
428
- public function update_activity_spam_meta( $activity ) {
429
- // By default, only handle activity updates and activity comments.
430
- if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
431
- return;
432
-
433
- $this->update_activity_history( $activity->id, sprintf( __( '%s reported this activity as spam', 'buddypress' ), bp_get_loggedin_user_username() ), 'report-spam' );
434
- bp_activity_update_meta( $activity->id, '_bp_akismet_user_result', 'true' );
435
- bp_activity_update_meta( $activity->id, '_bp_akismet_user', bp_get_loggedin_user_username() );
436
- }
437
-
438
- /**
439
- * Update activity meta after a manual ham change (user-initiated).
440
- *
441
- * @since 1.6.0
442
- *
443
- * @param BP_Activity_Activity $activity The activity to check.
444
- */
445
- public function update_activity_ham_meta( $activity ) {
446
- // By default, only handle activity updates and activity comments.
447
- if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
448
- return;
449
-
450
- $this->update_activity_history( $activity->id, sprintf( __( '%s reported this activity as not spam', 'buddypress' ), bp_get_loggedin_user_username() ), 'report-ham' );
451
- bp_activity_update_meta( $activity->id, '_bp_akismet_user_result', 'false' );
452
- bp_activity_update_meta( $activity->id, '_bp_akismet_user', bp_get_loggedin_user_username() );
453
- }
454
-
455
- /**
456
- * Update activity meta after an automatic spam check (not user-initiated).
457
- *
458
- * @since 1.6.0
459
- *
460
- * @param BP_Activity_Activity $activity The activity to check.
461
- */
462
- public function update_activity_akismet_meta( $activity ) {
463
- // Check we're dealing with what was last updated by Akismet.
464
- if ( empty( $this->last_activity ) || !empty( $this->last_activity ) && $activity->id != $this->last_activity->id )
465
- return;
466
-
467
- // By default, only handle activity updates and activity comments.
468
- if ( !in_array( $this->last_activity->type, BP_Akismet::get_activity_types() ) )
469
- return;
470
-
471
- // Spam.
472
- if ( 'true' == $this->last_activity->akismet_submission['bp_as_result'] ) {
473
- bp_activity_update_meta( $activity->id, '_bp_akismet_result', 'true' );
474
- $this->update_activity_history( $activity->id, __( 'Akismet caught this item as spam', 'buddypress' ), 'check-spam' );
475
-
476
- // Not spam.
477
- } elseif ( 'false' == $this->last_activity->akismet_submission['bp_as_result'] ) {
478
- bp_activity_update_meta( $activity->id, '_bp_akismet_result', 'false' );
479
- $this->update_activity_history( $activity->id, __( 'Akismet cleared this item', 'buddypress' ), 'check-ham' );
480
-
481
- // Uh oh, something's gone horribly wrong. Unexpected result.
482
- } else {
483
- bp_activity_update_meta( $activity->id, '_bp_akismet_error', bp_core_current_time() );
484
- $this->update_activity_history( $activity->id, sprintf( __( 'Akismet was unable to check this item (response: %s), will automatically retry again later.', 'buddypress' ), $this->last_activity->akismet_submission['bp_as_result'] ), 'check-error' );
485
- }
486
-
487
- // Record the original data which was submitted to Akismet for checking.
488
- bp_activity_update_meta( $activity->id, '_bp_akismet_submission', $this->last_activity->akismet_submission );
489
- }
490
-
491
- /**
492
- * Contact Akismet to check if this is spam or ham.
493
- *
494
- * Props to WordPress core Akismet plugin for a lot of this.
495
- *
496
- * @since 1.6.0
497
- *
498
- * @param array $activity_data Packet of information to submit to Akismet.
499
- * @param string $check "check" or "submit".
500
- * @param string $spam "spam" or "ham".
501
- * @return array $activity_data Activity data, with Akismet data added.
502
- */
503
- public function send_akismet_request( $activity_data, $check = 'check', $spam = 'spam' ) {
504
- $query_string = $path = '';
505
-
506
- $activity_data['blog'] = bp_get_option( 'home' );
507
- $activity_data['blog_charset'] = bp_get_option( 'blog_charset' );
508
- $activity_data['blog_lang'] = get_locale();
509
- $activity_data['referrer'] = $_SERVER['HTTP_REFERER'];
510
- $activity_data['user_agent'] = bp_core_current_user_ua();
511
- $activity_data['user_ip'] = bp_core_current_user_ip();
512
-
513
- if ( Akismet::is_test_mode() )
514
- $activity_data['is_test'] = 'true';
515
-
516
- // Loop through _POST args and rekey strings.
517
- foreach ( $_POST as $key => $value )
518
- if ( is_string( $value ) && 'cookie' != $key )
519
- $activity_data['POST_' . $key] = $value;
520
-
521
- // Keys to ignore.
522
- $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
523
-
524
- // Loop through _SERVER args and remove whitelisted keys.
525
- foreach ( $_SERVER as $key => $value ) {
526
-
527
- // Key should not be ignored.
528
- if ( !in_array( $key, $ignore ) && is_string( $value ) ) {
529
- $activity_data[$key] = $value;
530
-
531
- // Key should be ignored.
532
- } else {
533
- $activity_data[$key] = '';
534
- }
535
- }
536
-
537
- foreach ( $activity_data as $key => $data )
538
- $query_string .= $key . '=' . urlencode( stripslashes( $data ) ) . '&';
539
-
540
- if ( 'check' == $check )
541
- $path = 'comment-check';
542
- elseif ( 'submit' == $check )
543
- $path = 'submit-' . $spam;
544
-
545
- // Send to Akismet.
546
- add_filter( 'akismet_ua', array( $this, 'buddypress_ua' ) );
547
- $response = Akismet::http_post( $query_string, $path );
548
- remove_filter( 'akismet_ua', array( $this, 'buddypress_ua' ) );
549
-
550
- // Get the response.
551
- if ( ! empty( $response[1] ) && ! is_wp_error( $response[1] ) )
552
- $activity_data['bp_as_result'] = $response[1];
553
- else
554
- $activity_data['bp_as_result'] = false;
555
-
556
- // Perform a daily tidy up.
557
- if ( ! wp_next_scheduled( 'bp_activity_akismet_delete_old_metadata' ) )
558
- wp_schedule_event( time(), 'daily', 'bp_activity_akismet_delete_old_metadata' );
559
-
560
- return $activity_data;
561
- }
562
-
563
- /**
564
- * Filters user agent when sending to Akismet to add BuddyPress info.
565
- *
566
- * @since 1.6.0
567
- *
568
- * @param string $user_agent User agent string, as generated by Akismet.
569
- * @return string $user_agent Modified user agent string.
570
- */
571
- public function buddypress_ua( $user_agent ) {
572