BuddyPress - Version 2.8.0-beta1

Version Description

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

Download this release

Release Info

Developer slaFFik
Plugin Icon 128x128 BuddyPress
Version 2.8.0-beta1
Comparing to
See all releases

Code changes from version 2.5.4 to 2.8.0-beta1

Files changed (197) hide show
  1. bp-activity/admin/js/admin.min.js +0 -1
  2. bp-activity/bp-activity-actions.php +6 -143
  3. bp-activity/bp-activity-admin.php +41 -14
  4. bp-activity/bp-activity-adminbar.php +47 -0
  5. bp-activity/bp-activity-akismet.php +22 -1
  6. bp-activity/bp-activity-cache.php +21 -0
  7. bp-activity/bp-activity-classes.php +0 -15
  8. bp-activity/bp-activity-embeds.php +352 -0
  9. bp-activity/bp-activity-filters.php +56 -51
  10. bp-activity/bp-activity-functions.php +437 -233
  11. bp-activity/bp-activity-loader.php +1 -3
  12. bp-activity/bp-activity-notifications.php +184 -237
  13. bp-activity/bp-activity-screens.php +23 -65
  14. bp-activity/bp-activity-template.php +47 -328
  15. bp-activity/classes/class-bp-activity-activity.php +115 -81
  16. bp-activity/classes/class-bp-activity-component.php +23 -32
  17. bp-activity/classes/class-bp-activity-list-table.php +41 -18
  18. bp-activity/classes/class-bp-activity-oembed-extension.php +329 -0
  19. bp-activity/classes/class-bp-activity-template.php +1 -2
  20. bp-activity/css/mentions-rtl.css +2 -3
  21. bp-activity/css/mentions-rtl.min.css +1 -1
  22. bp-activity/css/mentions.css +3 -3
  23. bp-activity/css/mentions.min.css +1 -1
  24. bp-activity/js/mentions.js +1 -1
  25. bp-activity/js/mentions.min.js +1 -2
  26. bp-blogs/bp-blogs-activity.php +150 -7
  27. bp-blogs/bp-blogs-classes.php +0 -13
  28. bp-blogs/bp-blogs-filters.php +14 -1
  29. bp-blogs/bp-blogs-functions.php +209 -162
  30. bp-blogs/bp-blogs-loader.php +2 -2
  31. bp-blogs/bp-blogs-screens.php +0 -2
  32. bp-blogs/bp-blogs-template.php +135 -48
  33. bp-blogs/bp-blogs-widgets.php +1 -3
  34. bp-blogs/classes/class-bp-blogs-blog.php +50 -10
  35. bp-blogs/classes/class-bp-blogs-component.php +15 -3
  36. bp-blogs/classes/class-bp-blogs-recent-posts-widget.php +3 -2
  37. bp-core/admin/bp-core-admin-actions.php +0 -9
  38. bp-core/admin/bp-core-admin-classes.php +0 -13
  39. bp-core/admin/bp-core-admin-components.php +28 -94
  40. bp-core/admin/bp-core-admin-functions.php +88 -18
  41. bp-core/admin/bp-core-admin-schema.php +13 -48
  42. bp-core/admin/bp-core-admin-settings.php +0 -16
  43. bp-core/admin/bp-core-admin-slugs.php +11 -4
  44. bp-core/admin/bp-core-admin-tools.php +38 -23
  45. bp-core/admin/css/common-rtl.css +345 -80
  46. bp-core/admin/css/common-rtl.min.css +1 -1
  47. bp-core/admin/css/common.css +345 -80
  48. bp-core/admin/css/common.min.css +1 -1
  49. bp-core/admin/images/autolink-feature.png +0 -0
  50. bp-core/admin/images/bp-emails-feature.png +0 -0
  51. bp-core/admin/images/emoji-feature.png +0 -0
  52. bp-core/admin/images/post-type.png +0 -0
  53. bp-core/admin/images/twentytwelve.png +0 -0
  54. bp-core/admin/js/customizer-controls.min.js +0 -1
  55. bp-core/admin/js/customizer-receiver-emails.min.js +0 -1
  56. bp-core/admin/js/dismissible-admin-notices.js +16 -0
  57. bp-core/admin/js/dismissible-admin-notices.min.js +1 -0
  58. bp-core/bp-core-actions.php +13 -4
  59. bp-core/bp-core-admin.php +27 -22
  60. bp-core/bp-core-adminbar.php +0 -11
  61. bp-core/bp-core-attachments.php +26 -11
  62. bp-core/bp-core-avatars.php +102 -85
  63. bp-core/bp-core-buddybar.php +225 -161
  64. bp-core/bp-core-cache.php +107 -0
  65. bp-core/bp-core-caps.php +65 -37
  66. bp-core/bp-core-catchuri.php +147 -29
  67. bp-core/bp-core-classes.php +0 -32
  68. bp-core/bp-core-component.php +3 -1
  69. bp-core/bp-core-cssjs.php +145 -22
  70. bp-core/bp-core-customizer-email.php +6 -13
  71. bp-core/bp-core-dependency.php +39 -47
  72. bp-core/bp-core-filters.php +68 -49
  73. bp-core/bp-core-functions.php +598 -115
  74. bp-core/bp-core-loader.php +1 -5
  75. bp-core/bp-core-moderation.php +28 -27
  76. bp-core/bp-core-options.php +22 -102
  77. bp-core/bp-core-taxonomy.php +165 -19
  78. bp-core/bp-core-template-loader.php +68 -15
  79. bp-core/bp-core-template.php +235 -114
  80. bp-core/bp-core-theme-compatibility.php +15 -43
  81. bp-core/bp-core-update.php +109 -42
  82. bp-core/bp-core-widgets.php +1 -3
  83. bp-core/bp-core-wpabstraction.php +0 -7
  84. bp-core/classes/class-bp-admin.php +212 -96
  85. bp-core/classes/class-bp-attachment-avatar.php +1 -21
  86. bp-core/classes/class-bp-attachment-cover-image.php +291 -291
  87. bp-core/classes/class-bp-attachment.php +14 -28
  88. bp-core/classes/class-bp-button.php +231 -76
  89. bp-core/classes/class-bp-component.php +2 -16
  90. bp-core/classes/class-bp-core-bp-nav-backcompat.php +270 -0
  91. bp-core/classes/class-bp-core-bp-options-nav-backcompat.php +138 -0
  92. bp-core/classes/class-bp-core-html-element.php +127 -0
  93. bp-core/classes/class-bp-core-login-widget.php +4 -3
  94. bp-core/classes/class-bp-core-nav-item.php +15 -0
  95. bp-core/classes/class-bp-core-nav.php +402 -0
  96. bp-core/classes/class-bp-core-oembed-extension.php +622 -0
  97. bp-core/classes/class-bp-core-sort-by-key-callback.php +0 -83
  98. bp-core/classes/class-bp-core-user.php +18 -13
  99. bp-core/classes/class-bp-core.php +4 -1
  100. bp-core/classes/class-bp-email-recipient.php +36 -13
  101. bp-core/classes/class-bp-embed.php +0 -9
  102. bp-core/classes/class-bp-media-extractor.php +1 -1
  103. bp-core/classes/class-bp-phpmailer.php +12 -1
  104. bp-core/classes/class-bp-theme-compat.php +1 -1
  105. bp-core/classes/class-bp-user-query.php +18 -10
  106. bp-core/classes/class-bp-walker-category-checklist.php +1 -1
  107. bp-core/classes/class-bp-walker-nav-menu.php +1 -3
  108. bp-core/css/admin-bar-rtl.css +15 -2
  109. bp-core/css/admin-bar-rtl.min.css +1 -1
  110. bp-core/css/admin-bar.css +15 -2
  111. bp-core/css/admin-bar.min.css +1 -1
  112. bp-core/css/avatar-rtl.css +16 -2
  113. bp-core/css/avatar-rtl.min.css +1 -1
  114. bp-core/css/avatar.css +16 -2
  115. bp-core/css/avatar.min.css +1 -1
  116. bp-core/css/buddybar-rtl.css +3 -3
  117. bp-core/css/buddybar-rtl.min.css +1 -1
  118. bp-core/deprecated/1.2.php +0 -2
  119. bp-core/deprecated/1.7.php +0 -1
  120. bp-core/deprecated/2.5.php +2 -2
  121. bp-core/deprecated/2.6.php +50 -0
  122. bp-core/deprecated/2.7.php +26 -0
  123. bp-core/deprecated/2.8.php +199 -0
  124. bp-core/images/mystery-group-50.png +0 -0
  125. bp-core/images/mystery-group.png +0 -0
  126. bp-core/js/avatar.min.js +0 -1
  127. bp-core/js/bp-plupload.min.js +1 -2
  128. bp-core/js/confirm.min.js +1 -2
  129. bp-core/js/cover-image.js +277 -277
  130. bp-core/js/cover-image.min.js +0 -1
  131. bp-core/js/jquery-query.min.js +0 -1
  132. bp-core/js/jquery.atwho.min.js +0 -2
  133. bp-core/js/{jquery-cookie.js → vendor/jquery-cookie.js} +0 -0
  134. bp-core/js/{jquery-cookie.min.js → vendor/jquery-cookie.min.js} +1 -2
  135. bp-core/js/{jquery-scroll-to.js → vendor/jquery-scroll-to.js} +0 -0
  136. bp-core/js/{jquery-scroll-to.min.js → vendor/jquery-scroll-to.min.js} +1 -2
  137. bp-core/js/{jquery.atwho.js → vendor/jquery.atwho.js} +0 -0
  138. bp-core/js/vendor/jquery.atwho.min.js +1 -0
  139. bp-core/js/{jquery.atwho.txt → vendor/jquery.atwho.txt} +0 -0
  140. bp-core/js/{jquery.caret.js → vendor/jquery.caret.js} +0 -0
  141. bp-core/js/{jquery.caret.min.js → vendor/jquery.caret.min.js} +1 -2
  142. bp-core/js/{jquery.caret.txt → vendor/jquery.caret.txt} +0 -0
  143. bp-core/js/vendor/livestamp.js +129 -0
  144. bp-core/js/vendor/livestamp.min.js +1 -0
  145. bp-core/js/vendor/moment-js/locale/af.js +73 -0
  146. bp-core/js/vendor/moment-js/locale/af.min.js +1 -0
  147. bp-core/js/vendor/moment-js/locale/ar-ly.js +122 -0
  148. bp-core/js/vendor/moment-js/locale/ar-ly.min.js +1 -0
  149. bp-core/js/vendor/moment-js/locale/ar-ma.js +60 -0
  150. bp-core/js/vendor/moment-js/locale/ar-ma.min.js +1 -0
  151. bp-core/js/vendor/moment-js/locale/ar-sa.js +104 -0
  152. bp-core/js/vendor/moment-js/locale/ar-sa.min.js +1 -0
  153. bp-core/js/vendor/moment-js/locale/ar-tn.js +59 -0
  154. bp-core/js/vendor/moment-js/locale/ar-tn.min.js +1 -0
  155. bp-core/js/vendor/moment-js/locale/ar.js +137 -0
  156. bp-core/js/vendor/moment-js/locale/ar.min.js +1 -0
  157. bp-core/js/vendor/moment-js/locale/az.js +105 -0
  158. bp-core/js/vendor/moment-js/locale/az.min.js +1 -0
  159. bp-core/js/vendor/moment-js/locale/be.js +134 -0
  160. bp-core/js/vendor/moment-js/locale/be.min.js +1 -0
  161. bp-core/js/vendor/moment-js/locale/bg.js +90 -0
  162. bp-core/js/vendor/moment-js/locale/bg.min.js +1 -0
  163. bp-core/js/vendor/moment-js/locale/bn.js +119 -0
  164. bp-core/js/vendor/moment-js/locale/bn.min.js +1 -0
  165. bp-core/js/vendor/moment-js/locale/bo.js +119 -0
  166. bp-core/js/vendor/moment-js/locale/bo.min.js +1 -0
  167. bp-core/js/vendor/moment-js/locale/br.js +108 -0
  168. bp-core/js/vendor/moment-js/locale/br.min.js +1 -0
  169. bp-core/js/vendor/moment-js/locale/bs.js +143 -0
  170. bp-core/js/vendor/moment-js/locale/bs.min.js +1 -0
  171. bp-core/js/vendor/moment-js/locale/ca.js +81 -0
  172. bp-core/js/vendor/moment-js/locale/ca.min.js +1 -0
  173. bp-core/js/vendor/moment-js/locale/cs.js +172 -0
  174. bp-core/js/vendor/moment-js/locale/cs.min.js +1 -0
  175. bp-core/js/vendor/moment-js/locale/cv.js +63 -0
  176. bp-core/js/vendor/moment-js/locale/cv.min.js +1 -0
  177. bp-core/js/vendor/moment-js/locale/cy.js +81 -0
  178. bp-core/js/vendor/moment-js/locale/cy.min.js +1 -0
  179. bp-core/js/vendor/moment-js/locale/da.js +60 -0
  180. bp-core/js/vendor/moment-js/locale/da.min.js +1 -0
  181. bp-core/js/vendor/moment-js/locale/de-at.js +79 -0
  182. bp-core/js/vendor/moment-js/locale/de-at.min.js +1 -0
  183. bp-core/js/vendor/moment-js/locale/de.js +78 -0
  184. bp-core/js/vendor/moment-js/locale/de.min.js +1 -0
  185. bp-core/js/vendor/moment-js/locale/dv.js +99 -0
  186. bp-core/js/vendor/moment-js/locale/dv.min.js +1 -0
  187. bp-core/js/vendor/moment-js/locale/el.js +98 -0
  188. bp-core/js/vendor/moment-js/locale/el.min.js +1 -0
  189. bp-core/js/vendor/moment-js/locale/en-au.js +67 -0
  190. bp-core/js/vendor/moment-js/locale/en-au.min.js +1 -0
  191. bp-core/js/vendor/moment-js/locale/en-ca.js +63 -0
  192. bp-core/js/vendor/moment-js/locale/en-ca.min.js +1 -0
  193. bp-core/js/vendor/moment-js/locale/en-gb.js +67 -0
  194. bp-core/js/vendor/moment-js/locale/en-gb.min.js +1 -0
  195. bp-core/js/vendor/moment-js/locale/en-ie.js +67 -0
  196. bp-core/js/vendor/moment-js/locale/en-ie.min.js +1 -0
  197. bp-core/js/vendor/moment-js/locale/en-nz.js +26 -0
bp-activity/admin/js/admin.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 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
  !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
@@ -17,7 +17,6 @@ defined( 'ABSPATH' ) || exit;
17
  *
18
  * @since 1.2.0
19
  *
20
- * @uses do_action() To call 'bp_register_activity_actions' hook.
21
  */
22
  function bp_register_activity_actions() {
23
 
@@ -35,18 +34,6 @@ add_action( 'bp_init', 'bp_register_activity_actions', 8 );
35
  *
36
  * @since 1.2.0
37
  *
38
- * @uses bp_is_activity_component()
39
- * @uses bp_is_current_action()
40
- * @uses bp_action_variable()
41
- * @uses bp_activity_get_specific()
42
- * @uses bp_is_active()
43
- * @uses bp_core_get_user_domain()
44
- * @uses groups_get_group()
45
- * @uses bp_get_group_permalink()
46
- * @uses apply_filters_ref_array() To call the 'bp_activity_permalink_redirect_url' hook.
47
- * @uses bp_core_redirect()
48
- * @uses bp_get_root_domain()
49
- *
50
  * @return bool False on failure.
51
  */
52
  function bp_activity_action_permalink_router() {
@@ -84,7 +71,7 @@ function bp_activity_action_permalink_router() {
84
  } else {
85
 
86
  // Set redirect to group activity stream.
87
- if ( $group = groups_get_group( array( 'group_id' => $activity->item_id ) ) ) {
88
  $redirect = bp_get_group_permalink( $group ) . bp_get_activity_slug() . '/' . $activity->id . '/';
89
  }
90
  }
@@ -122,17 +109,6 @@ add_action( 'bp_actions', 'bp_activity_action_permalink_router' );
122
  *
123
  * @since 1.1.0
124
  *
125
- * @uses bp_is_activity_component()
126
- * @uses bp_is_current_action()
127
- * @uses bp_action_variable()
128
- * @uses check_admin_referer()
129
- * @uses bp_activity_user_can_delete()
130
- * @uses do_action() Calls 'bp_activity_before_action_delete_activity' hook to allow actions to be taken before the activity is deleted.
131
- * @uses bp_activity_delete()
132
- * @uses bp_core_add_message()
133
- * @uses do_action() Calls 'bp_activity_action_delete_activity' hook to allow actions to be taken after the activity is deleted.
134
- * @uses bp_core_redirect()
135
- *
136
  * @param int $activity_id Activity id to be deleted. Defaults to 0.
137
  * @return bool False on failure.
138
  */
@@ -267,20 +243,6 @@ add_action( 'bp_actions', 'bp_activity_action_spam_activity' );
267
  *
268
  * @since 1.2.0
269
  *
270
- * @uses is_user_logged_in()
271
- * @uses bp_is_activity_component()
272
- * @uses bp_is_current_action()
273
- * @uses check_admin_referer()
274
- * @uses apply_filters() To call 'bp_activity_post_update_content' hook.
275
- * @uses apply_filters() To call 'bp_activity_post_update_object' hook.
276
- * @uses apply_filters() To call 'bp_activity_post_update_item_id' hook.
277
- * @uses bp_core_add_message()
278
- * @uses bp_core_redirect()
279
- * @uses bp_activity_post_update()
280
- * @uses groups_post_update()
281
- * @uses bp_core_redirect()
282
- * @uses apply_filters() To call 'bp_activity_custom_update' hook.
283
- *
284
  * @return bool False on failure.
285
  */
286
  function bp_activity_action_post_update() {
@@ -371,17 +333,6 @@ add_action( 'bp_actions', 'bp_activity_action_post_update' );
371
  *
372
  * @since 1.2.0
373
  *
374
- * @uses is_user_logged_in()
375
- * @uses bp_is_activity_component()
376
- * @uses bp_is_current_action()
377
- * @uses check_admin_referer()
378
- * @uses apply_filters() To call 'bp_activity_post_comment_activity_id' hook.
379
- * @uses apply_filters() To call 'bp_activity_post_comment_content' hook.
380
- * @uses bp_core_add_message()
381
- * @uses bp_core_redirect()
382
- * @uses bp_activity_new_comment()
383
- * @uses wp_get_referer()
384
- *
385
  * @return bool False on failure.
386
  */
387
  function bp_activity_action_post_comment() {
@@ -435,16 +386,6 @@ add_action( 'bp_actions', 'bp_activity_action_post_comment' );
435
  *
436
  * @since 1.2.0
437
  *
438
- * @uses is_user_logged_in()
439
- * @uses bp_is_activity_component()
440
- * @uses bp_is_current_action()
441
- * @uses check_admin_referer()
442
- * @uses bp_activity_add_user_favorite()
443
- * @uses bp_action_variable()
444
- * @uses bp_core_add_message()
445
- * @uses bp_core_redirect()
446
- * @uses wp_get_referer()
447
- *
448
  * @return bool False on failure.
449
  */
450
  function bp_activity_action_mark_favorite() {
@@ -469,16 +410,6 @@ add_action( 'bp_actions', 'bp_activity_action_mark_favorite' );
469
  *
470
  * @since 1.2.0
471
  *
472
- * @uses is_user_logged_in()
473
- * @uses bp_is_activity_component()
474
- * @uses bp_is_current_action()
475
- * @uses check_admin_referer()
476
- * @uses bp_activity_remove_user_favorite()
477
- * @uses bp_action_variable()
478
- * @uses bp_core_add_message()
479
- * @uses bp_core_redirect()
480
- * @uses wp_get_referer()
481
- *
482
  * @return bool False on failure.
483
  */
484
  function bp_activity_action_remove_favorite() {
@@ -503,11 +434,6 @@ add_action( 'bp_actions', 'bp_activity_action_remove_favorite' );
503
  *
504
  * @since 1.0.0
505
  *
506
- * @uses bp_is_activity_component()
507
- * @uses bp_is_current_action()
508
- * @uses bp_is_user()
509
- * @uses status_header()
510
- *
511
  * @return bool False on failure.
512
  */
513
  function bp_activity_action_sitewide_feed() {
@@ -535,10 +461,6 @@ add_action( 'bp_actions', 'bp_activity_action_sitewide_feed' );
535
  *
536
  * @since 1.0.0
537
  *
538
- * @uses bp_is_user_activity()
539
- * @uses bp_is_current_action()
540
- * @uses status_header()
541
- *
542
  * @return bool False on failure.
543
  */
544
  function bp_activity_action_personal_feed() {
@@ -565,13 +487,6 @@ add_action( 'bp_actions', 'bp_activity_action_personal_feed' );
565
  *
566
  * @since 1.0.0
567
  *
568
- * @uses bp_is_active()
569
- * @uses bp_is_user_activity()
570
- * @uses bp_is_current_action()
571
- * @uses bp_get_friends_slug()
572
- * @uses bp_is_action_variable()
573
- * @uses status_header()
574
- *
575
  * @return bool False on failure.
576
  */
577
  function bp_activity_action_friends_feed() {
@@ -598,13 +513,6 @@ add_action( 'bp_actions', 'bp_activity_action_friends_feed' );
598
  *
599
  * @since 1.2.0
600
  *
601
- * @uses bp_is_active()
602
- * @uses bp_is_user_activity()
603
- * @uses bp_is_current_action()
604
- * @uses bp_get_groups_slug()
605
- * @uses bp_is_action_variable()
606
- * @uses status_header()
607
- *
608
  * @return bool False on failure.
609
  */
610
  function bp_activity_action_my_groups_feed() {
@@ -639,11 +547,6 @@ add_action( 'bp_actions', 'bp_activity_action_my_groups_feed' );
639
  *
640
  * @since 1.2.0
641
  *
642
- * @uses bp_is_user_activity()
643
- * @uses bp_is_current_action()
644
- * @uses bp_is_action_variable()
645
- * @uses status_header()
646
- *
647
  * @return bool False on failure.
648
  */
649
  function bp_activity_action_mentions_feed() {
@@ -676,11 +579,6 @@ add_action( 'bp_actions', 'bp_activity_action_mentions_feed' );
676
  *
677
  * @since 1.2.0
678
  *
679
- * @uses bp_is_user_activity()
680
- * @uses bp_is_current_action()
681
- * @uses bp_is_action_variable()
682
- * @uses status_header()
683
- *
684
  * @return bool False on failure.
685
  */
686
  function bp_activity_action_favorites_feed() {
@@ -706,45 +604,6 @@ function bp_activity_action_favorites_feed() {
706
  }
707
  add_action( 'bp_actions', 'bp_activity_action_favorites_feed' );
708
 
709
- /**
710
- * Loads Akismet filtering for activity.
711
- *
712
- * @since 1.6.0
713
- * @since 2.3.0 We only support Akismet 3+.
714
- */
715
- function bp_activity_setup_akismet() {
716
- $bp = buddypress();
717
-
718
- // Bail if Akismet is not active.
719
- if ( ! defined( 'AKISMET_VERSION' ) ) {
720
- return;
721
- }
722
-
723
- // Bail if older version of Akismet.
724
- if ( ! class_exists( 'Akismet' ) ) {
725
- return;
726
- }
727
-
728
- // Bail if no Akismet key is set.
729
- if ( ! bp_get_option( 'wordpress_api_key' ) && ! defined( 'WPCOM_API_KEY' ) ) {
730
- return;
731
- }
732
-
733
- /**
734
- * Filters if BuddyPress Activity Akismet support has been disabled by another plugin.
735
- *
736
- * @since 1.6.0
737
- *
738
- * @param bool $value Return value of bp_is_akismet_active boolean function.
739
- */
740
- if ( ! apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) ) {
741
- return;
742
- }
743
-
744
- // Instantiate Akismet for BuddyPress.
745
- $bp->activity->akismet = new BP_Akismet();
746
- }
747
-
748
  /**
749
  * AJAX endpoint for Suggestions API lookups.
750
  *
@@ -973,7 +832,11 @@ function bp_activity_transition_post_type_comment_status( $new_status, $old_stat
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
17
  *
18
  * @since 1.2.0
19
  *
 
20
  */
21
  function bp_register_activity_actions() {
22
 
34
  *
35
  * @since 1.2.0
36
  *
 
 
 
 
 
 
 
 
 
 
 
 
37
  * @return bool False on failure.
38
  */
39
  function bp_activity_action_permalink_router() {
71
  } else {
72
 
73
  // Set redirect to group activity stream.
74
+ if ( $group = groups_get_group( $activity->item_id ) ) {
75
  $redirect = bp_get_group_permalink( $group ) . bp_get_activity_slug() . '/' . $activity->id . '/';
76
  }
77
  }
109
  *
110
  * @since 1.1.0
111
  *
 
 
 
 
 
 
 
 
 
 
 
112
  * @param int $activity_id Activity id to be deleted. Defaults to 0.
113
  * @return bool False on failure.
114
  */
243
  *
244
  * @since 1.2.0
245
  *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  * @return bool False on failure.
247
  */
248
  function bp_activity_action_post_update() {
333
  *
334
  * @since 1.2.0
335
  *
 
 
 
 
 
 
 
 
 
 
 
336
  * @return bool False on failure.
337
  */
338
  function bp_activity_action_post_comment() {
386
  *
387
  * @since 1.2.0
388
  *
 
 
 
 
 
 
 
 
 
 
389
  * @return bool False on failure.
390
  */
391
  function bp_activity_action_mark_favorite() {
410
  *
411
  * @since 1.2.0
412
  *
 
 
 
 
 
 
 
 
 
 
413
  * @return bool False on failure.
414
  */
415
  function bp_activity_action_remove_favorite() {
434
  *
435
  * @since 1.0.0
436
  *
 
 
 
 
 
437
  * @return bool False on failure.
438
  */
439
  function bp_activity_action_sitewide_feed() {
461
  *
462
  * @since 1.0.0
463
  *
 
 
 
 
464
  * @return bool False on failure.
465
  */
466
  function bp_activity_action_personal_feed() {
487
  *
488
  * @since 1.0.0
489
  *
 
 
 
 
 
 
 
490
  * @return bool False on failure.
491
  */
492
  function bp_activity_action_friends_feed() {
513
  *
514
  * @since 1.2.0
515
  *
 
 
 
 
 
 
 
516
  * @return bool False on failure.
517
  */
518
  function bp_activity_action_my_groups_feed() {
547
  *
548
  * @since 1.2.0
549
  *
 
 
 
 
 
550
  * @return bool False on failure.
551
  */
552
  function bp_activity_action_mentions_feed() {
579
  *
580
  * @since 1.2.0
581
  *
 
 
 
 
 
582
  * @return bool False on failure.
583
  */
584
  function bp_activity_action_favorites_feed() {
604
  }
605
  add_action( 'bp_actions', 'bp_activity_action_favorites_feed' );
606
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
607
  /**
608
  * AJAX endpoint for Suggestions API lookups.
609
  *
832
 
833
  // Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated
834
  $post_type_comment_action = $activity_comment_object->action_id;
835
+ $comment_akismet_history = function ( $activity_types ) use ( $post_type_comment_action ) {
836
+ $activity_types[] = $post_type_comment_action;
837
+
838
+ return $activity_types;
839
+ };
840
  add_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
841
 
842
  // Make sure the activity change won't edit the comment if sync is on
bp-activity/bp-activity-admin.php CHANGED
@@ -16,8 +16,6 @@ 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
- 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 );
@@ -167,8 +165,9 @@ function bp_activity_admin_screen_options( $value, $option, $new_value ) {
167
  * @return array Hidden Meta Boxes.
168
  */
169
  function bp_activity_admin_edit_hidden_metaboxes( $hidden, $screen ) {
170
- if ( empty( $screen->id ) || 'toplevel_page_bp-activity' != $screen->id && 'toplevel_page_bp-activity_network' != $screen->id )
171
  return $hidden;
 
172
 
173
  // Hide the primary link meta box by default.
174
  $hidden = array_merge( (array) $hidden, array( 'bp_activity_itemids', 'bp_activity_link', 'bp_activity_type', 'bp_activity_userid', ) );
@@ -299,6 +298,7 @@ function bp_activity_admin_load() {
299
  // Add accessible hidden heading and text for Activity screen pagination.
300
  if ( bp_get_major_wp_version() >= 4.4 ) {
301
  get_current_screen()->set_screen_reader_content( array(
 
302
  'heading_pagination' => __( 'Activity list navigation', 'buddypress' ),
303
  ) );
304
  }
@@ -390,8 +390,8 @@ function bp_activity_admin_load() {
390
  * Remove moderation and blacklist checks in case we want to ham an activity
391
  * which contains one of these listed keys.
392
  */
393
- remove_action( 'bp_activity_before_save', 'bp_activity_check_moderation_keys', 2, 1 );
394
- remove_action( 'bp_activity_before_save', 'bp_activity_check_blacklist_keys', 2, 1 );
395
 
396
  bp_activity_mark_as_ham( $activity );
397
  $result = $activity->save();
@@ -576,9 +576,9 @@ function bp_activity_admin_load() {
576
 
577
  // If an error occurred, pass back the activity ID that failed.
578
  if ( $error )
579
- $redirect_to = add_query_arg( 'error', (int) $error, $redirect_to );
580
  else
581
- $redirect_to = add_query_arg( 'updated', (int) $activity->id, $redirect_to );
582
 
583
  /**
584
  * Filters URL to redirect to after saving.
@@ -674,6 +674,10 @@ function bp_activity_admin_edit() {
674
  <div id="bp_activity_action" class="postbox">
675
  <h2><?php _e( 'Action', 'buddypress' ); ?></h2>
676
  <div class="inside">
 
 
 
 
677
  <?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' ) ) ); ?>
678
  </div>
679
  </div>
@@ -681,6 +685,10 @@ function bp_activity_admin_edit() {
681
  <div id="bp_activity_content" class="postbox">
682
  <h2><?php _e( 'Content', 'buddypress' ); ?></h2>
683
  <div class="inside">
 
 
 
 
684
  <?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' ) ) ); ?>
685
  </div>
686
  </div>
@@ -704,10 +712,16 @@ function bp_activity_admin_edit() {
704
  </form>
705
 
706
  <?php else : ?>
707
- <p>
708
- <?php _e( 'No activity found with this ID.', 'buddypress' ); ?>
709
- <a href="<?php echo esc_url( bp_get_admin_url( 'admin.php?page=bp-activity' ) ); ?>"><?php _e( 'Go back and try again.', 'buddypress' ); ?></a>
710
- </p>
 
 
 
 
 
 
711
  <?php endif; ?>
712
 
713
  </div><!-- .wrap -->
@@ -781,7 +795,10 @@ function bp_activity_admin_edit_metabox_status( $item ) {
781
  function bp_activity_admin_edit_metabox_link( $item ) {
782
  ?>
783
 
784
- <label class="screen-reader-text" for="bp-activities-link"><?php _e( 'Link', 'buddypress' ); ?></label>
 
 
 
785
  <input type="url" name="bp-activities-link" id="bp-activities-link" value="<?php echo esc_url( $item->primary_link ); ?>" aria-describedby="bp-activities-link-description" />
786
  <p id="bp-activities-link-description"><?php _e( 'Activity generated by posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item.', 'buddypress' ); ?></p>
787
 
@@ -798,7 +815,10 @@ function bp_activity_admin_edit_metabox_link( $item ) {
798
  function bp_activity_admin_edit_metabox_userid( $item ) {
799
  ?>
800
 
801
- <label class="screen-reader-text" for="bp-activities-userid"><?php _e( 'Author ID', 'buddypress' ); ?></label>
 
 
 
802
  <input type="number" name="bp-activities-userid" id="bp-activities-userid" value="<?php echo esc_attr( $item->user_id ); ?>" min="1" />
803
 
804
  <?php
@@ -873,7 +893,10 @@ function bp_activity_admin_edit_metabox_type( $item ) {
873
 
874
  ?>
875
 
876
- <label for="bp-activities-type" class="screen-reader-text"><?php esc_html_e( 'Select activity type', 'buddypress' ); ?></label>
 
 
 
877
  <select name="bp-activities-type" id="bp-activities-type">
878
  <?php foreach ( $actions as $k => $v ) : ?>
879
  <option value="<?php echo esc_attr( $k ); ?>" <?php selected( $k, $selected ); ?>><?php echo esc_html( $v ); ?></option>
@@ -1016,6 +1039,10 @@ function bp_activity_admin_index() {
1016
  <form method="get" action="">
1017
 
1018
  <h3 id="bp-replyhead"><?php _e( 'Reply to Activity', 'buddypress' ); ?></h3>
 
 
 
 
1019
  <?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, ) ); ?>
1020
 
1021
  <p id="bp-replysubmit" class="submit">
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 );
165
  * @return array Hidden Meta Boxes.
166
  */
167
  function bp_activity_admin_edit_hidden_metaboxes( $hidden, $screen ) {
168
+ if ( empty( $screen->id ) || 'toplevel_page_bp-activity' !== $screen->id && 'toplevel_page_bp-activity-network' !== $screen->id ) {
169
  return $hidden;
170
+ }
171
 
172
  // Hide the primary link meta box by default.
173
  $hidden = array_merge( (array) $hidden, array( 'bp_activity_itemids', 'bp_activity_link', 'bp_activity_type', 'bp_activity_userid', ) );
298
  // Add accessible hidden heading and text for Activity screen pagination.
299
  if ( bp_get_major_wp_version() >= 4.4 ) {
300
  get_current_screen()->set_screen_reader_content( array(
301
+ /* translators: accessibility text */
302
  'heading_pagination' => __( 'Activity list navigation', 'buddypress' ),
303
  ) );
304
  }
390
  * Remove moderation and blacklist checks in case we want to ham an activity
391
  * which contains one of these listed keys.
392
  */
393
+ remove_action( 'bp_activity_before_save', 'bp_activity_check_moderation_keys', 2 );
394
+ remove_action( 'bp_activity_before_save', 'bp_activity_check_blacklist_keys', 2 );
395
 
396
  bp_activity_mark_as_ham( $activity );
397
  $result = $activity->save();
576
 
577
  // If an error occurred, pass back the activity ID that failed.
578
  if ( $error )
579
+ $redirect_to = add_query_arg( 'error', $error, $redirect_to );
580
  else
581
+ $redirect_to = add_query_arg( 'updated', $activity->id, $redirect_to );
582
 
583
  /**
584
  * Filters URL to redirect to after saving.
674
  <div id="bp_activity_action" class="postbox">
675
  <h2><?php _e( 'Action', 'buddypress' ); ?></h2>
676
  <div class="inside">
677
+ <label for="bp-activities-action" class="screen-reader-text"><?php
678
+ /* translators: accessibility text */
679
+ _e( 'Edit activity action', 'buddypress' );
680
+ ?></label>
681
  <?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' ) ) ); ?>
682
  </div>
683
  </div>
685
  <div id="bp_activity_content" class="postbox">
686
  <h2><?php _e( 'Content', 'buddypress' ); ?></h2>
687
  <div class="inside">
688
+ <label for="bp-activities-content" class="screen-reader-text"><?php
689
+ /* translators: accessibility text */
690
+ _e( 'Edit activity content', 'buddypress' );
691
+ ?></label>
692
  <?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' ) ) ); ?>
693
  </div>
694
  </div>
712
  </form>
713
 
714
  <?php else : ?>
715
+
716
+ <p><?php
717
+ printf(
718
+ '%1$s <a href="%2$s">%3$s</a>',
719
+ __( 'No activity found with this ID.', 'buddypress' ),
720
+ esc_url( bp_get_admin_url( 'admin.php?page=bp-activity' ) ),
721
+ __( 'Go back and try again.', 'buddypress' )
722
+ );
723
+ ?></p>
724
+
725
  <?php endif; ?>
726
 
727
  </div><!-- .wrap -->
795
  function bp_activity_admin_edit_metabox_link( $item ) {
796
  ?>
797
 
798
+ <label class="screen-reader-text" for="bp-activities-link"><?php
799
+ /* translators: accessibility text */
800
+ _e( 'Link', 'buddypress' );
801
+ ?></label>
802
  <input type="url" name="bp-activities-link" id="bp-activities-link" value="<?php echo esc_url( $item->primary_link ); ?>" aria-describedby="bp-activities-link-description" />
803
  <p id="bp-activities-link-description"><?php _e( 'Activity generated by posts and comments, forum topics and replies, and some plugins, uses the link field for a permalink back to the content item.', 'buddypress' ); ?></p>
804
 
815
  function bp_activity_admin_edit_metabox_userid( $item ) {
816
  ?>
817
 
818
+ <label class="screen-reader-text" for="bp-activities-userid"><?php
819
+ /* translators: accessibility text */
820
+ _e( 'Author ID', 'buddypress' );
821
+ ?></label>
822
  <input type="number" name="bp-activities-userid" id="bp-activities-userid" value="<?php echo esc_attr( $item->user_id ); ?>" min="1" />
823
 
824
  <?php
893
 
894
  ?>
895
 
896
+ <label for="bp-activities-type" class="screen-reader-text"><?php
897
+ /* translators: accessibility text */
898
+ esc_html_e( 'Select activity type', 'buddypress' );
899
+ ?></label>
900
  <select name="bp-activities-type" id="bp-activities-type">
901
  <?php foreach ( $actions as $k => $v ) : ?>
902
  <option value="<?php echo esc_attr( $k ); ?>" <?php selected( $k, $selected ); ?>><?php echo esc_html( $v ); ?></option>
1039
  <form method="get" action="">
1040
 
1041
  <h3 id="bp-replyhead"><?php _e( 'Reply to Activity', 'buddypress' ); ?></h3>
1042
+ <label for="bp-activities" class="screen-reader-text"><?php
1043
+ /* translators: accessibility text */
1044
+ _e( 'Reply', 'buddypress' );
1045
+ ?></label>
1046
  <?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, ) ); ?>
1047
 
1048
  <p id="bp-replysubmit" class="submit">
bp-activity/bp-activity-adminbar.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BuddyPress Activity Toolbar.
4
+ *
5
+ * Handles the activity functions related to the WordPress Toolbar.
6
+ *
7
+ * @package BuddyPress
8
+ * @subpackage Activity
9
+ */
10
+
11
+ // Exit if accessed directly.
12
+ defined( 'ABSPATH' ) || exit;
13
+
14
+ /**
15
+ * Add the Activity top-level menu link when viewing single activity item.
16
+ *
17
+ * @since 2.6.0
18
+ *
19
+ * @return null Null if user does not have access to editing functionality.
20
+ */
21
+ function bp_activity_admin_menu() {
22
+ global $wp_admin_bar;
23
+
24
+ // Only show if viewing a single activity item.
25
+ if ( ! bp_is_single_activity() ) {
26
+ return;
27
+ }
28
+
29
+ // Only show this menu to super admins
30
+ if ( ! bp_current_user_can( 'bp_moderate' ) ) {
31
+ return;
32
+ }
33
+
34
+ $activity_edit_link = add_query_arg( array(
35
+ 'page' => 'bp-activity',
36
+ 'aid' => bp_current_action(),
37
+ 'action' => 'edit'
38
+ ), bp_get_admin_url( 'admin.php' ) );
39
+
40
+ // Add the top-level Edit Activity button.
41
+ $wp_admin_bar->add_menu( array(
42
+ 'id' => 'activity-admin',
43
+ 'title' => __( 'Edit Activity', 'buddypress' ),
44
+ 'href' => esc_url( $activity_edit_link ),
45
+ ) );
46
+ }
47
+ add_action( 'admin_bar_menu', 'bp_activity_admin_menu', 99 );
bp-activity/bp-activity-akismet.php CHANGED
@@ -10,7 +10,28 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- require dirname( __FILE__ ) . '/classes/class-bp-akismet.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  /**
16
  * Delete old spam activity meta data.
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
+ /**
14
+ * Loads Akismet filtering for activity.
15
+ *
16
+ * @since 1.6.0
17
+ * @since 2.3.0 We only support Akismet 3+.
18
+ */
19
+ function bp_activity_setup_akismet() {
20
+ /**
21
+ * Filters if BuddyPress Activity Akismet support has been disabled by another plugin.
22
+ *
23
+ * @since 1.6.0
24
+ *
25
+ * @param bool $value Return value of bp_is_akismet_active boolean function.
26
+ */
27
+ if ( ! apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) ) {
28
+ return;
29
+ }
30
+
31
+ // Instantiate Akismet for BuddyPress.
32
+ buddypress()->activity->akismet = new BP_Akismet();
33
+ }
34
+ add_action( 'bp_activity_setup_globals', 'bp_activity_setup_akismet' );
35
 
36
  /**
37
  * Delete old spam activity meta data.
bp-activity/bp-activity-cache.php CHANGED
@@ -63,3 +63,24 @@ function bp_activity_clear_cache_for_deleted_activity( $deleted_ids ) {
63
  }
64
  }
65
  add_action( 'bp_activity_deleted_activities', 'bp_activity_clear_cache_for_deleted_activity' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
  }
65
  add_action( 'bp_activity_deleted_activities', 'bp_activity_clear_cache_for_deleted_activity' );
66
+
67
+ /**
68
+ * Reset cache incrementor for the Activity component.
69
+ *
70
+ * Called whenever an activity item is created, updated, or deleted, this
71
+ * function effectively invalidates all cached results of activity queries.
72
+ *
73
+ * @since 2.7.0
74
+ *
75
+ * @return bool True on success, false on failure.
76
+ */
77
+ function bp_activity_reset_cache_incrementor() {
78
+ $without_last_activity = bp_core_reset_incrementor( 'bp_activity' );
79
+ $with_last_activity = bp_core_reset_incrementor( 'bp_activity_with_last_activity' );
80
+ return $without_last_activity && $with_last_activity;
81
+ }
82
+ add_action( 'bp_activity_delete', 'bp_activity_reset_cache_incrementor' );
83
+ add_action( 'bp_activity_add', 'bp_activity_reset_cache_incrementor' );
84
+ add_action( 'added_activity_meta', 'bp_activity_reset_cache_incrementor' );
85
+ add_action( 'updated_activity_meta', 'bp_activity_reset_cache_incrementor' );
86
+ add_action( 'deleted_activity_meta', 'bp_activity_reset_cache_incrementor' );
bp-activity/bp-activity-classes.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Activity Classes.
4
- *
5
- * @package BuddyPress
6
- * @subpackage ActivityClasses
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- require dirname( __FILE__ ) . '/classes/class-bp-activity-activity.php';
14
- require dirname( __FILE__ ) . '/classes/class-bp-activity-feed.php';
15
- require dirname( __FILE__ ) . '/classes/class-bp-activity-query.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-activity/bp-activity-embeds.php ADDED
@@ -0,0 +1,352 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Functions related to embedding single activity items externally.
4
+ *
5
+ * Relies on WordPress 4.5.
6
+ *
7
+ * @since 2.6.0
8
+ *
9
+ * @package BuddyPress
10
+ * @subpackage ActivityEmbeds
11
+ */
12
+
13
+ // Exit if accessed directly.
14
+ defined( 'ABSPATH' ) || exit;
15
+
16
+ /**
17
+ * Loads our activity oEmbed component.
18
+ *
19
+ * @since 2.6.0
20
+ */
21
+ function bp_activity_setup_oembed() {
22
+ if ( version_compare( $GLOBALS['wp_version'], '4.5', '>=' ) && bp_is_active( 'activity', 'embeds' ) ) {
23
+ buddypress()->activity->oembed = new BP_Activity_oEmbed_Extension;
24
+ }
25
+ }
26
+ add_action( 'bp_loaded', 'bp_activity_setup_oembed' );
27
+
28
+ /**
29
+ * Catch links in embed excerpt so top.location.href can be added.
30
+ *
31
+ * Due to <iframe sandbox="allow-top-navigation">, links in embeds can only be
32
+ * clicked if invoked with top.location.href via JS.
33
+ *
34
+ * @since 2.6.0
35
+ *
36
+ * @param string $text Embed excerpt
37
+ * @return string
38
+ */
39
+ function bp_activity_embed_excerpt_onclick_location_filter( $text ) {
40
+ return preg_replace_callback( '/<a\s+[^>]*href=\"([^\"]*)\"/iU', 'bp_activity_embed_excerpt_onclick_location_filter_callback', $text );
41
+ }
42
+ /**
43
+ * Add onclick="top.location.href" to a link.
44
+ *
45
+ * @since 2.6.0
46
+ *
47
+ * @param array $matches Items matched by bp_activity_embed_excerpt_onclick_location_filter().
48
+ * @return string
49
+ */
50
+ function bp_activity_embed_excerpt_onclick_location_filter_callback( $matches ) {
51
+ return sprintf( '<a href="%1$s" onclick="top.location.href=\'%1$s\'"', $matches[1] );
52
+ }
53
+
54
+ /**
55
+ * Add inline styles for BP activity embeds.
56
+ *
57
+ * @since 2.6.0
58
+ */
59
+ function bp_activity_embed_add_inline_styles() {
60
+ if ( false === bp_is_single_activity() ) {
61
+ return;
62
+ }
63
+
64
+ $min = bp_core_get_minified_asset_suffix();
65
+
66
+ if ( is_rtl() ) {
67
+ $css = bp_locate_template_asset( "css/embeds-activity-rtl{$min}.css" );
68
+ } else {
69
+ $css = bp_locate_template_asset( "css/embeds-activity{$min}.css" );
70
+ }
71
+
72
+ // Bail if file wasn't found.
73
+ if ( false === $css ) {
74
+ return;
75
+ }
76
+
77
+ // Grab contents of CSS file and do some rudimentary CSS protection.
78
+ $css = file_get_contents( $css['file'] );
79
+ $css = wp_kses( $css, array( "\'", '\"' ) );
80
+
81
+ printf( '<style type="text/css">%s</style>', $css );
82
+ }
83
+ add_action( 'embed_head', 'bp_activity_embed_add_inline_styles', 20 );
84
+
85
+ /**
86
+ * Query for the activity item on the activity embed template.
87
+ *
88
+ * Basically a wrapper for {@link bp_has_activities()}, but allows us to
89
+ * use the activity loop without requerying for it again.
90
+ *
91
+ * @since 2.6.0
92
+ *
93
+ * @param int $activity_id The activity ID.
94
+ * @return bool
95
+ */
96
+ function bp_activity_embed_has_activity( $activity_id = 0 ) {
97
+ global $activities_template;
98
+
99
+ if ( empty( $activity_id ) ) {
100
+ return false;
101
+ }
102
+
103
+ if ( ! empty( $activities_template->activities ) ) {
104
+ $activity = (array) $activities_template->activities;
105
+ $activity = reset( $activity );
106
+
107
+ // No need to requery if we already got the embed activity
108
+ if ( (int) $activity_id === $activity->id ) {
109
+ return $activities_template->has_activities();
110
+ }
111
+ }
112
+
113
+ return bp_has_activities( array(
114
+ 'display_comments' => 'threaded',
115
+ 'show_hidden' => true,
116
+ 'include' => (int) $activity_id,
117
+ ) );
118
+ }
119
+
120
+ /**
121
+ * Outputs excerpt for an activity embed item.
122
+ *
123
+ * @since 2.6.0
124
+ */
125
+ function bp_activity_embed_excerpt( $content = '' ) {
126
+ echo bp_activity_get_embed_excerpt( $content = '' );
127
+ }
128
+
129
+ /**
130
+ * Generates excerpt for an activity embed item.
131
+ *
132
+ * @since 2.6.0
133
+ *
134
+ * @param string $content The content to generate an excerpt for.
135
+ * @return string
136
+ */
137
+ function bp_activity_get_embed_excerpt( $content = '' ) {
138
+ if ( empty( $content ) && ! empty( $GLOBALS['activities_template']->in_the_loop ) ) {
139
+ $content = $GLOBALS['activities_template']->activity->content;
140
+ }
141
+
142
+ /*
143
+ * bp_activity_truncate_entry() includes the 'Read More' link, which is why
144
+ * we're using this instead of bp_create_excerpt().
145
+ */
146
+ $content = html_entity_decode( $content );
147
+ $content = bp_activity_truncate_entry( $content, array(
148
+ 'html' => false,
149
+ 'filter_shortcodes' => true,
150
+ 'strip_tags' => true,
151
+ 'force_truncate' => true
152
+ ) );
153
+
154
+ /**
155
+ * Filter the activity embed excerpt.
156
+ *
157
+ * @since 2.6.0
158
+ *
159
+ * @var string $content Embed Excerpt.
160
+ * @var string $unmodified_content Unmodified activity content.
161
+ */
162
+ return apply_filters( 'bp_activity_get_embed_excerpt', $content, $GLOBALS['activities_template']->activity->content );
163
+ }
164
+
165
+ /**
166
+ * Outputs the first embedded item in the activity oEmbed template.
167
+ *
168
+ * @since 2.6.0
169
+ */
170
+ function bp_activity_embed_media() {
171
+ // Bail if oEmbed request explicitly hides media.
172
+ if ( isset( $_GET['hide_media'] ) && true == wp_validate_boolean( $_GET['hide_media'] ) ) {
173
+ /**
174
+ * Do something after media is rendered for an activity oEmbed item.
175
+ *
176
+ * @since 2.6.0
177
+ */
178
+ do_action( 'bp_activity_embed_after_media' );
179
+
180
+ return;
181
+ }
182
+
183
+ /**
184
+ * Should we display media in the oEmbed template?
185
+ *
186
+ * @since 2.6.0
187
+ *
188
+ * @param bool $retval Defaults to true.
189
+ */
190
+ $allow_media = apply_filters( 'bp_activity_embed_display_media', true );
191
+
192
+ // Find oEmbeds from only WP registered providers.
193
+ bp_remove_all_filters( 'oembed_providers' );
194
+ $media = bp_core_extract_media_from_content( $GLOBALS['activities_template']->activity->content, 'embeds' );
195
+ bp_restore_all_filters( 'oembed_providers' );
196
+
197
+ // oEmbeds have precedence over inline video / audio.
198
+ if ( isset( $media['embeds'] ) && true === $allow_media ) {
199
+ // Autoembed first URL.
200
+ $oembed_defaults = wp_embed_defaults();
201
+ $oembed_args = array(
202
+ 'width' => $oembed_defaults['width'],
203
+ 'height' => $oembed_defaults['height'],
204
+ 'discover' => true
205
+ );
206
+ $url = $media['embeds'][0]['url'];
207
+ $cachekey = '_oembed_response_' . md5( $url . serialize( $oembed_args ) );
208
+
209
+ // Try to fetch oEmbed response from meta.
210
+ $oembed = bp_activity_get_meta( bp_get_activity_id(), $cachekey );
211
+
212
+ // No cache, so fetch full oEmbed response now!
213
+ if ( '' === $oembed ) {
214
+ $o = _wp_oembed_get_object();
215
+ $oembed = $o->fetch( $o->get_provider( $url, $oembed_args ), $url, $oembed_args );
216
+
217
+ // Cache oEmbed response.
218
+ bp_activity_update_meta( bp_get_activity_id(), $cachekey, $oembed );
219
+ }
220
+
221
+ $content = '';
222
+
223
+ /**
224
+ * Filters the default embed display max width.
225
+ *
226
+ * This is used if the oEmbed response does not return a thumbnail width.
227
+ *
228
+ * @since 2.6.0
229
+ *
230
+ * @param int $width.
231
+ */
232
+ $width = (int) apply_filters( 'bp_activity_embed_display_media_width', 550 );
233
+
234
+ // Set thumbnail.
235
+ if ( 'photo' === $oembed->type ) {
236
+ $thumbnail = $oembed->url;
237
+ } elseif ( isset( $oembed->thumbnail_url ) ) {
238
+ $thumbnail = $oembed->thumbnail_url;
239
+
240
+ /* Non-oEmbed standard attributes */
241
+ // Mixcloud
242
+ } elseif ( isset( $oembed->image ) ) {
243
+ $thumbnail = $oembed->image;
244
+ // ReverbNation
245
+ } elseif ( isset( $oembed->{'thumbnail-url'} ) ) {
246
+ $thumbnail = $oembed->{'thumbnail-url'};
247
+ }
248
+
249
+ // Display thumb and related oEmbed meta.
250
+ if ( true === isset ( $thumbnail ) ) {
251
+ $play_icon = $caption = '';
252
+
253
+ // Add play icon for non-photos.
254
+ if ( 'photo' !== $oembed->type ) {
255
+ /**
256
+ * ion-play icon from Ionicons.
257
+ *
258
+ * @link http://ionicons.com/
259
+ * @license MIT
260
+ */
261
+ $play_icon = <<<EOD
262
+ <svg id="Layer_1" style="enable-background:new 0 0 512 512;" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M405.2,232.9L126.8,67.2c-3.4-2-6.9-3.2-10.9-3.2c-10.9,0-19.8,9-19.8,20H96v344h0.1c0,11,8.9,20,19.8,20 c4.1,0,7.5-1.4,11.2-3.4l278.1-165.5c6.6-5.5,10.8-13.8,10.8-23.1C416,246.7,411.8,238.5,405.2,232.9z"/></svg>
263
+ EOD;
264
+
265
+ $play_icon = sprintf( '<a rel="nofollow" class="play-btn" href="%1$s" onclick="top.location.href=\'%1$s\'">%2$s</a>', esc_url( $url ), $play_icon );
266
+ }
267
+
268
+ // Thumb width
269
+ $thumb_width = isset( $oembed->thumbnail_width ) && 'photo' !== $oembed->type && (int) $oembed->thumbnail_width < 550 ? (int) $oembed->thumbnail_width : $width;
270
+
271
+ $float_width = 350;
272
+
273
+ // Set up thumb.
274
+ $content = sprintf( '<div class="thumb" style="max-width:%1$spx">%2$s<a href="%3$s" rel="nofollow" onclick="top.location.href=\'%3$s\'"><img src="%4$s" /></a></div>', $thumb_width, $play_icon, esc_url( $url ), esc_url( $thumbnail ) );
275
+
276
+ // Show title.
277
+ if ( isset( $oembed->title ) ) {
278
+ $caption .= sprintf( '<p class="caption-title"><strong>%s</strong></p>', apply_filters( 'single_post_title', $oembed->title ) );
279
+ }
280
+
281
+ // Show description (non-oEmbed standard)
282
+ if ( isset( $oembed->description ) ) {
283
+ $caption .= sprintf( '<div class="caption-description">%s</div>', apply_filters( 'bp_activity_get_embed_excerpt', $oembed->description ) );
284
+ }
285
+
286
+ // Show author info.
287
+ if ( isset( $oembed->provider_name ) && isset( $oembed->author_name ) ) {
288
+ /* translators: By [oEmbed author] on [oEmbed provider]. eg. By BuddyPress on YouTube. */
289
+ $anchor_text = sprintf( __( 'By %1$s on %2$s', 'buddypress' ), $oembed->author_name, $oembed->provider_name );
290
+
291
+ } elseif ( isset( $oembed->provider_name ) ) {
292
+ $anchor_text = sprintf( __( 'View on %s', 'buddypress' ), $oembed->provider_name );
293
+ }
294
+
295
+ if ( true === isset( $anchor_text ) ) {
296
+ $caption .= sprintf( '<a rel="nofollow" href="%1$s" onclick="top.location.href=\'%1$s\'">%2$s</a>', esc_url( $url ), apply_filters( 'the_title', $anchor_text ) );
297
+ }
298
+
299
+ // Set up caption.
300
+ if ( '' !== $caption ) {
301
+ $css_class = isset( $oembed->provider_name ) ? sprintf( ' provider-%s', sanitize_html_class( strtolower( $oembed->provider_name ) ) ) : '';
302
+ $caption = sprintf( '<div class="caption%1$s" style="width:%2$s">%3$s</div>',
303
+ $css_class,
304
+ $thumb_width > $float_width ? 100 . '%' : round( ( $width - (int) $thumb_width ) / $width * 100 ) . '%',
305
+ $caption
306
+ );
307
+
308
+ $content .= $caption;
309
+ }
310
+ }
311
+
312
+ // Print rich content.
313
+ if ( '' !== $content ) {
314
+ printf( '<div class="bp-activity-embed-display-media %s" style="max-width:%spx">%s</div>',
315
+ $thumb_width < $float_width ? 'two-col' : 'one-col',
316
+ $thumb_width < $float_width ? $width : $thumb_width,
317
+ $content
318
+ );
319
+ }
320
+
321
+ // Video / audio.
322
+ } elseif ( true === $allow_media ) {
323
+ // Call BP_Embed if it hasn't already loaded.
324
+ bp_embed_init();
325
+
326
+ // Run shortcode and embed routine.
327
+ $content = buddypress()->embed->run_shortcode( $GLOBALS['activities_template']->activity->content );
328
+ $content = buddypress()->embed->autoembed( $content );
329
+
330
+ // Try to find inline video / audio.
331
+ $media = bp_core_extract_media_from_content( $content, 96 );
332
+
333
+ // Video takes precedence. HTML5-only.
334
+ if ( isset( $media['videos'] ) && 'shortcodes' === $media['videos'][0]['source'] ) {
335
+ printf( '<video controls preload="metadata"><source src="%1$s"><p>%2$s</p></video>',
336
+ esc_url( $media['videos'][0]['url'] ),
337
+ esc_html__( 'Your browser does not support HTML5 video', 'buddypress' )
338
+ );
339
+
340
+ // No video? Try audio. HTML5-only.
341
+ } elseif ( isset( $media['audio'] ) && 'shortcodes' === $media['audio'][0]['source'] ) {
342
+ printf( '<audio controls preload="metadata"><source src="%1$s"><p>%2$s</p></audio>',
343
+ esc_url( $media['audio'][0]['url'] ),
344
+ esc_html__( 'Your browser does not support HTML5 audio', 'buddypress' )
345
+ );
346
+ }
347
+
348
+ }
349
+
350
+ /** This hook is documented in /bp-activity/bp-activity-embeds.php */
351
+ do_action( 'bp_activity_embed_after_media' );
352
+ }
bp-activity/bp-activity-filters.php CHANGED
@@ -43,6 +43,7 @@ add_filter( 'bp_get_activity_content', 'wptexturize' );
43
  add_filter( 'bp_get_activity_parent_content', 'wptexturize' );
44
  add_filter( 'bp_get_activity_latest_update', 'wptexturize' );
45
  add_filter( 'bp_get_activity_latest_update_excerpt', 'wptexturize' );
 
46
 
47
  add_filter( 'bp_get_activity_action', 'convert_smilies' );
48
  add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
@@ -50,6 +51,7 @@ add_filter( 'bp_get_activity_content', 'convert_smilies' );
50
  add_filter( 'bp_get_activity_parent_content', 'convert_smilies' );
51
  add_filter( 'bp_get_activity_latest_update', 'convert_smilies' );
52
  add_filter( 'bp_get_activity_latest_update_excerpt', 'convert_smilies' );
 
53
 
54
  add_filter( 'bp_get_activity_action', 'convert_chars' );
55
  add_filter( 'bp_get_activity_content_body', 'convert_chars' );
@@ -57,11 +59,13 @@ add_filter( 'bp_get_activity_content', 'convert_chars' );
57
  add_filter( 'bp_get_activity_parent_content', 'convert_chars' );
58
  add_filter( 'bp_get_activity_latest_update', 'convert_chars' );
59
  add_filter( 'bp_get_activity_latest_update_excerpt', 'convert_chars' );
 
60
 
61
  add_filter( 'bp_get_activity_action', 'wpautop' );
62
  add_filter( 'bp_get_activity_content_body', 'wpautop' );
63
  add_filter( 'bp_get_activity_content', 'wpautop' );
64
  add_filter( 'bp_get_activity_feed_item_description', 'wpautop' );
 
65
 
66
  add_filter( 'bp_get_activity_action', 'make_clickable', 9 );
67
  add_filter( 'bp_get_activity_content_body', 'make_clickable', 9 );
@@ -70,6 +74,7 @@ add_filter( 'bp_get_activity_parent_content', 'make_clickable', 9 );
70
  add_filter( 'bp_get_activity_latest_update', 'make_clickable', 9 );
71
  add_filter( 'bp_get_activity_latest_update_excerpt', 'make_clickable', 9 );
72
  add_filter( 'bp_get_activity_feed_item_description', 'make_clickable', 9 );
 
73
 
74
  add_filter( 'bp_acomment_name', 'stripslashes_deep', 5 );
75
  add_filter( 'bp_get_activity_action', 'stripslashes_deep', 5 );
@@ -94,6 +99,7 @@ add_filter( 'pre_comment_content', 'bp_activity_at_name_filter
94
  add_filter( 'group_forum_topic_text_before_save', 'bp_activity_at_name_filter' );
95
  add_filter( 'group_forum_post_text_before_save', 'bp_activity_at_name_filter' );
96
  add_filter( 'the_content', 'bp_activity_at_name_filter' );
 
97
 
98
  add_filter( 'bp_get_activity_parent_content', 'bp_create_excerpt' );
99
 
@@ -103,6 +109,8 @@ add_filter( 'bp_get_activity_content', 'bp_activity_truncate_entry', 5 );
103
  add_filter( 'bp_get_total_favorite_count_for_user', 'bp_core_number_format' );
104
  add_filter( 'bp_get_total_mention_count_for_user', 'bp_core_number_format' );
105
 
 
 
106
  /* Actions *******************************************************************/
107
 
108
  // At-name filter.
@@ -147,13 +155,19 @@ function bp_activity_get_moderated_activity_types() {
147
  function bp_activity_check_moderation_keys( $activity ) {
148
 
149
  // Only check specific types of activity updates.
150
- if ( !in_array( $activity->type, bp_activity_get_moderated_activity_types() ) )
151
  return;
 
152
 
153
- // Unset the activity component so activity stream update fails
154
  // @todo This is temporary until some kind of moderation is built.
155
- if ( !bp_core_check_for_moderation( $activity->user_id, '', $activity->content ) )
 
 
 
 
156
  $activity->component = false;
 
157
  }
158
 
159
  /**
@@ -166,12 +180,19 @@ function bp_activity_check_moderation_keys( $activity ) {
166
  function bp_activity_check_blacklist_keys( $activity ) {
167
 
168
  // Only check specific types of activity updates.
169
- if ( ! in_array( $activity->type, bp_activity_get_moderated_activity_types() ) )
170
  return;
 
 
 
 
 
 
 
171
 
172
- // Mark as spam.
173
- if ( ! bp_core_check_for_blacklist( $activity->user_id, '', $activity->content ) )
174
- bp_activity_mark_as_spam( $activity, 'by_blacklist' );
175
  }
176
 
177
  /**
@@ -179,9 +200,6 @@ function bp_activity_check_blacklist_keys( $activity ) {
179
  *
180
  * @since 1.1.0
181
  *
182
- * @uses apply_filters() To call the 'bp_activity_allowed_tags' hook.
183
- * @uses wp_kses()
184
- *
185
  * @param string $content The activity content.
186
  * @return string $content Filtered activity content.
187
  */
@@ -189,13 +207,15 @@ function bp_activity_filter_kses( $content ) {
189
  global $allowedtags;
190
 
191
  $activity_allowedtags = $allowedtags;
192
- $activity_allowedtags['a']['class'] = array();
193
- $activity_allowedtags['a']['id'] = array();
194
- $activity_allowedtags['a']['rel'] = array();
195
- $activity_allowedtags['a']['title'] = array();
196
- $activity_allowedtags['b'] = array();
197
- $activity_allowedtags['code'] = array();
198
- $activity_allowedtags['i'] = array();
 
 
199
  $activity_allowedtags['img'] = array();
200
  $activity_allowedtags['img']['src'] = array();
201
  $activity_allowedtags['img']['alt'] = array();
@@ -204,8 +224,10 @@ function bp_activity_filter_kses( $content ) {
204
  $activity_allowedtags['img']['class'] = array();
205
  $activity_allowedtags['img']['id'] = array();
206
  $activity_allowedtags['img']['title'] = array();
207
- $activity_allowedtags['span'] = array();
208
- $activity_allowedtags['span']['class'] = array();
 
 
209
 
210
 
211
  /**
@@ -260,7 +282,7 @@ function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
260
 
261
  // Linkify the mentions with the username.
262
  foreach ( (array) $usernames as $user_id => $username ) {
263
- $content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $content );
264
  }
265
 
266
  // Put everything back.
@@ -282,8 +304,6 @@ function bp_activity_at_name_filter( $content, $activity_id = 0 ) {
282
  *
283
  * @since 1.5.0
284
  *
285
- * @uses bp_activity_find_mentions()
286
- *
287
  * @param BP_Activity_Activity $activity Activity Object.
288
  */
289
  function bp_activity_at_name_filter_updates( $activity ) {
@@ -303,7 +323,7 @@ function bp_activity_at_name_filter_updates( $activity ) {
303
  if ( ! empty( $usernames ) ) {
304
  // Replace @mention text with userlinks.
305
  foreach( (array) $usernames as $user_id => $username ) {
306
- $activity->content = preg_replace( '/(@' . $username . '\b)/', "<a href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $activity->content );
307
  }
308
 
309
  // Add our hook to send @mention emails after the activity item is saved.
@@ -319,9 +339,6 @@ function bp_activity_at_name_filter_updates( $activity ) {
319
  *
320
  * @since 1.7.0
321
  *
322
- * @uses bp_activity_at_message_notification()
323
- * @uses bp_activity_update_mention_count_for_user()
324
- *
325
  * @param BP_Activity_Activity $activity The BP_Activity_Activity object.
326
  */
327
  function bp_activity_at_name_send_emails( $activity ) {
@@ -395,19 +412,16 @@ function bp_activity_make_nofollow_filter( $text ) {
395
  * This method can only be used inside the Activity loop.
396
  *
397
  * @since 1.5.0
398
- *
399
- * @uses bp_is_single_activity()
400
- * @uses apply_filters() To call the 'bp_activity_excerpt_append_text' hook.
401
- * @uses apply_filters() To call the 'bp_activity_excerpt_length' hook.
402
- * @uses bp_create_excerpt()
403
- * @uses bp_get_activity_id()
404
- * @uses bp_get_activity_thread_permalink()
405
- * @uses apply_filters() To call the 'bp_activity_truncate_entry' hook.
406
  *
407
  * @param string $text The original activity entry text.
 
 
 
 
408
  * @return string $excerpt The truncated text.
409
  */
410
- function bp_activity_truncate_entry( $text ) {
411
  global $activities_template;
412
 
413
  /**
@@ -423,7 +437,7 @@ function bp_activity_truncate_entry( $text ) {
423
  );
424
 
425
  // The full text of the activity update should always show on the single activity screen.
426
- if ( ! $maybe_truncate_text || bp_is_single_activity() ) {
427
  return $text;
428
  }
429
 
@@ -436,24 +450,19 @@ function bp_activity_truncate_entry( $text ) {
436
  */
437
  $append_text = apply_filters( 'bp_activity_excerpt_append_text', __( '[Read more]', 'buddypress' ) );
438
 
439
- /**
440
- * Filters the excerpt length for the activity excerpt.
441
- *
442
- * @since 1.5.0
443
- *
444
- * @param int $value Number indicating how many words to trim the excerpt down to.
445
- */
446
- $excerpt_length = apply_filters( 'bp_activity_excerpt_length', 358 );
447
 
448
  // Run the text through the excerpt function. If it's too short, the original text will be returned.
449
- $excerpt = bp_create_excerpt( $text, $excerpt_length, array( 'ending' => __( '&hellip;', 'buddypress' ) ) );
450
 
451
  /*
452
  * If the text returned by bp_create_excerpt() is different from the original text (ie it's
453
  * been truncated), add the "Read More" link. Note that bp_create_excerpt() is stripping
454
  * shortcodes, so we have strip them from the $text before the comparison.
455
  */
456
- if ( $excerpt != strip_shortcodes( $text ) ) {
457
  $id = !empty( $activities_template->activity->current_comment->id ) ? 'acomment-read-more-' . $activities_template->activity->current_comment->id : 'activity-read-more-' . bp_get_activity_id();
458
 
459
  $excerpt = sprintf( '%1$s<span class="activity-read-more" id="%2$s"><a href="%3$s" rel="nofollow">%4$s</a></span>', $excerpt, $id, bp_get_activity_thread_permalink(), $append_text );
@@ -476,8 +485,6 @@ function bp_activity_truncate_entry( $text ) {
476
  *
477
  * @since 2.0.0
478
  *
479
- * @uses bp_activity_do_heartbeat() to check if heartbeat is required.
480
- *
481
  * @param array $js_handles The original dependencies.
482
  * @return array $js_handles The new dependencies.
483
  */
@@ -543,8 +550,6 @@ add_filter( 'bp_get_activity_css_class', 'bp_activity_timestamp_class', 9, 1 );
543
  *
544
  * @since 2.0.0
545
  *
546
- * @uses bp_activity_get_last_updated() to get the recorded date of the last activity.
547
- *
548
  * @param array $response Array containing Heartbeat API response.
549
  * @param array $data Array containing data for Heartbeat API response.
550
  * @return array $response
@@ -591,7 +596,7 @@ function bp_activity_heartbeat_last_recorded( $response = array(), $data = array
591
  ob_end_clean();
592
 
593
  // Remove the temporary filter.
594
- remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10, 1 );
595
 
596
  if ( ! empty( $newest_activities['last_recorded'] ) ) {
597
  $response['bp_activity_newest_activities'] = $newest_activities;
43
  add_filter( 'bp_get_activity_parent_content', 'wptexturize' );
44
  add_filter( 'bp_get_activity_latest_update', 'wptexturize' );
45
  add_filter( 'bp_get_activity_latest_update_excerpt', 'wptexturize' );
46
+ add_filter( 'bp_activity_get_embed_excerpt', 'wptexturize' );
47
 
48
  add_filter( 'bp_get_activity_action', 'convert_smilies' );
49
  add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
51
  add_filter( 'bp_get_activity_parent_content', 'convert_smilies' );
52
  add_filter( 'bp_get_activity_latest_update', 'convert_smilies' );
53
  add_filter( 'bp_get_activity_latest_update_excerpt', 'convert_smilies' );
54
+ add_filter( 'bp_activity_get_embed_excerpt', 'convert_smilies' );
55
 
56
  add_filter( 'bp_get_activity_action', 'convert_chars' );
57
  add_filter( 'bp_get_activity_content_body', 'convert_chars' );
59
  add_filter( 'bp_get_activity_parent_content', 'convert_chars' );
60
  add_filter( 'bp_get_activity_latest_update', 'convert_chars' );
61
  add_filter( 'bp_get_activity_latest_update_excerpt', 'convert_chars' );
62
+ add_filter( 'bp_activity_get_embed_excerpt', 'convert_chars' );
63
 
64
  add_filter( 'bp_get_activity_action', 'wpautop' );
65
  add_filter( 'bp_get_activity_content_body', 'wpautop' );
66
  add_filter( 'bp_get_activity_content', 'wpautop' );
67
  add_filter( 'bp_get_activity_feed_item_description', 'wpautop' );
68
+ add_filter( 'bp_activity_get_embed_excerpt', 'wpautop' );
69
 
70
  add_filter( 'bp_get_activity_action', 'make_clickable', 9 );
71
  add_filter( 'bp_get_activity_content_body', 'make_clickable', 9 );
74
  add_filter( 'bp_get_activity_latest_update', 'make_clickable', 9 );
75
  add_filter( 'bp_get_activity_latest_update_excerpt', 'make_clickable', 9 );
76
  add_filter( 'bp_get_activity_feed_item_description', 'make_clickable', 9 );
77
+ add_filter( 'bp_activity_get_embed_excerpt', 'make_clickable', 9 );
78
 
79
  add_filter( 'bp_acomment_name', 'stripslashes_deep', 5 );
80
  add_filter( 'bp_get_activity_action', 'stripslashes_deep', 5 );
99
  add_filter( 'group_forum_topic_text_before_save', 'bp_activity_at_name_filter' );
100
  add_filter( 'group_forum_post_text_before_save', 'bp_activity_at_name_filter' );
101
  add_filter( 'the_content', 'bp_activity_at_name_filter' );
102
+ add_filter( 'bp_activity_get_embed_excerpt', 'bp_activity_at_name_filter' );
103
 
104
  add_filter( 'bp_get_activity_parent_content', 'bp_create_excerpt' );
105
 
109
  add_filter( 'bp_get_total_favorite_count_for_user', 'bp_core_number_format' );
110
  add_filter( 'bp_get_total_mention_count_for_user', 'bp_core_number_format' );
111
 
112
+ add_filter( 'bp_activity_get_embed_excerpt', 'bp_activity_embed_excerpt_onclick_location_filter', 9 );
113
+
114
  /* Actions *******************************************************************/
115
 
116
  // At-name filter.
155
  function bp_activity_check_moderation_keys( $activity ) {
156
 
157
  // Only check specific types of activity updates.
158
+ if ( ! in_array( $activity->type, bp_activity_get_moderated_activity_types() ) ) {
159
  return;
160
+ }
161
 
162
+ // Send back the error so activity update fails.
163
  // @todo This is temporary until some kind of moderation is built.
164
+ $moderate = bp_core_check_for_moderation( $activity->user_id, '', $activity->content, 'wp_error' );
165
+ if ( is_wp_error( $moderate ) ) {
166
+ $activity->errors = $moderate;
167
+
168
+ // Backpat.
169
  $activity->component = false;
170
+ }
171
  }
172
 
173
  /**
180
  function bp_activity_check_blacklist_keys( $activity ) {
181
 
182
  // Only check specific types of activity updates.
183
+ if ( ! in_array( $activity->type, bp_activity_get_moderated_activity_types() ) ) {
184
  return;
185
+ }
186
+
187
+ // Send back the error so activity update fails.
188
+ // @todo This is temporary until some kind of trash status is built.
189
+ $blacklist = bp_core_check_for_blacklist( $activity->user_id, '', $activity->content, 'wp_error' );
190
+ if ( is_wp_error( $blacklist ) ) {
191
+ $activity->errors = $blacklist;
192
 
193
+ // Backpat.
194
+ $activity->component = false;
195
+ }
196
  }
197
 
198
  /**
200
  *
201
  * @since 1.1.0
202
  *
 
 
 
203
  * @param string $content The activity content.
204
  * @return string $content Filtered activity content.
205
  */
207
  global $allowedtags;
208
 
209
  $activity_allowedtags = $allowedtags;
210
+ $activity_allowedtags['a']['class'] = array();
211
+ $activity_allowedtags['a']['id'] = array();
212
+ $activity_allowedtags['a']['rel'] = array();
213
+ $activity_allowedtags['a']['title'] = array();
214
+
215
+ $activity_allowedtags['b'] = array();
216
+ $activity_allowedtags['code'] = array();
217
+ $activity_allowedtags['i'] = array();
218
+
219
  $activity_allowedtags['img'] = array();
220
  $activity_allowedtags['img']['src'] = array();
221
  $activity_allowedtags['img']['alt'] = array();
224
  $activity_allowedtags['img']['class'] = array();
225
  $activity_allowedtags['img']['id'] = array();
226
  $activity_allowedtags['img']['title'] = array();
227
+
228
+ $activity_allowedtags['span'] = array();
229
+ $activity_allowedtags['span']['class'] = array();
230
+ $activity_allowedtags['span']['data-livestamp'] = array();
231
 
232
 
233
  /**
282
 
283
  // Linkify the mentions with the username.
284
  foreach ( (array) $usernames as $user_id => $username ) {
285
+ $content = preg_replace( '/(@' . $username . '\b)/', "<a class='bp-suggestions-mention' href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $content );
286
  }
287
 
288
  // Put everything back.
304
  *
305
  * @since 1.5.0
306
  *
 
 
307
  * @param BP_Activity_Activity $activity Activity Object.
308
  */
309
  function bp_activity_at_name_filter_updates( $activity ) {
323
  if ( ! empty( $usernames ) ) {
324
  // Replace @mention text with userlinks.
325
  foreach( (array) $usernames as $user_id => $username ) {
326
+ $activity->content = preg_replace( '/(@' . $username . '\b)/', "<a class='bp-suggestions-mention' href='" . bp_core_get_user_domain( $user_id ) . "' rel='nofollow'>@$username</a>", $activity->content );
327
  }
328
 
329
  // Add our hook to send @mention emails after the activity item is saved.
339
  *
340
  * @since 1.7.0
341
  *
 
 
 
342
  * @param BP_Activity_Activity $activity The BP_Activity_Activity object.
343
  */
344
  function bp_activity_at_name_send_emails( $activity ) {
412
  * This method can only be used inside the Activity loop.
413
  *
414
  * @since 1.5.0
415
+ * @since 2.6.0 Added $args parameter.
 
 
 
 
 
 
 
416
  *
417
  * @param string $text The original activity entry text.
418
+ * @param array $args {
419
+ * Optional parameters. See $options argument of {@link bp_create_excerpt()}
420
+ * for all available parameters.
421
+ * }
422
  * @return string $excerpt The truncated text.
423
  */
424
+ function bp_activity_truncate_entry( $text, $args = array() ) {
425
  global $activities_template;
426
 
427
  /**
437
  );
438
 
439
  // The full text of the activity update should always show on the single activity screen.
440
+ if ( empty( $args['force_truncate'] ) && ( ! $maybe_truncate_text || bp_is_single_activity() ) ) {
441
  return $text;
442
  }
443
 
450
  */
451
  $append_text = apply_filters( 'bp_activity_excerpt_append_text', __( '[Read more]', 'buddypress' ) );
452
 
453
+ $excerpt_length = bp_activity_get_excerpt_length();
454
+
455
+ $args = wp_parse_args( $args, array( 'ending' => __( '&hellip;', 'buddypress' ) ) );
 
 
 
 
 
456
 
457
  // Run the text through the excerpt function. If it's too short, the original text will be returned.
458
+ $excerpt = bp_create_excerpt( $text, $excerpt_length, $args );
459
 
460
  /*
461
  * If the text returned by bp_create_excerpt() is different from the original text (ie it's
462
  * been truncated), add the "Read More" link. Note that bp_create_excerpt() is stripping
463
  * shortcodes, so we have strip them from the $text before the comparison.
464
  */
465
+ if ( strlen( $excerpt ) < strlen( strip_shortcodes( $text ) ) ) {
466
  $id = !empty( $activities_template->activity->current_comment->id ) ? 'acomment-read-more-' . $activities_template->activity->current_comment->id : 'activity-read-more-' . bp_get_activity_id();
467
 
468
  $excerpt = sprintf( '%1$s<span class="activity-read-more" id="%2$s"><a href="%3$s" rel="nofollow">%4$s</a></span>', $excerpt, $id, bp_get_activity_thread_permalink(), $append_text );
485
  *
486
  * @since 2.0.0
487
  *
 
 
488
  * @param array $js_handles The original dependencies.
489
  * @return array $js_handles The new dependencies.
490
  */
550
  *
551
  * @since 2.0.0
552
  *
 
 
553
  * @param array $response Array containing Heartbeat API response.
554
  * @param array $data Array containing data for Heartbeat API response.
555
  * @return array $response
596
  ob_end_clean();
597
 
598
  // Remove the temporary filter.
599
+ remove_filter( 'bp_get_activity_css_class', 'bp_activity_newest_class', 10 );
600
 
601
  if ( ! empty( $newest_activities['last_recorded'] ) ) {
602
  $response['bp_activity_newest_activities'] = $newest_activities;
bp-activity/bp-activity-functions.php CHANGED
@@ -40,8 +40,6 @@ function bp_activity_has_directory() {
40
  *
41
  * @since 1.8.0
42
  *
43
- * @uses apply_filters() To call 'bp_activity_do_mentions' hook.
44
- *
45
  * @return bool $retval True to enable mentions, false to disable.
46
  */
47
  function bp_activity_do_mentions() {
@@ -133,8 +131,6 @@ function bp_activity_find_mentions( $content ) {
133
  *
134
  * @since 1.5.0
135
  *
136
- * @uses bp_delete_user_meta()
137
- *
138
  * @param int $user_id The id of the user whose unread mentions are being reset.
139
  */
140
  function bp_activity_clear_new_mentions( $user_id ) {
@@ -161,9 +157,6 @@ function bp_activity_clear_new_mentions( $user_id ) {
161
  *
162
  * @since 1.5.0
163
  *
164
- * @uses bp_activity_find_mentions()
165
- * @uses bp_activity_update_mention_count_for_user()
166
- *
167
  * @param int $activity_id The unique id for the activity item.
168
  * @param string $action Can be 'delete' or 'add'. Defaults to 'add'.
169
  * @return bool
@@ -176,7 +169,7 @@ function bp_activity_adjust_mention_count( $activity_id = 0, $action = 'add' ) {
176
  }
177
 
178
  // Get activity object.
179
- $activity = new BP_Activity_Activity( (int) $activity_id );
180
 
181
  // Try to find mentions.
182
  $usernames = bp_activity_find_mentions( strip_tags( $activity->content ) );
@@ -200,9 +193,6 @@ function bp_activity_adjust_mention_count( $activity_id = 0, $action = 'add' ) {
200
  *
201
  * @since 1.7.0
202
  *
203
- * @uses bp_get_user_meta()
204
- * @uses bp_update_user_meta()
205
- *
206
  * @param int $user_id The user ID.
207
  * @param int $activity_id The unique ID for the activity item.
208
  * @param string $action 'delete' or 'add'. Default: 'add'.
@@ -416,7 +406,7 @@ function bp_activity_set_action( $component_id, $type, $description, $format_cal
416
  * @param array $args {
417
  * An associative array of tracking parameters. All items are optional.
418
  * @type string $bp_activity_admin_filter String to use in the Dashboard > Activity dropdown.
419
- * @type string $bp_activity_front_filter String to use in frontend dropdown.
420
  * @type string $bp_activity_new_post String format to use for generating the activity action. Should be a
421
  * translatable string where %1$s is replaced by a user link and %2$s is
422
  * the URL of the newly created post.
@@ -787,8 +777,6 @@ function bp_activity_get_actions() {
787
  *
788
  * @since 1.1.0
789
  *
790
- * @uses apply_filters() To call the 'bp_activity_get_action' hook.
791
- *
792
  * @param string $component_id The unique string ID of the component.
793
  * @param string $key The action key.
794
  * @return string|bool Action value if found, otherwise false.
@@ -851,6 +839,63 @@ function bp_activity_get_types() {
851
  return apply_filters( 'bp_activity_get_types', $actions );
852
  }
853
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
854
  /** Favorites ****************************************************************/
855
 
856
  /**
@@ -858,9 +903,6 @@ function bp_activity_get_types() {
858
  *
859
  * @since 1.2.0
860
  *
861
- * @uses bp_get_user_meta()
862
- * @uses apply_filters() To call the 'bp_activity_get_user_favorites' hook.
863
- *
864
  * @param int $user_id ID of the user whose favorites are being queried.
865
  * @return array IDs of the user's favorite activity items.
866
  */
@@ -889,14 +931,6 @@ function bp_activity_get_user_favorites( $user_id = 0 ) {
889
  *
890
  * @since 1.2.0
891
  *
892
- * @uses is_user_logged_in()
893
- * @uses bp_get_user_meta()
894
- * @uses bp_activity_get_meta()
895
- * @uses bp_update_user_meta()
896
- * @uses bp_activity_update_meta()
897
- * @uses do_action() To call the 'bp_activity_add_user_favorite' hook.
898
- * @uses do_action() To call the 'bp_activity_add_user_favorite_fail' hook.
899
- *
900
  * @param int $activity_id ID of the activity item being favorited.
901
  * @param int $user_id ID of the user favoriting the activity item.
902
  * @return bool True on success, false on failure.
@@ -971,13 +1005,6 @@ function bp_activity_add_user_favorite( $activity_id, $user_id = 0 ) {
971
  *
972
  * @since 1.2.0
973
  *
974
- * @uses is_user_logged_in()
975
- * @uses bp_get_user_meta()
976
- * @uses bp_activity_get_meta()
977
- * @uses bp_activity_update_meta()
978
- * @uses bp_update_user_meta()
979
- * @uses do_action() To call the 'bp_activity_remove_user_favorite' hook.
980
- *
981
  * @param int $activity_id ID of the activity item being unfavorited.
982
  * @param int $user_id ID of the user unfavoriting the activity item.
983
  * @return bool True on success, false on failure.
@@ -1050,9 +1077,6 @@ function bp_activity_remove_user_favorite( $activity_id, $user_id = 0 ) {
1050
  *
1051
  * @since 1.1.0
1052
  *
1053
- * @uses BP_Activity_Activity::check_exists_by_content() {@link BP_Activity_Activity}
1054
- * @uses apply_filters() To call the 'bp_activity_check_exists_by_content' hook.
1055
- *
1056
  * @param string $content The content to filter by.
1057
  * @return int|null The ID of the located activity item. Null if none is found.
1058
  */
@@ -1063,7 +1087,7 @@ function bp_activity_check_exists_by_content( $content ) {
1063
  *
1064
  * @since 1.1.0
1065
  *
1066
- * @param BP_Activity_Activity $content_exists ID of the activity if found, else null.
1067
  */
1068
  return apply_filters( 'bp_activity_check_exists_by_content', BP_Activity_Activity::check_exists_by_content( $content ) );
1069
  }
@@ -1073,9 +1097,6 @@ function bp_activity_check_exists_by_content( $content ) {
1073
  *
1074
  * @since 1.0.0
1075
  *
1076
- * @uses BP_Activity_Activity::get_last_updated() {@link BP_Activity_Activity}
1077
- * @uses apply_filters() To call the 'bp_activity_get_last_updated' hook.
1078
- *
1079
  * @return string Date last updated.
1080
  */
1081
  function bp_activity_get_last_updated() {
@@ -1095,8 +1116,6 @@ function bp_activity_get_last_updated() {
1095
  *
1096
  * @since 1.2.0
1097
  *
1098
- * @uses BP_Activity_Activity::total_favorite_count() {@link BP_Activity_Activity}
1099
- *
1100
  * @param int $user_id ID of the user whose favorite count is being requested.
1101
  * @return int Total favorite count for the user.
1102
  */
@@ -1160,8 +1179,6 @@ function bp_activity_delete_meta( $activity_id, $meta_key = '', $meta_value = ''
1160
  *
1161
  * @since 1.2.0
1162
  *
1163
- * @uses apply_filters() To call the 'bp_activity_get_meta' hook.
1164
- *
1165
  * @param int $activity_id ID of the activity item whose metadata is being requested.
1166
  * @param string $meta_key Optional. If present, only the metadata matching
1167
  * that meta key will be returned. Otherwise, all metadata for the
@@ -1239,12 +1256,6 @@ function bp_activity_add_meta( $activity_id, $meta_key, $meta_value, $unique = f
1239
  *
1240
  * @since 1.5.0
1241
  *
1242
- * @uses is_user_logged_in()
1243
- * @uses bp_activity_delete()
1244
- * @uses bp_delete_user_meta()
1245
- * @uses do_action() To call the 'bp_activity_remove_data' hook.
1246
- * @uses do_action() To call the 'bp_activity_remove_all_user_data' hook.
1247
- *
1248
  * @param int $user_id ID of the user whose activity is being deleted.
1249
  * @return bool
1250
  */
@@ -1491,7 +1502,7 @@ function bp_activity_generate_action_string( $activity ) {
1491
  $action = apply_filters( 'bp_activity_generate_action_string', $activity->action, $activity );
1492
 
1493
  // Remove the filter for future activity items.
1494
- remove_filter( 'bp_activity_generate_action_string', $actions->{$activity->component}->{$activity->type}['format_callback'], 10, 2 );
1495
 
1496
  return $action;
1497
  }
@@ -1671,11 +1682,6 @@ function bp_activity_format_activity_action_custom_post_type_comment( $action, $
1671
  *
1672
  * @see BP_Activity_Activity::get() For more information on accepted arguments
1673
  * and the format of the returned value.
1674
- * @uses wp_parse_args()
1675
- * @uses wp_cache_get()
1676
- * @uses wp_cache_set()
1677
- * @uses BP_Activity_Activity::get() {@link BP_Activity_Activity}
1678
- * @uses apply_filters_ref_array() To call the 'bp_activity_get' hook.
1679
  *
1680
  * @param array|string $args See BP_Activity_Activity::get() for description.
1681
  * @return array $activity See BP_Activity_Activity::get() for description.
@@ -1714,56 +1720,28 @@ function bp_activity_get( $args = '' ) {
1714
  * );
1715
  */
1716
  'filter' => array()
1717
- ) );
1718
-
1719
- // Attempt to return a cached copy of the first page of sitewide activity.
1720
- if ( ( 1 === (int) $r['page'] ) && empty( $r['max'] ) && ( 'all' === $r['fields'] ) && empty( $r['search_terms'] ) && empty( $r['meta_query'] ) && empty( $r['date_query'] ) && empty( $r['filter_query'] ) && empty( $r['filter'] ) && empty( $r['scope'] )&& empty( $r['exclude'] ) && empty( $r['in'] ) && ( 'DESC' === $r['sort'] ) && empty( $r['exclude'] ) && ( 'ham_only' === $r['spam'] ) ) {
1721
-
1722
- $activity = wp_cache_get( 'bp_activity_sitewide_front', 'bp' );
1723
- if ( false === $activity ) {
1724
-
1725
- $activity = BP_Activity_Activity::get( array(
1726
- 'page' => $r['page'],
1727
- 'per_page' => $r['per_page'],
1728
- 'max' => $r['max'],
1729
- 'fields' => $r['fields'],
1730
- 'sort' => $r['sort'],
1731
- 'search_terms' => $r['search_terms'],
1732
- 'meta_query' => $r['meta_query'],
1733
- 'date_query' => $r['date_query'],
1734
- 'filter_query' => $r['filter_query'],
1735
- 'filter' => $r['filter'],
1736
- 'scope' => $r['scope'],
1737
- 'display_comments' => $r['display_comments'],
1738
- 'show_hidden' => $r['show_hidden'],
1739
- 'spam' => $r['spam'],
1740
- 'update_meta_cache' => $r['update_meta_cache'],
1741
- 'count_total' => $r['count_total'],
1742
- ) );
1743
-
1744
- wp_cache_set( 'bp_activity_sitewide_front', $activity, 'bp' );
1745
- }
1746
 
1747
- } else {
1748
- $activity = BP_Activity_Activity::get( array(
1749
- 'page' => $r['page'],
1750
- 'per_page' => $r['per_page'],
1751
- 'max' => $r['max'],
1752
- 'sort' => $r['sort'],
1753
- 'search_terms' => $r['search_terms'],
1754
- 'meta_query' => $r['meta_query'],
1755
- 'date_query' => $r['date_query'],
1756
- 'filter_query' => $r['filter_query'],
1757
- 'filter' => $r['filter'],
1758
- 'scope' => $r['scope'],
1759
- 'display_comments' => $r['display_comments'],
1760
- 'show_hidden' => $r['show_hidden'],
1761
- 'exclude' => $r['exclude'],
1762
- 'in' => $r['in'],
1763
- 'spam' => $r['spam'],
1764
- 'count_total' => $r['count_total'],
1765
- ) );
1766
- }
1767
 
1768
  /**
1769
  * Filters the requested activity item(s).
@@ -1782,9 +1760,6 @@ function bp_activity_get( $args = '' ) {
1782
  * @since 1.2.0
1783
  *
1784
  * @see BP_Activity_Activity::get() For more information on accepted arguments.
1785
- * @uses wp_parse_args()
1786
- * @uses apply_filters() To call the 'bp_activity_get_specific' hook.
1787
- * @uses BP_Activity_Activity::get() {@link BP_Activity_Activity}
1788
  *
1789
  * @param array|string $args {
1790
  * All arguments and defaults are shared with BP_Activity_Activity::get(),
@@ -1836,12 +1811,7 @@ function bp_activity_get_specific( $args = '' ) {
1836
  * Add an activity item.
1837
  *
1838
  * @since 1.1.0
1839
- *
1840
- * @uses wp_parse_args()
1841
- * @uses BP_Activity_Activity::save() {@link BP_Activity_Activity}
1842
- * @uses BP_Activity_Activity::rebuild_activity_comment_tree() {@link BP_Activity_Activity}
1843
- * @uses wp_cache_delete()
1844
- * @uses do_action() To call the 'bp_activity_add' hook.
1845
  *
1846
  * @param array|string $args {
1847
  * An array of arguments.
@@ -1873,6 +1843,7 @@ function bp_activity_get_specific( $args = '' ) {
1873
  * @type bool $hide_sitewide Should the item be hidden on sitewide streams?
1874
  * Default: false.
1875
  * @type bool $is_spam Should the item be marked as spam? Default: false.
 
1876
  * }
1877
  * @return int|bool The ID of the activity on success. False on error.
1878
  */
@@ -1891,6 +1862,7 @@ function bp_activity_add( $args = '' ) {
1891
  'recorded_time' => bp_core_current_time(), // The GMT time that this activity was recorded.
1892
  'hide_sitewide' => false, // Should this be hidden on the sitewide activity stream?
1893
  'is_spam' => false, // Is this activity item to be marked as spam?
 
1894
  ), 'activity_add' );
1895
 
1896
  // Make sure we are backwards compatible.
@@ -1914,11 +1886,16 @@ function bp_activity_add( $args = '' ) {
1914
  $activity->date_recorded = $r['recorded_time'];
1915
  $activity->hide_sitewide = $r['hide_sitewide'];
1916
  $activity->is_spam = $r['is_spam'];
 
1917
  $activity->action = ! empty( $r['action'] )
1918
- ? $r['action']
1919
- : bp_activity_generate_action_string( $activity );
1920
 
1921
- if ( ! $activity->save() ) {
 
 
 
 
1922
  return false;
1923
  }
1924
 
@@ -1949,28 +1926,21 @@ function bp_activity_add( $args = '' ) {
1949
  *
1950
  * @since 1.2.0
1951
  *
1952
- * @uses wp_parse_args()
1953
- * @uses bp_is_user_inactive()
1954
- * @uses bp_core_get_userlink()
1955
- * @uses bp_activity_add()
1956
- * @uses apply_filters() To call the 'bp_activity_new_update_action' hook.
1957
- * @uses apply_filters() To call the 'bp_activity_new_update_content' hook.
1958
- * @uses apply_filters() To call the 'bp_activity_new_update_primary_link' hook.
1959
- * @uses bp_update_user_meta()
1960
- * @uses wp_filter_kses()
1961
- * @uses do_action() To call the 'bp_activity_posted_update' hook.
1962
- *
1963
  * @param array|string $args {
1964
- * @type string $content The content of the activity update.
1965
- * @type int $user_id Optional. Defaults to the logged-in user.
 
 
1966
  * }
1967
- * @return int $activity_id The activity id.
 
1968
  */
1969
  function bp_activity_post_update( $args = '' ) {
1970
 
1971
  $r = wp_parse_args( $args, array(
1972
- 'content' => false,
1973
- 'user_id' => bp_loggedin_user_id()
 
1974
  ) );
1975
 
1976
  if ( empty( $r['content'] ) || !strlen( trim( $r['content'] ) ) ) {
@@ -2010,8 +1980,14 @@ function bp_activity_post_update( $args = '' ) {
2010
  'primary_link' => $add_primary_link,
2011
  'component' => buddypress()->activity->id,
2012
  'type' => 'activity_update',
 
2013
  ) );
2014
 
 
 
 
 
 
2015
  /**
2016
  * Filters the latest update content for the activity item.
2017
  *
@@ -2304,10 +2280,9 @@ function bp_activity_post_type_unpublish( $post_id = 0, $post = null ) {
2304
  *
2305
  * @since 2.5.0
2306
  *
2307
- * @param int $comment_id ID of the comment.
2308
- * @param bool $is_approved Whether the comment is approved or not.
2309
- * @param object $activity_post_object the post type tracking args object.
2310
- *
2311
  * @return int|bool The ID of the activity on success. False on error.
2312
  */
2313
  function bp_activity_post_type_comment( $comment_id = 0, $is_approved = true, $activity_post_object = null ) {
@@ -2497,9 +2472,8 @@ add_action( 'edit_comment', 'bp_activity_post_type_comment', 10 );
2497
  *
2498
  * @since 2.5.0
2499
  *
2500
- * @param int $comment_id ID of the comment.
2501
- * @param object $activity_post_object The post type tracking args object.
2502
- *
2503
  * @return bool True on success. False on error.
2504
  */
2505
  function bp_activity_post_type_remove_comment( $comment_id = 0, $activity_post_object = null ) {
@@ -2564,15 +2538,10 @@ add_action( 'delete_comment', 'bp_activity_post_type_remove_comment', 10, 1 );
2564
  * @since 1.2.0
2565
  * @since 2.5.0 Add a new possible parameter $skip_notification for the array of arguments.
2566
  * Add the $primary_link parameter for the array of arguments.
2567
- *
2568
- * @uses wp_parse_args()
2569
- * @uses bp_activity_add()
2570
- * @uses apply_filters() To call the 'bp_activity_comment_action' hook.
2571
- * @uses apply_filters() To call the 'bp_activity_comment_content' hook.
2572
- * @uses wp_cache_delete()
2573
- * @uses do_action() To call the 'bp_activity_comment_posted' hook.
2574
  *
2575
  * @param array|string $args {
 
2576
  * @type int $id Optional. Pass an ID to update an existing comment.
2577
  * @type string $content The content of the comment.
2578
  * @type int $user_id Optional. The ID of the user making the comment.
@@ -2586,17 +2555,12 @@ add_action( 'delete_comment', 'bp_activity_post_type_remove_comment', 10, 1 );
2586
  * Defaults to an empty string.
2587
  * @type bool $skip_notification Optional. false to send a comment notification, false otherwise.
2588
  * Defaults to false.
 
2589
  * }
2590
  * @return int|bool The ID of the comment on success, otherwise false.
2591
  */
2592
  function bp_activity_new_comment( $args = '' ) {
2593
- $bp = buddypress();
2594
- $errors = new WP_Error();
2595
- $feedback = __( 'There was an error posting your reply. Please try again.', 'buddypress' );
2596
-
2597
- if ( empty( $bp->activity->errors ) ) {
2598
- $bp->activity->errors = array();
2599
- }
2600
 
2601
  $r = wp_parse_args( $args, array(
2602
  'id' => false,
@@ -2606,14 +2570,31 @@ function bp_activity_new_comment( $args = '' ) {
2606
  'parent_id' => false, // ID of a parent comment (optional).
2607
  'primary_link' => '',
2608
  'skip_notification' => false,
 
2609
  ) );
2610
 
 
 
 
 
 
 
 
 
 
 
2611
  // Bail if missing necessary data.
2612
  if ( empty( $r['content'] ) || empty( $r['user_id'] ) || empty( $r['activity_id'] ) ) {
2613
- $errors->add( 'missing_data', $feedback );
2614
- $bp->activity->errors['new_comment'] = $errors;
2615
 
2616
- return false;
 
 
 
 
 
 
 
2617
  }
2618
 
2619
  // Maybe set current activity ID as the parent.
@@ -2628,14 +2609,21 @@ function bp_activity_new_comment( $args = '' ) {
2628
 
2629
  // Bail if the parent activity does not exist.
2630
  if ( empty( $activity->date_recorded ) ) {
2631
- $errors->add( 'missing_activity', __( 'Sorry, the item you are replying to no longer exists.', 'buddypress' ) );
2632
- $bp->activity->errors['new_comment'] = $errors;
 
 
 
 
 
 
 
 
2633
 
2634
- return false;
2635
  }
2636
 
2637
  // Check to see if the parent activity is hidden, and if so, hide this comment publicly.
2638
- $is_hidden = ( (int) $activity->hide_sitewide ) ? 1 : 0;
2639
 
2640
  /**
2641
  * Filters the content of a new comment.
@@ -2656,9 +2644,15 @@ function bp_activity_new_comment( $args = '' ) {
2656
  'user_id' => $r['user_id'],
2657
  'item_id' => $activity_id,
2658
  'secondary_item_id' => $r['parent_id'],
2659
- 'hide_sitewide' => $is_hidden
 
2660
  ) );
2661
 
 
 
 
 
 
2662
  // Comment caches are stored only with the top-level item.
2663
  wp_cache_delete( $activity_id, 'bp_activity_comments' );
2664
 
@@ -2678,9 +2672,9 @@ function bp_activity_new_comment( $args = '' ) {
2678
  *
2679
  * @since 1.2.0
2680
  *
2681
- * @param int $comment_id ID of the newly posted activity comment.
2682
- * @param array $r Array of parsed comment arguments.
2683
- * @param int $activity ID of the activity item being commented on.
2684
  */
2685
  do_action( 'bp_activity_comment_posted', $comment_id, $r, $activity );
2686
  } else {
@@ -2690,16 +2684,23 @@ function bp_activity_new_comment( $args = '' ) {
2690
  *
2691
  * @since 2.5.0
2692
  *
2693
- * @param int $comment_id ID of the newly posted activity comment.
2694
- * @param array $r Array of parsed comment arguments.
2695
- * @param int $activity ID of the activity item being commented on.
2696
  */
2697
  do_action( 'bp_activity_comment_posted_notification_skipped', $comment_id, $r, $activity );
2698
  }
2699
 
2700
  if ( empty( $comment_id ) ) {
2701
- $errors->add( 'comment_failed', $feedback );
2702
- $bp->activity->errors['new_comment'] = $errors;
 
 
 
 
 
 
 
2703
  }
2704
 
2705
  return $comment_id;
@@ -2711,9 +2712,6 @@ function bp_activity_new_comment( $args = '' ) {
2711
  * @since 1.2.0
2712
  *
2713
  * @see BP_Activity_Activity::get() For more information on accepted arguments.
2714
- * @uses wp_parse_args()
2715
- * @uses apply_filters() To call the 'bp_activity_get_activity_id' hook.
2716
- * @uses BP_Activity_Activity::save() {@link BP_Activity_Activity}
2717
  *
2718
  * @param array|string $args See BP_Activity_Activity::get() for description.
2719
  * @return int $activity_id The ID of the activity item found.
@@ -2769,15 +2767,6 @@ function bp_activity_get_activity_id( $args = '' ) {
2769
  * @since 1.0.0
2770
  *
2771
  * @see BP_Activity_Activity::get() For more information on accepted arguments.
2772
- * @uses wp_parse_args()
2773
- * @uses bp_activity_adjust_mention_count()
2774
- * @uses BP_Activity_Activity::delete() {@link BP_Activity_Activity}
2775
- * @uses do_action() To call the 'bp_before_activity_delete' hook.
2776
- * @uses bp_get_user_meta()
2777
- * @uses bp_delete_user_meta()
2778
- * @uses do_action() To call the 'bp_activity_delete' hook.
2779
- * @uses do_action() To call the 'bp_activity_deleted_activities' hook.
2780
- * @uses wp_cache_delete()
2781
  *
2782
  * @param array|string $args To delete specific activity items, use
2783
  * $args = array( 'id' => $ids ); Otherwise, to use
@@ -2863,8 +2852,6 @@ function bp_activity_delete( $args = '' ) {
2863
  * @since 1.1.0
2864
  * @deprecated 1.2.0
2865
  *
2866
- * @uses wp_parse_args()
2867
- * @uses bp_activity_delete()
2868
  *
2869
  * @param array|string $args See BP_Activity_Activity::get for a
2870
  * description of accepted arguments.
@@ -2888,7 +2875,6 @@ function bp_activity_delete( $args = '' ) {
2888
  *
2889
  * @since 1.1.0
2890
  *
2891
- * @uses bp_activity_delete()
2892
  *
2893
  * @param int $activity_id ID of the activity item to be deleted.
2894
  * @return bool True on success, false on failure.
@@ -2905,7 +2891,6 @@ function bp_activity_delete( $args = '' ) {
2905
  * @since 1.1.0
2906
  * @deprecated 1.2.0
2907
  *
2908
- * @uses bp_activity_delete()
2909
  *
2910
  * @param int $user_id The user id.
2911
  * @param string $content The activity id.
@@ -2930,7 +2915,6 @@ function bp_activity_delete( $args = '' ) {
2930
  * @since 1.1.0
2931
  * @deprecated 1.2.0
2932
  *
2933
- * @uses bp_activity_delete()
2934
  *
2935
  * @param int $user_id The user id.
2936
  * @param string $component The activity component.
@@ -2948,11 +2932,6 @@ function bp_activity_delete( $args = '' ) {
2948
  *
2949
  * @since 1.2.0
2950
  *
2951
- * @uses apply_filters() To call the 'bp_activity_delete_comment_pre' hook.
2952
- * @uses bp_activity_delete_children()
2953
- * @uses bp_activity_delete()
2954
- * @uses BP_Activity_Activity::rebuild_activity_comment_tree() {@link BP_Activity_Activity}
2955
- * @uses do_action() To call the 'bp_activity_delete_comment' hook.
2956
  * @todo Why is an activity id required? We could look this up.
2957
  * @todo Why do we encourage users to call this function directly? We could just
2958
  * as easily examine the activity type in bp_activity_delete() and then
@@ -3018,9 +2997,6 @@ function bp_activity_delete_comment( $activity_id, $comment_id ) {
3018
  *
3019
  * @since 1.2.0
3020
  *
3021
- * @uses BP_Activity_Activity::get_child_comments() {@link BP_Activity_Activity}
3022
- * @uses bp_activity_delete_children()
3023
- * @uses bp_activity_delete()
3024
  *
3025
  * @param int $activity_id The ID of the "root" activity, ie the
3026
  * comment's oldest ancestor.
@@ -3056,10 +3032,6 @@ function bp_activity_delete_comment( $activity_id, $comment_id ) {
3056
  *
3057
  * @since 1.2.0
3058
  *
3059
- * @uses bp_get_root_domain()
3060
- * @uses bp_get_activity_root_slug()
3061
- * @uses apply_filters_ref_array() To call the 'bp_activity_get_permalink' hook.
3062
- *
3063
  * @param int $activity_id The unique id of the activity object.
3064
  * @param object|bool $activity_obj Optional. The activity object.
3065
  * @return string $link Permalink for the activity item.
@@ -3090,7 +3062,7 @@ function bp_activity_get_permalink( $activity_id, $activity_obj = false ) {
3090
  $link = $activity_obj->primary_link;
3091
  } else {
3092
  if ( 'activity_comment' == $activity_obj->type ) {
3093
- $link = bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $activity_obj->item_id . '/';
3094
  } else {
3095
  $link = bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $activity_obj->id . '/';
3096
  }
@@ -3111,8 +3083,6 @@ function bp_activity_get_permalink( $activity_id, $activity_obj = false ) {
3111
  *
3112
  * @since 1.2.0
3113
  *
3114
- * @uses BP_Activity_Activity::hide_all_for_user() {@link BP_Activity_Activity}
3115
- *
3116
  * @param int $user_id The ID of the user whose activity is being hidden.
3117
  * @return bool True on success, false on failure.
3118
  */
@@ -3134,9 +3104,6 @@ function bp_activity_hide_user_activity( $user_id ) {
3134
  *
3135
  * @since 1.2.0
3136
  *
3137
- * @uses esc_attr()
3138
- * @uses apply_filters() To call the 'bp_activity_thumbnail_content_images' hook.
3139
- *
3140
  * @param string $content The content of the activity item.
3141
  * @param string|bool $link Optional. The unescaped URL that the image should link
3142
  * to. If absent, the image will not be a link.
@@ -3202,6 +3169,24 @@ function bp_activity_thumbnail_content_images( $content, $link = false, $args =
3202
  return apply_filters( 'bp_activity_thumbnail_content_images', $content, $matches, $args );
3203
  }
3204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3205
  /**
3206
  * Create a rich summary of an activity item for the activity stream.
3207
  *
@@ -3339,8 +3324,12 @@ function bp_activity_create_summary( $content, $activity ) {
3339
  }
3340
 
3341
  // Generate a text excerpt for this activity item (and remove any oEmbeds URLs).
3342
- $summary = strip_shortcodes( html_entity_decode( strip_tags( $content ) ) );
3343
- $summary = bp_create_excerpt( preg_replace( '#^\s*(https?://[^\s"]+)\s*$#im', '', $summary ) );
 
 
 
 
3344
 
3345
  if ( $use_media_type === 'embeds' ) {
3346
  $summary .= PHP_EOL . PHP_EOL . $extracted_media['url'];
@@ -3387,6 +3376,8 @@ function bp_activity_user_can_mark_spam() {
3387
  *
3388
  * @since 1.6.0
3389
  *
 
 
3390
  * @param BP_Activity_Activity $activity The activity item to be spammed.
3391
  * @param string $source Optional. Default is "by_a_person" (ie, a person has
3392
  * manually marked the activity as spam). BP core also
@@ -3405,7 +3396,7 @@ function bp_activity_mark_as_spam( &$activity, $source = 'by_a_person' ) {
3405
 
3406
  // If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity.
3407
  if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
3408
- remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4, 1 );
3409
 
3410
  // Build data package for Akismet.
3411
  $activity_data = BP_Akismet::build_akismet_data_package( $activity );
@@ -3452,7 +3443,7 @@ function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
3452
 
3453
  // If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity.
3454
  if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
3455
- remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4, 1 );
3456
 
3457
  // Build data package for Akismet.
3458
  $activity_data = BP_Akismet::build_akismet_data_package( $activity );
@@ -3476,6 +3467,211 @@ function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
3476
  do_action( 'bp_activity_mark_as_ham', $activity, $source );
3477
  }
3478
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3479
 
3480
  /** Embeds *******************************************************************/
3481
 
@@ -3495,17 +3691,31 @@ function bp_activity_mark_as_ham( &$activity, $source = 'by_a_person' ) {
3495
  * @see bp_embed_activity_cache()
3496
  * @see bp_embed_activity_save_cache()
3497
  *
3498
- * @uses add_filter() To attach 'bp_get_activity_id' to 'embed_post_id'.
3499
- * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'.
3500
- * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'.
3501
  */
3502
  function bp_activity_embed() {
3503
  add_filter( 'embed_post_id', 'bp_get_activity_id' );
 
3504
  add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
3505
  add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
3506
  }
3507
  add_action( 'activity_loop_start', 'bp_activity_embed' );
3508
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3509
  /**
3510
  * Set up activity oEmbed cache while recursing through activity comments.
3511
  *
@@ -3520,9 +3730,6 @@ add_action( 'activity_loop_start', 'bp_activity_embed' );
3520
  * @see bp_embed_activity_cache()
3521
  * @see bp_embed_activity_save_cache()
3522
  *
3523
- * @uses add_filter() To attach 'bp_get_activity_comment_id' to 'embed_post_id'.
3524
- * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'.
3525
- * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'.
3526
  */
3527
  function bp_activity_comment_embed() {
3528
  add_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
@@ -3537,16 +3744,13 @@ add_action( 'bp_before_activity_comment', 'bp_activity_comment_embed' );
3537
  * @since 1.5.0
3538
  *
3539
  * @see BP_Embed
3540
- * @uses add_filter() To attach create_function() to 'embed_post_id'.
3541
- * @uses add_filter() To attach 'bp_embed_activity_cache' to 'bp_embed_get_cache'.
3542
- * @uses add_action() To attach 'bp_embed_activity_save_cache' to 'bp_embed_update_cache'.
3543
  *
3544
  * @param object $activity The activity that is being expanded.
3545
  */
3546
  function bp_dtheme_embed_read_more( $activity ) {
3547
  buddypress()->activity->read_more_id = $activity->id;
3548
 
3549
- add_filter( 'embed_post_id', create_function( '', 'return buddypress()->activity->read_more_id;' ) );
3550
  add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
3551
  add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
3552
  }
@@ -3562,7 +3766,6 @@ add_action( 'bp_legacy_theme_get_single_activity_content', 'bp_dtheme_embed_read
3562
  * @since 1.5.0
3563
  *
3564
  * @see bp_activity_comment_embed()
3565
- * @uses remove_filter() To remove 'bp_get_activity_comment_id' from 'embed_post_id'.
3566
  */
3567
  function bp_activity_comment_embed_after_recurse() {
3568
  remove_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
@@ -3577,7 +3780,6 @@ add_action( 'bp_after_activity_comment', 'bp_activity_comment_embed_after_recurs
3577
  * @since 1.5.0
3578
  *
3579
  * @see BP_Embed::parse_oembed()
3580
- * @uses bp_activity_get_meta()
3581
  *
3582
  * @param string $cache An empty string passed by BP_Embed::parse_oembed() for
3583
  * functions like this one to filter.
@@ -3597,7 +3799,6 @@ function bp_embed_activity_cache( $cache, $id, $cachekey ) {
3597
  * @since 1.5.0
3598
  *
3599
  * @see BP_Embed::parse_oembed()
3600
- * @uses bp_activity_update_meta()
3601
  *
3602
  * @param string $cache An empty string passed by BP_Embed::parse_oembed() for
3603
  * functions like this one to filter.
@@ -3606,6 +3807,12 @@ function bp_embed_activity_cache( $cache, $id, $cachekey ) {
3606
  */
3607
  function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
3608
  bp_activity_update_meta( $id, $cachekey, $cache );
 
 
 
 
 
 
3609
  }
3610
 
3611
  /**
@@ -3613,24 +3820,21 @@ function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
3613
  *
3614
  * @since 2.0.0
3615
  *
3616
- * @uses bp_is_activity_heartbeat_active() to check if heartbeat setting is on.
3617
- * @uses bp_is_activity_directory() to check if the current page is the activity
3618
- * directory.
3619
- * @uses bp_is_group_activity() to check if on a single group, the current page
3620
- * is the group activities.
3621
- *
3622
  * @return bool True if activity heartbeat is enabled, otherwise false.
3623
  */
3624
  function bp_activity_do_heartbeat() {
3625
  $retval = false;
3626
 
3627
- if ( ! bp_is_activity_heartbeat_active() ) {
3628
- return $retval;
3629
- }
3630
-
3631
- if ( bp_is_activity_directory() || bp_is_group_activity() ) {
3632
  $retval = true;
3633
  }
3634
 
3635
- return $retval;
 
 
 
 
 
 
 
3636
  }
40
  *
41
  * @since 1.8.0
42
  *
 
 
43
  * @return bool $retval True to enable mentions, false to disable.
44
  */
45
  function bp_activity_do_mentions() {
131
  *
132
  * @since 1.5.0
133
  *
 
 
134
  * @param int $user_id The id of the user whose unread mentions are being reset.
135
  */
136
  function bp_activity_clear_new_mentions( $user_id ) {
157
  *
158
  * @since 1.5.0
159
  *
 
 
 
160
  * @param int $activity_id The unique id for the activity item.
161
  * @param string $action Can be 'delete' or 'add'. Defaults to 'add'.
162
  * @return bool
169
  }
170
 
171
  // Get activity object.
172
+ $activity = new BP_Activity_Activity( $activity_id );
173
 
174
  // Try to find mentions.
175
  $usernames = bp_activity_find_mentions( strip_tags( $activity->content ) );
193
  *
194
  * @since 1.7.0
195
  *
 
 
 
196
  * @param int $user_id The user ID.
197
  * @param int $activity_id The unique ID for the activity item.
198
  * @param string $action 'delete' or 'add'. Default: 'add'.
406
  * @param array $args {
407
  * An associative array of tracking parameters. All items are optional.
408
  * @type string $bp_activity_admin_filter String to use in the Dashboard > Activity dropdown.
409
+ * @type string $bp_activity_front_filter String to use in the front-end dropdown.
410
  * @type string $bp_activity_new_post String format to use for generating the activity action. Should be a
411
  * translatable string where %1$s is replaced by a user link and %2$s is
412
  * the URL of the newly created post.
777
  *
778
  * @since 1.1.0
779
  *
 
 
780
  * @param string $component_id The unique string ID of the component.
781
  * @param string $key The action key.
782
  * @return string|bool Action value if found, otherwise false.
839
  return apply_filters( 'bp_activity_get_types', $actions );
840
  }
841
 
842
+ /**
843
+ * Gets the current activity context.
844
+ *
845
+ * The "context" is the current view type, corresponding roughly to the
846
+ * current component. Use this context to determine which activity actions
847
+ * should be whitelisted for the filter dropdown.
848
+ *
849
+ * @since 2.8.0
850
+ *
851
+ * @return string Activity context. 'member', 'member_groups', 'group', 'activity'.
852
+ */
853
+ function bp_activity_get_current_context() {
854
+ // On member pages, default to 'member', unless this is a user's Groups activity.
855
+ if ( bp_is_user() ) {
856
+ if ( bp_is_active( 'groups' ) && bp_is_current_action( bp_get_groups_slug() ) ) {
857
+ $context = 'member_groups';
858
+ } else {
859
+ $context = 'member';
860
+ }
861
+
862
+ // On individual group pages, default to 'group'.
863
+ } elseif ( bp_is_active( 'groups' ) && bp_is_group() ) {
864
+ $context = 'group';
865
+
866
+ // 'activity' everywhere else.
867
+ } else {
868
+ $context = 'activity';
869
+ }
870
+
871
+ return $context;
872
+ }
873
+
874
+ /**
875
+ * Gets a flat list of activity actions compatible with a given context.
876
+ *
877
+ * @since 2.8.0
878
+ *
879
+ * @param string $context Optional. Name of the context. Defaults to the current context.
880
+ * @return array
881
+ */
882
+ function bp_activity_get_actions_for_context( $context = '' ) {
883
+ if ( ! $context ) {
884
+ $context = bp_activity_get_current_context();
885
+ }
886
+
887
+ $actions = array();
888
+ foreach ( bp_activity_get_actions() as $component_actions ) {
889
+ foreach ( $component_actions as $component_action ) {
890
+ if ( in_array( $context, (array) $component_action['context'], true ) ) {
891
+ $actions[] = $component_action;
892
+ }
893
+ }
894
+ }
895
+
896
+ return $actions;
897
+ }
898
+
899
  /** Favorites ****************************************************************/
900
 
901
  /**
903
  *
904
  * @since 1.2.0
905
  *
 
 
 
906
  * @param int $user_id ID of the user whose favorites are being queried.
907
  * @return array IDs of the user's favorite activity items.
908
  */
931
  *
932
  * @since 1.2.0
933
  *
 
 
 
 
 
 
 
 
934
  * @param int $activity_id ID of the activity item being favorited.
935
  * @param int $user_id ID of the user favoriting the activity item.
936
  * @return bool True on success, false on failure.
1005
  *
1006
  * @since 1.2.0
1007
  *
 
 
 
 
 
 
 
1008
  * @param int $activity_id ID of the activity item being unfavorited.
1009
  * @param int $user_id ID of the user unfavoriting the activity item.
1010
  * @return bool True on success, false on failure.
1077
  *
1078
  * @since 1.1.0
1079
  *
 
 
 
1080
  * @param string $content The content to filter by.
1081
  * @return int|null The ID of the located activity item. Null if none is found.
1082
  */
1087
  *
1088
  * @since 1.1.0
1089
  *
1090
+ * @param BP_Activity_Activity $value ID of the activity if found, else null.
1091
  */
1092
  return apply_filters( 'bp_activity_check_exists_by_content', BP_Activity_Activity::check_exists_by_content( $content ) );
1093
  }
1097
  *
1098
  * @since 1.0.0
1099
  *
 
 
 
1100
  * @return string Date last updated.
1101
  */
1102
  function bp_activity_get_last_updated() {
1116
  *
1117
  * @since 1.2.0
1118
  *
 
 
1119
  * @param int $user_id ID of the user whose favorite count is being requested.
1120
  * @return int Total favorite count for the user.
1121
  */
1179
  *
1180
  * @since 1.2.0
1181
  *
 
 
1182
  * @param int $activity_id ID of the activity item whose metadata is being requested.
1183
  * @param string $meta_key Optional. If present, only the metadata matching
1184
  * that meta key will be returned. Otherwise, all metadata for the
1256
  *
1257
  * @since 1.5.0
1258
  *
 
 
 
 
 
 
1259
  * @param int $user_id ID of the user whose activity is being deleted.
1260
  * @return bool
1261
  */
1502
  $action = apply_filters( 'bp_activity_generate_action_string', $activity->action, $activity );
1503
 
1504
  // Remove the filter for future activity items.
1505
+ remove_filter( 'bp_activity_generate_action_string', $actions->{$activity->component}->{$activity->type}['format_callback'], 10 );
1506
 
1507
  return $action;
1508
  }
1682
  *
1683
  * @see BP_Activity_Activity::get() For more information on accepted arguments
1684
  * and the format of the returned value.
 
 
 
 
 
1685
  *
1686
  * @param array|string $args See BP_Activity_Activity::get() for description.
1687
  * @return array $activity See BP_Activity_Activity::get() for description.
1720
  * );
1721
  */
1722
  'filter' => array()
1723
+ ), 'activity_get' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1724
 
1725
+ $activity = BP_Activity_Activity::get( array(
1726
+ 'page' => $r['page'],
1727
+ 'per_page' => $r['per_page'],
1728
+ 'max' => $r['max'],
1729
+ 'sort' => $r['sort'],
1730
+ 'search_terms' => $r['search_terms'],
1731
+ 'meta_query' => $r['meta_query'],
1732
+ 'date_query' => $r['date_query'],
1733
+ 'filter_query' => $r['filter_query'],
1734
+ 'filter' => $r['filter'],
1735
+ 'scope' => $r['scope'],
1736
+ 'display_comments' => $r['display_comments'],
1737
+ 'show_hidden' => $r['show_hidden'],
1738
+ 'exclude' => $r['exclude'],
1739
+ 'in' => $r['in'],
1740
+ 'spam' => $r['spam'],
1741
+ 'update_meta_cache' => $r['update_meta_cache'],
1742
+ 'count_total' => $r['count_total'],
1743
+ 'fields' => $r['fields'],
1744
+ ) );
1745
 
1746
  /**
1747
  * Filters the requested activity item(s).
1760
  * @since 1.2.0
1761
  *
1762
  * @see BP_Activity_Activity::get() For more information on accepted arguments.
 
 
 
1763
  *
1764
  * @param array|string $args {
1765
  * All arguments and defaults are shared with BP_Activity_Activity::get(),
1811
  * Add an activity item.
1812
  *
1813
  * @since 1.1.0
1814
+ * @since 2.6.0 Added 'error_type' parameter to $args.
 
 
 
 
 
1815
  *
1816
  * @param array|string $args {
1817
  * An array of arguments.
1843
  * @type bool $hide_sitewide Should the item be hidden on sitewide streams?
1844
  * Default: false.
1845
  * @type bool $is_spam Should the item be marked as spam? Default: false.
1846
+ * @type string $error_type Optional. Error type. Either 'bool' or 'wp_error'. Default: 'bool'.
1847
  * }
1848
  * @return int|bool The ID of the activity on success. False on error.
1849
  */
1862
  'recorded_time' => bp_core_current_time(), // The GMT time that this activity was recorded.
1863
  'hide_sitewide' => false, // Should this be hidden on the sitewide activity stream?
1864
  'is_spam' => false, // Is this activity item to be marked as spam?
1865
+ 'error_type' => 'bool'
1866
  ), 'activity_add' );
1867
 
1868
  // Make sure we are backwards compatible.
1886
  $activity->date_recorded = $r['recorded_time'];
1887
  $activity->hide_sitewide = $r['hide_sitewide'];
1888
  $activity->is_spam = $r['is_spam'];
1889
+ $activity->error_type = $r['error_type'];
1890
  $activity->action = ! empty( $r['action'] )
1891
+ ? $r['action']
1892
+ : bp_activity_generate_action_string( $activity );
1893
 
1894
+ $save = $activity->save();
1895
+
1896
+ if ( 'wp_error' === $r['error_type'] && is_wp_error( $save ) ) {
1897
+ return $save;
1898
+ } elseif ('bool' === $r['error_type'] && false === $save ) {
1899
  return false;
1900
  }
1901
 
1926
  *
1927
  * @since 1.2.0
1928
  *
 
 
 
 
 
 
 
 
 
 
 
1929
  * @param array|string $args {
1930
+ * @type string $content The content of the activity update.
1931
+ * @type int $user_id Optional. Defaults to the logged-in user.
1932
+ * @type string $error_type Optional. Error type to return. Either 'bool' or 'wp_error'. Defaults to
1933
+ * 'bool' for boolean. 'wp_error' will return a WP_Error object.
1934
  * }
1935
+ * @return int|bool|WP_Error $activity_id The activity id on success. On failure, either boolean false or WP_Error
1936
+ * object depending on the 'error_type' $args parameter.
1937
  */
1938
  function bp_activity_post_update( $args = '' ) {
1939
 
1940
  $r = wp_parse_args( $args, array(
1941
+ 'content' => false,
1942
+ 'user_id' => bp_loggedin_user_id(),
1943
+ 'error_type' => 'bool',
1944
  ) );
1945
 
1946
  if ( empty( $r['content'] ) || !strlen( trim( $r['content'] ) ) ) {
1980
  'primary_link' => $add_primary_link,
1981
  'component' => buddypress()->activity->id,
1982
  'type' => 'activity_update',
1983
+ 'error_type' => $r['error_type']
1984
  ) );
1985
 
1986
+ // Bail on failure.
1987
+ if ( false === $activity_id || is_wp_error( $activity_id ) ) {
1988
+ return $activity_id;
1989
+ }
1990
+
1991
  /**
1992
  * Filters the latest update content for the activity item.
1993
  *
2280
  *
2281
  * @since 2.5.0
2282
  *
2283
+ * @param int $comment_id ID of the comment.
2284
+ * @param bool $is_approved Whether the comment is approved or not.
2285
+ * @param object|null $activity_post_object The post type tracking args object.
 
2286
  * @return int|bool The ID of the activity on success. False on error.
2287
  */
2288
  function bp_activity_post_type_comment( $comment_id = 0, $is_approved = true, $activity_post_object = null ) {
2472
  *
2473
  * @since 2.5.0
2474
  *
2475
+ * @param int $comment_id ID of the comment.
2476
+ * @param object|null $activity_post_object The post type tracking args object.
 
2477
  * @return bool True on success. False on error.
2478
  */
2479
  function bp_activity_post_type_remove_comment( $comment_id = 0, $activity_post_object = null ) {
2538
  * @since 1.2.0
2539
  * @since 2.5.0 Add a new possible parameter $skip_notification for the array of arguments.
2540
  * Add the $primary_link parameter for the array of arguments.
2541
+ * @since 2.6.0 Added 'error_type' parameter to $args.
 
 
 
 
 
 
2542
  *
2543
  * @param array|string $args {
2544
+ * An array of arguments.
2545
  * @type int $id Optional. Pass an ID to update an existing comment.
2546
  * @type string $content The content of the comment.
2547
  * @type int $user_id Optional. The ID of the user making the comment.
2555
  * Defaults to an empty string.
2556
  * @type bool $skip_notification Optional. false to send a comment notification, false otherwise.
2557
  * Defaults to false.
2558
+ * @type string $error_type Optional. Error type. Either 'bool' or 'wp_error'. Default: 'bool'.
2559
  * }
2560
  * @return int|bool The ID of the comment on success, otherwise false.
2561
  */
2562
  function bp_activity_new_comment( $args = '' ) {
2563
+ $bp = buddypress();
 
 
 
 
 
 
2564
 
2565
  $r = wp_parse_args( $args, array(
2566
  'id' => false,
2570
  'parent_id' => false, // ID of a parent comment (optional).
2571
  'primary_link' => '',
2572
  'skip_notification' => false,
2573
+ 'error_type' => 'bool'
2574
  ) );
2575
 
2576
+ // Error type is boolean; need to initialize some variables for backpat.
2577
+ if ( 'bool' === $r['error_type'] ) {
2578
+ if ( empty( $bp->activity->errors ) ) {
2579
+ $bp->activity->errors = array();
2580
+ }
2581
+ }
2582
+
2583
+ // Default error message.
2584
+ $feedback = __( 'There was an error posting your reply. Please try again.', 'buddypress' );
2585
+
2586
  // Bail if missing necessary data.
2587
  if ( empty( $r['content'] ) || empty( $r['user_id'] ) || empty( $r['activity_id'] ) ) {
2588
+ $error = new WP_Error( 'missing_data', $feedback );
 
2589
 
2590
+ if ( 'wp_error' === $r['error_type'] ) {
2591
+ return $error;
2592
+
2593
+ // Backpat.
2594
+ } else {
2595
+ $bp->activity->errors['new_comment'] = $error;
2596
+ return false;
2597
+ }
2598
  }
2599
 
2600
  // Maybe set current activity ID as the parent.
2609
 
2610
  // Bail if the parent activity does not exist.
2611
  if ( empty( $activity->date_recorded ) ) {
2612
+ $error = new WP_Error( 'missing_activity', __( 'The item you were replying to no longer exists.', 'buddypress' ) );
2613
+
2614
+ if ( 'wp_error' === $r['error_type'] ) {
2615
+ return $error;
2616
+
2617
+ // Backpat.
2618
+ } else {
2619
+ $bp->activity->errors['new_comment'] = $error;
2620
+ return false;
2621
+ }
2622
 
 
2623
  }
2624
 
2625
  // Check to see if the parent activity is hidden, and if so, hide this comment publicly.
2626
+ $is_hidden = $activity->hide_sitewide ? 1 : 0;
2627
 
2628
  /**
2629
  * Filters the content of a new comment.
2644
  'user_id' => $r['user_id'],
2645
  'item_id' => $activity_id,
2646
  'secondary_item_id' => $r['parent_id'],
2647
+ 'hide_sitewide' => $is_hidden,
2648
+ 'error_type' => $r['error_type']
2649
  ) );
2650
 
2651
+ // Bail on failure.
2652
+ if ( false === $comment_id || is_wp_error( $comment_id ) ) {
2653
+ return $comment_id;
2654
+ }
2655
+
2656
  // Comment caches are stored only with the top-level item.
2657
  wp_cache_delete( $activity_id, 'bp_activity_comments' );
2658
 
2672
  *
2673
  * @since 1.2.0
2674
  *
2675
+ * @param int $comment_id ID of the newly posted activity comment.
2676
+ * @param array $r Array of parsed comment arguments.
2677
+ * @param BP_Activity_Activity $activity Activity item being commented on.
2678
  */
2679
  do_action( 'bp_activity_comment_posted', $comment_id, $r, $activity );
2680
  } else {
2684
  *
2685
  * @since 2.5.0
2686
  *
2687
+ * @param int $comment_id ID of the newly posted activity comment.
2688
+ * @param array $r Array of parsed comment arguments.
2689
+ * @param BP_Activity_Activity $activity Activity item being commented on.
2690
  */
2691
  do_action( 'bp_activity_comment_posted_notification_skipped', $comment_id, $r, $activity );
2692
  }
2693
 
2694
  if ( empty( $comment_id ) ) {
2695
+ $error = new WP_Error( 'comment_failed', $feedback );
2696
+
2697
+ if ( 'wp_error' === $r['error_type'] ) {
2698
+ return $error;
2699
+
2700
+ // Backpat.
2701
+ } else {
2702
+ $bp->activity->errors['new_comment'] = $error;
2703
+ }
2704
  }
2705
 
2706
  return $comment_id;
2712
  * @since 1.2.0
2713
  *
2714
  * @see BP_Activity_Activity::get() For more information on accepted arguments.
 
 
 
2715
  *
2716
  * @param array|string $args See BP_Activity_Activity::get() for description.
2717
  * @return int $activity_id The ID of the activity item found.
2767
  * @since 1.0.0
2768
  *
2769
  * @see BP_Activity_Activity::get() For more information on accepted arguments.
 
 
 
 
 
 
 
 
 
2770
  *
2771
  * @param array|string $args To delete specific activity items, use
2772
  * $args = array( 'id' => $ids ); Otherwise, to use
2852
  * @since 1.1.0
2853
  * @deprecated 1.2.0
2854
  *
 
 
2855
  *
2856
  * @param array|string $args See BP_Activity_Activity::get for a
2857
  * description of accepted arguments.
2875
  *
2876
  * @since 1.1.0
2877
  *
 
2878
  *
2879
  * @param int $activity_id ID of the activity item to be deleted.
2880
  * @return bool True on success, false on failure.
2891
  * @since 1.1.0
2892
  * @deprecated 1.2.0
2893
  *
 
2894
  *
2895
  * @param int $user_id The user id.
2896
  * @param string $content The activity id.
2915
  * @since 1.1.0
2916
  * @deprecated 1.2.0
2917
  *
 
2918
  *
2919
  * @param int $user_id The user id.
2920
  * @param string $component The activity component.
2932
  *
2933
  * @since 1.2.0
2934
  *
 
 
 
 
 
2935
  * @todo Why is an activity id required? We could look this up.
2936
  * @todo Why do we encourage users to call this function directly? We could just
2937
  * as easily examine the activity type in bp_activity_delete() and then
2997
  *
2998
  * @since 1.2.0
2999
  *
 
 
 
3000
  *
3001
  * @param int $activity_id The ID of the "root" activity, ie the
3002
  * comment's oldest ancestor.
3032
  *
3033
  * @since 1.2.0
3034
  *
 
 
 
 
3035
  * @param int $activity_id The unique id of the activity object.
3036
  * @param object|bool $activity_obj Optional. The activity object.
3037
  * @return string $link Permalink for the activity item.
3062
  $link = $activity_obj->primary_link;
3063
  } else {
3064
  if ( 'activity_comment' == $activity_obj->type ) {
3065
+ $link = bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $activity_obj->item_id . '/#acomment-' . $activity_obj->id;
3066
  } else {
3067
  $link = bp_get_root_domain() . '/' . bp_get_activity_root_slug() . '/p/' . $activity_obj->id . '/';
3068
  }
3083
  *
3084
  * @since 1.2.0
3085
  *
 
 
3086
  * @param int $user_id The ID of the user whose activity is being hidden.
3087
  * @return bool True on success, false on failure.
3088
  */
3104
  *
3105
  * @since 1.2.0
3106
  *
 
 
 
3107
  * @param string $content The content of the activity item.
3108
  * @param string|bool $link Optional. The unescaped URL that the image should link
3109
  * to. If absent, the image will not be a link.
3169
  return apply_filters( 'bp_activity_thumbnail_content_images', $content, $matches, $args );
3170
  }
3171
 
3172
+ /**
3173
+ * Gets the excerpt length for activity items.
3174
+ *
3175
+ * @since 2.8.0
3176
+ *
3177
+ * @return int Character length for activity excerpts.
3178
+ */
3179
+ function bp_activity_get_excerpt_length() {
3180
+ /**
3181
+ * Filters the excerpt length for the activity excerpt.
3182
+ *
3183
+ * @since 1.5.0
3184
+ *
3185
+ * @param int Character length for activity excerpts.
3186
+ */
3187
+ return (int) apply_filters( 'bp_activity_excerpt_length', 358 );
3188
+ }
3189
+
3190
  /**
3191
  * Create a rich summary of an activity item for the activity stream.
3192
  *
3324
  }
3325
 
3326
  // Generate a text excerpt for this activity item (and remove any oEmbeds URLs).
3327
+ $summary = bp_create_excerpt( html_entity_decode( $content ), 225, array(
3328
+ 'html' => false,
3329
+ 'filter_shortcodes' => true,
3330
+ 'strip_tags' => true,
3331
+ 'remove_links' => true
3332
+ ) );
3333
 
3334
  if ( $use_media_type === 'embeds' ) {
3335
  $summary .= PHP_EOL . PHP_EOL . $extracted_media['url'];
3376
  *
3377
  * @since 1.6.0
3378
  *
3379
+ * @todo We should probably save $source to activity meta.
3380
+ *
3381
  * @param BP_Activity_Activity $activity The activity item to be spammed.
3382
  * @param string $source Optional. Default is "by_a_person" (ie, a person has
3383
  * manually marked the activity as spam). BP core also
3396
 
3397
  // If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity.
3398
  if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
3399
+ remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4 );
3400
 
3401
  // Build data package for Akismet.
3402
  $activity_data = BP_Akismet::build_akismet_data_package( $activity );
3443
 
3444
  // If Akismet is active, and this was a manual spam/ham request, stop Akismet checking the activity.
3445
  if ( 'by_a_person' == $source && !empty( $bp->activity->akismet ) ) {
3446
+ remove_action( 'bp_activity_before_save', array( $bp->activity->akismet, 'check_activity' ), 4 );
3447
 
3448
  // Build data package for Akismet.
3449
  $activity_data = BP_Akismet::build_akismet_data_package( $activity );
3467
  do_action( 'bp_activity_mark_as_ham', $activity, $source );
3468
  }
3469
 
3470
+ /* Emails *********************************************************************/
3471
+
3472
+ /**
3473
+ * Send email and BP notifications when a user is mentioned in an update.
3474
+ *
3475
+ * @since 1.2.0
3476
+ *
3477
+ * @param int $activity_id The ID of the activity update.
3478
+ * @param int $receiver_user_id The ID of the user who is receiving the update.
3479
+ */
3480
+ function bp_activity_at_message_notification( $activity_id, $receiver_user_id ) {
3481
+ $notifications = BP_Core_Notification::get_all_for_user( $receiver_user_id, 'all' );
3482
+
3483
+ // Don't leave multiple notifications for the same activity item.
3484
+ foreach( $notifications as $notification ) {
3485
+ if ( $activity_id == $notification->item_id ) {
3486
+ return;
3487
+ }
3488
+ }
3489
+
3490
+ $activity = new BP_Activity_Activity( $activity_id );
3491
+ $email_type = 'activity-at-message';
3492
+ $group_name = '';
3493
+ $message_link = bp_activity_get_permalink( $activity_id );
3494
+ $poster_name = bp_core_get_user_displayname( $activity->user_id );
3495
+
3496
+ remove_filter( 'bp_get_activity_content_body', 'convert_smilies' );
3497
+ remove_filter( 'bp_get_activity_content_body', 'wpautop' );
3498
+ remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
3499
+
3500
+ /** This filter is documented in bp-activity/bp-activity-template.php */
3501
+ $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $activity->content, &$activity ) );
3502
+
3503
+ add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
3504
+ add_filter( 'bp_get_activity_content_body', 'wpautop' );
3505
+ add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
3506
+
3507
+ // Now email the user with the contents of the message (if they have enabled email notifications).
3508
+ if ( 'no' != bp_get_user_meta( $receiver_user_id, 'notification_activity_new_mention', true ) ) {
3509
+ if ( bp_is_active( 'groups' ) && bp_is_group() ) {
3510
+ $email_type = 'groups-at-message';
3511
+ $group_name = bp_get_current_group_name();
3512
+ }
3513
+
3514
+ $unsubscribe_args = array(
3515
+ 'user_id' => $receiver_user_id,
3516
+ 'notification_type' => $email_type,
3517
+ );
3518
+
3519
+ $args = array(
3520
+ 'tokens' => array(
3521
+ 'activity' => $activity,
3522
+ 'usermessage' => wp_strip_all_tags( $content ),
3523
+ 'group.name' => $group_name,
3524
+ 'mentioned.url' => $message_link,
3525
+ 'poster.name' => $poster_name,
3526
+ 'receiver-user.id' => $receiver_user_id,
3527
+ 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
3528
+ ),
3529
+ );
3530
+
3531
+ bp_send_email( $email_type, $receiver_user_id, $args );
3532
+ }
3533
+
3534
+ /**
3535
+ * Fires after the sending of an @mention email notification.
3536
+ *
3537
+ * @since 1.5.0
3538
+ * @since 2.5.0 $subject, $message, $content arguments unset and deprecated.
3539
+ *
3540
+ * @param BP_Activity_Activity $activity Activity Item object.
3541
+ * @param string $deprecated Removed in 2.5; now an empty string.
3542
+ * @param string $deprecated Removed in 2.5; now an empty string.
3543
+ * @param string $deprecated Removed in 2.5; now an empty string.
3544
+ * @param int $receiver_user_id The ID of the user who is receiving the update.
3545
+ */
3546
+ do_action( 'bp_activity_sent_mention_email', $activity, '', '', '', $receiver_user_id );
3547
+ }
3548
+
3549
+ /**
3550
+ * Send email and BP notifications when an activity item receives a comment.
3551
+ *
3552
+ * @since 1.2.0
3553
+ * @since 2.5.0 Updated to use new email APIs.
3554
+ *
3555
+ * @param int $comment_id The comment id.
3556
+ * @param int $commenter_id The ID of the user who posted the comment.
3557
+ * @param array $params {@link bp_activity_new_comment()}.
3558
+ */
3559
+ function bp_activity_new_comment_notification( $comment_id = 0, $commenter_id = 0, $params = array() ) {
3560
+ $original_activity = new BP_Activity_Activity( $params['activity_id'] );
3561
+ $poster_name = bp_core_get_user_displayname( $commenter_id );
3562
+ $thread_link = bp_activity_get_permalink( $params['activity_id'] );
3563
+
3564
+ remove_filter( 'bp_get_activity_content_body', 'convert_smilies' );
3565
+ remove_filter( 'bp_get_activity_content_body', 'wpautop' );
3566
+ remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
3567
+
3568
+ /** This filter is documented in bp-activity/bp-activity-template.php */
3569
+ $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $params['content'], &$original_activity ) );
3570
+
3571
+ add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
3572
+ add_filter( 'bp_get_activity_content_body', 'wpautop' );
3573
+ add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
3574
+
3575
+ if ( $original_activity->user_id != $commenter_id ) {
3576
+
3577
+ // Send an email if the user hasn't opted-out.
3578
+ if ( 'no' != bp_get_user_meta( $original_activity->user_id, 'notification_activity_new_reply', true ) ) {
3579
+
3580
+ $unsubscribe_args = array(
3581
+ 'user_id' => $original_activity->user_id,
3582
+ 'notification_type' => 'activity-comment',
3583
+ );
3584
+
3585
+ $args = array(
3586
+ 'tokens' => array(
3587
+ 'comment.id' => $comment_id,
3588
+ 'commenter.id' => $commenter_id,
3589
+ 'usermessage' => wp_strip_all_tags( $content ),
3590
+ 'original_activity.user_id' => $original_activity->user_id,
3591
+ 'poster.name' => $poster_name,
3592
+ 'thread.url' => esc_url( $thread_link ),
3593
+ 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
3594
+ ),
3595
+ );
3596
+
3597
+ bp_send_email( 'activity-comment', $original_activity->user_id, $args );
3598
+ }
3599
+
3600
+ /**
3601
+ * Fires at the point that notifications should be sent for activity comments.
3602
+ *
3603
+ * @since 2.6.0
3604
+ *
3605
+ * @param BP_Activity_Activity $original_activity The original activity.
3606
+ * @param int $comment_id ID for the newly received comment.
3607
+ * @param int $commenter_id ID of the user who made the comment.
3608
+ * @param array $params Arguments used with the original activity comment.
3609
+ */
3610
+ do_action( 'bp_activity_sent_reply_to_update_notification', $original_activity, $comment_id, $commenter_id, $params );
3611
+ }
3612
+
3613
+
3614
+ /*
3615
+ * If this is a reply to another comment, send an email notification to the
3616
+ * author of the immediate parent comment.
3617
+ */
3618
+ if ( empty( $params['parent_id'] ) || ( $params['activity_id'] == $params['parent_id'] ) ) {
3619
+ return;
3620
+ }
3621
+
3622
+ $parent_comment = new BP_Activity_Activity( $params['parent_id'] );
3623
+
3624
+ if ( $parent_comment->user_id != $commenter_id && $original_activity->user_id != $parent_comment->user_id ) {
3625
+
3626
+ // Send an email if the user hasn't opted-out.
3627
+ if ( 'no' != bp_get_user_meta( $parent_comment->user_id, 'notification_activity_new_reply', true ) ) {
3628
+
3629
+ $unsubscribe_args = array(
3630
+ 'user_id' => $parent_comment->user_id,
3631
+ 'notification_type' => 'activity-comment-author',
3632
+ );
3633
+
3634
+ $args = array(
3635
+ 'tokens' => array(
3636
+ 'comment.id' => $comment_id,
3637
+ 'commenter.id' => $commenter_id,
3638
+ 'usermessage' => wp_strip_all_tags( $content ),
3639
+ 'parent-comment-user.id' => $parent_comment->user_id,
3640
+ 'poster.name' => $poster_name,
3641
+ 'thread.url' => esc_url( $thread_link ),
3642
+ 'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
3643
+ ),
3644
+ );
3645
+
3646
+ bp_send_email( 'activity-comment-author', $parent_comment->user_id, $args );
3647
+ }
3648
+
3649
+ /**
3650
+ * Fires at the point that notifications should be sent for comments on activity replies.
3651
+ *
3652
+ * @since 2.6.0
3653
+ *
3654
+ * @param BP_Activity_Activity $parent_comment The parent activity.
3655
+ * @param int $comment_id ID for the newly received comment.
3656
+ * @param int $commenter_id ID of the user who made the comment.
3657
+ * @param array $params Arguments used with the original activity comment.
3658
+ */
3659
+ do_action( 'bp_activity_sent_reply_to_reply_notification', $parent_comment, $comment_id, $commenter_id, $params );
3660
+ }
3661
+ }
3662
+
3663
+ /**
3664
+ * Helper method to map action arguments to function parameters.
3665
+ *
3666
+ * @since 1.9.0
3667
+ *
3668
+ * @param int $comment_id ID of the comment being notified about.
3669
+ * @param array $params Parameters to use with notification.
3670
+ */
3671
+ function bp_activity_new_comment_notification_helper( $comment_id, $params ) {
3672
+ bp_activity_new_comment_notification( $comment_id, $params['user_id'], $params );
3673
+ }
3674
+ add_action( 'bp_activity_comment_posted', 'bp_activity_new_comment_notification_helper', 10, 2 );
3675
 
3676
  /** Embeds *******************************************************************/
3677
 
3691
  * @see bp_embed_activity_cache()
3692
  * @see bp_embed_activity_save_cache()
3693
  *
 
 
 
3694
  */
3695
  function bp_activity_embed() {
3696
  add_filter( 'embed_post_id', 'bp_get_activity_id' );
3697
+ add_filter( 'oembed_dataparse', 'bp_activity_oembed_dataparse', 10, 2 );
3698
  add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
3699
  add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
3700
  }
3701
  add_action( 'activity_loop_start', 'bp_activity_embed' );
3702
 
3703
+ /**
3704
+ * Cache full oEmbed response from oEmbed.
3705
+ *
3706
+ * @since 2.6.0
3707
+ *
3708
+ * @param string $retval Current oEmbed result.
3709
+ * @param object $data Full oEmbed response.
3710
+ * @param string $url URL used for the oEmbed request.
3711
+ * @return string
3712
+ */
3713
+ function bp_activity_oembed_dataparse( $retval, $data ) {
3714
+ buddypress()->activity->oembed_response = $data;
3715
+
3716
+ return $retval;
3717
+ }
3718
+
3719
  /**
3720
  * Set up activity oEmbed cache while recursing through activity comments.
3721
  *
3730
  * @see bp_embed_activity_cache()
3731
  * @see bp_embed_activity_save_cache()
3732
  *
 
 
 
3733
  */
3734
  function bp_activity_comment_embed() {
3735
  add_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
3744
  * @since 1.5.0
3745
  *
3746
  * @see BP_Embed
 
 
 
3747
  *
3748
  * @param object $activity The activity that is being expanded.
3749
  */
3750
  function bp_dtheme_embed_read_more( $activity ) {
3751
  buddypress()->activity->read_more_id = $activity->id;
3752
 
3753
+ add_filter( 'embed_post_id', function() { return buddypress()->activity->read_more_id; } );
3754
  add_filter( 'bp_embed_get_cache', 'bp_embed_activity_cache', 10, 3 );
3755
  add_action( 'bp_embed_update_cache', 'bp_embed_activity_save_cache', 10, 3 );
3756
  }
3766
  * @since 1.5.0
3767
  *
3768
  * @see bp_activity_comment_embed()
 
3769
  */
3770
  function bp_activity_comment_embed_after_recurse() {
3771
  remove_filter( 'embed_post_id', 'bp_get_activity_comment_id' );
3780
  * @since 1.5.0
3781
  *
3782
  * @see BP_Embed::parse_oembed()
 
3783
  *
3784
  * @param string $cache An empty string passed by BP_Embed::parse_oembed() for
3785
  * functions like this one to filter.
3799
  * @since 1.5.0
3800
  *
3801
  * @see BP_Embed::parse_oembed()
 
3802
  *
3803
  * @param string $cache An empty string passed by BP_Embed::parse_oembed() for
3804
  * functions like this one to filter.
3807
  */
3808
  function bp_embed_activity_save_cache( $cache, $cachekey, $id ) {
3809
  bp_activity_update_meta( $id, $cachekey, $cache );
3810
+
3811
+ // Cache full oEmbed response.
3812
+ if ( true === isset( buddypress()->activity->oembed_response ) ) {
3813
+ $cachekey = str_replace( '_oembed', '_oembed_response', $cachekey );
3814
+ bp_activity_update_meta( $id, $cachekey, buddypress()->activity->oembed_response );
3815
+ }
3816
  }
3817
 
3818
  /**
3820
  *
3821
  * @since 2.0.0
3822
  *
 
 
 
 
 
 
3823
  * @return bool True if activity heartbeat is enabled, otherwise false.
3824
  */
3825
  function bp_activity_do_heartbeat() {
3826
  $retval = false;
3827
 
3828
+ if ( bp_is_activity_heartbeat_active() && ( bp_is_activity_directory() || bp_is_group_activity() ) ) {
 
 
 
 
3829
  $retval = true;
3830
  }
3831
 
3832
+ /**
3833
+ * Filters whether the heartbeat feature in the activity stream should be active.
3834
+ *
3835
+ * @since 2.8.0
3836
+ *
3837
+ * @param bool $retval Whether or not activity heartbeat is active.
3838
+ */
3839
+ return (bool) apply_filters( 'bp_activity_do_heartbeat', $retval );
3840
  }
bp-activity/bp-activity-loader.php CHANGED
@@ -12,10 +12,8 @@
12
  // Exit if accessed directly.
13
  defined( 'ABSPATH' ) || exit;
14
 
15
- require dirname( __FILE__ ) . '/classes/class-bp-activity-component.php';
16
-
17
  /**
18
- * Bootstrap the Activity component.
19
  *
20
  * @since 1.6.0
21
  */
12
  // Exit if accessed directly.
13
  defined( 'ABSPATH' ) || exit;
14
 
 
 
15
  /**
16
+ * Set up the bp-activity component.
17
  *
18
  * @since 1.6.0
19
  */
bp-activity/bp-activity-notifications.php CHANGED
@@ -10,236 +10,68 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- /* Emails *********************************************************************/
14
-
15
- /**
16
- * Send email and BP notifications when a user is mentioned in an update.
17
- *
18
- * @since 1.2.0
19
- *
20
- * @uses bp_notifications_add_notification()
21
- * @uses bp_get_user_meta()
22
- * @uses bp_core_get_user_displayname()
23
- * @uses bp_activity_get_permalink()
24
- * @uses bp_core_get_user_domain()
25
- * @uses bp_get_settings_slug()
26
- * @uses bp_activity_filter_kses()
27
- * @uses bp_core_get_core_userdata()
28
- * @uses wp_specialchars_decode()
29
- * @uses get_blog_option()
30
- * @uses bp_is_active()
31
- * @uses bp_is_group()
32
- * @uses bp_get_current_group_name()
33
- * @uses apply_filters() To call the 'bp_activity_at_message_notification_to' hook.
34
- * @uses apply_filters() To call the 'bp_activity_at_message_notification_subject' hook.
35
- * @uses apply_filters() To call the 'bp_activity_at_message_notification_message' hook.
36
- * @uses wp_mail()
37
- * @uses do_action() To call the 'bp_activity_sent_mention_email' hook.
38
- *
39
- * @param int $activity_id The ID of the activity update.
40
- * @param int $receiver_user_id The ID of the user who is receiving the update.
41
- */
42
- function bp_activity_at_message_notification( $activity_id, $receiver_user_id ) {
43
- $notifications = BP_Core_Notification::get_all_for_user( $receiver_user_id, 'all' );
44
-
45
- // Don't leave multiple notifications for the same activity item.
46
- foreach( $notifications as $notification ) {
47
- if ( $activity_id == $notification->item_id ) {
48
- return;
49
- }
50
- }
51
-
52
- $activity = new BP_Activity_Activity( $activity_id );
53
- $email_type = 'activity-at-message';
54
- $group_name = '';
55
- $message_link = bp_activity_get_permalink( $activity_id );
56
- $poster_name = bp_core_get_user_displayname( $activity->user_id );
57
-
58
- remove_filter( 'bp_get_activity_content_body', 'convert_smilies' );
59
- remove_filter( 'bp_get_activity_content_body', 'wpautop' );
60
- remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
61
-
62
- /** This filter is documented in bp-activity/bp-activity-template.php */
63
- $content = apply_filters( 'bp_get_activity_content_body', $activity->content );
64
-
65
- add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
66
- add_filter( 'bp_get_activity_content_body', 'wpautop' );
67
- add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
68
-
69
- // Now email the user with the contents of the message (if they have enabled email notifications).
70
- if ( 'no' != bp_get_user_meta( $receiver_user_id, 'notification_activity_new_mention', true ) ) {
71
- if ( bp_is_active( 'groups' ) && bp_is_group() ) {
72
- $email_type = 'groups-at-message';
73
- $group_name = bp_get_current_group_name();
74
- }
75
-
76
- $args = array(
77
- 'tokens' => array(
78
- 'activity' => $activity,
79
- 'usermessage' => wp_strip_all_tags( $content ),
80
- 'group.name' => $group_name,
81
- 'mentioned.url' => $message_link,
82
- 'poster.name' => $poster_name,
83
- 'receiver-user.id' => $receiver_user_id,
84
- ),
85
- );
86
-
87
- bp_send_email( $email_type, $receiver_user_id, $args );
88
- }
89
-
90
- /**
91
- * Fires after the sending of an @mention email notification.
92
- *
93
- * @since 1.5.0
94
- * @since 2.5.0 $subject, $message, $content arguments unset and deprecated.
95
- *
96
- * @param BP_Activity_Activity $activity Activity Item object.
97
- * @param string $deprecated Removed in 2.5; now an empty string.
98
- * @param string $deprecated Removed in 2.5; now an empty string.
99
- * @param string $deprecated Removed in 2.5; now an empty string.
100
- * @param int $receiver_user_id The ID of the user who is receiving the update.
101
- */
102
- do_action( 'bp_activity_sent_mention_email', $activity, '', '', '', $receiver_user_id );
103
- }
104
-
105
- /**
106
- * Send email and BP notifications when an activity item receives a comment.
107
- *
108
- * @since 1.2.0
109
- * @since 2.5.0 Updated to use new email APIs.
110
- *
111
- * @uses bp_get_user_meta()
112
- * @uses bp_core_get_user_displayname()
113
- * @uses bp_activity_get_permalink()
114
- * @uses bp_core_get_user_domain()
115
- * @uses bp_get_settings_slug()
116
- * @uses bp_activity_filter_kses()
117
- * @uses bp_core_get_core_userdata()
118
- * @uses wp_specialchars_decode()
119
- * @uses get_blog_option()
120
- * @uses bp_get_root_blog_id()
121
- * @uses apply_filters() To call the 'bp_activity_new_comment_notification_to' hook.
122
- * @uses apply_filters() To call the 'bp_activity_new_comment_notification_subject' hook.
123
- * @uses apply_filters() To call the 'bp_activity_new_comment_notification_message' hook.
124
- * @uses wp_mail()
125
- * @uses do_action() To call the 'bp_activity_sent_reply_to_update_email' hook.
126
- * @uses apply_filters() To call the 'bp_activity_new_comment_notification_comment_author_to' hook.
127
- * @uses apply_filters() To call the 'bp_activity_new_comment_notification_comment_author_subject' hook.
128
- * @uses apply_filters() To call the 'bp_activity_new_comment_notification_comment_author_message' hook.
129
- * @uses do_action() To call the 'bp_activity_sent_reply_to_reply_email' hook.
130
- *
131
- * @param int $comment_id The comment id.
132
- * @param int $commenter_id The ID of the user who posted the comment.
133
- * @param array $params {@link bp_activity_new_comment()}.
134
- */
135
- function bp_activity_new_comment_notification( $comment_id = 0, $commenter_id = 0, $params = array() ) {
136
- $original_activity = new BP_Activity_Activity( $params['activity_id'] );
137
- $poster_name = bp_core_get_user_displayname( $commenter_id );
138
- $thread_link = bp_activity_get_permalink( $params['activity_id'] );
139
-
140
- remove_filter( 'bp_get_activity_content_body', 'convert_smilies' );
141
- remove_filter( 'bp_get_activity_content_body', 'wpautop' );
142
- remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
143
-
144
- /** This filter is documented in bp-activity/bp-activity-template.php */
145
- $content = apply_filters( 'bp_get_activity_content_body', $params['content'] );
146
-
147
- add_filter( 'bp_get_activity_content_body', 'convert_smilies' );
148
- add_filter( 'bp_get_activity_content_body', 'wpautop' );
149
- add_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
150
-
151
- if ( $original_activity->user_id != $commenter_id && 'no' != bp_get_user_meta( $original_activity->user_id, 'notification_activity_new_reply', true ) ) {
152
- $args = array(
153
- 'tokens' => array(
154
- 'comment.id' => $comment_id,
155
- 'commenter.id' => $commenter_id,
156
- 'usermessage' => wp_strip_all_tags( $content ),
157
- 'original_activity.user_id' => $original_activity->user_id,
158
- 'poster.name' => $poster_name,
159
- 'thread.url' => esc_url( $thread_link ),
160
- ),
161
- );
162
-
163
- bp_send_email( 'activity-comment', $original_activity->user_id, $args );
164
- }
165
-
166
-
167
- /*
168
- * If this is a reply to another comment, send an email notification to the
169
- * author of the immediate parent comment.
170
- */
171
- if ( empty( $params['parent_id'] ) || ( $params['activity_id'] == $params['parent_id'] ) ) {
172
- return;
173
- }
174
-
175
- $parent_comment = new BP_Activity_Activity( $params['parent_id'] );
176
-
177
- if ( $parent_comment->user_id != $commenter_id && $original_activity->user_id != $parent_comment->user_id && 'no' != bp_get_user_meta( $parent_comment->user_id, 'notification_activity_new_reply', true ) ) {
178
- $args = array(
179
- 'tokens' => array(
180
- 'comment.id' => $comment_id,
181
- 'commenter.id' => $commenter_id,
182
- 'usermessage' => wp_strip_all_tags( $content ),
183
- 'parent-comment-user.id' => $parent_comment->user_id,
184
- 'poster.name' => $poster_name,
185
- 'thread.url' => esc_url( $thread_link ),
186
- ),
187
- );
188
-
189
- bp_send_email( 'activity-comment-author', $parent_comment->user_id, $args );
190
- }
191
- }
192
-
193
- /**
194
- * Helper method to map action arguments to function parameters.
195
- *
196
- * @since 1.9.0
197
- *
198
- * @param int $comment_id ID of the comment being notified about.
199
- * @param array $params Parameters to use with notification.
200
- */
201
- function bp_activity_new_comment_notification_helper( $comment_id, $params ) {
202
- bp_activity_new_comment_notification( $comment_id, $params['user_id'], $params );
203
- }
204
- add_action( 'bp_activity_comment_posted', 'bp_activity_new_comment_notification_helper', 10, 2 );
205
-
206
- /** Notifications *************************************************************/
207
-
208
  /**
209
  * Format notifications related to activity.
210
  *
211
  * @since 1.5.0
212
  *
213
- * @uses bp_loggedin_user_domain()
214
- * @uses bp_get_activity_slug()
215
- * @uses bp_core_get_user_displayname()
216
- * @uses apply_filters() To call the 'bp_activity_multiple_at_mentions_notification' hook.
217
- * @uses apply_filters() To call the 'bp_activity_single_at_mentions_notification' hook.
218
- * @uses do_action() To call 'activity_format_notifications' hook.
219
- *
220
  * @param string $action The type of activity item. Just 'new_at_mention' for now.
221
  * @param int $item_id The activity ID.
222
  * @param int $secondary_item_id In the case of at-mentions, this is the mentioner's ID.
223
  * @param int $total_items The total number of notifications to format.
224
  * @param string $format 'string' to get a BuddyBar-compatible notification, 'array' otherwise.
 
225
  * @return string $return Formatted @mention notification.
226
  */
227
- function bp_activity_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string' ) {
 
 
 
 
 
228
 
229
  switch ( $action ) {
230
  case 'new_at_mention':
231
- $activity_id = $item_id;
232
- $poster_user_id = $secondary_item_id;
233
- $at_mention_link = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/';
234
- $at_mention_title = sprintf( __( '@%s Mentions', 'buddypress' ), bp_get_loggedin_user_username() );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  $amount = 'single';
236
 
237
  if ( (int) $total_items > 1 ) {
238
- $text = sprintf( __( 'You have %1$d new mentions', 'buddypress' ), (int) $total_items );
 
239
  $amount = 'multiple';
240
  } else {
241
- $user_fullname = bp_core_get_user_displayname( $poster_user_id );
242
- $text = sprintf( __( '%1$s mentioned you', 'buddypress' ), $user_fullname );
243
  }
244
  break;
245
  }
@@ -247,42 +79,44 @@ function bp_activity_format_notifications( $action, $item_id, $secondary_item_id
247
  if ( 'string' == $format ) {
248
 
249
  /**
250
- * Filters the @mention notification for the string format.
251
  *
252
  * This is a variable filter that is dependent on how many items
253
  * need notified about. The two possible hooks are bp_activity_single_at_mentions_notification
254
  * or bp_activity_multiple_at_mentions_notification.
255
  *
256
  * @since 1.5.0
 
257
  *
258
- * @param string $string HTML anchor tag for the mention.
259
- * @param string $at_mention_link The permalink for the mention.
260
  * @param int $total_items How many items being notified about.
261
  * @param int $activity_id ID of the activity item being formatted.
262
- * @param int $poster_user_id ID of the user posting the mention.
263
  */
264
- $return = apply_filters( 'bp_activity_' . $amount . '_at_mentions_notification', '<a href="' . esc_url( $at_mention_link ) . '" title="' . esc_attr( $at_mention_title ) . '">' . esc_html( $text ) . '</a>', $at_mention_link, (int) $total_items, $activity_id, $poster_user_id );
265
  } else {
266
 
267
  /**
268
- * Filters the @mention notification for any non-string format.
269
  *
270
  * This is a variable filter that is dependent on how many items need notified about.
271
  * The two possible hooks are bp_activity_single_at_mentions_notification
272
  * or bp_activity_multiple_at_mentions_notification.
273
  *
274
  * @since 1.5.0
 
275
  *
276
- * @param array $array Array holding the content and permalink for the mention notification.
277
- * @param string $at_mention_link The permalink for the mention.
278
  * @param int $total_items How many items being notified about.
279
  * @param int $activity_id ID of the activity item being formatted.
280
- * @param int $poster_user_id ID of the user posting the mention.
281
  */
282
- $return = apply_filters( 'bp_activity_' . $amount . '_at_mentions_notification', array(
283
  'text' => $text,
284
- 'link' => $at_mention_link
285
- ), $at_mention_link, (int) $total_items, $activity_id, $poster_user_id );
286
  }
287
 
288
  /**
@@ -292,7 +126,7 @@ function bp_activity_format_notifications( $action, $item_id, $secondary_item_id
292
  *
293
  * @param string $action The type of activity item.
294
  * @param int $item_id The activity ID.
295
- * @param int $secondary_item_id @mention mentioner ID.
296
  * @param int $total_items Total amount of items to format.
297
  */
298
  do_action( 'activity_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
@@ -317,8 +151,7 @@ function bp_activity_format_notifications( $action, $item_id, $secondary_item_id
317
  * @param int $receiver_user_id ID of user receiving notification.
318
  */
319
  function bp_activity_at_mention_add_notification( $activity, $subject, $message, $content, $receiver_user_id ) {
320
- if ( bp_is_active( 'notifications' ) ) {
321
- bp_notifications_add_notification( array(
322
  'user_id' => $receiver_user_id,
323
  'item_id' => $activity->id,
324
  'secondary_item_id' => $activity->user_id,
@@ -326,11 +159,54 @@ function bp_activity_at_mention_add_notification( $activity, $subject, $message,
326
  'component_action' => 'new_at_mention',
327
  'date_notified' => bp_core_current_time(),
328
  'is_new' => 1,
329
- ) );
330
- }
331
  }
332
  add_action( 'bp_activity_sent_mention_email', 'bp_activity_at_mention_add_notification', 10, 5 );
333
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  /**
335
  * Mark at-mention notifications as read when users visit their Mentions page.
336
  *
@@ -338,13 +214,8 @@ add_action( 'bp_activity_sent_mention_email', 'bp_activity_at_mention_add_notifi
338
  * @since 2.5.0 Add the $user_id parameter
339
  *
340
  * @param int $user_id The id of the user whose notifications are marked as read.
341
- * @uses bp_notifications_mark_all_notifications_by_type()
342
  */
343
  function bp_activity_remove_screen_notifications( $user_id = 0 ) {
344
- if ( ! bp_is_active( 'notifications' ) ) {
345
- return;
346
- }
347
-
348
  // Only mark read if the current user is looking at his own mentions.
349
  if ( empty( $user_id ) || (int) $user_id !== (int) bp_loggedin_user_id() ) {
350
  return;
@@ -362,10 +233,6 @@ add_action( 'bp_activity_clear_new_mentions', 'bp_activity_remove_screen_notific
362
  * @param BP_Activity_Activity $activity Activity object.
363
  */
364
  function bp_activity_remove_screen_notifications_single_activity_permalink( $activity ) {
365
- if ( ! bp_is_active( 'notifications' ) ) {
366
- return;
367
- }
368
-
369
  if ( ! is_user_logged_in() ) {
370
  return;
371
  }
@@ -375,6 +242,32 @@ function bp_activity_remove_screen_notifications_single_activity_permalink( $act
375
  }
376
  add_action( 'bp_activity_screen_single_activity_permalink', 'bp_activity_remove_screen_notifications_single_activity_permalink' );
377
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  /**
379
  * Delete at-mention notifications when the corresponding activity item is deleted.
380
  *
@@ -385,10 +278,64 @@ add_action( 'bp_activity_screen_single_activity_permalink', 'bp_activity_remove_
385
  function bp_activity_at_mention_delete_notification( $activity_ids_deleted = array() ) {
386
  // Let's delete all without checking if content contains any mentions
387
  // to avoid a query to get the activity.
388
- if ( bp_is_active( 'notifications' ) && ! empty( $activity_ids_deleted ) ) {
389
  foreach ( $activity_ids_deleted as $activity_id ) {
390
  bp_notifications_delete_all_notifications_by_type( $activity_id, buddypress()->activity->id );
391
  }
392
  }
393
  }
394
  add_action( 'bp_activity_deleted_activities', 'bp_activity_at_mention_delete_notification', 10 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Format notifications related to activity.
15
  *
16
  * @since 1.5.0
17
  *
 
 
 
 
 
 
 
18
  * @param string $action The type of activity item. Just 'new_at_mention' for now.
19
  * @param int $item_id The activity ID.
20
  * @param int $secondary_item_id In the case of at-mentions, this is the mentioner's ID.
21
  * @param int $total_items The total number of notifications to format.
22
  * @param string $format 'string' to get a BuddyBar-compatible notification, 'array' otherwise.
23
+ * @param int $id Optional. The notification ID.
24
  * @return string $return Formatted @mention notification.
25
  */
26
+ function bp_activity_format_notifications( $action, $item_id, $secondary_item_id, $total_items, $format = 'string', $id = 0 ) {
27
+ $action_filter = $action;
28
+ $return = false;
29
+ $activity_id = $item_id;
30
+ $user_id = $secondary_item_id;
31
+ $user_fullname = bp_core_get_user_displayname( $user_id );
32
 
33
  switch ( $action ) {
34
  case 'new_at_mention':
35
+ $action_filter = 'at_mentions';
36
+ $link = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/';
37
+ $title = sprintf( __( '@%s Mentions', 'buddypress' ), bp_get_loggedin_user_username() );
38
+ $amount = 'single';
39
+
40
+ if ( (int) $total_items > 1 ) {
41
+ $text = sprintf( __( 'You have %1$d new mentions', 'buddypress' ), (int) $total_items );
42
+ $amount = 'multiple';
43
+ } else {
44
+ $text = sprintf( __( '%1$s mentioned you', 'buddypress' ), $user_fullname );
45
+ }
46
+ break;
47
+
48
+ case 'update_reply':
49
+ $link = bp_get_notifications_permalink();
50
+ $title = __( 'New Activity reply', 'buddypress' );
51
+ $amount = 'single';
52
+
53
+ if ( (int) $total_items > 1 ) {
54
+ $link = add_query_arg( 'type', $action, $link );
55
+ $text = sprintf( __( 'You have %1$d new replies', 'buddypress' ), (int) $total_items );
56
+ $amount = 'multiple';
57
+ } else {
58
+ $link = add_query_arg( 'nid', (int) $id, bp_activity_get_permalink( $activity_id ) );
59
+ $text = sprintf( __( '%1$s commented on one of your updates', 'buddypress' ), $user_fullname );
60
+ }
61
+ break;
62
+
63
+ case 'comment_reply':
64
+ $link = bp_get_notifications_permalink();
65
+ $title = __( 'New Activity comment reply', 'buddypress' );
66
  $amount = 'single';
67
 
68
  if ( (int) $total_items > 1 ) {
69
+ $link = add_query_arg( 'type', $action, $link );
70
+ $text = sprintf( __( 'You have %1$d new comment replies', 'buddypress' ), (int) $total_items );
71
  $amount = 'multiple';
72
  } else {
73
+ $link = add_query_arg( 'nid', (int) $id, bp_activity_get_permalink( $activity_id ) );
74
+ $text = sprintf( __( '%1$s replied to one your activity comments', 'buddypress' ), $user_fullname );
75
  }
76
  break;
77
  }
79
  if ( 'string' == $format ) {
80
 
81
  /**
82
+ * Filters the activity notification for the string format.
83
  *
84
  * This is a variable filter that is dependent on how many items
85
  * need notified about. The two possible hooks are bp_activity_single_at_mentions_notification
86
  * or bp_activity_multiple_at_mentions_notification.
87
  *
88
  * @since 1.5.0
89
+ * @since 2.6.0 use the $action_filter as a new dynamic portion of the filter name.
90
  *
91
+ * @param string $string HTML anchor tag for the interaction.
92
+ * @param string $link The permalink for the interaction.
93
  * @param int $total_items How many items being notified about.
94
  * @param int $activity_id ID of the activity item being formatted.
95
+ * @param int $user_id ID of the user who inited the interaction.
96
  */
97
+ $return = apply_filters( 'bp_activity_' . $amount . '_' . $action_filter . '_notification', '<a href="' . esc_url( $link ) . '" title="' . esc_attr( $title ) . '">' . esc_html( $text ) . '</a>', $link, (int) $total_items, $activity_id, $user_id );
98
  } else {
99
 
100
  /**
101
+ * Filters the activity notification for any non-string format.
102
  *
103
  * This is a variable filter that is dependent on how many items need notified about.
104
  * The two possible hooks are bp_activity_single_at_mentions_notification
105
  * or bp_activity_multiple_at_mentions_notification.
106
  *
107
  * @since 1.5.0
108
+ * @since 2.6.0 use the $action_filter as a new dynamic portion of the filter name.
109
  *
110
+ * @param array $array Array holding the content and permalink for the interaction notification.
111
+ * @param string $link The permalink for the interaction.
112
  * @param int $total_items How many items being notified about.
113
  * @param int $activity_id ID of the activity item being formatted.
114
+ * @param int $user_id ID of the user who inited the interaction.
115
  */
116
+ $return = apply_filters( 'bp_activity_' . $amount . '_' . $action_filter . '_notification', array(
117
  'text' => $text,
118
+ 'link' => $link
119
+ ), $link, (int) $total_items, $activity_id, $user_id );
120
  }
121
 
122
  /**
126
  *
127
  * @param string $action The type of activity item.
128
  * @param int $item_id The activity ID.
129
+ * @param int $secondary_item_id The user ID who inited the interaction.
130
  * @param int $total_items Total amount of items to format.
131
  */
132
  do_action( 'activity_format_notifications', $action, $item_id, $secondary_item_id, $total_items );
151
  * @param int $receiver_user_id ID of user receiving notification.
152
  */
153
  function bp_activity_at_mention_add_notification( $activity, $subject, $message, $content, $receiver_user_id ) {
154
+ bp_notifications_add_notification( array(
 
155
  'user_id' => $receiver_user_id,
156
  'item_id' => $activity->id,
157
  'secondary_item_id' => $activity->user_id,
159
  'component_action' => 'new_at_mention',
160
  'date_notified' => bp_core_current_time(),
161
  'is_new' => 1,
162
+ ) );
 
163
  }
164
  add_action( 'bp_activity_sent_mention_email', 'bp_activity_at_mention_add_notification', 10, 5 );
165
 
166
+ /**
167
+ * Notify a member one of their activity received a reply.
168
+ *
169
+ * @since 2.6.0
170
+ *
171
+ * @param BP_Activity_Activity $activity The original activity.
172
+ * @param int $comment_id ID for the newly received comment.
173
+ * @param int $commenter_id ID of the user who made the comment.
174
+ */
175
+ function bp_activity_update_reply_add_notification( $activity, $comment_id, $commenter_id ) {
176
+ bp_notifications_add_notification( array(
177
+ 'user_id' => $activity->user_id,
178
+ 'item_id' => $comment_id,
179
+ 'secondary_item_id' => $commenter_id,
180
+ 'component_name' => buddypress()->activity->id,
181
+ 'component_action' => 'update_reply',
182
+ 'date_notified' => bp_core_current_time(),
183
+ 'is_new' => 1,
184
+ ) );
185
+ }
186
+ add_action( 'bp_activity_sent_reply_to_update_notification', 'bp_activity_update_reply_add_notification', 10, 3 );
187
+
188
+ /**
189
+ * Notify a member one of their activity comment received a reply.
190
+ *
191
+ * @since 2.6.0
192
+ *
193
+ * @param BP_Activity_Activity $activity_comment The parent activity.
194
+ * @param int $comment_id ID for the newly received comment.
195
+ * @param int $commenter_id ID of the user who made the comment.
196
+ */
197
+ function bp_activity_comment_reply_add_notification( $activity_comment, $comment_id, $commenter_id ) {
198
+ bp_notifications_add_notification( array(
199
+ 'user_id' => $activity_comment->user_id,
200
+ 'item_id' => $comment_id,
201
+ 'secondary_item_id' => $commenter_id,
202
+ 'component_name' => buddypress()->activity->id,
203
+ 'component_action' => 'comment_reply',
204
+ 'date_notified' => bp_core_current_time(),
205
+ 'is_new' => 1,
206
+ ) );
207
+ }
208
+ add_action( 'bp_activity_sent_reply_to_reply_notification', 'bp_activity_comment_reply_add_notification', 10, 3 );
209
+
210
  /**
211
  * Mark at-mention notifications as read when users visit their Mentions page.
212
  *
214
  * @since 2.5.0 Add the $user_id parameter
215
  *
216
  * @param int $user_id The id of the user whose notifications are marked as read.
 
217
  */
218
  function bp_activity_remove_screen_notifications( $user_id = 0 ) {
 
 
 
 
219
  // Only mark read if the current user is looking at his own mentions.
220
  if ( empty( $user_id ) || (int) $user_id !== (int) bp_loggedin_user_id() ) {
221
  return;
233
  * @param BP_Activity_Activity $activity Activity object.
234
  */
235
  function bp_activity_remove_screen_notifications_single_activity_permalink( $activity ) {
 
 
 
 
236
  if ( ! is_user_logged_in() ) {
237
  return;
238
  }
242
  }
243
  add_action( 'bp_activity_screen_single_activity_permalink', 'bp_activity_remove_screen_notifications_single_activity_permalink' );
244
 
245
+ /**
246
+ * Mark non-mention notifications as read when user visits our read permalink.
247
+ *
248
+ * In particular, 'update_reply' and 'comment_reply' notifications are handled
249
+ * here. See {@link bp_activity_format_notifications()} for more info.
250
+ *
251
+ * @since 2.6.0
252
+ */
253
+ function bp_activity_remove_screen_notifications_for_non_mentions() {
254
+ if ( false === is_singular() || false === is_user_logged_in() || empty( $_GET['nid'] ) ) {
255
+ return;
256
+ }
257
+
258
+ // Mark notification as read.
259
+ BP_Notifications_Notification::update(
260
+ array(
261
+ 'is_new' => false
262
+ ),
263
+ array(
264
+ 'user_id' => bp_loggedin_user_id(),
265
+ 'id' => (int) $_GET['nid']
266
+ )
267
+ );
268
+ }
269
+ add_action( 'bp_screens', 'bp_activity_remove_screen_notifications_for_non_mentions' );
270
+
271
  /**
272
  * Delete at-mention notifications when the corresponding activity item is deleted.
273
  *
278
  function bp_activity_at_mention_delete_notification( $activity_ids_deleted = array() ) {
279
  // Let's delete all without checking if content contains any mentions
280
  // to avoid a query to get the activity.
281
+ if ( ! empty( $activity_ids_deleted ) ) {
282
  foreach ( $activity_ids_deleted as $activity_id ) {
283
  bp_notifications_delete_all_notifications_by_type( $activity_id, buddypress()->activity->id );
284
  }
285
  }
286
  }
287
  add_action( 'bp_activity_deleted_activities', 'bp_activity_at_mention_delete_notification', 10 );
288
+
289
+ /**
290
+ * Add a notification for post comments to the post author or post commenter.
291
+ *
292
+ * Requires "activity stream commenting on blog and forum posts" to be enabled.
293
+ *
294
+ * @since 2.6.0
295
+ *
296
+ * @param int $activity_id The activity comment ID.
297
+ * @param WP_Comment $post_type_comment WP Comment object.
298
+ * @param array $activity_args Activity comment arguments.
299
+ * @param object $activity_post_object The post type tracking args object.
300
+ */
301
+ function bp_activity_add_notification_for_synced_blog_comment( $activity_id, $post_type_comment, $activity_args, $activity_post_object ) {
302
+ // If activity comments are disabled for WP posts, stop now!
303
+ if ( bp_disable_blogforum_comments() || empty( $activity_id ) ) {
304
+ return;
305
+ }
306
+
307
+ // Send a notification to the blog post author.
308
+ if ( (int) $post_type_comment->post->post_author !== (int) $activity_args['user_id'] ) {
309
+ // Only add a notification if comment author is a registered user.
310
+ // @todo Should we remove this restriction?
311
+ if ( ! empty( $post_type_comment->user_id ) ) {
312
+ bp_notifications_add_notification( array(
313
+ 'user_id' => $post_type_comment->post->post_author,
314
+ 'item_id' => $activity_id,
315
+ 'secondary_item_id' => $post_type_comment->user_id,
316
+ 'component_name' => buddypress()->activity->id,
317
+ 'component_action' => 'update_reply',
318
+ 'date_notified' => $post_type_comment->comment_date_gmt,
319
+ 'is_new' => 1,
320
+ ) );
321
+ }
322
+ }
323
+
324
+ // Send a notification to the parent comment author for follow-up comments.
325
+ if ( ! empty( $post_type_comment->comment_parent ) ) {
326
+ $parent_comment = get_comment( $post_type_comment->comment_parent );
327
+
328
+ if ( ! empty( $parent_comment->user_id ) && (int) $parent_comment->user_id !== (int) $activity_args['user_id'] ) {
329
+ bp_notifications_add_notification( array(
330
+ 'user_id' => $parent_comment->user_id,
331
+ 'item_id' => $activity_id,
332
+ 'secondary_item_id' => $post_type_comment->user_id,
333
+ 'component_name' => buddypress()->activity->id,
334
+ 'component_action' => 'comment_reply',
335
+ 'date_notified' => $post_type_comment->comment_date_gmt,
336
+ 'is_new' => 1,
337
+ ) );
338
+ }
339
+ }
340
+ }
341
+ add_action( 'bp_blogs_comment_sync_activity_comment', 'bp_activity_add_notification_for_synced_blog_comment', 10, 4 );
bp-activity/bp-activity-screens.php CHANGED
@@ -14,20 +14,11 @@
14
  // Exit if accessed directly.
15
  defined( 'ABSPATH' ) || exit;
16
 
17
- require dirname( __FILE__ ) . '/classes/class-bp-activity-theme-compat.php';
18
-
19
  /**
20
  * Load the Activity directory.
21
  *
22
  * @since 1.5.0
23
  *
24
- * @uses bp_displayed_user_id()
25
- * @uses bp_is_activity_component()
26
- * @uses bp_current_action()
27
- * @uses bp_update_is_directory()
28
- * @uses do_action() To call the 'bp_activity_screen_index' hook.
29
- * @uses bp_core_load_template()
30
- * @uses apply_filters() To call the 'bp_activity_screen_index' hook.
31
  */
32
  function bp_activity_screen_index() {
33
  if ( bp_is_activity_directory() ) {
@@ -57,9 +48,6 @@ add_action( 'bp_screens', 'bp_activity_screen_index' );
57
  *
58
  * @since 1.0.0
59
  *
60
- * @uses do_action() To call the 'bp_activity_screen_my_activity' hook.
61
- * @uses bp_core_load_template()
62
- * @uses apply_filters() To call the 'bp_activity_template_my_activity' hook.
63
  */
64
  function bp_activity_screen_my_activity() {
65
 
@@ -85,12 +73,6 @@ function bp_activity_screen_my_activity() {
85
  *
86
  * @since 1.0.0
87
  *
88
- * @uses bp_is_active()
89
- * @uses bp_update_is_item_admin()
90
- * @uses bp_current_user_can()
91
- * @uses do_action() To call the 'bp_activity_screen_friends' hook.
92
- * @uses bp_core_load_template()
93
- * @uses apply_filters() To call the 'bp_activity_template_friends_activity' hook.
94
  */
95
  function bp_activity_screen_friends() {
96
  if ( !bp_is_active( 'friends' ) )
@@ -120,12 +102,6 @@ function bp_activity_screen_friends() {
120
  *
121
  * @since 1.2.0
122
  *
123
- * @uses bp_is_active()
124
- * @uses bp_update_is_item_admin()
125
- * @uses bp_current_user_can()
126
- * @uses do_action() To call the 'bp_activity_screen_groups' hook.
127
- * @uses bp_core_load_template()
128
- * @uses apply_filters() To call the 'bp_activity_template_groups_activity' hook.
129
  */
130
  function bp_activity_screen_groups() {
131
  if ( !bp_is_active( 'groups' ) )
@@ -155,11 +131,6 @@ function bp_activity_screen_groups() {
155
  *
156
  * @since 1.2.0
157
  *
158
- * @uses bp_update_is_item_admin()
159
- * @uses bp_current_user_can()
160
- * @uses do_action() To call the 'bp_activity_screen_favorites' hook.
161
- * @uses bp_core_load_template()
162
- * @uses apply_filters() To call the 'bp_activity_template_favorite_activity' hook.
163
  */
164
  function bp_activity_screen_favorites() {
165
  bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
@@ -186,11 +157,6 @@ function bp_activity_screen_favorites() {
186
  *
187
  * @since 1.2.0
188
  *
189
- * @uses bp_update_is_item_admin()
190
- * @uses bp_current_user_can()
191
- * @uses do_action() To call the 'bp_activity_screen_mentions' hook.
192
- * @uses bp_core_load_template()
193
- * @uses apply_filters() To call the 'bp_activity_template_mention_activity' hook.
194
  */
195
  function bp_activity_screen_mentions() {
196
  bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
@@ -217,9 +183,6 @@ function bp_activity_screen_mentions() {
217
  *
218
  * @since 1.5.0
219
  *
220
- * @uses bp_is_my_profile()
221
- * @uses bp_activity_clear_new_mentions()
222
- * @uses bp_loggedin_user_id()
223
  */
224
  function bp_activity_reset_my_new_mentions() {
225
  if ( bp_is_my_profile() )
@@ -232,25 +195,6 @@ add_action( 'bp_activity_screen_mentions', 'bp_activity_reset_my_new_mentions' )
232
  *
233
  * @since 1.2.0
234
  *
235
- * @uses bp_is_activity_component()
236
- * @uses bp_activity_get_specific()
237
- * @uses bp_current_action()
238
- * @uses bp_action_variables()
239
- * @uses bp_do_404()
240
- * @uses bp_is_active()
241
- * @uses groups_get_group()
242
- * @uses groups_is_user_member()
243
- * @uses apply_filters_ref_array() To call the 'bp_activity_permalink_access' hook.
244
- * @uses do_action() To call the 'bp_activity_screen_single_activity_permalink' hook.
245
- * @uses bp_core_add_message()
246
- * @uses is_user_logged_in()
247
- * @uses bp_core_redirect()
248
- * @uses site_url()
249
- * @uses esc_url()
250
- * @uses bp_get_root_domain()
251
- * @uses bp_get_activity_root_slug()
252
- * @uses bp_core_load_template()
253
- * @uses apply_filters() To call the 'bp_activity_template_profile_activity_permalink' hook.
254
  */
255
  function bp_activity_screen_single_activity_permalink() {
256
  $bp = buddypress();
@@ -288,7 +232,7 @@ function bp_activity_screen_single_activity_permalink() {
288
 
289
  // Check to see if the group is not public, if so, check the
290
  // user has access to see this activity.
291
- if ( $group = groups_get_group( array( 'group_id' => $activity->item_id ) ) ) {
292
 
293
  // Group is not public.
294
  if ( 'public' != $group->status ) {
@@ -301,6 +245,11 @@ function bp_activity_screen_single_activity_permalink() {
301
  }
302
  }
303
 
 
 
 
 
 
304
  /**
305
  * Filters the access permission for a single activity view.
306
  *
@@ -333,7 +282,7 @@ function bp_activity_screen_single_activity_permalink() {
333
  } else {
334
  $url = sprintf(
335
  site_url( 'wp-login.php?redirect_to=%s' ),
336
- urlencode( esc_url_raw( bp_activity_get_permalink( (int) bp_current_action() ) ) )
337
  );
338
  }
339
 
@@ -356,9 +305,6 @@ add_action( 'bp_screens', 'bp_activity_screen_single_activity_permalink' );
356
  *
357
  * @since 1.2.0
358
  *
359
- * @uses bp_get_user_meta()
360
- * @uses bp_core_get_username()
361
- * @uses do_action() To call the 'bp_activity_screen_notification_settings' hook.
362
  */
363
  function bp_activity_screen_notification_settings() {
364
 
@@ -389,16 +335,28 @@ function bp_activity_screen_notification_settings() {
389
  <tr id="activity-notification-settings-mentions">
390
  <td>&nbsp;</td>
391
  <td><?php printf( __( 'A member mentions you in an update using "@%s"', 'buddypress' ), bp_core_get_username( bp_displayed_user_id() ) ) ?></td>
392
- <td class="yes"><input type="radio" name="notifications[notification_activity_new_mention]" id="notification-activity-new-mention-yes" value="yes" <?php checked( $mention, 'yes', true ) ?>/><label for="notification-activity-new-mention-yes" class="bp-screen-reader-text"><?php _e( 'Yes, send email', 'buddypress' ); ?></label></td>
393
- <td class="no"><input type="radio" name="notifications[notification_activity_new_mention]" id="notification-activity-new-mention-no" value="no" <?php checked( $mention, 'no', true ) ?>/><label for="notification-activity-new-mention-no" class="bp-screen-reader-text"><?php _e( 'No, do not send email', 'buddypress' ); ?></label></td>
 
 
 
 
 
 
394
  </tr>
395
  <?php endif; ?>
396
 
397
  <tr id="activity-notification-settings-replies">
398
  <td>&nbsp;</td>
399
  <td><?php _e( "A member replies to an update or comment you've posted", 'buddypress' ) ?></td>
400
- <td class="yes"><input type="radio" name="notifications[notification_activity_new_reply]" id="notification-activity-new-reply-yes" value="yes" <?php checked( $reply, 'yes', true ) ?>/><label for="notification-activity-new-reply-yes" class="bp-screen-reader-text"><?php _e( 'Yes, send email', 'buddypress' ); ?></label></td>
401
- <td class="no"><input type="radio" name="notifications[notification_activity_new_reply]" id="notification-activity-new-reply-no" value="no" <?php checked( $reply, 'no', true ) ?>/><label for="notification-activity-new-reply-no" class="bp-screen-reader-text"><?php _e( 'No, do not send email', 'buddypress' ); ?></label></td>
 
 
 
 
 
 
402
  </tr>
403
 
404
  <?php
14
  // Exit if accessed directly.
15
  defined( 'ABSPATH' ) || exit;
16
 
 
 
17
  /**
18
  * Load the Activity directory.
19
  *
20
  * @since 1.5.0
21
  *
 
 
 
 
 
 
 
22
  */
23
  function bp_activity_screen_index() {
24
  if ( bp_is_activity_directory() ) {
48
  *
49
  * @since 1.0.0
50
  *
 
 
 
51
  */
52
  function bp_activity_screen_my_activity() {
53
 
73
  *
74
  * @since 1.0.0
75
  *
 
 
 
 
 
 
76
  */
77
  function bp_activity_screen_friends() {
78
  if ( !bp_is_active( 'friends' ) )
102
  *
103
  * @since 1.2.0
104
  *
 
 
 
 
 
 
105
  */
106
  function bp_activity_screen_groups() {
107
  if ( !bp_is_active( 'groups' ) )
131
  *
132
  * @since 1.2.0
133
  *
 
 
 
 
 
134
  */
135
  function bp_activity_screen_favorites() {
136
  bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
157
  *
158
  * @since 1.2.0
159
  *
 
 
 
 
 
160
  */
161
  function bp_activity_screen_mentions() {
162
  bp_update_is_item_admin( bp_current_user_can( 'bp_moderate' ), 'activity' );
183
  *
184
  * @since 1.5.0
185
  *
 
 
 
186
  */
187
  function bp_activity_reset_my_new_mentions() {
188
  if ( bp_is_my_profile() )
195
  *
196
  * @since 1.2.0
197
  *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  */
199
  function bp_activity_screen_single_activity_permalink() {
200
  $bp = buddypress();
232
 
233
  // Check to see if the group is not public, if so, check the
234
  // user has access to see this activity.
235
+ if ( $group = groups_get_group( $activity->item_id ) ) {
236
 
237
  // Group is not public.
238
  if ( 'public' != $group->status ) {
245
  }
246
  }
247
 
248
+ // If activity author does not match displayed user, block access.
249
+ if ( true === $has_access && bp_displayed_user_id() !== $activity->user_id ) {
250
+ $has_access = false;
251
+ }
252
+
253
  /**
254
  * Filters the access permission for a single activity view.
255
  *
282
  } else {
283
  $url = sprintf(
284
  site_url( 'wp-login.php?redirect_to=%s' ),
285
+ urlencode( esc_url_raw( bp_activity_get_permalink( bp_current_action() ) ) )
286
  );
287
  }
288
 
305
  *
306
  * @since 1.2.0
307
  *
 
 
 
308
  */
309
  function bp_activity_screen_notification_settings() {
310
 
335
  <tr id="activity-notification-settings-mentions">
336
  <td>&nbsp;</td>
337
  <td><?php printf( __( 'A member mentions you in an update using "@%s"', 'buddypress' ), bp_core_get_username( bp_displayed_user_id() ) ) ?></td>
338
+ <td class="yes"><input type="radio" name="notifications[notification_activity_new_mention]" id="notification-activity-new-mention-yes" value="yes" <?php checked( $mention, 'yes', true ) ?>/><label for="notification-activity-new-mention-yes" class="bp-screen-reader-text"><?php
339
+ /* translators: accessibility text */
340
+ _e( 'Yes, send email', 'buddypress' );
341
+ ?></label></td>
342
+ <td class="no"><input type="radio" name="notifications[notification_activity_new_mention]" id="notification-activity-new-mention-no" value="no" <?php checked( $mention, 'no', true ) ?>/><label for="notification-activity-new-mention-no" class="bp-screen-reader-text"><?php
343
+ /* translators: accessibility text */
344
+ _e( 'No, do not send email', 'buddypress' );
345
+ ?></label></td>
346
  </tr>
347
  <?php endif; ?>
348
 
349
  <tr id="activity-notification-settings-replies">
350
  <td>&nbsp;</td>
351
  <td><?php _e( "A member replies to an update or comment you've posted", 'buddypress' ) ?></td>
352
+ <td class="yes"><input type="radio" name="notifications[notification_activity_new_reply]" id="notification-activity-new-reply-yes" value="yes" <?php checked( $reply, 'yes', true ) ?>/><label for="notification-activity-new-reply-yes" class="bp-screen-reader-text"><?php
353
+ /* translators: accessibility text */
354
+ _e( 'Yes, send email', 'buddypress' );
355
+ ?></label></td>
356
+ <td class="no"><input type="radio" name="notifications[notification_activity_new_reply]" id="notification-activity-new-reply-no" value="no" <?php checked( $reply, 'no', true ) ?>/><label for="notification-activity-new-reply-no" class="bp-screen-reader-text"><?php
357
+ /* translators: accessibility text */
358
+ _e( 'No, do not send email', 'buddypress' );
359
+ ?></label></td>
360
  </tr>
361
 
362
  <?php
bp-activity/bp-activity-template.php CHANGED
@@ -10,14 +10,11 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- require dirname( __FILE__ ) . '/classes/class-bp-activity-template.php';
14
-
15
  /**
16
  * Output the activity component slug.
17
  *
18
  * @since 1.5.0
19
  *
20
- * @uses bp_get_activity_slug()
21
  */
22
  function bp_activity_slug() {
23
  echo bp_get_activity_slug();
@@ -27,7 +24,6 @@ function bp_activity_slug() {
27
  *
28
  * @since 1.5.0
29
  *
30
- * @uses apply_filters() To call the 'bp_get_activity_slug' hook.
31
  *
32
  * @return string The activity component slug.
33
  */
@@ -48,7 +44,6 @@ function bp_activity_slug() {
48
  *
49
  * @since 1.5.0
50
  *
51
- * @uses bp_get_activity_root_slug()
52
  */
53
  function bp_activity_root_slug() {
54
  echo bp_get_activity_root_slug();
@@ -58,7 +53,6 @@ function bp_activity_root_slug() {
58
  *
59
  * @since 1.5.0
60
  *
61
- * @uses apply_filters() To call the 'bp_get_activity_root_slug' hook.
62
  *
63
  * @return string The activity component root slug.
64
  */
@@ -79,7 +73,6 @@ function bp_activity_root_slug() {
79
  *
80
  * @since 1.5.0
81
  *
82
- * @uses bp_get_activity_directory_permalink()
83
  */
84
  function bp_activity_directory_permalink() {
85
  echo esc_url( bp_get_activity_directory_permalink() );
@@ -89,10 +82,6 @@ function bp_activity_directory_permalink() {
89
  *
90
  * @since 1.5.0
91
  *
92
- * @uses trailingslashit()
93
- * @uses bp_get_root_domain()
94
- * @uses bp_get_activity_root_slug()
95
- * @uses apply_filters() To call the 'bp_get_activity_directory_permalink' hook.
96
  *
97
  * @return string Activity directory permalink.
98
  */
@@ -119,17 +108,6 @@ function bp_activity_directory_permalink() {
119
  * @since 2.4.0 Introduced the `$fields` parameter.
120
  *
121
  * @global object $activities_template {@link BP_Activity_Template}
122
- * @uses groups_is_user_member()
123
- * @uses bp_current_action()
124
- * @uses bp_is_current_action()
125
- * @uses bp_get_activity_slug()
126
- * @uses bp_action_variable()
127
- * @uses wp_parse_args()
128
- * @uses bp_is_active()
129
- * @uses friends_get_friend_user_ids()
130
- * @uses groups_get_user_groups()
131
- * @uses bp_activity_get_user_favorites()
132
- * @uses apply_filters() To call the 'bp_has_activities' hook.
133
  *
134
  * @param array|string $args {
135
  * Arguments for limiting the contents of the activity loop. Most arguments
@@ -388,7 +366,6 @@ function bp_has_activities( $args = '' ) {
388
  * @since 1.0.0
389
  *
390
  * @global object $activities_template {@link BP_Activity_Template}
391
- * @uses BP_Activity_Template::user_activities() {@link BP_Activity_Template::user_activities()}
392
  *
393
  * @return bool Returns true when activities are found.
394
  */
@@ -403,7 +380,6 @@ function bp_activities() {
403
  * @since 1.0.0
404
  *
405
  * @global object $activities_template {@link BP_Activity_Template}
406
- * @uses BP_Activity_Template::the_activity() {@link BP_Activity_Template::the_activity()}
407
  *
408
  * @return object The current activity within the loop.
409
  */
@@ -451,7 +427,6 @@ function bp_activity_load_more_link() {
451
  * @since 1.0.0
452
  *
453
  * @global object $activities_template {@link BP_Activity_Template}
454
- * @uses BP_Activity_Template::the_activity() {@link BP_Activity_Template::the_activity()}
455
  */
456
  function bp_activity_pagination_count() {
457
  echo bp_get_activity_pagination_count();
@@ -463,7 +438,6 @@ function bp_activity_pagination_count() {
463
  * @since 1.2.0
464
  *
465
  * @global object $activities_template {@link BP_Activity_Template}
466
- * @uses bp_core_number_format()
467
  *
468
  * @return string The pagination text.
469
  */
@@ -489,7 +463,6 @@ function bp_activity_pagination_count() {
489
  *
490
  * @since 1.0.0
491
  *
492
- * @uses bp_get_activity_pagination_links()
493
  */
494
  function bp_activity_pagination_links() {
495
  echo bp_get_activity_pagination_links();
@@ -501,7 +474,6 @@ function bp_activity_pagination_links() {
501
  * @since 1.0.0
502
  *
503
  * @global object $activities_template {@link BP_Activity_Template}
504
- * @uses apply_filters() To call the 'bp_get_activity_pagination_links' hook.
505
  *
506
  * @return string The pagination links.
507
  */
@@ -524,7 +496,6 @@ function bp_activity_pagination_links() {
524
  * @since 1.5.0
525
  *
526
  * @global object $activities_template {@link BP_Activity_Template}
527
- * @uses apply_filters() To call the 'bp_activity_has_more_items' hook.
528
  *
529
  * @return bool $has_more_items True if more items, false if not.
530
  */
@@ -558,7 +529,6 @@ function bp_activity_has_more_items() {
558
  *
559
  * @since 1.2.0
560
  *
561
- * @uses bp_get_activity_count()
562
  */
563
  function bp_activity_count() {
564
  echo bp_get_activity_count();
@@ -570,7 +540,6 @@ function bp_activity_count() {
570
  * @since 1.2.0
571
  *
572
  * @global object $activities_template {@link BP_Activity_Template}
573
- * @uses apply_filters() To call the 'bp_get_activity_count' hook.
574
  *
575
  * @return int The activity count.
576
  */
@@ -592,7 +561,6 @@ function bp_activity_count() {
592
  *
593
  * @since 1.2.0
594
  *
595
- * @uses bp_get_activity_per_page()
596
  */
597
  function bp_activity_per_page() {
598
  echo bp_get_activity_per_page();
@@ -604,7 +572,6 @@ function bp_activity_per_page() {
604
  * @since 1.2.0
605
  *
606
  * @global object $activities_template {@link BP_Activity_Template}
607
- * @uses apply_filters() To call the 'bp_get_activity_per_page' hook.
608
  *
609
  * @return int The activities per page.
610
  */
@@ -626,7 +593,6 @@ function bp_activity_per_page() {
626
  *
627
  * @since 1.0.0
628
  *
629
- * @uses bp_get_activities_title()
630
  * @todo Deprecate.
631
  */
632
  function bp_activities_title() {
@@ -639,7 +605,6 @@ function bp_activities_title() {
639
  * @since 1.0.0
640
  *
641
  * @global string $bp_activity_title
642
- * @uses apply_filters() To call the 'bp_get_activities_title' hook.
643
  * @todo Deprecate.
644
  *
645
  * @return string The activities title.
@@ -662,7 +627,6 @@ function bp_activities_title() {
662
  *
663
  * @since 1.0.0
664
  *
665
- * @uses bp_get_activities_no_activity()
666
  * @todo Deprecate.
667
  */
668
  function bp_activities_no_activity() {
@@ -675,7 +639,6 @@ function bp_activities_no_activity() {
675
  * @since 1.0.0
676
  *
677
  * @global string $bp_activity_no_activity
678
- * @uses apply_filters() To call the 'bp_get_activities_no_activity' hook.
679
  * @todo Deprecate.
680
  *
681
  * @return string
@@ -698,7 +661,6 @@ function bp_activities_no_activity() {
698
  *
699
  * @since 1.2.0
700
  *
701
- * @uses bp_get_activity_id()
702
  */
703
  function bp_activity_id() {
704
  echo bp_get_activity_id();
@@ -710,7 +672,6 @@ function bp_activity_id() {
710
  * @since 1.2.0
711
  *
712
  * @global object $activities_template {@link BP_Activity_Template}
713
- * @uses apply_filters() To call the 'bp_get_activity_id' hook.
714
  *
715
  * @return int The activity ID.
716
  */
@@ -732,7 +693,6 @@ function bp_activity_id() {
732
  *
733
  * @since 1.2.0
734
  *
735
- * @uses bp_get_activity_item_id()
736
  */
737
  function bp_activity_item_id() {
738
  echo bp_get_activity_item_id();
@@ -744,7 +704,6 @@ function bp_activity_item_id() {
744
  * @since 1.2.0
745
  *
746
  * @global object $activities_template {@link BP_Activity_Template}
747
- * @uses apply_filters() To call the 'bp_get_activity_item_id' hook.
748
  *
749
  * @return int The activity item ID.
750
  */
@@ -766,7 +725,6 @@ function bp_activity_item_id() {
766
  *
767
  * @since 1.2.0
768
  *
769
- * @uses bp_get_activity_secondary_item_id()
770
  */
771
  function bp_activity_secondary_item_id() {
772
  echo bp_get_activity_secondary_item_id();
@@ -778,7 +736,6 @@ function bp_activity_secondary_item_id() {
778
  * @since 1.2.0
779
  *
780
  * @global object $activities_template {@link BP_Activity_Template}
781
- * @uses apply_filters() To call the 'bp_get_activity_secondary_item_id' hook.
782
  *
783
  * @return int The activity secondary item ID.
784
  */
@@ -800,7 +757,6 @@ function bp_activity_secondary_item_id() {
800
  *
801
  * @since 1.2.0
802
  *
803
- * @uses bp_get_activity_date_recorded()
804
  */
805
  function bp_activity_date_recorded() {
806
  echo bp_get_activity_date_recorded();
@@ -812,7 +768,6 @@ function bp_activity_date_recorded() {
812
  * @since 1.2.0
813
  *
814
  * @global object $activities_template {@link BP_Activity_Template}
815
- * @uses apply_filters() To call the 'bp_get_activity_date_recorded' hook.
816
  *
817
  * @return string The date the activity was recorded.
818
  */
@@ -834,7 +789,6 @@ function bp_activity_date_recorded() {
834
  *
835
  * @since 2.1.0
836
  *
837
- * @uses bp_get_activity_member_display_name()
838
  */
839
  function bp_activity_member_display_name() {
840
  echo bp_get_activity_member_display_name();
@@ -846,7 +800,6 @@ function bp_activity_member_display_name() {
846
  * @since 2.1.0
847
  *
848
  * @global object $activities_template {@link BP_Activity_Template}
849
- * @uses apply_filters() To call the 'bp_get_activity_member_display_name' hook.
850
  *
851
  * @return string The date the activity was recorded.
852
  */
@@ -872,7 +825,6 @@ function bp_activity_member_display_name() {
872
  *
873
  * @since 1.2.0
874
  *
875
- * @uses bp_get_activity_object_name()
876
  */
877
  function bp_activity_object_name() {
878
  echo bp_get_activity_object_name();
@@ -884,7 +836,6 @@ function bp_activity_object_name() {
884
  * @since 1.2.0
885
  *
886
  * @global object $activities_template {@link BP_Activity_Template}
887
- * @uses apply_filters() To call the 'bp_get_activity_object_name' hook.
888
  *
889
  * @return string The activity object name.
890
  */
@@ -906,7 +857,6 @@ function bp_activity_object_name() {
906
  *
907
  * @since 1.2.0
908
  *
909
- * @uses bp_get_activity_type()
910
  */
911
  function bp_activity_type() {
912
  echo bp_get_activity_type();
@@ -918,7 +868,6 @@ function bp_activity_type() {
918
  * @since 1.2.0
919
  *
920
  * @global object $activities_template {@link BP_Activity_Template}
921
- * @uses apply_filters() To call the 'bp_get_activity_type' hook.
922
  *
923
  * @return string The activity type.
924
  */
@@ -946,7 +895,6 @@ function bp_activity_type() {
946
  * @todo Properly deprecate in favor of bp_activity_type() and
947
  * remove redundant echo
948
  *
949
- * @uses bp_activity_type()
950
  */
951
  function bp_activity_action_name() { echo bp_activity_type(); }
952
 
@@ -960,7 +908,6 @@ function bp_activity_type() {
960
  *
961
  * @todo Properly deprecate in favor of bp_get_activity_type().
962
  *
963
- * @uses bp_get_activity_type()
964
  *
965
  * @return string The activity type.
966
  */
@@ -971,7 +918,6 @@ function bp_activity_type() {
971
  *
972
  * @since 1.1.0
973
  *
974
- * @uses bp_get_activity_user_id()
975
  */
976
  function bp_activity_user_id() {
977
  echo bp_get_activity_user_id();
@@ -983,7 +929,6 @@ function bp_activity_user_id() {
983
  * @since 1.1.0
984
  *
985
  * @global object $activities_template {@link BP_Activity_Template}
986
- * @uses apply_filters() To call the 'bp_get_activity_user_id' hook.
987
  *
988
  * @return int The activity user ID.
989
  */
@@ -1005,7 +950,6 @@ function bp_activity_user_id() {
1005
  *
1006
  * @since 1.2.0
1007
  *
1008
- * @uses bp_get_activity_user_link()
1009
  */
1010
  function bp_activity_user_link() {
1011
  echo bp_get_activity_user_link();
@@ -1017,8 +961,6 @@ function bp_activity_user_link() {
1017
  * @since 1.2.0
1018
  *
1019
  * @global object $activities_template {@link BP_Activity_Template}
1020
- * @uses bp_core_get_user_domain()
1021
- * @uses apply_filters() To call the 'bp_get_activity_user_link' hook.
1022
  *
1023
  * @return string $link The activity user link.
1024
  */
@@ -1047,7 +989,6 @@ function bp_activity_user_link() {
1047
  * @since 1.1.0
1048
  *
1049
  * @see bp_get_activity_avatar() for description of arguments.
1050
- * @uses bp_get_activity_avatar()
1051
  *
1052
  * @param array|string $args See {@link bp_get_activity_avatar()} for description.
1053
  */
@@ -1061,12 +1002,6 @@ function bp_activity_avatar( $args = '' ) {
1061
  *
1062
  * @see bp_core_fetch_avatar() For a description of the arguments.
1063
  * @global object $activities_template {@link BP_Activity_Template}
1064
- * @uses bp_is_single_activity()
1065
- * @uses wp_parse_args()
1066
- * @uses apply_filters() To call the 'bp_get_activity_avatar_object_' . $current_activity_item->component hook.
1067
- * @uses apply_filters() To call the 'bp_get_activity_avatar_item_id' hook.
1068
- * @uses bp_core_fetch_avatar()
1069
- * @uses apply_filters() To call the 'bp_get_activity_avatar' hook.
1070
  *
1071
  * @param array|string $args {
1072
  * Arguments are listed here with an explanation of their defaults.
@@ -1162,7 +1097,7 @@ function bp_activity_avatar( $args = '' ) {
1162
  *
1163
  * @since 1.1.3
1164
  *
1165
- * @param array $value Array of arguments calculated for use with bp_core_fetch_avatar.
1166
  */
1167
  return apply_filters( 'bp_get_activity_avatar', bp_core_fetch_avatar( array(
1168
  'item_id' => $item_id,
@@ -1182,7 +1117,6 @@ function bp_activity_avatar( $args = '' ) {
1182
  * @since 1.2.0
1183
  *
1184
  * @see bp_get_activity_secondary_avatar() for description of arguments.
1185
- * @uses bp_get_activity_secondary_avatar()
1186
  *
1187
  * @param array|string $args See {@link bp_get_activity_secondary_avatar} for description.
1188
  */
@@ -1197,12 +1131,6 @@ function bp_activity_secondary_avatar( $args = '' ) {
1197
  *
1198
  * @see bp_core_fetch_avatar() for description of arguments.
1199
  * @global object $activities_template {@link BP_Activity_Template}
1200
- * @uses wp_parse_args()
1201
- * @uses get_blog_option()
1202
- * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar_object_' . $activities_template->activity->component hook.
1203
- * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar_item_id' hook.
1204
- * @uses bp_core_fetch_avatar()
1205
- * @uses apply_filters() To call the 'bp_get_activity_secondary_avatar' hook.
1206
  *
1207
  * @param array|string $args {
1208
  * For a complete description of arguments, see {@link bp_core_fetch_avatar()}.
@@ -1245,11 +1173,7 @@ function bp_activity_secondary_avatar( $args = '' ) {
1245
 
1246
  // Only if groups is active.
1247
  if ( bp_is_active( 'groups' ) ) {
1248
- $group = groups_get_group( array(
1249
- 'group_id' => $item_id,
1250
- 'populate_extras' => false,
1251
- 'update_meta_cache' => false,
1252
- ) );
1253
  $link = bp_get_group_permalink( $group );
1254
  $name = $group->name;
1255
  }
@@ -1373,7 +1297,6 @@ function bp_activity_secondary_avatar( $args = '' ) {
1373
  * @since 1.2.0
1374
  *
1375
  * @param array $args See bp_get_activity_action().
1376
- * @uses bp_get_activity_action()
1377
  */
1378
  function bp_activity_action( $args = array() ) {
1379
  echo bp_get_activity_action( $args );
@@ -1385,9 +1308,6 @@ function bp_activity_action( $args = array() ) {
1385
  * @since 1.2.0
1386
  *
1387
  * @global object $activities_template {@link BP_Activity_Template}
1388
- * @uses apply_filters_ref_array() To call the 'bp_get_activity_action_pre_meta' hook.
1389
- * @uses bp_insert_activity_meta()
1390
- * @uses apply_filters_ref_array() To call the 'bp_get_activity_action' hook.
1391
  *
1392
  * @param array $args {
1393
  * @type bool $no_timestamp Whether to exclude the timestamp.
@@ -1439,7 +1359,6 @@ function bp_activity_action( $args = array() ) {
1439
  *
1440
  * @since 1.2.0
1441
  *
1442
- * @uses bp_get_activity_content_body()
1443
  */
1444
  function bp_activity_content_body() {
1445
  echo bp_get_activity_content_body();
@@ -1451,8 +1370,6 @@ function bp_activity_content_body() {
1451
  * @since 1.2.0
1452
  *
1453
  * @global object $activities_template {@link BP_Activity_Template}
1454
- * @uses bp_insert_activity_meta()
1455
- * @uses apply_filters_ref_array() To call the 'bp_get_activity_content_body' hook.
1456
  *
1457
  * @return string The activity content body.
1458
  */
@@ -1469,7 +1386,8 @@ function bp_activity_content_body() {
1469
  *
1470
  * @since 1.2.0
1471
  *
1472
- * @param array $value Array containing the current activity content body and the current activity.
 
1473
  */
1474
  return apply_filters_ref_array( 'bp_get_activity_content_body', array( $activities_template->activity->content, &$activities_template->activity ) );
1475
  }
@@ -1501,7 +1419,6 @@ function bp_activity_has_content() {
1501
  *
1502
  * @todo properly deprecate this function.
1503
  *
1504
- * @uses bp_get_activity_content()
1505
  */
1506
  function bp_activity_content() {
1507
  echo bp_get_activity_content();
@@ -1515,9 +1432,6 @@ function bp_activity_content() {
1515
  *
1516
  * @todo properly deprecate this function.
1517
  *
1518
- * @uses bp_get_activity_action()
1519
- * @uses bp_get_activity_content_body()
1520
- * @uses apply_filters() To call the 'bp_get_activity_content' hook.
1521
  *
1522
  * @return string The activity content.
1523
  */
@@ -1542,13 +1456,6 @@ function bp_activity_content() {
1542
  * @since 1.2.0
1543
  *
1544
  * @global object $activities_template {@link BP_Activity_Template}
1545
- * @uses bp_core_time_since()
1546
- * @uses apply_filters_ref_array() To call the 'bp_activity_time_since' hook.
1547
- * @uses bp_is_single_activity()
1548
- * @uses bp_activity_get_permalink()
1549
- * @uses esc_attr__()
1550
- * @uses apply_filters_ref_array() To call the 'bp_activity_permalink' hook.
1551
- * @uses apply_filters() To call the 'bp_insert_activity_meta' hook.
1552
  *
1553
  * @param string $content The activity content.
1554
  * @return string The activity content with the metadata string attached.
@@ -1562,6 +1469,13 @@ function bp_insert_activity_meta( $content = '' ) {
1562
  // Get the time since this activity was recorded.
1563
  $date_recorded = bp_core_time_since( $activities_template->activity->date_recorded );
1564
 
 
 
 
 
 
 
 
1565
  /**
1566
  * Filters the activity item time since markup.
1567
  *
@@ -1570,7 +1484,7 @@ function bp_insert_activity_meta( $content = '' ) {
1570
  * @param array $value Array containing the time since markup and the current activity component.
1571
  */
1572
  $time_since = apply_filters_ref_array( 'bp_activity_time_since', array(
1573
- '<span class="time-since">' . $date_recorded . '</span>',
1574
  &$activities_template->activity
1575
  ) );
1576
 
@@ -1618,9 +1532,8 @@ function bp_insert_activity_meta( $content = '' ) {
1618
  * @since 1.2.0
1619
  *
1620
  * @global object $activities_template {@link BP_Activity_Template}
1621
- * @uses apply_filters() To call the 'bp_activity_user_can_delete' hook.
1622
  *
1623
- * @param object|bool $activity Optional. Falls back on the current item in the loop.
1624
  * @return bool True if can delete, false otherwise.
1625
  */
1626
  function bp_activity_user_can_delete( $activity = false ) {
@@ -1650,7 +1563,7 @@ function bp_activity_user_can_delete( $activity = false ) {
1650
  // Users are allowed to delete their own activity. This is actually
1651
  // quite powerful, because doing so also deletes all comments to that
1652
  // activity item. We should revisit this eventually.
1653
- if ( isset( $activity->user_id ) && ( (int) $activity->user_id === bp_loggedin_user_id() ) ) {
1654
  $can_delete = true;
1655
  }
1656
 
@@ -1677,7 +1590,6 @@ function bp_activity_user_can_delete( $activity = false ) {
1677
  * @since 1.2.0
1678
  *
1679
  * @see bp_get_activity_parent_content() for a description of arguments.
1680
- * @uses bp_get_activity_parent_content()
1681
  *
1682
  * @param array|string $args See {@link bp_get_activity_parent_content} for description.
1683
  */
@@ -1691,7 +1603,6 @@ function bp_activity_parent_content( $args = '' ) {
1691
  * @since 1.2.0
1692
  *
1693
  * @global object $activities_template {@link BP_Activity_Template}
1694
- * @uses apply_filters() To call the 'bp_get_activity_parent_content' hook.
1695
  *
1696
  * @param string $args Unused. Left over from an earlier implementation.
1697
  * @return mixed False on failure, otherwise the activity parent content.
@@ -1705,7 +1616,7 @@ function bp_activity_parent_content( $args = '' ) {
1705
  }
1706
 
1707
  // Get the ID of the parent activity content.
1708
- $parent_id = (int) $activities_template->activity->item_id;
1709
 
1710
  // Bail if no parent content.
1711
  if ( empty( $activities_template->activity_parents[ $parent_id ] ) ) {
@@ -1769,7 +1680,7 @@ function bp_activity_parent_user_id() {
1769
  }
1770
 
1771
  // Get the ID of the parent activity content.
1772
- $parent_id = (int) $activities_template->activity->item_id;
1773
 
1774
  // Bail if no parent item.
1775
  if ( empty( $activities_template->activity_parents[ $parent_id ] ) ) {
@@ -1798,7 +1709,6 @@ function bp_activity_parent_user_id() {
1798
  *
1799
  * @since 1.2.0
1800
  *
1801
- * @uses bp_get_activity_is_favorite()
1802
  */
1803
  function bp_activity_is_favorite() {
1804
  echo bp_get_activity_is_favorite();
@@ -1810,7 +1720,6 @@ function bp_activity_is_favorite() {
1810
  * @since 1.2.0
1811
  *
1812
  * @global object $activities_template {@link BP_Activity_Template}
1813
- * @uses apply_filters() To call the 'bp_get_activity_is_favorite' hook.
1814
  *
1815
  * @return bool True if user favorite, false otherwise.
1816
  */
@@ -1850,7 +1759,6 @@ function bp_activity_comments( $args = '' ) {
1850
  * this function can probably be streamlined or removed.
1851
  *
1852
  * @global object $activities_template {@link BP_Activity_Template}
1853
- * @uses bp_activity_recurse_comments()
1854
  *
1855
  * @param string $args Unused. Left over from an earlier implementation.
1856
  * @return bool
@@ -1874,7 +1782,6 @@ function bp_activity_comments( $args = '' ) {
1874
  * @since 1.2.0
1875
  *
1876
  * @global object $activities_template {@link BP_Activity_Template}
1877
- * @uses locate_template()
1878
  *
1879
  * @param object $comment The activity object currently being recursed.
1880
  * @return bool|string
@@ -1934,7 +1841,6 @@ function bp_activity_comments( $args = '' ) {
1934
  * @since 1.5.0
1935
  *
1936
  * @global object $activities_template {@link BP_Activity_Template}
1937
- * @uses apply_filters() To call the 'bp_activity_current_comment' hook.
1938
  *
1939
  * @return object|bool $current_comment The activity comment currently being
1940
  * displayed. False on failure.
@@ -1962,7 +1868,6 @@ function bp_activity_current_comment() {
1962
  *
1963
  * @since 1.5.0
1964
  *
1965
- * @uses bp_get_activity_comment_id()
1966
  */
1967
  function bp_activity_comment_id() {
1968
  echo bp_get_activity_comment_id();
@@ -1974,7 +1879,6 @@ function bp_activity_comment_id() {
1974
  * @since 1.5.0
1975
  *
1976
  * @global object $activities_template {@link BP_Activity_Template}
1977
- * @uses apply_filters() To call the 'bp_activity_comment_id' hook.
1978
  *
1979
  * @return int|bool $comment_id The ID of the activity comment currently
1980
  * being displayed, false if none is found.
@@ -1999,7 +1903,6 @@ function bp_activity_comment_id() {
1999
  *
2000
  * @since 1.5.0
2001
  *
2002
- * @uses bp_get_activity_comment_user_id()
2003
  */
2004
  function bp_activity_comment_user_id() {
2005
  echo bp_get_activity_comment_user_id();
@@ -2011,7 +1914,6 @@ function bp_activity_comment_user_id() {
2011
  * @since 1.5.0
2012
  *
2013
  * @global object $activities_template {@link BP_Activity_Template}
2014
- * @uses apply_filters() To call the 'bp_activity_comment_user_id' hook.
2015
  *
2016
  * @return int|bool $user_id The user_id of the author of the displayed
2017
  * activity comment. False on failure.
@@ -2036,7 +1938,6 @@ function bp_activity_comment_user_id() {
2036
  *
2037
  * @since 1.5.0
2038
  *
2039
- * @uses bp_get_activity_comment_user_link()
2040
  */
2041
  function bp_activity_comment_user_link() {
2042
  echo bp_get_activity_comment_user_link();
@@ -2047,9 +1948,6 @@ function bp_activity_comment_user_link() {
2047
  *
2048
  * @since 1.5.0
2049
  *
2050
- * @uses bp_core_get_user_domain()
2051
- * @uses bp_get_activity_comment_user_id()
2052
- * @uses apply_filters() To call the 'bp_activity_comment_user_link' hook.
2053
  *
2054
  * @return string $user_link The URL of the activity comment author's profile.
2055
  */
@@ -2071,7 +1969,6 @@ function bp_activity_comment_user_link() {
2071
  *
2072
  * @since 1.5.0
2073
  *
2074
- * @uses bp_get_activity_comment_name()
2075
  */
2076
  function bp_activity_comment_name() {
2077
  echo bp_get_activity_comment_name();
@@ -2086,8 +1983,6 @@ function bp_activity_comment_name() {
2086
  * @since 1.5.0
2087
  *
2088
  * @global object $activities_template {@link BP_Activity_Template}
2089
- * @uses apply_filters() To call the 'bp_acomment_name' hook.
2090
- * @uses apply_filters() To call the 'bp_activity_comment_name' hook.
2091
  *
2092
  * @return string $name The full name of the activity comment author.
2093
  */
@@ -2116,7 +2011,6 @@ function bp_activity_comment_name() {
2116
  *
2117
  * @since 1.5.0
2118
  *
2119
- * @uses bp_get_activity_comment_date_recorded()
2120
  */
2121
  function bp_activity_comment_date_recorded() {
2122
  echo bp_get_activity_comment_date_recorded();
@@ -2127,8 +2021,6 @@ function bp_activity_comment_date_recorded() {
2127
  *
2128
  * @since 1.5.0
2129
  *
2130
- * @uses bp_core_time_since()
2131
- * @uses apply_filters() To call the 'bp_activity_comment_date_recorded' hook.
2132
  *
2133
  * @return string|bool $date_recorded Time since the activity was recorded,
2134
  * in the form "%s ago". False on failure.
@@ -2150,7 +2042,6 @@ function bp_activity_comment_date_recorded() {
2150
  *
2151
  * @since 2.3.0
2152
  *
2153
- * @uses bp_get_activity_comment_date_recorded()
2154
  */
2155
  function bp_activity_comment_date_recorded_raw() {
2156
  echo bp_get_activity_comment_date_recorded_raw();
@@ -2162,8 +2053,6 @@ function bp_activity_comment_date_recorded_raw() {
2162
  * @since 2.3.0
2163
  *
2164
  * @global object $activities_template {@link BP_Activity_Template}
2165
- * @uses bp_core_time_since()
2166
- * @uses apply_filters() To call the 'bp_activity_comment_date_recorded' hook.
2167
  *
2168
  * @return string|bool $date_recorded Time since the activity was recorded,
2169
  * in the form "%s ago". False on failure.
@@ -2186,7 +2075,6 @@ function bp_activity_comment_date_recorded_raw() {
2186
  *
2187
  * @since 1.5.0
2188
  *
2189
- * @uses bp_get_activity_comment_delete_link()
2190
  */
2191
  function bp_activity_comment_delete_link() {
2192
  echo bp_get_activity_comment_delete_link();
@@ -2197,17 +2085,12 @@ function bp_activity_comment_delete_link() {
2197
  *
2198
  * @since 1.5.0
2199
  *
2200
- * @uses wp_nonce_url()
2201
- * @uses bp_get_root_domain()
2202
- * @uses bp_get_activity_slug()
2203
- * @uses bp_get_activity_comment_id()
2204
- * @uses apply_filters() To call the 'bp_activity_comment_delete_link' hook.
2205
  *
2206
  * @return string $link The nonced URL for deleting the current
2207
  * activity comment.
2208
  */
2209
  function bp_get_activity_comment_delete_link() {
2210
- $link = wp_nonce_url( bp_get_root_domain() . '/' . bp_get_activity_slug() . '/delete/' . bp_get_activity_comment_id() . '?cid=' . bp_get_activity_comment_id(), 'bp_activity_delete_link' );
2211
 
2212
  /**
2213
  * Filters the link used for deleting the activity comment currently being displayed.
@@ -2224,7 +2107,6 @@ function bp_activity_comment_delete_link() {
2224
  *
2225
  * @since 1.5.0
2226
  *
2227
- * @uses bp_get_activity_comment_content()
2228
  */
2229
  function bp_activity_comment_content() {
2230
  echo bp_get_activity_comment_content();
@@ -2241,8 +2123,6 @@ function bp_activity_comment_content() {
2241
  * @since 1.5.0
2242
  *
2243
  * @global object $activities_template {@link BP_Activity_Template}
2244
- * @uses apply_filters() To call the 'bp_get_activity_content' hook.
2245
- * @uses apply_filters() To call the 'bp_activity_comment_content' hook.
2246
  *
2247
  * @return string $content The content of the current activity comment.
2248
  */
@@ -2267,7 +2147,6 @@ function bp_activity_comment_content() {
2267
  *
2268
  * @since 1.2.0
2269
  *
2270
- * @uses bp_activity_get_comment_count()
2271
  */
2272
  function bp_activity_comment_count() {
2273
  echo bp_activity_get_comment_count();
@@ -2279,8 +2158,6 @@ function bp_activity_comment_count() {
2279
  * @since 1.2.0
2280
  *
2281
  * @global object $activities_template {@link BP_Activity_Template}
2282
- * @uses bp_activity_recurse_comment_count()
2283
- * @uses apply_filters() To call the 'bp_activity_get_comment_count' hook.
2284
  *
2285
  * @param array|null $deprecated Deprecated.
2286
  * @return int $count The activity comment count.
@@ -2316,8 +2193,6 @@ function bp_activity_comment_count() {
2316
  *
2317
  * @since 1.2.0
2318
  *
2319
- * @uses bp_activity_recurse_comment_count()
2320
- * @uses apply_filters() To call the 'bp_activity_recurse_comment_count' hook.
2321
  *
2322
  * @param object $comment Activity comment object.
2323
  * @param int $count The current iteration count.
@@ -2381,7 +2256,6 @@ function bp_activity_comment_depth() {
2381
  *
2382
  * @since 1.2.0
2383
  *
2384
- * @uses bp_get_activity_comment_link()
2385
  */
2386
  function bp_activity_comment_link() {
2387
  echo bp_get_activity_comment_link();
@@ -2393,7 +2267,6 @@ function bp_activity_comment_link() {
2393
  * @since 1.2.0
2394
  *
2395
  * @global object $activities_template {@link BP_Activity_Template}
2396
- * @uses apply_filters() To call the 'bp_get_activity_comment_link' hook.
2397
  *
2398
  * @return string The activity comment link.
2399
  */
@@ -2415,7 +2288,6 @@ function bp_activity_comment_link() {
2415
  *
2416
  * @since 1.2.0
2417
  *
2418
- * @uses bp_get_activity_comment_form_nojs_display()
2419
  */
2420
  function bp_activity_comment_form_nojs_display() {
2421
  echo bp_get_activity_comment_form_nojs_display();
@@ -2446,7 +2318,6 @@ function bp_activity_comment_form_nojs_display() {
2446
  *
2447
  * @since 1.2.0
2448
  *
2449
- * @uses bp_get_activity_comment_form_action()
2450
  */
2451
  function bp_activity_comment_form_action() {
2452
  echo bp_get_activity_comment_form_action();
@@ -2457,9 +2328,6 @@ function bp_activity_comment_form_action() {
2457
  *
2458
  * @since 1.2.0
2459
  *
2460
- * @uses home_url()
2461
- * @uses bp_get_activity_root_slug()
2462
- * @uses apply_filters() To call the 'bp_get_activity_comment_form_action' hook.
2463
  *
2464
  * @return string The activity comment form action.
2465
  */
@@ -2480,7 +2348,6 @@ function bp_activity_comment_form_action() {
2480
  *
2481
  * @since 1.2.0
2482
  *
2483
- * @uses bp_get_activity_permalink_id()
2484
  */
2485
  function bp_activity_permalink_id() {
2486
  echo bp_get_activity_permalink_id();
@@ -2491,7 +2358,6 @@ function bp_activity_permalink_id() {
2491
  *
2492
  * @since 1.2.0
2493
  *
2494
- * @uses apply_filters() To call the 'bp_get_activity_permalink_id' hook.
2495
  *
2496
  * @return string The activity permalink ID.
2497
  */
@@ -2512,10 +2378,9 @@ function bp_activity_permalink_id() {
2512
  *
2513
  * @since 1.2.0
2514
  *
2515
- * @uses bp_get_activity_permalink_id()
2516
  */
2517
  function bp_activity_thread_permalink() {
2518
- echo bp_get_activity_thread_permalink();
2519
  }
2520
 
2521
  /**
@@ -2523,8 +2388,6 @@ function bp_activity_thread_permalink() {
2523
  *
2524
  * @since 1.2.0
2525
  *
2526
- * @uses bp_activity_get_permalink()
2527
- * @uses apply_filters() To call the 'bp_get_activity_thread_permalink' hook.
2528
  *
2529
  * @return string $link The activity thread permalink.
2530
  */
@@ -2548,37 +2411,27 @@ function bp_activity_thread_permalink() {
2548
  *
2549
  * @since 1.8.0
2550
  *
2551
- * @uses bp_get_activity_permalink_id()
2552
  */
2553
  function bp_activity_comment_permalink() {
2554
- echo bp_get_activity_comment_permalink();
2555
  }
2556
  /**
2557
  * Return the activity comment permalink.
2558
  *
2559
  * @since 1.8.0
2560
  *
2561
- * @uses bp_activity_get_permalink()
2562
- * @uses apply_filters() To call the 'bp_get_activity_comment_permalink' hook.
2563
- *
2564
  * @return string $link The activity comment permalink.
2565
  */
2566
  function bp_get_activity_comment_permalink() {
2567
  global $activities_template;
2568
 
2569
- // Check that comment exists.
 
 
2570
  $comment_id = isset( $activities_template->activity->current_comment->id )
2571
  ? $activities_template->activity->current_comment->id
2572
  : 0;
2573
 
2574
- // Setup the comment link.
2575
- $comment_link = ! empty( $comment_id )
2576
- ? '#acomment-' .$comment_id
2577
- : false;
2578
-
2579
- // Append comment ID to end of activity permalink.
2580
- $link = bp_activity_get_permalink( $activities_template->activity->id, $activities_template->activity ) . $comment_link;
2581
-
2582
  /**
2583
  * Filters the activity comment permalink.
2584
  *
@@ -2595,7 +2448,6 @@ function bp_activity_comment_permalink() {
2595
  *
2596
  * @since 1.2.0
2597
  *
2598
- * @uses bp_get_activity_favorite_link()
2599
  */
2600
  function bp_activity_favorite_link() {
2601
  echo bp_get_activity_favorite_link();
@@ -2607,10 +2459,6 @@ function bp_activity_favorite_link() {
2607
  * @since 1.2.0
2608
  *
2609
  * @global object $activities_template {@link BP_Activity_Template}
2610
- * @uses wp_nonce_url()
2611
- * @uses home_url()
2612
- * @uses bp_get_activity_root_slug()
2613
- * @uses apply_filters() To call the 'bp_get_activity_favorite_link' hook.
2614
  *
2615
  * @return string The activity favorite link.
2616
  */
@@ -2632,7 +2480,6 @@ function bp_activity_favorite_link() {
2632
  *
2633
  * @since 1.2.0
2634
  *
2635
- * @uses bp_get_activity_unfavorite_link()
2636
  */
2637
  function bp_activity_unfavorite_link() {
2638
  echo bp_get_activity_unfavorite_link();
@@ -2644,10 +2491,6 @@ function bp_activity_unfavorite_link() {
2644
  * @since 1.2.0
2645
  *
2646
  * @global object $activities_template {@link BP_Activity_Template}
2647
- * @uses wp_nonce_url()
2648
- * @uses home_url()
2649
- * @uses bp_get_activity_root_slug()
2650
- * @uses apply_filters() To call the 'bp_get_activity_unfavorite_link' hook.
2651
  *
2652
  * @return string The activity unfavorite link.
2653
  */
@@ -2669,7 +2512,6 @@ function bp_activity_unfavorite_link() {
2669
  *
2670
  * @since 1.0.0
2671
  *
2672
- * @uses bp_get_activity_css_class()
2673
  */
2674
  function bp_activity_css_class() {
2675
  echo bp_get_activity_css_class();
@@ -2681,10 +2523,6 @@ function bp_activity_css_class() {
2681
  * @since 1.0.0
2682
  *
2683
  * @global object $activities_template {@link BP_Activity_Template}
2684
- * @uses apply_filters() To call the 'bp_activity_mini_activity_types' hook.
2685
- * @uses bp_activity_get_comment_count()
2686
- * @uses bp_activity_can_comment()
2687
- * @uses apply_filters() To call the 'bp_get_activity_css_class' hook.
2688
  *
2689
  * @return string The activity item's CSS class.
2690
  */
@@ -2732,7 +2570,6 @@ function bp_activity_css_class() {
2732
  *
2733
  * @since 1.1.0
2734
  *
2735
- * @uses bp_get_activity_delete_link()
2736
  */
2737
  function bp_activity_delete_link() {
2738
  echo bp_get_activity_delete_link();
@@ -2744,13 +2581,6 @@ function bp_activity_delete_link() {
2744
  * @since 1.1.0
2745
  *
2746
  * @global object $activities_template {@link BP_Activity_Template}
2747
- * @uses bp_get_root_domain()
2748
- * @uses bp_get_activity_root_slug()
2749
- * @uses bp_is_activity_component()
2750
- * @uses bp_current_action()
2751
- * @uses wp_get_referer()
2752
- * @uses wp_nonce_url()
2753
- * @uses apply_filters() To call the 'bp_get_activity_delete_link' hook.
2754
  *
2755
  * @return string $link Activity delete link. Contains $redirect_to arg
2756
  * if on single activity page.
@@ -2782,7 +2612,6 @@ function bp_activity_delete_link() {
2782
  *
2783
  * @since 2.1.0
2784
  *
2785
- * @uses bp_get_activity_delete_link()
2786
  */
2787
  function bp_activity_delete_url() {
2788
  echo esc_url( bp_get_activity_delete_url() );
@@ -2793,14 +2622,6 @@ function bp_activity_delete_url() {
2793
  * @since 2.1.0
2794
  *
2795
  * @global object $activities_template {@link BP_Activity_Template}
2796
- * @uses bp_get_root_domain()
2797
- * @uses bp_get_activity_root_slug()
2798
- * @uses bp_is_activity_component()
2799
- * @uses bp_current_action()
2800
- * @uses add_query_arg()
2801
- * @uses wp_get_referer()
2802
- * @uses wp_nonce_url()
2803
- * @uses apply_filters() To call the 'bp_get_activity_delete_link' hook.
2804
  *
2805
  * @return string $link Activity delete link. Contains $redirect_to arg
2806
  * if on single activity page.
@@ -2833,7 +2654,6 @@ function bp_activity_delete_url() {
2833
  * @since 1.2.0
2834
  *
2835
  * @see bp_get_activity_latest_update() for description of parameters.
2836
- * @uses bp_get_activity_latest_update()
2837
  *
2838
  * @param int $user_id See {@link bp_get_activity_latest_update()} for description.
2839
  */
@@ -2846,14 +2666,6 @@ function bp_activity_latest_update( $user_id = 0 ) {
2846
  *
2847
  * @since 1.2.0
2848
  *
2849
- * @uses bp_is_user_inactive()
2850
- * @uses bp_core_is_user_deleted()
2851
- * @uses bp_get_user_meta()
2852
- * @uses apply_filters() To call the 'bp_get_activity_latest_update_excerpt' hook.
2853
- * @uses bp_create_excerpt()
2854
- * @uses bp_get_root_domain()
2855
- * @uses bp_get_activity_root_slug()
2856
- * @uses apply_filters() To call the 'bp_get_activity_latest_update' hook.
2857
  *
2858
  * @param int $user_id If empty, will fall back on displayed user.
2859
  * @return string|bool $latest_update The activity latest update link.
@@ -2877,10 +2689,12 @@ function bp_activity_latest_update( $user_id = 0 ) {
2877
  * Filters the latest update excerpt.
2878
  *
2879
  * @since 1.2.10
 
2880
  *
2881
- * @param string $value The excerpt for the latest update.
 
2882
  */
2883
- $latest_update = apply_filters( 'bp_get_activity_latest_update_excerpt', trim( strip_tags( bp_create_excerpt( $update['content'], 358 ) ) ) );
2884
 
2885
  $latest_update = sprintf(
2886
  '%s <a href="%s">%s</a>',
@@ -2893,10 +2707,12 @@ function bp_activity_latest_update( $user_id = 0 ) {
2893
  * Filters the latest update excerpt with view link appended to the end.
2894
  *
2895
  * @since 1.2.0
 
2896
  *
2897
  * @param string $latest_update The latest update with "view" link appended to it.
 
2898
  */
2899
- return apply_filters( 'bp_get_activity_latest_update', $latest_update );
2900
  }
2901
 
2902
  /**
@@ -2905,7 +2721,6 @@ function bp_activity_latest_update( $user_id = 0 ) {
2905
  * @since 1.1.0
2906
  *
2907
  * @see bp_get_activity_filter_links() for description of parameters.
2908
- * @uses bp_get_activity_filter_links()
2909
  *
2910
  * @param array|bool $args See {@link bp_get_activity_filter_links()} for description.
2911
  */
@@ -2918,13 +2733,6 @@ function bp_activity_filter_links( $args = false ) {
2918
  *
2919
  * @since 1.1.0
2920
  *
2921
- * @uses wp_parse_args()
2922
- * @uses BP_Activity_Activity::get_recorded_components() {@link BP_Activity_Activity}
2923
- * @uses esc_attr()
2924
- * @uses add_query_arg()
2925
- * @uses remove_query_arg()
2926
- * @uses apply_filters() To call the 'bp_get_activity_filter_link_href' hook.
2927
- * @uses apply_filters() To call the 'bp_get_activity_filter_links' hook.
2928
  *
2929
  * @param array|bool $args {
2930
  * @type string $style The type of markup to use for the links.
@@ -3008,10 +2816,12 @@ function bp_activity_filter_links( $args = false ) {
3008
  * Filters all of the constructed filter links.
3009
  *
3010
  * @since 1.1.0
 
3011
  *
3012
  * @param string $value All of the links to be displayed to the user.
 
3013
  */
3014
- return apply_filters( 'bp_get_activity_filter_links', implode( "\n", $component_links ) );
3015
  }
3016
 
3017
  /**
@@ -3020,8 +2830,6 @@ function bp_activity_filter_links( $args = false ) {
3020
  * @since 1.2.0
3021
  *
3022
  * @global object $activities_template {@link BP_Activity_Template}
3023
- * @uses bp_get_activity_action_name()
3024
- * @uses apply_filters() To call the 'bp_activity_can_comment' hook.
3025
  *
3026
  * @return bool $can_comment True if item can receive comments.
3027
  */
@@ -3106,8 +2914,6 @@ function bp_activity_can_comment_reply( $comment = false ) {
3106
  *
3107
  * @since 1.5.0
3108
  *
3109
- * @uses apply_filters() To call the 'bp_activity_can_favorite' hook.
3110
- *
3111
  * @return bool True if comment can receive comments.
3112
  */
3113
  function bp_activity_can_favorite() {
@@ -3128,7 +2934,6 @@ function bp_activity_can_favorite() {
3128
  * @since 1.2.0
3129
  *
3130
  * @see bp_get_total_favorite_count_for_user() for description of parameters.
3131
- * @uses bp_get_total_favorite_count_for_user()
3132
  *
3133
  * @param int $user_id See {@link bp_get_total_favorite_count_for_user()}.
3134
  */
@@ -3141,8 +2946,6 @@ function bp_total_favorite_count_for_user( $user_id = 0 ) {
3141
  *
3142
  * @since 1.2.0
3143
  *
3144
- * @uses bp_activity_total_favorites_for_user()
3145
- * @uses apply_filters() To call the 'bp_get_total_favorite_count_for_user' hook.
3146
  *
3147
  * @param int $user_id ID of user being queried. Default: displayed user ID.
3148
  * @return int The total favorite count for the specified user.
@@ -3166,10 +2969,12 @@ function bp_total_favorite_count_for_user( $user_id = 0 ) {
3166
  * Filters the total favorite count for a user.
3167
  *
3168
  * @since 1.2.0
 
3169
  *
3170
- * @param int|bool $retval Total favorite count for a user. False on no favorites.
 
3171
  */
3172
- return apply_filters( 'bp_get_total_favorite_count_for_user', $retval );
3173
  }
3174
 
3175
 
@@ -3179,7 +2984,6 @@ function bp_total_favorite_count_for_user( $user_id = 0 ) {
3179
  * @since 1.2.0
3180
  *
3181
  * @see bp_get_total_mention_count_for_user() for description of parameters.
3182
- * @uses bp_get_total_favorite_count_for_user()
3183
  *
3184
  * @param int $user_id See {@link bp_get_total_mention_count_for_user()}.
3185
  */
@@ -3192,8 +2996,6 @@ function bp_total_mention_count_for_user( $user_id = 0 ) {
3192
  *
3193
  * @since 1.2.0
3194
  *
3195
- * @uses bp_get_user_meta()
3196
- * @uses apply_filters() To call the 'bp_get_total_mention_count_for_user' hook.
3197
  *
3198
  * @param int $user_id ID of user being queried. Default: displayed user ID.
3199
  * @return int The total mention count for the specified user.
@@ -3214,10 +3016,12 @@ function bp_total_mention_count_for_user( $user_id = 0 ) {
3214
  * Filters the total mention count for a user.
3215
  *
3216
  * @since 1.2.0
 
3217
  *
3218
- * @param int|bool $retval Total mention count for a user. False on no mentions.
 
3219
  */
3220
- return apply_filters( 'bp_get_total_mention_count_for_user', $retval );
3221
  }
3222
 
3223
  /**
@@ -3225,7 +3029,6 @@ function bp_total_mention_count_for_user( $user_id = 0 ) {
3225
  *
3226
  * @since 1.2.0
3227
  *
3228
- * @uses bp_get_send_public_message_link()
3229
  */
3230
  function bp_send_public_message_link() {
3231
  echo esc_url( bp_get_send_public_message_link() );
@@ -3236,12 +3039,6 @@ function bp_send_public_message_link() {
3236
  *
3237
  * @since 1.2.0
3238
  *
3239
- * @uses is_user_logged_in()
3240
- * @uses bp_is_my_profile()
3241
- * @uses bp_is_user()
3242
- * @uses wp_nonce_url()
3243
- * @uses bp_get_activity_directory_permalink()
3244
- * @uses apply_filters() To call the 'bp_get_send_public_message_link' hook.
3245
  *
3246
  * @return string The public message link for the displayed user.
3247
  */
@@ -3299,7 +3096,6 @@ function bp_activity_recurse_comments_activity_ids( $activity = array(), $activi
3299
  * @since 1.2.0
3300
  *
3301
  * @see bp_get_mentioned_user_display_name() for description of parameters.
3302
- * @uses bp_get_mentioned_user_display_name()
3303
  *
3304
  * @param int|string|bool $user_id_or_username See {@link bp_get_mentioned_user_display_name()}.
3305
  */
@@ -3312,8 +3108,6 @@ function bp_mentioned_user_display_name( $user_id_or_username = false ) {
3312
  *
3313
  * @since 1.2.0
3314
  *
3315
- * @uses bp_core_get_user_displayname()
3316
- * @uses apply_filters() To call the 'bp_get_mentioned_user_display_name' hook.
3317
  *
3318
  * @param int|string|bool $user_id_or_username User ID or username.
3319
  * @return string The mentioned user's display name.
@@ -3345,7 +3139,6 @@ function bp_mentioned_user_display_name( $user_id_or_username = false ) {
3345
  * @since 1.2.0
3346
  *
3347
  * @see bp_get_send_public_message_button() for description of parameters.
3348
- * @uses bp_get_send_public_message_button()
3349
  *
3350
  * @param array|string $args See {@link bp_get_send_public_message_button()}.
3351
  */
@@ -3358,10 +3151,6 @@ function bp_send_public_message_button( $args = '' ) {
3358
  *
3359
  * @since 1.2.0
3360
  *
3361
- * @uses bp_get_send_public_message_link()
3362
- * @uses wp_parse_args()
3363
- * @uses bp_get_button()
3364
- * @uses apply_filters() To call the 'bp_get_send_public_message_button' hook.
3365
  *
3366
  * @param array|string $args {
3367
  * All arguments are optional. See {@link BP_Button} for complete
@@ -3373,8 +3162,6 @@ function bp_send_public_message_button( $args = '' ) {
3373
  * @type string $wrapper_id Default: 'post-mention'.
3374
  * @type string $link_href Default: the public message link for
3375
  * the current member in the loop.
3376
- * @type string $link_title Default: 'Send a public message on your
3377
- * activity stream.'.
3378
  * @type string $link_text Default: 'Public Message'.
3379
  * @type string $link_class Default: 'activity-button mention'.
3380
  * }
@@ -3389,7 +3176,6 @@ function bp_send_public_message_button( $args = '' ) {
3389
  'block_self' => true,
3390
  'wrapper_id' => 'post-mention',
3391
  'link_href' => bp_get_send_public_message_link(),
3392
- 'link_title' => __( 'Send a public message on your activity stream.', 'buddypress' ),
3393
  'link_text' => __( 'Public Message', 'buddypress' ),
3394
  'link_class' => 'activity-button mention'
3395
  ) );
@@ -3409,7 +3195,6 @@ function bp_send_public_message_button( $args = '' ) {
3409
  *
3410
  * @since 1.2.0
3411
  *
3412
- * @uses bp_get_activity_post_form_action()
3413
  */
3414
  function bp_activity_post_form_action() {
3415
  echo bp_get_activity_post_form_action();
@@ -3420,9 +3205,6 @@ function bp_activity_post_form_action() {
3420
  *
3421
  * @since 1.2.0
3422
  *
3423
- * @uses home_url()
3424
- * @uses bp_get_activity_root_slug()
3425
- * @uses apply_filters() To call the 'bp_get_activity_post_form_action' hook.
3426
  *
3427
  * @return string The activity post form action.
3428
  */
@@ -3675,7 +3457,6 @@ function bp_activity_types_list( $output = 'select', $args = '' ) {
3675
  *
3676
  * @since 1.0.0
3677
  *
3678
- * @uses bp_get_sitewide_activity_feed_link()
3679
  */
3680
  function bp_sitewide_activity_feed_link() {
3681
  echo bp_get_sitewide_activity_feed_link();
@@ -3686,9 +3467,6 @@ function bp_sitewide_activity_feed_link() {
3686
  *
3687
  * @since 1.0.0
3688
  *
3689
- * @uses home_url()
3690
- * @uses bp_get_activity_root_slug()
3691
- * @uses apply_filters() To call the 'bp_get_sitewide_activity_feed_link' hook.
3692
  *
3693
  * @return string The sitewide activity feed link.
3694
  */
@@ -3709,7 +3487,6 @@ function bp_sitewide_activity_feed_link() {
3709
  *
3710
  * @since 1.2.0
3711
  *
3712
- * @uses bp_get_member_activity_feed_link()
3713
  */
3714
  function bp_member_activity_feed_link() {
3715
  echo bp_get_member_activity_feed_link();
@@ -3723,7 +3500,6 @@ function bp_member_activity_feed_link() {
3723
  *
3724
  * @todo properly deprecate in favor of bp_member_activity_feed_link().
3725
  *
3726
- * @uses bp_get_member_activity_feed_link()
3727
  */
3728
  function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link(); }
3729
 
@@ -3732,14 +3508,6 @@ function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link
3732
  *
3733
  * @since 1.2.0
3734
  *
3735
- * @uses bp_is_profile_component()
3736
- * @uses bp_is_current_action()
3737
- * @uses bp_displayed_user_domain()
3738
- * @uses bp_get_activity_slug()
3739
- * @uses bp_is_active()
3740
- * @uses bp_get_friends_slug()
3741
- * @uses bp_get_groups_slug()
3742
- * @uses apply_filters() To call the 'bp_get_activities_member_rss_link' hook.
3743
  *
3744
  * @return string $link The member activity feed link.
3745
  */
@@ -3788,7 +3556,6 @@ function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link
3788
  *
3789
  * @todo properly deprecate in favor of bp_get_member_activity_feed_link().
3790
  *
3791
- * @uses bp_get_member_activity_feed_link()
3792
  *
3793
  * @return string The member activity feed link.
3794
  */
@@ -3802,7 +3569,6 @@ function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link
3802
  *
3803
  * @since 1.0.0
3804
  *
3805
- * @uses bp_activity_feed_item_guid()
3806
  */
3807
  function bp_activity_feed_item_guid() {
3808
  echo bp_get_activity_feed_item_guid();
@@ -3814,7 +3580,6 @@ function bp_activity_feed_item_guid() {
3814
  * @since 1.2.0
3815
  *
3816
  * @global object $activities_template {@link BP_Activity_Template}
3817
- * @uses apply_filters() To call the 'bp_get_activity_feed_item_guid' hook.
3818
  *
3819
  * @return string The activity feed item guid.
3820
  */
@@ -3836,7 +3601,6 @@ function bp_activity_feed_item_guid() {
3836
  *
3837
  * @since 1.0.0
3838
  *
3839
- * @uses bp_get_activity_feed_item_title()
3840
  */
3841
  function bp_activity_feed_item_title() {
3842
  echo bp_get_activity_feed_item_title();
@@ -3848,10 +3612,6 @@ function bp_activity_feed_item_title() {
3848
  * @since 1.0.0
3849
  *
3850
  * @global object $activities_template {@link BP_Activity_Template}
3851
- * @uses ent2ncr()
3852
- * @uses convert_chars()
3853
- * @uses bp_create_excerpt()
3854
- * @uses apply_filters() To call the 'bp_get_activity_feed_item_title' hook.
3855
  *
3856
  * @return string $title The activity feed item title.
3857
  */
@@ -3890,7 +3650,6 @@ function bp_activity_feed_item_title() {
3890
  *
3891
  * @since 1.0.0
3892
  *
3893
- * @uses bp_get_activity_feed_item_link()
3894
  */
3895
  function bp_activity_feed_item_link() {
3896
  echo bp_get_activity_feed_item_link();
@@ -3902,7 +3661,6 @@ function bp_activity_feed_item_link() {
3902
  * @since 1.0.0
3903
  *
3904
  * @global object $activities_template {@link BP_Activity_Template}
3905
- * @uses apply_filters() To call the 'bp_get_activity_feed_item_link' hook.
3906
  *
3907
  * @return string The activity feed item link.
3908
  */
@@ -3928,7 +3686,6 @@ function bp_activity_feed_item_link() {
3928
  *
3929
  * @since 1.0.0
3930
  *
3931
- * @uses bp_get_activity_feed_item_date()
3932
  */
3933
  function bp_activity_feed_item_date() {
3934
  echo bp_get_activity_feed_item_date();
@@ -3940,7 +3697,6 @@ function bp_activity_feed_item_date() {
3940
  * @since 1.0.0
3941
  *
3942
  * @global object $activities_template {@link BP_Activity_Template}
3943
- * @uses apply_filters() To call the 'bp_get_activity_feed_item_date' hook.
3944
  *
3945
  * @return string The activity feed item date.
3946
  */
@@ -3966,7 +3722,6 @@ function bp_activity_feed_item_date() {
3966
  *
3967
  * @since 1.0.0
3968
  *
3969
- * @uses bp_get_activity_feed_item_description()
3970
  */
3971
  function bp_activity_feed_item_description() {
3972
  echo bp_get_activity_feed_item_description();
@@ -3978,9 +3733,6 @@ function bp_activity_feed_item_description() {
3978
  * @since 1.0.0
3979
  *
3980
  * @global object $activities_template {@link BP_Activity_Template}
3981
- * @uses ent2ncr()
3982
- * @uses convert_chars()
3983
- * @uses apply_filters() To call the 'bp_get_activity_feed_item_description' hook.
3984
  *
3985
  * @return string The activity feed item description.
3986
  */
@@ -4012,8 +3764,6 @@ function bp_activity_feed_item_description() {
4012
  *
4013
  * @since 1.5.0
4014
  *
4015
- * @uses bloginfo()
4016
- * @uses bp_sitewide_activity_feed_link()
4017
  */
4018
  function bp_activity_sitewide_feed() {
4019
  ?>
@@ -4031,7 +3781,6 @@ add_action( 'bp_head', 'bp_activity_sitewide_feed' );
4031
  *
4032
  * @param string $context The current context. 'activity', 'member',
4033
  * 'member_groups', 'group'.
4034
- * @uses bp_get_activity_show_filters()
4035
  */
4036
  function bp_activity_show_filters( $context = '' ) {
4037
  echo bp_get_activity_show_filters( $context );
@@ -4047,45 +3796,15 @@ function bp_activity_show_filters( $context = '' ) {
4047
  * @return string HTML for <option> values.
4048
  */
4049
  function bp_get_activity_show_filters( $context = '' ) {
4050
- // Set default context based on current page.
4051
- if ( empty( $context ) ) {
4052
-
4053
- // On member pages, default to 'member', unless this
4054
- // is a user's Groups activity.
4055
- if ( bp_is_user() ) {
4056
- if ( bp_is_active( 'groups' ) && bp_is_current_action( bp_get_groups_slug() ) ) {
4057
- $context = 'member_groups';
4058
- } else {
4059
- $context = 'member';
4060
- }
4061
-
4062
- // On individual group pages, default to 'group'.
4063
- } elseif ( bp_is_active( 'groups' ) && bp_is_group() ) {
4064
- $context = 'group';
4065
-
4066
- // 'activity' everywhere else.
4067
- } else {
4068
- $context = 'activity';
4069
- }
4070
- }
4071
-
4072
  $filters = array();
4073
-
4074
- // Walk through the registered actions, and prepare an the
4075
- // select box options.
4076
- foreach ( bp_activity_get_actions() as $actions ) {
4077
- foreach ( $actions as $action ) {
4078
- if ( ! in_array( $context, (array) $action['context'] ) ) {
4079
- continue;
4080
- }
4081
-
4082
- // Friends activity collapses two filters into one.
4083
- if ( in_array( $action['key'], array( 'friendship_accepted', 'friendship_created' ) ) ) {
4084
- $action['key'] = 'friendship_accepted,friendship_created';
4085
- }
4086
-
4087
- $filters[ $action['key'] ] = $action['label'];
4088
  }
 
 
4089
  }
4090
 
4091
  /**
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
13
  /**
14
  * Output the activity component slug.
15
  *
16
  * @since 1.5.0
17
  *
 
18
  */
19
  function bp_activity_slug() {
20
  echo bp_get_activity_slug();
24
  *
25
  * @since 1.5.0
26
  *
 
27
  *
28
  * @return string The activity component slug.
29
  */
44
  *
45
  * @since 1.5.0
46
  *
 
47
  */
48
  function bp_activity_root_slug() {
49
  echo bp_get_activity_root_slug();
53
  *
54
  * @since 1.5.0
55
  *
 
56
  *
57
  * @return string The activity component root slug.
58
  */
73
  *
74
  * @since 1.5.0
75
  *
 
76
  */
77
  function bp_activity_directory_permalink() {
78
  echo esc_url( bp_get_activity_directory_permalink() );
82
  *
83
  * @since 1.5.0
84
  *
 
 
 
 
85
  *
86
  * @return string Activity directory permalink.
87
  */
108
  * @since 2.4.0 Introduced the `$fields` parameter.
109
  *
110
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
 
 
 
 
 
 
 
111
  *
112
  * @param array|string $args {
113
  * Arguments for limiting the contents of the activity loop. Most arguments
366
  * @since 1.0.0
367
  *
368
  * @global object $activities_template {@link BP_Activity_Template}
 
369
  *
370
  * @return bool Returns true when activities are found.
371
  */
380
  * @since 1.0.0
381
  *
382
  * @global object $activities_template {@link BP_Activity_Template}
 
383
  *
384
  * @return object The current activity within the loop.
385
  */
427
  * @since 1.0.0
428
  *
429
  * @global object $activities_template {@link BP_Activity_Template}
 
430
  */
431
  function bp_activity_pagination_count() {
432
  echo bp_get_activity_pagination_count();
438
  * @since 1.2.0
439
  *
440
  * @global object $activities_template {@link BP_Activity_Template}
 
441
  *
442
  * @return string The pagination text.
443
  */
463
  *
464
  * @since 1.0.0
465
  *
 
466
  */
467
  function bp_activity_pagination_links() {
468
  echo bp_get_activity_pagination_links();
474
  * @since 1.0.0
475
  *
476
  * @global object $activities_template {@link BP_Activity_Template}
 
477
  *
478
  * @return string The pagination links.
479
  */
496
  * @since 1.5.0
497
  *
498
  * @global object $activities_template {@link BP_Activity_Template}
 
499
  *
500
  * @return bool $has_more_items True if more items, false if not.
501
  */
529
  *
530
  * @since 1.2.0
531
  *
 
532
  */
533
  function bp_activity_count() {
534
  echo bp_get_activity_count();
540
  * @since 1.2.0
541
  *
542
  * @global object $activities_template {@link BP_Activity_Template}
 
543
  *
544
  * @return int The activity count.
545
  */
561
  *
562
  * @since 1.2.0
563
  *
 
564
  */
565
  function bp_activity_per_page() {
566
  echo bp_get_activity_per_page();
572
  * @since 1.2.0
573
  *
574
  * @global object $activities_template {@link BP_Activity_Template}
 
575
  *
576
  * @return int The activities per page.
577
  */
593
  *
594
  * @since 1.0.0
595
  *
 
596
  * @todo Deprecate.
597
  */
598
  function bp_activities_title() {
605
  * @since 1.0.0
606
  *
607
  * @global string $bp_activity_title
 
608
  * @todo Deprecate.
609
  *
610
  * @return string The activities title.
627
  *
628
  * @since 1.0.0
629
  *
 
630
  * @todo Deprecate.
631
  */
632
  function bp_activities_no_activity() {
639
  * @since 1.0.0
640
  *
641
  * @global string $bp_activity_no_activity
 
642
  * @todo Deprecate.
643
  *
644
  * @return string
661
  *
662
  * @since 1.2.0
663
  *
 
664
  */
665
  function bp_activity_id() {
666
  echo bp_get_activity_id();
672
  * @since 1.2.0
673
  *
674
  * @global object $activities_template {@link BP_Activity_Template}
 
675
  *
676
  * @return int The activity ID.
677
  */
693
  *
694
  * @since 1.2.0
695
  *
 
696
  */
697
  function bp_activity_item_id() {
698
  echo bp_get_activity_item_id();
704
  * @since 1.2.0
705
  *
706
  * @global object $activities_template {@link BP_Activity_Template}
 
707
  *
708
  * @return int The activity item ID.
709
  */
725
  *
726
  * @since 1.2.0
727
  *
 
728
  */
729
  function bp_activity_secondary_item_id() {
730
  echo bp_get_activity_secondary_item_id();
736
  * @since 1.2.0
737
  *
738
  * @global object $activities_template {@link BP_Activity_Template}
 
739
  *
740
  * @return int The activity secondary item ID.
741
  */
757
  *
758
  * @since 1.2.0
759
  *
 
760
  */
761
  function bp_activity_date_recorded() {
762
  echo bp_get_activity_date_recorded();
768
  * @since 1.2.0
769
  *
770
  * @global object $activities_template {@link BP_Activity_Template}
 
771
  *
772
  * @return string The date the activity was recorded.
773
  */
789
  *
790
  * @since 2.1.0
791
  *
 
792
  */
793
  function bp_activity_member_display_name() {
794
  echo bp_get_activity_member_display_name();
800
  * @since 2.1.0
801
  *
802
  * @global object $activities_template {@link BP_Activity_Template}
 
803
  *
804
  * @return string The date the activity was recorded.
805
  */
825
  *
826
  * @since 1.2.0
827
  *
 
828
  */
829
  function bp_activity_object_name() {
830
  echo bp_get_activity_object_name();
836
  * @since 1.2.0
837
  *
838
  * @global object $activities_template {@link BP_Activity_Template}
 
839
  *
840
  * @return string The activity object name.
841
  */
857
  *
858
  * @since 1.2.0
859
  *
 
860
  */
861
  function bp_activity_type() {
862
  echo bp_get_activity_type();
868
  * @since 1.2.0
869
  *
870
  * @global object $activities_template {@link BP_Activity_Template}
 
871
  *
872
  * @return string The activity type.
873
  */
895
  * @todo Properly deprecate in favor of bp_activity_type() and
896
  * remove redundant echo
897
  *
 
898
  */
899
  function bp_activity_action_name() { echo bp_activity_type(); }
900
 
908
  *
909
  * @todo Properly deprecate in favor of bp_get_activity_type().
910
  *
 
911
  *
912
  * @return string The activity type.
913
  */
918
  *
919
  * @since 1.1.0
920
  *
 
921
  */
922
  function bp_activity_user_id() {
923
  echo bp_get_activity_user_id();
929
  * @since 1.1.0
930
  *
931
  * @global object $activities_template {@link BP_Activity_Template}
 
932
  *
933
  * @return int The activity user ID.
934
  */
950
  *
951
  * @since 1.2.0
952
  *
 
953
  */
954
  function bp_activity_user_link() {
955
  echo bp_get_activity_user_link();
961
  * @since 1.2.0
962
  *
963
  * @global object $activities_template {@link BP_Activity_Template}
 
 
964
  *
965
  * @return string $link The activity user link.
966
  */
989
  * @since 1.1.0
990
  *
991
  * @see bp_get_activity_avatar() for description of arguments.
 
992
  *
993
  * @param array|string $args See {@link bp_get_activity_avatar()} for description.
994
  */
1002
  *
1003
  * @see bp_core_fetch_avatar() For a description of the arguments.
1004
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
 
 
1005
  *
1006
  * @param array|string $args {
1007
  * Arguments are listed here with an explanation of their defaults.
1097
  *
1098
  * @since 1.1.3
1099
  *
1100
+ * @param array $value HTML image element containing the activity avatar.
1101
  */
1102
  return apply_filters( 'bp_get_activity_avatar', bp_core_fetch_avatar( array(
1103
  'item_id' => $item_id,
1117
  * @since 1.2.0
1118
  *
1119
  * @see bp_get_activity_secondary_avatar() for description of arguments.
 
1120
  *
1121
  * @param array|string $args See {@link bp_get_activity_secondary_avatar} for description.
1122
  */
1131
  *
1132
  * @see bp_core_fetch_avatar() for description of arguments.
1133
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
 
 
1134
  *
1135
  * @param array|string $args {
1136
  * For a complete description of arguments, see {@link bp_core_fetch_avatar()}.
1173
 
1174
  // Only if groups is active.
1175
  if ( bp_is_active( 'groups' ) ) {
1176
+ $group = groups_get_group( $item_id );
 
 
 
 
1177
  $link = bp_get_group_permalink( $group );
1178
  $name = $group->name;
1179
  }
1297
  * @since 1.2.0
1298
  *
1299
  * @param array $args See bp_get_activity_action().
 
1300
  */
1301
  function bp_activity_action( $args = array() ) {
1302
  echo bp_get_activity_action( $args );
1308
  * @since 1.2.0
1309
  *
1310
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
1311
  *
1312
  * @param array $args {
1313
  * @type bool $no_timestamp Whether to exclude the timestamp.
1359
  *
1360
  * @since 1.2.0
1361
  *
 
1362
  */
1363
  function bp_activity_content_body() {
1364
  echo bp_get_activity_content_body();
1370
  * @since 1.2.0
1371
  *
1372
  * @global object $activities_template {@link BP_Activity_Template}
 
 
1373
  *
1374
  * @return string The activity content body.
1375
  */
1386
  *
1387
  * @since 1.2.0
1388
  *
1389
+ * @param string $content Content body.
1390
+ * @param object $activity Activity object. Passed by reference.
1391
  */
1392
  return apply_filters_ref_array( 'bp_get_activity_content_body', array( $activities_template->activity->content, &$activities_template->activity ) );
1393
  }
1419
  *
1420
  * @todo properly deprecate this function.
1421
  *
 
1422
  */
1423
  function bp_activity_content() {
1424
  echo bp_get_activity_content();
1432
  *
1433
  * @todo properly deprecate this function.
1434
  *
 
 
 
1435
  *
1436
  * @return string The activity content.
1437
  */
1456
  * @since 1.2.0
1457
  *
1458
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
 
 
 
1459
  *
1460
  * @param string $content The activity content.
1461
  * @return string The activity content with the metadata string attached.
1469
  // Get the time since this activity was recorded.
1470
  $date_recorded = bp_core_time_since( $activities_template->activity->date_recorded );
1471
 
1472
+ // Set up 'time-since' <span>.
1473
+ $time_since = sprintf(
1474
+ '<span class="time-since" data-livestamp="%1$s">%2$s</span>',
1475
+ bp_core_get_iso8601_date( $activities_template->activity->date_recorded ),
1476
+ $date_recorded
1477
+ );
1478
+
1479
  /**
1480
  * Filters the activity item time since markup.
1481
  *
1484
  * @param array $value Array containing the time since markup and the current activity component.
1485
  */
1486
  $time_since = apply_filters_ref_array( 'bp_activity_time_since', array(
1487
+ $time_since,
1488
  &$activities_template->activity
1489
  ) );
1490
 
1532
  * @since 1.2.0
1533
  *
1534
  * @global object $activities_template {@link BP_Activity_Template}
 
1535
  *
1536
+ * @param BP_Activity_Activity $activity Optional. Falls back on the current item in the loop.
1537
  * @return bool True if can delete, false otherwise.
1538
  */
1539
  function bp_activity_user_can_delete( $activity = false ) {
1563
  // Users are allowed to delete their own activity. This is actually
1564
  // quite powerful, because doing so also deletes all comments to that
1565
  // activity item. We should revisit this eventually.
1566
+ if ( isset( $activity->user_id ) && ( $activity->user_id === bp_loggedin_user_id() ) ) {
1567
  $can_delete = true;
1568
  }
1569
 
1590
  * @since 1.2.0
1591
  *
1592
  * @see bp_get_activity_parent_content() for a description of arguments.
 
1593
  *
1594
  * @param array|string $args See {@link bp_get_activity_parent_content} for description.
1595
  */
1603
  * @since 1.2.0
1604
  *
1605
  * @global object $activities_template {@link BP_Activity_Template}
 
1606
  *
1607
  * @param string $args Unused. Left over from an earlier implementation.
1608
  * @return mixed False on failure, otherwise the activity parent content.
1616
  }
1617
 
1618
  // Get the ID of the parent activity content.
1619
+ $parent_id = $activities_template->activity->item_id;
1620
 
1621
  // Bail if no parent content.
1622
  if ( empty( $activities_template->activity_parents[ $parent_id ] ) ) {
1680
  }
1681
 
1682
  // Get the ID of the parent activity content.
1683
+ $parent_id = $activities_template->activity->item_id;
1684
 
1685
  // Bail if no parent item.
1686
  if ( empty( $activities_template->activity_parents[ $parent_id ] ) ) {
1709
  *
1710
  * @since 1.2.0
1711
  *
 
1712
  */
1713
  function bp_activity_is_favorite() {
1714
  echo bp_get_activity_is_favorite();
1720
  * @since 1.2.0
1721
  *
1722
  * @global object $activities_template {@link BP_Activity_Template}
 
1723
  *
1724
  * @return bool True if user favorite, false otherwise.
1725
  */
1759
  * this function can probably be streamlined or removed.
1760
  *
1761
  * @global object $activities_template {@link BP_Activity_Template}
 
1762
  *
1763
  * @param string $args Unused. Left over from an earlier implementation.
1764
  * @return bool
1782
  * @since 1.2.0
1783
  *
1784
  * @global object $activities_template {@link BP_Activity_Template}
 
1785
  *
1786
  * @param object $comment The activity object currently being recursed.
1787
  * @return bool|string
1841
  * @since 1.5.0
1842
  *
1843
  * @global object $activities_template {@link BP_Activity_Template}
 
1844
  *
1845
  * @return object|bool $current_comment The activity comment currently being
1846
  * displayed. False on failure.
1868
  *
1869
  * @since 1.5.0
1870
  *
 
1871
  */
1872
  function bp_activity_comment_id() {
1873
  echo bp_get_activity_comment_id();
1879
  * @since 1.5.0
1880
  *
1881
  * @global object $activities_template {@link BP_Activity_Template}
 
1882
  *
1883
  * @return int|bool $comment_id The ID of the activity comment currently
1884
  * being displayed, false if none is found.
1903
  *
1904
  * @since 1.5.0
1905
  *
 
1906
  */
1907
  function bp_activity_comment_user_id() {
1908
  echo bp_get_activity_comment_user_id();
1914
  * @since 1.5.0
1915
  *
1916
  * @global object $activities_template {@link BP_Activity_Template}
 
1917
  *
1918
  * @return int|bool $user_id The user_id of the author of the displayed
1919
  * activity comment. False on failure.
1938
  *
1939
  * @since 1.5.0
1940
  *
 
1941
  */
1942
  function bp_activity_comment_user_link() {
1943
  echo bp_get_activity_comment_user_link();
1948
  *
1949
  * @since 1.5.0
1950
  *
 
 
 
1951
  *
1952
  * @return string $user_link The URL of the activity comment author's profile.
1953
  */
1969
  *
1970
  * @since 1.5.0
1971
  *
 
1972
  */
1973
  function bp_activity_comment_name() {
1974
  echo bp_get_activity_comment_name();
1983
  * @since 1.5.0
1984
  *
1985
  * @global object $activities_template {@link BP_Activity_Template}
 
 
1986
  *
1987
  * @return string $name The full name of the activity comment author.
1988
  */
2011
  *
2012
  * @since 1.5.0
2013
  *
 
2014
  */
2015
  function bp_activity_comment_date_recorded() {
2016
  echo bp_get_activity_comment_date_recorded();
2021
  *
2022
  * @since 1.5.0
2023
  *
 
 
2024
  *
2025
  * @return string|bool $date_recorded Time since the activity was recorded,
2026
  * in the form "%s ago". False on failure.
2042
  *
2043
  * @since 2.3.0
2044
  *
 
2045
  */
2046
  function bp_activity_comment_date_recorded_raw() {
2047
  echo bp_get_activity_comment_date_recorded_raw();
2053
  * @since 2.3.0
2054
  *
2055
  * @global object $activities_template {@link BP_Activity_Template}
 
 
2056
  *
2057
  * @return string|bool $date_recorded Time since the activity was recorded,
2058
  * in the form "%s ago". False on failure.
2075
  *
2076
  * @since 1.5.0
2077
  *
 
2078
  */
2079
  function bp_activity_comment_delete_link() {
2080
  echo bp_get_activity_comment_delete_link();
2085
  *
2086
  * @since 1.5.0
2087
  *
 
 
 
 
 
2088
  *
2089
  * @return string $link The nonced URL for deleting the current
2090
  * activity comment.
2091
  */
2092
  function bp_get_activity_comment_delete_link() {
2093
+ $link = wp_nonce_url( bp_get_activity_directory_permalink() . 'delete/' . bp_get_activity_comment_id() . '?cid=' . bp_get_activity_comment_id(), 'bp_activity_delete_link' );
2094
 
2095
  /**
2096
  * Filters the link used for deleting the activity comment currently being displayed.
2107
  *
2108
  * @since 1.5.0
2109
  *
 
2110
  */
2111
  function bp_activity_comment_content() {
2112
  echo bp_get_activity_comment_content();
2123
  * @since 1.5.0
2124
  *
2125
  * @global object $activities_template {@link BP_Activity_Template}
 
 
2126
  *
2127
  * @return string $content The content of the current activity comment.
2128
  */
2147
  *
2148
  * @since 1.2.0
2149
  *
 
2150
  */
2151
  function bp_activity_comment_count() {
2152
  echo bp_activity_get_comment_count();
2158
  * @since 1.2.0
2159
  *
2160
  * @global object $activities_template {@link BP_Activity_Template}
 
 
2161
  *
2162
  * @param array|null $deprecated Deprecated.
2163
  * @return int $count The activity comment count.
2193
  *
2194
  * @since 1.2.0
2195
  *
 
 
2196
  *
2197
  * @param object $comment Activity comment object.
2198
  * @param int $count The current iteration count.
2256
  *
2257
  * @since 1.2.0
2258
  *
 
2259
  */
2260
  function bp_activity_comment_link() {
2261
  echo bp_get_activity_comment_link();
2267
  * @since 1.2.0
2268
  *
2269
  * @global object $activities_template {@link BP_Activity_Template}
 
2270
  *
2271
  * @return string The activity comment link.
2272
  */
2288
  *
2289
  * @since 1.2.0
2290
  *
 
2291
  */
2292
  function bp_activity_comment_form_nojs_display() {
2293
  echo bp_get_activity_comment_form_nojs_display();
2318
  *
2319
  * @since 1.2.0
2320
  *
 
2321
  */
2322
  function bp_activity_comment_form_action() {
2323
  echo bp_get_activity_comment_form_action();
2328
  *
2329
  * @since 1.2.0
2330
  *
 
 
 
2331
  *
2332
  * @return string The activity comment form action.
2333
  */
2348
  *
2349
  * @since 1.2.0
2350
  *
 
2351
  */
2352
  function bp_activity_permalink_id() {
2353
  echo bp_get_activity_permalink_id();
2358
  *
2359
  * @since 1.2.0
2360
  *
 
2361
  *
2362
  * @return string The activity permalink ID.
2363
  */
2378
  *
2379
  * @since 1.2.0
2380
  *
 
2381
  */
2382
  function bp_activity_thread_permalink() {
2383
+ echo esc_url( bp_get_activity_thread_permalink() );
2384
  }
2385
 
2386
  /**
2388
  *
2389
  * @since 1.2.0
2390
  *
 
 
2391
  *
2392
  * @return string $link The activity thread permalink.
2393
  */
2411
  *
2412
  * @since 1.8.0
2413
  *
 
2414
  */
2415
  function bp_activity_comment_permalink() {
2416
+ echo esc_url( bp_get_activity_comment_permalink() );
2417
  }
2418
  /**
2419
  * Return the activity comment permalink.
2420
  *
2421
  * @since 1.8.0
2422
  *
 
 
 
2423
  * @return string $link The activity comment permalink.
2424
  */
2425
  function bp_get_activity_comment_permalink() {
2426
  global $activities_template;
2427
 
2428
+ $link = bp_activity_get_permalink( $activities_template->activity->id, $activities_template->activity );
2429
+
2430
+ // Used for filter below.
2431
  $comment_id = isset( $activities_template->activity->current_comment->id )
2432
  ? $activities_template->activity->current_comment->id
2433
  : 0;
2434
 
 
 
 
 
 
 
 
 
2435
  /**
2436
  * Filters the activity comment permalink.
2437
  *
2448
  *
2449
  * @since 1.2.0
2450
  *
 
2451
  */
2452
  function bp_activity_favorite_link() {
2453
  echo bp_get_activity_favorite_link();
2459
  * @since 1.2.0
2460
  *
2461
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
2462
  *
2463
  * @return string The activity favorite link.
2464
  */
2480
  *
2481
  * @since 1.2.0
2482
  *
 
2483
  */
2484
  function bp_activity_unfavorite_link() {
2485
  echo bp_get_activity_unfavorite_link();
2491
  * @since 1.2.0
2492
  *
2493
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
2494
  *
2495
  * @return string The activity unfavorite link.
2496
  */
2512
  *
2513
  * @since 1.0.0
2514
  *
 
2515
  */
2516
  function bp_activity_css_class() {
2517
  echo bp_get_activity_css_class();
2523
  * @since 1.0.0
2524
  *
2525
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
2526
  *
2527
  * @return string The activity item's CSS class.
2528
  */
2570
  *
2571
  * @since 1.1.0
2572
  *
 
2573
  */
2574
  function bp_activity_delete_link() {
2575
  echo bp_get_activity_delete_link();
2581
  * @since 1.1.0
2582
  *
2583
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
 
 
 
2584
  *
2585
  * @return string $link Activity delete link. Contains $redirect_to arg
2586
  * if on single activity page.
2612
  *
2613
  * @since 2.1.0
2614
  *
 
2615
  */
2616
  function bp_activity_delete_url() {
2617
  echo esc_url( bp_get_activity_delete_url() );
2622
  * @since 2.1.0
2623
  *
2624
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
 
 
 
 
2625
  *
2626
  * @return string $link Activity delete link. Contains $redirect_to arg
2627
  * if on single activity page.
2654
  * @since 1.2.0
2655
  *
2656
  * @see bp_get_activity_latest_update() for description of parameters.
 
2657
  *
2658
  * @param int $user_id See {@link bp_get_activity_latest_update()} for description.
2659
  */
2666
  *
2667
  * @since 1.2.0
2668
  *
 
 
 
 
 
 
 
 
2669
  *
2670
  * @param int $user_id If empty, will fall back on displayed user.
2671
  * @return string|bool $latest_update The activity latest update link.
2689
  * Filters the latest update excerpt.
2690
  *
2691
  * @since 1.2.10
2692
+ * @since 2.6.0 Added the `$user_id` parameter.
2693
  *
2694
+ * @param string $value The excerpt for the latest update.
2695
+ * @param int $user_id ID of the queried user.
2696
  */
2697
+ $latest_update = apply_filters( 'bp_get_activity_latest_update_excerpt', trim( strip_tags( bp_create_excerpt( $update['content'], bp_activity_get_excerpt_length() ) ) ), $user_id );
2698
 
2699
  $latest_update = sprintf(
2700
  '%s <a href="%s">%s</a>',
2707
  * Filters the latest update excerpt with view link appended to the end.
2708
  *
2709
  * @since 1.2.0
2710
+ * @since 2.6.0 Added the `$user_id` parameter.
2711
  *
2712
  * @param string $latest_update The latest update with "view" link appended to it.
2713
+ * @param int $user_id ID of the queried user.
2714
  */
2715
+ return apply_filters( 'bp_get_activity_latest_update', $latest_update, $user_id );
2716
  }
2717
 
2718
  /**
2721
  * @since 1.1.0
2722
  *
2723
  * @see bp_get_activity_filter_links() for description of parameters.
 
2724
  *
2725
  * @param array|bool $args See {@link bp_get_activity_filter_links()} for description.
2726
  */
2733
  *
2734
  * @since 1.1.0
2735
  *
 
 
 
 
 
 
 
2736
  *
2737
  * @param array|bool $args {
2738
  * @type string $style The type of markup to use for the links.
2816
  * Filters all of the constructed filter links.
2817
  *
2818
  * @since 1.1.0
2819
+ * @since 2.6.0 Added the `$r` parameter.
2820
  *
2821
  * @param string $value All of the links to be displayed to the user.
2822
+ * @param array $r Array of parsed arguments.
2823
  */
2824
+ return apply_filters( 'bp_get_activity_filter_links', implode( "\n", $component_links ), $r );
2825
  }
2826
 
2827
  /**
2830
  * @since 1.2.0
2831
  *
2832
  * @global object $activities_template {@link BP_Activity_Template}
 
 
2833
  *
2834
  * @return bool $can_comment True if item can receive comments.
2835
  */
2914
  *
2915
  * @since 1.5.0
2916
  *
 
 
2917
  * @return bool True if comment can receive comments.
2918
  */
2919
  function bp_activity_can_favorite() {
2934
  * @since 1.2.0
2935
  *
2936
  * @see bp_get_total_favorite_count_for_user() for description of parameters.
 
2937
  *
2938
  * @param int $user_id See {@link bp_get_total_favorite_count_for_user()}.
2939
  */
2946
  *
2947
  * @since 1.2.0
2948
  *
 
 
2949
  *
2950
  * @param int $user_id ID of user being queried. Default: displayed user ID.
2951
  * @return int The total favorite count for the specified user.
2969
  * Filters the total favorite count for a user.
2970
  *
2971
  * @since 1.2.0
2972
+ * @since 2.6.0 Added the `$user_id` parameter.
2973
  *
2974
+ * @param int|bool $retval Total favorite count for a user. False on no favorites.
2975
+ * @param int $user_id ID of the queried user.
2976
  */
2977
+ return apply_filters( 'bp_get_total_favorite_count_for_user', $retval, $user_id );
2978
  }
2979
 
2980
 
2984
  * @since 1.2.0
2985
  *
2986
  * @see bp_get_total_mention_count_for_user() for description of parameters.
 
2987
  *
2988
  * @param int $user_id See {@link bp_get_total_mention_count_for_user()}.
2989
  */
2996
  *
2997
  * @since 1.2.0
2998
  *
 
 
2999
  *
3000
  * @param int $user_id ID of user being queried. Default: displayed user ID.
3001
  * @return int The total mention count for the specified user.
3016
  * Filters the total mention count for a user.
3017
  *
3018
  * @since 1.2.0
3019
+ * @since 2.6.0 Added the `$user_id` parameter.
3020
  *
3021
+ * @param int|bool $retval Total mention count for a user. False on no mentions.
3022
+ * @param int $user_id ID of the queried user.
3023
  */
3024
+ return apply_filters( 'bp_get_total_mention_count_for_user', $retval, $user_id );
3025
  }
3026
 
3027
  /**
3029
  *
3030
  * @since 1.2.0
3031
  *
 
3032
  */
3033
  function bp_send_public_message_link() {
3034
  echo esc_url( bp_get_send_public_message_link() );
3039
  *
3040
  * @since 1.2.0
3041
  *
 
 
 
 
 
 
3042
  *
3043
  * @return string The public message link for the displayed user.
3044
  */
3096
  * @since 1.2.0
3097
  *
3098
  * @see bp_get_mentioned_user_display_name() for description of parameters.
 
3099
  *
3100
  * @param int|string|bool $user_id_or_username See {@link bp_get_mentioned_user_display_name()}.
3101
  */
3108
  *
3109
  * @since 1.2.0
3110
  *
 
 
3111
  *
3112
  * @param int|string|bool $user_id_or_username User ID or username.
3113
  * @return string The mentioned user's display name.
3139
  * @since 1.2.0
3140
  *
3141
  * @see bp_get_send_public_message_button() for description of parameters.
 
3142
  *
3143
  * @param array|string $args See {@link bp_get_send_public_message_button()}.
3144
  */
3151
  *
3152
  * @since 1.2.0
3153
  *
 
 
 
 
3154
  *
3155
  * @param array|string $args {
3156
  * All arguments are optional. See {@link BP_Button} for complete
3162
  * @type string $wrapper_id Default: 'post-mention'.
3163
  * @type string $link_href Default: the public message link for
3164
  * the current member in the loop.
 
 
3165
  * @type string $link_text Default: 'Public Message'.
3166
  * @type string $link_class Default: 'activity-button mention'.
3167
  * }
3176
  'block_self' => true,
3177
  'wrapper_id' => 'post-mention',
3178
  'link_href' => bp_get_send_public_message_link(),
 
3179
  'link_text' => __( 'Public Message', 'buddypress' ),
3180
  'link_class' => 'activity-button mention'
3181
  ) );
3195
  *
3196
  * @since 1.2.0
3197
  *
 
3198
  */
3199
  function bp_activity_post_form_action() {
3200
  echo bp_get_activity_post_form_action();
3205
  *
3206
  * @since 1.2.0
3207
  *
 
 
 
3208
  *
3209
  * @return string The activity post form action.
3210
  */
3457
  *
3458
  * @since 1.0.0
3459
  *
 
3460
  */
3461
  function bp_sitewide_activity_feed_link() {
3462
  echo bp_get_sitewide_activity_feed_link();
3467
  *
3468
  * @since 1.0.0
3469
  *
 
 
 
3470
  *
3471
  * @return string The sitewide activity feed link.
3472
  */
3487
  *
3488
  * @since 1.2.0
3489
  *
 
3490
  */
3491
  function bp_member_activity_feed_link() {
3492
  echo bp_get_member_activity_feed_link();
3500
  *
3501
  * @todo properly deprecate in favor of bp_member_activity_feed_link().
3502
  *
 
3503
  */
3504
  function bp_activities_member_rss_link() { echo bp_get_member_activity_feed_link(); }
3505
 
3508
  *
3509
  * @since 1.2.0
3510
  *
 
 
 
 
 
 
 
 
3511
  *
3512
  * @return string $link The member activity feed link.
3513
  */
3556
  *
3557
  * @todo properly deprecate in favor of bp_get_member_activity_feed_link().
3558
  *
 
3559
  *
3560
  * @return string The member activity feed link.
3561
  */
3569
  *
3570
  * @since 1.0.0
3571
  *
 
3572
  */
3573
  function bp_activity_feed_item_guid() {
3574
  echo bp_get_activity_feed_item_guid();
3580
  * @since 1.2.0
3581
  *
3582
  * @global object $activities_template {@link BP_Activity_Template}
 
3583
  *
3584
  * @return string The activity feed item guid.
3585
  */
3601
  *
3602
  * @since 1.0.0
3603
  *
 
3604
  */
3605
  function bp_activity_feed_item_title() {
3606
  echo bp_get_activity_feed_item_title();
3612
  * @since 1.0.0
3613
  *
3614
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
 
3615
  *
3616
  * @return string $title The activity feed item title.
3617
  */
3650
  *
3651
  * @since 1.0.0
3652
  *
 
3653
  */
3654
  function bp_activity_feed_item_link() {
3655
  echo bp_get_activity_feed_item_link();
3661
  * @since 1.0.0
3662
  *
3663
  * @global object $activities_template {@link BP_Activity_Template}
 
3664
  *
3665
  * @return string The activity feed item link.
3666
  */
3686
  *
3687
  * @since 1.0.0
3688
  *
 
3689
  */
3690
  function bp_activity_feed_item_date() {
3691
  echo bp_get_activity_feed_item_date();
3697
  * @since 1.0.0
3698
  *
3699
  * @global object $activities_template {@link BP_Activity_Template}
 
3700
  *
3701
  * @return string The activity feed item date.
3702
  */
3722
  *
3723
  * @since 1.0.0
3724
  *
 
3725
  */
3726
  function bp_activity_feed_item_description() {
3727
  echo bp_get_activity_feed_item_description();
3733
  * @since 1.0.0
3734
  *
3735
  * @global object $activities_template {@link BP_Activity_Template}
 
 
 
3736
  *
3737
  * @return string The activity feed item description.
3738
  */
3764
  *
3765
  * @since 1.5.0
3766
  *
 
 
3767
  */
3768
  function bp_activity_sitewide_feed() {
3769
  ?>
3781
  *
3782
  * @param string $context The current context. 'activity', 'member',
3783
  * 'member_groups', 'group'.
 
3784
  */
3785
  function bp_activity_show_filters( $context = '' ) {
3786
  echo bp_get_activity_show_filters( $context );
3796
  * @return string HTML for <option> values.
3797
  */
3798
  function bp_get_activity_show_filters( $context = '' ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3799
  $filters = array();
3800
+ $actions = bp_activity_get_actions_for_context( $context );
3801
+ foreach ( $actions as $action ) {
3802
+ // Friends activity collapses two filters into one.
3803
+ if ( in_array( $action['key'], array( 'friendship_accepted', 'friendship_created' ) ) ) {
3804
+ $action['key'] = 'friendship_accepted,friendship_created';
 
 
 
 
 
 
 
 
 
 
3805
  }
3806
+
3807
+ $filters[ $action['key'] ] = $action['label'];
3808
  }
3809
 
3810
  /**
bp-activity/classes/class-bp-activity-activity.php CHANGED
@@ -107,7 +107,7 @@ class BP_Activity_Activity {
107
  * @since 1.1.0
108
  * @var int
109
  */
110
- var $hide_sitewide = false;
111
 
112
  /**
113
  * Node boundary start for activity or activity comment.
@@ -133,6 +133,24 @@ class BP_Activity_Activity {
133
  */
134
  var $is_spam;
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  /**
137
  * Constructor method.
138
  *
@@ -141,8 +159,11 @@ class BP_Activity_Activity {
141
  * @param int|bool $id Optional. The ID of a specific activity item.
142
  */
143
  public function __construct( $id = false ) {
 
 
 
144
  if ( !empty( $id ) ) {
145
- $this->id = $id;
146
  $this->populate();
147
  }
148
  }
@@ -164,23 +185,26 @@ class BP_Activity_Activity {
164
  wp_cache_set( $this->id, $row, 'bp_activity' );
165
  }
166
 
167
- if ( ! empty( $row ) ) {
168
- $this->id = (int) $row->id;
169
- $this->item_id = (int) $row->item_id;
170
- $this->secondary_item_id = (int) $row->secondary_item_id;
171
- $this->user_id = (int) $row->user_id;
172
- $this->primary_link = $row->primary_link;
173
- $this->component = $row->component;
174
- $this->type = $row->type;
175
- $this->action = $row->action;
176
- $this->content = $row->content;
177
- $this->date_recorded = $row->date_recorded;
178
- $this->hide_sitewide = $row->hide_sitewide;
179
- $this->mptt_left = (int) $row->mptt_left;
180
- $this->mptt_right = (int) $row->mptt_right;
181
- $this->is_spam = $row->is_spam;
182
  }
183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  // Generate dynamic 'action' when possible.
185
  $action = bp_activity_generate_action_string( $this );
186
  if ( false !== $action ) {
@@ -235,8 +259,22 @@ class BP_Activity_Activity {
235
  */
236
  do_action_ref_array( 'bp_activity_before_save', array( &$this ) );
237
 
 
 
 
 
238
  if ( empty( $this->component ) || empty( $this->type ) ) {
239
- return false;
 
 
 
 
 
 
 
 
 
 
240
  }
241
 
242
  if ( empty( $this->primary_link ) ) {
@@ -338,8 +376,7 @@ class BP_Activity_Activity {
338
  10 => 'spam'
339
  );
340
 
341
- $func_args = func_get_args();
342
- $args = bp_core_parse_args_array( $old_args_keys, $func_args );
343
  }
344
 
345
  $bp = buddypress();
@@ -388,7 +425,7 @@ class BP_Activity_Activity {
388
 
389
  // Override some arguments if needed.
390
  if ( ! empty( $scope_query['override'] ) ) {
391
- $r = self::array_replace_recursive( $r, $scope_query['override'] );
392
  }
393
 
394
  // Advanced filtering.
@@ -578,6 +615,18 @@ class BP_Activity_Activity {
578
  $activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}, a.id {$sort}", $select_sql, $from_sql, $where_sql, $sort, $pag_sql ) );
579
  }
580
 
 
 
 
 
 
 
 
 
 
 
 
 
581
  } else {
582
  // Query first for activity IDs.
583
  $activity_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}, a.id {$sort}";
@@ -598,7 +647,23 @@ class BP_Activity_Activity {
598
  */
599
  $activity_ids_sql = apply_filters( 'bp_activity_paged_activities_sql', $activity_ids_sql, $r );
600
 
601
- $activity_ids = $wpdb->get_col( $activity_ids_sql );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
 
603
  $retval['has_more_items'] = ! empty( $per_page ) && count( $activity_ids ) > $per_page;
604
 
@@ -655,7 +720,13 @@ class BP_Activity_Activity {
655
  * @param string $sort Sort direction for query.
656
  */
657
  $total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$join_sql} {$where_sql}", $where_sql, $sort );
658
- $total_activities = $wpdb->get_var( $total_activities_sql );
 
 
 
 
 
 
659
 
660
  if ( !empty( $r['max'] ) ) {
661
  if ( (int) $total_activities > (int) $r['max'] ) {
@@ -708,7 +779,20 @@ class BP_Activity_Activity {
708
 
709
  // Now fetch data from the cache.
710
  foreach ( $activity_ids as $activity_id ) {
711
- $activities[] = wp_cache_get( $activity_id, 'bp_activity' );
 
 
 
 
 
 
 
 
 
 
 
 
 
712
  }
713
 
714
  // Then fetch user data.
@@ -1071,7 +1155,9 @@ class BP_Activity_Activity {
1071
 
1072
  if ( ! empty( $where_args ) ) {
1073
  $where_sql = 'WHERE ' . join( ' AND ', $where_args );
1074
- return $wpdb->get_var( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
 
 
1075
  }
1076
 
1077
  return false;
@@ -1387,7 +1473,6 @@ class BP_Activity_Activity {
1387
  }
1388
 
1389
  // Legacy query - not recommended.
1390
- $func_args = func_get_args();
1391
 
1392
  /**
1393
  * Filters if BuddyPress should use the legacy activity query.
@@ -1398,7 +1483,7 @@ class BP_Activity_Activity {
1398
  * @param BP_Activity_Activity $value Magic method referring to currently called method.
1399
  * @param array $func_args Array of the method's argument list.
1400
  */
1401
- if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $func_args ) ) {
1402
 
1403
  /**
1404
  * Filters the MySQL prepared statement for the legacy activity query.
@@ -1763,7 +1848,9 @@ class BP_Activity_Activity {
1763
 
1764
  $bp = buddypress();
1765
 
1766
- return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE content = %s", $content ) );
 
 
1767
  }
1768
 
1769
  /**
@@ -1781,57 +1868,4 @@ class BP_Activity_Activity {
1781
 
1782
  return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) );
1783
  }
1784
-
1785
- /**
1786
- * PHP-agnostic version of {@link array_replace_recursive()}.
1787
- *
1788
- * The array_replace_recursive() function is a PHP 5.3 function. BuddyPress (and
1789
- * WordPress) currently supports down to PHP 5.2, so this method is a workaround
1790
- * for PHP 5.2.
1791
- *
1792
- * Note: array_replace_recursive() supports infinite arguments, but for our use-
1793
- * case, we only need to support two arguments.
1794
- *
1795
- * Subject to removal once WordPress makes PHP 5.3.0 the minimum requirement.
1796
- *
1797
- * @since 2.2.0
1798
- *
1799
- * @see http://php.net/manual/en/function.array-replace-recursive.php#109390
1800
- *
1801
- * @param array $base Array with keys needing to be replaced.
1802
- * @param array $replacements Array with the replaced keys.
1803
- * @return array
1804
- */
1805
- protected static function array_replace_recursive( $base = array(), $replacements = array() ) {
1806
- if ( function_exists( 'array_replace_recursive' ) ) {
1807
- return array_replace_recursive( $base, $replacements );
1808
- }
1809
-
1810
- // PHP 5.2-compatible version
1811
- // http://php.net/manual/en/function.array-replace-recursive.php#109390.
1812
- foreach ( array_slice( func_get_args(), 1 ) as $replacements ) {
1813
- $bref_stack = array( &$base );
1814
- $head_stack = array( $replacements );
1815
-
1816
- do {
1817
- end( $bref_stack );
1818
-
1819
- $bref = &$bref_stack[ key( $bref_stack ) ];
1820
- $head = array_pop( $head_stack );
1821
-
1822
- unset( $bref_stack[ key($bref_stack) ] );
1823
-
1824
- foreach ( array_keys( $head ) as $key ) {
1825
- if ( isset( $key, $bref ) && is_array( $bref[$key] ) && is_array( $head[$key] ) ) {
1826
- $bref_stack[] = &$bref[ $key ];
1827
- $head_stack[] = $head[ $key ];
1828
- } else {
1829
- $bref[ $key ] = $head[ $key ];
1830
- }
1831
- }
1832
- } while( count( $head_stack ) );
1833
- }
1834
-
1835
- return $base;
1836
- }
1837
  }
107
  * @since 1.1.0
108
  * @var int
109
  */
110
+ var $hide_sitewide = 0;
111
 
112
  /**
113
  * Node boundary start for activity or activity comment.
133
  */
134
  var $is_spam;
135
 
136
+ /**
137
+ * Error holder.
138
+ *
139
+ * @since 2.6.0
140
+ *
141
+ * @var WP_Error
142
+ */
143
+ public $errors;
144
+
145
+ /**
146
+ * Error type to return. Either 'bool' or 'wp_error'.
147
+ *
148
+ * @since 2.6.0
149
+ *
150
+ * @var string
151
+ */
152
+ public $error_type = 'bool';
153
+
154
  /**
155
  * Constructor method.
156
  *
159
  * @param int|bool $id Optional. The ID of a specific activity item.
160
  */
161
  public function __construct( $id = false ) {
162
+ // Instantiate errors object.
163
+ $this->errors = new WP_Error;
164
+
165
  if ( !empty( $id ) ) {
166
+ $this->id = (int) $id;
167
  $this->populate();
168
  }
169
  }
185
  wp_cache_set( $this->id, $row, 'bp_activity' );
186
  }
187
 
188
+ if ( empty( $row ) ) {
189
+ $this->id = 0;
190
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
191
  }
192
 
193
+ $this->id = (int) $row->id;
194
+ $this->item_id = (int) $row->item_id;
195
+ $this->secondary_item_id = (int) $row->secondary_item_id;
196
+ $this->user_id = (int) $row->user_id;
197
+ $this->primary_link = $row->primary_link;
198
+ $this->component = $row->component;
199
+ $this->type = $row->type;
200
+ $this->action = $row->action;
201
+ $this->content = $row->content;
202
+ $this->date_recorded = $row->date_recorded;
203
+ $this->hide_sitewide = (int) $row->hide_sitewide;
204
+ $this->mptt_left = (int) $row->mptt_left;
205
+ $this->mptt_right = (int) $row->mptt_right;
206
+ $this->is_spam = (int) $row->is_spam;
207
+
208
  // Generate dynamic 'action' when possible.
209
  $action = bp_activity_generate_action_string( $this );
210
  if ( false !== $action ) {
259
  */
260
  do_action_ref_array( 'bp_activity_before_save', array( &$this ) );
261
 
262
+ if ( 'wp_error' === $this->error_type && $this->errors->get_error_code() ) {
263
+ return $this->errors;
264
+ }
265
+
266
  if ( empty( $this->component ) || empty( $this->type ) ) {
267
+ if ( 'bool' === $this->error_type ) {
268
+ return false;
269
+ } else {
270
+ if ( empty( $this->component ) ) {
271
+ $this->errors->add( 'bp_activity_missing_component' );
272
+ } else {
273
+ $this->errors->add( 'bp_activity_missing_type' );
274
+ }
275
+
276
+ return $this->errors;
277
+ }
278
  }
279
 
280
  if ( empty( $this->primary_link ) ) {
376
  10 => 'spam'
377
  );
378
 
379
+ $args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
 
380
  }
381
 
382
  $bp = buddypress();
425
 
426
  // Override some arguments if needed.
427
  if ( ! empty( $scope_query['override'] ) ) {
428
+ $r = array_replace_recursive( $r, $scope_query['override'] );
429
  }
430
 
431
  // Advanced filtering.
615
  $activities = $wpdb->get_results( apply_filters( 'bp_activity_get_user_join_filter', "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}, a.id {$sort}", $select_sql, $from_sql, $where_sql, $sort, $pag_sql ) );
616
  }
617
 
618
+ // Integer casting for legacy activity query.
619
+ foreach ( (array) $activities as $i => $ac ) {
620
+ $activities[ $i ]->id = (int) $ac->id;
621
+ $activities[ $i ]->item_id = (int) $ac->item_id;
622
+ $activities[ $i ]->secondary_item_id = (int) $ac->secondary_item_id;
623
+ $activities[ $i ]->user_id = (int) $ac->user_id;
624
+ $activities[ $i ]->hide_sitewide = (int) $ac->hide_sitewide;
625
+ $activities[ $i ]->mptt_left = (int) $ac->mptt_left;
626
+ $activities[ $i ]->mptt_right = (int) $ac->mptt_right;
627
+ $activities[ $i ]->is_spam = (int) $ac->is_spam;
628
+ }
629
+
630
  } else {
631
  // Query first for activity IDs.
632
  $activity_ids_sql = "{$select_sql} {$from_sql} {$join_sql} {$where_sql} ORDER BY a.date_recorded {$sort}, a.id {$sort}";
647
  */
648
  $activity_ids_sql = apply_filters( 'bp_activity_paged_activities_sql', $activity_ids_sql, $r );
649
 
650
+ /*
651
+ * Queries that include 'last_activity' are cached separately,
652
+ * since they are generally much less long-lived.
653
+ */
654
+ if ( preg_match( '/a\.type NOT IN \([^\)]*\'last_activity\'[^\)]*\)/', $activity_ids_sql ) ) {
655
+ $cache_group = 'bp_activity';
656
+ } else {
657
+ $cache_group = 'bp_activity_with_last_activity';
658
+ }
659
+
660
+ $cached = bp_core_get_incremented_cache( $activity_ids_sql, $cache_group );
661
+ if ( false === $cached ) {
662
+ $activity_ids = $wpdb->get_col( $activity_ids_sql );
663
+ bp_core_set_incremented_cache( $activity_ids_sql, $cache_group, $activity_ids );
664
+ } else {
665
+ $activity_ids = $cached;
666
+ }
667
 
668
  $retval['has_more_items'] = ! empty( $per_page ) && count( $activity_ids ) > $per_page;
669
 
720
  * @param string $sort Sort direction for query.
721
  */
722
  $total_activities_sql = apply_filters( 'bp_activity_total_activities_sql', "SELECT count(DISTINCT a.id) FROM {$bp->activity->table_name} a {$join_sql} {$where_sql}", $where_sql, $sort );
723
+ $cached = bp_core_get_incremented_cache( $total_activities_sql, $cache_group );
724
+ if ( false === $cached ) {
725
+ $total_activities = $wpdb->get_var( $total_activities_sql );
726
+ bp_core_set_incremented_cache( $total_activities_sql, $cache_group, $total_activities );
727
+ } else {
728
+ $total_activities = $cached;
729
+ }
730
 
731
  if ( !empty( $r['max'] ) ) {
732
  if ( (int) $total_activities > (int) $r['max'] ) {
779
 
780
  // Now fetch data from the cache.
781
  foreach ( $activity_ids as $activity_id ) {
782
+ // Integer casting.
783
+ $activity = wp_cache_get( $activity_id, 'bp_activity' );
784
+ if ( ! empty( $activity ) ) {
785
+ $activity->id = (int) $activity->id;
786
+ $activity->user_id = (int) $activity->user_id;
787
+ $activity->item_id = (int) $activity->item_id;
788
+ $activity->secondary_item_id = (int) $activity->secondary_item_id;
789
+ $activity->hide_sitewide = (int) $activity->hide_sitewide;
790
+ $activity->mptt_left = (int) $activity->mptt_left;
791
+ $activity->mptt_right = (int) $activity->mptt_right;
792
+ $activity->is_spam = (int) $activity->is_spam;
793
+ }
794
+
795
+ $activities[] = $activity;
796
  }
797
 
798
  // Then fetch user data.
1155
 
1156
  if ( ! empty( $where_args ) ) {
1157
  $where_sql = 'WHERE ' . join( ' AND ', $where_args );
1158
+ $result = $wpdb->get_var( "SELECT id FROM {$bp->activity->table_name} {$where_sql}" );
1159
+
1160
+ return is_numeric( $result ) ? (int) $result : false;
1161
  }
1162
 
1163
  return false;
1473
  }
1474
 
1475
  // Legacy query - not recommended.
 
1476
 
1477
  /**
1478
  * Filters if BuddyPress should use the legacy activity query.
1483
  * @param BP_Activity_Activity $value Magic method referring to currently called method.
1484
  * @param array $func_args Array of the method's argument list.
1485
  */
1486
+ if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, func_get_args() ) ) {
1487
 
1488
  /**
1489
  * Filters the MySQL prepared statement for the legacy activity query.
1848
 
1849
  $bp = buddypress();
1850
 
1851
+ $result = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->activity->table_name} WHERE content = %s", $content ) );
1852
+
1853
+ return is_numeric( $result ) ? (int) $result : false;
1854
  }
1855
 
1856
  /**
1868
 
1869
  return $wpdb->get_var( $wpdb->prepare( "UPDATE {$bp->activity->table_name} SET hide_sitewide = 1 WHERE user_id = %d", $user_id ) );
1870
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1871
  }
bp-activity/classes/class-bp-activity-component.php CHANGED
@@ -32,6 +32,7 @@ class BP_Activity_Component extends BP_Component {
32
  array(
33
  'adminbar_myaccount_order' => 10,
34
  'search_query_arg' => 'activity_search',
 
35
  )
36
  );
37
  }
@@ -53,21 +54,30 @@ class BP_Activity_Component extends BP_Component {
53
  'actions',
54
  'screens',
55
  'filters',
56
- 'classes',
57
  'template',
58
  'functions',
59
- 'notifications',
60
  'cache'
61
  );
62
 
 
 
 
 
 
63
  // Load Akismet support if Akismet is configured.
64
  $akismet_key = bp_get_option( 'wordpress_api_key' );
65
 
66
- /** This filter is documented in bp-activity/bp-activity-actions.php */
67
  if ( defined( 'AKISMET_VERSION' ) && class_exists( 'Akismet' ) && ( ! empty( $akismet_key ) || defined( 'WPCOM_API_KEY' ) ) && apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) ) {
68
  $includes[] = 'akismet';
69
  }
70
 
 
 
 
 
 
71
  if ( is_admin() ) {
72
  $includes[] = 'admin';
73
  }
@@ -106,13 +116,17 @@ class BP_Activity_Component extends BP_Component {
106
  'activity' => $bp->table_prefix . 'bp_activity_meta',
107
  );
108
 
 
 
 
 
109
  // All globals for activity component.
110
  // Note that global_tables is included in this array.
111
  $args = array(
112
  'slug' => BP_ACTIVITY_SLUG,
113
  'root_slug' => isset( $bp->pages->activity->slug ) ? $bp->pages->activity->slug : BP_ACTIVITY_SLUG,
114
  'has_directory' => true,
115
- 'directory_title' => _x( 'Site-Wide Activity', 'component directory title', 'buddypress' ),
116
  'notification_callback' => 'bp_activity_format_notifications',
117
  'search_string' => __( 'Search Activity...', 'buddypress' ),
118
  'global_tables' => $global_tables,
@@ -128,10 +142,6 @@ class BP_Activity_Component extends BP_Component {
128
  * @since 1.5.0
129
  *
130
  * @see BP_Component::setup_nav() for a description of arguments.
131
- * @uses bp_is_active()
132
- * @uses is_user_logged_in()
133
- * @uses bp_get_friends_slug()
134
- * @uses bp_get_groups_slug()
135
  *
136
  * @param array $main_nav Optional. See BP_Component::setup_nav() for description.
137
  * @param array $sub_nav Optional. See BP_Component::setup_nav() for description.
@@ -237,13 +247,6 @@ class BP_Activity_Component extends BP_Component {
237
  *
238
  * @see BP_Component::setup_nav() for a description of the $wp_admin_nav
239
  * parameter array.
240
- * @uses is_user_logged_in()
241
- * @uses trailingslashit()
242
- * @uses bp_get_total_mention_count_for_user()
243
- * @uses bp_loggedin_user_id()
244
- * @uses bp_is_active()
245
- * @uses bp_get_friends_slug()
246
- * @uses bp_get_groups_slug()
247
  *
248
  * @param array $wp_admin_nav See BP_Component::setup_admin_bar() for a
249
  * description.
@@ -260,7 +263,11 @@ class BP_Activity_Component extends BP_Component {
260
  if ( bp_activity_do_mentions() ) {
261
  $count = bp_get_total_mention_count_for_user( bp_loggedin_user_id() );
262
  if ( !empty( $count ) ) {
263
- $title = sprintf( _x( 'Mentions <span class="count">%s</span>', 'Toolbar Mention logged in user', 'buddypress' ), bp_core_number_format( $count ) );
 
 
 
 
264
  } else {
265
  $title = _x( 'Mentions', 'Toolbar Mention logged in user', 'buddypress' );
266
  }
@@ -336,9 +343,6 @@ class BP_Activity_Component extends BP_Component {
336
  *
337
  * @since 1.5.0
338
  *
339
- * @uses bp_is_activity_component()
340
- * @uses bp_is_my_profile()
341
- * @uses bp_core_fetch_avatar()
342
  */
343
  public function setup_title() {
344
 
@@ -361,19 +365,6 @@ class BP_Activity_Component extends BP_Component {
361
  parent::setup_title();
362
  }
363
 
364
- /**
365
- * Set up actions necessary for the component.
366
- *
367
- * @since 1.6.0
368
- */
369
- public function setup_actions() {
370
-
371
- // Spam prevention.
372
- add_action( 'bp_include', 'bp_activity_setup_akismet' );
373
-
374
- parent::setup_actions();
375
- }
376
-
377
  /**
378
  * Setup cache groups.
379
  *
32
  array(
33
  'adminbar_myaccount_order' => 10,
34
  'search_query_arg' => 'activity_search',
35
+ 'features' => array( 'embeds' )
36
  )
37
  );
38
  }
54
  'actions',
55
  'screens',
56
  'filters',
57
+ 'adminbar',
58
  'template',
59
  'functions',
 
60
  'cache'
61
  );
62
 
63
+ // Notifications support.
64
+ if ( bp_is_active( 'notifications' ) ) {
65
+ $includes[] = 'notifications';
66
+ }
67
+
68
  // Load Akismet support if Akismet is configured.
69
  $akismet_key = bp_get_option( 'wordpress_api_key' );
70
 
71
+ /** This filter is documented in bp-activity/bp-activity-akismet.php */
72
  if ( defined( 'AKISMET_VERSION' ) && class_exists( 'Akismet' ) && ( ! empty( $akismet_key ) || defined( 'WPCOM_API_KEY' ) ) && apply_filters( 'bp_activity_use_akismet', bp_is_akismet_active() ) ) {
73
  $includes[] = 'akismet';
74
  }
75
 
76
+ // Embeds - only applicable for WP 4.5+
77
+ if ( version_compare( $GLOBALS['wp_version'], '4.5', '>=' ) && bp_is_active( $this->id, 'embeds' ) ) {
78
+ $includes[] = 'embeds';
79
+ }
80
+
81
  if ( is_admin() ) {
82
  $includes[] = 'admin';
83
  }
116
  'activity' => $bp->table_prefix . 'bp_activity_meta',
117
  );
118
 
119
+ // Fetch the default directory title.
120
+ $default_directory_titles = bp_core_get_directory_page_default_titles();
121
+ $default_directory_title = $default_directory_titles[$this->id];
122
+
123
  // All globals for activity component.
124
  // Note that global_tables is included in this array.
125
  $args = array(
126
  'slug' => BP_ACTIVITY_SLUG,
127
  'root_slug' => isset( $bp->pages->activity->slug ) ? $bp->pages->activity->slug : BP_ACTIVITY_SLUG,
128
  'has_directory' => true,
129
+ 'directory_title' => isset( $bp->pages->activity->title ) ? $bp->pages->activity->title : $default_directory_title,
130
  'notification_callback' => 'bp_activity_format_notifications',
131
  'search_string' => __( 'Search Activity...', 'buddypress' ),
132
  'global_tables' => $global_tables,
142
  * @since 1.5.0
143
  *
144
  * @see BP_Component::setup_nav() for a description of arguments.
 
 
 
 
145
  *
146
  * @param array $main_nav Optional. See BP_Component::setup_nav() for description.
147
  * @param array $sub_nav Optional. See BP_Component::setup_nav() for description.
247
  *
248
  * @see BP_Component::setup_nav() for a description of the $wp_admin_nav
249
  * parameter array.
 
 
 
 
 
 
 
250
  *
251
  * @param array $wp_admin_nav See BP_Component::setup_admin_bar() for a
252
  * description.
263
  if ( bp_activity_do_mentions() ) {
264
  $count = bp_get_total_mention_count_for_user( bp_loggedin_user_id() );
265
  if ( !empty( $count ) ) {
266
+ $title = sprintf(
267
+ /* translators: %s: Unread mention count for the current user */
268
+ _x( 'Mentions %s', 'Toolbar Mention logged in user', 'buddypress' ),
269
+ '<span class="count">' . bp_core_number_format( $count ) . '</span>'
270
+ );
271
  } else {
272
  $title = _x( 'Mentions', 'Toolbar Mention logged in user', 'buddypress' );
273
  }
343
  *
344
  * @since 1.5.0
345
  *
 
 
 
346
  */
347
  public function setup_title() {
348
 
365
  parent::setup_title();
366
  }
367
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  /**
369
  * Setup cache groups.
370
  *
bp-activity/classes/class-bp-activity-list-table.php CHANGED
@@ -171,7 +171,7 @@ class BP_Activity_List_Table extends WP_List_Table {
171
  $activities['total'] = count( $activities['activities'] );
172
 
173
  // Sort the array by the activity object's date_recorded value.
174
- usort( $activities['activities'], create_function( '$a, $b', 'return $a->date_recorded > $b->date_recorded;' ) );
175
  }
176
 
177
  // The bp_activity_get function returns an array of objects; cast these to arrays for WP_List_Table.
@@ -243,7 +243,10 @@ class BP_Activity_List_Table extends WP_List_Table {
243
  function display() {
244
  $this->display_tablenav( 'top' ); ?>
245
 
246
- <h2 class="screen-reader-text"><?php _e( 'Activities list', 'buddypress' ); ?></h2>
 
 
 
247
 
248
  <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
249
  <thead>
@@ -252,15 +255,15 @@ class BP_Activity_List_Table extends WP_List_Table {
252
  </tr>
253
  </thead>
254
 
 
 
 
 
255
  <tfoot>
256
  <tr>
257
  <?php $this->print_column_headers( false ); ?>
258
  </tr>
259
  </tfoot>
260
-
261
- <tbody id="the-comment-list">
262
- <?php $this->display_rows_or_placeholder(); ?>
263
- </tbody>
264
  </table>
265
  <?php
266
 
@@ -304,7 +307,10 @@ class BP_Activity_List_Table extends WP_List_Table {
304
  function get_views() {
305
  $url_base = add_query_arg( array( 'page' => 'bp-activity' ), bp_get_admin_url( 'admin.php' ) ); ?>
306
 
307
- <h2 class="screen-reader-text"><?php _e( 'Filter activities list', 'buddypress' ); ?></h2>
 
 
 
308
 
309
  <ul class="subsubsub">
310
  <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>
@@ -414,13 +420,34 @@ class BP_Activity_List_Table extends WP_List_Table {
414
  $activity_actions = bp_activity_get_actions(); ?>
415
 
416
  <div class="alignleft actions">
417
- <label for="activity-type" class="screen-reader-text"><?php _e( 'Filter by activity type', 'buddypress' ); ?></label>
 
 
 
418
  <select name="activity_type" id="activity-type">
419
  <option value="" <?php selected( ! $selected ); ?>><?php _e( 'View all actions', 'buddypress' ); ?></option>
420
 
421
  <?php foreach ( $activity_actions as $component => $actions ) : ?>
422
-
423
- <optgroup label="<?php echo ucfirst( $component ); ?>">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
 
425
  <?php foreach ( $actions as $action_key => $action_values ) : ?>
426
 
@@ -488,6 +515,7 @@ class BP_Activity_List_Table extends WP_List_Table {
488
  * @param array $item A singular item (one full row).
489
  */
490
  function column_cb( $item ) {
 
491
  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'] );
492
  }
493
 
@@ -613,15 +641,10 @@ class BP_Activity_List_Table extends WP_List_Table {
613
 
614
  // Get activity content - if not set, use the action.
615
  if ( ! empty( $item['content'] ) ) {
 
616
 
617
- /**
618
- * Filters current activity item content.
619
- *
620
- * @since 1.2.0
621
- *
622
- * @param array $item Array index holding current activity item content.
623
- */
624
- $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'] ) );
625
  } else {
626
  /**
627
  * Filters current activity item action.
171
  $activities['total'] = count( $activities['activities'] );
172
 
173
  // Sort the array by the activity object's date_recorded value.
174
+ usort( $activities['activities'], function( $a, $b ) { return $a->date_recorded > $b->date_recorded; } );
175
  }
176
 
177
  // The bp_activity_get function returns an array of objects; cast these to arrays for WP_List_Table.
243
  function display() {
244
  $this->display_tablenav( 'top' ); ?>
245
 
246
+ <h2 class="screen-reader-text"><?php
247
+ /* translators: accessibility text */
248
+ _e( 'Activities list', 'buddypress' );
249
+ ?></h2>
250
 
251
  <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
252
  <thead>
255
  </tr>
256
  </thead>
257
 
258
+ <tbody id="the-comment-list">
259
+ <?php $this->display_rows_or_placeholder(); ?>
260
+ </tbody>
261
+
262
  <tfoot>
263
  <tr>
264
  <?php $this->print_column_headers( false ); ?>
265
  </tr>
266
  </tfoot>
 
 
 
 
267
  </table>
268
  <?php
269
 
307
  function get_views() {
308
  $url_base = add_query_arg( array( 'page' => 'bp-activity' ), bp_get_admin_url( 'admin.php' ) ); ?>
309
 
310
+ <h2 class="screen-reader-text"><?php
311
+ /* translators: accessibility text */
312
+ _e( 'Filter activities list', 'buddypress' );
313
+ ?></h2>
314
 
315
  <ul class="subsubsub">
316
  <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>
420
  $activity_actions = bp_activity_get_actions(); ?>
421
 
422
  <div class="alignleft actions">
423
+ <label for="activity-type" class="screen-reader-text"><?php
424
+ /* translators: accessibility text */
425
+ _e( 'Filter by activity type', 'buddypress' );
426
+ ?></label>
427
  <select name="activity_type" id="activity-type">
428
  <option value="" <?php selected( ! $selected ); ?>><?php _e( 'View all actions', 'buddypress' ); ?></option>
429
 
430
  <?php foreach ( $activity_actions as $component => $actions ) : ?>
431
+ <?php
432
+ // Older avatar activity items use 'profile' for component. See r4273.
433
+ if ( $component === 'profile' ) {
434
+ $component = 'xprofile';
435
+ }
436
+
437
+ if ( bp_is_active( $component ) ) {
438
+ if ( $component === 'xprofile' ) {
439
+ $component_name = buddypress()->profile->name;
440
+ } else {
441
+ $component_name = buddypress()->$component->name;
442
+ }
443
+
444
+ } else {
445
+ // Prevent warnings by other plugins if a component is disabled but the activity type has been registered.
446
+ $component_name = ucfirst( $component );
447
+ }
448
+ ?>
449
+
450
+ <optgroup label="<?php echo esc_html( $component_name ); ?>">
451
 
452
  <?php foreach ( $actions as $action_key => $action_values ) : ?>
453
 
515
  * @param array $item A singular item (one full row).
516
  */
517
  function column_cb( $item ) {
518
+ /* translators: accessibility text */
519
  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'] );
520
  }
521
 
641
 
642
  // Get activity content - if not set, use the action.
643
  if ( ! empty( $item['content'] ) ) {
644
+ $activity = new BP_Activity_Activity( $item['id'] );
645
 
646
+ /** This filter is documented in bp-activity/bp-activity-template.php */
647
+ $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'], &$activity ) );
 
 
 
 
 
 
648
  } else {
649
  /**
650
  * Filters current activity item action.
bp-activity/classes/class-bp-activity-oembed-extension.php ADDED
@@ -0,0 +1,329 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BuddyPress Activity Classes.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage Embeds
7
+ */
8
+
9
+ // Exit if accessed directly.
10
+ defined( 'ABSPATH' ) || exit;
11
+
12
+ /**
13
+ * oEmbed handler to respond and render single activity items.
14
+ *
15
+ * @since 2.6.0
16
+ */
17
+ class BP_Activity_oEmbed_Extension extends BP_Core_oEmbed_Extension {
18
+ /**
19
+ * Custom oEmbed slug endpoint.
20
+ *
21
+ * @since 2.6.0
22
+ *
23
+ * @var string
24
+ */
25
+ public $slug_endpoint = 'activity';
26
+
27
+ /**
28
+ * Custom hooks.
29
+ *
30
+ * @since 2.6.0
31
+ */
32
+ protected function custom_hooks() {
33
+ add_action( 'oembed_dataparse', array( $this, 'use_custom_iframe_sandbox_attribute' ), 20, 3 );
34
+ add_action( 'embed_content_meta', array( $this, 'embed_comments_button' ), 5 );
35
+ add_action( 'get_template_part_assets/embeds/header', array( $this, 'on_activity_header' ), 10, 2 );
36
+
37
+ add_filter( 'bp_activity_embed_html', array( $this, 'modify_iframe' ) );
38
+ }
39
+
40
+ /**
41
+ * Add custom endpoint arguments.
42
+ *
43
+ * Currently, includes 'hide_media'.
44
+ *
45
+ * @since 2.6.0
46
+ *
47
+ * @return array
48
+ */
49
+ protected function set_route_args() {
50
+ return array(
51
+ 'hide_media' => array(
52
+ 'default' => false,
53
+ 'sanitize_callback' => 'wp_validate_boolean'
54
+ )
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Output our custom embed template part.
60
+ *
61
+ * @since 2.6.0
62
+ */
63
+ protected function content() {
64
+ bp_get_asset_template_part( 'embeds/activity' );
65
+ }
66
+
67
+ /**
68
+ * Check if we're on our single activity page.
69
+ *
70
+ * @since 2.6.0
71
+ *
72
+ * @return bool
73
+ */
74
+ protected function is_page() {
75
+ return bp_is_single_activity();
76
+ }
77
+
78
+ /**
79
+ * Validates the URL to determine if the activity item is valid.
80
+ *
81
+ * @since 2.6.0
82
+ *
83
+ * @param string $url The URL to check.
84
+ * @return int|bool Activity ID on success; boolean false on failure.
85
+ */
86
+ protected function validate_url_to_item_id( $url ) {
87
+ if ( bp_core_enable_root_profiles() ) {
88
+ $domain = bp_get_root_domain();
89
+ } else {
90
+ $domain = bp_get_members_directory_permalink();
91
+ }
92
+
93
+ // Check the URL to see if this is a single activity URL.
94
+ if ( 0 !== strpos( $url, $domain ) ) {
95
+ return false;
96
+ }
97
+
98
+ // Check for activity slug.
99
+ if ( false === strpos( $url, '/' . bp_get_activity_slug() . '/' ) ) {
100
+ return false;
101
+ }
102
+
103
+ // Do more checks.
104
+ $url = trim( untrailingslashit( $url ) );
105
+
106
+ // Grab the activity ID.
107
+ $activity_id = (int) substr(
108
+ $url,
109
+ strrpos( $url, '/' ) + 1
110
+ );
111
+
112
+ if ( ! empty( $activity_id ) ) {
113
+ // Check if activity item still exists.
114
+ $activity = new BP_Activity_Activity( $activity_id );
115
+
116
+ // Okay, we're good to go!
117
+ if ( ! empty( $activity->component ) && 0 === (int) $activity->is_spam ) {
118
+ return $activity_id;
119
+ }
120
+ }
121
+
122
+ return false;
123
+ }
124
+
125
+ /**
126
+ * Sets the oEmbed response data for our activity item.
127
+ *
128
+ * @since 2.6.0
129
+ *
130
+ * @param int $item_id The activity ID.
131
+ * @return array
132
+ */
133
+ protected function set_oembed_response_data( $item_id ) {
134
+ $activity = new BP_Activity_Activity( $item_id );
135
+
136
+ return array(
137
+ 'content' => $activity->content,
138
+ 'title' => __( 'Activity', 'buddypress' ),
139
+ 'author_name' => bp_core_get_user_displayname( $activity->user_id ),
140
+ 'author_url' => bp_core_get_user_domain( $activity->user_id ),
141
+
142
+ // Custom identifier.
143
+ 'x_buddypress' => 'activity'
144
+ );
145
+ }
146
+
147
+ /**
148
+ * Sets a custom <blockquote> for our oEmbed fallback HTML.
149
+ *
150
+ * @since 2.6.0
151
+ *
152
+ * @param int $item_id The activity ID.
153
+ * @return string
154
+ */
155
+ protected function set_fallback_html( $item_id ) {
156
+ $activity = new BP_Activity_Activity( $item_id );
157
+ $mentionname = bp_activity_do_mentions() ? ' (@' . bp_activity_get_user_mentionname( $activity->user_id ) . ')' : '';
158
+ $date = date_i18n( get_option( 'date_format' ), strtotime( $activity->date_recorded ) );
159
+
160
+ // Make sure we can use some activity functions that depend on the loop.
161
+ $GLOBALS['activities_template'] = new stdClass;
162
+ $GLOBALS['activities_template']->activity = $activity;
163
+
164
+ // 'wp-embedded-content' CSS class is necessary due to how the embed JS works.
165
+ $blockquote = sprintf( '<blockquote class="wp-embedded-content bp-activity-item">%1$s%2$s %3$s</blockquote>',
166
+ bp_activity_get_embed_excerpt( $activity->content ),
167
+ '- ' . bp_core_get_user_displayname( $activity->user_id ) . $mentionname,
168
+ '<a href="' . esc_url( bp_activity_get_permalink( $item_id ) ) . '">' . $date . '</a>'
169
+ );
170
+
171
+ // Clean up.
172
+ unset( $GLOBALS['activities_template'] );
173
+
174
+ /**
175
+ * Filters the fallback HTML used when embedding a BP activity item.
176
+ *
177
+ * @since 2.6.0
178
+ *
179
+ * @param string $blockquote Current fallback HTML
180
+ * @param BP_Activity_Activity $activity Activity object
181
+ */
182
+ return apply_filters( 'bp_activity_embed_fallback_html', $blockquote, $activity );
183
+ }
184
+
185
+ /**
186
+ * Sets a custom <iframe> title for our oEmbed item.
187
+ *
188
+ * @since 2.6.0
189
+ *
190
+ * @param int $item_id The activity ID
191
+ * @return string
192
+ */
193
+ protected function set_iframe_title( $item_id ) {
194
+ return __( 'Embedded Activity Item', 'buddypress' );
195
+ }
196
+
197
+ /**
198
+ * Use our custom <iframe> sandbox attribute in our oEmbed response.
199
+ *
200
+ * WordPress sets the <iframe> sandbox attribute to 'allow-scripts' regardless
201
+ * of whatever the oEmbed response is in {@link wp_filter_oembed_result()}. We
202
+ * need to add back our custom sandbox value so links will work.
203
+ *
204
+ * @since 2.6.0
205
+ *
206
+ * @see BP_Activity_Component::modify_iframe() where our custom sandbox value is set.
207
+ *
208
+ * @param string $result The oEmbed HTML result.
209
+ * @param object $data A data object result from an oEmbed provider.
210
+ * @param string $url The URL of the content to be embedded.
211
+ * @return string
212
+ */
213
+ public function use_custom_iframe_sandbox_attribute( $result, $data, $url ) {
214
+ // Make sure we are on a BuddyPress activity oEmbed request.
215
+ if ( false === isset( $data->x_buddypress ) || 'activity' !== $data->x_buddypress ) {
216
+ return $result;
217
+ }
218
+
219
+ // Get unfiltered sandbox attribute from our own oEmbed response.
220
+ $sandbox_pos = strpos( $data->html, 'sandbox=' ) + 9;
221
+ $sandbox = substr( $data->html, $sandbox_pos, strpos( $data->html, '"', $sandbox_pos ) - $sandbox_pos );
222
+
223
+ // Replace only if our sandbox attribute contains 'allow-top-navigation'.
224
+ if ( false !== strpos( $sandbox, 'allow-top-navigation' ) ) {
225
+ $result = str_replace( ' sandbox="allow-scripts"', " sandbox=\"{$sandbox}\"", $result );
226
+
227
+ // Also remove 'security' attribute; this is only used for IE < 10.
228
+ $result = str_replace( 'security="restricted"', "", $result );
229
+ }
230
+
231
+ return $result;
232
+ }
233
+
234
+ /**
235
+ * Modify various IFRAME-related items if embeds are allowed.
236
+ *
237
+ * HTML modified:
238
+ * - Add sandbox="allow-top-navigation" attribute. This allows links to work
239
+ * within the iframe sandbox attribute.
240
+ *
241
+ * JS modified:
242
+ * - Remove IFRAME height restriction of 1000px. Fixes long embed items being
243
+ * truncated.
244
+ *
245
+ * @since 2.6.0
246
+ *
247
+ * @param string $retval Current embed HTML.
248
+ * @return string
249
+ */
250
+ public function modify_iframe( $retval ) {
251
+ // Add 'allow-top-navigation' to allow links to be clicked.
252
+ $retval = str_replace( 'sandbox="', 'sandbox="allow-top-navigation ', $retval );
253
+
254
+ // See /wp-includes/js/wp-embed.js.
255
+ if ( SCRIPT_DEBUG ) {
256
+ // Removes WP's hardcoded IFRAME height restriction.
257
+ $retval = str_replace( 'height = 1000;', 'height = height;', $retval );
258
+
259
+ // This is for the WP build minified version.
260
+ } else {
261
+ $retval = str_replace( 'g=1e3', 'g=g', $retval );
262
+ }
263
+
264
+ return $retval;
265
+ }
266
+
267
+ /**
268
+ * Do stuff when our oEmbed activity header template part is loading.
269
+ *
270
+ * Currently, removes wpautop() from the bp_activity_action() function.
271
+ *
272
+ * @since 2.6.0
273
+ *
274
+ * @param string $slug Template part slug requested.
275
+ * @param string $name Template part name requested.
276
+ */
277
+ public function on_activity_header( $slug, $name ) {
278
+ if ( false === $this->is_page() || 'activity' !== $name ) {
279
+ return;
280
+ }
281
+
282
+ remove_filter( 'bp_get_activity_action', 'wpautop' );
283
+ }
284
+
285
+ /**
286
+ * Prints the markup for the activity embed comments button.
287
+ *
288
+ * Basically a copy of {@link print_embed_comments_button()}, but modified for
289
+ * the BP activity component.
290
+ *
291
+ * @since 2.6.0
292
+ */
293
+ public function embed_comments_button() {
294
+ if ( ! did_action( 'bp_embed_content' ) || ! bp_is_single_activity() ) {
295
+ return;
296
+ }
297
+
298
+ // Make sure our custom permalink shows up in the 'WordPress Embed' block.
299
+ add_filter( 'the_permalink', array( $this, 'filter_embed_url' ) );
300
+
301
+ // Only show comment bubble if we have some activity comments.
302
+ $count = bp_activity_get_comment_count();
303
+ if ( empty( $count ) ) {
304
+ return;
305
+ }
306
+ ?>
307
+
308
+ <div class="wp-embed-comments">
309
+ <a href="<?php bp_activity_thread_permalink(); ?>">
310
+ <span class="dashicons dashicons-admin-comments"></span>
311
+ <?php
312
+ printf(
313
+ _n(
314
+ /* translators: accessibility text */
315
+ '%s <span class="screen-reader-text">Comment</span>',
316
+ /* translators: accessibility text */
317
+ '%s <span class="screen-reader-text">Comments</span>',
318
+ $count,
319
+ 'buddypress'
320
+ ),
321
+ number_format_i18n( $count )
322
+ );
323
+ ?>
324
+ </a>
325
+ </div>
326
+
327
+ <?php
328
+ }
329
+ }
bp-activity/classes/class-bp-activity-template.php CHANGED
@@ -159,8 +159,7 @@ class BP_Activity_Template {
159
  12 => 'page_arg'
160
  );
161
 
162
- $func_args = func_get_args();
163
- $args = bp_core_parse_args_array( $old_args_keys, $func_args );
164
  }
165
 
166
  $defaults = array(
159
  12 => 'page_arg'
160
  );
161
 
162
+ $args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
 
163
  }
164
 
165
  $defaults = array(
bp-activity/css/mentions-rtl.css CHANGED
@@ -11,9 +11,8 @@
11
  top: 0;
12
  z-index: 1000; /* >999 for wp-admin */
13
  }
14
- /* @noflip */
15
  .atwho-view {
16
- left: 0;
17
  }
18
  .atwho-view ul {
19
  background: #FFF;
@@ -42,7 +41,7 @@
42
  }
43
  .atwho-view strong {
44
  background: #EFEFEF;
45
- font: bold;
46
  }
47
  .atwho-view .username strong {
48
  color: #D54E21;
11
  top: 0;
12
  z-index: 1000; /* >999 for wp-admin */
13
  }
 
14
  .atwho-view {
15
+ left: 0;
16
  }
17
  .atwho-view ul {
18
  background: #FFF;
41
  }
42
  .atwho-view strong {
43
  background: #EFEFEF;
44
+ font-weight: bold;
45
  }
46
  .atwho-view .username strong {
47
  color: #D54E21;
bp-activity/css/mentions-rtl.min.css CHANGED
@@ -1 +1 @@
1
- .atwho-view{background:rgba(204,204,204,.8);border-radius:2px;border:1px solid #ccc;box-shadow:0 0 5px rgba(204,204,204,.25),0 0 1px #FFF;color:#D84800;display:none;font-family:sans-serif;margin-top:18px;position:absolute;top:0;z-index:1000;left:0}.atwho-view ul{background:#FFF;list-style:none;margin:auto;padding:0}.atwho-view ul li{border-bottom:1px solid #EFEFEF;box-sizing:content-box;cursor:pointer;display:block;font-size:14px;height:20px;line-height:20px;margin:0;overflow:hidden;padding:5px 10px}.atwho-view img{border-radius:2px;float:left;height:20px;margin-top:0;width:20px}.atwho-view strong{background:#EFEFEF;font:700}.atwho-view .username strong{color:#D54E21}.atwho-view small{color:#AAA;float:left;font-size:smaller;font-weight:400;margin:0 40px 0 10px}.atwho-view .cur{background:rgba(239,239,239,.5)}@media (max-width:900px){.atwho-view img{float:right;margin:0 0 0 10px}}@media (max-width:400px){.atwho-view ul li{font-size:16px;line-height:23px;padding:13px}.atwho-view ul li img{height:30px;margin-top:-5px;width:30px}.atwho-view{border-radius:0;height:100%;right:0!important;width:100%}.atwho-view ul li .username{display:inline-block;margin:-10px 0 0;padding:10px 0}.atwho-view ul li small{display:inline-block;margin-right:20px}}
1
+ .atwho-view{background:rgba(204,204,204,.8);border-radius:2px;border:1px solid #ccc;box-shadow:0 0 5px rgba(204,204,204,.25),0 0 1px #FFF;color:#D84800;display:none;font-family:sans-serif;margin-top:18px;position:absolute;top:0;z-index:1000;left:0}.atwho-view ul{background:#FFF;list-style:none;margin:auto;padding:0}.atwho-view ul li{border-bottom:1px solid #EFEFEF;box-sizing:content-box;cursor:pointer;display:block;font-size:14px;height:20px;line-height:20px;margin:0;overflow:hidden;padding:5px 10px}.atwho-view img{border-radius:2px;float:left;height:20px;margin-top:0;width:20px}.atwho-view strong{background:#EFEFEF;font-weight:700}.atwho-view .username strong{color:#D54E21}.atwho-view small{color:#AAA;float:left;font-size:smaller;font-weight:400;margin:0 40px 0 10px}.atwho-view .cur{background:rgba(239,239,239,.5)}@media (max-width:900px){.atwho-view img{float:right;margin:0 0 0 10px}}@media (max-width:400px){.atwho-view ul li{font-size:16px;line-height:23px;padding:13px}.atwho-view ul li img{height:30px;margin-top:-5px;width:30px}.atwho-view{border-radius:0;height:100%;right:0!important;width:100%}.atwho-view ul li .username{display:inline-block;margin:-10px 0 0;padding:10px 0}.atwho-view ul li small{display:inline-block;margin-right:20px}}
bp-activity/css/mentions.css CHANGED
@@ -11,9 +11,9 @@
11
  top: 0;
12
  z-index: 1000; /* >999 for wp-admin */
13
  }
14
- /* @noflip */
15
  .atwho-view {
16
- left: 0;
17
  }
18
  .atwho-view ul {
19
  background: #FFF;
@@ -42,7 +42,7 @@
42
  }
43
  .atwho-view strong {
44
  background: #EFEFEF;
45
- font: bold;
46
  }
47
  .atwho-view .username strong {
48
  color: #D54E21;
11
  top: 0;
12
  z-index: 1000; /* >999 for wp-admin */
13
  }
14
+ /* rtl:ignore */
15
  .atwho-view {
16
+ left: 0;
17
  }
18
  .atwho-view ul {
19
  background: #FFF;
42
  }
43
  .atwho-view strong {
44
  background: #EFEFEF;
45
+ font-weight: bold;
46
  }
47
  .atwho-view .username strong {
48
  color: #D54E21;
bp-activity/css/mentions.min.css CHANGED
@@ -1 +1 @@
1
- .atwho-view{background:rgba(204,204,204,.8);border-radius:2px;border:1px solid #ccc;box-shadow:0 0 5px rgba(204,204,204,.25),0 0 1px #FFF;color:#D84800;display:none;font-family:sans-serif;margin-top:18px;position:absolute;top:0;z-index:1000;left:0}.atwho-view ul{background:#FFF;list-style:none;margin:auto;padding:0}.atwho-view ul li{border-bottom:1px solid #EFEFEF;box-sizing:content-box;cursor:pointer;display:block;font-size:14px;height:20px;line-height:20px;margin:0;overflow:hidden;padding:5px 10px}.atwho-view img{border-radius:2px;float:right;height:20px;margin-top:0;width:20px}.atwho-view strong{background:#EFEFEF;font:700}.atwho-view .username strong{color:#D54E21}.atwho-view small{color:#AAA;float:right;font-size:smaller;font-weight:400;margin:0 10px 0 40px}.atwho-view .cur{background:rgba(239,239,239,.5)}@media (max-width:900px){.atwho-view img{float:left;margin:0 10px 0 0}}@media (max-width:400px){.atwho-view ul li{font-size:16px;line-height:23px;padding:13px}.atwho-view ul li img{height:30px;margin-top:-5px;width:30px}.atwho-view{border-radius:0;height:100%;left:0!important;width:100%}.atwho-view ul li .username{display:inline-block;margin:-10px 0 0;padding:10px 0}.atwho-view ul li small{display:inline-block;margin-left:20px}}
1
+ .atwho-view{background:rgba(204,204,204,.8);border-radius:2px;border:1px solid #ccc;box-shadow:0 0 5px rgba(204,204,204,.25),0 0 1px #FFF;color:#D84800;display:none;font-family:sans-serif;margin-top:18px;position:absolute;top:0;z-index:1000;left:0}.atwho-view ul{background:#FFF;list-style:none;margin:auto;padding:0}.atwho-view ul li{border-bottom:1px solid #EFEFEF;box-sizing:content-box;cursor:pointer;display:block;font-size:14px;height:20px;line-height:20px;margin:0;overflow:hidden;padding:5px 10px}.atwho-view img{border-radius:2px;float:right;height:20px;margin-top:0;width:20px}.atwho-view strong{background:#EFEFEF;font-weight:700}.atwho-view .username strong{color:#D54E21}.atwho-view small{color:#AAA;float:right;font-size:smaller;font-weight:400;margin:0 10px 0 40px}.atwho-view .cur{background:rgba(239,239,239,.5)}@media (max-width:900px){.atwho-view img{float:left;margin:0 10px 0 0}}@media (max-width:400px){.atwho-view ul li{font-size:16px;line-height:23px;padding:13px}.atwho-view ul li img{height:30px;margin-top:-5px;width:30px}.atwho-view{border-radius:0;height:100%;left:0!important;width:100%}.atwho-view ul li .username{display:inline-block;margin:-10px 0 0;padding:10px 0}.atwho-view ul li small{display:inline-block;margin-left:20px}}
bp-activity/js/mentions.js CHANGED
@@ -248,7 +248,7 @@ window.bp = window.bp || {};
248
  return;
249
  } else {
250
  $( window.tinyMCE.activeEditor.contentDocument.activeElement )
251
- .atwho( 'setIframe', $( '#content_ifr' )[0] )
252
  .bp_mentions( bp.mentions.users );
253
  }
254
  };
248
  return;
249
  } else {
250
  $( window.tinyMCE.activeEditor.contentDocument.activeElement )
251
+ .atwho( 'setIframe', $( '.wp-editor-wrap iframe' )[0] )
252
  .bp_mentions( bp.mentions.users );
253
  }
254
  };
bp-activity/js/mentions.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
- window.bp=window.bp||{},function(a,b,c){var d,e=[];a.mentions=a.mentions||{},a.mentions.users=window.bp.mentions.users||[],"object"==typeof window.BP_Suggestions&&(a.mentions.users=window.BP_Suggestions.friends||a.mentions.users),b.fn.bp_mentions=function(a){b.isArray(a)&&(a={data:a});var c={delay:200,hide_without_suffix:!0,insert_tpl:"</>${atwho-data-value}</>",limit:10,start_with_space:!1,suffix:"",callbacks:{filter:function(a,b,c){var d,e,f,g=[],h=new RegExp("^"+a+"| "+a,"ig");for(e=0,f=b.length;f>e;e++)d=b[e],d[c].toLowerCase().match(h)&&g.push(d);return g},highlighter:function(a,b){if(!b)return a;var c=new RegExp(">(\\s*|[\\w\\s]*)("+this.at.replace("+","\\+")+"?"+b.replace("+","\\+")+")([\\w ]*)\\s*<","ig");return a.replace(c,function(a,b,c,d){return">"+b+"<strong>"+c+"</strong>"+d+"<"})},before_reposition:function(a){var c,d,e,f,g=b("#atwho-ground-"+this.id+" .atwho-view"),h=b("body"),i=this.$inputor.data("atwho");"undefined"!==i&&"undefined"!==i.iframe&&null!==i.iframe?(c=this.$inputor.caret("offset",{iframe:i.iframe}),e=b(i.iframe).offset(),"undefined"!==e&&(c.left+=e.left,c.top+=e.top)):c=this.$inputor.caret("offset"),c.left>h.width()/2?(g.addClass("right"),f=c.left-a.left-this.view.$el.width()):(g.removeClass("right"),f=c.left-a.left+1),h.width()<=400&&b(document).scrollTop(c.top-6),d=parseInt(this.$inputor.css("line-height").substr(0,this.$inputor.css("line-height").length-2),10),(!d||5>d)&&(d=19),a.top=c.top+d,a.left+=f},inserting_wrapper:function(a,b,c){return""+b+c}}},f={callbacks:{remote_filter:function(a,c){var f=b(this),g={};return d=e[a],"object"==typeof d?void c(d):(f.xhr&&f.xhr.abort(),g={action:"bp_get_suggestions",term:a,type:"members"},b.isNumeric(this.$inputor.data("suggestions-group-id"))&&(g["group-id"]=parseInt(this.$inputor.data("suggestions-group-id"),10)),void(f.xhr=b.getJSON(ajaxurl,g).done(function(d){if(d.success){var f=b.map(d.data,function(a){return a.search=a.search||a.ID+" "+a.name,a});e[a]=f,c(f)}})))}},data:b.map(a.data,function(a){return a.search=a.search||a.ID+" "+a.name,a}),at:"@",search_key:"search",tpl:'<li data-value="@${ID}"><img src="${image}" /><span class="username">@${ID}</span><small>${name}</small></li>'},g=b.extend(!0,{},c,f,a);return b.fn.atwho.call(this,g)},b(document).ready(function(){b(".bp-suggestions, #comments form textarea, .wp-editor-area").bp_mentions(a.mentions.users)}),a.mentions.tinyMCEinit=function(){"undefined"!=typeof window.tinyMCE&&null!==window.tinyMCE.activeEditor&&"undefined"!=typeof window.tinyMCE.activeEditor&&b(window.tinyMCE.activeEditor.contentDocument.activeElement).atwho("setIframe",b("#content_ifr")[0]).bp_mentions(a.mentions.users)}}(bp,jQuery);
1
+ window.bp=window.bp||{},function(a,b,c){var d,e=[];a.mentions=a.mentions||{},a.mentions.users=window.bp.mentions.users||[],"object"==typeof window.BP_Suggestions&&(a.mentions.users=window.BP_Suggestions.friends||a.mentions.users),b.fn.bp_mentions=function(a){b.isArray(a)&&(a={data:a});var c={delay:200,hide_without_suffix:!0,insert_tpl:"</>${atwho-data-value}</>",limit:10,start_with_space:!1,suffix:"",callbacks:{filter:function(a,b,c){var d,e,f,g=[],h=new RegExp("^"+a+"| "+a,"ig");for(e=0,f=b.length;e<f;e++)d=b[e],d[c].toLowerCase().match(h)&&g.push(d);return g},highlighter:function(a,b){if(!b)return a;var c=new RegExp(">(\\s*|[\\w\\s]*)("+this.at.replace("+","\\+")+"?"+b.replace("+","\\+")+")([\\w ]*)\\s*<","ig");return a.replace(c,function(a,b,c,d){return">"+b+"<strong>"+c+"</strong>"+d+"<"})},before_reposition:function(a){var c,d,e,f,g=b("#atwho-ground-"+this.id+" .atwho-view"),h=b("body"),i=this.$inputor.data("atwho");"undefined"!==i&&"undefined"!==i.iframe&&null!==i.iframe?(c=this.$inputor.caret("offset",{iframe:i.iframe}),e=b(i.iframe).offset(),"undefined"!==e&&(c.left+=e.left,c.top+=e.top)):c=this.$inputor.caret("offset"),c.left>h.width()/2?(g.addClass("right"),f=c.left-a.left-this.view.$el.width()):(g.removeClass("right"),f=c.left-a.left+1),h.width()<=400&&b(document).scrollTop(c.top-6),d=parseInt(this.$inputor.css("line-height").substr(0,this.$inputor.css("line-height").length-2),10),(!d||d<5)&&(d=19),a.top=c.top+d,a.left+=f},inserting_wrapper:function(a,b,c){return""+b+c}}},f={callbacks:{remote_filter:function(a,c){var f=b(this),g={};return d=e[a],"object"==typeof d?void c(d):(f.xhr&&f.xhr.abort(),g={action:"bp_get_suggestions",term:a,type:"members"},b.isNumeric(this.$inputor.data("suggestions-group-id"))&&(g["group-id"]=parseInt(this.$inputor.data("suggestions-group-id"),10)),void(f.xhr=b.getJSON(ajaxurl,g).done(function(d){if(d.success){var f=b.map(d.data,function(a){return a.search=a.search||a.ID+" "+a.name,a});e[a]=f,c(f)}})))}},data:b.map(a.data,function(a){return a.search=a.search||a.ID+" "+a.name,a}),at:"@",search_key:"search",tpl:'<li data-value="@${ID}"><img src="${image}" /><span class="username">@${ID}</span><small>${name}</small></li>'},g=b.extend(!0,{},c,f,a);return b.fn.atwho.call(this,g)},b(document).ready(function(){b(".bp-suggestions, #comments form textarea, .wp-editor-area").bp_mentions(a.mentions.users)}),a.mentions.tinyMCEinit=function(){"undefined"!=typeof window.tinyMCE&&null!==window.tinyMCE.activeEditor&&"undefined"!=typeof window.tinyMCE.activeEditor&&b(window.tinyMCE.activeEditor.contentDocument.activeElement).atwho("setIframe",b(".wp-editor-wrap iframe")[0]).bp_mentions(a.mentions.users)}}(bp,jQuery);
 
bp-blogs/bp-blogs-activity.php CHANGED
@@ -547,7 +547,7 @@ function bp_blogs_comments_open( $activity ) {
547
  switch_to_blog( $blog_id );
548
 
549
  // Use comments_open().
550
- remove_filter( 'comments_open', 'bp_comments_open', 10, 2 );
551
  $open = comments_open( $activity->secondary_item_id );
552
  add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
553
 
@@ -606,6 +606,143 @@ function bp_blogs_comments_open( $activity ) {
606
  return $open;
607
  }
608
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
  /** POST COMMENT SYNCHRONIZATION ****************************************/
610
 
611
  /**
@@ -633,6 +770,12 @@ function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_
633
  return;
634
  }
635
 
 
 
 
 
 
 
636
  // Get userdata.
637
  if ( $params['user_id'] == bp_loggedin_user_id() ) {
638
  $user = buddypress()->loggedin_user->userdata;
@@ -663,7 +806,7 @@ function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_
663
  );
664
 
665
  // Prevent separate activity entry being made.
666
- remove_action( 'comment_post', 'bp_activity_post_type_comment', 10, 2 );
667
 
668
  // Handle multisite.
669
  switch_to_blog( $parent_activity->item_id );
@@ -689,7 +832,7 @@ function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_
689
  // permalinks to use the post comment link
690
  //
691
  // @todo since this is done after AJAX posting, the activity comment permalink
692
- // doesn't change on the frontend until the next page refresh.
693
  $resave_activity = new BP_Activity_Activity( $comment_id );
694
  $resave_activity->primary_link = get_comment_link( $post_comment_id );
695
 
@@ -827,10 +970,10 @@ function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $acti
827
  $old_comment_status = $post_comment_status;
828
 
829
  // No need to edit the activity, as it's the activity who's updating the comment
830
- remove_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
831
- remove_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10, 4 );
832
 
833
- if ( 1 === (int) $activity->is_spam && 'spam' !== $post_comment_status ) {
834
  wp_spam_comment( $post_comment_id );
835
  } elseif ( ! $activity->is_spam ) {
836
  if ( 'spam' === $post_comment_status ) {
@@ -1157,7 +1300,7 @@ function bp_blogs_can_comment_reply( $retval, $comment ) {
1157
 
1158
  // Check comment depth and disable if depth is too large.
1159
  if ( isset( buddypress()->blogs->thread_depth[$comment->item_id] ) ){
1160
- if ( $comment->mptt_left > buddypress()->blogs->thread_depth[$comment->item_id] ) {
1161
  $retval = false;
1162
  }
1163
  }
547
  switch_to_blog( $blog_id );
548
 
549
  // Use comments_open().
550
+ remove_filter( 'comments_open', 'bp_comments_open', 10 );
551
  $open = comments_open( $activity->secondary_item_id );
552
  add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
553
 
606
  return $open;
607
  }
608
 
609
+ /** SITE TRACKING *******************************************************/
610
+
611
+ /**
612
+ * Add an activity entry for a newly-created site.
613
+ *
614
+ * Hooked to the 'bp_blogs_new_blog' action.
615
+ *
616
+ * @since 2.6.0
617
+ *
618
+ * @param BP_Blogs_Blog $recorded_blog Current site being recorded. Passed by reference.
619
+ * @param bool $is_private Whether the current site being recorded is private.
620
+ * @param bool $is_recorded Whether the current site was recorded.
621
+ */
622
+ function bp_blogs_record_activity_on_site_creation( $recorded_blog, $is_private, $is_recorded, $no_activity ) {
623
+ // Only record this activity if the blog is public.
624
+ if ( ! $is_private && ! $no_activity && bp_blogs_is_blog_trackable( $recorded_blog->blog_id, $recorded_blog->user_id ) ) {
625
+ bp_blogs_record_activity( array(
626
+ 'user_id' => $recorded_blog->user_id,
627
+
628
+ /**
629
+ * Filters the activity created blog primary link.
630
+ *
631
+ * @since 1.1.0
632
+ *
633
+ * @param string $value Blog primary link.
634
+ * @param int $value Blog ID.
635
+ */
636
+ 'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', bp_blogs_get_blogmeta( $recorded_blog->blog_id, 'url' ), $recorded_blog->blog_id ),
637
+ 'type' => 'new_blog',
638
+ 'item_id' => $recorded_blog->blog_id
639
+ ) );
640
+ }
641
+ }
642
+ add_action( 'bp_blogs_new_blog', 'bp_blogs_record_activity_on_site_creation', 10, 4 );
643
+
644
+ /**
645
+ * Deletes the 'new_blog' activity entry when a site is deleted.
646
+ *
647
+ * @since 2.6.0
648
+ *
649
+ * @param int $blog_id Site ID.
650
+ */
651
+ function bp_blogs_delete_new_blog_activity_for_site( $blog_id, $user_id = 0 ) {
652
+ $args = array(
653
+ 'item_id' => $blog_id,
654
+ 'component' => buddypress()->blogs->id,
655
+ 'type' => 'new_blog'
656
+ );
657
+
658
+ /**
659
+ * In the case a user is removed, make sure he is the author of the 'new_blog' activity
660
+ * when trying to delete it.
661
+ */
662
+ if ( ! empty( $user_id ) ) {
663
+ $args['user_id'] = $user_id;
664
+ }
665
+
666
+ bp_blogs_delete_activity( $args );
667
+ }
668
+ add_action( 'bp_blogs_remove_blog', 'bp_blogs_delete_new_blog_activity_for_site', 10, 1 );
669
+ add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_delete_new_blog_activity_for_site', 10, 2 );
670
+
671
+ /**
672
+ * Delete all 'blogs' activity items for a site when the site is deleted.
673
+ *
674
+ * @since 2.6.0
675
+ *
676
+ * @param int $blog_id Site ID.
677
+ */
678
+ function bp_blogs_delete_activity_for_site( $blog_id ) {
679
+ bp_blogs_delete_activity( array(
680
+ 'item_id' => $blog_id,
681
+ 'component' => buddypress()->blogs->id,
682
+ 'type' => false
683
+ ) );
684
+ }
685
+ add_action( 'bp_blogs_remove_data_for_blog', 'bp_blogs_delete_activity_for_site' );
686
+
687
+ /**
688
+ * Remove a blog post activity item from the activity stream.
689
+ *
690
+ * @since 1.0.0
691
+ *
692
+ * @param int $post_id ID of the post to be removed.
693
+ * @param int $blog_id Optional. Defaults to current blog ID.
694
+ * @param int $user_id Optional. Defaults to the logged-in user ID. This param
695
+ * is currently unused in the function (but is passed to hooks).
696
+ * @return bool
697
+ */
698
+ function bp_blogs_remove_post( $post_id, $blog_id = 0, $user_id = 0 ) {
699
+ global $wpdb;
700
+
701
+ if ( empty( $wpdb->blogid ) ) {
702
+ return false;
703
+ }
704
+
705
+ $post_id = (int) $post_id;
706
+
707
+ if ( ! $blog_id ) {
708
+ $blog_id = (int) $wpdb->blogid;
709
+ }
710
+
711
+ if ( ! $user_id ) {
712
+ $user_id = bp_loggedin_user_id();
713
+ }
714
+
715
+ /**
716
+ * Fires before removal of a blog post activity item from the activity stream.
717
+ *
718
+ * @since 1.5.0
719
+ *
720
+ * @param int $blog_id ID of the blog associated with the post that was removed.
721
+ * @param int $post_id ID of the post that was removed.
722
+ * @param int $user_id ID of the user having the blog removed for.
723
+ */
724
+ do_action( 'bp_blogs_before_remove_post', $blog_id, $post_id, $user_id );
725
+
726
+ bp_blogs_delete_activity( array(
727
+ 'item_id' => $blog_id,
728
+ 'secondary_item_id' => $post_id,
729
+ 'component' => buddypress()->blogs->id,
730
+ 'type' => 'new_blog_post'
731
+ ) );
732
+
733
+ /**
734
+ * Fires after removal of a blog post activity item from the activity stream.
735
+ *
736
+ * @since 1.0.0
737
+ *
738
+ * @param int $blog_id ID of the blog associated with the post that was removed.
739
+ * @param int $post_id ID of the post that was removed.
740
+ * @param int $user_id ID of the user having the blog removed for.
741
+ */
742
+ do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $user_id );
743
+ }
744
+ add_action( 'delete_post', 'bp_blogs_remove_post' );
745
+
746
  /** POST COMMENT SYNCHRONIZATION ****************************************/
747
 
748
  /**
770
  return;
771
  }
772
 
773
+ // Do not sync if the activity comment was marked as spam.
774
+ $activity = new BP_Activity_Activity( $comment_id );
775
+ if ( $activity->is_spam ) {
776
+ return;
777
+ }
778
+
779
  // Get userdata.
780
  if ( $params['user_id'] == bp_loggedin_user_id() ) {
781
  $user = buddypress()->loggedin_user->userdata;
806
  );
807
 
808
  // Prevent separate activity entry being made.
809
+ remove_action( 'comment_post', 'bp_activity_post_type_comment', 10 );
810
 
811
  // Handle multisite.
812
  switch_to_blog( $parent_activity->item_id );
832
  // permalinks to use the post comment link
833
  //
834
  // @todo since this is done after AJAX posting, the activity comment permalink
835
+ // doesn't change on the front end until the next page refresh.
836
  $resave_activity = new BP_Activity_Activity( $comment_id );
837
  $resave_activity->primary_link = get_comment_link( $post_comment_id );
838
 
970
  $old_comment_status = $post_comment_status;
971
 
972
  // No need to edit the activity, as it's the activity who's updating the comment
973
+ remove_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10 );
974
+ remove_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10 );
975
 
976
+ if ( 1 === $activity->is_spam && 'spam' !== $post_comment_status ) {
977
  wp_spam_comment( $post_comment_id );
978
  } elseif ( ! $activity->is_spam ) {
979
  if ( 'spam' === $post_comment_status ) {
1300
 
1301
  // Check comment depth and disable if depth is too large.
1302
  if ( isset( buddypress()->blogs->thread_depth[$comment->item_id] ) ){
1303
+ if ( bp_activity_get_comment_depth() > buddypress()->blogs->thread_depth[$comment->item_id] ) {
1304
  $retval = false;
1305
  }
1306
  }
bp-blogs/bp-blogs-classes.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
- /**
3
- * BuddyPress Blogs Classes.
4
- *
5
- * @package BuddyPress
6
- * @subpackage BlogsClasses
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- require dirname( __FILE__ ) . '/classes/class-bp-blogs-blog.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-blogs/bp-blogs-filters.php CHANGED
@@ -25,7 +25,6 @@ add_filter( 'bp_blog_latest_post_content', 'prepend_attachment' );
25
  *
26
  * @since 1.6.0
27
  *
28
- * @uses apply_filters() Filter 'bp_blogs_creation_location' to alter the
29
  * returned value.
30
  *
31
  * @param string $url The original URL (points to wp-signup.php by default).
@@ -122,3 +121,17 @@ function bp_blogs_post_pre_publish( $return = true, $blog_id = 0, $post_id = 0,
122
  }
123
  add_filter( 'bp_activity_post_pre_publish', 'bp_blogs_post_pre_publish', 10, 4 );
124
  add_filter( 'bp_activity_post_pre_comment', 'bp_blogs_post_pre_publish', 10, 4 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  *
26
  * @since 1.6.0
27
  *
 
28
  * returned value.
29
  *
30
  * @param string $url The original URL (points to wp-signup.php by default).
121
  }
122
  add_filter( 'bp_activity_post_pre_publish', 'bp_blogs_post_pre_publish', 10, 4 );
123
  add_filter( 'bp_activity_post_pre_comment', 'bp_blogs_post_pre_publish', 10, 4 );
124
+
125
+ /**
126
+ * Registers our custom thumb size with WP's Site Icon feature.
127
+ *
128
+ * @since 2.7.0
129
+ *
130
+ * @param array $sizes Current array of custom site icon sizes.
131
+ * @return array
132
+ */
133
+ function bp_blogs_register_custom_site_icon_size( $sizes ) {
134
+ $sizes[] = bp_core_avatar_thumb_width();
135
+ return $sizes;
136
+ }
137
+ add_filter( 'site_icon_image_sizes', 'bp_blogs_register_custom_site_icon_size' );
bp-blogs/bp-blogs-functions.php CHANGED
@@ -65,75 +65,122 @@ function bp_blogs_get_blogs( $args = '' ) {
65
  $r['include_blog_ids']
66
  );
67
 
68
- // Filter and return.
 
 
 
 
 
 
 
69
  return apply_filters( 'bp_blogs_get_blogs', $blogs, $r );
70
  }
71
 
72
  /**
73
  * Populate the BP blogs table with existing blogs.
74
  *
75
- * @since 1.0.0
 
76
  *
77
- * @global object $wpdb WordPress database object.
78
- * @uses get_users()
79
- * @uses bp_blogs_record_blog()
 
 
 
 
 
 
 
80
  *
81
  * @return bool
82
  */
83
- function bp_blogs_record_existing_blogs() {
84
  global $wpdb;
85
 
86
  // Query for all sites in network.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  if ( is_multisite() ) {
 
 
88
 
89
- // Get blog ID's if not a large network.
90
- if ( ! wp_is_large_network() ) {
91
- $blog_ids = $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$wpdb->base_prefix}blogs WHERE mature = 0 AND spam = 0 AND deleted = 0 AND site_id = %d", $wpdb->siteid ) );
 
92
 
93
- // If error running this query, set blog ID's to false.
94
- if ( is_wp_error( $blog_ids ) ) {
95
- $blog_ids = false;
96
- }
 
97
 
98
- // Large networks are not currently supported.
99
- } else {
100
- $blog_ids = false;
 
 
 
101
  }
102
 
 
 
103
  // Record a single site.
104
  } else {
105
- $blog_ids = $wpdb->blogid;
106
- }
107
 
108
- // Bail if there are no blogs in the network.
109
- if ( empty( $blog_ids ) ) {
110
- return false;
 
 
111
  }
112
 
113
- // Get BuddyPress.
114
- $bp = buddypress();
115
-
116
- // Truncate user blogs table.
117
- $truncate = $wpdb->query( "TRUNCATE {$bp->blogs->table_name}" );
118
- if ( is_wp_error( $truncate ) ) {
119
- return false;
120
- }
121
 
122
- // Truncate user blogsmeta table.
123
- $truncate = $wpdb->query( "TRUNCATE {$bp->blogs->table_name_blogmeta}" );
124
- if ( is_wp_error( $truncate ) ) {
125
  return false;
126
  }
127
 
128
  // Loop through users of blogs and record the relationship.
129
- foreach ( (array) $blog_ids as $blog_id ) {
130
 
131
  // Ensure that the cache is clear after the table TRUNCATE above.
132
- wp_cache_delete( $blog_id, 'blog_meta' );
133
 
134
  // Get all users.
135
  $users = get_users( array(
136
- 'blog_id' => $blog_id
 
137
  ) );
138
 
139
  // Continue on if no users exist for this site (how did this happen?).
@@ -142,8 +189,42 @@ function bp_blogs_record_existing_blogs() {
142
  }
143
 
144
  // Loop through users and record their relationship to this blog.
145
- foreach ( (array) $users as $user ) {
146
- bp_blogs_add_user_to_blog( $user->ID, false, $blog_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
  }
149
 
@@ -166,17 +247,32 @@ function bp_blogs_record_existing_blogs() {
166
  *
167
  * @since 1.7.0
168
  *
169
- * @uses apply_filters()
170
- *
171
  * @param int $blog_id ID of the blog being checked.
172
  * @param int $user_id Optional. ID of the user for whom access is being checked.
173
  * @return bool True if blog is recordable, otherwise false.
174
  */
175
  function bp_blogs_is_blog_recordable( $blog_id, $user_id = 0 ) {
176
 
 
 
 
 
 
 
 
 
177
  $recordable_globally = apply_filters( 'bp_blogs_is_blog_recordable', true, $blog_id );
178
 
179
  if ( !empty( $user_id ) ) {
 
 
 
 
 
 
 
 
 
180
  $recordable_for_user = apply_filters( 'bp_blogs_is_blog_recordable_for_user', $recordable_globally, $blog_id, $user_id );
181
  } else {
182
  $recordable_for_user = $recordable_globally;
@@ -197,18 +293,33 @@ function bp_blogs_is_blog_recordable( $blog_id, $user_id = 0 ) {
197
  *
198
  * @since 1.7.0
199
  *
200
- * @uses bp_blogs_is_blog_recordable
201
- * @uses apply_filters()
202
- *
203
  * @param int $blog_id ID of the blog being checked.
204
  * @param int $user_id Optional. ID of the user for whom access is being checked.
205
  * @return bool True if blog is trackable, otherwise false.
206
  */
207
  function bp_blogs_is_blog_trackable( $blog_id, $user_id = 0 ) {
208
 
 
 
 
 
 
 
 
 
209
  $trackable_globally = apply_filters( 'bp_blogs_is_blog_trackable', bp_blogs_is_blog_recordable( $blog_id, $user_id ), $blog_id );
210
 
211
  if ( !empty( $user_id ) ) {
 
 
 
 
 
 
 
 
 
 
212
  $trackable_for_user = apply_filters( 'bp_blogs_is_blog_trackable_for_user', $trackable_globally, $blog_id, $user_id );
213
  } else {
214
  $trackable_for_user = $trackable_globally;
@@ -226,8 +337,6 @@ function bp_blogs_is_blog_trackable( $blog_id, $user_id = 0 ) {
226
  *
227
  * @since 1.0.0
228
  *
229
- * @uses BP_Blogs_Blog
230
- *
231
  * @param int $blog_id ID of the blog being recorded.
232
  * @param int $user_id ID of the user for whom the blog is being recorded.
233
  * @param bool $no_activity Optional. Whether to skip recording an activity
@@ -277,30 +386,28 @@ function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
277
  bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'thread_comments_depth', $thread_depth );
278
 
279
  $is_private = !empty( $_POST['blog_public'] ) && (int) $_POST['blog_public'] ? false : true;
280
- $is_private = !apply_filters( 'bp_is_new_blog_public', !$is_private );
281
-
282
- // Only record this activity if the activity component is active and the blog is public.
283
- if ( bp_is_active( 'activity' ) && !$is_private && !$no_activity && bp_blogs_is_blog_trackable( $blog_id, $user_id ) ) {
284
 
285
- // Record this in activity streams.
286
- bp_blogs_record_activity( array(
287
- 'user_id' => $recorded_blog->user_id,
288
- 'primary_link' => apply_filters( 'bp_blogs_activity_created_blog_primary_link', $url, $recorded_blog->blog_id ),
289
- 'type' => 'new_blog',
290
- 'item_id' => $recorded_blog->blog_id
291
- ) );
292
- }
293
 
294
  /**
295
  * Fires after BuddyPress has been made aware of a new site for activity tracking.
296
  *
297
  * @since 1.0.0
 
298
  *
299
  * @param BP_Blogs_Blog $recorded_blog Current blog being recorded. Passed by reference.
300
  * @param bool $is_private Whether or not the current blog being recorded is private.
301
  * @param bool $is_recorded Whether or not the current blog was recorded.
 
302
  */
303
- do_action_ref_array( 'bp_blogs_new_blog', array( &$recorded_blog, $is_private, $is_recorded ) );
304
  }
305
  add_action( 'wpmu_new_blog', 'bp_blogs_record_blog', 10, 2 );
306
 
@@ -418,6 +525,26 @@ function bp_blogs_update_option_thread_comments_depth( $oldvalue, $newvalue ) {
418
  }
419
  add_action( 'update_option_thread_comments_depth', 'bp_blogs_update_option_thread_comments_depth', 10, 2 );
420
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
421
  /**
422
  * Deletes the 'url' blogmeta for a site.
423
  *
@@ -563,11 +690,11 @@ add_action( 'bp_activity_post_type_updated', 'bp_blogs_update_post_activity_meta
563
  *
564
  * @since 2.5.0
565
  *
566
- * @param int|bool $activity_id ID of recorded activity, or false if sync is active.
567
- * @param WP_Comment $comment The comment object.
568
- * @param array $activity_args Array of activity arguments.
569
- * @param object $activity_post_object The post type tracking args object.
570
- * @return int|bool Returns false if no activity, the activity id otherwise.
571
  */
572
  function bp_blogs_comment_sync_activity_comment( &$activity_id, $comment = null, $activity_args = array(), $activity_post_object = null ) {
573
  if ( empty( $activity_args ) || empty( $comment->post->ID ) || empty( $activity_post_object->comment_action_id ) ) {
@@ -658,6 +785,18 @@ function bp_blogs_comment_sync_activity_comment( &$activity_id, $comment = null,
658
  bp_activity_update_meta( $activity_id, 'post_url', esc_url_raw( add_query_arg( 'p', $comment->post->ID, home_url( '/' ) ) ) );
659
  }
660
  }
 
 
 
 
 
 
 
 
 
 
 
 
661
  }
662
  }
663
 
@@ -755,6 +894,14 @@ add_action( 'user_register', 'bp_blogs_add_user_to_blog' );
755
  * @return string
756
  */
757
  function bp_blogs_get_allowed_roles() {
 
 
 
 
 
 
 
 
758
  return apply_filters( 'bp_blogs_get_allowed_roles', array( 'contributor', 'author', 'editor', 'administrator' ) );
759
  }
760
 
@@ -815,19 +962,6 @@ function bp_blogs_remove_blog( $blog_id ) {
815
 
816
  BP_Blogs_Blog::delete_blog_for_all( $blog_id );
817
 
818
- /**
819
- * Delete activity stream item only if the Activity component is active
820
- *
821
- * @see https://buddypress.trac.wordpress.org/ticket/6937
822
- */
823
- if ( bp_is_active( 'activity' ) ) {
824
- bp_blogs_delete_activity( array(
825
- 'item_id' => $blog_id,
826
- 'component' => buddypress()->blogs->id,
827
- 'type' => 'new_blog'
828
- ) );
829
- }
830
-
831
  /**
832
  * Fires after a "blog created" item has been removed from blogs
833
  * tracker and activity stream.
@@ -863,19 +997,6 @@ function bp_blogs_remove_blog_for_user( $user_id, $blog_id ) {
863
 
864
  BP_Blogs_Blog::delete_blog_for_user( $blog_id, $user_id );
865
 
866
- /**
867
- * Delete activity stream item only if the Activity component is active
868
- *
869
- * @see https://buddypress.trac.wordpress.org/ticket/6937
870
- */
871
- if ( bp_is_active( 'activity' ) ) {
872
- bp_blogs_delete_activity( array(
873
- 'item_id' => $blog_id,
874
- 'component' => buddypress()->blogs->id,
875
- 'type' => 'new_blog'
876
- ) );
877
- }
878
-
879
  /**
880
  * Fires after a blog has been removed from the tracker for a specific user.
881
  *
@@ -888,67 +1009,6 @@ function bp_blogs_remove_blog_for_user( $user_id, $blog_id ) {
888
  }
889
  add_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
890
 
891
- /**
892
- * Remove a blog post activity item from the activity stream.
893
- *
894
- * @param int $post_id ID of the post to be removed.
895
- * @param int $blog_id Optional. Defaults to current blog ID.
896
- * @param int $user_id Optional. Defaults to the logged-in user ID. This param
897
- * is currently unused in the function (but is passed to hooks).
898
- * @return bool
899
- */
900
- function bp_blogs_remove_post( $post_id, $blog_id = 0, $user_id = 0 ) {
901
- global $wpdb;
902
-
903
- if ( empty( $wpdb->blogid ) )
904
- return false;
905
-
906
- $post_id = (int) $post_id;
907
-
908
- if ( !$blog_id )
909
- $blog_id = (int) $wpdb->blogid;
910
-
911
- if ( !$user_id )
912
- $user_id = bp_loggedin_user_id();
913
-
914
- /**
915
- * Fires before removal of a blog post activity item from the activity stream.
916
- *
917
- * @since 1.5.0
918
- *
919
- * @param int $blog_id ID of the blog associated with the post that was removed.
920
- * @param int $post_id ID of the post that was removed.
921
- * @param int $user_id ID of the user having the blog removed for.
922
- */
923
- do_action( 'bp_blogs_before_remove_post', $blog_id, $post_id, $user_id );
924
-
925
- /**
926
- * Delete activity stream item only if the Activity component is active
927
- *
928
- * @see https://buddypress.trac.wordpress.org/ticket/6937
929
- */
930
- if ( bp_is_active( 'activity' ) ) {
931
- bp_blogs_delete_activity( array(
932
- 'item_id' => $blog_id,
933
- 'secondary_item_id' => $post_id,
934
- 'component' => buddypress()->blogs->id,
935
- 'type' => 'new_blog_post'
936
- ) );
937
- }
938
-
939
- /**
940
- * Fires after removal of a blog post activity item from the activity stream.
941
- *
942
- * @since 1.0.0
943
- *
944
- * @param int $blog_id ID of the blog associated with the post that was removed.
945
- * @param int $post_id ID of the post that was removed.
946
- * @param int $user_id ID of the user having the blog removed for.
947
- */
948
- do_action( 'bp_blogs_remove_post', $blog_id, $post_id, $user_id );
949
- }
950
- add_action( 'delete_post', 'bp_blogs_remove_post' );
951
-
952
  /**
953
  * Remove a synced activity comment from the activity stream.
954
  *
@@ -1126,19 +1186,6 @@ function bp_blogs_remove_data_for_blog( $blog_id ) {
1126
  // If this is regular blog, delete all data for that blog.
1127
  BP_Blogs_Blog::delete_blog_for_all( $blog_id );
1128
 
1129
- /**
1130
- * Delete activity stream item only if the Activity component is active
1131
- *
1132
- * @see https://buddypress.trac.wordpress.org/ticket/6937
1133
- */
1134
- if ( bp_is_active( 'activity' ) ) {
1135
- bp_blogs_delete_activity( array(
1136
- 'item_id' => $blog_id,
1137
- 'component' => buddypress()->blogs->id,
1138
- 'type' => false
1139
- ) );
1140
- }
1141
-
1142
  /**
1143
  * Fires after all data related to a given blog has been removed from blogs tracker
1144
  * and activity stream.
65
  $r['include_blog_ids']
66
  );
67
 
68
+ /**
69
+ * Filters a set of blogs.
70
+ *
71
+ * @since 1.2.0
72
+ *
73
+ * @param array $blogs Array of blog data.
74
+ * @param array $r Parsed query arguments.
75
+ */
76
  return apply_filters( 'bp_blogs_get_blogs', $blogs, $r );
77
  }
78
 
79
  /**
80
  * Populate the BP blogs table with existing blogs.
81
  *
82
+ * Warning: By default, this will remove all existing records from the BP
83
+ * blogs and blogmeta tables before re-populating the tables.
84
  *
85
+ * @since 1.0.0
86
+ * @since 2.6.0 Accepts $args as a parameter.
87
+ *
88
+ * @param array $args {
89
+ * Array of arguments.
90
+ * @type int $offset The offset to use.
91
+ * @type int $limit The number of blogs to record at one time.
92
+ * @type array $blog_ids Blog IDs to record. If empty, all blogs will be recorded.
93
+ * @type array $site_id The network site ID to use.
94
+ * }
95
  *
96
  * @return bool
97
  */
98
+ function bp_blogs_record_existing_blogs( $args = array() ) {
99
  global $wpdb;
100
 
101
  // Query for all sites in network.
102
+ $r = bp_parse_args( $args, array(
103
+ 'offset' => false === bp_get_option( '_bp_record_blogs_offset' ) ? 0 : bp_get_option( '_bp_record_blogs_offset' ),
104
+ 'limit' => 50,
105
+ 'blog_ids' => array(),
106
+ 'site_id' => $wpdb->siteid
107
+ ), 'record_existing_blogs' );
108
+
109
+ // Truncate all BP blogs tables if starting fresh
110
+ if ( empty( $r['offset'] ) && empty( $r['blog_ids'] ) ) {
111
+ $bp = buddypress();
112
+
113
+ // Truncate user blogs table
114
+ $truncate = $wpdb->query( "TRUNCATE {$bp->blogs->table_name}" );
115
+ if ( is_wp_error( $truncate ) ) {
116
+ return false;
117
+ }
118
+
119
+ // Truncate user blogmeta table
120
+ $truncate = $wpdb->query( "TRUNCATE {$bp->blogs->table_name_blogmeta}" );
121
+ if ( is_wp_error( $truncate ) ) {
122
+ return false;
123
+ }
124
+ }
125
+
126
+ // Multisite
127
  if ( is_multisite() ) {
128
+ $sql = array();
129
+ $sql['select'] = $wpdb->prepare( "SELECT blog_id, last_updated FROM {$wpdb->base_prefix}blogs WHERE mature = 0 AND spam = 0 AND deleted = 0 AND site_id = %d", $r['site_id'] );
130
 
131
+ // Omit root blog if large network
132
+ if ( wp_is_large_network( 'users' ) ) {
133
+ $sql['omit_root_blog'] = $wpdb->prepare( "AND blog_id != %d", bp_get_root_blog_id() );
134
+ }
135
 
136
+ // Filter by selected blog IDs
137
+ if ( ! empty( $r['blog_ids'] ) ) {
138
+ $in = implode( ',', wp_parse_id_list( $r['blog_ids'] ) );
139
+ $sql['in'] = "AND blog_id IN ({$in})";
140
+ }
141
 
142
+ $sql['orderby'] = 'ORDER BY blog_id ASC';
143
+
144
+ $sql['limit'] = $wpdb->prepare( "LIMIT %d", $r['limit'] );
145
+
146
+ if ( ! empty( $r['offset'] ) ) {
147
+ $sql['offset'] = $wpdb->prepare( "OFFSET %d", $r['offset'] );
148
  }
149
 
150
+ $blogs = $wpdb->get_results( implode( ' ', $sql ) );
151
+
152
  // Record a single site.
153
  } else {
154
+ // Just record blog for the current user only.
155
+ $record = bp_blogs_record_blog( $wpdb->blogid, get_current_user_id(), true );
156
 
157
+ if ( false === $record ) {
158
+ return false;
159
+ } else {
160
+ return true;
161
+ }
162
  }
163
 
164
+ // Bail if there are no blogs
165
+ if ( empty( $blogs ) ) {
166
+ // Make sure we remove our offset marker
167
+ if ( is_multisite() ) {
168
+ bp_delete_option( '_bp_record_blogs_offset' );
169
+ }
 
 
170
 
 
 
 
171
  return false;
172
  }
173
 
174
  // Loop through users of blogs and record the relationship.
175
+ foreach ( (array) $blogs as $blog ) {
176
 
177
  // Ensure that the cache is clear after the table TRUNCATE above.
178
+ wp_cache_delete( $blog->blog_id, 'blog_meta' );
179
 
180
  // Get all users.
181
  $users = get_users( array(
182
+ 'blog_id' => $blog->blog_id,
183
+ 'fields' => 'ID'
184
  ) );
185
 
186
  // Continue on if no users exist for this site (how did this happen?).
189
  }
190
 
191
  // Loop through users and record their relationship to this blog.
192
+ foreach ( (array) $users as $user_id ) {
193
+ bp_blogs_add_user_to_blog( $user_id, false, $blog->blog_id );
194
+
195
+ // Clear cache
196
+ bp_blogs_clear_blog_object_cache( $blog->blog_id, $user_id );
197
+ }
198
+
199
+ // Update blog last activity timestamp
200
+ if ( ! empty( $blog->last_updated ) && false !== strtotime( $blog->last_updated ) ) {
201
+ bp_blogs_update_blogmeta( $blog->blog_id, 'last_activity', $blog->last_updated );
202
+ }
203
+ }
204
+
205
+ // See if we need to do this again
206
+ if ( is_multisite() && empty( $r['blog_ids'] ) ) {
207
+ $sql['offset'] = $wpdb->prepare( " OFFSET %d", $r['limit'] + $r['offset'] );
208
+
209
+ // Check if there are more blogs to record
210
+ $blog_ids = $wpdb->get_results( implode( ' ', $sql ) );
211
+
212
+ // We have more blogs; record offset and re-run function
213
+ if ( ! empty( $blog_ids ) ) {
214
+ bp_update_option( '_bp_record_blogs_offset', $r['limit'] + $r['offset'] );
215
+ bp_blogs_record_existing_blogs( array(
216
+ 'offset' => $r['limit'] + $r['offset'],
217
+ 'limit' => $r['limit'],
218
+ 'blog_ids' => $r['blog_ids'],
219
+ 'site_id' => $r['site_id']
220
+ ) );
221
+
222
+ // Bail since we have more blogs to record.
223
+ return;
224
+
225
+ // No more blogs; delete offset marker
226
+ } else {
227
+ bp_delete_option( '_bp_record_blogs_offset' );
228
  }
229
  }
230
 
247
  *
248
  * @since 1.7.0
249
  *
 
 
250
  * @param int $blog_id ID of the blog being checked.
251
  * @param int $user_id Optional. ID of the user for whom access is being checked.
252
  * @return bool True if blog is recordable, otherwise false.
253
  */
254
  function bp_blogs_is_blog_recordable( $blog_id, $user_id = 0 ) {
255
 
256
+ /**
257
+ * Filters whether or not a blog is globally activity stream recordable.
258
+ *
259
+ * @since 1.7.0
260
+ *
261
+ * @param bool $value Whether or not recordable. Default true.
262
+ * @param int $blog_id Current blog ID.
263
+ */
264
  $recordable_globally = apply_filters( 'bp_blogs_is_blog_recordable', true, $blog_id );
265
 
266
  if ( !empty( $user_id ) ) {
267
+ /**
268
+ * Filters whether or not a blog is globally activity stream recordable for user.
269
+ *
270
+ * @since 1.7.0
271
+ *
272
+ * @param bool $recordable_globally Whether or not recordable.
273
+ * @param int $blog_id Current blog ID.
274
+ * @param int $user_id Current user ID.
275
+ */
276
  $recordable_for_user = apply_filters( 'bp_blogs_is_blog_recordable_for_user', $recordable_globally, $blog_id, $user_id );
277
  } else {
278
  $recordable_for_user = $recordable_globally;
293
  *
294
  * @since 1.7.0
295
  *
 
 
 
296
  * @param int $blog_id ID of the blog being checked.
297
  * @param int $user_id Optional. ID of the user for whom access is being checked.
298
  * @return bool True if blog is trackable, otherwise false.
299
  */
300
  function bp_blogs_is_blog_trackable( $blog_id, $user_id = 0 ) {
301
 
302
+ /**
303
+ * Filters whether or not a blog is globally trackable.
304
+ *
305
+ * @since 1.7.0
306
+ *
307
+ * @param bool $value Whether or not trackable.
308
+ * @param int $blog_id Current blog ID.
309
+ */
310
  $trackable_globally = apply_filters( 'bp_blogs_is_blog_trackable', bp_blogs_is_blog_recordable( $blog_id, $user_id ), $blog_id );
311
 
312
  if ( !empty( $user_id ) ) {
313
+
314
+ /**
315
+ * Filters whether or not a blog is globally trackable for user.
316
+ *
317
+ * @since 1.7.0
318
+ *
319
+ * @param bool $value Whether or not trackable.
320
+ * @param int $blog_id Current blog ID.
321
+ * @param int $user_id Current user ID.
322
+ */
323
  $trackable_for_user = apply_filters( 'bp_blogs_is_blog_trackable_for_user', $trackable_globally, $blog_id, $user_id );
324
  } else {
325
  $trackable_for_user = $trackable_globally;
337
  *
338
  * @since 1.0.0
339
  *
 
 
340
  * @param int $blog_id ID of the blog being recorded.
341
  * @param int $user_id ID of the user for whom the blog is being recorded.
342
  * @param bool $no_activity Optional. Whether to skip recording an activity
386
  bp_blogs_update_blogmeta( $recorded_blog->blog_id, 'thread_comments_depth', $thread_depth );
387
 
388
  $is_private = !empty( $_POST['blog_public'] ) && (int) $_POST['blog_public'] ? false : true;
 
 
 
 
389
 
390
+ /**
391
+ * Filters whether or not a new blog is public.
392
+ *
393
+ * @since 1.5.0
394
+ *
395
+ * @param bool $is_private Whether or not blog is public.
396
+ */
397
+ $is_private = !apply_filters( 'bp_is_new_blog_public', !$is_private );
398
 
399
  /**
400
  * Fires after BuddyPress has been made aware of a new site for activity tracking.
401
  *
402
  * @since 1.0.0
403
+ * @since 2.6.0 Added $no_activity as a parameter.
404
  *
405
  * @param BP_Blogs_Blog $recorded_blog Current blog being recorded. Passed by reference.
406
  * @param bool $is_private Whether or not the current blog being recorded is private.
407
  * @param bool $is_recorded Whether or not the current blog was recorded.
408
+ * @param bool $no_activity Whether to skip recording an activity item for this blog creation.
409
  */
410
+ do_action_ref_array( 'bp_blogs_new_blog', array( &$recorded_blog, $is_private, $is_recorded, $no_activity ) );
411
  }
412
  add_action( 'wpmu_new_blog', 'bp_blogs_record_blog', 10, 2 );
413
 
525
  }
526
  add_action( 'update_option_thread_comments_depth', 'bp_blogs_update_option_thread_comments_depth', 10, 2 );
527
 
528
+ /**
529
+ * Syncs site icon URLs to blogmeta.
530
+ *
531
+ * @since 2.7.0
532
+ *
533
+ * @param int|string $old_value Old value
534
+ * @param int|string $new_value New value
535
+ */
536
+ function bp_blogs_update_option_site_icon( $old_value, $new_value ) {
537
+ if ( 0 === $new_value ) {
538
+ bp_blogs_update_blogmeta( get_current_blog_id(), 'site_icon_url_thumb', 0 );
539
+ bp_blogs_update_blogmeta( get_current_blog_id(), 'site_icon_url_full', 0 );
540
+ } else {
541
+ // Save site icon URL as blogmeta.
542
+ bp_blogs_update_blogmeta( get_current_blog_id(), 'site_icon_url_thumb', get_site_icon_url( bp_core_avatar_thumb_width() ) );
543
+ bp_blogs_update_blogmeta( get_current_blog_id(), 'site_icon_url_full', get_site_icon_url( bp_core_avatar_full_width() ) );
544
+ }
545
+ }
546
+ add_action( 'update_option_site_icon', 'bp_blogs_update_option_site_icon', 10, 2 );
547
+
548
  /**
549
  * Deletes the 'url' blogmeta for a site.
550
  *
690
  *
691
  * @since 2.5.0
692
  *
693
+ * @param int|bool $activity_id ID of recorded activity, or false if sync is active.
694
+ * @param WP_Comment|null $comment The comment object.
695
+ * @param array $activity_args Array of activity arguments.
696
+ * @param object|null $activity_post_object The post type tracking args object.
697
+ * @return int|bool Returns false if no activity, the activity id otherwise.
698
  */
699
  function bp_blogs_comment_sync_activity_comment( &$activity_id, $comment = null, $activity_args = array(), $activity_post_object = null ) {
700
  if ( empty( $activity_args ) || empty( $comment->post->ID ) || empty( $activity_post_object->comment_action_id ) ) {
785
  bp_activity_update_meta( $activity_id, 'post_url', esc_url_raw( add_query_arg( 'p', $comment->post->ID, home_url( '/' ) ) ) );
786
  }
787
  }
788
+
789
+ /**
790
+ * Fires after an activity comment is added from a WP post comment.
791
+ *
792
+ * @since 2.6.0
793
+ *
794
+ * @param int $activity_id The activity comment ID.
795
+ * @param WP_Comment $post_type_comment WP Comment object.
796
+ * @param array $activity_args Activity comment arguments.
797
+ * @param object $activity_post_object The post type tracking args object.
798
+ */
799
+ do_action( 'bp_blogs_comment_sync_activity_comment', $activity_id, $comment, $activity_args, $activity_post_object );
800
  }
801
  }
802
 
894
  * @return string
895
  */
896
  function bp_blogs_get_allowed_roles() {
897
+
898
+ /**
899
+ * Filters the allowed roles a member must have to be recorded into bp_user_blogs pointer table.
900
+ *
901
+ * @since 2.1.0
902
+ *
903
+ * @param array $value Array of potential roles user needs.
904
+ */
905
  return apply_filters( 'bp_blogs_get_allowed_roles', array( 'contributor', 'author', 'editor', 'administrator' ) );
906
  }
907
 
962
 
963
  BP_Blogs_Blog::delete_blog_for_all( $blog_id );
964
 
 
 
 
 
 
 
 
 
 
 
 
 
 
965
  /**
966
  * Fires after a "blog created" item has been removed from blogs
967
  * tracker and activity stream.
997
 
998
  BP_Blogs_Blog::delete_blog_for_user( $blog_id, $user_id );
999
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1000
  /**
1001
  * Fires after a blog has been removed from the tracker for a specific user.
1002
  *
1009
  }
1010
  add_action( 'remove_user_from_blog', 'bp_blogs_remove_blog_for_user', 10, 2 );
1011
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1012
  /**
1013
  * Remove a synced activity comment from the activity stream.
1014
  *
1186
  // If this is regular blog, delete all data for that blog.
1187
  BP_Blogs_Blog::delete_blog_for_all( $blog_id );
1188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1189
  /**
1190
  * Fires after all data related to a given blog has been removed from blogs tracker
1191
  * and activity stream.
bp-blogs/bp-blogs-loader.php CHANGED
@@ -14,10 +14,10 @@
14
  // Exit if accessed directly.
15
  defined( 'ABSPATH' ) || exit;
16
 
17
- require dirname( __FILE__ ) . '/classes/class-bp-blogs-component.php';
18
-
19
  /**
20
  * Set up the bp-blogs component.
 
 
21
  */
22
  function bp_setup_blogs() {
23
  buddypress()->blogs = new BP_Blogs_Component();
14
  // Exit if accessed directly.
15
  defined( 'ABSPATH' ) || exit;
16
 
 
 
17
  /**
18
  * Set up the bp-blogs component.
19
+ *
20
+ * @since 1.5.0
21
  */
22
  function bp_setup_blogs() {
23
  buddypress()->blogs = new BP_Blogs_Component();
bp-blogs/bp-blogs-screens.php CHANGED
@@ -10,8 +10,6 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- require dirname( __FILE__ ) . '/classes/class-bp-blogs-theme-compat.php';
14
-
15
  /**
16
  * Load the "My Blogs" screen.
17
  */
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
13
  /**
14
  * Load the "My Blogs" screen.
15
  */
bp-blogs/bp-blogs-template.php CHANGED
@@ -10,14 +10,11 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- require dirname( __FILE__ ) . '/classes/class-bp-blogs-template.php';
14
-
15
  /**
16
  * Output the blogs component slug.
17
  *
18
  * @since 1.5.0
19
  *
20
- * @uses bp_get_blogs_slug()
21
  */
22
  function bp_blogs_slug() {
23
  echo bp_get_blogs_slug();
@@ -46,7 +43,6 @@ function bp_blogs_slug() {
46
  *
47
  * @since 1.5.0
48
  *
49
- * @uses bp_get_blogs_root_slug()
50
  */
51
  function bp_blogs_root_slug() {
52
  echo bp_get_blogs_root_slug();
@@ -75,7 +71,6 @@ function bp_blogs_root_slug() {
75
  *
76
  * @since 1.5.0
77
  *
78
- * @uses bp_get_blogs_directory_permalink()
79
  */
80
  function bp_blogs_directory_permalink() {
81
  echo esc_url( bp_get_blogs_directory_permalink() );
@@ -85,10 +80,6 @@ function bp_blogs_directory_permalink() {
85
  *
86
  * @since 1.5.0
87
  *
88
- * @uses apply_filters()
89
- * @uses trailingslashit()
90
- * @uses bp_get_root_domain()
91
- * @uses bp_get_blogs_root_slug()
92
  *
93
  * @return string The URL of the Blogs directory.
94
  */
@@ -225,9 +216,20 @@ function bp_the_blog() {
225
  /**
226
  * Output the blogs pagination count.
227
  *
228
- * @global object $blogs_template {@link BP_Blogs_Template}
229
  */
230
  function bp_blogs_pagination_count() {
 
 
 
 
 
 
 
 
 
 
 
231
  global $blogs_template;
232
 
233
  $start_num = intval( ( $blogs_template->pag_page - 1 ) * $blogs_template->pag_num ) + 1;
@@ -241,7 +243,17 @@ function bp_blogs_pagination_count() {
241
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s site', 'Viewing %1$s - %2$s of %3$s sites', $blogs_template->total_blog_count, 'buddypress' ), $from_num, $to_num, $total );
242
  }
243
 
244
- echo $message;
 
 
 
 
 
 
 
 
 
 
245
  }
246
 
247
  /**
@@ -297,7 +309,6 @@ function bp_blog_avatar( $args = '' ) {
297
  * {@link bp_core_fetch_avatar()}.
298
  * @type string $alt Default: 'Profile picture of site author [user name]'.
299
  * @type string $class Default: 'avatar'.
300
- * @type string $title Default: 'Profile picture of site author [user name]'.
301
  * @type string $type Default: 'full'.
302
  * @type int|bool $width Default: false.
303
  * @type int|bool $height Default: false.
@@ -323,25 +334,81 @@ function bp_blog_avatar( $args = '' ) {
323
  'width' => false,
324
  'height' => false,
325
  'class' => 'avatar',
326
- 'title' => sprintf( __( 'Profile picture of site author %s', 'buddypress' ), esc_attr( $author_displayname ) ),
327
  'id' => false,
328
  'alt' => sprintf( __( 'Profile picture of site author %s', 'buddypress' ), esc_attr( $author_displayname ) ),
329
  'no_grav' => true,
330
  ) );
331
 
332
- // Fetch the avatar.
333
- $avatar = bp_core_fetch_avatar( array(
334
- 'item_id' => $blogs_template->blog->admin_user_id,
335
- 'title' => $r['title'],
336
- // 'avatar_dir' => 'blog-avatars',
337
- // 'object' => 'blog',
338
- 'type' => $r['type'],
339
- 'alt' => $r['alt'],
340
- 'css_id' => $r['id'],
341
- 'class' => $r['class'],
342
- 'width' => $r['width'],
343
- 'height' => $r['height']
344
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
345
 
346
  /**
347
  * In future BuddyPress versions you will be able to set the avatar for a blog.
@@ -571,7 +638,7 @@ function bp_blog_last_active( $args = array() ) {
571
  /**
572
  * Filters the last active date of the current blog in the loop.
573
  *
574
- * @since
575
  *
576
  * @param string $last_activity Last active date.
577
  * @param array $r Array of parsed args used to determine formatting.
@@ -629,10 +696,12 @@ function bp_blog_latest_post( $args = array() ) {
629
  * Filters the HTML markup result for the latest blog post in loop.
630
  *
631
  * @since 1.2.0
 
632
  *
633
  * @param string $retval HTML markup for the latest post.
 
634
  */
635
- return apply_filters( 'bp_get_blog_latest_post', $retval );
636
  }
637
 
638
  /**
@@ -714,7 +783,6 @@ function bp_blog_latest_post_permalink() {
714
  *
715
  * @since 1.7.0
716
  *
717
- * @uses bp_get_blog_latest_post_content()
718
  */
719
  function bp_blog_latest_post_content() {
720
  echo bp_get_blog_latest_post_content();
@@ -874,10 +942,12 @@ function bp_total_blog_count_for_user( $user_id = 0 ) {
874
  * Filters the total number of blogs for a given user.
875
  *
876
  * @since 1.2.0
 
877
  *
878
- * @param int $value Total number of blogs for a given user.
 
879
  */
880
- return apply_filters( 'bp_get_total_blog_count_for_user', bp_blogs_total_blogs_for_user( $user_id ) );
881
  }
882
  add_filter( 'bp_get_total_blog_count_for_user', 'bp_core_number_format' );
883
 
@@ -1034,9 +1104,8 @@ function bp_blogs_signup_blog( $blogname = '', $blog_title = '', $errors = '' )
1034
  echo '<input name="blog_title" type="text" id="blog_title" value="'.esc_html($blog_title, 1).'" /></p>';
1035
  ?>
1036
 
1037
- <p>
1038
- <label for="blog_public_on"><?php _e('Privacy:', 'buddypress') ?></label>
1039
- <?php _e( 'I would like my site to appear in search engines, and in public listings around this network.', 'buddypress' ); ?>
1040
 
1041
  <label class="checkbox" for="blog_public_on">
1042
  <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if( !isset( $_POST['blog_public'] ) || '1' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
@@ -1046,7 +1115,7 @@ function bp_blogs_signup_blog( $blogname = '', $blog_title = '', $errors = '' )
1046
  <input type="radio" id="blog_public_off" name="blog_public" value="0" <?php if( isset( $_POST['blog_public'] ) && '0' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
1047
  <strong><?php _e( 'No' , 'buddypress'); ?></strong>
1048
  </label>
1049
- </p>
1050
 
1051
  <?php
1052
 
@@ -1108,8 +1177,8 @@ function bp_blogs_validate_blog_signup() {
1108
  if ( is_subdomain_install() )
1109
  $domain = $blogname . '.' . preg_replace( '|^www\.|', '', $current_site->domain );
1110
 
1111
- wpmu_create_blog( $domain, $path, $blog_title, $current_user->ID, $meta, $wpdb->siteid );
1112
- bp_blogs_confirm_blog_signup($domain, $path, $blog_title, $current_user->user_login, $current_user->user_email, $meta);
1113
  return true;
1114
  }
1115
 
@@ -1131,20 +1200,38 @@ function bp_blogs_validate_blog_form() {
1131
  /**
1132
  * Display a message after successful blog registration.
1133
  *
 
 
1134
  * @param string $domain The new blog's domain.
1135
  * @param string $path The new blog's path.
1136
  * @param string $blog_title The new blog's title.
1137
  * @param string $user_name The user name of the user who created the blog. Unused.
1138
  * @param string $user_email The email of the user who created the blog. Unused.
1139
  * @param string|array $meta Meta values associated with the new blog. Unused.
 
1140
  */
1141
- function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name, $user_email = '', $meta = '' ) {
1142
- $protocol = is_ssl() ? 'https://' : 'http://';
1143
- $blog_url = $protocol . $domain . $path; ?>
 
 
1144
 
 
1145
  <p><?php _e( 'Congratulations! You have successfully registered a new site.', 'buddypress' ) ?></p>
1146
  <p>
1147
- <?php printf(__( '<a href="%1$s">%2$s</a> is your new site. <a href="%3$s">Login</a> as "%4$s" using your existing password.', 'buddypress' ), $blog_url, $blog_url, $blog_url . "wp-login.php", $user_name ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
1148
  </p>
1149
 
1150
  <?php
@@ -1264,7 +1351,6 @@ function bp_blog_create_button() {
1264
  'id' => 'create_blog',
1265
  'component' => 'blogs',
1266
  'link_text' => __( 'Create a Site', 'buddypress' ),
1267
- 'link_title' => __( 'Create a Site', 'buddypress' ),
1268
  'link_class' => 'blog-create no-ajax',
1269
  'link_href' => trailingslashit( bp_get_blogs_directory_permalink() . 'create' ),
1270
  'wrapper' => false,
@@ -1308,6 +1394,13 @@ function bp_blog_create_nav_item() {
1308
 
1309
  $output = '<li id="blog-create-nav">' . $create_blog_button . '</li>';
1310
 
 
 
 
 
 
 
 
1311
  return apply_filters( 'bp_get_blog_create_nav_item', $output );
1312
  }
1313
 
@@ -1317,8 +1410,6 @@ function bp_blog_create_nav_item() {
1317
  *
1318
  * @since 2.2.0
1319
  *
1320
- * @uses bp_blog_create_nav_item() to output the Create a Site nav item.
1321
- *
1322
  * @return string HTML Output
1323
  */
1324
  function bp_blog_backcompat_create_nav_item() {
@@ -1363,7 +1454,6 @@ function bp_blogs_visit_blog_button( $args = '' ) {
1363
  * @type string $link_href Permalink of the current blog in the loop.
1364
  * @type string $link_class Default: 'blog-button visit'.
1365
  * @type string $link_text Default: 'Visit Site'.
1366
- * @type string $link_title Default: 'Visit Site'.
1367
  * }
1368
  * @return string The HTML for the Visit button.
1369
  */
@@ -1377,7 +1467,6 @@ function bp_blogs_visit_blog_button( $args = '' ) {
1377
  'link_href' => bp_get_blog_permalink(),
1378
  'link_class' => 'blog-button visit',
1379
  'link_text' => __( 'Visit Site', 'buddypress' ),
1380
- 'link_title' => __( 'Visit Site', 'buddypress' ),
1381
  );
1382
 
1383
  $button = wp_parse_args( $args, $defaults );
@@ -1399,8 +1488,6 @@ function bp_blogs_visit_blog_button( $args = '' ) {
1399
  *
1400
  * @since 2.0.0
1401
  *
1402
- * @uses bp_blogs_admin_get_profile_stats() to get the stats.
1403
- *
1404
  * @param array|string $args Before|after|user_id.
1405
  */
1406
  function bp_blogs_profile_stats( $args = '' ) {
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
13
  /**
14
  * Output the blogs component slug.
15
  *
16
  * @since 1.5.0
17
  *
 
18
  */
19
  function bp_blogs_slug() {
20
  echo bp_get_blogs_slug();
43
  *
44
  * @since 1.5.0
45
  *
 
46
  */
47
  function bp_blogs_root_slug() {
48
  echo bp_get_blogs_root_slug();
71
  *
72
  * @since 1.5.0
73
  *
 
74
  */
75
  function bp_blogs_directory_permalink() {
76
  echo esc_url( bp_get_blogs_directory_permalink() );
80
  *
81
  * @since 1.5.0
82
  *
 
 
 
 
83
  *
84
  * @return string The URL of the Blogs directory.
85
  */
216
  /**
217
  * Output the blogs pagination count.
218
  *
219
+ * @since 1.0.0
220
  */
221
  function bp_blogs_pagination_count() {
222
+ echo bp_get_blogs_pagination_count();
223
+ }
224
+
225
+ /**
226
+ * Get the blogs pagination count.
227
+ *
228
+ * @since 2.7.0
229
+ *
230
+ * @global object $blogs_template {@link BP_Blogs_Template}
231
+ */
232
+ function bp_get_blogs_pagination_count() {
233
  global $blogs_template;
234
 
235
  $start_num = intval( ( $blogs_template->pag_page - 1 ) * $blogs_template->pag_num ) + 1;
243
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s site', 'Viewing %1$s - %2$s of %3$s sites', $blogs_template->total_blog_count, 'buddypress' ), $from_num, $to_num, $total );
244
  }
245
 
246
+ /**
247
+ * Filters the "Viewing x-y of z blogs" pagination message.
248
+ *
249
+ * @since 2.7.0
250
+ *
251
+ * @param string $message "Viewing x-y of z blogs" text.
252
+ * @param string $from_num Total amount for the low value in the range.
253
+ * @param string $to_num Total amount for the high value in the range.
254
+ * @param string $total Total amount of blogs found.
255
+ */
256
+ return apply_filters( 'bp_get_blogs_pagination_count', $message, $from_num, $to_num, $total );
257
  }
258
 
259
  /**
309
  * {@link bp_core_fetch_avatar()}.
310
  * @type string $alt Default: 'Profile picture of site author [user name]'.
311
  * @type string $class Default: 'avatar'.
 
312
  * @type string $type Default: 'full'.
313
  * @type int|bool $width Default: false.
314
  * @type int|bool $height Default: false.
334
  'width' => false,
335
  'height' => false,
336
  'class' => 'avatar',
 
337
  'id' => false,
338
  'alt' => sprintf( __( 'Profile picture of site author %s', 'buddypress' ), esc_attr( $author_displayname ) ),
339
  'no_grav' => true,
340
  ) );
341
 
342
+ // Use site icon if available.
343
+ $avatar = '';
344
+ if ( bp_is_active( 'blogs', 'site-icon' ) && function_exists( 'has_site_icon' ) ) {
345
+ $site_icon = bp_blogs_get_blogmeta( bp_get_blog_id(), "site_icon_url_{$r['type']}" );
346
+
347
+ // Never attempted to fetch site icon before; do it now!
348
+ if ( '' === $site_icon ) {
349
+ switch_to_blog( bp_get_blog_id() );
350
+
351
+ // Fetch the other size first.
352
+ if ( 'full' === $r['type'] ) {
353
+ $size = bp_core_avatar_thumb_width();
354
+ $save_size = 'thumb';
355
+ } else {
356
+ $size = bp_core_avatar_full_width();
357
+ $save_size = 'full';
358
+ }
359
+
360
+ $site_icon = get_site_icon_url( $size );
361
+ // Empty site icons get saved as integer 0.
362
+ if ( empty( $site_icon ) ) {
363
+ $site_icon = 0;
364
+ }
365
+
366
+ // Sync site icon for other size to blogmeta.
367
+ bp_blogs_update_blogmeta( bp_get_blog_id(), "site_icon_url_{$save_size}", $site_icon );
368
+
369
+ // Now, fetch the size we want.
370
+ if ( 0 !== $site_icon ) {
371
+ $size = 'full' === $r['type'] ? bp_core_avatar_full_width() : bp_core_avatar_thumb_width();
372
+ $site_icon = get_site_icon_url( $size );
373
+ }
374
+
375
+ // Sync site icon to blogmeta.
376
+ bp_blogs_update_blogmeta( bp_get_blog_id(), "site_icon_url_{$r['type']}", $site_icon );
377
+
378
+ restore_current_blog();
379
+ }
380
+
381
+ // We have a site icon.
382
+ if ( ! is_numeric( $site_icon ) ) {
383
+ if ( empty( $r['width'] ) && ! isset( $size ) ) {
384
+ $size = 'full' === $r['type'] ? bp_core_avatar_full_width() : bp_core_avatar_thumb_width();
385
+ } else {
386
+ $size = (int) $r['width'];
387
+ }
388
+
389
+ $avatar = sprintf( '<img src="%1$s" class="%2$s" width="%3$s" height="%3$s" alt="%4$s" />',
390
+ esc_url( $site_icon ),
391
+ esc_attr( "{$r['class']} avatar-{$size}" ),
392
+ esc_attr( $size ),
393
+ sprintf( esc_attr__( 'Site icon for %s', 'buddypress' ), bp_get_blog_name() )
394
+ );
395
+ }
396
+ }
397
+
398
+ // Fallback to user ID avatar.
399
+ if ( '' === $avatar ) {
400
+ $avatar = bp_core_fetch_avatar( array(
401
+ 'item_id' => $blogs_template->blog->admin_user_id,
402
+ // 'avatar_dir' => 'blog-avatars',
403
+ // 'object' => 'blog',
404
+ 'type' => $r['type'],
405
+ 'alt' => $r['alt'],
406
+ 'css_id' => $r['id'],
407
+ 'class' => $r['class'],
408
+ 'width' => $r['width'],
409
+ 'height' => $r['height']
410
+ ) );
411
+ }
412
 
413
  /**
414
  * In future BuddyPress versions you will be able to set the avatar for a blog.
638
  /**
639
  * Filters the last active date of the current blog in the loop.
640
  *
641
+ * @since 1.2.0
642
  *
643
  * @param string $last_activity Last active date.
644
  * @param array $r Array of parsed args used to determine formatting.
696
  * Filters the HTML markup result for the latest blog post in loop.
697
  *
698
  * @since 1.2.0
699
+ * @since 2.6.0 Added the `$r` parameter.
700
  *
701
  * @param string $retval HTML markup for the latest post.
702
+ * @param array $r Array of parsed arguments.
703
  */
704
+ return apply_filters( 'bp_get_blog_latest_post', $retval, $r );
705
  }
706
 
707
  /**
783
  *
784
  * @since 1.7.0
785
  *
 
786
  */
787
  function bp_blog_latest_post_content() {
788
  echo bp_get_blog_latest_post_content();
942
  * Filters the total number of blogs for a given user.
943
  *
944
  * @since 1.2.0
945
+ * @since 2.6.0 Added the `$user_id` parameter.
946
  *
947
+ * @param int $value Total number of blogs for a given user.
948
+ * @param int $user_id ID of the queried user.
949
  */
950
+ return apply_filters( 'bp_get_total_blog_count_for_user', bp_blogs_total_blogs_for_user( $user_id ), $user_id );
951
  }
952
  add_filter( 'bp_get_total_blog_count_for_user', 'bp_core_number_format' );
953
 
1104
  echo '<input name="blog_title" type="text" id="blog_title" value="'.esc_html($blog_title, 1).'" /></p>';
1105
  ?>
1106
 
1107
+ <fieldset class="create-site">
1108
+ <legend class="label"><?php _e('Privacy: I would like my site to appear in search engines, and in public listings around this network', 'buddypress') ?></legend>
 
1109
 
1110
  <label class="checkbox" for="blog_public_on">
1111
  <input type="radio" id="blog_public_on" name="blog_public" value="1" <?php if( !isset( $_POST['blog_public'] ) || '1' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
1115
  <input type="radio" id="blog_public_off" name="blog_public" value="0" <?php if( isset( $_POST['blog_public'] ) && '0' == $_POST['blog_public'] ) { ?>checked="checked"<?php } ?> />
1116
  <strong><?php _e( 'No' , 'buddypress'); ?></strong>
1117
  </label>
1118
+ </fieldset>
1119
 
1120
  <?php
1121
 
1177
  if ( is_subdomain_install() )
1178
  $domain = $blogname . '.' . preg_replace( '|^www\.|', '', $current_site->domain );
1179
 
1180
+ $blog_id = wpmu_create_blog( $domain, $path, $blog_title, $current_user->ID, $meta, $wpdb->siteid );
1181
+ bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $current_user->user_login, $current_user->user_email, $meta, $blog_id );
1182
  return true;
1183
  }
1184
 
1200
  /**
1201
  * Display a message after successful blog registration.
1202
  *
1203
+ * @since 2.6.0 Introduced `$blog_id` parameter.
1204
+ *
1205
  * @param string $domain The new blog's domain.
1206
  * @param string $path The new blog's path.
1207
  * @param string $blog_title The new blog's title.
1208
  * @param string $user_name The user name of the user who created the blog. Unused.
1209
  * @param string $user_email The email of the user who created the blog. Unused.
1210
  * @param string|array $meta Meta values associated with the new blog. Unused.
1211
+ * @param int|null $blog_id ID of the newly created blog.
1212
  */
1213
+ function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name, $user_email = '', $meta = '', $blog_id = null ) {
1214
+ switch_to_blog( $blog_id );
1215
+ $blog_url = set_url_scheme( home_url() );
1216
+ $login_url = set_url_scheme( wp_login_url() );
1217
+ restore_current_blog();
1218
 
1219
+ ?>
1220
  <p><?php _e( 'Congratulations! You have successfully registered a new site.', 'buddypress' ) ?></p>
1221
  <p>
1222
+ <?php printf(
1223
+ '%s %s',
1224
+ sprintf(
1225
+ __( '%s is your new site.', 'buddypress' ),
1226
+ sprintf( '<a href="%s">%s</a>', esc_url( $blog_url ), esc_url( $blog_url ) )
1227
+ ),
1228
+ sprintf(
1229
+ /* translators: 1: Login URL, 2: User name */
1230
+ __( '<a href="%1$s">Log in</a> as "%2$s" using your existing password.', 'buddypress' ),
1231
+ esc_url( $login_url ),
1232
+ esc_html( $user_name )
1233
+ )
1234
+ ); ?>
1235
  </p>
1236
 
1237
  <?php
1351
  'id' => 'create_blog',
1352
  'component' => 'blogs',
1353
  'link_text' => __( 'Create a Site', 'buddypress' ),
 
1354
  'link_class' => 'blog-create no-ajax',
1355
  'link_href' => trailingslashit( bp_get_blogs_directory_permalink() . 'create' ),
1356
  'wrapper' => false,
1394
 
1395
  $output = '<li id="blog-create-nav">' . $create_blog_button . '</li>';
1396
 
1397
+ /**
1398
+ * Filters the Create A Site nav item output.
1399
+ *
1400
+ * @since 2.2.0
1401
+ *
1402
+ * @param string $output Nav item output.
1403
+ */
1404
  return apply_filters( 'bp_get_blog_create_nav_item', $output );
1405
  }
1406
 
1410
  *
1411
  * @since 2.2.0
1412
  *
 
 
1413
  * @return string HTML Output
1414
  */
1415
  function bp_blog_backcompat_create_nav_item() {
1454
  * @type string $link_href Permalink of the current blog in the loop.
1455
  * @type string $link_class Default: 'blog-button visit'.
1456
  * @type string $link_text Default: 'Visit Site'.
 
1457
  * }
1458
  * @return string The HTML for the Visit button.
1459
  */
1467
  'link_href' => bp_get_blog_permalink(),
1468
  'link_class' => 'blog-button visit',
1469
  'link_text' => __( 'Visit Site', 'buddypress' ),
 
1470
  );
1471
 
1472
  $button = wp_parse_args( $args, $defaults );
1488
  *
1489
  * @since 2.0.0
1490
  *
 
 
1491
  * @param array|string $args Before|after|user_id.
1492
  */
1493
  function bp_blogs_profile_stats( $args = '' ) {
bp-blogs/bp-blogs-widgets.php CHANGED
@@ -10,8 +10,6 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- require dirname( __FILE__ ) . '/classes/class-bp-blogs-recent-posts-widget.php';
14
-
15
  /**
16
  * Register the widgets for the Blogs component.
17
  */
@@ -19,7 +17,7 @@ function bp_blogs_register_widgets() {
19
  global $wpdb;
20
 
21
  if ( bp_is_active( 'activity' ) && bp_is_root_blog( $wpdb->blogid ) ) {
22
- add_action( 'widgets_init', create_function( '', 'return register_widget("BP_Blogs_Recent_Posts_Widget");' ) );
23
  }
24
  }
25
  add_action( 'bp_register_widgets', 'bp_blogs_register_widgets' );
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
13
  /**
14
  * Register the widgets for the Blogs component.
15
  */
17
  global $wpdb;
18
 
19
  if ( bp_is_active( 'activity' ) && bp_is_root_blog( $wpdb->blogid ) ) {
20
+ add_action( 'widgets_init', function() { register_widget( 'BP_Blogs_Recent_Posts_Widget' ); } );
21
  }
22
  }
23
  add_action( 'bp_register_widgets', 'bp_blogs_register_widgets' );
bp-blogs/classes/class-bp-blogs-blog.php CHANGED
@@ -48,7 +48,7 @@ class BP_Blogs_Blog {
48
  */
49
  public function __construct( $id = null ) {
50
  if ( !empty( $id ) ) {
51
- $this->id = $id;
52
  $this->populate();
53
  }
54
  }
@@ -63,8 +63,8 @@ class BP_Blogs_Blog {
63
 
64
  $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name} WHERE id = %d", $this->id ) );
65
 
66
- $this->user_id = $blog->user_id;
67
- $this->blog_id = $blog->blog_id;
68
  }
69
 
70
  /**
@@ -75,7 +75,24 @@ class BP_Blogs_Blog {
75
  public function save() {
76
  global $wpdb;
77
 
 
 
 
 
 
 
 
 
78
  $this->user_id = apply_filters( 'bp_blogs_blog_user_id_before_save', $this->user_id, $this->id );
 
 
 
 
 
 
 
 
 
79
  $this->blog_id = apply_filters( 'bp_blogs_blog_id_before_save', $this->blog_id, $this->id );
80
 
81
  /**
@@ -243,6 +260,12 @@ class BP_Blogs_Blog {
243
 
244
  $paged_blogs = BP_Blogs_Blog::get_blog_extras( $paged_blogs, $blog_ids, $type );
245
 
 
 
 
 
 
 
246
  if ( $update_meta_cache ) {
247
  bp_blogs_update_meta_cache( $blog_ids );
248
  }
@@ -338,8 +361,8 @@ class BP_Blogs_Blog {
338
  $user_blogs = array();
339
  foreach ( (array) $blogs as $blog ) {
340
  $user_blogs[$blog->blog_id] = new stdClass;
341
- $user_blogs[$blog->blog_id]->id = $blog->id;
342
- $user_blogs[$blog->blog_id]->blog_id = $blog->blog_id;
343
  $user_blogs[$blog->blog_id]->siteurl = ( is_ssl() ) ? 'https://' . $blog->domain . $blog->path : 'http://' . $blog->domain . $blog->path;
344
  $user_blogs[$blog->blog_id]->name = $blog->name;
345
  }
@@ -364,7 +387,7 @@ class BP_Blogs_Blog {
364
  if ( !$user_id )
365
  $user_id = bp_displayed_user_id();
366
 
367
- return $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$bp->blogs->table_name} WHERE user_id = %d", $user_id ) );
368
  }
369
 
370
  /**
@@ -379,7 +402,9 @@ class BP_Blogs_Blog {
379
 
380
  $bp = buddypress();
381
 
382
- return $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
 
 
383
  }
384
 
385
  /**
@@ -444,7 +469,12 @@ class BP_Blogs_Blog {
444
  $paged_blogs = $wpdb->get_results( "SELECT DISTINCT bm.blog_id FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE ( ( bm.meta_key = 'name' OR bm.meta_key = 'description' ) AND {$search_terms_sql} ) {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY meta_value ASC{$pag_sql}" );
445
  $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT bm.blog_id) FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE ( ( bm.meta_key = 'name' OR bm.meta_key = 'description' ) AND {$search_terms_sql} ) {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY meta_value ASC" );
446
 
447
- return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
 
 
 
 
 
448
  }
449
 
450
  /**
@@ -472,7 +502,12 @@ class BP_Blogs_Blog {
472
  $paged_blogs = $wpdb->get_results( "SELECT DISTINCT b.blog_id FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 {$hidden_sql} {$pag_sql}" );
473
  $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 {$hidden_sql}" );
474
 
475
- return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
 
 
 
 
 
476
  }
477
 
478
  /**
@@ -509,7 +544,12 @@ class BP_Blogs_Blog {
509
  $paged_blogs = $wpdb->get_results( "SELECT DISTINCT bm.blog_id FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE bm.meta_key = 'name' AND {$letter_sql} {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY bm.meta_value ASC{$pag_sql}" );
510
  $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT bm.blog_id) FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE bm.meta_key = 'name' AND {$letter_sql} {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY bm.meta_value ASC" );
511
 
512
- return array( 'blogs' => $paged_blogs, 'total' => $total_blogs );
 
 
 
 
 
513
  }
514
 
515
  /**
48
  */
49
  public function __construct( $id = null ) {
50
  if ( !empty( $id ) ) {
51
+ $this->id = (int) $id;
52
  $this->populate();
53
  }
54
  }
63
 
64
  $blog = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$bp->blogs->table_name} WHERE id = %d", $this->id ) );
65
 
66
+ $this->user_id = (int) $blog->user_id;
67
+ $this->blog_id = (int) $blog->blog_id;
68
  }
69
 
70
  /**
75
  public function save() {
76
  global $wpdb;
77
 
78
+ /**
79
+ * Filters the blog user ID before save.
80
+ *
81
+ * @since 1.0.0
82
+ *
83
+ * @param int $value User ID.
84
+ * @param int $value Site ID.
85
+ */
86
  $this->user_id = apply_filters( 'bp_blogs_blog_user_id_before_save', $this->user_id, $this->id );
87
+
88
+ /**
89
+ * Filters the blog blog ID before save.
90
+ *
91
+ * @since 1.0.0
92
+ *
93
+ * @param int $value Blog ID.
94
+ * @param int $value Site ID.
95
+ */
96
  $this->blog_id = apply_filters( 'bp_blogs_blog_id_before_save', $this->blog_id, $this->id );
97
 
98
  /**
260
 
261
  $paged_blogs = BP_Blogs_Blog::get_blog_extras( $paged_blogs, $blog_ids, $type );
262
 
263
+ // Integer casting.
264
+ foreach ( (array) $paged_blogs as $key => $data ) {
265
+ $paged_blogs[ $key ]->blog_id = (int) $paged_blogs[ $key ]->blog_id;
266
+ $paged_blogs[ $key ]->admin_user_id = (int) $paged_blogs[ $key ]->admin_user_id;
267
+ }
268
+
269
  if ( $update_meta_cache ) {
270
  bp_blogs_update_meta_cache( $blog_ids );
271
  }
361
  $user_blogs = array();
362
  foreach ( (array) $blogs as $blog ) {
363
  $user_blogs[$blog->blog_id] = new stdClass;
364
+ $user_blogs[$blog->blog_id]->id = (int) $blog->id;
365
+ $user_blogs[$blog->blog_id]->blog_id = (int) $blog->blog_id;
366
  $user_blogs[$blog->blog_id]->siteurl = ( is_ssl() ) ? 'https://' . $blog->domain . $blog->path : 'http://' . $blog->domain . $blog->path;
367
  $user_blogs[$blog->blog_id]->name = $blog->name;
368
  }
387
  if ( !$user_id )
388
  $user_id = bp_displayed_user_id();
389
 
390
+ return array_map( 'intval', $wpdb->get_col( $wpdb->prepare( "SELECT blog_id FROM {$bp->blogs->table_name} WHERE user_id = %d", $user_id ) ) );
391
  }
392
 
393
  /**
402
 
403
  $bp = buddypress();
404
 
405
+ $query = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->blogs->table_name} WHERE blog_id = %d", $blog_id ) );
406
+
407
+ return is_numeric( $query ) ? (int) $query : $query;
408
  }
409
 
410
  /**
469
  $paged_blogs = $wpdb->get_results( "SELECT DISTINCT bm.blog_id FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE ( ( bm.meta_key = 'name' OR bm.meta_key = 'description' ) AND {$search_terms_sql} ) {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY meta_value ASC{$pag_sql}" );
470
  $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT bm.blog_id) FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE ( ( bm.meta_key = 'name' OR bm.meta_key = 'description' ) AND {$search_terms_sql} ) {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY meta_value ASC" );
471
 
472
+ // Integer casting.
473
+ foreach ( (array) $paged_blogs as $key => $data ) {
474
+ $paged_blogs[ $key ]->blog_id = (int) $paged_blogs[ $key ]->blog_id;
475
+ }
476
+
477
+ return array( 'blogs' => $paged_blogs, 'total' => (int) $total_blogs );
478
  }
479
 
480
  /**
502
  $paged_blogs = $wpdb->get_results( "SELECT DISTINCT b.blog_id FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 {$hidden_sql} {$pag_sql}" );
503
  $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT b.blog_id) FROM {$bp->blogs->table_name} b LEFT JOIN {$wpdb->base_prefix}blogs wb ON b.blog_id = wb.blog_id WHERE wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 {$hidden_sql}" );
504
 
505
+ // Integer casting.
506
+ foreach ( (array) $paged_blogs as $key => $data ) {
507
+ $paged_blogs[ $key ]->blog_id = (int) $paged_blogs[ $key ]->blog_id;
508
+ }
509
+
510
+ return array( 'blogs' => $paged_blogs, 'total' => (int) $total_blogs );
511
  }
512
 
513
  /**
544
  $paged_blogs = $wpdb->get_results( "SELECT DISTINCT bm.blog_id FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE bm.meta_key = 'name' AND {$letter_sql} {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY bm.meta_value ASC{$pag_sql}" );
545
  $total_blogs = $wpdb->get_var( "SELECT COUNT(DISTINCT bm.blog_id) FROM {$bp->blogs->table_name_blogmeta} bm LEFT JOIN {$wpdb->base_prefix}blogs wb ON bm.blog_id = wb.blog_id WHERE bm.meta_key = 'name' AND {$letter_sql} {$hidden_sql} AND wb.mature = 0 AND wb.spam = 0 AND wb.archived = '0' AND wb.deleted = 0 ORDER BY bm.meta_value ASC" );
546
 
547
+ // Integer casting.
548
+ foreach ( (array) $paged_blogs as $key => $data ) {
549
+ $paged_blogs[ $key ]->blog_id = (int) $paged_blogs[ $key ]->blog_id;
550
+ }
551
+
552
+ return array( 'blogs' => $paged_blogs, 'total' => (int) $total_blogs );
553
  }
554
 
555
  /**
bp-blogs/classes/class-bp-blogs-component.php CHANGED
@@ -32,6 +32,7 @@ class BP_Blogs_Component extends BP_Component {
32
  array(
33
  'adminbar_myaccount_order' => 30,
34
  'search_query_arg' => 'sites_search',
 
35
  )
36
  );
37
  }
@@ -65,12 +66,16 @@ class BP_Blogs_Component extends BP_Component {
65
  'blog' => $bp->table_prefix . 'bp_user_blogs_blogmeta',
66
  );
67
 
 
 
 
 
68
  // All globals for blogs component.
69
  $args = array(
70
  'slug' => BP_BLOGS_SLUG,
71
  'root_slug' => isset( $bp->pages->blogs->slug ) ? $bp->pages->blogs->slug : BP_BLOGS_SLUG,
72
  'has_directory' => is_multisite(), // Non-multisite installs don't need a top-level Sites directory, since there's only one site.
73
- 'directory_title' => _x( 'Sites', 'component directory title', 'buddypress' ),
74
  'notification_callback' => 'bp_blogs_format_notifications',
75
  'search_string' => __( 'Search sites...', 'buddypress' ),
76
  'autocomplete_all' => defined( 'BP_MESSAGES_AUTOCOMPLETE_ALL' ),
@@ -122,7 +127,6 @@ class BP_Blogs_Component extends BP_Component {
122
  'cache',
123
  'actions',
124
  'screens',
125
- 'classes',
126
  'template',
127
  'filters',
128
  'functions',
@@ -176,7 +180,15 @@ class BP_Blogs_Component extends BP_Component {
176
  // Add 'Sites' to the main navigation.
177
  $count = (int) bp_get_total_blog_count_for_user();
178
  $class = ( 0 === $count ) ? 'no-count' : 'count';
179
- $nav_text = sprintf( __( 'Sites <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), bp_core_number_format( $count ) );
 
 
 
 
 
 
 
 
180
  $main_nav = array(
181
  'name' => $nav_text,
182
  'slug' => $slug,
32
  array(
33
  'adminbar_myaccount_order' => 30,
34
  'search_query_arg' => 'sites_search',
35
+ 'features' => array( 'site-icon' )
36
  )
37
  );
38
  }
66
  'blog' => $bp->table_prefix . 'bp_user_blogs_blogmeta',
67
  );
68
 
69
+ // Fetch the default directory title.
70
+ $default_directory_titles = bp_core_get_directory_page_default_titles();
71
+ $default_directory_title = $default_directory_titles[$this->id];
72
+
73
  // All globals for blogs component.
74
  $args = array(
75
  'slug' => BP_BLOGS_SLUG,
76
  'root_slug' => isset( $bp->pages->blogs->slug ) ? $bp->pages->blogs->slug : BP_BLOGS_SLUG,
77
  'has_directory' => is_multisite(), // Non-multisite installs don't need a top-level Sites directory, since there's only one site.
78
+ 'directory_title' => isset( $bp->pages->blogs->title ) ? $bp->pages->blogs->title : $default_directory_title,
79
  'notification_callback' => 'bp_blogs_format_notifications',
80
  'search_string' => __( 'Search sites...', 'buddypress' ),
81
  'autocomplete_all' => defined( 'BP_MESSAGES_AUTOCOMPLETE_ALL' ),
127
  'cache',
128
  'actions',
129
  'screens',
 
130
  'template',
131
  'filters',
132
  'functions',
180
  // Add 'Sites' to the main navigation.
181
  $count = (int) bp_get_total_blog_count_for_user();
182
  $class = ( 0 === $count ) ? 'no-count' : 'count';
183
+ $nav_text = sprintf(
184
+ /* translators: %s: Site count for the current user */
185
+ __( 'Sites %s', 'buddypress' ),
186
+ sprintf(
187
+ '<span class="%s">%s</span>',
188
+ esc_attr( $class ),
189
+ bp_core_number_format( $count )
190
+ )
191
+ );
192
  $main_nav = array(
193
  'name' => $nav_text,
194
  'slug' => $slug,
bp-blogs/classes/class-bp-blogs-recent-posts-widget.php CHANGED
@@ -20,8 +20,9 @@ class BP_Blogs_Recent_Posts_Widget extends WP_Widget {
20
  */
21
  public function __construct() {
22
  $widget_ops = array(
23
- 'description' => __( 'A list of recently published posts from across your network.', 'buddypress' ),
24
- 'classname' => 'widget_bp_blogs_widget buddypress widget',
 
25
  );
26
  parent::__construct( false, $name = _x( '(BuddyPress) Recent Networkwide Posts', 'widget name', 'buddypress' ), $widget_ops );
27
  }
20
  */
21
  public function __construct() {
22
  $widget_ops = array(
23
+ 'description' => __( 'A list of recently published posts from across your network.', 'buddypress' ),
24
+ 'classname' => 'widget_bp_blogs_widget buddypress widget',
25
+ 'customize_selective_refresh' => true,
26
  );
27
  parent::__construct( false, $name = _x( '(BuddyPress) Recent Networkwide Posts', 'widget name', 'buddypress' ), $widget_ops );
28
  }
bp-core/admin/bp-core-admin-actions.php CHANGED
@@ -106,7 +106,6 @@ function bp_new_site( $blog_id, $user_id, $domain, $path, $site_id, $meta ) {
106
  *
107
  * @since 1.7.0
108
  *
109
- * @uses do_action() Calls 'bp_admin_init'.
110
  */
111
  function bp_admin_init() {
112
 
@@ -123,7 +122,6 @@ function bp_admin_init() {
123
  *
124
  * @since 1.7.0
125
  *
126
- * @uses do_action() Calls 'bp_admin_menu'.
127
  */
128
  function bp_admin_menu() {
129
 
@@ -140,7 +138,6 @@ function bp_admin_menu() {
140
  *
141
  * @since 1.7.0
142
  *
143
- * @uses do_action() Calls 'bp_admin_head'.
144
  */
145
  function bp_admin_head() {
146
 
@@ -157,7 +154,6 @@ function bp_admin_head() {
157
  *
158
  * @since 1.7.0
159
  *
160
- * @uses do_action() Calls 'bp_admin_notices'.
161
  */
162
  function bp_admin_notices() {
163
 
@@ -174,8 +170,6 @@ function bp_admin_notices() {
174
  *
175
  * @since 1.7.0
176
  *
177
- * @uses do_action() Calls 'bp_admin_enqueue_scripts'.
178
- *
179
  * @param string $hook_suffix The current admin page, passed to
180
  * 'admin_enqueue_scripts'.
181
  */
@@ -196,7 +190,6 @@ function bp_admin_enqueue_scripts( $hook_suffix = '' ) {
196
  *
197
  * @since 1.7.0
198
  *
199
- * @uses do_action() Calls 'bp_admin_notices'.
200
  */
201
  function bp_register_importers() {
202
 
@@ -215,7 +208,6 @@ function bp_register_importers() {
215
  *
216
  * @since 1.7.0
217
  *
218
- * @uses do_action() Calls 'bp_admin_notices'.
219
  */
220
  function bp_register_admin_style() {
221
 
@@ -232,7 +224,6 @@ function bp_register_admin_style() {
232
  *
233
  * @since 1.7.0
234
  *
235
- * @uses do_action() Calls 'bp_register_admin_settings'.
236
  */
237
  function bp_register_admin_settings() {
238
 
106
  *
107
  * @since 1.7.0
108
  *
 
109
  */
110
  function bp_admin_init() {
111
 
122
  *
123
  * @since 1.7.0
124
  *
 
125
  */
126
  function bp_admin_menu() {
127
 
138
  *
139
  * @since 1.7.0
140
  *
 
141
  */
142
  function bp_admin_head() {
143
 
154
  *
155
  * @since 1.7.0
156
  *
 
157
  */
158
  function bp_admin_notices() {
159
 
170
  *
171
  * @since 1.7.0
172
  *
 
 
173
  * @param string $hook_suffix The current admin page, passed to
174
  * 'admin_enqueue_scripts'.
175
  */
190
  *
191
  * @since 1.7.0
192
  *
 
193
  */
194
  function bp_register_importers() {
195
 
208
  *
209
  * @since 1.7.0
210
  *
 
211
  */
212
  function bp_register_admin_style() {
213
 
224
  *
225
  * @since 1.7.0
226
  *
 
227
  */
228
  function bp_register_admin_settings() {
229
 
bp-core/admin/bp-core-admin-classes.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
- /**
3
- * Core component classes for wp-admin screens.
4
- *
5
- * @package BuddyPress
6
- * @subpackage Core
7
- * @since 2.5.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- require dirname( dirname( __FILE__ ) ) . '/classes/class-bp-walker-category-checklist.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core/admin/bp-core-admin-components.php CHANGED
@@ -15,7 +15,6 @@ defined( 'ABSPATH' ) || exit;
15
  *
16
  * @since 1.6.0
17
  *
18
- * @uses bp_core_admin_component_options()
19
  */
20
  function bp_core_admin_components_settings() {
21
  ?>
@@ -150,7 +149,10 @@ function bp_core_admin_components_options() {
150
  break;
151
  } ?>
152
 
153
- <h3 class="screen-reader-text"><?php _e( 'Filter components list', 'buddypress' ); ?></h3>
 
 
 
154
 
155
  <ul class="subsubsub">
156
  <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'all' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'all' ) : ?>class="current"<?php endif; ?>><?php printf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $all_count, 'plugins', 'buddypress' ), number_format_i18n( $all_count ) ); ?></a> | </li>
@@ -160,12 +162,18 @@ function bp_core_admin_components_options() {
160
  <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'retired' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'retired' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>', count( $retired_components ), 'buddypress' ), number_format_i18n( count( $retired_components ) ) ); ?></a></li>
161
  </ul>
162
 
163
- <h3 class="screen-reader-text"><?php _e( 'Components list', 'buddypress' ); ?></h3>
 
 
 
164
 
165
  <table class="wp-list-table widefat plugins">
166
  <thead>
167
  <tr>
168
- <td id="cb" class="manage-column column-cb check-column"><input id="cb-select-all-1" type="checkbox" disabled><label class="screen-reader-text" for="cb-select-all-1"><?php _e( 'Bulk selection is disabled', 'buddypress' ); ?></label></td>
 
 
 
169
  <th scope="col" id="name" class="manage-column column-title column-primary"><?php _e( 'Component', 'buddypress' ); ?></th>
170
  <th scope="col" id="description" class="manage-column column-description"><?php _e( 'Description', 'buddypress' ); ?></th>
171
  </tr>
@@ -188,17 +196,21 @@ function bp_core_admin_components_options() {
188
 
189
  <?php if ( !in_array( $name, array( 'core', 'members' ) ) ) : ?>
190
 
191
- <input type="checkbox" id="<?php echo esc_attr( "bp_components[$name]" ); ?>" name="<?php echo esc_attr( "bp_components[$name]" ); ?>" value="1"<?php checked( isset( $active_components[esc_attr( $name )] ) ); ?> /><label for="<?php echo esc_attr( "bp_components[$name]" ); ?>" class="screen-reader-text"><?php printf( __( 'Select %s', 'buddypress' ), esc_html( $labels['title'] ) ); ?></label>
 
 
192
 
193
  <?php else : ?>
194
 
195
- <input type="checkbox" id="<?php echo esc_attr( "bp_components[$name]" ); ?>" name="<?php echo esc_attr( "bp_components[$name]" ); ?>" value="1" checked="checked" disabled><label for="<?php echo esc_attr( "bp_components[$name]" ); ?>" class="screen-reader-text"><?php printf( __( '%s is a required component', 'buddypress' ), esc_html( $labels['title'] ) ); ?></label>
 
 
196
 
197
  <?php endif; ?>
198
 
199
  </th>
200
  <td class="plugin-title column-primary">
201
- <span></span>
202
  <strong><?php echo esc_html( $labels['title'] ); ?></strong>
203
  </td>
204
 
@@ -224,7 +236,10 @@ function bp_core_admin_components_options() {
224
 
225
  <tfoot>
226
  <tr>
227
- <td class="manage-column column-cb check-column"><input id="cb-select-all-2" type="checkbox" disabled><label class="screen-reader-text" for="cb-select-all-2"><?php _e( 'Bulk selection is disabled', 'buddypress' ); ?></label></td>
 
 
 
228
  <th class="manage-column column-title column-primary"><?php _e( 'Component', 'buddypress' ); ?></th>
229
  <th class="manage-column column-description"><?php _e( 'Description', 'buddypress' ); ?></th>
230
  </tr>
@@ -261,6 +276,7 @@ function bp_core_admin_components_settings_handler() {
261
  $bp = buddypress();
262
 
263
  // Save settings and upgrade schema.
 
264
  require_once( $bp->plugin_dir . '/bp-core/admin/bp-core-admin-schema.php' );
265
 
266
  $submitted = stripslashes_deep( $_POST['bp_components'] );
@@ -340,100 +356,18 @@ function bp_core_admin_get_active_components_from_submitted_settings( $submitted
340
  }
341
 
342
  /**
343
- * Return a list of component information, optionally filtered by type.
344
  *
345
  * We use this information both to build the markup for the admin screens, as
346
  * well as to do some processing on settings data submitted from those screens.
347
  *
348
  * @since 1.7.0
349
  *
350
- * @param string $type 'all', 'optional', 'retired', 'required'.
351
- * @return array An array of requested component data.
352
  */
353
  function bp_core_admin_get_components( $type = 'all' ) {
354
-
355
- // Required components.
356
- $required_components = array(
357
- 'core' => array(
358
- 'title' => __( 'BuddyPress Core', 'buddypress' ),
359
- 'description' => __( 'It&#8216;s what makes <del>time travel</del> BuddyPress possible!', 'buddypress' )
360
- ),
361
- 'members' => array(
362
- 'title' => __( 'Community Members', 'buddypress' ),
363
- 'description' => __( 'Everything in a BuddyPress community revolves around its members.', 'buddypress' )
364
- ),
365
- );
366
-
367
- // Retired components.
368
- $retired_components = array(
369
- 'forums' => array(
370
- 'title' => __( 'Group Forums', 'buddypress' ),
371
- 'description' => sprintf( __( 'BuddyPress Forums are retired. Use %s.', 'buddypress' ), '<a href="https://bbpress.org/">bbPress</a>' )
372
- ),
373
- );
374
-
375
- // Optional core components.
376
- $optional_components = array(
377
- 'xprofile' => array(
378
- 'title' => __( 'Extended Profiles', 'buddypress' ),
379
- 'description' => __( 'Customize your community with fully editable profile fields that allow your users to describe themselves.', 'buddypress' )
380
- ),
381
- 'settings' => array(
382
- 'title' => __( 'Account Settings', 'buddypress' ),
383
- 'description' => __( 'Allow your users to modify their account and notification settings directly from within their profiles.', 'buddypress' )
384
- ),
385
- 'friends' => array(
386
- 'title' => __( 'Friend Connections', 'buddypress' ),
387
- 'description' => __( 'Let your users make connections so they can track the activity of others and focus on the people they care about the most.', 'buddypress' )
388
- ),
389
- 'messages' => array(
390
- 'title' => __( 'Private Messaging', 'buddypress' ),
391
- 'description' => __( 'Allow your users to talk to each other directly and in private. Not just limited to one-on-one discussions, messages can be sent between any number of members.', 'buddypress' )
392
- ),
393
- 'activity' => array(
394
- 'title' => __( 'Activity Streams', 'buddypress' ),
395
- 'description' => __( 'Global, personal, and group activity streams with threaded commenting, direct posting, favoriting, and @mentions, all with full RSS feed and email notification support.', 'buddypress' )
396
- ),
397
- 'notifications' => array(
398
- 'title' => __( 'Notifications', 'buddypress' ),
399
- 'description' => __( 'Notify members of relevant activity with a toolbar bubble and/or via email, and allow them to customize their notification settings.', 'buddypress' )
400
- ),
401
- 'groups' => array(
402
- 'title' => __( 'User Groups', 'buddypress' ),
403
- 'description' => __( 'Groups allow your users to organize themselves into specific public, private or hidden sections with separate activity streams and member listings.', 'buddypress' )
404
- ),
405
- 'forums' => array(
406
- 'title' => __( 'Group Forums (Legacy)', 'buddypress' ),
407
- 'description' => __( 'Group forums allow for focused, bulletin-board style conversations.', 'buddypress' )
408
- ),
409
- 'blogs' => array(
410
- 'title' => __( 'Site Tracking', 'buddypress' ),
411
- 'description' => __( 'Record activity for new posts and comments from your site.', 'buddypress' )
412
- )
413
- );
414
-
415
-
416
- // Add blogs tracking if multisite.
417
- if ( is_multisite() ) {
418
- $optional_components['blogs']['description'] = __( 'Record activity for new sites, posts, and comments across your network.', 'buddypress' );
419
- }
420
-
421
- switch ( $type ) {
422
- case 'required' :
423
- $components = $required_components;
424
- break;
425
- case 'optional' :
426
- $components = $optional_components;
427
- break;
428
- case 'retired' :
429
- $components = $retired_components;
430
- break;
431
- case 'all' :
432
- default :
433
- $components = array_merge( $required_components, $optional_components, $retired_components );
434
- break;
435
-
436
- }
437
 
438
  /**
439
  * Filters the list of component information.
15
  *
16
  * @since 1.6.0
17
  *
 
18
  */
19
  function bp_core_admin_components_settings() {
20
  ?>
149
  break;
150
  } ?>
151
 
152
+ <h3 class="screen-reader-text"><?php
153
+ /* translators: accessibility text */
154
+ _e( 'Filter components list', 'buddypress' );
155
+ ?></h3>
156
 
157
  <ul class="subsubsub">
158
  <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'all' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'all' ) : ?>class="current"<?php endif; ?>><?php printf( _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $all_count, 'plugins', 'buddypress' ), number_format_i18n( $all_count ) ); ?></a> | </li>
162
  <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'retired' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'retired' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>', count( $retired_components ), 'buddypress' ), number_format_i18n( count( $retired_components ) ) ); ?></a></li>
163
  </ul>
164
 
165
+ <h3 class="screen-reader-text"><?php
166
+ /* translators: accessibility text */
167
+ _e( 'Components list', 'buddypress' );
168
+ ?></h3>
169
 
170
  <table class="wp-list-table widefat plugins">
171
  <thead>
172
  <tr>
173
+ <td id="cb" class="manage-column column-cb check-column"><input id="cb-select-all-1" type="checkbox" disabled><label class="screen-reader-text" for="cb-select-all-1"><?php
174
+ /* translators: accessibility text */
175
+ _e( 'Bulk selection is disabled', 'buddypress' );
176
+ ?></label></td>
177
  <th scope="col" id="name" class="manage-column column-title column-primary"><?php _e( 'Component', 'buddypress' ); ?></th>
178
  <th scope="col" id="description" class="manage-column column-description"><?php _e( 'Description', 'buddypress' ); ?></th>
179
  </tr>
196
 
197
  <?php if ( !in_array( $name, array( 'core', 'members' ) ) ) : ?>
198
 
199
+ <input type="checkbox" id="<?php echo esc_attr( "bp_components[$name]" ); ?>" name="<?php echo esc_attr( "bp_components[$name]" ); ?>" value="1"<?php checked( isset( $active_components[esc_attr( $name )] ) ); ?> /><label for="<?php echo esc_attr( "bp_components[$name]" ); ?>" class="screen-reader-text"><?php
200
+ /* translators: accessibility text */
201
+ printf( __( 'Select %s', 'buddypress' ), esc_html( $labels['title'] ) ); ?></label>
202
 
203
  <?php else : ?>
204
 
205
+ <input type="checkbox" id="<?php echo esc_attr( "bp_components[$name]" ); ?>" name="<?php echo esc_attr( "bp_components[$name]" ); ?>" value="1" checked="checked" disabled><label for="<?php echo esc_attr( "bp_components[$name]" ); ?>" class="screen-reader-text"><?php
206
+ /* translators: accessibility text */
207
+ printf( __( '%s is a required component', 'buddypress' ), esc_html( $labels['title'] ) ); ?></label>
208
 
209
  <?php endif; ?>
210
 
211
  </th>
212
  <td class="plugin-title column-primary">
213
+ <span aria-hidden="true"></span>
214
  <strong><?php echo esc_html( $labels['title'] ); ?></strong>
215
  </td>
216
 
236
 
237
  <tfoot>
238
  <tr>
239
+ <td class="manage-column column-cb check-column"><input id="cb-select-all-2" type="checkbox" disabled><label class="screen-reader-text" for="cb-select-all-2"><?php
240
+ /* translators: accessibility text */
241
+ _e( 'Bulk selection is disabled', 'buddypress' );
242
+ ?></label></td>
243
  <th class="manage-column column-title column-primary"><?php _e( 'Component', 'buddypress' ); ?></th>
244
  <th class="manage-column column-description"><?php _e( 'Description', 'buddypress' ); ?></th>
245
  </tr>
276
  $bp = buddypress();
277
 
278
  // Save settings and upgrade schema.
279
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
280
  require_once( $bp->plugin_dir . '/bp-core/admin/bp-core-admin-schema.php' );
281
 
282
  $submitted = stripslashes_deep( $_POST['bp_components'] );
356
  }
357
 
358
  /**
359
+ * Return a list of component information.
360
  *
361
  * We use this information both to build the markup for the admin screens, as
362
  * well as to do some processing on settings data submitted from those screens.
363
  *
364
  * @since 1.7.0
365
  *
366
+ * @param string $type Optional; component type to fetch. Default value is 'all', or 'optional', 'retired', 'required'.
367
+ * @return array Requested components' data.
368
  */
369
  function bp_core_admin_get_components( $type = 'all' ) {
370
+ $components = bp_core_get_components( $type );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
 
372
  /**
373
  * Filters the list of component information.
bp-core/admin/bp-core-admin-functions.php CHANGED
@@ -15,7 +15,6 @@ defined( 'ABSPATH' ) || exit;
15
  /**
16
  * Initializes the wp-admin area "BuddyPress" menus and sub menus.
17
  *
18
- * @uses bp_current_user_can() returns true if the current user is a site admin, false if not.
19
  */
20
  function bp_core_admin_menu_init() {
21
  add_action( bp_core_admin_hook(), 'bp_core_add_admin_menu', 9 );
@@ -123,8 +122,6 @@ function bp_core_admin_backpat_page() {
123
  *
124
  * @since 1.5.0
125
  *
126
- * @uses bp_current_user_can() to check current user permissions before showing the notices.
127
- * @uses bp_is_root_blog()
128
  */
129
  function bp_core_print_admin_notices() {
130
 
@@ -302,7 +299,15 @@ function bp_core_activation_notice() {
302
 
303
  if ( !empty( $orphaned_components ) ) {
304
  $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
305
- $notice = sprintf( __( 'The following active BuddyPress Components do not have associated WordPress Pages: %2$s. <a href="%1$s">Repair</a>', 'buddypress' ), esc_url( $admin_url ), '<strong>' . implode( '</strong>, <strong>', $orphaned_components ) . '</strong>' );
 
 
 
 
 
 
 
 
306
 
307
  bp_core_add_admin_notice( $notice );
308
  }
@@ -324,7 +329,15 @@ function bp_core_activation_notice() {
324
  // If there are duplicates, post a message about them.
325
  if ( !empty( $dupe_names ) ) {
326
  $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
327
- $notice = sprintf( __( 'Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %2$s. <a href="%1$s">Repair</a>', 'buddypress' ), esc_url( $admin_url ), '<strong>' . implode( '</strong>, <strong>', $dupe_names ) . '</strong>' );
 
 
 
 
 
 
 
 
328
 
329
  bp_core_add_admin_notice( $notice );
330
  }
@@ -337,12 +350,6 @@ function bp_core_activation_notice() {
337
  *
338
  * @internal Used internally to redirect BuddyPress to the about page on activation.
339
  *
340
- * @uses get_transient() To see if transient to redirect exists.
341
- * @uses delete_transient() To delete the transient if it exists.
342
- * @uses is_network_admin() To bail if being network activated.
343
- * @uses wp_safe_redirect() To redirect.
344
- * @uses add_query_arg() To help build the URL to redirect to.
345
- * @uses admin_url() To get the admin URL to index.php.
346
  */
347
  function bp_do_activation_redirect() {
348
 
@@ -548,7 +555,10 @@ function bp_core_add_contextual_help( $screen = '' ) {
548
  break;
549
  }
550
  }
551
- add_action( 'contextual_help', 'bp_core_add_contextual_help' );
 
 
 
552
 
553
  /**
554
  * Renders contextual help content to contextual help tabs.
@@ -597,7 +607,6 @@ function bp_core_add_contextual_help_content( $tab = '' ) {
597
  *
598
  * @since 1.7.0
599
  *
600
- * @uses bp_current_user_can() To check users capability on root blog.
601
  */
602
  function bp_admin_separator() {
603
 
@@ -632,8 +641,6 @@ function bp_admin_separator() {
632
  *
633
  * @since 1.7.0
634
  *
635
- * @uses bp_current_user_can() To check users capability on root blog.
636
- *
637
  * @param bool $menu_order Menu order.
638
  * @return bool Always true.
639
  */
@@ -652,8 +659,6 @@ function bp_admin_custom_menu_order( $menu_order = false ) {
652
  *
653
  * @since 1.7.0
654
  *
655
- * @uses bp_current_user_can() To check users capability on root blog.
656
- *
657
  * @param array $menu_order Menu Order.
658
  * @return array Modified menu order.
659
  */
@@ -799,7 +804,29 @@ function bp_admin_do_wp_nav_menu_meta_box() {
799
  </ul>
800
  </div>
801
 
 
 
 
 
 
 
 
 
 
 
 
802
  <p class="button-controls">
 
 
 
 
 
 
 
 
 
 
 
803
  <span class="add-to-menu">
804
  <input type="submit"<?php if ( function_exists( 'wp_nav_menu_disabled_check' ) ) : wp_nav_menu_disabled_check( $nav_menu_selected_id ); endif; ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to Menu', 'buddypress' ); ?>" name="add-custom-menu-item" id="submit-buddypress-menu" />
805
  <span class="spinner"></span>
@@ -928,7 +955,10 @@ add_action( 'add_meta_boxes_' . bp_get_email_post_type(), 'bp_email_custom_metab
928
  function bp_email_plaintext_metabox( $post ) {
929
  ?>
930
 
931
- <label class="screen-reader-text" for="excerpt"><?php _e( 'Plain text email content', 'buddypress' ); ?></label><textarea rows="5" cols="40" name="excerpt" id="excerpt"><?php echo $post->post_excerpt; // textarea_escaped ?></textarea>
 
 
 
932
 
933
  <p><?php _e( 'Most email clients support HTML email. However, some people prefer to receive plain text email. Enter a plain text alternative version of your email here.', 'buddypress' ); ?></p>
934
 
@@ -1083,3 +1113,43 @@ function bp_core_admin_user_spammed_js() {
1083
  </script>
1084
  <?php
1085
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  /**
16
  * Initializes the wp-admin area "BuddyPress" menus and sub menus.
17
  *
 
18
  */
19
  function bp_core_admin_menu_init() {
20
  add_action( bp_core_admin_hook(), 'bp_core_add_admin_menu', 9 );
122
  *
123
  * @since 1.5.0
124
  *
 
 
125
  */
126
  function bp_core_print_admin_notices() {
127
 
299
 
300
  if ( !empty( $orphaned_components ) ) {
301
  $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
302
+ $notice = sprintf(
303
+ '%1$s <a href="%2$s">%3$s</a>',
304
+ sprintf(
305
+ __( 'The following active BuddyPress Components do not have associated WordPress Pages: %s.', 'buddypress' ),
306
+ '<strong>' . implode( '</strong>, <strong>', array_map( 'esc_html', $orphaned_components ) ) . '</strong>'
307
+ ),
308
+ esc_url( $admin_url ),
309
+ __( 'Repair', 'buddypress' )
310
+ );
311
 
312
  bp_core_add_admin_notice( $notice );
313
  }
329
  // If there are duplicates, post a message about them.
330
  if ( !empty( $dupe_names ) ) {
331
  $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
332
+ $notice = sprintf(
333
+ '%1$s <a href="%2$s">%3$s</a>',
334
+ sprintf(
335
+ __( 'Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %s.', 'buddypress' ),
336
+ '<strong>' . implode( '</strong>, <strong>', array_map( 'esc_html', $dupe_names ) ) . '</strong>'
337
+ ),
338
+ esc_url( $admin_url ),
339
+ __( 'Repair', 'buddypress' )
340
+ );
341
 
342
  bp_core_add_admin_notice( $notice );
343
  }
350
  *
351
  * @internal Used internally to redirect BuddyPress to the about page on activation.
352
  *
 
 
 
 
 
 
353
  */
354
  function bp_do_activation_redirect() {
355
 
555
  break;
556
  }
557
  }
558
+ add_action( 'load-settings_page_bp-components', 'bp_core_add_contextual_help' );
559
+ add_action( 'load-settings_page_bp-page-settings', 'bp_core_add_contextual_help' );
560
+ add_action( 'load-settings_page_bp-settings', 'bp_core_add_contextual_help' );
561
+ add_action( 'load-users_page_bp-profile-setup', 'bp_core_add_contextual_help' );
562
 
563
  /**
564
  * Renders contextual help content to contextual help tabs.
607
  *
608
  * @since 1.7.0
609
  *
 
610
  */
611
  function bp_admin_separator() {
612
 
641
  *
642
  * @since 1.7.0
643
  *
 
 
644
  * @param bool $menu_order Menu order.
645
  * @return bool Always true.
646
  */
659
  *
660
  * @since 1.7.0
661
  *
 
 
662
  * @param array $menu_order Menu Order.
663
  * @return array Modified menu order.
664
  */
804
  </ul>
805
  </div>
806
 
807
+ <?php
808
+ $removed_args = array(
809
+ 'action',
810
+ 'customlink-tab',
811
+ 'edit-menu-item',
812
+ 'menu-item',
813
+ 'page-tab',
814
+ '_wpnonce',
815
+ );
816
+ ?>
817
+
818
  <p class="button-controls">
819
+ <span class="list-controls">
820
+ <a href="<?php
821
+ echo esc_url( add_query_arg(
822
+ array(
823
+ $post_type_name . '-tab' => 'all',
824
+ 'selectall' => 1,
825
+ ),
826
+ remove_query_arg( $removed_args )
827
+ ) );
828
+ ?>#buddypress-menu" class="select-all"><?php _e( 'Select All', 'buddypress' ); ?></a>
829
+ </span>
830
  <span class="add-to-menu">
831
  <input type="submit"<?php if ( function_exists( 'wp_nav_menu_disabled_check' ) ) : wp_nav_menu_disabled_check( $nav_menu_selected_id ); endif; ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e( 'Add to Menu', 'buddypress' ); ?>" name="add-custom-menu-item" id="submit-buddypress-menu" />
832
  <span class="spinner"></span>
955
  function bp_email_plaintext_metabox( $post ) {
956
  ?>
957
 
958
+ <label class="screen-reader-text" for="excerpt"><?php
959
+ /* translators: accessibility text */
960
+ _e( 'Plain text email content', 'buddypress' );
961
+ ?></label><textarea rows="5" cols="40" name="excerpt" id="excerpt"><?php echo $post->post_excerpt; // textarea_escaped ?></textarea>
962
 
963
  <p><?php _e( 'Most email clients support HTML email. However, some people prefer to receive plain text email. Enter a plain text alternative version of your email here.', 'buddypress' ); ?></p>
964
 
1113
  </script>
1114
  <?php
1115
  }
1116
+
1117
+ /**
1118
+ * Catch and process an admin notice dismissal.
1119
+ *
1120
+ * @since 2.7.0
1121
+ */
1122
+ function bp_core_admin_notice_dismiss_callback() {
1123
+ if ( ! current_user_can( 'install_plugins' ) ) {
1124
+ wp_send_json_error();
1125
+ }
1126
+
1127
+ if ( empty( $_POST['nonce'] ) || empty( $_POST['notice_id'] ) ) {
1128
+ wp_send_json_error();
1129
+ }
1130
+
1131
+ $notice_id = wp_unslash( $_POST['notice_id'] );
1132
+
1133
+ if ( ! wp_verify_nonce( $_POST['nonce'], 'bp-dismissible-notice-' . $notice_id ) ) {
1134
+ wp_send_json_error();
1135
+ }
1136
+
1137
+ bp_update_option( "bp-dismissed-notice-$notice_id", 1 );
1138
+
1139
+ wp_send_json_success();
1140
+ }
1141
+ add_action( 'wp_ajax_bp_dismiss_notice', 'bp_core_admin_notice_dismiss_callback' );
1142
+
1143
+ /**
1144
+ * Add a "buddypress" class to body element of wp-admin.
1145
+ *
1146
+ * @since 2.8.0
1147
+ *
1148
+ * @param string $classes CSS classes for the body tag in the admin, a comma separated string.
1149
+ *
1150
+ * @return string
1151
+ */
1152
+ function bp_core_admin_body_classes( $classes ) {
1153
+ return $classes . ' buddypress';
1154
+ }
1155
+ add_filter( 'admin_body_class', 'bp_core_admin_body_classes' );
bp-core/admin/bp-core-admin-schema.php CHANGED
@@ -10,23 +10,6 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- /**
14
- * Get the DB schema to use for BuddyPress components.
15
- *
16
- * @since 1.1.0
17
- *
18
- * @global $wpdb $wpdb
19
- *
20
- * @return string The default database character-set, if set.
21
- */
22
- function bp_core_set_charset() {
23
- global $wpdb;
24
-
25
- require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
26
-
27
- return !empty( $wpdb->charset ) ? "DEFAULT CHARACTER SET {$wpdb->charset}" : '';
28
- }
29
-
30
  /**
31
  * Main installer.
32
  *
@@ -90,13 +73,10 @@ function bp_core_install( $active_components = false ) {
90
  *
91
  * @since 1.0.0
92
  *
93
- * @uses bp_core_set_charset()
94
- * @uses bp_core_get_table_prefix()
95
- * @uses dbDelta()
96
  */
97
  function bp_core_install_notifications() {
98
  $sql = array();
99
- $charset_collate = bp_core_set_charset();
100
  $bp_prefix = bp_core_get_table_prefix();
101
 
102
  $sql[] = "CREATE TABLE {$bp_prefix}bp_notifications (
@@ -134,13 +114,10 @@ function bp_core_install_notifications() {
134
  *
135
  * @since 1.0.0
136
  *
137
- * @uses bp_core_set_charset()
138
- * @uses bp_core_get_table_prefix()
139
- * @uses dbDelta()
140
  */
141
  function bp_core_install_activity_streams() {
142
  $sql = array();
143
- $charset_collate = bp_core_set_charset();
144
  $bp_prefix = bp_core_get_table_prefix();
145
 
146
  $sql[] = "CREATE TABLE {$bp_prefix}bp_activity (
@@ -187,13 +164,10 @@ function bp_core_install_activity_streams() {
187
  *
188
  * @since 1.0.0
189
  *
190
- * @uses bp_core_set_charset()
191
- * @uses bp_core_get_table_prefix()
192
- * @uses dbDelta()
193
  */
194
  function bp_core_install_friends() {
195
  $sql = array();
196
- $charset_collate = bp_core_set_charset();
197
  $bp_prefix = bp_core_get_table_prefix();
198
 
199
  $sql[] = "CREATE TABLE {$bp_prefix}bp_friends (
@@ -215,13 +189,10 @@ function bp_core_install_friends() {
215
  *
216
  * @since 1.0.0
217
  *
218
- * @uses bp_core_set_charset()
219
- * @uses bp_core_get_table_prefix()
220
- * @uses dbDelta()
221
  */
222
  function bp_core_install_groups() {
223
  $sql = array();
224
- $charset_collate = bp_core_set_charset();
225
  $bp_prefix = bp_core_get_table_prefix();
226
 
227
  $sql[] = "CREATE TABLE {$bp_prefix}bp_groups (
@@ -231,10 +202,12 @@ function bp_core_install_groups() {
231
  slug varchar(200) NOT NULL,
232
  description longtext NOT NULL,
233
  status varchar(10) NOT NULL DEFAULT 'public',
 
234
  enable_forum tinyint(1) NOT NULL DEFAULT '1',
235
  date_created datetime NOT NULL,
236
  KEY creator_id (creator_id),
237
- KEY status (status)
 
238
  ) {$charset_collate};";
239
 
240
  $sql[] = "CREATE TABLE {$bp_prefix}bp_groups_members (
@@ -275,13 +248,10 @@ function bp_core_install_groups() {
275
  *
276
  * @since 1.0.0
277
  *
278
- * @uses bp_core_set_charset()
279
- * @uses bp_core_get_table_prefix()
280
- * @uses dbDelta()
281
  */
282
  function bp_core_install_private_messaging() {
283
  $sql = array();
284
- $charset_collate = bp_core_set_charset();
285
  $bp_prefix = bp_core_get_table_prefix();
286
 
287
  $sql[] = "CREATE TABLE {$bp_prefix}bp_messages_messages (
@@ -335,15 +305,12 @@ function bp_core_install_private_messaging() {
335
  *
336
  * @since 1.0.0
337
  *
338
- * @uses bp_core_set_charset()
339
- * @uses bp_core_get_table_prefix()
340
- * @uses dbDelta()
341
  */
342
  function bp_core_install_extended_profiles() {
343
  global $wpdb;
344
 
345
  $sql = array();
346
- $charset_collate = bp_core_set_charset();
347
  $bp_prefix = bp_core_get_table_prefix();
348
 
349
  // These values should only be updated if they are not already present.
@@ -425,13 +392,10 @@ function bp_core_install_extended_profiles() {
425
  *
426
  * @since 1.0.0
427
  *
428
- * @uses bp_core_set_charset()
429
- * @uses bp_core_get_table_prefix()
430
- * @uses dbDelta()
431
  */
432
  function bp_core_install_blog_tracking() {
433
  $sql = array();
434
- $charset_collate = bp_core_set_charset();
435
  $bp_prefix = bp_core_get_table_prefix();
436
 
437
  $sql[] = "CREATE TABLE {$bp_prefix}bp_user_blogs (
@@ -462,7 +426,6 @@ function bp_core_install_blog_tracking() {
462
  * @since 2.0.0
463
  *
464
  * @global $wpdb
465
- * @uses wp_get_db_schema() to get WordPress ms_global schema
466
  */
467
  function bp_core_install_signups() {
468
  global $wpdb;
@@ -539,7 +502,7 @@ function bp_core_install_emails() {
539
  );
540
 
541
  $emails = bp_email_get_schema();
542
- $descriptions = bp_email_get_type_schema();
543
 
544
  // Add these emails to the database.
545
  foreach ( $emails as $id => $email ) {
@@ -557,6 +520,8 @@ function bp_core_install_emails() {
557
  }
558
  }
559
 
 
 
560
  /**
561
  * Fires after BuddyPress adds the posts for its emails.
562
  *
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Main installer.
15
  *
73
  *
74
  * @since 1.0.0
75
  *
 
 
 
76
  */
77
  function bp_core_install_notifications() {
78
  $sql = array();
79
+ $charset_collate = $GLOBALS['wpdb']->get_charset_collate();
80
  $bp_prefix = bp_core_get_table_prefix();
81
 
82
  $sql[] = "CREATE TABLE {$bp_prefix}bp_notifications (
114
  *
115
  * @since 1.0.0
116
  *
 
 
 
117
  */
118
  function bp_core_install_activity_streams() {
119
  $sql = array();
120
+ $charset_collate = $GLOBALS['wpdb']->get_charset_collate();
121
  $bp_prefix = bp_core_get_table_prefix();
122
 
123
  $sql[] = "CREATE TABLE {$bp_prefix}bp_activity (
164
  *
165
  * @since 1.0.0
166
  *
 
 
 
167
  */
168
  function bp_core_install_friends() {
169
  $sql = array();
170
+ $charset_collate = $GLOBALS['wpdb']->get_charset_collate();
171
  $bp_prefix = bp_core_get_table_prefix();
172
 
173
  $sql[] = "CREATE TABLE {$bp_prefix}bp_friends (
189
  *
190
  * @since 1.0.0
191
  *
 
 
 
192
  */
193
  function bp_core_install_groups() {
194
  $sql = array();
195
+ $charset_collate = $GLOBALS['wpdb']->get_charset_collate();
196
  $bp_prefix = bp_core_get_table_prefix();
197
 
198
  $sql[] = "CREATE TABLE {$bp_prefix}bp_groups (
202
  slug varchar(200) NOT NULL,
203
  description longtext NOT NULL,
204
  status varchar(10) NOT NULL DEFAULT 'public',
205
+ parent_id bigint(20) NOT NULL DEFAULT 0,
206
  enable_forum tinyint(1) NOT NULL DEFAULT '1',
207
  date_created datetime NOT NULL,
208
  KEY creator_id (creator_id),
209
+ KEY status (status),
210
+ KEY parent_id (parent_id)
211
  ) {$charset_collate};";
212
 
213
  $sql[] = "CREATE TABLE {$bp_prefix}bp_groups_members (
248
  *
249
  * @since 1.0.0
250
  *
 
 
 
251
  */
252
  function bp_core_install_private_messaging() {
253
  $sql = array();
254
+ $charset_collate = $GLOBALS['wpdb']->get_charset_collate();
255
  $bp_prefix = bp_core_get_table_prefix();
256
 
257
  $sql[] = "CREATE TABLE {$bp_prefix}bp_messages_messages (
305
  *
306
  * @since 1.0.0
307
  *
 
 
 
308
  */
309
  function bp_core_install_extended_profiles() {
310
  global $wpdb;
311
 
312
  $sql = array();
313
+ $charset_collate = $GLOBALS['wpdb']->get_charset_collate();
314
  $bp_prefix = bp_core_get_table_prefix();
315
 
316
  // These values should only be updated if they are not already present.
392
  *
393
  * @since 1.0.0
394
  *
 
 
 
395
  */
396
  function bp_core_install_blog_tracking() {
397
  $sql = array();
398
+ $charset_collate = $GLOBALS['wpdb']->get_charset_collate();
399
  $bp_prefix = bp_core_get_table_prefix();
400
 
401
  $sql[] = "CREATE TABLE {$bp_prefix}bp_user_blogs (
426
  * @since 2.0.0
427
  *
428
  * @global $wpdb
 
429
  */
430
  function bp_core_install_signups() {
431
  global $wpdb;
502
  );
503
 
504
  $emails = bp_email_get_schema();
505
+ $descriptions = bp_email_get_type_schema( 'description' );
506
 
507
  // Add these emails to the database.
508
  foreach ( $emails as $id => $email ) {
520
  }
521
  }
522
 
523
+ bp_update_option( 'bp-emails-unsubscribe-salt', base64_encode( wp_generate_password( 64, true, true ) ) );
524
+
525
  /**
526
  * Fires after BuddyPress adds the posts for its emails.
527
  *
bp-core/admin/bp-core-admin-settings.php CHANGED
@@ -22,7 +22,6 @@ function bp_admin_setting_callback_main_section() { }
22
  *
23
  * @since 1.6.0
24
  *
25
- * @uses bp_form_option() To output the option value.
26
  */
27
  function bp_admin_setting_callback_admin_bar() {
28
  ?>
@@ -38,7 +37,6 @@ function bp_admin_setting_callback_admin_bar() {
38
  *
39
  * @since 1.6.0
40
  *
41
- * @uses checked() To display the checked attribute.
42
  */
43
  function bp_admin_setting_callback_account_deletion() {
44
  ?>
@@ -63,7 +61,6 @@ function bp_admin_setting_callback_activity_section() { }
63
  *
64
  * @since 1.6.0
65
  *
66
- * @uses checked() To display the checked attribute.
67
  */
68
  function bp_admin_setting_callback_activity_akismet() {
69
  ?>
@@ -132,7 +129,6 @@ function bp_admin_setting_callback_xprofile_section() { }
132
  *
133
  * @since 1.6.0
134
  *
135
- * @uses bp_form_option() To output the option value.
136
  */
137
  function bp_admin_setting_callback_profile_sync() {
138
  ?>
@@ -148,7 +144,6 @@ function bp_admin_setting_callback_profile_sync() {
148
  *
149
  * @since 1.6.0
150
  *
151
- * @uses checked() To display the checked attribute.
152
  */
153
  function bp_admin_setting_callback_avatar_uploads() {
154
  ?>
@@ -185,7 +180,6 @@ function bp_admin_setting_callback_groups_section() { }
185
  *
186
  * @since 1.6.0
187
  *
188
- * @uses checked() To display the checked attribute.
189
  */
190
  function bp_admin_setting_callback_group_creation() {
191
  ?>
@@ -235,9 +229,6 @@ function bp_admin_setting_callback_bbpress_section() { }
235
  *
236
  * @since 1.6.0
237
  *
238
- * @uses checked() To display the checked attribute.
239
- * @uses bp_get_option() To get the config location.
240
- * @uses bp_form_option() To get the sanitized form option.
241
  */
242
  function bp_admin_setting_callback_bbpress_configuration() {
243
 
@@ -265,8 +256,6 @@ function bp_admin_setting_callback_bbpress_configuration() {
265
  *
266
  * @since 1.6.0
267
  *
268
- * @uses settings_fields() To output the hidden fields for the form.
269
- * @uses do_settings_sections() To output the settings sections.
270
  */
271
  function bp_core_admin_settings() {
272
 
@@ -350,8 +339,6 @@ add_action( 'bp_admin_init', 'bp_core_admin_settings_save', 100 );
350
  *
351
  * @since 1.6.0
352
  *
353
- * @uses bp_get_bp_form_option()
354
- *
355
  * @param string $option Form option to echo.
356
  * @param string $default Form option default.
357
  * @param bool $slug Form option slug.
@@ -364,9 +351,6 @@ function bp_form_option( $option, $default = '' , $slug = false ) {
364
  *
365
  * @since 1.6.0
366
  *
367
- * @uses bp_get_option()
368
- * @uses esc_attr()
369
- * @uses apply_filters()
370
  *
371
  * @param string $option Form option to return.
372
  * @param string $default Form option default.
22
  *
23
  * @since 1.6.0
24
  *
 
25
  */
26
  function bp_admin_setting_callback_admin_bar() {
27
  ?>
37
  *
38
  * @since 1.6.0
39
  *
 
40
  */
41
  function bp_admin_setting_callback_account_deletion() {
42
  ?>
61
  *
62
  * @since 1.6.0
63
  *
 
64
  */
65
  function bp_admin_setting_callback_activity_akismet() {
66
  ?>
129
  *
130
  * @since 1.6.0
131
  *
 
132
  */
133
  function bp_admin_setting_callback_profile_sync() {
134
  ?>
144
  *
145
  * @since 1.6.0
146
  *
 
147
  */
148
  function bp_admin_setting_callback_avatar_uploads() {
149
  ?>
180
  *
181
  * @since 1.6.0
182
  *
 
183
  */
184
  function bp_admin_setting_callback_group_creation() {
185
  ?>
229
  *
230
  * @since 1.6.0
231
  *
 
 
 
232
  */
233
  function bp_admin_setting_callback_bbpress_configuration() {
234
 
256
  *
257
  * @since 1.6.0
258
  *
 
 
259
  */
260
  function bp_core_admin_settings() {
261
 
339
  *
340
  * @since 1.6.0
341
  *
 
 
342
  * @param string $option Form option to echo.
343
  * @param string $default Form option default.
344
  * @param bool $slug Form option slug.
351
  *
352
  * @since 1.6.0
353
  *
 
 
 
354
  *
355
  * @param string $option Form option to return.
356
  * @param string $default Form option default.
bp-core/admin/bp-core-admin-slugs.php CHANGED
@@ -15,7 +15,6 @@ defined( 'ABSPATH' ) || exit;
15
  *
16
  * @since 1.6.0
17
  * @todo Use settings API
18
- * @uses bp_core_admin_component_options()
19
  */
20
  function bp_core_admin_slugs_settings() {
21
  ?>
@@ -185,12 +184,20 @@ function bp_core_admin_slugs_options() {
185
 
186
  <h3><?php _e( 'Registration', 'buddypress' ); ?></h3>
187
 
188
- <p><?php _e( 'Associate WordPress Pages with the following BuddyPress Registration pages.', 'buddypress' ); ?></p>
 
 
 
 
 
 
 
 
189
 
190
  <table class="form-table">
191
  <tbody>
192
 
193
- <?php foreach ( $static_pages as $name => $label ) : ?>
194
 
195
  <tr valign="top">
196
  <th scope="row">
@@ -219,7 +226,7 @@ function bp_core_admin_slugs_options() {
219
  </td>
220
  </tr>
221
 
222
- <?php endforeach ?>
223
 
224
  <?php
225
 
15
  *
16
  * @since 1.6.0
17
  * @todo Use settings API
 
18
  */
19
  function bp_core_admin_slugs_settings() {
20
  ?>
184
 
185
  <h3><?php _e( 'Registration', 'buddypress' ); ?></h3>
186
 
187
+ <?php if ( bp_get_signup_allowed() ) : ?>
188
+ <p><?php _e( 'Associate WordPress Pages with the following BuddyPress Registration pages.', 'buddypress' ); ?></p>
189
+ <?php else : ?>
190
+ <?php if ( is_multisite() ) : ?>
191
+ <p><?php printf( __( 'Registration is currently disabled. Before associating a page is allowed, please enable registration by selecting either the "User accounts may be registered" or "Both sites and user accounts can be registered" option on <a href="%s">this page</a>.', 'buddypress' ), network_admin_url( 'settings.php' ) ); ?></p>
192
+ <?php else : ?>
193
+ <p><?php printf( __( 'Registration is currently disabled. Before associating a page is allowed, please enable registration by clicking on the "Anyone can register" checkbox on <a href="%s">this page</a>.', 'buddypress' ), admin_url( 'options-general.php' ) ); ?></p>
194
+ <?php endif; ?>
195
+ <?php endif; ?>
196
 
197
  <table class="form-table">
198
  <tbody>
199
 
200
+ <?php if ( bp_get_signup_allowed() ) : foreach ( $static_pages as $name => $label ) : ?>
201
 
202
  <tr valign="top">
203
  <th scope="row">
226
  </td>
227
  </tr>
228
 
229
+ <?php endforeach; endif; ?>
230
 
231
  <?php
232
 
bp-core/admin/bp-core-admin-tools.php CHANGED
@@ -21,39 +21,33 @@ function bp_core_admin_tools() {
21
 
22
  <h1><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h1>
23
 
24
- <p>
25
- <?php esc_html_e( 'BuddyPress keeps track of various relationships between members, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?>
26
- <?php esc_html_e( 'Use the tools below to manually recalculate these relationships.', 'buddypress' ); ?>
27
  </p>
28
  <p class="description"><?php esc_html_e( 'Some of these tools create substantial database overhead. Avoid running more than one repair job at a time.', 'buddypress' ); ?></p>
29
 
30
  <form class="settings" method="post" action="">
31
- <table class="form-table">
32
- <tbody>
33
- <tr valign="top">
34
- <th scope="row"><?php esc_html_e( 'Repair tools', 'buddypress' ) ?></th>
35
- <td>
36
- <fieldset>
37
- <legend class="screen-reader-text"><span><?php esc_html_e( 'Repair', 'buddypress' ) ?></span></legend>
38
-
39
- <?php foreach ( bp_admin_repair_list() as $item ) : ?>
40
 
41
- <label for="<?php echo esc_attr( str_replace( '_', '-', $item[0] ) ); ?>"><input type="checkbox" class="checkbox" name="<?php echo esc_attr( $item[0] ) . '" id="' . esc_attr( str_replace( '_', '-', $item[0] ) ); ?>" value="1" /> <?php echo esc_html( $item[1] ); ?></label><br />
 
42
 
43
- <?php endforeach; ?>
 
 
 
 
44
 
45
- </fieldset>
46
- </td>
47
- </tr>
48
- </tbody>
49
- </table>
50
 
51
- <fieldset class="submit">
52
- <input class="button-primary" type="submit" name="bp-tools-submit" value="<?php esc_attr_e( 'Repair Items', 'buddypress' ); ?>" />
53
- <?php wp_nonce_field( 'bp-do-counts' ); ?>
54
  </fieldset>
 
55
  </form>
 
56
  </div>
 
57
  <?php
58
  }
59
 
@@ -363,7 +357,7 @@ function bp_admin_tools_feedback( $message, $class = false ) {
363
 
364
  $message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
365
  $message = str_replace( "'", "\'", $message );
366
- $lambda = create_function( '', "echo '$message';" );
367
 
368
  add_action( bp_core_do_network_admin() ? 'network_admin_notices' : 'admin_notices', $lambda );
369
 
@@ -473,3 +467,24 @@ function bp_admin_reinstall_emails() {
473
 
474
  return array( 0, __( 'Emails have been successfully reinstalled.', 'buddypress' ) );
475
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  <h1><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h1>
23
 
24
+ <p><?php esc_html_e( 'BuddyPress keeps track of various relationships between members, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?></p>
25
+ <p><?php esc_html_e( 'Use the tools below to manually recalculate these relationships.', 'buddypress' ); ?>
 
26
  </p>
27
  <p class="description"><?php esc_html_e( 'Some of these tools create substantial database overhead. Avoid running more than one repair job at a time.', 'buddypress' ); ?></p>
28
 
29
  <form class="settings" method="post" action="">
 
 
 
 
 
 
 
 
 
30
 
31
+ <fieldset>
32
+ <legend><?php esc_html_e( 'Repair tools', 'buddypress' ) ?></legend>
33
 
34
+ <div class="checkbox">
35
+ <?php foreach ( bp_admin_repair_list() as $item ) : ?>
36
+ <label for="<?php echo esc_attr( str_replace( '_', '-', $item[0] ) ); ?>"><input type="checkbox" class="checkbox" name="<?php echo esc_attr( $item[0] ) . '" id="' . esc_attr( str_replace( '_', '-', $item[0] ) ); ?>" value="1" /> <?php echo esc_html( $item[1] ); ?></label>
37
+ <?php endforeach; ?>
38
+ </div>
39
 
40
+ <p class="submit">
41
+ <input class="button-primary" type="submit" name="bp-tools-submit" value="<?php esc_attr_e( 'Repair Items', 'buddypress' ); ?>" />
42
+ <?php wp_nonce_field( 'bp-do-counts' ); ?>
43
+ </p>
 
44
 
 
 
 
45
  </fieldset>
46
+
47
  </form>
48
+
49
  </div>
50
+
51
  <?php
52
  }
53
 
357
 
358
  $message = '<div id="message" class="' . esc_attr( $class ) . '">' . $message . '</div>';
359
  $message = str_replace( "'", "\'", $message );
360
+ $lambda = function() use ( $message ) { echo $message; };
361
 
362
  add_action( bp_core_do_network_admin() ? 'network_admin_notices' : 'admin_notices', $lambda );
363
 
467
 
468
  return array( 0, __( 'Emails have been successfully reinstalled.', 'buddypress' ) );
469
  }
470
+
471
+ /**
472
+ * Add notice on the "Tools > BuddyPress" page if more sites need recording.
473
+ *
474
+ * This notice only shows up in the network admin dashboard.
475
+ *
476
+ * @since 2.6.0
477
+ */
478
+ function bp_core_admin_notice_repopulate_blogs_resume() {
479
+ $screen = get_current_screen();
480
+ if ( 'tools_page_bp-tools-network' !== $screen->id ) {
481
+ return;
482
+ }
483
+
484
+ if ( '' === bp_get_option( '_bp_record_blogs_offset' ) ) {
485
+ return;
486
+ }
487
+
488
+ echo '<div class="error"><p>' . __( 'It looks like you have more sites to record. Resume recording by checking the "Repopulate site tracking records" option.', 'buddypress' ) . '</p></div>';
489
+ }
490
+ add_action( 'network_admin_notices', 'bp_core_admin_notice_repopulate_blogs_resume' );
bp-core/admin/css/common-rtl.css CHANGED
@@ -12,15 +12,16 @@ TABLE OF CONTENTS:
12
  1.1 Version Badge
13
  1.2 About Panel
14
  1.2.1 Headline Feature
15
- 1.2.2 Columns
16
- 1.2.3 Features Section
17
- 1.2.4 Changelog Section
18
  2.0 Dashicons
19
  2.1 Top level menus
20
  2.2 Settings - Components
21
  2.3 Tools
22
  3.0 User's Lists
23
  4.0 Emails - Edit page
 
 
24
  ------------------------------------------------------------------------------*/
25
 
26
  /*------------------------------------------------------------------------------
@@ -62,140 +63,332 @@ TABLE OF CONTENTS:
62
  /*
63
  * 1.2.1 Headline Feature
64
  */
65
- .index_page_bp-about .about-wrap .headline-feature,
66
- .dashboard_page_bp-about .about-wrap .headline-feature {
67
- margin-bottom: 2em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  text-align: center;
 
69
  }
70
 
71
- .index_page_bp-about .about-wrap .headline-feature h3,
72
- .index_page_bp-about .headline-feature .headline-title,
73
- .dashboard_page_bp-about .about-wrap .headline-feature h3,
74
- .dashboard_page_bp-about .headline-feature .headline-title {
75
  font-size: 2.2em;
76
- font-weight: normal;
77
- line-height: 1.3;
78
- margin: 1.25em 0 0.6em;
79
- text-align: center;
80
  }
81
 
82
- .index_page_bp-about .about-wrap .headline-feature p,
83
- .dashboard_page_bp-about .about-wrap .headline-feature p {
84
  font-size: 1.15em;
85
- margin: 1.15em auto 0.6em;
86
  }
87
 
88
- .index_page_bp-about .about-wrap .headline-feature .introduction,
89
- .dashboard_page_bp-about .about-wrap .headline-feature .introduction {
90
  font-weight: 600;
91
  }
92
 
 
93
  /*
94
- * 1.2.2 Columns
95
  */
96
- .index_page_bp-about .about-wrap .two-col > div,
97
- .dashboard_page_bp-about .about-wrap .two-col > div {
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  float: right;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  margin-left: 4.799999999%;
100
- position: relative;
101
  width: 47.6%;
102
  }
103
 
104
- .index_page_bp-about .about-wrap .two-col .last-feature,
105
- .dashboard_page_bp-about .about-wrap .two-col .last-feature {
 
 
 
 
 
 
 
106
  margin-left: 0;
107
  }
108
 
109
- /*
110
- * 1.2.3 Features Section
111
- */
112
- .index_page_bp-about .bp-features-section,
113
- .dashboard_page_bp-about .bp-features-section {
114
- margin-bottom: 2em;
 
 
 
 
 
 
 
115
  }
116
 
117
- .index_page_bp-about .about-wrap .feature-section,
118
- .dashboard_page_bp-about .about-wrap .feature-section {
 
 
 
 
 
 
 
 
119
  clear: both;
120
- margin-top: 2em;
 
121
  overflow: hidden;
122
  padding-bottom: 0;
123
  }
124
 
125
- .index_page_bp-about .about-wrap .changelog .feature-section,
126
- .dashboard_page_bp-about .about-wrap .changelog .feature-section {
127
- margin-top: 0;
128
  }
129
 
130
- .index_page_bp-about .about-wrap .feature-section h3,
131
- .dashboard_page_bp-about .about-wrap .feature-section h3 {
132
- font-size: 1.25em;
133
- line-height: 1.5em;
134
- margin: 0 0 0.6em;
 
 
 
135
  }
136
 
137
- .index_page_bp-about .about-wrap .changelog h4,
138
- .dashboard_page_bp-about .about-wrap .changelog h4 {
139
- color: #23282d;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  font-size: 1em;
141
- margin: 1.4em 0 0.6em;
 
142
  }
143
 
144
- /*
145
- * 1.2.4 Changelog Section
146
- */
147
- .index_page_bp-about .about-wrap .changelog,
148
- .dashboard_page_bp-about .about-wrap .changelog {
149
- border-top: 1px solid #eee;
150
  margin-bottom: 3em;
151
  }
152
 
153
- .index_page_bp-about .about-wrap .changelog .changelog-title,
154
- .dashboard_page_bp-about .about-wrap .changelog .changelog-title {
155
- font-size: 1.25em;
156
- line-height: 1.5em;
157
- margin: 1.25em 0 .6em;
158
  text-align: center;
159
  }
160
 
 
 
 
 
 
161
  @media screen and ( max-width: 782px ) {
162
- .index_page_bp-about .about-wrap .headline-feature,
163
- .dashboard_page_bp-about .about-wrap .headline-feature {
164
- max-width: 100%;
165
  }
166
- .index_page_bp-about .about-wrap .headline-feature h3,
167
- .dahsboard_page_bp-about .about-wrap .headline-feature h3,
168
- .index_page_bp-about .about-wrap .headline-feature .headline-title,
169
- .dashboard_page_bp-about .about-wrap .headline-feature .headline-title {
170
- font-size: 2em;
171
  }
172
  .index_page_bp-about .bp-features-section,
173
  .dashboard_page_bp-about .bp-features-section {
 
174
  margin-bottom: 0;
 
175
  }
176
- .index_page_bp-about .about-wrap .feature-section,
177
- .dashboard_page_bp-about .about-wrap .feature-section {
178
- margin-top: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
180
- .index_page_bp-about .about-wrap .two-col > div,
181
- .dashboard_page_bp-about .about-wrap .two-col > div {
182
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
183
- margin-top: 1.25em;
184
- padding-bottom: 1em;
185
  width: 100%;
186
  }
187
- .index_page_bp-about .changelog .two-col > div,
188
- .dashboard_page_bp-about .changelog .two-col > div {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  margin-top: 0;
190
- padding-bottom: 0;
 
191
  }
192
- .index_page_bp-about .about-wrap .changelog .changelog-title,
193
- .dashboard_page_bp-about .about-wrap .changelog .changelog-title {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  text-align: right;
195
  }
196
  }
197
-
198
-
199
  /*------------------------------------------------------------------------------
200
  * 2.0 Dashicons
201
  *----------------------------------------------------------------------------*/
@@ -367,3 +560,75 @@ body.users_page_bp-signups td.count_sent {
367
  body.post-type-bp-email #excerpt {
368
  height: auto;
369
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  1.1 Version Badge
13
  1.2 About Panel
14
  1.2.1 Headline Feature
15
+ 1.2.2 Features Section
16
+ 1.2.3 Changelog Section
 
17
  2.0 Dashicons
18
  2.1 Top level menus
19
  2.2 Settings - Components
20
  2.3 Tools
21
  3.0 User's Lists
22
  4.0 Emails - Edit page
23
+ 5.0 Tools - BuddyPress
24
+ 6.0 Plugins page
25
  ------------------------------------------------------------------------------*/
26
 
27
  /*------------------------------------------------------------------------------
63
  /*
64
  * 1.2.1 Headline Feature
65
  */
66
+ .index_page_bp-about .bp-headline-feature,
67
+ .dashboard_page_bp-about .bp-headline-feature {
68
+ margin-bottom: 3em;
69
+ margin-top: 3em;
70
+ padding: 2em 3em;
71
+ }
72
+
73
+ .index_page_bp-about .bp-headline,
74
+ .dashboard_page_bp-about .bp-headline {
75
+ margin: 0 auto;
76
+ width: 35em;
77
+ }
78
+
79
+ .index_page_bp-about .bp-headline span.dashicons,
80
+ .dashboard_page_bp-about .bp-headline span.dashicons {
81
+ background-color: #f1f1f1;
82
+ clear: right;
83
+ font-size: 100px;
84
+ float: right;
85
+ height: 100px;
86
+ line-height: 100px;
87
+ margin: 0 0 15px 15px ;
88
  text-align: center;
89
+ width: 100px;
90
  }
91
 
92
+ .index_page_bp-about .bp-headline-feature h3,
93
+ .index_page_bp-about .bp-headline-feature .headline-title,
94
+ .dashboard_page_bp-about .bp-headline-feature h3,
95
+ .dashboard_page_bp-about .bp-headline-feature .headline-title {
96
  font-size: 2.2em;
97
+ font-weight: 300;
98
+ line-height: 1;
99
+ margin: 0 125px 0 0;
 
100
  }
101
 
102
+ .index_page_bp-about .bp-headline-feature p,
103
+ .dashboard_page_bp-about .bp-headline-feature p {
104
  font-size: 1.15em;
105
+ margin: 1.15em 125px 0.6em auto;
106
  }
107
 
108
+ .index_page_bp-about .bp-headline-feature .introduction,
109
+ .dashboard_page_bp-about .bp-headline-feature .introduction {
110
  font-weight: 600;
111
  }
112
 
113
+
114
  /*
115
+ * 1.2.2 Features Section
116
  */
117
+ .index_page_bp-about .bp-features-section,
118
+ .dashboard_page_bp-about .bp-features-section {
119
+ clear: both;
120
+ margin-top: 3em;
121
+ overflow: hidden;
122
+ padding-bottom: 0;
123
+ }
124
+
125
+ .index_page_bp-about span.dashicons,
126
+ .dashboard_page_bp-about span.dashicons {
127
+ background-color: #fff;
128
+ border-radius: 50%;
129
+ clear: right;
130
+ color: #d84800;
131
+ font-size: 50px;
132
  float: right;
133
+ height: 80px;
134
+ line-height: 80px;
135
+ margin: 0 0 15px 15px ;
136
+ text-align: center;
137
+ width: 80px;
138
+ }
139
+
140
+ .index_page_bp-about .bp-features-section h3,
141
+ .dashboard_page_bp-about .bp-features-section h3 {
142
+ font-size: 2em;
143
+ font-weight: 300;
144
+ line-height: 1.5;
145
+ margin: 0 auto 3em;
146
+ text-align: center;
147
+ }
148
+
149
+ .index_page_bp-about .bp-feature,
150
+ .dashboard_page_bp-about .bp-feature {
151
+ float: right;
152
+ margin-bottom: 3em;
153
  margin-left: 4.799999999%;
 
154
  width: 47.6%;
155
  }
156
 
157
+
158
+ .index_page_bp-about .bp-feature code,
159
+ .dashboard_page_bp-about .bp-feature code{
160
+ font-size: 0.95em;
161
+ line-height: 1.5;
162
+ }
163
+
164
+ .index_page_bp-about .bp-feature:nth-of-type(2n),
165
+ .dashboard_page_bp-about .bp-feature:nth-of-type(2n) {
166
  margin-left: 0;
167
  }
168
 
169
+ .index_page_bp-about .bp-feature::after,
170
+ .dashboard_page_bp-about .bp-feature::after {
171
+ content: '';
172
+ }
173
+
174
+ .index_page_bp-about .bp-feature h4,
175
+ .dashboard_page_bp-about .bp-feature h4 {
176
+ font-size: 1.25em;
177
+ line-height: 1.5;
178
+ margin-bottom: 0;
179
+ margin-right: 110px;
180
+ margin-top: 0;
181
+ text-align: right;
182
  }
183
 
184
+ .index_page_bp-about .bp-feature p,
185
+ .dashboard_page_bp-about .bp-feature p {
186
+ margin-right: 110px;
187
+ }
188
+
189
+ /*
190
+ * 1.2.3 Changelog Section
191
+ */
192
+ .index_page_bp-about .bp-changelog-section,
193
+ .dashboard_page_bp-about .bp-changelog-section {
194
  clear: both;
195
+ margin-bottom: 8em;
196
+ margin-top: 3em;
197
  overflow: hidden;
198
  padding-bottom: 0;
199
  }
200
 
201
+ .index_page_bp-about .bp-changelog-section::after,
202
+ .dashboard_page_bp-about .bp-changelog-section::after {
203
+ content: '';
204
  }
205
 
206
+ .index_page_bp-about .bp-changelog-section .changelog-title,
207
+ .dashboard_page_bp-about .bp-changelog-section .changelog-title {
208
+ color: #23282d;
209
+ font-size: 1.8em;
210
+ font-weight: 300;
211
+ line-height: 1.5;
212
+ margin: 0 auto 0.5em;
213
+ text-align: center;
214
  }
215
 
216
+ .index_page_bp-about .bp-changelog-section .two-col > div,
217
+ .dashboard_page_bp-about .bp-changelog-section .two-col > div {
218
+ float: right;
219
+ margin-left: 4.799999999%;
220
+ position: relative;
221
+ width: 47.6%;
222
+ }
223
+
224
+ .index_page_bp-about .bp-changelog-section .two-col > div.last-feature,
225
+ .dashboard_page_bp-about .bp-changelog-section .two-col > div.last-feature {
226
+ margin-left: 0;
227
+ }
228
+
229
+ .index_page_bp-about .bp-changelog,
230
+ .dashboard_page_bp-about .bp-changelog {
231
+ margin-bottom: 3em;
232
+ }
233
+
234
+ .index_page_bp-about .bp-changelog h4,
235
+ .dashboard_page_bp-about .bp-changelog h4 {
236
  font-size: 1em;
237
+ margin-bottom: 0;
238
+ margin-top: 0;
239
  }
240
 
241
+ .index_page_bp-about .bp-changelog p,
242
+ .dashboard_page_bp-about .bp-changelog p {
 
 
 
 
243
  margin-bottom: 3em;
244
  }
245
 
246
+ .bp-changelog-url {
 
 
 
 
247
  text-align: center;
248
  }
249
 
250
+ .bp-assets {
251
+ clear: both;
252
+ margin-bottom: 2em;
253
+ }
254
+
255
  @media screen and ( max-width: 782px ) {
256
+ .index_page_bp-about .bp-headline-feature,
257
+ .dashboard_page_bp-about .bp-headline-feature {
258
+ padding: 0;
259
  }
260
+ .index_page_bp-about .bp-headline,
261
+ .dashboard_page_bp-about .bp-headline {
262
+ margin: 0;
263
+ width: 97%;
 
264
  }
265
  .index_page_bp-about .bp-features-section,
266
  .dashboard_page_bp-about .bp-features-section {
267
+ clear: both;
268
  margin-bottom: 0;
269
+ margin-top: 2em;
270
  }
271
+ .index_page_bp-about .bp-features-section h3,
272
+ .dashboard_page_bp-about .bp-features-section h3,
273
+ .index_page_bp-about .bp-changelog-section .changelog-title,
274
+ .dashboard_page_bp-about .bp-changelog-section .changelog-title {
275
+ font-size: 1.8em;
276
+ font-weight: 300;
277
+ line-height: 1.5;
278
+ margin-bottom: 0.5em;
279
+ margin-top: 0.5em;
280
+ }
281
+ .index_page_bp-about .bp-features-section h4,
282
+ .dashboard_page_bp-about .bp-features-section h4,
283
+ .index_page_bp-about .bp-changelog-section h4,
284
+ .dashboard_page_bp-about .bp-changelog-section h4 {
285
+ font-size: 1.25em;
286
+ line-height: 1.25;
287
+ margin-top: 0.6em;
288
+ text-align: right;
289
+ }
290
+ .index_page_bp-about .bp-feature,
291
+ .dashboard_page_bp-about .bp-feature {
292
+ clear: both;
293
+ float: right;
294
+ margin-bottom: 1em;
295
+ margin-top: 1em;
296
+ margin-left: 0;
297
+ padding-left: 1em;
298
+ width: 100%;
299
+ }
300
+ .index_page_bp-about .bp-feature span,
301
+ .dashboard_page_bp-about .bp-feature span {
302
+ margin-top: 0.33em;
303
  }
304
+ .index_page_bp-about .bp-feature h4,
305
+ .dashboard_page_bp-about .bp-feature h4,
306
+ .index_page_bp-about .bp-feature p,
307
+ .dashboard_page_bp-about .bp-feature p {
 
308
  width: 100%;
309
  }
310
+ .index_page_bp-about .bp-feature.opposite h4,
311
+ .dashboard_page_bp-about .bp-feature.opposite h4,
312
+ .index_page_bp-about .bp-feature.opposite p,
313
+ .dashboard_page_bp-about .bp-feature.opposite p {
314
+ float: none;
315
+ }
316
+ .index_page_bp-about .bp-changelog-section,
317
+ .dashboard_page_bp-about .bp-changelog-section {
318
+ clear: both;
319
+ margin-bottom: 2em;
320
+ }
321
+ .index_page_bp-about .bp-changelog-section .changelog-title,
322
+ .dashboard_page_bp-about .bp-changelog-section .changelog-title {
323
+ margin-bottom: 1em;
324
+ }
325
+ .index_page_bp-about .bp-changelog h4,
326
+ .dashboard_page_bp-about .bp-changelog h4 {
327
+ font-size: 1em;
328
+ }
329
+ .index_page_bp-about .bp-changelog p,
330
+ .dashboard_page_bp-about .bp-changelog p {
331
+ margin-bottom: 2em;
332
+ }
333
+ .index_page_bp-about .bp-changelog-section .two-col > div,
334
+ .dashboard_page_bp-about .bp-changelog-section .two-col > div {
335
  margin-top: 0;
336
+ padding-bottom: 0.5em;
337
+ width: 100%;
338
  }
339
+ }
340
+ @media screen and ( max-width: 360px ) {
341
+ .index_page_bp-about .bp-headline,
342
+ .dashboard_page_bp-about .bp-headline {
343
+ text-align: center;
344
+ }
345
+ .index_page_bp-about .bp-headline span.dashicons,
346
+ .dashboard_page_bp-about .bp-headline span.dashicons {
347
+ clear: none;
348
+ font-size: 80px;
349
+ float: none;
350
+ height: 80px;
351
+ line-height: 80px;
352
+ margin: 0 auto;
353
+ width: 80px;
354
+ }
355
+ .index_page_bp-about .bp-headline-feature h3,
356
+ .index_page_bp-about .bp-headline-feature .headline-title,
357
+ .dashboard_page_bp-about .bp-headline-feature h3,
358
+ .dashboard_page_bp-about .bp-headline-feature .headline-title {
359
+ margin: 1em 0 0 0;
360
+ text-align: right;
361
+ }
362
+ .index_page_bp-about .bp-headline-feature p,
363
+ .dashboard_page_bp-about .bp-headline-feature p {
364
+ margin: 1.15em 0 0.6em auto;
365
+ text-align: right;
366
+ }
367
+ .index_page_bp-about .bp-headline-feature .headline-title,
368
+ .dashboard_page_bp-about .bp-headline-feature .headline-title {
369
+ font-size: 1.5em;
370
+ line-height: 1.5;
371
+ }
372
+ .index_page_bp-about .bp-headline-feature p,
373
+ .dashboard_page_bp-about .bp-headline-feature p {
374
+ width: auto;
375
+ }
376
+ .index_page_bp-about .bp-feature,
377
+ .dashboard_page_bp-about .bp-feature {
378
+ text-align: center;
379
+ }
380
+ .index_page_bp-about span.dashicons,
381
+ .dashboard_page_bp-about span.dashicons {
382
+ float: none;
383
+ }
384
+ .index_page_bp-about .bp-features-section h4,
385
+ .dashboard_page_bp-about .bp-features-section h4,
386
+ .index_page_bp-about .bp-features-section p,
387
+ .dashboard_page_bp-about .bp-features-section p {
388
+ margin-right: 0;
389
  text-align: right;
390
  }
391
  }
 
 
392
  /*------------------------------------------------------------------------------
393
  * 2.0 Dashicons
394
  *----------------------------------------------------------------------------*/
560
  body.post-type-bp-email #excerpt {
561
  height: auto;
562
  }
563
+
564
+ body.post-type-bp-email th#situation {
565
+ width: 20%;
566
+ }
567
+
568
+ body.post-type-bp-email td.column-situation ul {
569
+ margin: 0;
570
+ }
571
+
572
+ body.post-type-bp-email .categorydiv label {
573
+ display: block;
574
+ float: right;
575
+ padding-right: 25px;
576
+ text-indent: -25px;
577
+ }
578
+
579
+ /*------------------------------------------------------------------------------
580
+ * 5.0 Tools - BuddyPress
581
+ *----------------------------------------------------------------------------*/
582
+ .tools_page_bp-tools .wrap {
583
+ max-width: 950px;
584
+ }
585
+
586
+ .tools_page_bp-tools p {
587
+ line-height: 2;
588
+ }
589
+
590
+ .tools_page_bp-tools fieldset {
591
+ margin: 2em 0 0;
592
+ }
593
+
594
+ .tools_page_bp-tools legend {
595
+ color: #23282d;
596
+ font-size: 1.3em;
597
+ font-weight: 600px;
598
+ margin: 1em 0;
599
+ }
600
+
601
+ .tools_page_bp-tools label {
602
+ clear: right;
603
+ display: block;
604
+ line-height: 1.5em;
605
+ margin: 0 0 1em;
606
+ vertical-align: middle;
607
+ }
608
+
609
+ @media screen and (max-width: 782px) {
610
+ .tools_page_bp-tools p {
611
+ line-height: 1.5;
612
+ }
613
+ .tools_page_bp-tools label {
614
+ margin-bottom: 1em;
615
+ padding-left: 25px;
616
+ text-indent: -33px;
617
+ }
618
+ .tools_page_bp-tools .checkbox {
619
+ padding: 0 30px 0 0;
620
+ }
621
+ }
622
+
623
+
624
+ /*------------------------------------------------------------------------------
625
+ * 6.0 Plugins page
626
+ *----------------------------------------------------------------------------*/
627
+ #buddypress-update.not-shiny .update-message {
628
+ border-right: 0;
629
+ padding-right: 36px;
630
+ }
631
+
632
+ #buddypress-update.not-shiny .update-message:before {
633
+ content: "\f534";
634
+ }
bp-core/admin/css/common-rtl.min.css CHANGED
@@ -1 +1 @@
1
- .bp-badge{color:#d84800;display:inline-block;font:400 150px/1 dashicons!important}.bp-badge:before{content:"\f448"}.about-wrap .bp-badge{position:absolute;top:0;left:0}@media only screen and (max-width:500px){.about-wrap .bp-badge{position:relative;margin:10px auto;top:auto;left:auto}}.dashboard_page_bp-about .about-wrap .headline-feature,.index_page_bp-about .about-wrap .headline-feature{margin-bottom:2em;text-align:center}.dashboard_page_bp-about .about-wrap .headline-feature h3,.dashboard_page_bp-about .headline-feature .headline-title,.index_page_bp-about .about-wrap .headline-feature h3,.index_page_bp-about .headline-feature .headline-title{font-size:2.2em;font-weight:400;line-height:1.3;margin:1.25em 0 .6em;text-align:center}.dashboard_page_bp-about .about-wrap .headline-feature p,.index_page_bp-about .about-wrap .headline-feature p{font-size:1.15em;margin:1.15em auto .6em}.dashboard_page_bp-about .about-wrap .headline-feature .introduction,.index_page_bp-about .about-wrap .headline-feature .introduction{font-weight:600}.dashboard_page_bp-about .about-wrap .two-col>div,.index_page_bp-about .about-wrap .two-col>div{float:right;margin-left:4.799999999%;position:relative;width:47.6%}.dashboard_page_bp-about .about-wrap .two-col .last-feature,.index_page_bp-about .about-wrap .two-col .last-feature{margin-left:0}.dashboard_page_bp-about .bp-features-section,.index_page_bp-about .bp-features-section{margin-bottom:2em}.dashboard_page_bp-about .about-wrap .feature-section,.index_page_bp-about .about-wrap .feature-section{clear:both;margin-top:2em;overflow:hidden;padding-bottom:0}.dashboard_page_bp-about .about-wrap .changelog .feature-section,.index_page_bp-about .about-wrap .changelog .feature-section{margin-top:0}.dashboard_page_bp-about .about-wrap .feature-section h3,.index_page_bp-about .about-wrap .feature-section h3{font-size:1.25em;line-height:1.5em;margin:0 0 .6em}.dashboard_page_bp-about .about-wrap .changelog h4,.index_page_bp-about .about-wrap .changelog h4{color:#23282d;font-size:1em;margin:1.4em 0 .6em}.dashboard_page_bp-about .about-wrap .changelog,.index_page_bp-about .about-wrap .changelog{border-top:1px solid #eee;margin-bottom:3em}.dashboard_page_bp-about .about-wrap .changelog .changelog-title,.index_page_bp-about .about-wrap .changelog .changelog-title{font-size:1.25em;line-height:1.5em;margin:1.25em 0 .6em;text-align:center}@media screen and (max-width:782px){.dashboard_page_bp-about .about-wrap .headline-feature,.index_page_bp-about .about-wrap .headline-feature{max-width:100%}.dahsboard_page_bp-about .about-wrap .headline-feature h3,.dashboard_page_bp-about .about-wrap .headline-feature .headline-title,.index_page_bp-about .about-wrap .headline-feature .headline-title,.index_page_bp-about .about-wrap .headline-feature h3{font-size:2em}.dashboard_page_bp-about .bp-features-section,.index_page_bp-about .bp-features-section{margin-bottom:0}.dashboard_page_bp-about .about-wrap .feature-section,.index_page_bp-about .about-wrap .feature-section{margin-top:0}.dashboard_page_bp-about .about-wrap .two-col>div,.index_page_bp-about .about-wrap .two-col>div{border-bottom:1px solid rgba(0,0,0,.1);margin-top:1.25em;padding-bottom:1em;width:100%}.dashboard_page_bp-about .changelog .two-col>div,.index_page_bp-about .changelog .two-col>div{margin-top:0;padding-bottom:0}.dashboard_page_bp-about .about-wrap .changelog .changelog-title,.index_page_bp-about .about-wrap .changelog .changelog-title{text-align:right}}#adminmenu #toplevel_page_bp-activity .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_user .wp-menu-image:before{content:"\f452"}#adminmenu #toplevel_page_bp-groups .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_user .wp-menu-image:before{content:"\f456"}#adminmenu #toplevel_page_bp-notifications .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_user .wp-menu-image:before{content:"\f439"}#adminmenu #toplevel_page_bp-messages .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_user .wp-menu-image:before{content:"\f457"}#adminmenu #toplevel_page_bp-friends .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_user .wp-menu-image:before{content:"\f454"}#adminmenu #toplevel_page_bp-settings .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_user .wp-menu-image:before{content:"\f108"}#adminmenu li.toplevel_page_bp-components .wp-menu-image,#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image{content:"\f448"}.settings_page_bp-components td.plugin-title span{float:right;width:18px;height:18px;margin-left:5px}.settings_page_bp-components td.plugin-title span:before{font-family:dashicons;font-size:18px}.settings_page_bp-components tr.activity td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.notifications td.plugin-title span:before{content:"\f339"}.settings_page_bp-components tr.xprofile td.plugin-title span:before{content:"\f336"}.settings_page_bp-components tr.settings td.plugin-title span:before{content:"\f108"}.settings_page_bp-components tr.groups td.plugin-title span:before{content:"\f456"}.settings_page_bp-components tr.messages td.plugin-title span:before{content:"\f457"}.settings_page_bp-components tr.forums td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.blogs td.plugin-title span:before{content:"\f120"}.settings_page_bp-components tr.friends td.plugin-title span:before{content:"\f454"}.settings_page_bp-components tr.core td.plugin-title span:before{content:"\f448"}.settings_page_bp-components tr.members td.plugin-title span:before{content:"\f307"}#bp-admin-component-form .wp-list-table.plugins .plugin-title{width:25%}@media screen and (max-width:782px){.settings_page_bp-components td.plugin-title span{margin-top:5px}#bp-admin-component-form .wp-list-table.plugins .plugin-title{display:block;width:auto}#bp-admin-component-form .subsubsub{margin-bottom:0;padding-bottom:35px}}#adminmenu .toplevel_page_network-tools div.wp-menu-image:before{content:""}body.site-users-php th#role,body.users-php th#role,body.users_page_bp-signups th#count_sent{width:10%}body.site-users-php th#email,body.site-users-php th#name,body.users-php th#email,body.users-php th#name,body.users-php th#registered,body.users_page_bp-signups th#date_sent,body.users_page_bp-signups th#email,body.users_page_bp-signups th#name,body.users_page_bp-signups th#registered{width:15%}body.users-php th#blogs,body.users_page_bp-signups th#blogs{width:20%}body.users_page_bp-signups td.count_sent,body.users_page_bp-signups th.column-count_sent{text-align:center}body.post-type-bp-email #excerpt{height:auto}
1
+ .bp-badge{color:#d84800;display:inline-block;font:400 150px/1 dashicons!important}.bp-badge:before{content:"\f448"}.dashboard_page_bp-about .bp-changelog-section::after,.dashboard_page_bp-about .bp-feature::after,.index_page_bp-about .bp-changelog-section::after,.index_page_bp-about .bp-feature::after{content:''}.about-wrap .bp-badge{position:absolute;top:0;left:0}@media only screen and (max-width:500px){.about-wrap .bp-badge{position:relative;margin:10px auto;top:auto;left:auto}}.dashboard_page_bp-about .bp-headline-feature,.index_page_bp-about .bp-headline-feature{margin-bottom:3em;margin-top:3em;padding:2em 3em}.dashboard_page_bp-about .bp-headline,.index_page_bp-about .bp-headline{margin:0 auto;width:35em}.dashboard_page_bp-about .bp-headline span.dashicons,.index_page_bp-about .bp-headline span.dashicons{background-color:#f1f1f1;clear:right;font-size:100px;float:right;height:100px;line-height:100px;margin:0 0 15px 15px;text-align:center;width:100px}.dashboard_page_bp-about .bp-headline-feature .headline-title,.dashboard_page_bp-about .bp-headline-feature h3,.index_page_bp-about .bp-headline-feature .headline-title,.index_page_bp-about .bp-headline-feature h3{font-size:2.2em;font-weight:300;line-height:1;margin:0 125px 0 0}.dashboard_page_bp-about .bp-headline-feature p,.index_page_bp-about .bp-headline-feature p{font-size:1.15em;margin:1.15em 125px .6em auto}.dashboard_page_bp-about .bp-headline-feature .introduction,.index_page_bp-about .bp-headline-feature .introduction{font-weight:600}.dashboard_page_bp-about .bp-features-section,.index_page_bp-about .bp-features-section{clear:both;margin-top:3em;overflow:hidden;padding-bottom:0}.dashboard_page_bp-about span.dashicons,.index_page_bp-about span.dashicons{background-color:#fff;border-radius:50%;clear:right;color:#d84800;font-size:50px;float:right;height:80px;line-height:80px;margin:0 0 15px 15px;text-align:center;width:80px}.dashboard_page_bp-about .bp-features-section h3,.index_page_bp-about .bp-features-section h3{font-size:2em;font-weight:300;line-height:1.5;margin:0 auto 3em;text-align:center}.dashboard_page_bp-about .bp-feature,.index_page_bp-about .bp-feature{float:right;margin-bottom:3em;margin-left:4.799999999%;width:47.6%}.dashboard_page_bp-about .bp-feature code,.index_page_bp-about .bp-feature code{font-size:.95em;line-height:1.5}.dashboard_page_bp-about .bp-feature:nth-of-type(2n),.index_page_bp-about .bp-feature:nth-of-type(2n){margin-left:0}.dashboard_page_bp-about .bp-feature h4,.index_page_bp-about .bp-feature h4{font-size:1.25em;line-height:1.5;margin-bottom:0;margin-right:110px;margin-top:0;text-align:right}.dashboard_page_bp-about .bp-feature p,.index_page_bp-about .bp-feature p{margin-right:110px}.dashboard_page_bp-about .bp-changelog-section,.index_page_bp-about .bp-changelog-section{clear:both;margin-bottom:8em;margin-top:3em;overflow:hidden;padding-bottom:0}.dashboard_page_bp-about .bp-changelog-section .changelog-title,.index_page_bp-about .bp-changelog-section .changelog-title{color:#23282d;font-size:1.8em;font-weight:300;line-height:1.5;margin:0 auto .5em;text-align:center}.dashboard_page_bp-about .bp-changelog-section .two-col>div,.index_page_bp-about .bp-changelog-section .two-col>div{float:right;margin-left:4.799999999%;position:relative;width:47.6%}.dashboard_page_bp-about .bp-changelog-section .two-col>div.last-feature,.index_page_bp-about .bp-changelog-section .two-col>div.last-feature{margin-left:0}.dashboard_page_bp-about .bp-changelog,.index_page_bp-about .bp-changelog{margin-bottom:3em}.dashboard_page_bp-about .bp-changelog h4,.index_page_bp-about .bp-changelog h4{font-size:1em;margin-bottom:0;margin-top:0}.dashboard_page_bp-about .bp-changelog p,.index_page_bp-about .bp-changelog p{margin-bottom:3em}.bp-changelog-url{text-align:center}.bp-assets{clear:both;margin-bottom:2em}@media screen and (max-width:782px){.dashboard_page_bp-about .bp-headline-feature,.index_page_bp-about .bp-headline-feature{padding:0}.dashboard_page_bp-about .bp-headline,.index_page_bp-about .bp-headline{margin:0;width:97%}.dashboard_page_bp-about .bp-features-section,.index_page_bp-about .bp-features-section{clear:both;margin-bottom:0;margin-top:2em}.dashboard_page_bp-about .bp-changelog-section .changelog-title,.dashboard_page_bp-about .bp-features-section h3,.index_page_bp-about .bp-changelog-section .changelog-title,.index_page_bp-about .bp-features-section h3{font-size:1.8em;font-weight:300;line-height:1.5;margin-bottom:.5em;margin-top:.5em}.dashboard_page_bp-about .bp-changelog-section h4,.dashboard_page_bp-about .bp-features-section h4,.index_page_bp-about .bp-changelog-section h4,.index_page_bp-about .bp-features-section h4{font-size:1.25em;line-height:1.25;margin-top:.6em;text-align:right}.dashboard_page_bp-about .bp-feature,.index_page_bp-about .bp-feature{clear:both;float:right;margin-bottom:1em;margin-top:1em;margin-left:0;padding-left:1em;width:100%}.dashboard_page_bp-about .bp-feature span,.index_page_bp-about .bp-feature span{margin-top:.33em}.dashboard_page_bp-about .bp-feature h4,.dashboard_page_bp-about .bp-feature p,.index_page_bp-about .bp-feature h4,.index_page_bp-about .bp-feature p{width:100%}.dashboard_page_bp-about .bp-feature.opposite h4,.dashboard_page_bp-about .bp-feature.opposite p,.index_page_bp-about .bp-feature.opposite h4,.index_page_bp-about .bp-feature.opposite p{float:none}.dashboard_page_bp-about .bp-changelog-section,.index_page_bp-about .bp-changelog-section{clear:both;margin-bottom:2em}.dashboard_page_bp-about .bp-changelog-section .changelog-title,.index_page_bp-about .bp-changelog-section .changelog-title{margin-bottom:1em}.dashboard_page_bp-about .bp-changelog h4,.index_page_bp-about .bp-changelog h4{font-size:1em}.dashboard_page_bp-about .bp-changelog p,.index_page_bp-about .bp-changelog p{margin-bottom:2em}.dashboard_page_bp-about .bp-changelog-section .two-col>div,.index_page_bp-about .bp-changelog-section .two-col>div{margin-top:0;padding-bottom:.5em;width:100%}}@media screen and (max-width:360px){.dashboard_page_bp-about .bp-headline,.index_page_bp-about .bp-headline{text-align:center}.dashboard_page_bp-about .bp-headline span.dashicons,.index_page_bp-about .bp-headline span.dashicons{clear:none;font-size:80px;float:none;height:80px;line-height:80px;margin:0 auto;width:80px}.dashboard_page_bp-about .bp-headline-feature .headline-title,.dashboard_page_bp-about .bp-headline-feature h3,.index_page_bp-about .bp-headline-feature .headline-title,.index_page_bp-about .bp-headline-feature h3{margin:1em 0 0;text-align:right}.dashboard_page_bp-about .bp-headline-feature p,.index_page_bp-about .bp-headline-feature p{margin:1.15em 0 .6em auto;text-align:right;width:auto}.dashboard_page_bp-about .bp-headline-feature .headline-title,.index_page_bp-about .bp-headline-feature .headline-title{font-size:1.5em;line-height:1.5}.dashboard_page_bp-about .bp-feature,.index_page_bp-about .bp-feature{text-align:center}.dashboard_page_bp-about span.dashicons,.index_page_bp-about span.dashicons{float:none}.dashboard_page_bp-about .bp-features-section h4,.dashboard_page_bp-about .bp-features-section p,.index_page_bp-about .bp-features-section h4,.index_page_bp-about .bp-features-section p{margin-right:0;text-align:right}}#adminmenu #toplevel_page_bp-activity .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_user .wp-menu-image:before{content:"\f452"}#adminmenu #toplevel_page_bp-groups .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_user .wp-menu-image:before{content:"\f456"}#adminmenu #toplevel_page_bp-notifications .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_user .wp-menu-image:before{content:"\f439"}#adminmenu #toplevel_page_bp-messages .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_user .wp-menu-image:before{content:"\f457"}#adminmenu #toplevel_page_bp-friends .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_user .wp-menu-image:before{content:"\f454"}#adminmenu #toplevel_page_bp-settings .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_user .wp-menu-image:before{content:"\f108"}#adminmenu li.toplevel_page_bp-components .wp-menu-image,#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image{content:"\f448"}.settings_page_bp-components td.plugin-title span{float:right;width:18px;height:18px;margin-left:5px}.settings_page_bp-components td.plugin-title span:before{font-family:dashicons;font-size:18px}.settings_page_bp-components tr.activity td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.notifications td.plugin-title span:before{content:"\f339"}.settings_page_bp-components tr.xprofile td.plugin-title span:before{content:"\f336"}.settings_page_bp-components tr.settings td.plugin-title span:before{content:"\f108"}.settings_page_bp-components tr.groups td.plugin-title span:before{content:"\f456"}.settings_page_bp-components tr.messages td.plugin-title span:before{content:"\f457"}.settings_page_bp-components tr.forums td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.blogs td.plugin-title span:before{content:"\f120"}.settings_page_bp-components tr.friends td.plugin-title span:before{content:"\f454"}.settings_page_bp-components tr.core td.plugin-title span:before{content:"\f448"}.settings_page_bp-components tr.members td.plugin-title span:before{content:"\f307"}#bp-admin-component-form .wp-list-table.plugins .plugin-title{width:25%}@media screen and (max-width:782px){.settings_page_bp-components td.plugin-title span{margin-top:5px}#bp-admin-component-form .wp-list-table.plugins .plugin-title{display:block;width:auto}#bp-admin-component-form .subsubsub{margin-bottom:0;padding-bottom:35px}}#adminmenu .toplevel_page_network-tools div.wp-menu-image:before{content:""}body.site-users-php th#role,body.users-php th#role,body.users_page_bp-signups th#count_sent{width:10%}body.site-users-php th#email,body.site-users-php th#name,body.users-php th#email,body.users-php th#name,body.users-php th#registered,body.users_page_bp-signups th#date_sent,body.users_page_bp-signups th#email,body.users_page_bp-signups th#name,body.users_page_bp-signups th#registered{width:15%}body.post-type-bp-email th#situation,body.users-php th#blogs,body.users_page_bp-signups th#blogs{width:20%}body.users_page_bp-signups td.count_sent,body.users_page_bp-signups th.column-count_sent{text-align:center}body.post-type-bp-email #excerpt{height:auto}body.post-type-bp-email td.column-situation ul{margin:0}body.post-type-bp-email .categorydiv label{display:block;float:right;padding-right:25px;text-indent:-25px}.tools_page_bp-tools .wrap{max-width:950px}.tools_page_bp-tools p{line-height:2}.tools_page_bp-tools fieldset{margin:2em 0 0}.tools_page_bp-tools legend{color:#23282d;font-size:1.3em;font-weight:600px;margin:1em 0}.tools_page_bp-tools label{clear:right;display:block;line-height:1.5em;margin:0 0 1em;vertical-align:middle}@media screen and (max-width:782px){.tools_page_bp-tools p{line-height:1.5}.tools_page_bp-tools label{margin-bottom:1em;padding-left:25px;text-indent:-33px}.tools_page_bp-tools .checkbox{padding:0 30px 0 0}}#buddypress-update.not-shiny .update-message{border-right:0;padding-right:36px}#buddypress-update.not-shiny .update-message:before{content:"\f534"}
bp-core/admin/css/common.css CHANGED
@@ -12,15 +12,16 @@ TABLE OF CONTENTS:
12
  1.1 Version Badge
13
  1.2 About Panel
14
  1.2.1 Headline Feature
15
- 1.2.2 Columns
16
- 1.2.3 Features Section
17
- 1.2.4 Changelog Section
18
  2.0 Dashicons
19
  2.1 Top level menus
20
  2.2 Settings - Components
21
  2.3 Tools
22
  3.0 User's Lists
23
  4.0 Emails - Edit page
 
 
24
  ------------------------------------------------------------------------------*/
25
 
26
  /*------------------------------------------------------------------------------
@@ -62,140 +63,332 @@ TABLE OF CONTENTS:
62
  /*
63
  * 1.2.1 Headline Feature
64
  */
65
- .index_page_bp-about .about-wrap .headline-feature,
66
- .dashboard_page_bp-about .about-wrap .headline-feature {
67
- margin-bottom: 2em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  text-align: center;
 
69
  }
70
 
71
- .index_page_bp-about .about-wrap .headline-feature h3,
72
- .index_page_bp-about .headline-feature .headline-title,
73
- .dashboard_page_bp-about .about-wrap .headline-feature h3,
74
- .dashboard_page_bp-about .headline-feature .headline-title {
75
  font-size: 2.2em;
76
- font-weight: normal;
77
- line-height: 1.3;
78
- margin: 1.25em 0 0.6em;
79
- text-align: center;
80
  }
81
 
82
- .index_page_bp-about .about-wrap .headline-feature p,
83
- .dashboard_page_bp-about .about-wrap .headline-feature p {
84
  font-size: 1.15em;
85
- margin: 1.15em auto 0.6em;
86
  }
87
 
88
- .index_page_bp-about .about-wrap .headline-feature .introduction,
89
- .dashboard_page_bp-about .about-wrap .headline-feature .introduction {
90
  font-weight: 600;
91
  }
92
 
 
93
  /*
94
- * 1.2.2 Columns
95
  */
96
- .index_page_bp-about .about-wrap .two-col > div,
97
- .dashboard_page_bp-about .about-wrap .two-col > div {
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  float: left;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  margin-right: 4.799999999%;
100
- position: relative;
101
  width: 47.6%;
102
  }
103
 
104
- .index_page_bp-about .about-wrap .two-col .last-feature,
105
- .dashboard_page_bp-about .about-wrap .two-col .last-feature {
 
 
 
 
 
 
 
106
  margin-right: 0;
107
  }
108
 
109
- /*
110
- * 1.2.3 Features Section
111
- */
112
- .index_page_bp-about .bp-features-section,
113
- .dashboard_page_bp-about .bp-features-section {
114
- margin-bottom: 2em;
 
 
 
 
 
 
 
115
  }
116
 
117
- .index_page_bp-about .about-wrap .feature-section,
118
- .dashboard_page_bp-about .about-wrap .feature-section {
 
 
 
 
 
 
 
 
119
  clear: both;
120
- margin-top: 2em;
 
121
  overflow: hidden;
122
  padding-bottom: 0;
123
  }
124
 
125
- .index_page_bp-about .about-wrap .changelog .feature-section,
126
- .dashboard_page_bp-about .about-wrap .changelog .feature-section {
127
- margin-top: 0;
128
  }
129
 
130
- .index_page_bp-about .about-wrap .feature-section h3,
131
- .dashboard_page_bp-about .about-wrap .feature-section h3 {
132
- font-size: 1.25em;
133
- line-height: 1.5em;
134
- margin: 0 0 0.6em;
 
 
 
135
  }
136
 
137
- .index_page_bp-about .about-wrap .changelog h4,
138
- .dashboard_page_bp-about .about-wrap .changelog h4 {
139
- color: #23282d;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  font-size: 1em;
141
- margin: 1.4em 0 0.6em;
 
142
  }
143
 
144
- /*
145
- * 1.2.4 Changelog Section
146
- */
147
- .index_page_bp-about .about-wrap .changelog,
148
- .dashboard_page_bp-about .about-wrap .changelog {
149
- border-top: 1px solid #eee;
150
  margin-bottom: 3em;
151
  }
152
 
153
- .index_page_bp-about .about-wrap .changelog .changelog-title,
154
- .dashboard_page_bp-about .about-wrap .changelog .changelog-title {
155
- font-size: 1.25em;
156
- line-height: 1.5em;
157
- margin: 1.25em 0 .6em;
158
  text-align: center;
159
  }
160
 
 
 
 
 
 
161
  @media screen and ( max-width: 782px ) {
162
- .index_page_bp-about .about-wrap .headline-feature,
163
- .dashboard_page_bp-about .about-wrap .headline-feature {
164
- max-width: 100%;
165
  }
166
- .index_page_bp-about .about-wrap .headline-feature h3,
167
- .dahsboard_page_bp-about .about-wrap .headline-feature h3,
168
- .index_page_bp-about .about-wrap .headline-feature .headline-title,
169
- .dashboard_page_bp-about .about-wrap .headline-feature .headline-title {
170
- font-size: 2em;
171
  }
172
  .index_page_bp-about .bp-features-section,
173
  .dashboard_page_bp-about .bp-features-section {
 
174
  margin-bottom: 0;
 
175
  }
176
- .index_page_bp-about .about-wrap .feature-section,
177
- .dashboard_page_bp-about .about-wrap .feature-section {
178
- margin-top: 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  }
180
- .index_page_bp-about .about-wrap .two-col > div,
181
- .dashboard_page_bp-about .about-wrap .two-col > div {
182
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
183
- margin-top: 1.25em;
184
- padding-bottom: 1em;
185
  width: 100%;
186
  }
187
- .index_page_bp-about .changelog .two-col > div,
188
- .dashboard_page_bp-about .changelog .two-col > div {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  margin-top: 0;
190
- padding-bottom: 0;
 
191
  }
192
- .index_page_bp-about .about-wrap .changelog .changelog-title,
193
- .dashboard_page_bp-about .about-wrap .changelog .changelog-title {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  text-align: left;
195
  }
196
  }
197
-
198
-
199
  /*------------------------------------------------------------------------------
200
  * 2.0 Dashicons
201
  *----------------------------------------------------------------------------*/
@@ -367,3 +560,75 @@ body.users_page_bp-signups td.count_sent {
367
  body.post-type-bp-email #excerpt {
368
  height: auto;
369
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  1.1 Version Badge
13
  1.2 About Panel
14
  1.2.1 Headline Feature
15
+ 1.2.2 Features Section
16
+ 1.2.3 Changelog Section
 
17
  2.0 Dashicons
18
  2.1 Top level menus
19
  2.2 Settings - Components
20
  2.3 Tools
21
  3.0 User's Lists
22
  4.0 Emails - Edit page
23
+ 5.0 Tools - BuddyPress
24
+ 6.0 Plugins page
25
  ------------------------------------------------------------------------------*/
26
 
27
  /*------------------------------------------------------------------------------
63
  /*
64
  * 1.2.1 Headline Feature
65
  */
66
+ .index_page_bp-about .bp-headline-feature,
67
+ .dashboard_page_bp-about .bp-headline-feature {
68
+ margin-bottom: 3em;
69
+ margin-top: 3em;
70
+ padding: 2em 3em;
71
+ }
72
+
73
+ .index_page_bp-about .bp-headline,
74
+ .dashboard_page_bp-about .bp-headline {
75
+ margin: 0 auto;
76
+ width: 35em;
77
+ }
78
+
79
+ .index_page_bp-about .bp-headline span.dashicons,
80
+ .dashboard_page_bp-about .bp-headline span.dashicons {
81
+ background-color: #f1f1f1;
82
+ clear: left;
83
+ font-size: 100px;
84
+ float: left;
85
+ height: 100px;
86
+ line-height: 100px;
87
+ margin: 0 15px 15px 0 ;
88
  text-align: center;
89
+ width: 100px;
90
  }
91
 
92
+ .index_page_bp-about .bp-headline-feature h3,
93
+ .index_page_bp-about .bp-headline-feature .headline-title,
94
+ .dashboard_page_bp-about .bp-headline-feature h3,
95
+ .dashboard_page_bp-about .bp-headline-feature .headline-title {
96
  font-size: 2.2em;
97
+ font-weight: 300;
98
+ line-height: 1;
99
+ margin: 0 0 0 125px;
 
100
  }
101
 
102
+ .index_page_bp-about .bp-headline-feature p,
103
+ .dashboard_page_bp-about .bp-headline-feature p {
104
  font-size: 1.15em;
105
+ margin: 1.15em auto 0.6em 125px;
106
  }
107
 
108
+ .index_page_bp-about .bp-headline-feature .introduction,
109
+ .dashboard_page_bp-about .bp-headline-feature .introduction {
110
  font-weight: 600;
111
  }
112
 
113
+
114
  /*
115
+ * 1.2.2 Features Section
116
  */
117
+ .index_page_bp-about .bp-features-section,
118
+ .dashboard_page_bp-about .bp-features-section {
119
+ clear: both;
120
+ margin-top: 3em;
121
+ overflow: hidden;
122
+ padding-bottom: 0;
123
+ }
124
+
125
+ .index_page_bp-about span.dashicons,
126
+ .dashboard_page_bp-about span.dashicons {
127
+ background-color: #fff;
128
+ border-radius: 50%;
129
+ clear: left;
130
+ color: #d84800;
131
+ font-size: 50px;
132
  float: left;
133
+ height: 80px;
134
+ line-height: 80px;
135
+ margin: 0 15px 15px 0 ;
136
+ text-align: center;
137
+ width: 80px;
138
+ }
139
+
140
+ .index_page_bp-about .bp-features-section h3,
141
+ .dashboard_page_bp-about .bp-features-section h3 {
142
+ font-size: 2em;
143
+ font-weight: 300;
144
+ line-height: 1.5;
145
+ margin: 0 auto 3em;
146
+ text-align: center;
147
+ }
148
+
149
+ .index_page_bp-about .bp-feature,
150
+ .dashboard_page_bp-about .bp-feature {
151
+ float: left;
152
+ margin-bottom: 3em;
153
  margin-right: 4.799999999%;
 
154
  width: 47.6%;
155
  }
156
 
157
+
158
+ .index_page_bp-about .bp-feature code,
159
+ .dashboard_page_bp-about .bp-feature code{
160
+ font-size: 0.95em;
161
+ line-height: 1.5;
162
+ }
163
+
164
+ .index_page_bp-about .bp-feature:nth-of-type(2n),
165
+ .dashboard_page_bp-about .bp-feature:nth-of-type(2n) {
166
  margin-right: 0;
167
  }
168
 
169
+ .index_page_bp-about .bp-feature::after,
170
+ .dashboard_page_bp-about .bp-feature::after {
171
+ content: '';
172
+ }
173
+
174
+ .index_page_bp-about .bp-feature h4,
175
+ .dashboard_page_bp-about .bp-feature h4 {
176
+ font-size: 1.25em;
177
+ line-height: 1.5;
178
+ margin-bottom: 0;
179
+ margin-left: 110px;
180
+ margin-top: 0;
181
+ text-align: left;
182
  }
183
 
184
+ .index_page_bp-about .bp-feature p,
185
+ .dashboard_page_bp-about .bp-feature p {
186
+ margin-left: 110px;
187
+ }
188
+
189
+ /*
190
+ * 1.2.3 Changelog Section
191
+ */
192
+ .index_page_bp-about .bp-changelog-section,
193
+ .dashboard_page_bp-about .bp-changelog-section {
194
  clear: both;
195
+ margin-bottom: 8em;
196
+ margin-top: 3em;
197
  overflow: hidden;
198
  padding-bottom: 0;
199
  }
200
 
201
+ .index_page_bp-about .bp-changelog-section::after,
202
+ .dashboard_page_bp-about .bp-changelog-section::after {
203
+ content: '';
204
  }
205
 
206
+ .index_page_bp-about .bp-changelog-section .changelog-title,
207
+ .dashboard_page_bp-about .bp-changelog-section .changelog-title {
208
+ color: #23282d;
209
+ font-size: 1.8em;
210
+ font-weight: 300;
211
+ line-height: 1.5;
212
+ margin: 0 auto 0.5em;
213
+ text-align: center;
214
  }
215
 
216
+ .index_page_bp-about .bp-changelog-section .two-col > div,
217
+ .dashboard_page_bp-about .bp-changelog-section .two-col > div {
218
+ float: left;
219
+ margin-right: 4.799999999%;
220
+ position: relative;
221
+ width: 47.6%;
222
+ }
223
+
224
+ .index_page_bp-about .bp-changelog-section .two-col > div.last-feature,
225
+ .dashboard_page_bp-about .bp-changelog-section .two-col > div.last-feature {
226
+ margin-right: 0;
227
+ }
228
+
229
+ .index_page_bp-about .bp-changelog,
230
+ .dashboard_page_bp-about .bp-changelog {
231
+ margin-bottom: 3em;
232
+ }
233
+
234
+ .index_page_bp-about .bp-changelog h4,
235
+ .dashboard_page_bp-about .bp-changelog h4 {
236
  font-size: 1em;
237
+ margin-bottom: 0;
238
+ margin-top: 0;
239
  }
240
 
241
+ .index_page_bp-about .bp-changelog p,
242
+ .dashboard_page_bp-about .bp-changelog p {
 
 
 
 
243
  margin-bottom: 3em;
244
  }
245
 
246
+ .bp-changelog-url {
 
 
 
 
247
  text-align: center;
248
  }
249
 
250
+ .bp-assets {
251
+ clear: both;
252
+ margin-bottom: 2em;
253
+ }
254
+
255
  @media screen and ( max-width: 782px ) {
256
+ .index_page_bp-about .bp-headline-feature,
257
+ .dashboard_page_bp-about .bp-headline-feature {
258
+ padding: 0;
259
  }
260
+ .index_page_bp-about .bp-headline,
261
+ .dashboard_page_bp-about .bp-headline {
262
+ margin: 0;
263
+ width: 97%;
 
264
  }
265
  .index_page_bp-about .bp-features-section,
266
  .dashboard_page_bp-about .bp-features-section {
267
+ clear: both;
268
  margin-bottom: 0;
269
+ margin-top: 2em;
270
  }
271
+ .index_page_bp-about .bp-features-section h3,
272
+ .dashboard_page_bp-about .bp-features-section h3,
273
+ .index_page_bp-about .bp-changelog-section .changelog-title,
274
+ .dashboard_page_bp-about .bp-changelog-section .changelog-title {
275
+ font-size: 1.8em;
276
+ font-weight: 300;
277
+ line-height: 1.5;
278
+ margin-bottom: 0.5em;
279
+ margin-top: 0.5em;
280
+ }
281
+ .index_page_bp-about .bp-features-section h4,
282
+ .dashboard_page_bp-about .bp-features-section h4,
283
+ .index_page_bp-about .bp-changelog-section h4,
284
+ .dashboard_page_bp-about .bp-changelog-section h4 {
285
+ font-size: 1.25em;
286
+ line-height: 1.25;
287
+ margin-top: 0.6em;
288
+ text-align: left;
289
+ }
290
+ .index_page_bp-about .bp-feature,
291
+ .dashboard_page_bp-about .bp-feature {
292
+ clear: both;
293
+ float: left;
294
+ margin-bottom: 1em;
295
+ margin-top: 1em;
296
+ margin-right: 0;
297
+ padding-right: 1em;
298
+ width: 100%;
299
+ }
300
+ .index_page_bp-about .bp-feature span,
301
+ .dashboard_page_bp-about .bp-feature span {
302
+ margin-top: 0.33em;
303
  }
304
+ .index_page_bp-about .bp-feature h4,
305
+ .dashboard_page_bp-about .bp-feature h4,
306
+ .index_page_bp-about .bp-feature p,
307
+ .dashboard_page_bp-about .bp-feature p {
 
308
  width: 100%;
309
  }
310
+ .index_page_bp-about .bp-feature.opposite h4,
311
+ .dashboard_page_bp-about .bp-feature.opposite h4,
312
+ .index_page_bp-about .bp-feature.opposite p,
313
+ .dashboard_page_bp-about .bp-feature.opposite p {
314
+ float: none;
315
+ }
316
+ .index_page_bp-about .bp-changelog-section,
317
+ .dashboard_page_bp-about .bp-changelog-section {
318
+ clear: both;
319
+ margin-bottom: 2em;
320
+ }
321
+ .index_page_bp-about .bp-changelog-section .changelog-title,
322
+ .dashboard_page_bp-about .bp-changelog-section .changelog-title {
323
+ margin-bottom: 1em;
324
+ }
325
+ .index_page_bp-about .bp-changelog h4,
326
+ .dashboard_page_bp-about .bp-changelog h4 {
327
+ font-size: 1em;
328
+ }
329
+ .index_page_bp-about .bp-changelog p,
330
+ .dashboard_page_bp-about .bp-changelog p {
331
+ margin-bottom: 2em;
332
+ }
333
+ .index_page_bp-about .bp-changelog-section .two-col > div,
334
+ .dashboard_page_bp-about .bp-changelog-section .two-col > div {
335
  margin-top: 0;
336
+ padding-bottom: 0.5em;
337
+ width: 100%;
338
  }
339
+ }
340
+ @media screen and ( max-width: 360px ) {
341
+ .index_page_bp-about .bp-headline,
342
+ .dashboard_page_bp-about .bp-headline {
343
+ text-align: center;
344
+ }
345
+ .index_page_bp-about .bp-headline span.dashicons,
346
+ .dashboard_page_bp-about .bp-headline span.dashicons {
347
+ clear: none;
348
+ font-size: 80px;
349
+ float: none;
350
+ height: 80px;
351
+ line-height: 80px;
352
+ margin: 0 auto;
353
+ width: 80px;
354
+ }
355
+ .index_page_bp-about .bp-headline-feature h3,
356
+ .index_page_bp-about .bp-headline-feature .headline-title,
357
+ .dashboard_page_bp-about .bp-headline-feature h3,
358
+ .dashboard_page_bp-about .bp-headline-feature .headline-title {
359
+ margin: 1em 0 0 0;
360
+ text-align: left;
361
+ }
362
+ .index_page_bp-about .bp-headline-feature p,
363
+ .dashboard_page_bp-about .bp-headline-feature p {
364
+ margin: 1.15em auto 0.6em 0;
365
+ text-align: left;
366
+ }
367
+ .index_page_bp-about .bp-headline-feature .headline-title,
368
+ .dashboard_page_bp-about .bp-headline-feature .headline-title {
369
+ font-size: 1.5em;
370
+ line-height: 1.5;
371
+ }
372
+ .index_page_bp-about .bp-headline-feature p,
373
+ .dashboard_page_bp-about .bp-headline-feature p {
374
+ width: auto;
375
+ }
376
+ .index_page_bp-about .bp-feature,
377
+ .dashboard_page_bp-about .bp-feature {
378
+ text-align: center;
379
+ }
380
+ .index_page_bp-about span.dashicons,
381
+ .dashboard_page_bp-about span.dashicons {
382
+ float: none;
383
+ }
384
+ .index_page_bp-about .bp-features-section h4,
385
+ .dashboard_page_bp-about .bp-features-section h4,
386
+ .index_page_bp-about .bp-features-section p,
387
+ .dashboard_page_bp-about .bp-features-section p {
388
+ margin-left: 0;
389
  text-align: left;
390
  }
391
  }
 
 
392
  /*------------------------------------------------------------------------------
393
  * 2.0 Dashicons
394
  *----------------------------------------------------------------------------*/
560
  body.post-type-bp-email #excerpt {
561
  height: auto;
562
  }
563
+
564
+ body.post-type-bp-email th#situation {
565
+ width: 20%;
566
+ }
567
+
568
+ body.post-type-bp-email td.column-situation ul {
569
+ margin: 0;
570
+ }
571
+
572
+ body.post-type-bp-email .categorydiv label {
573
+ display: block;
574
+ float: left;
575
+ padding-left: 25px;
576
+ text-indent: -25px;
577
+ }
578
+
579
+ /*------------------------------------------------------------------------------
580
+ * 5.0 Tools - BuddyPress
581
+ *----------------------------------------------------------------------------*/
582
+ .tools_page_bp-tools .wrap {
583
+ max-width: 950px;
584
+ }
585
+
586
+ .tools_page_bp-tools p {
587
+ line-height: 2;
588
+ }
589
+
590
+ .tools_page_bp-tools fieldset {
591
+ margin: 2em 0 0;
592
+ }
593
+
594
+ .tools_page_bp-tools legend {
595
+ color: #23282d;
596
+ font-size: 1.3em;
597
+ font-weight: 600px;
598
+ margin: 1em 0;
599
+ }
600
+
601
+ .tools_page_bp-tools label {
602
+ clear: left;
603
+ display: block;
604
+ line-height: 1.5em;
605
+ margin: 0 0 1em;
606
+ vertical-align: middle;
607
+ }
608
+
609
+ @media screen and (max-width: 782px) {
610
+ .tools_page_bp-tools p {
611
+ line-height: 1.5;
612
+ }
613
+ .tools_page_bp-tools label {
614
+ margin-bottom: 1em;
615
+ padding-right: 25px;
616
+ text-indent: -33px;
617
+ }
618
+ .tools_page_bp-tools .checkbox {
619
+ padding: 0 0 0 30px;
620
+ }
621
+ }
622
+
623
+
624
+ /*------------------------------------------------------------------------------
625
+ * 6.0 Plugins page
626
+ *----------------------------------------------------------------------------*/
627
+ #buddypress-update.not-shiny .update-message {
628
+ border-left: 0;
629
+ padding-left: 36px;
630
+ }
631
+
632
+ #buddypress-update.not-shiny .update-message:before {
633
+ content: "\f534";
634
+ }
bp-core/admin/css/common.min.css CHANGED
@@ -1 +1 @@
1
- .bp-badge{color:#d84800;display:inline-block;font:400 150px/1 dashicons!important}.bp-badge:before{content:"\f448"}.about-wrap .bp-badge{position:absolute;top:0;right:0}@media only screen and (max-width:500px){.about-wrap .bp-badge{position:relative;margin:10px auto;top:auto;right:auto}}.dashboard_page_bp-about .about-wrap .headline-feature,.index_page_bp-about .about-wrap .headline-feature{margin-bottom:2em;text-align:center}.dashboard_page_bp-about .about-wrap .headline-feature h3,.dashboard_page_bp-about .headline-feature .headline-title,.index_page_bp-about .about-wrap .headline-feature h3,.index_page_bp-about .headline-feature .headline-title{font-size:2.2em;font-weight:400;line-height:1.3;margin:1.25em 0 .6em;text-align:center}.dashboard_page_bp-about .about-wrap .headline-feature p,.index_page_bp-about .about-wrap .headline-feature p{font-size:1.15em;margin:1.15em auto .6em}.dashboard_page_bp-about .about-wrap .headline-feature .introduction,.index_page_bp-about .about-wrap .headline-feature .introduction{font-weight:600}.dashboard_page_bp-about .about-wrap .two-col>div,.index_page_bp-about .about-wrap .two-col>div{float:left;margin-right:4.799999999%;position:relative;width:47.6%}.dashboard_page_bp-about .about-wrap .two-col .last-feature,.index_page_bp-about .about-wrap .two-col .last-feature{margin-right:0}.dashboard_page_bp-about .bp-features-section,.index_page_bp-about .bp-features-section{margin-bottom:2em}.dashboard_page_bp-about .about-wrap .feature-section,.index_page_bp-about .about-wrap .feature-section{clear:both;margin-top:2em;overflow:hidden;padding-bottom:0}.dashboard_page_bp-about .about-wrap .changelog .feature-section,.index_page_bp-about .about-wrap .changelog .feature-section{margin-top:0}.dashboard_page_bp-about .about-wrap .feature-section h3,.index_page_bp-about .about-wrap .feature-section h3{font-size:1.25em;line-height:1.5em;margin:0 0 .6em}.dashboard_page_bp-about .about-wrap .changelog h4,.index_page_bp-about .about-wrap .changelog h4{color:#23282d;font-size:1em;margin:1.4em 0 .6em}.dashboard_page_bp-about .about-wrap .changelog,.index_page_bp-about .about-wrap .changelog{border-top:1px solid #eee;margin-bottom:3em}.dashboard_page_bp-about .about-wrap .changelog .changelog-title,.index_page_bp-about .about-wrap .changelog .changelog-title{font-size:1.25em;line-height:1.5em;margin:1.25em 0 .6em;text-align:center}@media screen and (max-width:782px){.dashboard_page_bp-about .about-wrap .headline-feature,.index_page_bp-about .about-wrap .headline-feature{max-width:100%}.dahsboard_page_bp-about .about-wrap .headline-feature h3,.dashboard_page_bp-about .about-wrap .headline-feature .headline-title,.index_page_bp-about .about-wrap .headline-feature .headline-title,.index_page_bp-about .about-wrap .headline-feature h3{font-size:2em}.dashboard_page_bp-about .bp-features-section,.index_page_bp-about .bp-features-section{margin-bottom:0}.dashboard_page_bp-about .about-wrap .feature-section,.index_page_bp-about .about-wrap .feature-section{margin-top:0}.dashboard_page_bp-about .about-wrap .two-col>div,.index_page_bp-about .about-wrap .two-col>div{border-bottom:1px solid rgba(0,0,0,.1);margin-top:1.25em;padding-bottom:1em;width:100%}.dashboard_page_bp-about .changelog .two-col>div,.index_page_bp-about .changelog .two-col>div{margin-top:0;padding-bottom:0}.dashboard_page_bp-about .about-wrap .changelog .changelog-title,.index_page_bp-about .about-wrap .changelog .changelog-title{text-align:left}}#adminmenu #toplevel_page_bp-activity .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_user .wp-menu-image:before{content:"\f452"}#adminmenu #toplevel_page_bp-groups .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_user .wp-menu-image:before{content:"\f456"}#adminmenu #toplevel_page_bp-notifications .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_user .wp-menu-image:before{content:"\f439"}#adminmenu #toplevel_page_bp-messages .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_user .wp-menu-image:before{content:"\f457"}#adminmenu #toplevel_page_bp-friends .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_user .wp-menu-image:before{content:"\f454"}#adminmenu #toplevel_page_bp-settings .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_user .wp-menu-image:before{content:"\f108"}#adminmenu li.toplevel_page_bp-components .wp-menu-image,#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image{content:"\f448"}.settings_page_bp-components td.plugin-title span{float:left;width:18px;height:18px;margin-right:5px}.settings_page_bp-components td.plugin-title span:before{font-family:dashicons;font-size:18px}.settings_page_bp-components tr.activity td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.notifications td.plugin-title span:before{content:"\f339"}.settings_page_bp-components tr.xprofile td.plugin-title span:before{content:"\f336"}.settings_page_bp-components tr.settings td.plugin-title span:before{content:"\f108"}.settings_page_bp-components tr.groups td.plugin-title span:before{content:"\f456"}.settings_page_bp-components tr.messages td.plugin-title span:before{content:"\f457"}.settings_page_bp-components tr.forums td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.blogs td.plugin-title span:before{content:"\f120"}.settings_page_bp-components tr.friends td.plugin-title span:before{content:"\f454"}.settings_page_bp-components tr.core td.plugin-title span:before{content:"\f448"}.settings_page_bp-components tr.members td.plugin-title span:before{content:"\f307"}#bp-admin-component-form .wp-list-table.plugins .plugin-title{width:25%}@media screen and (max-width:782px){.settings_page_bp-components td.plugin-title span{margin-top:5px}#bp-admin-component-form .wp-list-table.plugins .plugin-title{display:block;width:auto}#bp-admin-component-form .subsubsub{margin-bottom:0;padding-bottom:35px}}#adminmenu .toplevel_page_network-tools div.wp-menu-image:before{content:""}body.site-users-php th#role,body.users-php th#role,body.users_page_bp-signups th#count_sent{width:10%}body.site-users-php th#email,body.site-users-php th#name,body.users-php th#email,body.users-php th#name,body.users-php th#registered,body.users_page_bp-signups th#date_sent,body.users_page_bp-signups th#email,body.users_page_bp-signups th#name,body.users_page_bp-signups th#registered{width:15%}body.users-php th#blogs,body.users_page_bp-signups th#blogs{width:20%}body.users_page_bp-signups td.count_sent,body.users_page_bp-signups th.column-count_sent{text-align:center}body.post-type-bp-email #excerpt{height:auto}
1
+ .bp-badge{color:#d84800;display:inline-block;font:400 150px/1 dashicons!important}.bp-badge:before{content:"\f448"}.dashboard_page_bp-about .bp-changelog-section::after,.dashboard_page_bp-about .bp-feature::after,.index_page_bp-about .bp-changelog-section::after,.index_page_bp-about .bp-feature::after{content:''}.about-wrap .bp-badge{position:absolute;top:0;right:0}@media only screen and (max-width:500px){.about-wrap .bp-badge{position:relative;margin:10px auto;top:auto;right:auto}}.dashboard_page_bp-about .bp-headline-feature,.index_page_bp-about .bp-headline-feature{margin-bottom:3em;margin-top:3em;padding:2em 3em}.dashboard_page_bp-about .bp-headline,.index_page_bp-about .bp-headline{margin:0 auto;width:35em}.dashboard_page_bp-about .bp-headline span.dashicons,.index_page_bp-about .bp-headline span.dashicons{background-color:#f1f1f1;clear:left;font-size:100px;float:left;height:100px;line-height:100px;margin:0 15px 15px 0;text-align:center;width:100px}.dashboard_page_bp-about .bp-headline-feature .headline-title,.dashboard_page_bp-about .bp-headline-feature h3,.index_page_bp-about .bp-headline-feature .headline-title,.index_page_bp-about .bp-headline-feature h3{font-size:2.2em;font-weight:300;line-height:1;margin:0 0 0 125px}.dashboard_page_bp-about .bp-headline-feature p,.index_page_bp-about .bp-headline-feature p{font-size:1.15em;margin:1.15em auto .6em 125px}.dashboard_page_bp-about .bp-headline-feature .introduction,.index_page_bp-about .bp-headline-feature .introduction{font-weight:600}.dashboard_page_bp-about .bp-features-section,.index_page_bp-about .bp-features-section{clear:both;margin-top:3em;overflow:hidden;padding-bottom:0}.dashboard_page_bp-about span.dashicons,.index_page_bp-about span.dashicons{background-color:#fff;border-radius:50%;clear:left;color:#d84800;font-size:50px;float:left;height:80px;line-height:80px;margin:0 15px 15px 0;text-align:center;width:80px}.dashboard_page_bp-about .bp-features-section h3,.index_page_bp-about .bp-features-section h3{font-size:2em;font-weight:300;line-height:1.5;margin:0 auto 3em;text-align:center}.dashboard_page_bp-about .bp-feature,.index_page_bp-about .bp-feature{float:left;margin-bottom:3em;margin-right:4.799999999%;width:47.6%}.dashboard_page_bp-about .bp-feature code,.index_page_bp-about .bp-feature code{font-size:.95em;line-height:1.5}.dashboard_page_bp-about .bp-feature:nth-of-type(2n),.index_page_bp-about .bp-feature:nth-of-type(2n){margin-right:0}.dashboard_page_bp-about .bp-feature h4,.index_page_bp-about .bp-feature h4{font-size:1.25em;line-height:1.5;margin-bottom:0;margin-left:110px;margin-top:0;text-align:left}.dashboard_page_bp-about .bp-feature p,.index_page_bp-about .bp-feature p{margin-left:110px}.dashboard_page_bp-about .bp-changelog-section,.index_page_bp-about .bp-changelog-section{clear:both;margin-bottom:8em;margin-top:3em;overflow:hidden;padding-bottom:0}.dashboard_page_bp-about .bp-changelog-section .changelog-title,.index_page_bp-about .bp-changelog-section .changelog-title{color:#23282d;font-size:1.8em;font-weight:300;line-height:1.5;margin:0 auto .5em;text-align:center}.dashboard_page_bp-about .bp-changelog-section .two-col>div,.index_page_bp-about .bp-changelog-section .two-col>div{float:left;margin-right:4.799999999%;position:relative;width:47.6%}.dashboard_page_bp-about .bp-changelog-section .two-col>div.last-feature,.index_page_bp-about .bp-changelog-section .two-col>div.last-feature{margin-right:0}.dashboard_page_bp-about .bp-changelog,.index_page_bp-about .bp-changelog{margin-bottom:3em}.dashboard_page_bp-about .bp-changelog h4,.index_page_bp-about .bp-changelog h4{font-size:1em;margin-bottom:0;margin-top:0}.dashboard_page_bp-about .bp-changelog p,.index_page_bp-about .bp-changelog p{margin-bottom:3em}.bp-changelog-url{text-align:center}.bp-assets{clear:both;margin-bottom:2em}@media screen and (max-width:782px){.dashboard_page_bp-about .bp-headline-feature,.index_page_bp-about .bp-headline-feature{padding:0}.dashboard_page_bp-about .bp-headline,.index_page_bp-about .bp-headline{margin:0;width:97%}.dashboard_page_bp-about .bp-features-section,.index_page_bp-about .bp-features-section{clear:both;margin-bottom:0;margin-top:2em}.dashboard_page_bp-about .bp-changelog-section .changelog-title,.dashboard_page_bp-about .bp-features-section h3,.index_page_bp-about .bp-changelog-section .changelog-title,.index_page_bp-about .bp-features-section h3{font-size:1.8em;font-weight:300;line-height:1.5;margin-bottom:.5em;margin-top:.5em}.dashboard_page_bp-about .bp-changelog-section h4,.dashboard_page_bp-about .bp-features-section h4,.index_page_bp-about .bp-changelog-section h4,.index_page_bp-about .bp-features-section h4{font-size:1.25em;line-height:1.25;margin-top:.6em;text-align:left}.dashboard_page_bp-about .bp-feature,.index_page_bp-about .bp-feature{clear:both;float:left;margin-bottom:1em;margin-top:1em;margin-right:0;padding-right:1em;width:100%}.dashboard_page_bp-about .bp-feature span,.index_page_bp-about .bp-feature span{margin-top:.33em}.dashboard_page_bp-about .bp-feature h4,.dashboard_page_bp-about .bp-feature p,.index_page_bp-about .bp-feature h4,.index_page_bp-about .bp-feature p{width:100%}.dashboard_page_bp-about .bp-feature.opposite h4,.dashboard_page_bp-about .bp-feature.opposite p,.index_page_bp-about .bp-feature.opposite h4,.index_page_bp-about .bp-feature.opposite p{float:none}.dashboard_page_bp-about .bp-changelog-section,.index_page_bp-about .bp-changelog-section{clear:both;margin-bottom:2em}.dashboard_page_bp-about .bp-changelog-section .changelog-title,.index_page_bp-about .bp-changelog-section .changelog-title{margin-bottom:1em}.dashboard_page_bp-about .bp-changelog h4,.index_page_bp-about .bp-changelog h4{font-size:1em}.dashboard_page_bp-about .bp-changelog p,.index_page_bp-about .bp-changelog p{margin-bottom:2em}.dashboard_page_bp-about .bp-changelog-section .two-col>div,.index_page_bp-about .bp-changelog-section .two-col>div{margin-top:0;padding-bottom:.5em;width:100%}}@media screen and (max-width:360px){.dashboard_page_bp-about .bp-headline,.index_page_bp-about .bp-headline{text-align:center}.dashboard_page_bp-about .bp-headline span.dashicons,.index_page_bp-about .bp-headline span.dashicons{clear:none;font-size:80px;float:none;height:80px;line-height:80px;margin:0 auto;width:80px}.dashboard_page_bp-about .bp-headline-feature .headline-title,.dashboard_page_bp-about .bp-headline-feature h3,.index_page_bp-about .bp-headline-feature .headline-title,.index_page_bp-about .bp-headline-feature h3{margin:1em 0 0;text-align:left}.dashboard_page_bp-about .bp-headline-feature p,.index_page_bp-about .bp-headline-feature p{margin:1.15em auto .6em 0;text-align:left;width:auto}.dashboard_page_bp-about .bp-headline-feature .headline-title,.index_page_bp-about .bp-headline-feature .headline-title{font-size:1.5em;line-height:1.5}.dashboard_page_bp-about .bp-feature,.index_page_bp-about .bp-feature{text-align:center}.dashboard_page_bp-about span.dashicons,.index_page_bp-about span.dashicons{float:none}.dashboard_page_bp-about .bp-features-section h4,.dashboard_page_bp-about .bp-features-section p,.index_page_bp-about .bp-features-section h4,.index_page_bp-about .bp-features-section p{margin-left:0;text-align:left}}#adminmenu #toplevel_page_bp-activity .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-activity_user .wp-menu-image:before{content:"\f452"}#adminmenu #toplevel_page_bp-groups .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-groups_user .wp-menu-image:before{content:"\f456"}#adminmenu #toplevel_page_bp-notifications .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-notifications_user .wp-menu-image:before{content:"\f439"}#adminmenu #toplevel_page_bp-messages .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-messages_user .wp-menu-image:before{content:"\f457"}#adminmenu #toplevel_page_bp-friends .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-friends_user .wp-menu-image:before{content:"\f454"}#adminmenu #toplevel_page_bp-settings .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_network .wp-menu-image:before,#adminmenu #toplevel_page_bp-settings_user .wp-menu-image:before{content:"\f108"}#adminmenu li.toplevel_page_bp-components .wp-menu-image,#adminmenu li.toplevel_page_bp-general-settings .wp-menu-image{content:"\f448"}.settings_page_bp-components td.plugin-title span{float:left;width:18px;height:18px;margin-right:5px}.settings_page_bp-components td.plugin-title span:before{font-family:dashicons;font-size:18px}.settings_page_bp-components tr.activity td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.notifications td.plugin-title span:before{content:"\f339"}.settings_page_bp-components tr.xprofile td.plugin-title span:before{content:"\f336"}.settings_page_bp-components tr.settings td.plugin-title span:before{content:"\f108"}.settings_page_bp-components tr.groups td.plugin-title span:before{content:"\f456"}.settings_page_bp-components tr.messages td.plugin-title span:before{content:"\f457"}.settings_page_bp-components tr.forums td.plugin-title span:before{content:"\f452"}.settings_page_bp-components tr.blogs td.plugin-title span:before{content:"\f120"}.settings_page_bp-components tr.friends td.plugin-title span:before{content:"\f454"}.settings_page_bp-components tr.core td.plugin-title span:before{content:"\f448"}.settings_page_bp-components tr.members td.plugin-title span:before{content:"\f307"}#bp-admin-component-form .wp-list-table.plugins .plugin-title{width:25%}@media screen and (max-width:782px){.settings_page_bp-components td.plugin-title span{margin-top:5px}#bp-admin-component-form .wp-list-table.plugins .plugin-title{display:block;width:auto}#bp-admin-component-form .subsubsub{margin-bottom:0;padding-bottom:35px}}#adminmenu .toplevel_page_network-tools div.wp-menu-image:before{content:""}body.site-users-php th#role,body.users-php th#role,body.users_page_bp-signups th#count_sent{width:10%}body.site-users-php th#email,body.site-users-php th#name,body.users-php th#email,body.users-php th#name,body.users-php th#registered,body.users_page_bp-signups th#date_sent,body.users_page_bp-signups th#email,body.users_page_bp-signups th#name,body.users_page_bp-signups th#registered{width:15%}body.post-type-bp-email th#situation,body.users-php th#blogs,body.users_page_bp-signups th#blogs{width:20%}body.users_page_bp-signups td.count_sent,body.users_page_bp-signups th.column-count_sent{text-align:center}body.post-type-bp-email #excerpt{height:auto}body.post-type-bp-email td.column-situation ul{margin:0}body.post-type-bp-email .categorydiv label{display:block;float:left;padding-left:25px;text-indent:-25px}.tools_page_bp-tools .wrap{max-width:950px}.tools_page_bp-tools p{line-height:2}.tools_page_bp-tools fieldset{margin:2em 0 0}.tools_page_bp-tools legend{color:#23282d;font-size:1.3em;font-weight:600px;margin:1em 0}.tools_page_bp-tools label{clear:left;display:block;line-height:1.5em;margin:0 0 1em;vertical-align:middle}@media screen and (max-width:782px){.tools_page_bp-tools p{line-height:1.5}.tools_page_bp-tools label{margin-bottom:1em;padding-right:25px;text-indent:-33px}.tools_page_bp-tools .checkbox{padding:0 0 0 30px}}#buddypress-update.not-shiny .update-message{border-left:0;padding-left:36px}#buddypress-update.not-shiny .update-message:before{content:"\f534"}
bp-core/admin/images/autolink-feature.png DELETED
Binary file
bp-core/admin/images/bp-emails-feature.png DELETED
Binary file
bp-core/admin/images/emoji-feature.png DELETED
Binary file
bp-core/admin/images/post-type.png DELETED
Binary file
bp-core/admin/images/twentytwelve.png DELETED
Binary file
bp-core/admin/js/customizer-controls.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
  !function(a){a(window).on("load",function(){a(".customize-control-range input").on("input",function(){var b=a(this);b.siblings("output").text(b.val())})})}(jQuery);
 
1
  !function(a){a(window).on("load",function(){a(".customize-control-range input").on("input",function(){var b=a(this);b.siblings("output").text(b.val())})})}(jQuery);
bp-core/admin/js/customizer-receiver-emails.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
  !function(a){wp.customize("bp_email_options[email_bg]",function(b){b.bind(function(b){b.length&&(a(".email_bg").attr("bgcolor",b),a("hr").attr("color",b))})}),wp.customize("bp_email_options[header_bg]",function(b){b.bind(function(b){b.length&&a(".header_bg").attr("bgcolor",b)})}),wp.customize("bp_email_options[header_text_size]",function(b){b.bind(function(b){b.length&&a(".header_text_size").css("font-size",b+"px")})}),wp.customize("bp_email_options[header_text_color]",function(b){b.bind(function(b){b.length&&a(".header_text_color").css("color",b)})}),wp.customize("bp_email_options[highlight_color]",function(b){b.bind(function(b){b.length&&(a(".header_bg").css("border-top-color",b),a("a").css("color",b),a("hr").attr("color",b))})}),wp.customize("bp_email_options[body_bg]",function(b){b.bind(function(b){b.length&&a(".body_bg").attr("bgcolor",b)})}),wp.customize("bp_email_options[body_text_size]",function(b){b.bind(function(b){b.length&&(a(".body_text_size").css("font-size",b+"px").css("line-height",Math.floor(1.618*b)+"px"),a(".welcome").css("font-size",Math.floor(1.35*b)+"px"))})}),wp.customize("bp_email_options[body_text_color]",function(b){b.bind(function(b){b.length&&a(".body_text_color").css("color",b)})}),wp.customize("bp_email_options[footer_bg]",function(b){b.bind(function(b){b.length&&a(".footer_bg").attr("bgcolor",b)})}),wp.customize("bp_email_options[footer_text_size]",function(b){b.bind(function(b){b.length&&a(".footer_text_size").css("font-size",b+"px").css("line-height",Math.floor(1.618*b)+"px")})}),wp.customize("bp_email_options[footer_text_color]",function(b){b.bind(function(b){b.length&&a(".footer_text_color").css("color",b)})}),wp.customize("bp_email_options[footer_text]",function(b){b.bind(function(b){a(".footer_text").text(b)})})}(jQuery);
 
1
  !function(a){wp.customize("bp_email_options[email_bg]",function(b){b.bind(function(b){b.length&&(a(".email_bg").attr("bgcolor",b),a("hr").attr("color",b))})}),wp.customize("bp_email_options[header_bg]",function(b){b.bind(function(b){b.length&&a(".header_bg").attr("bgcolor",b)})}),wp.customize("bp_email_options[header_text_size]",function(b){b.bind(function(b){b.length&&a(".header_text_size").css("font-size",b+"px")})}),wp.customize("bp_email_options[header_text_color]",function(b){b.bind(function(b){b.length&&a(".header_text_color").css("color",b)})}),wp.customize("bp_email_options[highlight_color]",function(b){b.bind(function(b){b.length&&(a(".header_bg").css("border-top-color",b),a("a").css("color",b),a("hr").attr("color",b))})}),wp.customize("bp_email_options[body_bg]",function(b){b.bind(function(b){b.length&&a(".body_bg").attr("bgcolor",b)})}),wp.customize("bp_email_options[body_text_size]",function(b){b.bind(function(b){b.length&&(a(".body_text_size").css("font-size",b+"px").css("line-height",Math.floor(1.618*b)+"px"),a(".welcome").css("font-size",Math.floor(1.35*b)+"px"))})}),wp.customize("bp_email_options[body_text_color]",function(b){b.bind(function(b){b.length&&a(".body_text_color").css("color",b)})}),wp.customize("bp_email_options[footer_bg]",function(b){b.bind(function(b){b.length&&a(".footer_bg").attr("bgcolor",b)})}),wp.customize("bp_email_options[footer_text_size]",function(b){b.bind(function(b){b.length&&a(".footer_text_size").css("font-size",b+"px").css("line-height",Math.floor(1.618*b)+"px")})}),wp.customize("bp_email_options[footer_text_color]",function(b){b.bind(function(b){b.length&&a(".footer_text_color").css("color",b)})}),wp.customize("bp_email_options[footer_text]",function(b){b.bind(function(b){a(".footer_text").text(b)})})}(jQuery);
bp-core/admin/js/dismissible-admin-notices.js ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function($){
2
+ $(document).ready(function() {
3
+ $( '.bp-is-dismissible .notice-dismiss' ).click( function() {
4
+ var $notice = $( this ).closest( '.notice' );
5
+ var notice_id = $notice.data( 'noticeid' );
6
+ $.post( {
7
+ url: ajaxurl,
8
+ data: {
9
+ action: 'bp_dismiss_notice',
10
+ nonce: $( '#bp-dismissible-nonce-' + notice_id ).val(),
11
+ notice_id: $notice.data( 'noticeid' )
12
+ }
13
+ } );
14
+ } );
15
+ });
16
+ }(jQuery));
bp-core/admin/js/dismissible-admin-notices.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a){a(document).ready(function(){a(".bp-is-dismissible .notice-dismiss").click(function(){var b=a(this).closest(".notice"),c=b.data("noticeid");a.post({url:ajaxurl,data:{action:"bp_dismiss_notice",nonce:a("#bp-dismissible-nonce-"+c).val(),notice_id:b.data("noticeid")}})})})}(jQuery);
bp-core/bp-core-actions.php CHANGED
@@ -29,9 +29,10 @@ defined( 'ABSPATH' ) || exit;
29
  * near the bottom of this file.
30
  *
31
  * v--WordPress Actions v--BuddyPress Sub-actions
32
- */
33
  add_action( 'plugins_loaded', 'bp_loaded', 10 );
34
  add_action( 'init', 'bp_init', 10 );
 
35
  add_action( 'customize_register', 'bp_customize_register', 20 ); // After WP core.
36
  add_action( 'parse_query', 'bp_parse_query', 2 ); // Early for overrides.
37
  add_action( 'wp', 'bp_ready', 10 );
@@ -39,6 +40,7 @@ add_action( 'set_current_user', 'bp_setup_current_user', 10 );
39
  add_action( 'setup_theme', 'bp_setup_theme', 10 );
40
  add_action( 'after_setup_theme', 'bp_after_setup_theme', 100 ); // After WP themes.
41
  add_action( 'wp_enqueue_scripts', 'bp_enqueue_scripts', 10 );
 
42
  add_action( 'admin_bar_menu', 'bp_setup_admin_bar', 20 ); // After WP core.
43
  add_action( 'template_redirect', 'bp_template_redirect', 10 );
44
  add_action( 'widgets_init', 'bp_widgets_init', 10 );
@@ -55,7 +57,6 @@ add_action( 'bp_loaded', 'bp_setup_components', 2 );
55
  add_action( 'bp_loaded', 'bp_include', 4 );
56
  add_action( 'bp_loaded', 'bp_setup_cache_groups', 5 );
57
  add_action( 'bp_loaded', 'bp_setup_widgets', 6 );
58
- add_action( 'bp_loaded', 'bp_register_member_types', 8 );
59
  add_action( 'bp_loaded', 'bp_register_theme_packages', 12 );
60
  add_action( 'bp_loaded', 'bp_register_theme_directory', 14 );
61
 
@@ -66,9 +67,9 @@ add_action( 'bp_loaded', 'bp_register_theme_directory', 14 );
66
  * The load order helps to execute code at the correct time.
67
  * v---Load order
68
  */
 
 
69
  add_action( 'bp_init', 'bp_core_set_uri_globals', 2 );
70
- add_action( 'bp_init', 'bp_register_post_types', 3 );
71
- add_action( 'bp_init', 'bp_register_taxonomies', 3 );
72
  add_action( 'bp_init', 'bp_setup_globals', 4 );
73
  add_action( 'bp_init', 'bp_setup_canonical_stack', 5 );
74
  add_action( 'bp_init', 'bp_setup_nav', 6 );
@@ -78,6 +79,11 @@ add_action( 'bp_init', 'bp_add_rewrite_tags', 20 );
78
  add_action( 'bp_init', 'bp_add_rewrite_rules', 30 );
79
  add_action( 'bp_init', 'bp_add_permastructs', 40 );
80
 
 
 
 
 
 
81
  /**
82
  * The bp_template_redirect hook - Attached to 'template_redirect' above.
83
  *
@@ -108,3 +114,6 @@ if ( is_admin() ) {
108
 
109
  // Activation redirect.
110
  add_action( 'bp_activation', 'bp_add_activation_redirect' );
 
 
 
29
  * near the bottom of this file.
30
  *
31
  * v--WordPress Actions v--BuddyPress Sub-actions
32
+ */
33
  add_action( 'plugins_loaded', 'bp_loaded', 10 );
34
  add_action( 'init', 'bp_init', 10 );
35
+ add_action( 'rest_api_init', 'bp_rest_api_init', 20 ); // After WP core.
36
  add_action( 'customize_register', 'bp_customize_register', 20 ); // After WP core.
37
  add_action( 'parse_query', 'bp_parse_query', 2 ); // Early for overrides.
38
  add_action( 'wp', 'bp_ready', 10 );
40
  add_action( 'setup_theme', 'bp_setup_theme', 10 );
41
  add_action( 'after_setup_theme', 'bp_after_setup_theme', 100 ); // After WP themes.
42
  add_action( 'wp_enqueue_scripts', 'bp_enqueue_scripts', 10 );
43
+ add_action( 'enqueue_embed_scripts', 'bp_enqueue_embed_scripts', 10 );
44
  add_action( 'admin_bar_menu', 'bp_setup_admin_bar', 20 ); // After WP core.
45
  add_action( 'template_redirect', 'bp_template_redirect', 10 );
46
  add_action( 'widgets_init', 'bp_widgets_init', 10 );
57
  add_action( 'bp_loaded', 'bp_include', 4 );
58
  add_action( 'bp_loaded', 'bp_setup_cache_groups', 5 );
59
  add_action( 'bp_loaded', 'bp_setup_widgets', 6 );
 
60
  add_action( 'bp_loaded', 'bp_register_theme_packages', 12 );
61
  add_action( 'bp_loaded', 'bp_register_theme_directory', 14 );
62
 
67
  * The load order helps to execute code at the correct time.
68
  * v---Load order
69
  */
70
+ add_action( 'bp_init', 'bp_register_post_types', 2 );
71
+ add_action( 'bp_init', 'bp_register_taxonomies', 2 );
72
  add_action( 'bp_init', 'bp_core_set_uri_globals', 2 );
 
 
73
  add_action( 'bp_init', 'bp_setup_globals', 4 );
74
  add_action( 'bp_init', 'bp_setup_canonical_stack', 5 );
75
  add_action( 'bp_init', 'bp_setup_nav', 6 );
79
  add_action( 'bp_init', 'bp_add_rewrite_rules', 30 );
80
  add_action( 'bp_init', 'bp_add_permastructs', 40 );
81
 
82
+ /**
83
+ * The bp_register_taxonomies hook - Attached to 'bp_init' @ priority 2 above.
84
+ */
85
+ add_action( 'bp_register_taxonomies', 'bp_register_member_types' );
86
+
87
  /**
88
  * The bp_template_redirect hook - Attached to 'template_redirect' above.
89
  *
114
 
115
  // Activation redirect.
116
  add_action( 'bp_activation', 'bp_add_activation_redirect' );
117
+
118
+ // Email unsubscribe.
119
+ add_action( 'bp_get_request_unsubscribe', 'bp_email_unsubscribe_handler' );
bp-core/bp-core-admin.php CHANGED
@@ -10,14 +10,11 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- require dirname( __FILE__ ) . '/classes/class-bp-admin.php';
14
-
15
  /**
16
  * Setup BuddyPress Admin.
17
  *
18
  * @since 1.6.0
19
  *
20
- * @uses BP_Admin
21
  */
22
  function bp_admin() {
23
  buddypress()->admin = new BP_Admin();
@@ -29,25 +26,33 @@ function bp_admin() {
29
  _n_noop( 'Security Release', 'Security Releases', 'buddypress' );
30
  _n_noop( 'Maintenance and Security Release', 'Maintenance and Security Releases', 'buddypress' );
31
 
32
- /* translators: 1: WordPress version number. */
33
- _n_noop( '<strong>Version %1$s</strong> addressed a security issue.',
34
- '<strong>Version %1$s</strong> addressed some security issues.',
35
- 'buddypress' );
36
-
37
- /* translators: 1: WordPress version number, 2: plural number of bugs. */
38
- _n_noop( '<strong>Version %1$s</strong> addressed %2$s bug.',
39
- '<strong>Version %1$s</strong> addressed %2$s bugs.',
40
- 'buddypress' );
41
-
42
- /* translators: 1: WordPress version number, 2: plural number of bugs. Singular security issue. */
43
- _n_noop( '<strong>Version %1$s</strong> addressed a security issue and fixed %2$s bug.',
44
- '<strong>Version %1$s</strong> addressed a security issue and fixed %2$s bugs.',
45
- 'buddypress' );
46
-
47
- /* translators: 1: WordPress version number, 2: plural number of bugs. More than one security issue. */
48
- _n_noop( '<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bug.',
49
- '<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bugs.',
50
- 'buddypress' );
 
 
 
 
 
 
 
 
51
 
52
  __( 'For more information, see <a href="%s">the release notes</a>.', 'buddypress' );
53
  }
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
13
  /**
14
  * Setup BuddyPress Admin.
15
  *
16
  * @since 1.6.0
17
  *
 
18
  */
19
  function bp_admin() {
20
  buddypress()->admin = new BP_Admin();
26
  _n_noop( 'Security Release', 'Security Releases', 'buddypress' );
27
  _n_noop( 'Maintenance and Security Release', 'Maintenance and Security Releases', 'buddypress' );
28
 
29
+ /* translators: 1: BuddyPress version number. */
30
+ _n_noop(
31
+ '<strong>Version %1$s</strong> addressed a security issue.',
32
+ '<strong>Version %1$s</strong> addressed some security issues.',
33
+ 'buddypress'
34
+ );
35
+
36
+ /* translators: 1: BuddyPress version number, 2: plural number of bugs. */
37
+ _n_noop(
38
+ '<strong>Version %1$s</strong> addressed %2$s bug.',
39
+ '<strong>Version %1$s</strong> addressed %2$s bugs.',
40
+ 'buddypress'
41
+ );
42
+
43
+ /* translators: 1: BuddyPress version number, 2: plural number of bugs. Singular security issue. */
44
+ _n_noop(
45
+ '<strong>Version %1$s</strong> addressed a security issue and fixed %2$s bug.',
46
+ '<strong>Version %1$s</strong> addressed a security issue and fixed %2$s bugs.',
47
+ 'buddypress'
48
+ );
49
+
50
+ /* translators: 1: BuddyPress version number, 2: plural number of bugs. More than one security issue. */
51
+ _n_noop(
52
+ '<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bug.',
53
+ '<strong>Version %1$s</strong> addressed some security issues and fixed %2$s bugs.',
54
+ 'buddypress'
55
+ );
56
 
57
  __( 'For more information, see <a href="%s">the release notes</a>.', 'buddypress' );
58
  }
bp-core/bp-core-adminbar.php CHANGED
@@ -55,17 +55,6 @@ add_action( 'admin_bar_menu', 'bp_admin_bar_my_account_root', 100 );
55
  * @since 1.2.0
56
  *
57
  * @global string $wp_version
58
- * @uses bp_get_option()
59
- * @uses is_user_logged_in()
60
- * @uses bp_use_wp_admin_bar()
61
- * @uses show_admin_bar()
62
- * @uses add_action() To hook 'bp_adminbar_logo' to 'bp_adminbar_logo'.
63
- * @uses add_action() To hook 'bp_adminbar_login_menu' to 'bp_adminbar_menus'.
64
- * @uses add_action() To hook 'bp_adminbar_account_menu' to 'bp_adminbar_menus'.
65
- * @uses add_action() To hook 'bp_adminbar_thisblog_menu' to 'bp_adminbar_menus'.
66
- * @uses add_action() To hook 'bp_adminbar_random_menu' to 'bp_adminbar_menus'.
67
- * @uses add_action() To hook 'bp_core_admin_bar' to 'wp_footer'.
68
- * @uses add_action() To hook 'bp_core_admin_bar' to 'admin_footer'.
69
  */
70
  function bp_core_load_admin_bar() {
71
 
55
  * @since 1.2.0
56
  *
57
  * @global string $wp_version
 
 
 
 
 
 
 
 
 
 
 
58
  */
59
  function bp_core_load_admin_bar() {
60
 
bp-core/bp-core-attachments.php CHANGED
@@ -52,6 +52,11 @@ function bp_attachments_uploads_dir_get( $data = '' ) {
52
  foreach ( $upload_data as $key => $value ) {
53
  if ( 'basedir' === $key || 'baseurl' === $key ) {
54
  $upload_data[ $key ] = trailingslashit( $value ) . $attachments_dir;
 
 
 
 
 
55
  } else {
56
  unset( $upload_data[ $key ] );
57
  }
@@ -507,7 +512,7 @@ function bp_attachments_delete_file( $args = array() ) {
507
  * @since 2.5.1
508
  *
509
  * @param bool $value Whether or not to delete the BuddyPress attachment.
510
- * @param array Array of arguments for the attachment deletion.
511
  */
512
  if ( ! apply_filters( 'bp_attachments_pre_delete_file', true, $args ) ) {
513
  return true;
@@ -944,7 +949,7 @@ function bp_attachments_get_template_part( $slug ) {
944
  * @since 2.4.0
945
  *
946
  * @param string $component The component to get the settings for ("xprofile" for user or "groups").
947
- * @return array The cover image settings.
948
  */
949
  function bp_attachments_get_cover_image_settings( $component = 'xprofile' ) {
950
  // Default parameters.
@@ -963,7 +968,7 @@ function bp_attachments_get_cover_image_settings( $component = 'xprofile' ) {
963
  * Eg: for the user's profile cover image use:
964
  * add_filter( 'bp_before_xprofile_cover_image_settings_parse_args', 'your_filter', 10, 1 );
965
  *
966
- * @since 2.4.0
967
  *
968
  * @param array $settings The cover image settings
969
  */
@@ -990,12 +995,12 @@ function bp_attachments_get_cover_image_settings( $component = 'xprofile' ) {
990
  }
991
 
992
  /**
993
- * Get cover image Width and Height
994
  *
995
  * @since 2.4.0
996
  *
997
  * @param string $component The BuddyPress component concerned ("xprofile" for user or "groups").
998
- * @return array An associative array containing the advised width and height for the cover image.
999
  */
1000
  function bp_attachments_get_cover_image_dimensions( $component = 'xprofile' ) {
1001
  // Let's prevent notices when setting the warning strings.
@@ -1033,7 +1038,7 @@ function bp_attachments_cover_image_is_edit() {
1033
  $retval = false;
1034
 
1035
  $current_component = bp_current_component();
1036
- if ( 'profile' === $current_component ) {
1037
  $current_component = 'xprofile';
1038
  }
1039
 
@@ -1180,7 +1185,7 @@ function bp_attachments_cover_image_generate_file( $args = array(), $cover_image
1180
  *
1181
  * @since 2.4.0
1182
  *
1183
- * @return string|null A json object containing success data if the upload succeeded
1184
  * error message otherwise.
1185
  */
1186
  function bp_attachments_cover_image_ajax_upload() {
@@ -1242,10 +1247,7 @@ function bp_attachments_cover_image_ajax_upload() {
1242
 
1243
  if ( ! bp_get_current_group_id() && ! empty( $bp_params['item_id'] ) ) {
1244
  $needs_reset = array( 'component' => 'groups', 'key' => 'current_group', 'value' => $bp->groups->current_group );
1245
- $bp->groups->current_group = groups_get_group( array(
1246
- 'group_id' => $bp_params['item_id'],
1247
- 'populate_extras' => false,
1248
- ) );
1249
  }
1250
 
1251
  // Other object's cover image.
@@ -1421,6 +1423,19 @@ function bp_attachments_cover_image_ajax_delete() {
1421
 
1422
  // Handle delete.
1423
  if ( bp_attachments_delete_file( array( 'item_id' => $cover_image_data['item_id'], 'object_dir' => $dir, 'type' => 'cover-image' ) ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
1424
 
1425
  // Defaults no cover image.
1426
  $response = array(
52
  foreach ( $upload_data as $key => $value ) {
53
  if ( 'basedir' === $key || 'baseurl' === $key ) {
54
  $upload_data[ $key ] = trailingslashit( $value ) . $attachments_dir;
55
+
56
+ // Fix for HTTPS.
57
+ if ( 'baseurl' === $key && is_ssl() ) {
58
+ $upload_data[ $key ] = str_replace( 'http://', 'https://', $upload_data[ $key ] );
59
+ }
60
  } else {
61
  unset( $upload_data[ $key ] );
62
  }
512
  * @since 2.5.1
513
  *
514
  * @param bool $value Whether or not to delete the BuddyPress attachment.
515
+ ` * @param array $args Array of arguments for the attachment deletion.
516
  */
517
  if ( ! apply_filters( 'bp_attachments_pre_delete_file', true, $args ) ) {
518
  return true;
949
  * @since 2.4.0
950
  *
951
  * @param string $component The component to get the settings for ("xprofile" for user or "groups").
952
+ * @return array|bool The cover image settings in array, false on failure.
953
  */
954
  function bp_attachments_get_cover_image_settings( $component = 'xprofile' ) {
955
  // Default parameters.
968
  * Eg: for the user's profile cover image use:
969
  * add_filter( 'bp_before_xprofile_cover_image_settings_parse_args', 'your_filter', 10, 1 );
970
  *
971
+ * @since 2.4.0
972
  *
973
  * @param array $settings The cover image settings
974
  */
995
  }
996
 
997
  /**
998
+ * Get cover image Width and Height.
999
  *
1000
  * @since 2.4.0
1001
  *
1002
  * @param string $component The BuddyPress component concerned ("xprofile" for user or "groups").
1003
+ * @return array|bool An associative array containing the advised width and height for the cover image. False if settings are empty.
1004
  */
1005
  function bp_attachments_get_cover_image_dimensions( $component = 'xprofile' ) {
1006
  // Let's prevent notices when setting the warning strings.
1038
  $retval = false;
1039
 
1040
  $current_component = bp_current_component();
1041
+ if ( bp_is_active( 'xprofile' ) && bp_is_current_component( 'xprofile' ) ) {
1042
  $current_component = 'xprofile';
1043
  }
1044
 
1185
  *
1186
  * @since 2.4.0
1187
  *
1188
+ * @return string|null A json object containing success data if the upload succeeded,
1189
  * error message otherwise.
1190
  */
1191
  function bp_attachments_cover_image_ajax_upload() {
1247
 
1248
  if ( ! bp_get_current_group_id() && ! empty( $bp_params['item_id'] ) ) {
1249
  $needs_reset = array( 'component' => 'groups', 'key' => 'current_group', 'value' => $bp->groups->current_group );
1250
+ $bp->groups->current_group = groups_get_group( $bp_params['item_id'] );
 
 
 
1251
  }
1252
 
1253
  // Other object's cover image.
1423
 
1424
  // Handle delete.
1425
  if ( bp_attachments_delete_file( array( 'item_id' => $cover_image_data['item_id'], 'object_dir' => $dir, 'type' => 'cover-image' ) ) ) {
1426
+ /**
1427
+ * Fires if the cover image was successfully deleted.
1428
+ *
1429
+ * The dynamic portion of the hook will be xprofile in case of a user's
1430
+ * cover image, groups in case of a group's cover image. For instance:
1431
+ * Use add_action( 'xprofile_cover_image_deleted' ) to run your specific
1432
+ * code once the user has deleted his cover image.
1433
+ *
1434
+ * @since 2.8.0
1435
+ *
1436
+ * @param int $item_id Inform about the item id the cover image was deleted for.
1437
+ */
1438
+ do_action( "{$component}_cover_image_deleted", (int) $cover_image_data['item_id'] );
1439
 
1440
  // Defaults no cover image.
1441
  $response = array(
bp-core/bp-core-avatars.php CHANGED
@@ -175,7 +175,7 @@ add_action( 'bp_setup_globals', 'bp_core_set_avatar_globals' );
175
  * local avatar. In some cases, this may be undesirable, in which
176
  * case 'no_grav' should be set to true. To disable Gravatar
177
  * fallbacks globally, see the 'bp_core_fetch_avatar_no_grav' filter.
178
- * Default: false.
179
  * @type bool $html Whether to return an <img> HTML element, vs a raw URL
180
  * to an avatar. If false, <img>-specific arguments (like 'css_id')
181
  * will be ignored. Default: true.
@@ -211,7 +211,7 @@ function bp_core_fetch_avatar( $args = '' ) {
211
  'css_id' => false,
212
  'alt' => '',
213
  'email' => false,
214
- 'no_grav' => false,
215
  'html' => true,
216
  'title' => '',
217
  'extra_attr' => '',
@@ -313,7 +313,7 @@ function bp_core_fetch_avatar( $args = '' ) {
313
  break;
314
 
315
  case 'group' :
316
- $item_name = bp_get_group_name( groups_get_group( array( 'group_id' => $params['item_id'] ) ) );
317
  break;
318
 
319
  case 'user' :
@@ -542,9 +542,9 @@ function bp_core_fetch_avatar( $args = '' ) {
542
  * @param string $value Subdirectory where the requested avatar should be found.
543
  * @param string $html_css_id ID attribute for avatar.
544
  * @param string $html_width Width attribute for avatar.
545
- * @param string $html_height Height attribtue for avatar.
546
  * @param string $avatar_folder_url Avatar URL path.
547
- * @param string $avatar_folder_dir Avatar dir path.
548
  */
549
  return apply_filters( 'bp_core_fetch_avatar', '<img src="' . $avatar_url . '"' . $html_class . $html_css_id . $html_width . $html_height . $html_alt . $html_title . $extra_attr . ' />', $params, $params['item_id'], $params['avatar_dir'], $html_css_id, $html_width, $html_height, $avatar_folder_url, $avatar_folder_dir );
550
 
@@ -564,6 +564,11 @@ function bp_core_fetch_avatar( $args = '' ) {
564
  }
565
  }
566
 
 
 
 
 
 
567
  /**
568
  * Filters whether or not to skip Gravatar check.
569
  *
@@ -636,6 +641,17 @@ function bp_core_fetch_avatar( $args = '' ) {
636
  if ( ! empty( $params['rating'] ) ) {
637
  $url_args['r'] = strtolower( $params['rating'] );
638
  }
 
 
 
 
 
 
 
 
 
 
 
639
  // Only set default image if 'Gravatar Logo' is not requested.
640
  if ( 'gravatar_default' !== $default_grav ) {
641
  $url_args['d'] = $default_grav;
@@ -660,7 +676,7 @@ function bp_core_fetch_avatar( $args = '' ) {
660
  * @param string $value Default avatar for non-gravatar requests.
661
  * @param array $params Array of parameters for the avatar request.
662
  */
663
- $gravatar = apply_filters( 'bp_core_default_avatar_' . $params['object'], bp_core_avatar_default( 'local' ), $params );
664
  }
665
 
666
  if ( true === $params['html'] ) {
@@ -710,7 +726,7 @@ function bp_core_delete_existing_avatar( $args = '' ) {
710
  *
711
  * @since 2.5.1
712
  *
713
- * @param bool $value Whether or not to delete the avatar.
714
  * @param array $args {
715
  * Array of function parameters.
716
  *
@@ -789,7 +805,7 @@ function bp_core_delete_existing_avatar( $args = '' ) {
789
  *
790
  * @since 2.3.0
791
  *
792
- * @return string|null A json object containing success data if the avatar was deleted
793
  * error message otherwise.
794
  */
795
  function bp_avatar_ajax_delete() {
@@ -932,8 +948,8 @@ function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
932
  *
933
  * @since 2.3.0
934
  *
935
- * @return string|null A json object containing success data if the upload succeeded
936
- * error message otherwise.
937
  */
938
  function bp_avatar_ajax_upload() {
939
  // Bail if not a POST action.
@@ -943,7 +959,7 @@ function bp_avatar_ajax_upload() {
943
 
944
  /**
945
  * Sending the json response will be different if
946
- * the current Plupload runtime is html4
947
  */
948
  $is_html4 = false;
949
  if ( ! empty( $_POST['html4' ] ) ) {
@@ -989,10 +1005,7 @@ function bp_avatar_ajax_upload() {
989
 
990
  if ( ! bp_get_current_group_id() && ! empty( $bp_params['item_id'] ) ) {
991
  $needs_reset = array( 'component' => 'groups', 'key' => 'current_group', 'value' => $bp->groups->current_group );
992
- $bp->groups->current_group = groups_get_group( array(
993
- 'group_id' => $bp_params['item_id'],
994
- 'populate_extras' => false,
995
- ) );
996
  }
997
  } else {
998
  /**
@@ -1038,8 +1051,9 @@ function bp_avatar_ajax_upload() {
1038
  // Remove template message.
1039
  $bp->template_message = false;
1040
  $bp->template_message_type = false;
1041
- @setcookie( 'bp-message', false, time() - 1000, COOKIEPATH );
1042
- @setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH );
 
1043
  }
1044
 
1045
  if ( empty( $avatar ) ) {
@@ -1080,15 +1094,15 @@ function bp_avatar_ajax_upload() {
1080
  }
1081
  add_action( 'wp_ajax_bp_avatar_upload', 'bp_avatar_ajax_upload' );
1082
 
1083
- /**
1084
- * Handle avatar webcam capture.
1085
- *
1086
- * @since 2.3.0
1087
- *
1088
- * @param string $data Base64 encoded image.
1089
- * @param int $item_id Item to associate.
1090
- * @return bool True on success, false on failure.
1091
- */
1092
  function bp_avatar_handle_capture( $data = '', $item_id = 0 ) {
1093
  if ( empty( $data ) || empty( $item_id ) ) {
1094
  return false;
@@ -1154,16 +1168,6 @@ function bp_avatar_handle_capture( $data = '', $item_id = 0 ) {
1154
  /**
1155
  * Crop an uploaded avatar.
1156
  *
1157
- * $args has the following parameters:
1158
- * object - What component the avatar is for, e.g. "user"
1159
- * avatar_dir The absolute path to the avatar
1160
- * item_id - Item ID
1161
- * original_file - The absolute path to the original avatar file
1162
- * crop_w - Crop width
1163
- * crop_h - Crop height
1164
- * crop_x - The horizontal starting point of the crop
1165
- * crop_y - The vertical starting point of the crop
1166
- *
1167
  * @since 1.1.0
1168
  *
1169
  * @param array|string $args {
@@ -1229,8 +1233,8 @@ function bp_core_avatar_handle_crop( $args = '' ) {
1229
  *
1230
  * @since 2.3.0
1231
  *
1232
- * @return string|null A json object containing success data if the crop/capture succeeded
1233
- * error message otherwise.
1234
  */
1235
  function bp_avatar_ajax_set() {
1236
  // Bail if not a POST action.
@@ -1289,11 +1293,13 @@ function bp_avatar_ajax_set() {
1289
  * @since 2.3.4 Add two new parameters to inform about the user id and
1290
  * about the way the avatar was set (eg: 'crop' or 'camera')
1291
  * Move the action at the right place, once the avatar is set
 
1292
  *
1293
- * @param string $item_id Inform about the user id the avatar was set for
1294
- * @param string $type Inform about the way the avatar was set ('camera')
 
1295
  */
1296
- do_action( 'xprofile_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'] );
1297
 
1298
  wp_send_json_success( $return );
1299
  }
@@ -1338,18 +1344,11 @@ function bp_avatar_ajax_set() {
1338
  );
1339
 
1340
  if ( 'user' === $avatar_data['object'] ) {
1341
- /**
1342
- * Fires if the new avatar was successfully cropped.
1343
- *
1344
- * @since 1.1.0 Used to inform the avatar was successfully cropped
1345
- * @since 2.3.4 Add two new parameters to inform about the user id and
1346
- * about the way the avatar was set (eg: 'crop' or 'camera')
1347
- * Move the action at the right place, once the avatar is set
1348
- *
1349
- * @param string $item_id Inform about the user id the avatar was set for
1350
- * @param string $type Inform about the way the avatar was set ('crop')
1351
- */
1352
- do_action( 'xprofile_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'] );
1353
  }
1354
 
1355
  wp_send_json_success( $return );
@@ -1380,9 +1379,10 @@ add_action( 'wp_ajax_bp_avatar_set', 'bp_avatar_ajax_set' );
1380
  function bp_core_fetch_avatar_filter( $avatar, $user, $size, $default, $alt = '', $args = array() ) {
1381
  global $pagenow;
1382
 
1383
- // Do not filter if inside WordPress options page.
1384
- if ( 'options-discussion.php' == $pagenow )
1385
  return $avatar;
 
1386
 
1387
  // If passed an object, assume $user->user_id.
1388
  if ( is_object( $user ) ) {
@@ -1494,6 +1494,8 @@ function bp_core_check_avatar_size( $file ) {
1494
  * Get allowed avatar types.
1495
  *
1496
  * @since 2.3.0
 
 
1497
  */
1498
  function bp_core_get_allowed_avatar_types() {
1499
  $allowed_types = bp_attachments_get_allowed_types( 'avatar' );
@@ -1520,6 +1522,8 @@ function bp_core_get_allowed_avatar_types() {
1520
  * Get allowed avatar mime types.
1521
  *
1522
  * @since 2.3.0
 
 
1523
  */
1524
  function bp_core_get_allowed_avatar_mimes() {
1525
  $allowed_types = bp_core_get_allowed_avatar_types();
@@ -1623,8 +1627,6 @@ function bp_core_get_upload_dir( $type = 'upload_path' ) {
1623
  *
1624
  * @since 1.2.0
1625
  *
1626
- * @uses bp_core_get_upload_dir() To get upload directory info.
1627
- *
1628
  * @return string Absolute path to WP upload directory.
1629
  */
1630
  function bp_core_avatar_upload_path() {
@@ -1644,8 +1646,6 @@ function bp_core_avatar_upload_path() {
1644
  *
1645
  * @since 1.2.0
1646
  *
1647
- * @uses bp_core_get_upload_dir() To get upload directory info.
1648
- *
1649
  * @return string Full URL to current upload location.
1650
  */
1651
  function bp_core_avatar_url() {
@@ -1674,7 +1674,7 @@ function bp_get_user_has_avatar( $user_id = 0 ) {
1674
  $user_id = bp_displayed_user_id();
1675
 
1676
  $retval = false;
1677
- if ( bp_core_fetch_avatar( array( 'item_id' => $user_id, 'no_grav' => true, 'html' => false ) ) != bp_core_avatar_default( 'local' ) )
1678
  $retval = true;
1679
 
1680
  /**
@@ -1833,34 +1833,53 @@ function bp_core_avatar_original_max_filesize() {
1833
  * Get the URL of the 'full' default avatar.
1834
  *
1835
  * @since 1.5.0
 
1836
  *
1837
- * @param string $type 'local' if the fallback should be the locally-hosted version
1838
- * of the mystery-person, 'gravatar' if the fallback should be
1839
- * Gravatar's version. Default: 'gravatar'.
 
1840
  * @return string The URL of the default avatar.
1841
  */
1842
- function bp_core_avatar_default( $type = 'gravatar' ) {
1843
  // Local override.
1844
  if ( defined( 'BP_AVATAR_DEFAULT' ) ) {
1845
  $avatar = BP_AVATAR_DEFAULT;
1846
 
1847
  // Use the local default image.
1848
  } elseif ( 'local' === $type ) {
1849
- $avatar = buddypress()->plugin_url . 'bp-core/images/mystery-man.jpg';
 
 
 
 
 
 
 
 
 
1850
 
1851
  // Use Gravatar's mystery person as fallback.
1852
  } else {
1853
- $avatar = '//www.gravatar.com/avatar/00000000000000000000000000000000?d=mm&amp;s=' . bp_core_avatar_full_width();
 
 
 
 
 
 
1854
  }
1855
 
1856
  /**
1857
  * Filters the URL of the 'full' default avatar.
1858
  *
1859
  * @since 1.5.0
 
1860
  *
1861
  * @param string $avatar URL of the default avatar.
 
1862
  */
1863
- return apply_filters( 'bp_core_avatar_default', $avatar );
1864
  }
1865
 
1866
  /**
@@ -1870,13 +1889,15 @@ function bp_core_avatar_default( $type = 'gravatar' ) {
1870
  * defined.
1871
  *
1872
  * @since 1.5.0
 
1873
  *
1874
- * @param string $type 'local' if the fallback should be the locally-hosted version
1875
- * of the mystery-person, 'gravatar' if the fallback should be
1876
- * Gravatar's version. Default: 'gravatar'.
 
1877
  * @return string The URL of the default avatar thumb.
1878
  */
1879
- function bp_core_avatar_default_thumb( $type = 'gravatar' ) {
1880
  // Local override.
1881
  if ( defined( 'BP_AVATAR_DEFAULT_THUMB' ) ) {
1882
  $avatar = BP_AVATAR_DEFAULT_THUMB;
@@ -1894,10 +1915,12 @@ function bp_core_avatar_default_thumb( $type = 'gravatar' ) {
1894
  * Filters the URL of the 'thumb' default avatar.
1895
  *
1896
  * @since 1.5.0
 
1897
  *
1898
  * @param string $avatar URL of the default avatar.
 
1899
  */
1900
- return apply_filters( 'bp_core_avatar_thumb', $avatar );
1901
  }
1902
 
1903
  /**
@@ -1907,13 +1930,7 @@ function bp_core_avatar_default_thumb( $type = 'gravatar' ) {
1907
  * parameter of the WordPress main query to this posted var. To avoid
1908
  * notices, we need to make sure this 'week' query var is reset to 0.
1909
  *
1910
- * @since 2.2.0
1911
- *
1912
- * @uses bp_is_group_create()
1913
- * @uses bp_is_group_admin_page()
1914
- * @uses bp_is_group_admin_screen() to check for a group admin screen
1915
- * @uses bp_action_variable() to check for the group's avatar creation step
1916
- * @uses bp_is_user_change_avatar() to check for the user's change profile screen
1917
  *
1918
  * @param WP_Query|null $posts_query The main query object.
1919
  */
@@ -1947,7 +1964,7 @@ add_action( 'bp_parse_query', 'bp_core_avatar_reset_query', 10, 1 );
1947
  /**
1948
  * Checks whether Avatar UI should be loaded.
1949
  *
1950
- * @since 2.3.0
1951
  *
1952
  * @return bool True if Avatar UI should load, false otherwise.
1953
  */
@@ -1979,7 +1996,7 @@ function bp_avatar_is_front_edit() {
1979
  * - Load the avatar UI for a component that is !groups or !user (return true regarding your conditions)
1980
  * - Completely disable the avatar UI introduced in 2.3 (eg: __return_false())
1981
  *
1982
- * @since 2.3.0
1983
  *
1984
  * @param bool $retval Whether or not to load the Avatar UI.
1985
  */
@@ -1989,7 +2006,7 @@ function bp_avatar_is_front_edit() {
1989
  /**
1990
  * Checks whether the Webcam Avatar UI part should be loaded.
1991
  *
1992
- * @since 2.3.0
1993
  *
1994
  * @global $is_safari
1995
  * @global $is_IE
@@ -2010,7 +2027,7 @@ function bp_avatar_use_webcam() {
2010
  /**
2011
  * Bail when the browser does not support getUserMedia.
2012
  *
2013
- * @see http://caniuse.com/#feat=stream
2014
  */
2015
  if ( $is_safari || $is_IE || ( $is_chrome && ! is_ssl() ) ) {
2016
  return false;
@@ -2030,7 +2047,7 @@ function bp_avatar_use_webcam() {
2030
  /**
2031
  * Template function to load the Avatar UI javascript templates.
2032
  *
2033
- * @since 2.3.0
2034
  */
2035
  function bp_avatar_get_templates() {
2036
  if ( ! bp_avatar_is_front_edit() ) {
@@ -2046,7 +2063,7 @@ function bp_avatar_get_templates() {
2046
  * If the "avatar templates" are not including the new template tag, this will
2047
  * help users to get the avatar UI.
2048
  *
2049
- * @since 2.3.0
2050
  */
2051
  function bp_avatar_template_check() {
2052
  if ( ! bp_avatar_is_front_edit() ) {
175
  * local avatar. In some cases, this may be undesirable, in which
176
  * case 'no_grav' should be set to true. To disable Gravatar
177
  * fallbacks globally, see the 'bp_core_fetch_avatar_no_grav' filter.
178
+ * Default: true for groups, otherwise false.
179
  * @type bool $html Whether to return an <img> HTML element, vs a raw URL
180
  * to an avatar. If false, <img>-specific arguments (like 'css_id')
181
  * will be ignored. Default: true.
211
  'css_id' => false,
212
  'alt' => '',
213
  'email' => false,
214
+ 'no_grav' => null,
215
  'html' => true,
216
  'title' => '',
217
  'extra_attr' => '',
313
  break;
314
 
315
  case 'group' :
316
+ $item_name = bp_get_group_name( groups_get_group( $params['item_id'] ) );
317
  break;
318
 
319
  case 'user' :
542
  * @param string $value Subdirectory where the requested avatar should be found.
543
  * @param string $html_css_id ID attribute for avatar.
544
  * @param string $html_width Width attribute for avatar.
545
+ * @param string $html_height Height attribute for avatar.
546
  * @param string $avatar_folder_url Avatar URL path.
547
+ * @param string $avatar_folder_dir Avatar DIR path.
548
  */
549
  return apply_filters( 'bp_core_fetch_avatar', '<img src="' . $avatar_url . '"' . $html_class . $html_css_id . $html_width . $html_height . $html_alt . $html_title . $extra_attr . ' />', $params, $params['item_id'], $params['avatar_dir'], $html_css_id, $html_width, $html_height, $avatar_folder_url, $avatar_folder_dir );
550
 
564
  }
565
  }
566
 
567
+ // By default, Gravatar is not pinged for groups.
568
+ if ( null === $params['no_grav'] ) {
569
+ $params['no_grav'] = 'group' === $params['object'];
570
+ }
571
+
572
  /**
573
  * Filters whether or not to skip Gravatar check.
574
  *
641
  if ( ! empty( $params['rating'] ) ) {
642
  $url_args['r'] = strtolower( $params['rating'] );
643
  }
644
+
645
+ /**
646
+ * Filters the Gravatar "d" parameter.
647
+ *
648
+ * @since 2.6.0
649
+ *
650
+ * @param string $default_grav The avatar default.
651
+ * @param array $params The avatar's data.
652
+ */
653
+ $default_grav = apply_filters( 'bp_core_avatar_default', $default_grav, $params );
654
+
655
  // Only set default image if 'Gravatar Logo' is not requested.
656
  if ( 'gravatar_default' !== $default_grav ) {
657
  $url_args['d'] = $default_grav;
676
  * @param string $value Default avatar for non-gravatar requests.
677
  * @param array $params Array of parameters for the avatar request.
678
  */
679
+ $gravatar = apply_filters( 'bp_core_default_avatar_' . $params['object'], bp_core_avatar_default( 'local', $params ), $params );
680
  }
681
 
682
  if ( true === $params['html'] ) {
726
  *
727
  * @since 2.5.1
728
  *
729
+ * @param bool $value Whether or not to delete the avatar.
730
  * @param array $args {
731
  * Array of function parameters.
732
  *
805
  *
806
  * @since 2.3.0
807
  *
808
+ * @return string|null A JSON object containing success data if the avatar was deleted,
809
  * error message otherwise.
810
  */
811
  function bp_avatar_ajax_delete() {
948
  *
949
  * @since 2.3.0
950
  *
951
+ * @return string|null A JSON object containing success data if the upload succeeded
952
+ * error message otherwise.
953
  */
954
  function bp_avatar_ajax_upload() {
955
  // Bail if not a POST action.
959
 
960
  /**
961
  * Sending the json response will be different if
962
+ * the current Plupload runtime is html4.
963
  */
964
  $is_html4 = false;
965
  if ( ! empty( $_POST['html4' ] ) ) {
1005
 
1006
  if ( ! bp_get_current_group_id() && ! empty( $bp_params['item_id'] ) ) {
1007
  $needs_reset = array( 'component' => 'groups', 'key' => 'current_group', 'value' => $bp->groups->current_group );
1008
+ $bp->groups->current_group = groups_get_group( $bp_params['item_id'] );
 
 
 
1009
  }
1010
  } else {
1011
  /**
1051
  // Remove template message.
1052
  $bp->template_message = false;
1053
  $bp->template_message_type = false;
1054
+
1055
+ @setcookie( 'bp-message', false, time() - 1000, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
1056
+ @setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
1057
  }
1058
 
1059
  if ( empty( $avatar ) ) {
1094
  }
1095
  add_action( 'wp_ajax_bp_avatar_upload', 'bp_avatar_ajax_upload' );
1096
 
1097
+ /**
1098
+ * Handle avatar webcam capture.
1099
+ *
1100
+ * @since 2.3.0
1101
+ *
1102
+ * @param string $data Base64 encoded image.
1103
+ * @param int $item_id Item to associate.
1104
+ * @return bool True on success, false on failure.
1105
+ */
1106
  function bp_avatar_handle_capture( $data = '', $item_id = 0 ) {
1107
  if ( empty( $data ) || empty( $item_id ) ) {
1108
  return false;
1168
  /**
1169
  * Crop an uploaded avatar.
1170
  *
 
 
 
 
 
 
 
 
 
 
1171
  * @since 1.1.0
1172
  *
1173
  * @param array|string $args {
1233
  *
1234
  * @since 2.3.0
1235
  *
1236
+ * @return string|null A JSON object containing success data if the crop/capture succeeded
1237
+ * error message otherwise.
1238
  */
1239
  function bp_avatar_ajax_set() {
1240
  // Bail if not a POST action.
1293
  * @since 2.3.4 Add two new parameters to inform about the user id and
1294
  * about the way the avatar was set (eg: 'crop' or 'camera')
1295
  * Move the action at the right place, once the avatar is set
1296
+ * @since 2.8.0 Added the `$avatar_data` parameter.
1297
  *
1298
+ * @param string $item_id Inform about the user id the avatar was set for.
1299
+ * @param string $type Inform about the way the avatar was set ('camera').
1300
+ * @param array $avatar_data Array of parameters passed to the avatar handler.
1301
  */
1302
+ do_action( 'xprofile_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $avatar_data );
1303
 
1304
  wp_send_json_success( $return );
1305
  }
1344
  );
1345
 
1346
  if ( 'user' === $avatar_data['object'] ) {
1347
+ /** This action is documented in bp-core/bp-core-avatars.php */
1348
+ do_action( 'xprofile_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $r );
1349
+ } elseif ( 'group' === $avatar_data['object'] ) {
1350
+ /** This action is documented in bp-groups/bp-groups-screens.php */
1351
+ do_action( 'groups_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $r );
 
 
 
 
 
 
 
1352
  }
1353
 
1354
  wp_send_json_success( $return );
1379
  function bp_core_fetch_avatar_filter( $avatar, $user, $size, $default, $alt = '', $args = array() ) {
1380
  global $pagenow;
1381
 
1382
+ // Don't filter if inside WordPress options page and force_default is true.
1383
+ if ( 'options-discussion.php' === $pagenow && true === $args['force_default'] ) {
1384
  return $avatar;
1385
+ }
1386
 
1387
  // If passed an object, assume $user->user_id.
1388
  if ( is_object( $user ) ) {
1494
  * Get allowed avatar types.
1495
  *
1496
  * @since 2.3.0
1497
+ *
1498
+ * @return array
1499
  */
1500
  function bp_core_get_allowed_avatar_types() {
1501
  $allowed_types = bp_attachments_get_allowed_types( 'avatar' );
1522
  * Get allowed avatar mime types.
1523
  *
1524
  * @since 2.3.0
1525
+ *
1526
+ * @return array
1527
  */
1528
  function bp_core_get_allowed_avatar_mimes() {
1529
  $allowed_types = bp_core_get_allowed_avatar_types();
1627
  *
1628
  * @since 1.2.0
1629
  *
 
 
1630
  * @return string Absolute path to WP upload directory.
1631
  */
1632
  function bp_core_avatar_upload_path() {
1646
  *
1647
  * @since 1.2.0
1648
  *
 
 
1649
  * @return string Full URL to current upload location.
1650
  */
1651
  function bp_core_avatar_url() {
1674
  $user_id = bp_displayed_user_id();
1675
 
1676
  $retval = false;
1677
+ if ( bp_core_fetch_avatar( array( 'item_id' => $user_id, 'no_grav' => true, 'html' => false, 'type' => 'full' ) ) != bp_core_avatar_default( 'local' ) )
1678
  $retval = true;
1679
 
1680
  /**
1833
  * Get the URL of the 'full' default avatar.
1834
  *
1835
  * @since 1.5.0
1836
+ * @since 2.6.0 Introduced `$params` and `$object_type` parameters.
1837
  *
1838
+ * @param string $type 'local' if the fallback should be the locally-hosted version
1839
+ * of the mystery person, 'gravatar' if the fallback should be
1840
+ * Gravatar's version. Default: 'gravatar'.
1841
+ * @param array $params Parameters passed to bp_core_fetch_avatar().
1842
  * @return string The URL of the default avatar.
1843
  */
1844
+ function bp_core_avatar_default( $type = 'gravatar', $params = array() ) {
1845
  // Local override.
1846
  if ( defined( 'BP_AVATAR_DEFAULT' ) ) {
1847
  $avatar = BP_AVATAR_DEFAULT;
1848
 
1849
  // Use the local default image.
1850
  } elseif ( 'local' === $type ) {
1851
+ $size = '';
1852
+ if (
1853
+ ( isset( $params['type'] ) && 'thumb' === $params['type'] && bp_core_avatar_thumb_width() <= 50 ) ||
1854
+ ( isset( $params['width'] ) && $params['width'] <= 50 )
1855
+ ) {
1856
+
1857
+ $size = '-50';
1858
+ }
1859
+
1860
+ $avatar = buddypress()->plugin_url . "bp-core/images/mystery-man{$size}.jpg";
1861
 
1862
  // Use Gravatar's mystery person as fallback.
1863
  } else {
1864
+ $size = '';
1865
+ if ( isset( $params['type'] ) && 'thumb' === $params['type'] ) {
1866
+ $size = bp_core_avatar_thumb_width();
1867
+ } else {
1868
+ $size = bp_core_avatar_full_width();
1869
+ }
1870
+ $avatar = '//www.gravatar.com/avatar/00000000000000000000000000000000?d=mm&amp;s=' . $size;
1871
  }
1872
 
1873
  /**
1874
  * Filters the URL of the 'full' default avatar.
1875
  *
1876
  * @since 1.5.0
1877
+ * @since 2.6.0 Added `$params`.
1878
  *
1879
  * @param string $avatar URL of the default avatar.
1880
+ * @param array $params Params provided to bp_core_fetch_avatar().
1881
  */
1882
+ return apply_filters( 'bp_core_avatar_default', $avatar, $params );
1883
  }
1884
 
1885
  /**
1889
  * defined.
1890
  *
1891
  * @since 1.5.0
1892
+ * @since 2.6.0 Introduced `$object_type` parameter.
1893
  *
1894
+ * @param string $type 'local' if the fallback should be the locally-hosted version
1895
+ * of the mystery person, 'gravatar' if the fallback should be
1896
+ * Gravatar's version. Default: 'gravatar'.
1897
+ * @param array $params Parameters passed to bp_core_fetch_avatar().
1898
  * @return string The URL of the default avatar thumb.
1899
  */
1900
+ function bp_core_avatar_default_thumb( $type = 'gravatar', $params = array() ) {
1901
  // Local override.
1902
  if ( defined( 'BP_AVATAR_DEFAULT_THUMB' ) ) {
1903
  $avatar = BP_AVATAR_DEFAULT_THUMB;
1915
  * Filters the URL of the 'thumb' default avatar.
1916
  *
1917
  * @since 1.5.0
1918
+ * @since 2.6.0 Added `$params`.
1919
  *
1920
  * @param string $avatar URL of the default avatar.
1921
+ * @param string $params Params provided to bp_core_fetch_avatar().
1922
  */
1923
+ return apply_filters( 'bp_core_avatar_thumb', $avatar, $params );
1924
  }
1925
 
1926
  /**
1930
  * parameter of the WordPress main query to this posted var. To avoid
1931
  * notices, we need to make sure this 'week' query var is reset to 0.
1932
  *
1933
+ * @since 2.2.0
 
 
 
 
 
 
1934
  *
1935
  * @param WP_Query|null $posts_query The main query object.
1936
  */
1964
  /**
1965
  * Checks whether Avatar UI should be loaded.
1966
  *
1967
+ * @since 2.3.0
1968
  *
1969
  * @return bool True if Avatar UI should load, false otherwise.
1970
  */
1996
  * - Load the avatar UI for a component that is !groups or !user (return true regarding your conditions)
1997
  * - Completely disable the avatar UI introduced in 2.3 (eg: __return_false())
1998
  *
1999
+ * @since 2.3.0
2000
  *
2001
  * @param bool $retval Whether or not to load the Avatar UI.
2002
  */
2006
  /**
2007
  * Checks whether the Webcam Avatar UI part should be loaded.
2008
  *
2009
+ * @since 2.3.0
2010
  *
2011
  * @global $is_safari
2012
  * @global $is_IE
2027
  /**
2028
  * Bail when the browser does not support getUserMedia.
2029
  *
2030
+ * @see http://caniuse.com/#feat=stream
2031
  */
2032
  if ( $is_safari || $is_IE || ( $is_chrome && ! is_ssl() ) ) {
2033
  return false;
2047
  /**
2048
  * Template function to load the Avatar UI javascript templates.
2049
  *
2050
+ * @since 2.3.0
2051
  */
2052
  function bp_avatar_get_templates() {
2053
  if ( ! bp_avatar_is_front_edit() ) {
2063
  * If the "avatar templates" are not including the new template tag, this will
2064
  * help users to get the avatar UI.
2065
  *
2066
+ * @since 2.3.0
2067
  */
2068
  function bp_avatar_template_check() {
2069
  if ( ! bp_avatar_is_front_edit() ) {
bp-core/bp-core-buddybar.php CHANGED
@@ -13,9 +13,10 @@
13
  defined( 'ABSPATH' ) || exit;
14
 
15
  /**
16
- * Add an item to the main BuddyPress navigation array.
17
  *
18
  * @since 1.1.0
 
19
  *
20
  * @param array|string $args {
21
  * Array describing the new nav item.
@@ -32,9 +33,13 @@ defined( 'ABSPATH' ) || exit;
32
  * @type bool|string $default_subnav_slug Optional. The slug of the default subnav item to select when the nav
33
  * item is clicked.
34
  * }
 
35
  * @return bool|null Returns false on failure.
36
  */
37
- function bp_core_new_nav_item( $args = '' ) {
 
 
 
38
 
39
  $defaults = array(
40
  'name' => false, // Display name for the nav item.
@@ -49,18 +54,19 @@ function bp_core_new_nav_item( $args = '' ) {
49
 
50
  $r = wp_parse_args( $args, $defaults );
51
 
52
- // First, add the nav item link to the bp_nav array.
53
- $created = bp_core_create_nav_link( $r );
54
 
55
- // To mimic the existing behavior, if bp_core_create_nav_link()
56
- // returns false, we make an early exit and don't attempt to register
57
- // the screen function.
58
- if ( false === $created ) {
 
59
  return false;
60
  }
61
 
62
  // Then, hook the screen function for the added nav item.
63
- $hooked = bp_core_register_nav_screen_function( $r );
64
  if ( false === $hooked ){
65
  return false;
66
  }
@@ -81,9 +87,10 @@ function bp_core_new_nav_item( $args = '' ) {
81
  }
82
 
83
  /**
84
- * Add a link to the main BuddyPress navigation array.
85
  *
86
  * @since 2.4.0
 
87
  *
88
  * @param array|string $args {
89
  * Array describing the new nav item.
@@ -100,9 +107,10 @@ function bp_core_new_nav_item( $args = '' ) {
100
  * @type bool|string $default_subnav_slug Optional. The slug of the default subnav item to select when the nav
101
  * item is clicked.
102
  * }
103
- * @return bool|null Returns false on failure.
 
104
  */
105
- function bp_core_create_nav_link( $args = '' ) {
106
  $bp = buddypress();
107
 
108
  $defaults = array(
@@ -132,7 +140,7 @@ function bp_core_create_nav_link( $args = '' ) {
132
  $r['item_css_id'] = $r['slug'];
133
  }
134
 
135
- $bp->bp_nav[$r['slug']] = array(
136
  'name' => $r['name'],
137
  'slug' => $r['slug'],
138
  'link' => trailingslashit( bp_loggedin_user_domain() . $r['slug'] ),
@@ -143,16 +151,23 @@ function bp_core_create_nav_link( $args = '' ) {
143
  'default_subnav_slug' => $r['default_subnav_slug']
144
  );
145
 
 
 
 
146
  /**
147
- * Fires after a link is added to the main BuddyPress navigation array.
148
  *
149
  * @since 2.4.0
 
150
  *
151
- * @param array $r Parsed arguments for the nav item.
152
- * @param array $args Originally passed in arguments for the nav item.
153
- * @param array $defaults Default arguments for a nav item.
 
154
  */
155
- do_action( 'bp_core_create_nav_link', $r, $args, $defaults );
 
 
156
  }
157
 
158
  /**
@@ -199,9 +214,9 @@ function bp_core_register_nav_screen_function( $args = '' ) {
199
  }
200
 
201
  /**
202
- * If this is for site admins only and the user is not one,
203
- * don't register this screen function.
204
- */
205
  if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
206
  return false;
207
  }
@@ -290,20 +305,33 @@ function bp_core_new_nav_default( $args = '' ) {
290
 
291
  $r = wp_parse_args( $args, $defaults );
292
 
293
- if ( $function = $bp->bp_nav[$r['parent_slug']]['screen_function'] ) {
 
 
 
 
 
 
 
 
 
294
  // Remove our screen hook if screen function is callable.
295
- if ( is_callable( $function ) ) {
296
- remove_action( 'bp_screens', $function, 3 );
297
  }
298
  }
299
 
300
- $bp->bp_nav[$r['parent_slug']]['screen_function'] = &$r['screen_function'];
 
 
 
 
301
 
302
- if ( bp_is_current_component( $r['parent_slug'] ) ) {
303
 
304
  // The only way to tell whether to set the subnav is to peek at the unfiltered_uri
305
  // Find the component.
306
- $component_uri_key = array_search( $r['parent_slug'], $bp->unfiltered_uri );
307
 
308
  if ( false !== $component_uri_key ) {
309
  if ( ! empty( $bp->unfiltered_uri[$component_uri_key + 1] ) ) {
@@ -339,47 +367,10 @@ function bp_core_new_nav_default( $args = '' ) {
339
  }
340
 
341
  /**
342
- * Sort the navigation menu items.
343
- *
344
- * The sorting is split into a separate function because it can only happen
345
- * after all plugins have had a chance to register their navigation items.
346
- *
347
- * @since 1.0.0
348
- *
349
- * @return bool|null Returns false on failure.
350
- */
351
- function bp_core_sort_nav_items() {
352
- $bp = buddypress();
353
-
354
- if ( empty( $bp->bp_nav ) || ! is_array( $bp->bp_nav ) ) {
355
- return false;
356
- }
357
-
358
- $temp = array();
359
-
360
- foreach ( (array) $bp->bp_nav as $slug => $nav_item ) {
361
- if ( empty( $temp[$nav_item['position']] ) ) {
362
- $temp[$nav_item['position']] = $nav_item;
363
- } else {
364
- // Increase numbers here to fit new items in.
365
- do {
366
- $nav_item['position']++;
367
- } while ( ! empty( $temp[$nav_item['position']] ) );
368
-
369
- $temp[$nav_item['position']] = $nav_item;
370
- }
371
- }
372
-
373
- ksort( $temp );
374
- $bp->bp_nav = &$temp;
375
- }
376
- add_action( 'wp_head', 'bp_core_sort_nav_items' );
377
- add_action( 'admin_head', 'bp_core_sort_nav_items' );
378
-
379
- /**
380
- * Add a subnav item to the BuddyPress navigation.
381
  *
382
  * @since 1.1.0
 
383
  *
384
  * @param array|string $args {
385
  * Array describing the new subnav item.
@@ -403,22 +394,49 @@ add_action( 'admin_head', 'bp_core_sort_nav_items' );
403
  * @type bool $show_in_admin_bar Optional. Whether the nav item should be added into the group's "Edit"
404
  * Admin Bar menu for group admins. Default: false.
405
  * }
 
406
  * @return bool|null Returns false on failure.
407
  */
408
- function bp_core_new_subnav_item( $args = '' ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
 
410
- // First, add the subnav item link to the bp_options_nav array.
411
- $created = bp_core_create_subnav_link( $args );
412
 
413
- // To mimic the existing behavior, if bp_core_create_subnav_link()
414
- // returns false, we make an early exit and don't attempt to register
415
- // the screen function.
416
- if ( false === $created ) {
 
417
  return false;
418
  }
419
 
420
  // Then, hook the screen function for the added subnav item.
421
- $hooked = bp_core_register_subnav_screen_function( $args );
422
  if ( false === $hooked ) {
423
  return false;
424
  }
@@ -428,6 +446,7 @@ function bp_core_new_subnav_item( $args = '' ) {
428
  * Add a subnav link to the BuddyPress navigation.
429
  *
430
  * @since 2.4.0
 
431
  *
432
  * @param array|string $args {
433
  * Array describing the new subnav item.
@@ -455,9 +474,10 @@ function bp_core_new_subnav_item( $args = '' ) {
455
  * the group's "Edit" Admin Bar menu for group admins.
456
  * Default: false.
457
  * }
458
- * @return bool|null Returns false on failure.
 
459
  */
460
- function bp_core_create_subnav_link( $args = '' ) {
461
  $bp = buddypress();
462
 
463
  $r = wp_parse_args( $args, array(
@@ -483,9 +503,14 @@ function bp_core_create_subnav_link( $args = '' ) {
483
  if ( empty( $r['link'] ) ) {
484
  $r['link'] = trailingslashit( $r['parent_url'] . $r['slug'] );
485
 
 
 
486
  // If this sub item is the default for its parent, skip the slug.
487
- if ( ! empty( $bp->bp_nav[$r['parent_slug']]['default_subnav_slug'] ) && $r['slug'] == $bp->bp_nav[$r['parent_slug']]['default_subnav_slug'] ) {
488
- $r['link'] = trailingslashit( $r['parent_url'] );
 
 
 
489
  }
490
  }
491
 
@@ -502,6 +527,7 @@ function bp_core_create_subnav_link( $args = '' ) {
502
  'name' => $r['name'],
503
  'link' => $r['link'],
504
  'slug' => $r['slug'],
 
505
  'css_id' => $r['item_css_id'],
506
  'position' => $r['position'],
507
  'user_has_access' => $r['user_has_access'],
@@ -510,13 +536,16 @@ function bp_core_create_subnav_link( $args = '' ) {
510
  'show_in_admin_bar' => (bool) $r['show_in_admin_bar'],
511
  );
512
 
513
- $bp->bp_options_nav[$r['parent_slug']][$r['slug']] = $subnav_item;
 
 
514
  }
515
 
516
  /**
517
  * Register a screen function, whether or not a related subnav link exists.
518
  *
519
  * @since 2.4.0
 
520
  *
521
  * @param array|string $args {
522
  * Array describing the new subnav item.
@@ -541,9 +570,10 @@ function bp_core_create_subnav_link( $args = '' ) {
541
  * the group's "Edit" Admin Bar menu for group admins.
542
  * Default: false.
543
  * }
 
544
  * @return bool|null Returns false on failure.
545
  */
546
- function bp_core_register_subnav_screen_function( $args = '' ) {
547
  $bp = buddypress();
548
 
549
  $r = wp_parse_args( $args, array(
@@ -555,7 +585,7 @@ function bp_core_register_subnav_screen_function( $args = '' ) {
555
  'screen_function' => false, // The name of the function to run when clicked.
556
  ) );
557
 
558
- /**
559
  * Hook the screen function for the added subnav item. But this only needs to
560
  * be done if this subnav item is the current view, and the user has access to the
561
  * subnav item. We figure out whether we're currently viewing this subnav by
@@ -568,8 +598,8 @@ function bp_core_register_subnav_screen_function( $args = '' ) {
568
  * (b) there is no current_action (ie, this is the default subnav for the parent nav)
569
  * and this subnav item is the default for the parent item (which we check by
570
  * comparing this subnav item's screen function with the screen function of the
571
- * parent nav item in $bp->bp_nav). This condition only arises when viewing a
572
- * user, since groups should always have an action set.
573
  */
574
 
575
  // If we *don't* meet condition (1), return.
@@ -577,15 +607,17 @@ function bp_core_register_subnav_screen_function( $args = '' ) {
577
  return;
578
  }
579
 
 
 
580
  // If we *do* meet condition (2), then the added subnav item is currently being requested.
581
- if ( ( bp_current_action() && bp_is_current_action( $r['slug'] ) ) || ( bp_is_user() && ! bp_current_action() && ( $r['screen_function'] == $bp->bp_nav[$r['parent_slug']]['screen_function'] ) ) ) {
582
 
583
  // If this is for site admins only and the user is not one, don't create the subnav item.
584
  if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
585
  return false;
586
  }
587
 
588
- $hooked = bp_core_maybe_hook_new_subnav_screen_function( $r );
589
 
590
  // If redirect args have been returned, perform the redirect now.
591
  if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) {
@@ -598,11 +630,14 @@ function bp_core_register_subnav_screen_function( $args = '' ) {
598
  * For a given subnav item, either hook the screen function or generate redirect arguments, as necessary.
599
  *
600
  * @since 2.1.0
 
601
  *
602
- * @param array $subnav_item The subnav array added to bp_options_nav in `bp_core_new_subnav_item()`.
 
 
603
  * @return array
604
  */
605
- function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) {
606
  $retval = array(
607
  'status' => '',
608
  );
@@ -645,10 +680,15 @@ function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) {
645
  // redirect URL.
646
  } elseif ( bp_is_user() ) {
647
 
 
 
 
 
 
648
  // Redirect to the displayed user's default
649
  // component, as long as that component is
650
  // publicly accessible.
651
- if ( bp_is_my_profile() || ! empty( $bp->bp_nav[ $bp->default_component ]['show_for_displayed_user'] ) ) {
652
  $message = __( 'You do not have access to this page.', 'buddypress' );
653
  $redirect_to = bp_displayed_user_domain();
654
 
@@ -691,58 +731,32 @@ function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item ) {
691
  }
692
 
693
  /**
694
- * Sort all subnavigation arrays.
695
  *
696
- * @since 1.1.0
 
697
  *
698
- * @return bool|null Returns false on failure.
 
 
 
699
  */
700
- function bp_core_sort_subnav_items() {
701
  $bp = buddypress();
702
 
703
- if ( empty( $bp->bp_options_nav ) || !is_array( $bp->bp_options_nav ) )
704
  return false;
 
705
 
706
- foreach ( (array) $bp->bp_options_nav as $parent_slug => $subnav_items ) {
707
- if ( !is_array( $subnav_items ) )
708
- continue;
709
-
710
- foreach ( (array) $subnav_items as $subnav_item ) {
711
- if ( empty( $temp[$subnav_item['position']]) )
712
- $temp[$subnav_item['position']] = $subnav_item;
713
- else {
714
- // Increase numbers here to fit new items in.
715
- do {
716
- $subnav_item['position']++;
717
- } while ( !empty( $temp[$subnav_item['position']] ) );
718
 
719
- $temp[$subnav_item['position']] = $subnav_item;
720
- }
721
  }
722
- ksort( $temp );
723
- $bp->bp_options_nav[$parent_slug] = &$temp;
724
- unset( $temp );
725
  }
726
- }
727
- add_action( 'wp_head', 'bp_core_sort_subnav_items' );
728
- add_action( 'admin_head', 'bp_core_sort_subnav_items' );
729
 
730
- /**
731
- * Check whether a given nav item has subnav items.
732
- *
733
- * @since 1.5.0
734
- *
735
- * @param string $nav_item The slug of the top-level nav item whose subnav items you're checking.
736
- * Default: the current component slug.
737
- * @return bool $has_subnav True if the nav item is found and has subnav items; false otherwise.
738
- */
739
- function bp_nav_item_has_subnav( $nav_item = '' ) {
740
- $bp = buddypress();
741
-
742
- if ( !$nav_item )
743
- $nav_item = bp_current_component();
744
-
745
- $has_subnav = isset( $bp->bp_options_nav[$nav_item] ) && count( $bp->bp_options_nav[$nav_item] ) > 0;
746
 
747
  /**
748
  * Filters whether or not a given nav item has subnav items.
@@ -756,75 +770,127 @@ function bp_nav_item_has_subnav( $nav_item = '' ) {
756
  }
757
 
758
  /**
759
- * Remove a nav item from the navigation array.
760
  *
761
  * @since 1.0.0
 
762
  *
763
- * @param int $parent_id The slug of the parent navigation item.
764
- * @return bool Returns false on failure, ie if the nav item can't be found.
 
765
  */
766
- function bp_core_remove_nav_item( $parent_id ) {
767
  $bp = buddypress();
768
 
769
- // Unset subnav items for this nav item.
770
- if ( isset( $bp->bp_options_nav[$parent_id] ) && is_array( $bp->bp_options_nav[$parent_id] ) ) {
771
- foreach( (array) $bp->bp_options_nav[$parent_id] as $subnav_item ) {
772
- bp_core_remove_subnav_item( $parent_id, $subnav_item['slug'] );
773
  }
774
  }
775
 
776
- if ( empty( $bp->bp_nav[ $parent_id ] ) )
 
 
 
 
777
  return false;
 
778
 
779
- if ( $function = $bp->bp_nav[$parent_id]['screen_function'] ) {
 
 
 
 
 
 
 
 
 
 
780
  // Remove our screen hook if screen function is callable.
781
- if ( is_callable( $function ) ) {
782
- remove_action( 'bp_screens', $function, 3 );
783
  }
784
  }
785
 
786
- unset( $bp->bp_nav[$parent_id] );
787
  }
788
 
789
  /**
790
- * Remove a subnav item from the navigation array.
791
  *
792
  * @since 1.0.0
 
793
  *
794
- * @param string $parent_id The slug of the parent navigation item.
795
- * @param string $slug The slug of the subnav item to be removed.
 
 
796
  */
797
- function bp_core_remove_subnav_item( $parent_id, $slug ) {
798
  $bp = buddypress();
799
 
800
- $screen_function = isset( $bp->bp_options_nav[$parent_id][$slug]['screen_function'] )
801
- ? $bp->bp_options_nav[$parent_id][$slug]['screen_function']
802
- : false;
803
-
804
- if ( ! empty( $screen_function ) ) {
805
- // Remove our screen hook if screen function is callable.
806
- if ( is_callable( $screen_function ) ) {
807
- remove_action( 'bp_screens', $screen_function, 3 );
808
  }
809
  }
810
 
811
- unset( $bp->bp_options_nav[$parent_id][$slug] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
812
 
813
- if ( isset( $bp->bp_options_nav[$parent_id] ) && !count( $bp->bp_options_nav[$parent_id] ) )
814
- unset($bp->bp_options_nav[$parent_id]);
815
  }
816
 
817
  /**
818
  * Clear all subnav items from a specific nav item.
819
  *
820
  * @since 1.0.0
 
821
  *
822
  * @param string $parent_slug The slug of the parent navigation item.
 
823
  */
824
- function bp_core_reset_subnav_items( $parent_slug ) {
825
  $bp = buddypress();
826
 
827
- unset( $bp->bp_options_nav[$parent_slug] );
 
 
 
 
 
 
 
 
 
 
 
 
828
  }
829
 
830
 
@@ -835,8 +901,6 @@ function bp_core_reset_subnav_items( $parent_slug ) {
835
  *
836
  * @since 1.5.0
837
  *
838
- * @uses get_user_option()
839
- *
840
  * @param string $context Context of this preference check. 'admin' or 'front'.
841
  * @param int $user Optional. ID of the user to check. Default: 0 (which falls back to the logged-in user's ID).
842
  * @return bool True if the toolbar should be showing for this user.
13
  defined( 'ABSPATH' ) || exit;
14
 
15
  /**
16
+ * Add an item to the primary navigation of the specified component.
17
  *
18
  * @since 1.1.0
19
+ * @since 2.6.0 Introduced the `$component` parameter.
20
  *
21
  * @param array|string $args {
22
  * Array describing the new nav item.
33
  * @type bool|string $default_subnav_slug Optional. The slug of the default subnav item to select when the nav
34
  * item is clicked.
35
  * }
36
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
37
  * @return bool|null Returns false on failure.
38
  */
39
+ function bp_core_new_nav_item( $args, $component = 'members' ) {
40
+ if ( ! bp_is_active( $component ) ) {
41
+ return;
42
+ }
43
 
44
  $defaults = array(
45
  'name' => false, // Display name for the nav item.
54
 
55
  $r = wp_parse_args( $args, $defaults );
56
 
57
+ // Validate nav link data.
58
+ $nav_item = bp_core_create_nav_link( $r, $component );
59
 
60
+ /*
61
+ * To mimic legacy behavior, if bp_core_create_nav_link() returns false, we make
62
+ * an early exit and don't attempt to register the screen function.
63
+ */
64
+ if ( false === $nav_item ) {
65
  return false;
66
  }
67
 
68
  // Then, hook the screen function for the added nav item.
69
+ $hooked = bp_core_register_nav_screen_function( $nav_item );
70
  if ( false === $hooked ){
71
  return false;
72
  }
87
  }
88
 
89
  /**
90
+ * Add a link to the main BuddyPress navigation.
91
  *
92
  * @since 2.4.0
93
+ * @since 2.6.0 Introduced the `$component` parameter. Began returning a BP_Core_Nav_Item object on success.
94
  *
95
  * @param array|string $args {
96
  * Array describing the new nav item.
107
  * @type bool|string $default_subnav_slug Optional. The slug of the default subnav item to select when the nav
108
  * item is clicked.
109
  * }
110
+ * @param string $component Optional. Component that the nav belongs to.
111
+ * @return bool|BP_Core_Nav_Item Returns false on failure, new nav item on success.
112
  */
113
+ function bp_core_create_nav_link( $args = '', $component = 'members' ) {
114
  $bp = buddypress();
115
 
116
  $defaults = array(
140
  $r['item_css_id'] = $r['slug'];
141
  }
142
 
143
+ $nav_item = array(
144
  'name' => $r['name'],
145
  'slug' => $r['slug'],
146
  'link' => trailingslashit( bp_loggedin_user_domain() . $r['slug'] ),
151
  'default_subnav_slug' => $r['default_subnav_slug']
152
  );
153
 
154
+ // Add the item to the nav.
155
+ buddypress()->{$component}->nav->add_nav( $nav_item );
156
+
157
  /**
158
+ * Fires after a link is added to the main BuddyPress nav.
159
  *
160
  * @since 2.4.0
161
+ * @since 2.6.0 Added `$component` parameter.
162
  *
163
+ * @param array $r Parsed arguments for the nav item.
164
+ * @param array $args Originally passed in arguments for the nav item.
165
+ * @param array $defaults Default arguments for a nav item.
166
+ * @param string $component Component that the nav belongs to.
167
  */
168
+ do_action( 'bp_core_create_nav_link', $r, $args, $defaults, $component );
169
+
170
+ return $nav_item;
171
  }
172
 
173
  /**
214
  }
215
 
216
  /**
217
+ * If this is for site admins only and the user is not one,
218
+ * don't register this screen function.
219
+ */
220
  if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
221
  return false;
222
  }
305
 
306
  $r = wp_parse_args( $args, $defaults );
307
 
308
+ // This is specific to Members - it's not available in Groups.
309
+ $parent_nav = $bp->members->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false );
310
+
311
+ if ( ! $parent_nav ) {
312
+ return ;
313
+ }
314
+
315
+ $parent_nav = reset( $parent_nav );
316
+
317
+ if ( ! empty( $parent_nav->screen_function ) ) {
318
  // Remove our screen hook if screen function is callable.
319
+ if ( is_callable( $parent_nav->screen_function ) ) {
320
+ remove_action( 'bp_screens', $parent_nav->screen_function, 3 );
321
  }
322
  }
323
 
324
+ // Edit the screen function for the parent nav.
325
+ $bp->members->nav->edit_nav( array(
326
+ 'screen_function' => &$r['screen_function'],
327
+ 'default_subnav_slug' => $r['subnav_slug'],
328
+ ), $parent_nav->slug );
329
 
330
+ if ( bp_is_current_component( $parent_nav->slug ) ) {
331
 
332
  // The only way to tell whether to set the subnav is to peek at the unfiltered_uri
333
  // Find the component.
334
+ $component_uri_key = array_search( $parent_nav->slug, $bp->unfiltered_uri );
335
 
336
  if ( false !== $component_uri_key ) {
337
  if ( ! empty( $bp->unfiltered_uri[$component_uri_key + 1] ) ) {
367
  }
368
 
369
  /**
370
+ * Add an item to secondary navigation of the specified component.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  *
372
  * @since 1.1.0
373
+ * @since 2.6.0 Introduced the `$component` parameter.
374
  *
375
  * @param array|string $args {
376
  * Array describing the new subnav item.
394
  * @type bool $show_in_admin_bar Optional. Whether the nav item should be added into the group's "Edit"
395
  * Admin Bar menu for group admins. Default: false.
396
  * }
397
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
398
  * @return bool|null Returns false on failure.
399
  */
400
+ function bp_core_new_subnav_item( $args, $component = null ) {
401
+ // Backward compatibility for plugins using `bp_core_new_subnav_item()` without `$component`
402
+ // to add group subnav items.
403
+ if ( null === $component && bp_is_active( 'groups' ) && bp_is_group() && isset( $args['parent_slug'] ) ) {
404
+ /*
405
+ * Assume that this item is intended to belong to the current group if:
406
+ * a) the 'parent_slug' is the same as the slug of the current group, or
407
+ * b) the 'parent_slug' starts with the slug of the current group, and the members nav doesn't have
408
+ * a primary item with that slug.
409
+ */
410
+ $group_slug = bp_get_current_group_slug();
411
+ if (
412
+ $group_slug === $args['parent_slug'] ||
413
+ ( 0 === strpos( $args['parent_slug'], $group_slug ) && ! buddypress()->members->nav->get_primary( array( 'slug' => $args['parent_slug'] ), false ) )
414
+ ) {
415
+ $component = 'groups';
416
+ }
417
+ }
418
+
419
+ if ( ! $component ) {
420
+ $component = 'members';
421
+ }
422
+
423
+ if ( ! bp_is_active( $component ) ) {
424
+ return;
425
+ }
426
 
427
+ // First, register the subnav item in the nav.
428
+ $subnav_item = bp_core_create_subnav_link( $args, $component );
429
 
430
+ /*
431
+ * To mimic legacy behavior, if bp_core_create_subnav_link() returns false, we make an
432
+ * early exit and don't attempt to register the screen function.
433
+ */
434
+ if ( false === $subnav_item ) {
435
  return false;
436
  }
437
 
438
  // Then, hook the screen function for the added subnav item.
439
+ $hooked = bp_core_register_subnav_screen_function( $subnav_item, $component );
440
  if ( false === $hooked ) {
441
  return false;
442
  }
446
  * Add a subnav link to the BuddyPress navigation.
447
  *
448
  * @since 2.4.0
449
+ * @since 2.6.0 Introduced the `$component` parameter. Began returning a BP_Core_Nav_Item object on success.
450
  *
451
  * @param array|string $args {
452
  * Array describing the new subnav item.
474
  * the group's "Edit" Admin Bar menu for group admins.
475
  * Default: false.
476
  * }
477
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
478
+ * @return bool|object Returns false on failure, new BP_Core_Nav_Item instance on success.
479
  */
480
+ function bp_core_create_subnav_link( $args = '', $component = 'members' ) {
481
  $bp = buddypress();
482
 
483
  $r = wp_parse_args( $args, array(
503
  if ( empty( $r['link'] ) ) {
504
  $r['link'] = trailingslashit( $r['parent_url'] . $r['slug'] );
505
 
506
+ $parent_nav = $bp->{$component}->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false );
507
+
508
  // If this sub item is the default for its parent, skip the slug.
509
+ if ( $parent_nav ) {
510
+ $parent_nav_item = reset( $parent_nav );
511
+ if ( ! empty( $parent_nav_item->default_subnav_slug ) && $r['slug'] === $parent_nav_item->default_subnav_slug ) {
512
+ $r['link'] = trailingslashit( $r['parent_url'] );
513
+ }
514
  }
515
  }
516
 
527
  'name' => $r['name'],
528
  'link' => $r['link'],
529
  'slug' => $r['slug'],
530
+ 'parent_slug' => $r['parent_slug'],
531
  'css_id' => $r['item_css_id'],
532
  'position' => $r['position'],
533
  'user_has_access' => $r['user_has_access'],
536
  'show_in_admin_bar' => (bool) $r['show_in_admin_bar'],
537
  );
538
 
539
+ buddypress()->{$component}->nav->add_nav( $subnav_item );
540
+
541
+ return $subnav_item;
542
  }
543
 
544
  /**
545
  * Register a screen function, whether or not a related subnav link exists.
546
  *
547
  * @since 2.4.0
548
+ * @since 2.6.0 Introduced the `$component` parameter.
549
  *
550
  * @param array|string $args {
551
  * Array describing the new subnav item.
570
  * the group's "Edit" Admin Bar menu for group admins.
571
  * Default: false.
572
  * }
573
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
574
  * @return bool|null Returns false on failure.
575
  */
576
+ function bp_core_register_subnav_screen_function( $args = '', $component = 'members' ) {
577
  $bp = buddypress();
578
 
579
  $r = wp_parse_args( $args, array(
585
  'screen_function' => false, // The name of the function to run when clicked.
586
  ) );
587
 
588
+ /*
589
  * Hook the screen function for the added subnav item. But this only needs to
590
  * be done if this subnav item is the current view, and the user has access to the
591
  * subnav item. We figure out whether we're currently viewing this subnav by
598
  * (b) there is no current_action (ie, this is the default subnav for the parent nav)
599
  * and this subnav item is the default for the parent item (which we check by
600
  * comparing this subnav item's screen function with the screen function of the
601
+ * parent nav item in the component's primary nav). This condition only arises
602
+ * when viewing a user, since groups should always have an action set.
603
  */
604
 
605
  // If we *don't* meet condition (1), return.
607
  return;
608
  }
609
 
610
+ $parent_nav = $bp->{$component}->nav->get_primary( array( 'slug' => $r['parent_slug'] ), false );
611
+
612
  // If we *do* meet condition (2), then the added subnav item is currently being requested.
613
+ if ( ( bp_current_action() && bp_is_current_action( $r['slug'] ) ) || ( bp_is_user() && ! bp_current_action() && ! empty( $parent_nav->screen_function ) && $r['screen_function'] == $parent_nav->screen_function ) ) {
614
 
615
  // If this is for site admins only and the user is not one, don't create the subnav item.
616
  if ( ! empty( $r['site_admin_only'] ) && ! bp_current_user_can( 'bp_moderate' ) ) {
617
  return false;
618
  }
619
 
620
+ $hooked = bp_core_maybe_hook_new_subnav_screen_function( $r, $component );
621
 
622
  // If redirect args have been returned, perform the redirect now.
623
  if ( ! empty( $hooked['status'] ) && 'failure' === $hooked['status'] && isset( $hooked['redirect_args'] ) ) {
630
  * For a given subnav item, either hook the screen function or generate redirect arguments, as necessary.
631
  *
632
  * @since 2.1.0
633
+ * @since 2.6.0 Introduced the `$component` parameter.
634
  *
635
+ * @param array $subnav_item The subnav array added to the secondary navigation of
636
+ * the component in bp_core_new_subnav_item().
637
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
638
  * @return array
639
  */
640
+ function bp_core_maybe_hook_new_subnav_screen_function( $subnav_item, $component = 'members' ) {
641
  $retval = array(
642
  'status' => '',
643
  );
680
  // redirect URL.
681
  } elseif ( bp_is_user() ) {
682
 
683
+ $parent_nav_default = $bp->{$component}->nav->get_primary( array( 'slug' => $bp->default_component ), false );
684
+ if ( $parent_nav_default ) {
685
+ $parent_nav_default_item = reset( $parent_nav_default );
686
+ }
687
+
688
  // Redirect to the displayed user's default
689
  // component, as long as that component is
690
  // publicly accessible.
691
+ if ( bp_is_my_profile() || ( isset( $parent_nav_default_item ) && $parent_nav_default_item->show_for_displayed_user ) ) {
692
  $message = __( 'You do not have access to this page.', 'buddypress' );
693
  $redirect_to = bp_displayed_user_domain();
694
 
731
  }
732
 
733
  /**
734
+ * Check whether a given nav item has subnav items.
735
  *
736
+ * @since 1.5.0
737
+ * @since 2.6.0 Introduced the `$component` parameter.
738
  *
739
+ * @param string $nav_item The slug of the top-level nav item whose subnav items you're checking.
740
+ * Default: the current component slug.
741
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
742
+ * @return bool $has_subnav True if the nav item is found and has subnav items; false otherwise.
743
  */
744
+ function bp_nav_item_has_subnav( $nav_item = '', $component = 'members' ) {
745
  $bp = buddypress();
746
 
747
+ if ( ! isset( $bp->{$component}->nav ) ) {
748
  return false;
749
+ }
750
 
751
+ if ( ! $nav_item ) {
752
+ $nav_item = bp_current_component();
 
 
 
 
 
 
 
 
 
 
753
 
754
+ if ( bp_is_group() ) {
755
+ $nav_item = bp_current_item();
756
  }
 
 
 
757
  }
 
 
 
758
 
759
+ $has_subnav = (bool) $bp->{$component}->nav->get_secondary( array( 'parent_slug' => $nav_item ), false );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
760
 
761
  /**
762
  * Filters whether or not a given nav item has subnav items.
770
  }
771
 
772
  /**
773
+ * Deletes an item from the primary navigation of the specified component.
774
  *
775
  * @since 1.0.0
776
+ * @since 2.6.0 Introduced the `$component` parameter.
777
  *
778
+ * @param string $slug The slug of the primary navigation item.
779
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
780
+ * @return bool Returns false on failure, True on success.
781
  */
782
+ function bp_core_remove_nav_item( $slug, $component = null ) {
783
  $bp = buddypress();
784
 
785
+ // Backward compatibility for removing group nav items using the group slug as `$parent_slug`.
786
+ if ( ! $component && bp_is_active( 'groups' ) && isset( $bp->groups->nav ) ) {
787
+ if ( $bp->groups->nav->get_primary( array( 'slug' => $slug ) ) ) {
788
+ $component = 'groups';
789
  }
790
  }
791
 
792
+ if ( ! $component ) {
793
+ $component = 'members';
794
+ }
795
+
796
+ if ( ! isset( $bp->{$component}->nav ) ) {
797
  return false;
798
+ }
799
 
800
+ $screen_functions = $bp->{$component}->nav->delete_nav( $slug );
801
+
802
+ // Reset backcompat nav items so that subsequent references will be correct.
803
+ $bp->bp_nav->reset();
804
+ $bp->bp_options_nav->reset();
805
+
806
+ if ( ! is_array( $screen_functions ) ) {
807
+ return false;
808
+ }
809
+
810
+ foreach ( $screen_functions as $screen_function ) {
811
  // Remove our screen hook if screen function is callable.
812
+ if ( is_callable( $screen_function ) ) {
813
+ remove_action( 'bp_screens', $screen_function, 3 );
814
  }
815
  }
816
 
817
+ return true;
818
  }
819
 
820
  /**
821
+ * Deletes an item from the secondary navigation of the specified component.
822
  *
823
  * @since 1.0.0
824
+ * @since 2.6.0 Introduced the `$component` parameter.
825
  *
826
+ * @param string $parent_slug The slug of the primary navigation item.
827
+ * @param string $slug The slug of the secondary item to be removed.
828
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
829
+ * @return bool Returns false on failure, True on success.
830
  */
831
+ function bp_core_remove_subnav_item( $parent_slug, $slug, $component = null ) {
832
  $bp = buddypress();
833
 
834
+ // Backward compatibility for removing group nav items using the group slug as `$parent_slug`.
835
+ if ( ! $component && bp_is_active( 'groups' ) && isset( $bp->groups->nav ) ) {
836
+ if ( $bp->groups->nav->get_primary( array( 'slug' => $parent_slug ) ) ) {
837
+ $component = 'groups';
 
 
 
 
838
  }
839
  }
840
 
841
+ if ( ! $component ) {
842
+ $component = 'members';
843
+ }
844
+
845
+ if ( ! isset( $bp->{$component}->nav ) ) {
846
+ return false;
847
+ }
848
+
849
+ $screen_functions = $bp->{$component}->nav->delete_nav( $slug, $parent_slug );
850
+
851
+ // Reset backcompat nav items so that subsequent references will be correct.
852
+ $bp->bp_nav->reset();
853
+ $bp->bp_options_nav->reset();
854
+
855
+ if ( ! is_array( $screen_functions ) ) {
856
+ return false;
857
+ }
858
+
859
+ $screen_function = reset( $screen_functions );
860
+
861
+ // Remove our screen hook if screen function is callable.
862
+ if ( is_callable( $screen_function ) ) {
863
+ remove_action( 'bp_screens', $screen_function, 3 );
864
+ }
865
 
866
+ return true;
 
867
  }
868
 
869
  /**
870
  * Clear all subnav items from a specific nav item.
871
  *
872
  * @since 1.0.0
873
+ * @since 2.6.0 Introduced the `$component` parameter.
874
  *
875
  * @param string $parent_slug The slug of the parent navigation item.
876
+ * @param string $component The component the navigation is attached to. Defaults to 'members'.
877
  */
878
+ function bp_core_reset_subnav_items( $parent_slug, $component = 'members' ) {
879
  $bp = buddypress();
880
 
881
+ if ( ! isset( $bp->{$component}->nav ) ) {
882
+ return;
883
+ }
884
+
885
+ $subnav_items = $bp->{$component}->nav->get_secondary( array( 'parent_slug' => $parent_slug ), false );
886
+
887
+ if ( ! $subnav_items ) {
888
+ return;
889
+ }
890
+
891
+ foreach( $subnav_items as $subnav_item ) {
892
+ $bp->{$component}->nav->delete_nav( $subnav_item->slug, $parent_slug );
893
+ }
894
  }
895
 
896
 
901
  *
902
  * @since 1.5.0
903
  *
 
 
904
  * @param string $context Context of this preference check. 'admin' or 'front'.
905
  * @param int $user Optional. ID of the user to check. Default: 0 (which falls back to the logged-in user's ID).
906
  * @return bool True if the toolbar should be showing for this user.
bp-core/bp-core-cache.php CHANGED
@@ -115,7 +115,17 @@ add_action( 'update_option', 'bp_core_clear_directory_pages_cache_settings_edit'
115
  * @param string $option Option name.
116
  */
117
  function bp_core_clear_root_options_cache( $option ) {
 
 
 
 
 
118
  $keys = array_keys( bp_get_default_options() );
 
 
 
 
 
119
  $keys = array_merge( $keys, array(
120
  'registration',
121
  'avatar_default',
@@ -252,3 +262,100 @@ function bp_update_meta_cache( $args = array() ) {
252
 
253
  return $cache;
254
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  * @param string $option Option name.
116
  */
117
  function bp_core_clear_root_options_cache( $option ) {
118
+ foreach ( array( 'add_option', 'add_site_option', 'update_option', 'update_site_option' ) as $action ) {
119
+ remove_action( $action, 'bp_core_clear_root_options_cache' );
120
+ }
121
+
122
+ // Surrounding code prevents infinite loops on WP < 4.4.
123
  $keys = array_keys( bp_get_default_options() );
124
+
125
+ foreach ( array( 'add_option', 'add_site_option', 'update_option', 'update_site_option' ) as $action ) {
126
+ add_action( $action, 'bp_core_clear_root_options_cache' );
127
+ }
128
+
129
  $keys = array_merge( $keys, array(
130
  'registration',
131
  'avatar_default',
262
 
263
  return $cache;
264
  }
265
+
266
+ /**
267
+ * Gets a value that has been cached using an incremented key.
268
+ *
269
+ * A utility function for use by query methods like BP_Activity_Activity::get().
270
+ *
271
+ * @since 2.7.0
272
+ * @see bp_core_set_incremented_cache()
273
+ *
274
+ * @param string $key Unique key for the query. Usually a SQL string.
275
+ * @param string $group Cache group. Eg 'bp_activity'.
276
+ * @return array|bool False if no cached values are found, otherwise an array of IDs.
277
+ */
278
+ function bp_core_get_incremented_cache( $key, $group ) {
279
+ $cache_key = bp_core_get_incremented_cache_key( $key, $group );
280
+ return wp_cache_get( $cache_key, $group );
281
+ }
282
+
283
+ /**
284
+ * Caches a value using an incremented key.
285
+ *
286
+ * An "incremented key" is a cache key that is hashed with a unique incrementor,
287
+ * allowing for bulk invalidation.
288
+ *
289
+ * Use this method when caching data that should be invalidated whenever any
290
+ * object of a given type is created, updated, or deleted. This usually means
291
+ * data related to object queries, which can only reliably cached until the
292
+ * underlying set of objects has been modified. See, eg, BP_Activity_Activity::get().
293
+ *
294
+ * @since 2.7.0
295
+ *
296
+ * @param string $key Unique key for the query. Usually a SQL string.
297
+ * @param string $group Cache group. Eg 'bp_activity'.
298
+ * @param array $ids Array of IDs.
299
+ * @return bool
300
+ */
301
+ function bp_core_set_incremented_cache( $key, $group, $ids ) {
302
+ $cache_key = bp_core_get_incremented_cache_key( $key, $group );
303
+ return wp_cache_set( $cache_key, $ids, $group );
304
+ }
305
+
306
+ /**
307
+ * Gets the key to be used when caching a value using an incremented cache key.
308
+ *
309
+ * The $key is hashed with a component-specific incrementor, which is used to
310
+ * invalidate multiple caches at once.
311
+
312
+ * @since 2.7.0
313
+ *
314
+ * @param string $key Unique key for the query. Usually a SQL string.
315
+ * @param string $group Cache group. Eg 'bp_activity'.
316
+ * @return string
317
+ */
318
+ function bp_core_get_incremented_cache_key( $key, $group ) {
319
+ $incrementor = bp_core_get_incrementor( $group );
320
+ $cache_key = md5( $key . $incrementor );
321
+ return $cache_key;
322
+ }
323
+
324
+ /**
325
+ * Gets a group-specific cache incrementor.
326
+ *
327
+ * The incrementor is paired with query identifiers (like SQL strings) to
328
+ * create cache keys that can be invalidated en masse.
329
+ *
330
+ * If an incrementor does not yet exist for the given `$group`, one will
331
+ * be created.
332
+ *
333
+ * @since 2.7.0
334
+ *
335
+ * @param string $group Cache group. Eg 'bp_activity'.
336
+ * @return string
337
+ */
338
+ function bp_core_get_incrementor( $group ) {
339
+ $incrementor = wp_cache_get( 'incrementor', $group );
340
+ if ( ! $incrementor ) {
341
+ $incrementor = microtime();
342
+ wp_cache_set( 'incrementor', $incrementor, $group );
343
+ }
344
+
345
+ return $incrementor;
346
+ }
347
+
348
+ /**
349
+ * Reset a group-specific cache incrementor.
350
+ *
351
+ * Call this function when all incrementor-based caches associated with a given
352
+ * cache group should be invalidated.
353
+ *
354
+ * @since 2.7.0
355
+ *
356
+ * @param string $group Cache group. Eg 'bp_activity'.
357
+ * @return bool True on success, false on failure.
358
+ */
359
+ function bp_core_reset_incrementor( $group ) {
360
+ return wp_cache_delete( 'incrementor', $group );
361
+ }
bp-core/bp-core-caps.php CHANGED
@@ -20,7 +20,7 @@ defined( 'ABSPATH' ) || exit;
20
  *
21
  * @since 2.1.0
22
  *
23
- * @return array
24
  */
25
  function bp_get_current_blog_roles() {
26
  global $wp_roles;
@@ -56,10 +56,6 @@ function bp_get_current_blog_roles() {
56
  * This is called on plugin activation.
57
  *
58
  * @since 1.6.0
59
- *
60
- * @uses get_role() To get the administrator, default and moderator roles.
61
- * @uses WP_Role::add_cap() To add various capabilities.
62
- * @uses do_action() Calls 'bp_add_caps'.
63
  */
64
  function bp_add_caps() {
65
  global $wp_roles;
@@ -92,10 +88,6 @@ function bp_add_caps() {
92
  * This is called on plugin deactivation.
93
  *
94
  * @since 1.6.0
95
- *
96
- * @uses get_role() To get the administrator and default roles.
97
- * @uses WP_Role::remove_cap() To remove various capabilities.
98
- * @uses do_action() Calls 'bp_remove_caps'.
99
  */
100
  function bp_remove_caps() {
101
  global $wp_roles;
@@ -129,7 +121,6 @@ function bp_remove_caps() {
129
  *
130
  * @see WP_User::has_cap() for description of the arguments passed to the
131
  * 'map_meta_cap' filter.
132
- * @uses apply_filters() Calls 'bp_map_meta_caps' with caps, cap, user ID and
133
  * args.
134
  *
135
  * @param array $caps See {@link WP_User::has_cap()}.
@@ -158,8 +149,6 @@ function bp_map_meta_caps( $caps, $cap, $user_id, $args ) {
158
  *
159
  * @since 1.6.0
160
  *
161
- * @uses apply_filters() Calls 'bp_get_community_caps' with the capabilities.
162
- *
163
  * @return array Community capabilities.
164
  */
165
  function bp_get_community_caps() {
@@ -182,8 +171,6 @@ function bp_get_community_caps() {
182
  *
183
  * @since 1.6.0
184
  *
185
- * @uses apply_filters() Allow return value to be filtered.
186
- *
187
  * @param string $role The role for which you're loading caps.
188
  * @return array Capabilities for $role.
189
  */
@@ -229,15 +216,6 @@ function bp_get_caps_for_role( $role = '' ) {
229
  * already have a role or capability on.
230
  *
231
  * @since 1.6.0
232
- *
233
- * @global BuddyPress $bp Global BuddyPress settings object.
234
- *
235
- * @uses is_multisite()
236
- * @uses bp_allow_global_access()
237
- * @uses bp_is_user_inactive()
238
- * @uses is_user_logged_in()
239
- * @uses current_user_can()
240
- * @uses WP_User::set_role()
241
  */
242
  function bp_set_current_user_default_role() {
243
 
@@ -265,55 +243,105 @@ function bp_set_current_user_default_role() {
265
  *
266
  * @since 1.6.0
267
  * @since 2.4.0 Second argument modified to accept an array, rather than `$blog_id`.
 
268
  *
269
  * @param string $capability Capability or role name.
270
  * @param array|int $args {
271
  * Array of extra arguments applicable to the capability check.
272
- * @type int $blog_id Optional. Blog ID. Defaults to the BP root blog.
 
273
  * @type mixed $a,... Optional. Extra arguments applicable to the capability check.
274
  * }
275
  * @return bool True if the user has the cap for the given parameters.
276
  */
277
  function bp_current_user_can( $capability, $args = array() ) {
278
- $blog_id = 0;
279
-
280
  // Backward compatibility for older $blog_id parameter.
281
  if ( is_int( $args ) ) {
282
- $blog_id = $args;
283
  $args = array();
 
284
 
285
  // New format for second parameter.
286
  } elseif ( is_array( $args ) && isset( $args['blog_id'] ) ) {
287
  // Get the blog ID if set, but don't pass along to `current_user_can_for_blog()`.
288
- $blog_id = (int) $args['blog_id'];
289
  unset( $args['blog_id'] );
290
  }
291
 
292
- // Backward compatibility for older bp_current_user_can() checks
293
- if ( empty( $args ) ) {
294
- $args = null;
295
- }
296
 
297
  // Use root blog if no ID passed.
298
- if ( empty( $blog_id ) ) {
299
- $blog_id = bp_get_root_blog_id();
300
  }
301
 
302
- $args = array( $blog_id, $capability, $args );
303
- $retval = call_user_func_array( 'current_user_can_for_blog', $args );
 
 
 
304
 
305
  /**
306
  * Filters whether or not the current user has a given capability.
307
  *
308
  * @since 1.6.0
309
  * @since 2.4.0 Pass `$args` variable.
 
310
  *
311
  * @param bool $retval Whether or not the current user has the capability.
312
  * @param string $capability The capability being checked for.
313
  * @param int $blog_id Blog ID. Defaults to the BP root blog.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  * @param array $args Array of extra arguments passed.
315
  */
316
- return (bool) apply_filters( 'bp_current_user_can', $retval, $capability, $blog_id, $args );
 
 
 
 
 
 
317
  }
318
 
319
  /**
20
  *
21
  * @since 2.1.0
22
  *
23
+ * @return object
24
  */
25
  function bp_get_current_blog_roles() {
26
  global $wp_roles;
56
  * This is called on plugin activation.
57
  *
58
  * @since 1.6.0
 
 
 
 
59
  */
60
  function bp_add_caps() {
61
  global $wp_roles;
88
  * This is called on plugin deactivation.
89
  *
90
  * @since 1.6.0
 
 
 
 
91
  */
92
  function bp_remove_caps() {
93
  global $wp_roles;
121
  *
122
  * @see WP_User::has_cap() for description of the arguments passed to the
123
  * 'map_meta_cap' filter.
 
124
  * args.
125
  *
126
  * @param array $caps See {@link WP_User::has_cap()}.
149
  *
150
  * @since 1.6.0
151
  *
 
 
152
  * @return array Community capabilities.
153
  */
154
  function bp_get_community_caps() {
171
  *
172
  * @since 1.6.0
173
  *
 
 
174
  * @param string $role The role for which you're loading caps.
175
  * @return array Capabilities for $role.
176
  */
216
  * already have a role or capability on.
217
  *
218
  * @since 1.6.0
 
 
 
 
 
 
 
 
 
219
  */
220
  function bp_set_current_user_default_role() {
221
 
243
  *
244
  * @since 1.6.0
245
  * @since 2.4.0 Second argument modified to accept an array, rather than `$blog_id`.
246
+ * @since 2.7.0 Deprecated $args['blog_id'] in favor of $args['site_id'].
247
  *
248
  * @param string $capability Capability or role name.
249
  * @param array|int $args {
250
  * Array of extra arguments applicable to the capability check.
251
+ * @type int $site_id Optional. Blog ID. Defaults to the BP root blog.
252
+ * @type int $blog_id Deprecated. Use $site_id instead.
253
  * @type mixed $a,... Optional. Extra arguments applicable to the capability check.
254
  * }
255
  * @return bool True if the user has the cap for the given parameters.
256
  */
257
  function bp_current_user_can( $capability, $args = array() ) {
 
 
258
  // Backward compatibility for older $blog_id parameter.
259
  if ( is_int( $args ) ) {
260
+ $site_id = $args;
261
  $args = array();
262
+ $args['site_id'] = $site_id;
263
 
264
  // New format for second parameter.
265
  } elseif ( is_array( $args ) && isset( $args['blog_id'] ) ) {
266
  // Get the blog ID if set, but don't pass along to `current_user_can_for_blog()`.
267
+ $args['site_id'] = (int) $args['blog_id'];
268
  unset( $args['blog_id'] );
269
  }
270
 
271
+ // Cast $args as an array.
272
+ $args = (array) $args;
 
 
273
 
274
  // Use root blog if no ID passed.
275
+ if ( empty( $args['site_id'] ) ) {
276
+ $args['site_id'] = bp_get_root_blog_id();
277
  }
278
 
279
+ /** This filter is documented in /bp-core/bp-core-template.php */
280
+ $current_user_id = apply_filters( 'bp_loggedin_user_id', get_current_user_id() );
281
+
282
+ // Call bp_user_can().
283
+ $retval = bp_user_can( $current_user_id, $capability, $args );
284
 
285
  /**
286
  * Filters whether or not the current user has a given capability.
287
  *
288
  * @since 1.6.0
289
  * @since 2.4.0 Pass `$args` variable.
290
+ * @since 2.7.0 Change format of $args variable array.
291
  *
292
  * @param bool $retval Whether or not the current user has the capability.
293
  * @param string $capability The capability being checked for.
294
  * @param int $blog_id Blog ID. Defaults to the BP root blog.
295
+ * @param array $args Array of extra arguments as originally passed.
296
+ */
297
+ return (bool) apply_filters( 'bp_current_user_can', $retval, $capability, $args['site_id'], $args );
298
+ }
299
+
300
+ /**
301
+ * Check whether the specified user has a given capability on a given site.
302
+ *
303
+ * @since 2.7.0
304
+ *
305
+ * @param int $user_id
306
+ * @param string $capability Capability or role name.
307
+ * @param array|int $args {
308
+ * Array of extra arguments applicable to the capability check.
309
+ *
310
+ * @type int $site_id Optional. Site ID. Defaults to the BP root blog.
311
+ * @type mixed $a,... Optional. Extra arguments applicable to the capability check.
312
+ * }
313
+ * @return bool True if the user has the cap for the given parameters.
314
+ */
315
+ function bp_user_can( $user_id, $capability, $args = array() ) {
316
+ $site_id = bp_get_root_blog_id();
317
+
318
+ // Get the site ID if set, but don't pass along to user_can().
319
+ if ( isset( $args['site_id'] ) ) {
320
+ $site_id = (int) $args['site_id'];
321
+ unset( $args['site_id'] );
322
+ }
323
+
324
+ $switched = is_multisite() ? switch_to_blog( $site_id ) : false;
325
+ $retval = call_user_func_array( 'user_can', array( $user_id, $capability, $args ) );
326
+
327
+ /**
328
+ * Filters whether or not the specified user has a given capability on a given site.
329
+ *
330
+ * @since 2.7.0
331
+ *
332
+ * @param bool $retval Whether or not the current user has the capability.
333
+ * @param int $user_id
334
+ * @param string $capability The capability being checked for.
335
+ * @param int $site_id Site ID. Defaults to the BP root blog.
336
  * @param array $args Array of extra arguments passed.
337
  */
338
+ $retval = (bool) apply_filters( 'bp_user_can', $retval, $user_id, $capability, $site_id, $args );
339
+
340
+ if ( $switched ) {
341
+ restore_current_blog();
342
+ }
343
+
344
+ return $retval;
345
  }
346
 
347
  /**
bp-core/bp-core-catchuri.php CHANGED
@@ -210,13 +210,27 @@ function bp_core_set_uri_globals() {
210
  }
211
 
212
  // URLs with BP_ENABLE_ROOT_PROFILES enabled won't be caught above.
213
- if ( empty( $matches ) && bp_core_enable_root_profiles() ) {
214
 
215
  // Switch field based on compat.
216
  $field = bp_is_username_compatibility_mode() ? 'login' : 'slug';
217
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  // Make sure there's a user corresponding to $bp_uri[0].
219
- if ( !empty( $bp->pages->members ) && !empty( $bp_uri[0] ) && $root_profile = get_user_by( $field, $bp_uri[0] ) ) {
220
 
221
  // Force BP to recognize that this is a members page.
222
  $matches[] = 1;
@@ -272,6 +286,10 @@ function bp_core_set_uri_globals() {
272
 
273
  // Are we viewing a specific user?
274
  if ( $after_member_slug ) {
 
 
 
 
275
  // If root profile, we've already queried for the user.
276
  if ( $root_profile instanceof WP_User ) {
277
  $bp->displayed_user->id = $root_profile->ID;
@@ -438,6 +456,17 @@ function bp_core_load_template( $templates ) {
438
  * @param array $filtered_templates Array of templates to attempt to load.
439
  */
440
  $located_template = apply_filters( 'bp_located_template', $template, $filtered_templates );
 
 
 
 
 
 
 
 
 
 
 
441
  if ( !empty( $located_template ) ) {
442
  // Template was located, lets set this as a valid page and not a 404.
443
  status_header( 200 );
@@ -516,6 +545,48 @@ function bp_core_catch_profile_uri() {
516
  }
517
  }
518
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  /**
520
  * Catch unauthorized access to certain BuddyPress pages and redirect accordingly.
521
  *
@@ -566,9 +637,9 @@ function bp_core_no_access( $args = '' ) {
566
  $redirect_url .= $_SERVER['REQUEST_URI'];
567
 
568
  $defaults = array(
569
- 'mode' => 2, // 1 = $root, 2 = wp-login.php
570
- 'redirect' => $redirect_url, // the URL you get redirected to when a user successfully logs in
571
- 'root' => bp_get_root_domain(), // the landing page you get redirected to when a user doesn't have access
572
  'message' => __( 'You must log in to access the page you requested.', 'buddypress' )
573
  );
574
 
@@ -585,7 +656,7 @@ function bp_core_no_access( $args = '' ) {
585
  extract( $r, EXTR_SKIP );
586
 
587
  /*
588
- * @ignore Ignore these filters and use 'bp_core_no_access' above
589
  */
590
  $mode = apply_filters( 'bp_no_access_mode', $mode, $root, $redirect, $message );
591
  $redirect = apply_filters( 'bp_no_access_redirect', $redirect, $root, $message, $mode );
@@ -595,7 +666,7 @@ function bp_core_no_access( $args = '' ) {
595
 
596
  switch ( $mode ) {
597
 
598
- // Option to redirect to wp-login.php
599
  // Error message is displayed with bp_core_no_access_wp_login_error().
600
  case 2 :
601
  if ( !empty( $redirect ) ) {
@@ -606,7 +677,7 @@ function bp_core_no_access( $args = '' ) {
606
 
607
  break;
608
 
609
- // Redirect to root with "redirect_to" parameter
610
  // Error message is displayed with bp_core_add_message().
611
  case 1 :
612
  default :
@@ -627,16 +698,18 @@ function bp_core_no_access( $args = '' ) {
627
  }
628
 
629
  /**
630
- * Add an error message to wp-login.php.
631
- *
632
- * Hooks into the "bpnoaccess" action defined in bp_core_no_access().
633
  *
634
  * @since 1.5.0
 
635
  *
636
- * @global string $error Error message to pass to wp-login.php.
 
637
  */
638
- function bp_core_no_access_wp_login_error() {
639
- global $error;
 
 
640
 
641
  /**
642
  * Filters the error message for wp-login.php when needing to log in before accessing.
@@ -646,12 +719,27 @@ function bp_core_no_access_wp_login_error() {
646
  * @param string $value Error message to display.
647
  * @param string $value URL to redirect user to after successful login.
648
  */
649
- $error = apply_filters( 'bp_wp_login_error', __( 'You must log in to access the page you requested.', 'buddypress' ), $_REQUEST['redirect_to'] );
650
 
651
- // Shake shake shake!.
652
- add_action( 'login_head', 'wp_shake_js', 12 );
 
653
  }
654
- add_action( 'login_form_bpnoaccess', 'bp_core_no_access_wp_login_error' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
 
656
  /**
657
  * Canonicalize BuddyPress URLs.
@@ -667,8 +755,6 @@ add_action( 'login_form_bpnoaccess', 'bp_core_no_access_wp_login_error' );
667
  * @see BP_Members_Component::setup_globals() where
668
  * $bp->canonical_stack['base_url'] and ['component'] may be set.
669
  * @see bp_core_new_nav_item() where $bp->canonical_stack['action'] may be set.
670
- * @uses bp_get_canonical_url()
671
- * @uses bp_get_requested_url()
672
  */
673
  function bp_redirect_canonical() {
674
 
@@ -738,8 +824,6 @@ function bp_rel_canonical() {
738
  *
739
  * @since 1.6.0
740
  *
741
- * @uses apply_filters() Filter bp_get_canonical_url to modify return value.
742
- *
743
  * @param array $args {
744
  * Optional array of arguments.
745
  * @type bool $include_query_args Whether to include current URL arguments
@@ -768,11 +852,14 @@ function bp_get_canonical_url( $args = array() ) {
768
  if ( 'page' == get_option( 'show_on_front' ) && $page_on_front = (int) get_option( 'page_on_front' ) ) {
769
  $front_page_component = array_search( $page_on_front, bp_core_get_directory_page_ids() );
770
 
771
- // If requesting the front page component directory, canonical
772
- // URL is the front page. We detect whether we're detecting a
773
- // component *directory* by checking that bp_current_action()
774
- // is empty - ie, this not a single item or a feed.
775
- if ( false !== $front_page_component && bp_is_current_component( $front_page_component ) && ! bp_current_action() ) {
 
 
 
776
  $bp->canonical_stack['canonical_url'] = trailingslashit( bp_get_root_domain() );
777
 
778
  // Except when the front page is set to the registration page
@@ -874,8 +961,6 @@ function bp_get_requested_url() {
874
  * notice in future versions of BuddyPress.
875
  *
876
  * @since 1.6.0
877
- *
878
- * @uses bp_is_blog_page()
879
  */
880
  function _bp_maybe_remove_redirect_canonical() {
881
  if ( ! bp_is_blog_page() )
@@ -933,3 +1018,36 @@ function _bp_maybe_remove_rel_canonical() {
933
  }
934
  }
935
  add_action( 'wp_head', '_bp_maybe_remove_rel_canonical', 8 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
211
 
212
  // URLs with BP_ENABLE_ROOT_PROFILES enabled won't be caught above.
213
+ if ( empty( $matches ) && bp_core_enable_root_profiles() && ! empty( $bp_uri[0] ) ) {
214
 
215
  // Switch field based on compat.
216
  $field = bp_is_username_compatibility_mode() ? 'login' : 'slug';
217
 
218
+ /**
219
+ * Filter the portion of the URI that is the displayed user's slug.
220
+ *
221
+ * Eg. example.com/ADMIN (when root profiles is enabled)
222
+ * example.com/members/ADMIN (when root profiles isn't enabled)
223
+ *
224
+ * ADMIN would be the displayed user's slug.
225
+ *
226
+ * @since 2.6.0
227
+ *
228
+ * @param string $member_slug
229
+ */
230
+ $member_slug = apply_filters( 'bp_core_set_uri_globals_member_slug', $bp_uri[0] );
231
+
232
  // Make sure there's a user corresponding to $bp_uri[0].
233
+ if ( ! empty( $bp->pages->members ) && $root_profile = get_user_by( $field, $member_slug ) ) {
234
 
235
  // Force BP to recognize that this is a members page.
236
  $matches[] = 1;
286
 
287
  // Are we viewing a specific user?
288
  if ( $after_member_slug ) {
289
+
290
+ /** This filter is documented in bp-core/bp-core-catchuri.php */
291
+ $after_member_slug = apply_filters( 'bp_core_set_uri_globals_member_slug', $after_member_slug );
292
+
293
  // If root profile, we've already queried for the user.
294
  if ( $root_profile instanceof WP_User ) {
295
  $bp->displayed_user->id = $root_profile->ID;
456
  * @param array $filtered_templates Array of templates to attempt to load.
457
  */
458
  $located_template = apply_filters( 'bp_located_template', $template, $filtered_templates );
459
+
460
+ /*
461
+ * If current page is an embed, wipe out bp-default template.
462
+ *
463
+ * Wiping out the bp-default template allows WordPress to use their special
464
+ * embed template, which is what we want.
465
+ */
466
+ if ( function_exists( 'is_embed' ) && is_embed() ) {
467
+ $located_template = '';
468
+ }
469
+
470
  if ( !empty( $located_template ) ) {
471
  // Template was located, lets set this as a valid page and not a 404.
472
  status_header( 200 );
545
  }
546
  }
547
 
548
+ /**
549
+ * Members user shortlink redirector.
550
+ *
551
+ * Redirects x.com/members/me/* to x.com/members/{LOGGED_IN_USER_SLUG}/*
552
+ *
553
+ * @since 2.6.0
554
+ *
555
+ * @param string $member_slug The current member slug.
556
+ * @return string $member_slug The current member slug.
557
+ */
558
+ function bp_core_members_shortlink_redirector( $member_slug ) {
559
+
560
+ /**
561
+ * Shortlink slug to redirect to logged-in user.
562
+ *
563
+ * The x.com/members/me/* url will redirect to x.com/members/{LOGGED_IN_USER_SLUG}/*
564
+ *
565
+ * @since 2.6.0
566
+ *
567
+ * @param string $slug Defaults to 'me'.
568
+ */
569
+ $me_slug = apply_filters( 'bp_core_members_shortlink_slug', 'me' );
570
+
571
+ // Check if we're on our special shortlink slug. If not, bail.
572
+ if ( $me_slug !== $member_slug ) {
573
+ return $member_slug;
574
+ }
575
+
576
+ // If logged out, redirect user to login.
577
+ if ( false === is_user_logged_in() ) {
578
+ // Add our login redirector hook.
579
+ add_action( 'template_redirect', 'bp_core_no_access', 0 );
580
+
581
+ return $member_slug;
582
+ }
583
+
584
+ $user = wp_get_current_user();
585
+
586
+ return bp_core_get_username( $user->ID, $user->user_nicename, $user->user_login );
587
+ }
588
+ add_filter( 'bp_core_set_uri_globals_member_slug', 'bp_core_members_shortlink_redirector' );
589
+
590
  /**
591
  * Catch unauthorized access to certain BuddyPress pages and redirect accordingly.
592
  *
637
  $redirect_url .= $_SERVER['REQUEST_URI'];
638
 
639
  $defaults = array(
640
+ 'mode' => 2, // 1 = $root, 2 = wp-login.php.
641
+ 'redirect' => $redirect_url, // the URL you get redirected to when a user successfully logs in.
642
+ 'root' => bp_get_root_domain(), // the landing page you get redirected to when a user doesn't have access.
643
  'message' => __( 'You must log in to access the page you requested.', 'buddypress' )
644
  );
645
 
656
  extract( $r, EXTR_SKIP );
657
 
658
  /*
659
+ * @ignore Ignore these filters and use 'bp_core_no_access' above.
660
  */
661
  $mode = apply_filters( 'bp_no_access_mode', $mode, $root, $redirect, $message );
662
  $redirect = apply_filters( 'bp_no_access_redirect', $redirect, $root, $message, $mode );
666
 
667
  switch ( $mode ) {
668
 
669
+ // Option to redirect to wp-login.php.
670
  // Error message is displayed with bp_core_no_access_wp_login_error().
671
  case 2 :
672
  if ( !empty( $redirect ) ) {
677
 
678
  break;
679
 
680
+ // Redirect to root with "redirect_to" parameter.
681
  // Error message is displayed with bp_core_add_message().
682
  case 1 :
683
  default :
698
  }
699
 
700
  /**
701
+ * Add a custom BuddyPress no access error message to wp-login.php.
 
 
702
  *
703
  * @since 1.5.0
704
+ * @since 2.7.0 Hook moved to 'wp_login_errors' made available since WP 3.6.0.
705
  *
706
+ * @param WP_Error $errors Current error container.
707
+ * @return WP_Error
708
  */
709
+ function bp_core_no_access_wp_login_error( $errors ) {
710
+ if ( empty( $_GET['action'] ) || 'bpnoaccess' !== $_GET['action'] ) {
711
+ return $errors;
712
+ }
713
 
714
  /**
715
  * Filters the error message for wp-login.php when needing to log in before accessing.
719
  * @param string $value Error message to display.
720
  * @param string $value URL to redirect user to after successful login.
721
  */
722
+ $message = apply_filters( 'bp_wp_login_error', __( 'You must log in to access the page you requested.', 'buddypress' ), $_REQUEST['redirect_to'] );
723
 
724
+ $errors->add( 'bp_no_access', $message );
725
+
726
+ return $errors;
727
  }
728
+ add_filter( 'wp_login_errors', 'bp_core_no_access_wp_login_error' );
729
+
730
+ /**
731
+ * Add our custom error code to WP login's shake error codes.
732
+ *
733
+ * @since 2.7.0
734
+ *
735
+ * @param array $codes Array of WP error codes.
736
+ * @return array
737
+ */
738
+ function bp_core_login_filter_shake_codes( $codes ) {
739
+ $codes[] = 'bp_no_access';
740
+ return $codes;
741
+ }
742
+ add_filter( 'shake_error_codes', 'bp_core_login_filter_shake_codes' );
743
 
744
  /**
745
  * Canonicalize BuddyPress URLs.
755
  * @see BP_Members_Component::setup_globals() where
756
  * $bp->canonical_stack['base_url'] and ['component'] may be set.
757
  * @see bp_core_new_nav_item() where $bp->canonical_stack['action'] may be set.
 
 
758
  */
759
  function bp_redirect_canonical() {
760
 
824
  *
825
  * @since 1.6.0
826
  *
 
 
827
  * @param array $args {
828
  * Optional array of arguments.
829
  * @type bool $include_query_args Whether to include current URL arguments
852
  if ( 'page' == get_option( 'show_on_front' ) && $page_on_front = (int) get_option( 'page_on_front' ) ) {
853
  $front_page_component = array_search( $page_on_front, bp_core_get_directory_page_ids() );
854
 
855
+ /*
856
+ * If requesting the front page component directory, canonical
857
+ * URL is the front page. We detect whether we're detecting a
858
+ * component *directory* by checking that bp_current_action()
859
+ * is empty - ie, this not a single item, a feed, or an item
860
+ * type directory.
861
+ */
862
+ if ( false !== $front_page_component && bp_is_current_component( $front_page_component ) && ! bp_current_action() && ! bp_get_current_member_type() ) {
863
  $bp->canonical_stack['canonical_url'] = trailingslashit( bp_get_root_domain() );
864
 
865
  // Except when the front page is set to the registration page
961
  * notice in future versions of BuddyPress.
962
  *
963
  * @since 1.6.0
 
 
964
  */
965
  function _bp_maybe_remove_redirect_canonical() {
966
  if ( ! bp_is_blog_page() )
1018
  }
1019
  }
1020
  add_action( 'wp_head', '_bp_maybe_remove_rel_canonical', 8 );
1021
+
1022
+ /**
1023
+ * Stop WordPress performing a DB query for its main loop.
1024
+ *
1025
+ * As of WordPress 4.6, it is possible to bypass the main WP_Query entirely.
1026
+ * This saves us one unnecessary database query! :)
1027
+ *
1028
+ * @since 2.7.0
1029
+ *
1030
+ * @param null $retval Current return value for filter.
1031
+ * @param WP_Query $query Current WordPress query object.
1032
+ * @return null|array
1033
+ */
1034
+ function bp_core_filter_wp_query( $retval, $query ) {
1035
+ if ( ! $query->is_main_query() ) {
1036
+ return $retval;
1037
+ }
1038
+
1039
+ /*
1040
+ * If not on a BP single page, bail.
1041
+ * Too early to use bp_is_single_item(), so use BP conditionals.
1042
+ */
1043
+ if ( false === ( bp_is_group() || bp_is_user() || bp_is_single_activity() ) ) {
1044
+ return $retval;
1045
+ }
1046
+
1047
+ // Set default properties as recommended in the 'posts_pre_query' DocBlock.
1048
+ $query->found_posts = 0;
1049
+ $query->max_num_pages = 0;
1050
+
1051
+ // Return something other than a null value to bypass WP_Query.
1052
+ return array();
1053
+ }
bp-core/bp-core-classes.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
- /**
3
- * Core component classes.
4
- *
5
- * @package BuddyPress
6
- * @subpackage Core
7
- * @since 1.0.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- require dirname( __FILE__ ) . '/classes/class-bp-user-query.php';
14
- require dirname( __FILE__ ) . '/classes/class-bp-core-user.php';
15
- require dirname( __FILE__ ) . '/classes/class-bp-date-query.php';
16
- require dirname( __FILE__ ) . '/classes/class-bp-core-notification.php';
17
- require dirname( __FILE__ ) . '/classes/class-bp-button.php';
18
- require dirname( __FILE__ ) . '/classes/class-bp-embed.php';
19
- require dirname( __FILE__ ) . '/classes/class-bp-walker-nav-menu.php';
20
- require dirname( __FILE__ ) . '/classes/class-bp-walker-nav-menu-checklist.php';
21
- require dirname( __FILE__ ) . '/classes/class-bp-suggestions.php';
22
- require dirname( __FILE__ ) . '/classes/class-bp-members-suggestions.php';
23
- require dirname( __FILE__ ) . '/classes/class-bp-recursive-query.php';
24
- require dirname( __FILE__ ) . '/classes/class-bp-core-sort-by-key-callback.php';
25
- require dirname( __FILE__ ) . '/classes/class-bp-media-extractor.php';
26
- require dirname( __FILE__ ) . '/classes/class-bp-attachment.php';
27
- require dirname( __FILE__ ) . '/classes/class-bp-attachment-avatar.php';
28
- require dirname( __FILE__ ) . '/classes/class-bp-attachment-cover-image.php';
29
- require dirname( __FILE__ ) . '/classes/class-bp-email-recipient.php';
30
- require dirname( __FILE__ ) . '/classes/class-bp-email.php';
31
- require dirname( __FILE__ ) . '/classes/class-bp-email-delivery.php';
32
- require dirname( __FILE__ ) . '/classes/class-bp-phpmailer.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core/bp-core-component.php CHANGED
@@ -10,4 +10,6 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- require dirname( __FILE__ ) . '/classes/class-bp-component.php';
 
 
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
+ if ( ! class_exists( 'BP_Component' ) ) {
14
+ require dirname( __FILE__ ) . '/classes/class-bp-component.php';
15
+ }
bp-core/bp-core-cssjs.php CHANGED
@@ -19,35 +19,79 @@ function bp_core_register_common_scripts() {
19
  $min = bp_core_get_minified_asset_suffix();
20
  $url = buddypress()->plugin_url . 'bp-core/js/';
21
 
22
- /**
23
- * Filters the BuddyPress Core javascript files to register.
24
  *
25
- * @since 2.1.0
26
  *
27
- * @param array $value Array of javascript file information to register.
 
28
  */
29
- $scripts = apply_filters( 'bp_core_register_common_scripts', array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
 
 
31
  // Legacy.
32
- 'bp-confirm' => array( 'file' => "{$url}confirm{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
33
  'bp-widget-members' => array( 'file' => "{$url}widget-members{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
34
- 'bp-jquery-query' => array( 'file' => "{$url}jquery-query{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
35
- 'bp-jquery-cookie' => array( 'file' => "{$url}jquery-cookie{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
36
- 'bp-jquery-scroll-to' => array( 'file' => "{$url}jquery-scroll-to{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
37
 
38
- // 2.1
39
- 'jquery-caret' => array( 'file' => "{$url}jquery.caret{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => true ),
40
- 'jquery-atwho' => array( 'file' => "{$url}jquery.atwho{$min}.js", 'dependencies' => array( 'jquery', 'jquery-caret' ), 'footer' => true ),
41
 
42
- // 2.3
43
  'bp-plupload' => array( 'file' => "{$url}bp-plupload{$min}.js", 'dependencies' => array( 'plupload', 'jquery', 'json2', 'wp-backbone' ), 'footer' => true ),
44
  'bp-avatar' => array( 'file' => "{$url}avatar{$min}.js", 'dependencies' => array( 'jcrop' ), 'footer' => true ),
45
  'bp-webcam' => array( 'file' => "{$url}webcam{$min}.js", 'dependencies' => array( 'bp-avatar' ), 'footer' => true ),
46
 
47
- // 2.4
48
  'bp-cover-image' => array( 'file' => "{$url}cover-image{$min}.js", 'dependencies' => array(), 'footer' => true ),
49
 
50
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  $version = bp_get_version();
53
  foreach ( $scripts as $id => $script ) {
@@ -106,7 +150,7 @@ add_action( 'bp_enqueue_scripts', 'bp_core_register_common_styles', 1 );
106
  add_action( 'bp_admin_enqueue_scripts', 'bp_core_register_common_styles', 1 );
107
 
108
  /**
109
- * Load the JS for "Are you sure?" .confirm links.
110
  *
111
  * @since 1.1.0
112
  */
@@ -128,7 +172,7 @@ add_action( 'bp_admin_enqueue_scripts', 'bp_core_confirmation_js' );
128
  /**
129
  * Enqueues the css and js required by the Avatar UI.
130
  *
131
- * @since 2.3.0
132
  */
133
  function bp_core_avatar_scripts() {
134
  if ( ! bp_avatar_is_front_edit() ) {
@@ -148,7 +192,7 @@ add_action( 'bp_enqueue_scripts', 'bp_core_avatar_scripts' );
148
  /**
149
  * Enqueues the css and js required by the Cover Image UI.
150
  *
151
- * @since 2.4.0
152
  */
153
  function bp_core_cover_image_scripts() {
154
  if ( ! bp_attachments_cover_image_is_edit() ) {
@@ -339,8 +383,6 @@ function bp_core_ajax_url() {
339
  *
340
  * @since 2.0.0
341
  *
342
- * @uses apply_filters() to allow other component to load extra dependencies.
343
- *
344
  * @return array The JavaScript dependencies.
345
  */
346
  function bp_core_get_js_dependencies() {
@@ -363,11 +405,11 @@ function bp_core_get_js_dependencies() {
363
  }
364
 
365
  /**
366
- * Add inline css to display the component's single item cover image
367
  *
368
  * @since 2.4.0
369
  *
370
- * @param bool $return True to get the inline css.
371
  * @return string|array the inline css or an associative array containing
372
  * the css rules and the style handle
373
  */
@@ -462,3 +504,84 @@ function bp_add_cover_image_inline_css( $return = false ) {
462
  }
463
  }
464
  add_action( 'bp_enqueue_scripts', 'bp_add_cover_image_inline_css', 11 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  $min = bp_core_get_minified_asset_suffix();
20
  $url = buddypress()->plugin_url . 'bp-core/js/';
21
 
22
+ /*
23
+ * Moment.js locale.
24
  *
25
+ * Try to map current WordPress locale to a moment.js locale file for loading.
26
  *
27
+ * eg. French (France) locale for WP is fr_FR. Here, we try to find fr-fr.js
28
+ * (this file doesn't exist).
29
  */
30
+ $locale = sanitize_file_name( strtolower( get_locale() ) );
31
+ $locale = str_replace( '_', '-', $locale );
32
+ if ( file_exists( buddypress()->core->path . "bp-core/js/vendor/moment-js/locale/{$locale}{$min}.js" ) ) {
33
+ $moment_locale_url = $url . "vendor/moment-js/locale/{$locale}{$min}.js";
34
+
35
+ /*
36
+ * Try to find the short-form locale.
37
+ *
38
+ * eg. French (France) locale for WP is fr_FR. Here, we try to find fr.js
39
+ * (this exists).
40
+ */
41
+ } else {
42
+ $locale = substr( $locale, 0, strpos( $locale, '-' ) );
43
+ if ( file_exists( buddypress()->core->path . "bp-core/js/vendor/moment-js/locale/{$locale}{$min}.js" ) ) {
44
+ $moment_locale_url = $url . "vendor/moment-js/locale/{$locale}{$min}.js";
45
+ }
46
+ }
47
 
48
+ // Set up default scripts to register.
49
+ $scripts = array(
50
  // Legacy.
51
+ 'bp-confirm' => array( 'file' => "{$url}confirm{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
52
  'bp-widget-members' => array( 'file' => "{$url}widget-members{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
53
+ 'bp-jquery-query' => array( 'file' => "{$url}jquery-query{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
54
+ 'bp-jquery-cookie' => array( 'file' => "{$url}vendor/jquery-cookie{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
55
+ 'bp-jquery-scroll-to' => array( 'file' => "{$url}vendor/jquery-scroll-to{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => false ),
56
 
57
+ // Version 2.1.
58
+ 'jquery-caret' => array( 'file' => "{$url}vendor/jquery.caret{$min}.js", 'dependencies' => array( 'jquery' ), 'footer' => true ),
59
+ 'jquery-atwho' => array( 'file' => "{$url}vendor/jquery.atwho{$min}.js", 'dependencies' => array( 'jquery', 'jquery-caret' ), 'footer' => true ),
60
 
61
+ // Version 2.3.
62
  'bp-plupload' => array( 'file' => "{$url}bp-plupload{$min}.js", 'dependencies' => array( 'plupload', 'jquery', 'json2', 'wp-backbone' ), 'footer' => true ),
63
  'bp-avatar' => array( 'file' => "{$url}avatar{$min}.js", 'dependencies' => array( 'jcrop' ), 'footer' => true ),
64
  'bp-webcam' => array( 'file' => "{$url}webcam{$min}.js", 'dependencies' => array( 'bp-avatar' ), 'footer' => true ),
65
 
66
+ // Version 2.4.
67
  'bp-cover-image' => array( 'file' => "{$url}cover-image{$min}.js", 'dependencies' => array(), 'footer' => true ),
68
 
69
+ // Version 2.7.
70
+ 'bp-moment' => array( 'file' => "{$url}vendor/moment-js/moment{$min}.js", 'dependencies' => array(), 'footer' => true ),
71
+ 'bp-livestamp' => array( 'file' => "{$url}vendor/livestamp{$min}.js", 'dependencies' => array( 'jquery', 'bp-moment' ), 'footer' => true ),
72
+ );
73
+
74
+ // Version 2.7 - Add Moment.js locale to our $scripts array if we found one.
75
+ if ( isset( $moment_locale_url ) ) {
76
+ $scripts['bp-moment-locale'] = array( 'file' => esc_url( $moment_locale_url ), 'dependencies' => array( 'bp-moment' ), 'footer' => true );
77
+ }
78
+
79
+ /**
80
+ * Filters the BuddyPress Core javascript files to register.
81
+ *
82
+ * Default handles include 'bp-confirm', 'bp-widget-members',
83
+ * 'bp-jquery-query', 'bp-jquery-cookie', and 'bp-jquery-scroll-to'.
84
+ *
85
+ * @since 2.1.0 'jquery-caret', 'jquery-atwho' added.
86
+ * @since 2.3.0 'bp-plupload', 'bp-avatar', 'bp-webcam' added.
87
+ * @since 2.4.0 'bp-cover-image' added.
88
+ * @since 2.7.0 'bp-moment', 'bp-livestamp' added.
89
+ * 'bp-moment-locale' is added conditionally if a moment.js locale file is found.
90
+ *
91
+ * @param array $value Array of javascript file information to register.
92
+ */
93
+ $scripts = apply_filters( 'bp_core_register_common_scripts', $scripts );
94
+
95
 
96
  $version = bp_get_version();
97
  foreach ( $scripts as $id => $script ) {
150
  add_action( 'bp_admin_enqueue_scripts', 'bp_core_register_common_styles', 1 );
151
 
152
  /**
153
+ * Load the JS for "Are you sure?" confirm links.
154
  *
155
  * @since 1.1.0
156
  */
172
  /**
173
  * Enqueues the css and js required by the Avatar UI.
174
  *
175
+ * @since 2.3.0
176
  */
177
  function bp_core_avatar_scripts() {
178
  if ( ! bp_avatar_is_front_edit() ) {
192
  /**
193
  * Enqueues the css and js required by the Cover Image UI.
194
  *
195
+ * @since 2.4.0
196
  */
197
  function bp_core_cover_image_scripts() {
198
  if ( ! bp_attachments_cover_image_is_edit() ) {
383
  *
384
  * @since 2.0.0
385
  *
 
 
386
  * @return array The JavaScript dependencies.
387
  */
388
  function bp_core_get_js_dependencies() {
405
  }
406
 
407
  /**
408
+ * Add inline css to display the component's single item cover image.
409
  *
410
  * @since 2.4.0
411
  *
412
+ * @param bool $return True to get the inline css.
413
  * @return string|array the inline css or an associative array containing
414
  * the css rules and the style handle
415
  */
504
  }
505
  }
506
  add_action( 'bp_enqueue_scripts', 'bp_add_cover_image_inline_css', 11 );
507
+
508
+ /**
509
+ * Enqueues livestamp.js on BuddyPress pages.
510
+ *
511
+ * @since 2.7.0
512
+ */
513
+ function bp_core_add_livestamp() {
514
+ if ( ! is_buddypress() ) {
515
+ return;
516
+ }
517
+
518
+ bp_core_enqueue_livestamp();
519
+ }
520
+ add_action( 'bp_enqueue_scripts', 'bp_core_add_livestamp' );
521
+
522
+ /**
523
+ * Enqueue and localize livestamp.js script.
524
+ *
525
+ * @since 2.7.0
526
+ */
527
+ function bp_core_enqueue_livestamp() {
528
+ // If bp-livestamp isn't enqueued, do it now.
529
+ if ( wp_script_is( 'bp-livestamp' ) ) {
530
+ return;
531
+ }
532
+
533
+ /*
534
+ * Only enqueue Moment.js locale if we registered it in
535
+ * bp_core_register_common_scripts().
536
+ */
537
+ if ( wp_script_is( 'bp-moment-locale', 'registered' ) ) {
538
+ wp_enqueue_script( 'bp-moment-locale' );
539
+
540
+ if ( function_exists( 'wp_add_inline_script' ) ) {
541
+ wp_add_inline_script ( 'bp-livestamp', bp_core_moment_js_config() );
542
+ } else {
543
+ add_action( 'wp_footer', '_bp_core_moment_js_config_footer', 20 );
544
+ }
545
+ }
546
+
547
+ wp_enqueue_script( 'bp-livestamp' );
548
+ }
549
+
550
+ /**
551
+ * Return moment.js config.
552
+ *
553
+ * @since 2.7.0
554
+ *
555
+ * @return string
556
+ */
557
+ function bp_core_moment_js_config() {
558
+ // Grab the locale from the enqueued JS.
559
+ $moment_locale = wp_scripts()->query( 'bp-moment-locale' );
560
+ $moment_locale = substr( $moment_locale->src, strpos( $moment_locale->src, '/moment-js/locale/' ) + 18 );
561
+ $moment_locale = str_replace( '.js', '', $moment_locale );
562
+
563
+ $inline_js = <<<EOD
564
+ jQuery(function() {
565
+ moment.locale( '{$moment_locale}' );
566
+ });
567
+ EOD;
568
+
569
+ return $inline_js;
570
+ }
571
+
572
+ /**
573
+ * Print moment.js config in page footer.
574
+ *
575
+ * Will be removed once we set our minimum version of WP 4.5.
576
+ *
577
+ * @since 2.7.0
578
+ *
579
+ * @access private
580
+ */
581
+ function _bp_core_moment_js_config_footer() {
582
+ if ( ! wp_script_is( 'bp-moment-locale' ) ) {
583
+ return;
584
+ }
585
+
586
+ printf( '<script>%s</script>', bp_core_moment_js_config() );
587
+ }
bp-core/bp-core-customizer-email.php CHANGED
@@ -2,10 +2,9 @@
2
  /**
3
  * BuddyPress Customizer implementation for email.
4
  *
5
- * @since 2.5.0
6
- *
7
  * @package BuddyPress
8
  * @subpackage Core
 
9
  */
10
 
11
  // Exit if accessed directly.
@@ -44,11 +43,6 @@ function bp_email_init_customizer( WP_Customize_Manager $wp_customize ) {
44
  $wp_customize->add_setting( $setting_id, $args );
45
  }
46
 
47
- /**
48
- * BP_Customizer_Control_Range class.
49
- */
50
- require_once dirname( __FILE__ ) . '/classes/class-bp-customizer-control-range.php';
51
-
52
  /**
53
  * Fires to let plugins register extra Customizer controls for emails.
54
  *
@@ -63,7 +57,6 @@ function bp_email_init_customizer( WP_Customize_Manager $wp_customize ) {
63
  $wp_customize->add_control( new $args['class']( $wp_customize, $control_id, $args ) );
64
  }
65
 
66
-
67
  /*
68
  * Hook actions/filters for further configuration.
69
  */
@@ -88,7 +81,7 @@ function bp_email_init_customizer( WP_Customize_Manager $wp_customize ) {
88
  true
89
  );
90
 
91
- // Include the preview loading style
92
  add_action( 'wp_footer', array( $wp_customize, 'customize_preview_loading_style' ) );
93
  }
94
  }
@@ -110,7 +103,7 @@ function bp_is_email_customizer() {
110
  *
111
  * @since 2.5.0
112
  *
113
- * @param $active Whether the Customizer section is active.
114
  * @param WP_Customize_Section $section {@see WP_Customize_Section} instance.
115
  * @return bool
116
  */
@@ -192,7 +185,7 @@ function bp_email_get_customizer_settings() {
192
  'bp_email_options[header_text_size]' => array(
193
  'capability' => 'bp_moderate',
194
  'default' => $defaults['header_text_size'],
195
- 'sanitize_callback' => 'intval',
196
  'transport' => 'postMessage',
197
  'type' => 'option',
198
  ),
@@ -220,7 +213,7 @@ function bp_email_get_customizer_settings() {
220
  'bp_email_options[body_text_size]' => array(
221
  'capability' => 'bp_moderate',
222
  'default' => $defaults['body_text_size'],
223
- 'sanitize_callback' => 'intval',
224
  'transport' => 'postMessage',
225
  'type' => 'option',
226
  ),
@@ -248,7 +241,7 @@ function bp_email_get_customizer_settings() {
248
  'bp_email_options[footer_text_size]' => array(
249
  'capability' => 'bp_moderate',
250
  'default' => $defaults['footer_text_size'],
251
- 'sanitize_callback' => 'intval',
252
  'transport' => 'postMessage',
253
  'type' => 'option',
254
  ),
2
  /**
3
  * BuddyPress Customizer implementation for email.
4
  *
 
 
5
  * @package BuddyPress
6
  * @subpackage Core
7
+ * @since 2.5.0
8
  */
9
 
10
  // Exit if accessed directly.
43
  $wp_customize->add_setting( $setting_id, $args );
44
  }
45
 
 
 
 
 
 
46
  /**
47
  * Fires to let plugins register extra Customizer controls for emails.
48
  *
57
  $wp_customize->add_control( new $args['class']( $wp_customize, $control_id, $args ) );
58
  }
59
 
 
60
  /*
61
  * Hook actions/filters for further configuration.
62
  */
81
  true
82
  );
83
 
84
+ // Include the preview loading style.
85
  add_action( 'wp_footer', array( $wp_customize, 'customize_preview_loading_style' ) );
86
  }
87
  }
103
  *
104
  * @since 2.5.0
105
  *
106
+ * @param bool $active Whether the Customizer section is active.
107
  * @param WP_Customize_Section $section {@see WP_Customize_Section} instance.
108
  * @return bool
109
  */
185
  'bp_email_options[header_text_size]' => array(
186
  'capability' => 'bp_moderate',
187
  'default' => $defaults['header_text_size'],
188
+ 'sanitize_callback' => 'absint',
189
  'transport' => 'postMessage',
190
  'type' => 'option',
191
  ),
213
  'bp_email_options[body_text_size]' => array(
214
  'capability' => 'bp_moderate',
215
  'default' => $defaults['body_text_size'],
216
+ 'sanitize_callback' => 'absint',
217
  'transport' => 'postMessage',
218
  'type' => 'option',
219
  ),
241
  'bp_email_options[footer_text_size]' => array(
242
  'capability' => 'bp_moderate',
243
  'default' => $defaults['footer_text_size'],
244
+ 'sanitize_callback' => 'absint',
245
  'transport' => 'postMessage',
246
  'type' => 'option',
247
  ),
bp-core/bp-core-dependency.php CHANGED
@@ -13,8 +13,6 @@
13
  * The following functions are wrappers for hooks, allowing them to be
14
  * manually called and/or piggy-backed on top of other hooks if needed.
15
  *
16
- * @todo use anonymous functions when PHP minimum requirement allows (5.3)
17
- *
18
  * @package BuddyPress
19
  * @subpackage Core
20
  * @since 1.7.0
@@ -140,7 +138,7 @@ function bp_setup_admin_bar() {
140
  *
141
  * @since 1.5.0
142
  */
143
- do_action( 'bp_setup_admin_bar' );
144
  }
145
  }
146
 
@@ -207,24 +205,13 @@ function bp_setup_cache_groups() {
207
  /**
208
  * Set up the currently logged-in user.
209
  *
210
- * We white-list the WordPress customizer which purposely loads the user early.
211
- *
212
  * @since 1.7.0
213
  *
214
  * @link https://buddypress.trac.wordpress.org/ticket/6046
215
  * @link https://core.trac.wordpress.org/ticket/24169
216
- *
217
- * @uses did_action() To make sure the user isn't loaded out of order.
218
- * @uses do_action() Calls 'bp_setup_current_user'.
219
  */
220
  function bp_setup_current_user() {
221
 
222
- // If the current user is being setup before the "init" action has fired,
223
- // strange (and difficult to debug) role/capability issues will occur.
224
- if ( ! isset( $GLOBALS['wp_customize'] ) && ! did_action( 'after_setup_theme' ) ) {
225
- _doing_it_wrong( __FUNCTION__, __( 'The current user is being initialized without using $wp->init().', 'buddypress' ), '1.7' );
226
- }
227
-
228
  /**
229
  * Fires to set up the current user setup process.
230
  *
@@ -248,6 +235,21 @@ function bp_init() {
248
  do_action( 'bp_init' );
249
  }
250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  /**
252
  * Fire the 'bp_customize_register' action when the Customizer has loaded,
253
  * allowing scripts and styles to be initialized.
@@ -356,7 +358,7 @@ function bp_widgets_init() {
356
  *
357
  * @since 1.6.0
358
  */
359
- do_action ( 'bp_widgets_init' );
360
  }
361
 
362
  /**
@@ -373,7 +375,7 @@ function bp_head() {
373
  *
374
  * @since 1.6.0
375
  */
376
- do_action ( 'bp_head' );
377
  }
378
 
379
  /** Theme Permissions *********************************************************/
@@ -386,8 +388,6 @@ function bp_head() {
386
  * who do not have the proper permission to access certain content.
387
  *
388
  * @since 1.6.0
389
- *
390
- * @uses do_action()
391
  */
392
  function bp_template_redirect() {
393
 
@@ -407,8 +407,6 @@ function bp_template_redirect() {
407
  * The main action used registering theme directories.
408
  *
409
  * @since 1.5.0
410
- *
411
- * @uses do_action()
412
  */
413
  function bp_register_theme_directory() {
414
 
@@ -428,8 +426,6 @@ function bp_register_theme_directory() {
428
  * The main action used registering theme packages.
429
  *
430
  * @since 1.7.0
431
- *
432
- * @uses do_action()
433
  */
434
  function bp_register_theme_packages() {
435
 
@@ -445,8 +441,6 @@ function bp_register_theme_packages() {
445
  * Fire the 'bp_enqueue_scripts' action, where BP enqueues its CSS and JS.
446
  *
447
  * @since 1.6.0
448
- *
449
- * @uses do_action() Calls 'bp_enqueue_scripts'.
450
  */
451
  function bp_enqueue_scripts() {
452
 
@@ -455,15 +449,31 @@ function bp_enqueue_scripts() {
455
  *
456
  * @since 1.6.0
457
  */
458
- do_action ( 'bp_enqueue_scripts' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  }
460
 
461
  /**
462
  * Fire the 'bp_add_rewrite_tag' action, where BP adds its custom rewrite tags.
463
  *
464
  * @since 1.8.0
465
- *
466
- * @uses do_action() Calls 'bp_add_rewrite_tags'.
467
  */
468
  function bp_add_rewrite_tags() {
469
 
@@ -479,8 +489,6 @@ function bp_add_rewrite_tags() {
479
  * Fire the 'bp_add_rewrite_rules' action, where BP adds its custom rewrite rules.
480
  *
481
  * @since 1.9.0
482
- *
483
- * @uses do_action() Calls 'bp_add_rewrite_rules'.
484
  */
485
  function bp_add_rewrite_rules() {
486
 
@@ -496,8 +504,6 @@ function bp_add_rewrite_rules() {
496
  * Fire the 'bp_add_permastructs' action, where BP adds its BP-specific permalink structure.
497
  *
498
  * @since 1.9.0
499
- *
500
- * @uses do_action() Calls 'bp_add_permastructs'.
501
  */
502
  function bp_add_permastructs() {
503
 
@@ -516,8 +522,6 @@ function bp_add_permastructs() {
516
  * BuddyPress-specific functionality.
517
  *
518
  * @since 1.6.0
519
- *
520
- * @uses do_action() Calls 'bp_setup_theme'.
521
  */
522
  function bp_setup_theme() {
523
 
@@ -526,7 +530,7 @@ function bp_setup_theme() {
526
  *
527
  * @since 1.6.0
528
  */
529
- do_action ( 'bp_setup_theme' );
530
  }
531
 
532
  /**
@@ -540,8 +544,6 @@ function bp_setup_theme() {
540
  * before our theme compatibility layer kicks in.
541
  *
542
  * @since 1.6.0
543
- *
544
- * @uses do_action() Calls 'bp_after_setup_theme'.
545
  */
546
  function bp_after_setup_theme() {
547
 
@@ -550,7 +552,7 @@ function bp_after_setup_theme() {
550
  *
551
  * @since 1.7.0
552
  */
553
- do_action ( 'bp_after_setup_theme' );
554
  }
555
 
556
  /** Theme Compatibility Filter ************************************************/
@@ -608,8 +610,6 @@ function bp_login_redirect( $redirect_to = '', $redirect_to_raw = '', $user = fa
608
  *
609
  * @since 1.6.0
610
  *
611
- * @uses apply_filters()
612
- *
613
  * @param string $template See 'template_include'.
614
  * @return string Template file to use.
615
  */
@@ -630,8 +630,6 @@ function bp_template_include( $template = '' ) {
630
  *
631
  * @since 1.7.0
632
  *
633
- * @uses do_action() Calls 'bp_generate_rewrite_rules' with {@link WP_Rewrite}.
634
- *
635
  * @param WP_Rewrite $wp_rewrite See 'generate_rewrite_rules'.
636
  */
637
  function bp_generate_rewrite_rules( $wp_rewrite ) {
@@ -653,8 +651,6 @@ function bp_generate_rewrite_rules( $wp_rewrite ) {
653
  *
654
  * @since 1.7.0
655
  *
656
- * @uses apply_filters() Calls 'bp_allowed_themes' with the allowed themes list.
657
- *
658
  * @param array $themes The path of the template to include.
659
  * @return array
660
  */
@@ -676,8 +672,6 @@ function bp_allowed_themes( $themes ) {
676
  * The main action used for handling theme-side POST requests.
677
  *
678
  * @since 1.9.0
679
- *
680
- * @uses do_action()
681
  */
682
  function bp_post_request() {
683
 
@@ -720,8 +714,6 @@ function bp_post_request() {
720
  * The main action used for handling theme-side GET requests.
721
  *
722
  * @since 1.9.0
723
- *
724
- * @uses do_action()
725
  */
726
  function bp_get_request() {
727
 
13
  * The following functions are wrappers for hooks, allowing them to be
14
  * manually called and/or piggy-backed on top of other hooks if needed.
15
  *
 
 
16
  * @package BuddyPress
17
  * @subpackage Core
18
  * @since 1.7.0
138
  *
139
  * @since 1.5.0
140
  */
141
+ do_action( 'bp_setup_admin_bar', array() );
142
  }
143
  }
144
 
205
  /**
206
  * Set up the currently logged-in user.
207
  *
 
 
208
  * @since 1.7.0
209
  *
210
  * @link https://buddypress.trac.wordpress.org/ticket/6046
211
  * @link https://core.trac.wordpress.org/ticket/24169
 
 
 
212
  */
213
  function bp_setup_current_user() {
214
 
 
 
 
 
 
 
215
  /**
216
  * Fires to set up the current user setup process.
217
  *
235
  do_action( 'bp_init' );
236
  }
237
 
238
+ /**
239
+ * Fire the 'bp_rest_api_init' action, where BuddyPress registers REST API endpoints.
240
+ *
241
+ * @since 2.6.0
242
+ */
243
+ function bp_rest_api_init() {
244
+
245
+ /**
246
+ * Fires the 'bp_rest_api_init' function, where BuddyPress registers REST API endpoints.
247
+ *
248
+ * @since 2.6.0
249
+ */
250
+ do_action( 'bp_rest_api_init' );
251
+ }
252
+
253
  /**
254
  * Fire the 'bp_customize_register' action when the Customizer has loaded,
255
  * allowing scripts and styles to be initialized.
358
  *
359
  * @since 1.6.0
360
  */
361
+ do_action( 'bp_widgets_init' );
362
  }
363
 
364
  /**
375
  *
376
  * @since 1.6.0
377
  */
378
+ do_action( 'bp_head' );
379
  }
380
 
381
  /** Theme Permissions *********************************************************/
388
  * who do not have the proper permission to access certain content.
389
  *
390
  * @since 1.6.0
 
 
391
  */
392
  function bp_template_redirect() {
393
 
407
  * The main action used registering theme directories.
408
  *
409
  * @since 1.5.0
 
 
410
  */
411
  function bp_register_theme_directory() {
412
 
426
  * The main action used registering theme packages.
427
  *
428
  * @since 1.7.0
 
 
429
  */
430
  function bp_register_theme_packages() {
431
 
441
  * Fire the 'bp_enqueue_scripts' action, where BP enqueues its CSS and JS.
442
  *
443
  * @since 1.6.0
 
 
444
  */
445
  function bp_enqueue_scripts() {
446
 
449
  *
450
  * @since 1.6.0
451
  */
452
+ do_action( 'bp_enqueue_scripts' );
453
+ }
454
+
455
+ /**
456
+ * Fires the 'bp_enqueue_embed_scripts' action in the <head> for BP oEmbeds.
457
+ *
458
+ * @since 2.6.0
459
+ */
460
+ function bp_enqueue_embed_scripts() {
461
+ if ( ! is_buddypress() ) {
462
+ return;
463
+ }
464
+
465
+ /**
466
+ * Enqueue CSS and JS files for BuddyPress embeds.
467
+ *
468
+ * @since 2.6.0
469
+ */
470
+ do_action( 'bp_enqueue_embed_scripts' );
471
  }
472
 
473
  /**
474
  * Fire the 'bp_add_rewrite_tag' action, where BP adds its custom rewrite tags.
475
  *
476
  * @since 1.8.0
 
 
477
  */
478
  function bp_add_rewrite_tags() {
479
 
489
  * Fire the 'bp_add_rewrite_rules' action, where BP adds its custom rewrite rules.
490
  *
491
  * @since 1.9.0
 
 
492
  */
493
  function bp_add_rewrite_rules() {
494
 
504
  * Fire the 'bp_add_permastructs' action, where BP adds its BP-specific permalink structure.
505
  *
506
  * @since 1.9.0
 
 
507
  */
508
  function bp_add_permastructs() {
509
 
522
  * BuddyPress-specific functionality.
523
  *
524
  * @since 1.6.0
 
 
525
  */
526
  function bp_setup_theme() {
527
 
530
  *
531
  * @since 1.6.0
532
  */
533
+ do_action( 'bp_setup_theme' );
534
  }
535
 
536
  /**
544
  * before our theme compatibility layer kicks in.
545
  *
546
  * @since 1.6.0
 
 
547
  */
548
  function bp_after_setup_theme() {
549
 
552
  *
553
  * @since 1.7.0
554
  */
555
+ do_action( 'bp_after_setup_theme' );
556
  }
557
 
558
  /** Theme Compatibility Filter ************************************************/
610
  *
611
  * @since 1.6.0
612
  *
 
 
613
  * @param string $template See 'template_include'.
614
  * @return string Template file to use.
615
  */
630
  *
631
  * @since 1.7.0
632
  *
 
 
633
  * @param WP_Rewrite $wp_rewrite See 'generate_rewrite_rules'.
634
  */
635
  function bp_generate_rewrite_rules( $wp_rewrite ) {
651
  *
652
  * @since 1.7.0
653
  *
 
 
654
  * @param array $themes The path of the template to include.
655
  * @return array
656
  */
672
  * The main action used for handling theme-side POST requests.
673
  *
674
  * @since 1.9.0
 
 
675
  */
676
  function bp_post_request() {
677
 
714
  * The main action used for handling theme-side GET requests.
715
  *
716
  * @since 1.9.0
 
 
717
  */
718
  function bp_get_request() {
719
 
bp-core/bp-core-filters.php CHANGED
@@ -75,13 +75,14 @@ add_filter( 'bp_get_template_stack', 'bp_add_template_stack_locations' );
75
  // Turn comments off for BuddyPress pages.
76
  add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
77
 
 
 
 
78
  /**
79
  * Prevent specific pages (eg 'Activate') from showing on page listings.
80
  *
81
  * @since 1.5.0
82
  *
83
- * @uses bp_is_active() checks if a BuddyPress component is active.
84
- *
85
  * @param array $pages List of excluded page IDs, as passed to the
86
  * 'wp_list_pages_excludes' filter.
87
  * @return array The exclude list, with BP's pages added.
@@ -119,9 +120,6 @@ add_filter( 'wp_list_pages_excludes', 'bp_core_exclude_pages' );
119
  *
120
  * @since 2.0.0
121
  *
122
- * @uses bp_is_root_blog() checks if current blog is root blog.
123
- * @uses buddypress() gets BuddyPress main instance
124
- *
125
  * @param object|null $object The post type object used in the meta box.
126
  * @return object|null The $object, with a query argument to remove register and activate pages id.
127
  */
@@ -180,7 +178,7 @@ function bp_core_menu_highlight_parent_page( $retval, $page ) {
180
  foreach ( (array) buddypress()->pages as $component => $bp_page ) {
181
  // Handles the majority of components.
182
  if ( bp_is_current_component( $component ) ) {
183
- $page_id = (int) $bp_page->id;
184
  }
185
 
186
  // Stop if not on a user page.
@@ -286,7 +284,6 @@ add_filter( 'comments_array', 'bp_core_filter_comments', 10, 2 );
286
  *
287
  * @since 1.2.0
288
  *
289
- * @uses apply_filters() Filter 'bp_core_login_redirect' to modify where users
290
  * are redirected to on login.
291
  *
292
  * @param string $redirect_to The URL to be redirected to, sanitized in wp-login.php.
@@ -314,7 +311,7 @@ function bp_core_login_redirect( $redirect_to, $redirect_to_raw, $user ) {
314
  *
315
  * @since 1.6.0
316
  *
317
- * @param bool $value Whether or not to redirect.
318
  * @param string $redirect_to Sanitized URL to be redirected to.
319
  * @param string $redirect_to_raw Unsanitized URL to be redirected to.
320
  * @param WP_User $user The WP_User object corresponding to a
@@ -355,6 +352,7 @@ add_filter( 'bp_login_redirect', 'bp_core_login_redirect', 10, 3 );
355
  * @param string $retval Current email content.
356
  * @param string $prop Email property to check against.
357
  * @param string $transform Either 'raw' or 'replace-tokens'.
 
358
  */
359
  function bp_email_plaintext_entity_decode( $retval, $prop, $transform ) {
360
  switch ( $prop ) {
@@ -551,9 +549,9 @@ add_filter( 'wpmu_signup_user_notification', 'bp_core_activation_signup_user_not
551
  * @see wp_title()
552
  * @global object $bp BuddyPress global settings.
553
  *
554
- * @param string $title Original page title.
555
- * @param string $sep How to separate the various items within the page title.
556
- * @param string $seplocation Direction to display title.
557
  * @return string New page title.
558
  */
559
  function bp_modify_page_title( $title = '', $sep = '&raquo;', $seplocation = 'right' ) {
@@ -576,7 +574,7 @@ function bp_modify_page_title( $title = '', $sep = '&raquo;', $seplocation = 'ri
576
  * @link https://buddypress.trac.wordpress.org/ticket/6107
577
  * @see wp_title()
578
  */
579
- $title_tag_compatibility = (bool) ( ! empty( $_wp_theme_features['title-tag'] ) || strstr( $title, $blogname ) );
580
 
581
  // Append the site title to title parts if theme supports title tag.
582
  if ( true === $title_tag_compatibility ) {
@@ -601,12 +599,12 @@ function bp_modify_page_title( $title = '', $sep = '&raquo;', $seplocation = 'ri
601
  /**
602
  * Filters the older 'wp_title' page title for BuddyPress pages.
603
  *
604
- * @since 1.5.0
605
  *
606
- * @param string $new_title The BuddyPress page title.
607
- * @param string $title The original WordPress page title.
608
- * @param string $sep The title parts separator.
609
- * @param string $seplocation Location of the separator (left or right).
610
  */
611
  return apply_filters( 'bp_modify_page_title', $new_title, $title, $sep, $seplocation );
612
  }
@@ -654,10 +652,10 @@ function bp_modify_document_title_parts( $title = array() ) {
654
  /**
655
  * Filters BuddyPress title parts that will be used into the document title.
656
  *
657
- * @since 2.4.3
658
  *
659
- * @param array $bp_title The BuddyPress page title parts.
660
- * @param array $title The original WordPress title parts.
661
  */
662
  return apply_filters( 'bp_modify_document_title_parts', $bp_title, $title );
663
  }
@@ -755,13 +753,13 @@ add_filter( 'wp_setup_nav_menu_item', 'bp_setup_nav_menu_item', 10, 1 );
755
  /**
756
  * Populate BuddyPress user nav items for the customizer.
757
  *
758
- * @since 2.3.3
759
  *
760
- * @param array $items The array of menu items.
761
- * @param string $type The requested type.
762
- * @param string $object The requested object name.
763
- * @param integer $page The page num being requested.
764
- * @return array The paginated BuddyPress user nav items.
765
  */
766
  function bp_customizer_nav_menus_get_items( $items = array(), $type = '', $object = '', $page = 0 ) {
767
  if ( 'bp_loggedin_nav' === $object ) {
@@ -792,9 +790,9 @@ add_filter( 'customize_nav_menu_available_items', 'bp_customizer_nav_menus_get_i
792
  /**
793
  * Set BuddyPress item navs for the customizer.
794
  *
795
- * @since 2.3.3
796
  *
797
- * @param array $item_types An associative array structured for the customizer.
798
  * @return array $item_types An associative array structured for the customizer.
799
  */
800
  function bp_customizer_nav_menus_set_item_types( $item_types = array() ) {
@@ -858,8 +856,8 @@ function bp_filter_metaid_column_name( $q ) {
858
  *
859
  * @since 2.1.0
860
  *
861
- * @param string $edit_link The edit link.
862
- * @param int $post_id Post ID.
863
  * @return bool|string Will be a boolean (false) if $post_id is 0. Will be a string (the unchanged edit link)
864
  * otherwise
865
  */
@@ -905,7 +903,8 @@ add_filter( 'bp_activity_maybe_load_mentions_scripts', 'bp_maybe_load_mentions_s
905
  * @access private
906
  *
907
  * @global array $wp_registered_widgets Current registered widgets.
908
- * @param array $params Current sidebar params.
 
909
  * @return array
910
  */
911
  function _bp_core_inject_bp_widget_css_class( $params ) {
@@ -957,9 +956,9 @@ add_filter( 'dynamic_sidebar_params', '_bp_core_inject_bp_widget_css_class' );
957
  *
958
  * @since 2.5.0
959
  *
960
- * @param string $value Property value.
961
- * @param string $property_name
962
- * @param string $transform How the return value was transformed.
963
  * @return string Updated value.
964
  */
965
  function bp_email_add_link_color_to_template( $value, $property_name, $transform ) {
@@ -996,16 +995,31 @@ add_filter( 'bp_email_get_property', 'bp_email_add_link_color_to_template', 6, 3
996
  *
997
  * @since 2.5.0
998
  *
999
- * @param array $headers
1000
- * @param string $property Name of property. Unused.
1001
- * @param string $transform Return value transformation. Unused.
1002
- * @param BP_Email $email Email object reference.
1003
  * @return array
1004
  */
1005
  function bp_email_set_default_headers( $headers, $property, $transform, $email ) {
1006
  $headers['X-BuddyPress'] = bp_get_version();
1007
  $headers['X-BuddyPress-Type'] = $email->get( 'type' );
1008
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1009
  return $headers;
1010
  }
1011
  add_filter( 'bp_email_get_headers', 'bp_email_set_default_headers', 6, 4 );
@@ -1015,10 +1029,10 @@ add_filter( 'bp_email_get_headers', 'bp_email_set_default_headers', 6, 4 );
1015
  *
1016
  * @since 2.5.0
1017
  *
1018
- * @param array $tokens Email tokens.
1019
- * @param string $property_name Unused.
1020
- * @param string $transform Unused.
1021
- * @param BP_Email $email Email being sent.
1022
  * @return array
1023
  */
1024
  function bp_email_set_default_tokens( $tokens, $property_name, $transform, $email ) {
@@ -1034,7 +1048,6 @@ function bp_email_set_default_tokens( $tokens, $property_name, $transform, $emai
1034
  $tokens['recipient.email'] = '';
1035
  $tokens['recipient.name'] = '';
1036
  $tokens['recipient.username'] = '';
1037
- $tokens['unsubscribe'] = site_url( 'wp-login.php' );
1038
 
1039
 
1040
  // Who is the email going to?
@@ -1051,16 +1064,22 @@ function bp_email_set_default_tokens( $tokens, $property_name, $transform, $emai
1051
  }
1052
 
1053
  if ( $user_obj ) {
1054
- // Unsubscribe link.
1055
- $tokens['unsubscribe'] = esc_url( sprintf(
1056
- '%s%s/notifications/',
1057
- bp_core_get_user_domain( $user_obj->ID ),
1058
- function_exists( 'bp_get_settings_slug' ) ? bp_get_settings_slug() : 'settings'
1059
- ) );
1060
  $tokens['recipient.username'] = $user_obj->user_login;
 
 
 
 
 
 
 
1061
  }
1062
  }
1063
 
 
 
 
 
 
1064
  // Email preheader.
1065
  $post = $email->get_post_object();
1066
  if ( $post ) {
75
  // Turn comments off for BuddyPress pages.
76
  add_filter( 'comments_open', 'bp_comments_open', 10, 2 );
77
 
78
+ // Prevent DB query for WP's main loop.
79
+ add_filter( 'posts_pre_query', 'bp_core_filter_wp_query', 10, 2 );
80
+
81
  /**
82
  * Prevent specific pages (eg 'Activate') from showing on page listings.
83
  *
84
  * @since 1.5.0
85
  *
 
 
86
  * @param array $pages List of excluded page IDs, as passed to the
87
  * 'wp_list_pages_excludes' filter.
88
  * @return array The exclude list, with BP's pages added.
120
  *
121
  * @since 2.0.0
122
  *
 
 
 
123
  * @param object|null $object The post type object used in the meta box.
124
  * @return object|null The $object, with a query argument to remove register and activate pages id.
125
  */
178
  foreach ( (array) buddypress()->pages as $component => $bp_page ) {
179
  // Handles the majority of components.
180
  if ( bp_is_current_component( $component ) ) {
181
+ $page_id = (int) $bp_page->id;
182
  }
183
 
184
  // Stop if not on a user page.
284
  *
285
  * @since 1.2.0
286
  *
 
287
  * are redirected to on login.
288
  *
289
  * @param string $redirect_to The URL to be redirected to, sanitized in wp-login.php.
311
  *
312
  * @since 1.6.0
313
  *
314
+ * @param bool $value Whether or not to redirect.
315
  * @param string $redirect_to Sanitized URL to be redirected to.
316
  * @param string $redirect_to_raw Unsanitized URL to be redirected to.
317
  * @param WP_User $user The WP_User object corresponding to a
352
  * @param string $retval Current email content.
353
  * @param string $prop Email property to check against.
354
  * @param string $transform Either 'raw' or 'replace-tokens'.
355
+ * @return string $retval Modified email content.
356
  */
357
  function bp_email_plaintext_entity_decode( $retval, $prop, $transform ) {
358
  switch ( $prop ) {
549
  * @see wp_title()
550
  * @global object $bp BuddyPress global settings.
551
  *
552
+ * @param string $title Original page title.
553
+ * @param string $sep How to separate the various items within the page title.
554
+ * @param string $seplocation Direction to display title.
555
  * @return string New page title.
556
  */
557
  function bp_modify_page_title( $title = '', $sep = '&raquo;', $seplocation = 'right' ) {
574
  * @link https://buddypress.trac.wordpress.org/ticket/6107
575
  * @see wp_title()
576
  */
577
+ $title_tag_compatibility = (bool) ( ! empty( $_wp_theme_features['title-tag'] ) || ( $blogname && strstr( $title, $blogname ) ) );
578
 
579
  // Append the site title to title parts if theme supports title tag.
580
  if ( true === $title_tag_compatibility ) {
599
  /**
600
  * Filters the older 'wp_title' page title for BuddyPress pages.
601
  *
602
+ * @since 1.5.0
603
  *
604
+ * @param string $new_title The BuddyPress page title.
605
+ * @param string $title The original WordPress page title.
606
+ * @param string $sep The title parts separator.
607
+ * @param string $seplocation Location of the separator (left or right).
608
  */
609
  return apply_filters( 'bp_modify_page_title', $new_title, $title, $sep, $seplocation );
610
  }
652
  /**
653
  * Filters BuddyPress title parts that will be used into the document title.
654
  *
655
+ * @since 2.4.3
656
  *
657
+ * @param array $bp_title The BuddyPress page title parts.
658
+ * @param array $title The original WordPress title parts.
659
  */
660
  return apply_filters( 'bp_modify_document_title_parts', $bp_title, $title );
661
  }
753
  /**
754
  * Populate BuddyPress user nav items for the customizer.
755
  *
756
+ * @since 2.3.3
757
  *
758
+ * @param array $items The array of menu items.
759
+ * @param string $type The requested type.
760
+ * @param string $object The requested object name.
761
+ * @param integer $page The page num being requested.
762
+ * @return array The paginated BuddyPress user nav items.
763
  */
764
  function bp_customizer_nav_menus_get_items( $items = array(), $type = '', $object = '', $page = 0 ) {
765
  if ( 'bp_loggedin_nav' === $object ) {
790
  /**
791
  * Set BuddyPress item navs for the customizer.
792
  *
793
+ * @since 2.3.3
794
  *
795
+ * @param array $item_types An associative array structured for the customizer.
796
  * @return array $item_types An associative array structured for the customizer.
797
  */
798
  function bp_customizer_nav_menus_set_item_types( $item_types = array() ) {
856
  *
857
  * @since 2.1.0
858
  *
859
+ * @param string $edit_link The edit link.
860
+ * @param int $post_id Post ID.
861
  * @return bool|string Will be a boolean (false) if $post_id is 0. Will be a string (the unchanged edit link)
862
  * otherwise
863
  */
903
  * @access private
904
  *
905
  * @global array $wp_registered_widgets Current registered widgets.
906
+ *
907
+ * @param array $params Current sidebar params.
908
  * @return array
909
  */
910
  function _bp_core_inject_bp_widget_css_class( $params ) {
956
  *
957
  * @since 2.5.0
958
  *
959
+ * @param string $value Property value.
960
+ * @param string $property_name Email template property name.
961
+ * @param string $transform How the return value was transformed.
962
  * @return string Updated value.
963
  */
964
  function bp_email_add_link_color_to_template( $value, $property_name, $transform ) {
995
  *
996
  * @since 2.5.0
997
  *
998
+ * @param array $headers Array of email headers.
999
+ * @param string $property Name of property. Unused.
1000
+ * @param string $transform Return value transformation. Unused.
1001
+ * @param BP_Email $email Email object reference.
1002
  * @return array
1003
  */
1004
  function bp_email_set_default_headers( $headers, $property, $transform, $email ) {
1005
  $headers['X-BuddyPress'] = bp_get_version();
1006
  $headers['X-BuddyPress-Type'] = $email->get( 'type' );
1007
 
1008
+ $tokens = $email->get_tokens();
1009
+
1010
+ // Add 'List-Unsubscribe' header if applicable.
1011
+ if ( ! empty( $tokens['unsubscribe'] ) && $tokens['unsubscribe'] !== site_url( 'wp-login.php' ) ) {
1012
+ $user = get_user_by( 'email', $tokens['recipient.email'] );
1013
+
1014
+ $headers['List-Unsubscribe'] = sprintf(
1015
+ '<%s>',
1016
+ esc_url_raw( bp_email_get_unsubscribe_link( array(
1017
+ 'user_id' => $user->ID,
1018
+ 'notification_type' => $email->get( 'type' ),
1019
+ ) ) )
1020
+ );
1021
+ }
1022
+
1023
  return $headers;
1024
  }
1025
  add_filter( 'bp_email_get_headers', 'bp_email_set_default_headers', 6, 4 );
1029
  *
1030
  * @since 2.5.0
1031
  *
1032
+ * @param array $tokens Email tokens.
1033
+ * @param string $property_name Unused.
1034
+ * @param string $transform Unused.
1035
+ * @param BP_Email $email Email being sent.
1036
  * @return array
1037
  */
1038
  function bp_email_set_default_tokens( $tokens, $property_name, $transform, $email ) {
1048
  $tokens['recipient.email'] = '';
1049
  $tokens['recipient.name'] = '';
1050
  $tokens['recipient.username'] = '';
 
1051
 
1052
 
1053
  // Who is the email going to?
1064
  }
1065
 
1066
  if ( $user_obj ) {
 
 
 
 
 
 
1067
  $tokens['recipient.username'] = $user_obj->user_login;
1068
+ if ( bp_is_active( 'settings' ) && empty( $tokens['unsubscribe'] ) ) {
1069
+ $tokens['unsubscribe'] = esc_url( sprintf(
1070
+ '%s%s/notifications/',
1071
+ bp_core_get_user_domain( $user_obj->ID ),
1072
+ bp_get_settings_slug()
1073
+ ) );
1074
+ }
1075
  }
1076
  }
1077
 
1078
+ // Set default unsubscribe link if not passed.
1079
+ if ( empty( $tokens['unsubscribe'] ) ) {
1080
+ $tokens['unsubscribe'] = site_url( 'wp-login.php' );
1081
+ }
1082
+
1083
  // Email preheader.
1084
  $post = $email->get_post_object();
1085
  if ( $post ) {
bp-core/bp-core-functions.php CHANGED
@@ -17,7 +17,6 @@ defined( 'ABSPATH' ) || exit;
17
  *
18
  * @since 1.6.0
19
  *
20
- * @uses bp_get_version() To get the BuddyPress version.
21
  */
22
  function bp_version() {
23
  echo bp_get_version();
@@ -38,7 +37,6 @@ function bp_version() {
38
  *
39
  * @since 1.6.0
40
  *
41
- * @uses bp_get_db_version() To get the BuddyPress database version.
42
  */
43
  function bp_db_version() {
44
  echo bp_get_db_version();
@@ -59,7 +57,6 @@ function bp_db_version() {
59
  *
60
  * @since 1.6.0
61
  *
62
- * @uses bp_get_db_version_raw() To get the current database BuddyPress version.
63
  */
64
  function bp_db_version_raw() {
65
  echo bp_get_db_version_raw();
@@ -111,14 +108,53 @@ function bp_core_get_table_prefix() {
111
  * your own awkward callback function for usort().
112
  *
113
  * @since 2.2.0
 
 
 
 
 
 
 
 
114
  *
115
- * @param array $items The items to be sorted. Its constituent items can be either associative arrays or objects.
116
- * @param string|int $key The array index or property name to sort by.
117
- * @param string $type Sort type. 'alpha' for alphabetical, 'num' for numeric. Default: 'alpha'.
118
  * @return array $items The sorted array.
119
  */
120
- function bp_sort_by_key( $items, $key, $type = 'alpha' ) {
121
- usort( $items, array( new BP_Core_Sort_By_Key_Callback( $key, $type ), 'sort_callback' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  return $items;
124
  }
@@ -358,7 +394,6 @@ function bp_esc_like( $text ) {
358
  *
359
  * @since 1.5.0
360
  *
361
- * @uses apply_filters() Filter 'bp_is_username_compatibility_mode' to alter.
362
  * @todo Move to members component?
363
  *
364
  * @return bool False when compatibility mode is disabled, true when enabled.
@@ -384,8 +419,6 @@ function bp_is_username_compatibility_mode() {
384
  *
385
  * @since 1.5.0
386
  *
387
- * @uses apply_filters() Filter 'bp_use_wp_admin_bar' to alter.
388
- *
389
  * @return bool Default: true. False when WP Toolbar support is disabled.
390
  */
391
  function bp_use_wp_admin_bar() {
@@ -492,6 +525,29 @@ function bp_core_get_directory_page_ids( $status = 'active' ) {
492
  return apply_filters( 'bp_core_get_directory_page_ids', $page_ids );
493
  }
494
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
495
  /**
496
  * Store the list of BP directory pages in the appropriate meta table.
497
  *
@@ -613,14 +669,7 @@ function bp_core_add_page_mappings( $components, $existing = 'keep' ) {
613
  $pages = array();
614
  }
615
 
616
- $page_titles = array(
617
- 'activity' => _x( 'Activity', 'Page title for the Activity directory.', 'buddypress' ),
618
- 'groups' => _x( 'Groups', 'Page title for the Groups directory.', 'buddypress' ),
619
- 'sites' => _x( 'Sites', 'Page title for the Sites directory.', 'buddypress' ),
620
- 'members' => _x( 'Members', 'Page title for the Members directory.', 'buddypress' ),
621
- 'activate' => _x( 'Activate', 'Page title for the user activation screen.', 'buddypress' ),
622
- 'register' => _x( 'Register', 'Page title for the user registration screen.', 'buddypress' ),
623
- );
624
 
625
  $pages_to_create = array();
626
  foreach ( array_keys( $components ) as $component_name ) {
@@ -640,8 +689,8 @@ function bp_core_add_page_mappings( $components, $existing = 'keep' ) {
640
  }
641
 
642
  // No need for a Sites directory unless we're on multisite.
643
- if ( ! is_multisite() && isset( $pages_to_create['sites'] ) ) {
644
- unset( $pages_to_create['sites'] );
645
  }
646
 
647
  // Members must always have a page, no matter what.
@@ -676,6 +725,33 @@ function bp_core_add_page_mappings( $components, $existing = 'keep' ) {
676
  }
677
  }
678
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
679
  /**
680
  * Remove the entry from bp_pages when the corresponding WP page is deleted.
681
  *
@@ -833,11 +909,17 @@ function bp_core_add_illegal_names() {
833
  * Get the 'search' query argument for a given component.
834
  *
835
  * @since 2.4.0
 
 
836
  *
837
- * @param string $component Component name.
838
  * @return string|bool Query argument on success. False on failure.
839
  */
840
- function bp_core_get_component_search_query_arg( $component ) {
 
 
 
 
841
  $query_arg = false;
842
  if ( isset( buddypress()->{$component}->search_query_arg ) ) {
843
  $query_arg = sanitize_title( buddypress()->{$component}->search_query_arg );
@@ -900,8 +982,6 @@ function bp_do_register_theme_directory() {
900
  *
901
  * @since 1.0.0
902
  *
903
- * @uses get_blog_option() WordPress function to fetch blog meta.
904
- *
905
  * @return string The domain URL for the blog.
906
  */
907
  function bp_core_get_root_domain() {
@@ -923,8 +1003,6 @@ function bp_core_get_root_domain() {
923
  *
924
  * @since 1.0.0
925
  *
926
- * @uses wp_safe_redirect()
927
- *
928
  * @param string $location The redirect URL.
929
  * @param int $status Optional. The numeric code to give in the redirect
930
  * headers. Default: 302.
@@ -1054,9 +1132,6 @@ function bp_core_current_time( $gmt = true, $type = 'mysql' ) {
1054
  *
1055
  * @since 1.0.0
1056
  *
1057
- * @uses apply_filters() Filter 'bp_core_time_since_pre' to bypass BP's calculations.
1058
- * @uses apply_filters() Filter 'bp_core_time_since' to modify BP's calculations.
1059
- *
1060
  * @param int|string $older_date The earlier time from which you're calculating
1061
  * the time elapsed. Enter either as an integer Unix timestamp,
1062
  * or as a date string of the format 'Y-m-d h:i:s'.
@@ -1248,6 +1323,41 @@ function bp_core_time_since( $older_date, $newer_date = false ) {
1248
  return apply_filters( 'bp_core_time_since', $output, $older_date, $newer_date );
1249
  }
1250
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1251
  /** Messages ******************************************************************/
1252
 
1253
  /**
@@ -1267,8 +1377,8 @@ function bp_core_add_message( $message, $type = '' ) {
1267
  }
1268
 
1269
  // Send the values to the cookie for page reload display.
1270
- @setcookie( 'bp-message', $message, time() + 60 * 60 * 24, COOKIEPATH );
1271
- @setcookie( 'bp-message-type', $type, time() + 60 * 60 * 24, COOKIEPATH );
1272
 
1273
  // Get BuddyPress.
1274
  $bp = buddypress();
@@ -1293,7 +1403,6 @@ function bp_core_add_message( $message, $type = '' ) {
1293
  *
1294
  * @since 1.1.0
1295
  *
1296
- * @uses setcookie() Sets a cookie value for the user.
1297
  */
1298
  function bp_core_setup_message() {
1299
 
@@ -1311,11 +1420,11 @@ function bp_core_setup_message() {
1311
  add_action( 'template_notices', 'bp_core_render_message' );
1312
 
1313
  if ( isset( $_COOKIE['bp-message'] ) ) {
1314
- @setcookie( 'bp-message', false, time() - 1000, COOKIEPATH );
1315
  }
1316
 
1317
  if ( isset( $_COOKIE['bp-message-type'] ) ) {
1318
- @setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH );
1319
  }
1320
  }
1321
  add_action( 'bp_actions', 'bp_core_setup_message', 5 );
@@ -1377,7 +1486,6 @@ function bp_core_render_message() {
1377
  *
1378
  * @since 1.0.0
1379
  *
1380
- * @uses bp_update_user_meta() BP function to update user metadata in the
1381
  * usermeta table.
1382
  *
1383
  * @return bool|null Returns false if there is nothing to do.
@@ -1406,7 +1514,7 @@ function bp_core_record_activity() {
1406
  }
1407
 
1408
  // Get current time.
1409
- $current_time = bp_core_current_time();
1410
 
1411
  // Use this action to detect the very first activity for a given member.
1412
  if ( empty( $activity ) ) {
@@ -1424,8 +1532,8 @@ function bp_core_record_activity() {
1424
  }
1425
 
1426
  // If it's been more than 5 minutes, record a newer last-activity time.
1427
- if ( empty( $activity ) || ( strtotime( $current_time ) >= strtotime( '+5 minutes', $activity ) ) ) {
1428
- bp_update_user_last_activity( $user_id, $current_time );
1429
  }
1430
  }
1431
  add_action( 'wp_head', 'bp_core_record_activity' );
@@ -1435,7 +1543,6 @@ add_action( 'wp_head', 'bp_core_record_activity' );
1435
  *
1436
  * @since 1.0.0
1437
  *
1438
- * @uses bp_core_time_since() This function will return an English
1439
  * representation of the time elapsed.
1440
  *
1441
  * @param int|string $last_activity_date The date of last activity.
@@ -1486,8 +1593,6 @@ function bp_core_get_last_activity( $last_activity_date = '', $string = '' ) {
1486
  *
1487
  * @since 1.5.0
1488
  *
1489
- * @uses apply_filters() Filter 'bp_get_user_meta_key' to modify keys individually.
1490
- *
1491
  * @param string|bool $key The usermeta meta_key.
1492
  * @return string $key The usermeta meta_key.
1493
  */
@@ -1513,7 +1618,6 @@ function bp_get_user_meta_key( $key = false ) {
1513
  * @since 1.5.0
1514
  *
1515
  * @see get_user_meta() For complete details about parameters and return values.
1516
- * @uses bp_get_user_meta_key() For a filterable version of the meta key.
1517
  *
1518
  * @param int $user_id The ID of the user whose meta you're fetching.
1519
  * @param string $key The meta key to retrieve.
@@ -1535,7 +1639,6 @@ function bp_get_user_meta( $user_id, $key, $single = false ) {
1535
  * @since 1.5.0
1536
  *
1537
  * @see update_user_meta() For complete details about parameters and return values.
1538
- * @uses bp_get_user_meta_key() For a filterable version of the meta key.
1539
  *
1540
  * @param int $user_id The ID of the user whose meta you're setting.
1541
  * @param string $key The meta key to set.
@@ -1557,7 +1660,6 @@ function bp_update_user_meta( $user_id, $key, $value, $prev_value = '' ) {
1557
  * @since 1.5.0
1558
  *
1559
  * @see delete_user_meta() For complete details about parameters and return values.
1560
- * @uses bp_get_user_meta_key() For a filterable version of the meta key.
1561
  *
1562
  * @param int $user_id The ID of the user whose meta you're deleting.
1563
  * @param string $key The meta key to delete.
@@ -1666,6 +1768,38 @@ function bp_use_embed_in_private_messages() {
1666
  return apply_filters( 'bp_use_embed_in_private_messages', !defined( 'BP_EMBED_DISABLE_PRIVATE_MESSAGES' ) || !BP_EMBED_DISABLE_PRIVATE_MESSAGES );
1667
  }
1668
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1669
  /** Admin *********************************************************************/
1670
 
1671
  /**
@@ -1686,9 +1820,6 @@ function bp_admin_url( $path = '', $scheme = 'admin' ) {
1686
  *
1687
  * @since 1.5.0
1688
  *
1689
- * @uses bp_core_do_network_admin()
1690
- * @uses network_admin_url()
1691
- * @uses admin_url()
1692
  *
1693
  * @param string $path Optional. The sub-path under /wp-admin to be
1694
  * appended to the admin URL.
@@ -1720,9 +1851,6 @@ function bp_admin_url( $path = '', $scheme = 'admin' ) {
1720
  *
1721
  * @since 1.5.0
1722
  *
1723
- * @uses bp_is_network_activated()
1724
- * @uses bp_is_multiblog_mode()
1725
- *
1726
  * @return bool True if the BP admin screen should appear in the Network Admin,
1727
  * otherwise false.
1728
  */
@@ -1855,8 +1983,6 @@ function bp_get_root_blog_id() {
1855
  *
1856
  * @since 1.5.0
1857
  *
1858
- * @uses apply_filters() Filter 'bp_is_multiblog_mode' to alter.
1859
- *
1860
  * @return bool False when multiblog mode is disabled; true when enabled.
1861
  * Default: false.
1862
  */
@@ -2044,8 +2170,6 @@ function bp_do_404( $redirect = 'remove_canonical_direct' ) {
2044
  *
2045
  * @since 1.6.0
2046
  *
2047
- * @uses do_action() Calls 'bp_verify_nonce_request' on $action.
2048
- *
2049
  * @param string $action Action nonce.
2050
  * @param string $query_arg Where to look for nonce in $_REQUEST.
2051
  * @return bool True if the nonce is verified, otherwise false.
@@ -2185,7 +2309,7 @@ function bp_core_load_buddypress_textdomain() {
2185
  // Default to WP and glotpress.
2186
  return load_plugin_textdomain( $domain );
2187
  }
2188
- add_action ( 'bp_core_loaded', 'bp_core_load_buddypress_textdomain' );
2189
 
2190
  /**
2191
  * A JavaScript-free implementation of the search functions in BuddyPress.
@@ -2263,20 +2387,6 @@ function bp_core_action_search_site( $slug = '' ) {
2263
  }
2264
  add_action( 'bp_init', 'bp_core_action_search_site', 7 );
2265
 
2266
- /**
2267
- * Print the generation time in the footer of the site.
2268
- *
2269
- * @since 1.0.0
2270
- */
2271
- function bp_core_print_generation_time() {
2272
- ?>
2273
-
2274
- <!-- Generated in <?php timer_stop(1); ?> seconds. (<?php echo get_num_queries(); ?> q) -->
2275
-
2276
- <?php
2277
- }
2278
- add_action( 'wp_footer', 'bp_core_print_generation_time' );
2279
-
2280
  /**
2281
  * Remove "prev" and "next" relational links from <head> on BuddyPress pages.
2282
  *
@@ -2292,7 +2402,7 @@ function bp_remove_adjacent_posts_rel_link() {
2292
  return;
2293
  }
2294
 
2295
- remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
2296
  }
2297
  add_action( 'bp_init', 'bp_remove_adjacent_posts_rel_link' );
2298
 
@@ -2331,6 +2441,105 @@ function bp_core_get_minified_asset_suffix() {
2331
  return $ext;
2332
  }
2333
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2334
  /** Nav Menu ******************************************************************/
2335
 
2336
  /**
@@ -2358,11 +2567,8 @@ function bp_nav_menu_get_loggedin_pages() {
2358
  return buddypress()->wp_nav_menu_items->loggedin;
2359
  }
2360
 
2361
- // Pull up a list of items registered in BP's top-level nav array.
2362
- $bp_menu_items = buddypress()->bp_nav;
2363
-
2364
- // Alphabetize.
2365
- $bp_menu_items = bp_alpha_sort_by_key( $bp_menu_items, 'name' );
2366
 
2367
  // Some BP nav menu items will not be represented in bp_nav, because
2368
  // they are not real BP components. We add them manually here.
@@ -2490,7 +2696,7 @@ function bp_nav_menu_get_loggedout_pages() {
2490
  * @since 1.9.0
2491
  *
2492
  * @param string $slug The slug of the nav item: login, register, or one of the
2493
- * slugs from buddypress()->bp_nav.
2494
  * @return string $nav_item_url The URL generated for the current user.
2495
  */
2496
  function bp_nav_menu_get_item_url( $slug ) {
@@ -2585,13 +2791,7 @@ function bp_core_get_suggestions( $args ) {
2585
  *
2586
  * @since 2.3.0
2587
  *
2588
- * @uses is_multisite()
2589
- * @uses bp_is_root_blog()
2590
- * @uses switch_to_blog()
2591
- * @uses wp_upload_dir()
2592
- * @uses restore_current_blog()
2593
- *
2594
- * @return string
2595
  */
2596
  function bp_upload_dir() {
2597
  $bp = buddypress();
@@ -3089,8 +3289,8 @@ function bp_email_get_template( WP_Post $object ) {
3089
  *
3090
  * @since 2.5.0
3091
  *
3092
- * @param string $text
3093
- * @param array $tokens Token names and replacement values for the $text.
3094
  * @return string
3095
  */
3096
  function bp_core_replace_tokens_in_text( $text, $tokens ) {
@@ -3127,7 +3327,7 @@ function bp_core_replace_tokens_in_text( $text, $tokens ) {
3127
 
3128
  /**
3129
  * Get a list of emails for populating the email post type.
3130
- *t
3131
  * @since 2.5.1
3132
  *
3133
  * @return array
@@ -3204,7 +3404,7 @@ function bp_email_get_schema() {
3204
  /* translators: do not remove {} brackets or translate its contents. */
3205
  'post_content' => __( "Group details for the group &quot;<a href=\"{{{group.url}}}\">{{group.name}}</a>&quot; were updated:\n<blockquote>{{changed_text}}</blockquote>", 'buddypress' ),
3206
  /* translators: do not remove {} brackets or translate its contents. */
3207
- 'post_excerpt' => __( "Group details for the group &quot;{{group.name}}&quot; were updated:\n\n{{changed_text}}\n\nTo view the group, visit: {{{group.url}}}", 'buddypress' ),
3208
  ),
3209
  'groups-invitation' => array(
3210
  /* translators: do not remove {} brackets or translate its contents. */
@@ -3212,7 +3412,7 @@ function bp_email_get_schema() {
3212
  /* translators: do not remove {} brackets or translate its contents. */
3213
  'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the group: &quot;{{group.name}}&quot;.\n<a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{group.url}}}\">visit the group</a> to learn more.", 'buddypress' ),
3214
  /* translators: do not remove {} brackets or translate its contents. */
3215
- 'post_excerpt' => __( "{{inviter.name}} has invited you to join the group: &quot;{{group.name}}&quot;.\n\nTo accept your invitation, visit: {{{invites.url}}}\n\nTo learn more about the group, visit {{{group.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ),
3216
  ),
3217
  'groups-member-promoted' => array(
3218
  /* translators: do not remove {} brackets or translate its contents. */
@@ -3220,7 +3420,7 @@ function bp_email_get_schema() {
3220
  /* translators: do not remove {} brackets or translate its contents. */
3221
  'post_content' => __( "You have been promoted to <b>{{promoted_to}}</b> in the group &quot;<a href=\"{{{group.url}}}\">{{group.name}}</a>&quot;.", 'buddypress' ),
3222
  /* translators: do not remove {} brackets or translate its contents. */
3223
- 'post_excerpt' => __( "You have been promoted to {{promoted_to}} in the group: &quot;{{group.name}}&quot;.\n\nTo visit the group, go to: {{{group.url}}}", 'buddypress' ),
3224
  ),
3225
  'groups-membership-request' => array(
3226
  /* translators: do not remove {} brackets or translate its contents. */
@@ -3228,7 +3428,7 @@ function bp_email_get_schema() {
3228
  /* translators: do not remove {} brackets or translate its contents. */
3229
  'post_content' => __( "<a href=\"{{{profile.url}}}\">{{requesting-user.name}}</a> wants to join the group &quot;{{group.name}}&quot;. As you are an administrator of this group, you must either accept or reject the membership request.\n\n<a href=\"{{{group-requests.url}}}\">Go here to manage this</a> and all other pending requests.", 'buddypress' ),
3230
  /* translators: do not remove {} brackets or translate its contents. */
3231
- 'post_excerpt' => __( "{{requesting-user.name}} wants to join the group &quot;{{group.name}}&quot;. As you are the administrator of this group, you must either accept or reject the membership request.\n\nTo manage this and all other pending requests, visit: {{{group-requests.url}}}\n\nTo view {{requesting-user.name}}'s profile, visit: {{{profile.url}}}", 'buddypress' ),
3232
  ),
3233
  'messages-unread' => array(
3234
  /* translators: do not remove {} brackets or translate its contents. */
@@ -3236,15 +3436,15 @@ function bp_email_get_schema() {
3236
  /* translators: do not remove {} brackets or translate its contents. */
3237
  'post_content' => __( "{{sender.name}} sent you a new message: &quot;{{usersubject}}&quot;\n\n<blockquote>&quot;{{usermessage}}&quot;</blockquote>\n\n<a href=\"{{{message.url}}}\">Go to the discussion</a> to reply or catch up on the conversation.", 'buddypress' ),
3238
  /* translators: do not remove {} brackets or translate its contents. */
3239
- 'post_excerpt' => __( "{{sender.name}} sent you a new message: &quot;{{usersubject}}&quot;\n\n&quot;{{usermessage}}&quot;\n\nGo to the discussion to reply or catch up on the conversation: {{{message.url}}}", 'buddypress' ),
3240
  ),
3241
  'settings-verify-email-change' => array(
3242
  /* translators: do not remove {} brackets or translate its contents. */
3243
  'post_title' => __( '[{{{site.name}}}] Verify your new email address', 'buddypress' ),
3244
  /* translators: do not remove {} brackets or translate its contents. */
3245
- 'post_content' => __( "You recently changed the email address associated with your account on {{site.name}}. If this is correct, <a href=\"{{{verify.url}}}\">go here to confirm the change</a>.\n\nOtherwise, you can safely ignore and delete this email if you have changed your mind, or if you think you have received this email in error.", 'buddypress' ),
3246
  /* translators: do not remove {} brackets or translate its contents. */
3247
- 'post_excerpt' => __( "You recently changed the email address associated with your account on {{site.name}}. If this is correct, go to the following link to confirm the change: {{{verify.url}}}\n\nOtherwise, you can safely ignore and delete this email if you have changed your mind, or if you think you have received this email in error.", 'buddypress' ),
3248
  ),
3249
  'groups-membership-request-accepted' => array(
3250
  /* translators: do not remove {} brackets or translate its contents. */
@@ -3252,7 +3452,7 @@ function bp_email_get_schema() {
3252
  /* translators: do not remove {} brackets or translate its contents. */
3253
  'post_content' => __( "Your membership request for the group &quot;<a href=\"{{{group.url}}}\">{{group.name}}</a>&quot; has been accepted.", 'buddypress' ),
3254
  /* translators: do not remove {} brackets or translate its contents. */
3255
- 'post_excerpt' => __( "Your membership request for the group &quot;{{group.name}}&quot; has been accepted.\n\nTo view the group, visit: {{{group.url}}}", 'buddypress' ),
3256
  ),
3257
  'groups-membership-request-rejected' => array(
3258
  /* translators: do not remove {} brackets or translate its contents. */
@@ -3260,7 +3460,7 @@ function bp_email_get_schema() {
3260
  /* translators: do not remove {} brackets or translate its contents. */
3261
  'post_content' => __( "Your membership request for the group &quot;<a href=\"{{{group.url}}}\">{{group.name}}</a>&quot; has been rejected.", 'buddypress' ),
3262
  /* translators: do not remove {} brackets or translate its contents. */
3263
- 'post_excerpt' => __( "Your membership request for the group &quot;{{group.name}}&quot; has been rejected.\n\nTo request membership again, visit: {{{group.url}}}", 'buddypress' ),
3264
  ),
3265
  );
3266
  }
@@ -3269,26 +3469,309 @@ function bp_email_get_schema() {
3269
  * Get a list of emails for populating email type taxonomy terms.
3270
  *
3271
  * @since 2.5.1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3272
  *
3273
- * @return array
3274
  */
3275
- function bp_email_get_type_schema() {
3276
- return array(
3277
- 'activity-comment' => __( 'A member has replied to an activity update that the recipient posted.', 'buddypress' ),
3278
- 'activity-comment-author' => __( 'A member has replied to a comment on an activity update that the recipient posted.', 'buddypress' ),
3279
- 'activity-at-message' => __( 'Recipient was mentioned in an activity update.', 'buddypress' ),
3280
- 'groups-at-message' => __( 'Recipient was mentioned in a group activity update.', 'buddypress' ),
3281
- 'core-user-registration' => __( 'Recipient has registered for an account.', 'buddypress' ),
3282
- 'core-user-registration-with-blog' => __( 'Recipient has registered for an account and site.', 'buddypress' ),
3283
- 'friends-request' => __( 'A member has sent a friend request to the recipient.', 'buddypress' ),
3284
- 'friends-request-accepted' => __( 'Recipient has had a friend request accepted by a member.', 'buddypress' ),
3285
- 'groups-details-updated' => __( "A group's details were updated.", 'buddypress' ),
3286
- 'groups-invitation' => __( 'A member has sent a group invitation to the recipient.', 'buddypress' ),
3287
- 'groups-member-promoted' => __( "Recipient's status within a group has changed.", 'buddypress' ),
3288
- 'groups-membership-request' => __( 'A member has requested permission to join a group.', 'buddypress' ),
3289
- 'messages-unread' => __( 'Recipient has received a private message.', 'buddypress' ),
3290
- 'settings-verify-email-change' => __( 'Recipient has changed their email address.', 'buddypress' ),
3291
- 'groups-membership-request-accepted' => __( 'Recipient had requested to join a group, which was accepted.', 'buddypress' ),
3292
- 'groups-membership-request-rejected' => __( 'Recipient had requested to join a group, which was rejected.', 'buddypress' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3293
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3294
  }
17
  *
18
  * @since 1.6.0
19
  *
 
20
  */
21
  function bp_version() {
22
  echo bp_get_version();
37
  *
38
  * @since 1.6.0
39
  *
 
40
  */
41
  function bp_db_version() {
42
  echo bp_get_db_version();
57
  *
58
  * @since 1.6.0
59
  *
 
60
  */
61
  function bp_db_version_raw() {
62
  echo bp_get_db_version_raw();
108
  * your own awkward callback function for usort().
109
  *
110
  * @since 2.2.0
111
+ * @since 2.7.0 Added $preserve_keys parameter.
112
+ *
113
+ * @param array $items The items to be sorted. Its constituent items
114
+ * can be either associative arrays or objects.
115
+ * @param string|int $key The array index or property name to sort by.
116
+ * @param string $type Sort type. 'alpha' for alphabetical, 'num'
117
+ * for numeric. Default: 'alpha'.
118
+ * @param bool $preserve_keys Whether to keep the keys or not.
119
  *
 
 
 
120
  * @return array $items The sorted array.
121
  */
122
+ function bp_sort_by_key( $items, $key, $type = 'alpha', $preserve_keys = false ) {
123
+ $callback = function( $a, $b ) use ( $key, $type ) {
124
+ $values = array( 0 => false, 1 => false );
125
+ foreach ( func_get_args() as $indexi => $index ) {
126
+ if ( isset( $index->{$key} ) ) {
127
+ $values[ $indexi ] = $index->{$key};
128
+ } elseif ( isset( $index[ $key ] ) ) {
129
+ $values[ $indexi ] = $index[ $key ];
130
+ }
131
+ }
132
+
133
+ if ( isset( $values[0], $values[1] ) ) {
134
+ if ( 'num' === $type ) {
135
+ $cmp = $values[0] - $values[1];
136
+ } else {
137
+ $cmp = strcmp( $values[0], $values[1] );
138
+ }
139
+
140
+ if ( 0 > $cmp ) {
141
+ $retval = -1;
142
+ } elseif ( 0 < $cmp ) {
143
+ $retval = 1;
144
+ } else {
145
+ $retval = 0;
146
+ }
147
+ return $retval;
148
+ } else {
149
+ return 0;
150
+ }
151
+ };
152
+
153
+ if ( true === $preserve_keys ) {
154
+ uasort( $items, $callback );
155
+ } else {
156
+ usort( $items, $callback );
157
+ }
158
 
159
  return $items;
160
  }
394
  *
395
  * @since 1.5.0
396
  *
 
397
  * @todo Move to members component?
398
  *
399
  * @return bool False when compatibility mode is disabled, true when enabled.
419
  *
420
  * @since 1.5.0
421
  *
 
 
422
  * @return bool Default: true. False when WP Toolbar support is disabled.
423
  */
424
  function bp_use_wp_admin_bar() {
525
  return apply_filters( 'bp_core_get_directory_page_ids', $page_ids );
526
  }
527
 
528
+ /**
529
+ * Get the page ID corresponding to a component directory.
530
+ *
531
+ * @since 2.6.0
532
+ *
533
+ * @param string $component The slug representing the component. Defaults to the current component.
534
+ * @return int|bool The ID of the directory page associated with the component. False if none is found.
535
+ */
536
+ function bp_core_get_directory_page_id( $component = null ) {
537
+ if ( ! $component ) {
538
+ $component = bp_current_component();
539
+ }
540
+
541
+ $bp_pages = bp_core_get_directory_page_ids( 'all' );
542
+
543
+ $page_id = false;
544
+ if ( $component && isset( $bp_pages[ $component ] ) ) {
545
+ $page_id = (int) $bp_pages[ $component ];
546
+ }
547
+
548
+ return $page_id;
549
+ }
550
+
551
  /**
552
  * Store the list of BP directory pages in the appropriate meta table.
553
  *
669
  $pages = array();
670
  }
671
 
672
+ $page_titles = bp_core_get_directory_page_default_titles();
 
 
 
 
 
 
 
673
 
674
  $pages_to_create = array();
675
  foreach ( array_keys( $components ) as $component_name ) {
689
  }
690
 
691
  // No need for a Sites directory unless we're on multisite.
692
+ if ( ! is_multisite() && isset( $pages_to_create['blogs'] ) ) {
693
+ unset( $pages_to_create['blogs'] );
694
  }
695
 
696
  // Members must always have a page, no matter what.
725
  }
726
  }
727
 
728
+ /**
729
+ * Get the default page titles for BP directory pages.
730
+ *
731
+ * @since 2.7.0
732
+ *
733
+ * @return array
734
+ */
735
+ function bp_core_get_directory_page_default_titles() {
736
+ $page_default_titles = array(
737
+ 'activity' => _x( 'Activity', 'Page title for the Activity directory.', 'buddypress' ),
738
+ 'groups' => _x( 'Groups', 'Page title for the Groups directory.', 'buddypress' ),
739
+ 'blogs' => _x( 'Sites', 'Page title for the Sites directory.', 'buddypress' ),
740
+ 'members' => _x( 'Members', 'Page title for the Members directory.', 'buddypress' ),
741
+ 'activate' => _x( 'Activate', 'Page title for the user activation screen.', 'buddypress' ),
742
+ 'register' => _x( 'Register', 'Page title for the user registration screen.', 'buddypress' ),
743
+ );
744
+
745
+ /**
746
+ * Filters the default page titles array
747
+ *
748
+ * @since 2.7.0
749
+ *
750
+ * @param array $page_default_titles the array of default WP (post_title) titles.
751
+ */
752
+ return apply_filters( 'bp_core_get_directory_page_default_titles', $page_default_titles );
753
+ }
754
+
755
  /**
756
  * Remove the entry from bp_pages when the corresponding WP page is deleted.
757
  *
909
  * Get the 'search' query argument for a given component.
910
  *
911
  * @since 2.4.0
912
+ * @since 2.7.0 The `$component` parameter was made optional, with the current component
913
+ * as the fallback value.
914
  *
915
+ * @param string $component Optional. Component name. Defaults to current component.
916
  * @return string|bool Query argument on success. False on failure.
917
  */
918
+ function bp_core_get_component_search_query_arg( $component = null ) {
919
+ if ( ! $component ) {
920
+ $component = bp_current_component();
921
+ }
922
+
923
  $query_arg = false;
924
  if ( isset( buddypress()->{$component}->search_query_arg ) ) {
925
  $query_arg = sanitize_title( buddypress()->{$component}->search_query_arg );
982
  *
983
  * @since 1.0.0
984
  *
 
 
985
  * @return string The domain URL for the blog.
986
  */
987
  function bp_core_get_root_domain() {
1003
  *
1004
  * @since 1.0.0
1005
  *
 
 
1006
  * @param string $location The redirect URL.
1007
  * @param int $status Optional. The numeric code to give in the redirect
1008
  * headers. Default: 302.
1132
  *
1133
  * @since 1.0.0
1134
  *
 
 
 
1135
  * @param int|string $older_date The earlier time from which you're calculating
1136
  * the time elapsed. Enter either as an integer Unix timestamp,
1137
  * or as a date string of the format 'Y-m-d h:i:s'.
1323
  return apply_filters( 'bp_core_time_since', $output, $older_date, $newer_date );
1324
  }
1325
 
1326
+ /**
1327
+ * Output an ISO-8601 date from a date string.
1328
+ *
1329
+ * @since 2.7.0
1330
+ *
1331
+ * @param string String of date to convert. Timezone should be UTC before using this.
1332
+ * @return string
1333
+ */
1334
+ function bp_core_iso8601_date( $timestamp = '' ) {
1335
+ echo bp_core_get_iso8601_date( $timestamp );
1336
+ }
1337
+ /**
1338
+ * Return an ISO-8601 date from a date string.
1339
+ *
1340
+ * @since 2.7.0
1341
+ *
1342
+ * @param string String of date to convert. Timezone should be UTC before using this.
1343
+ * @return string
1344
+ */
1345
+ function bp_core_get_iso8601_date( $timestamp = '' ) {
1346
+ if ( ! $timestamp ) {
1347
+ return '';
1348
+ }
1349
+
1350
+ try {
1351
+ $date = new DateTime( $timestamp, new DateTimeZone( 'UTC' ) );
1352
+
1353
+ // Not a valid date, so return blank string.
1354
+ } catch( Exception $e ) {
1355
+ return '';
1356
+ }
1357
+
1358
+ return $date->format( DateTime::ISO8601 );
1359
+ }
1360
+
1361
  /** Messages ******************************************************************/
1362
 
1363
  /**
1377
  }
1378
 
1379
  // Send the values to the cookie for page reload display.
1380
+ @setcookie( 'bp-message', $message, time() + 60 * 60 * 24, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
1381
+ @setcookie( 'bp-message-type', $type, time() + 60 * 60 * 24, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
1382
 
1383
  // Get BuddyPress.
1384
  $bp = buddypress();
1403
  *
1404
  * @since 1.1.0
1405
  *
 
1406
  */
1407
  function bp_core_setup_message() {
1408
 
1420
  add_action( 'template_notices', 'bp_core_render_message' );
1421
 
1422
  if ( isset( $_COOKIE['bp-message'] ) ) {
1423
+ @setcookie( 'bp-message', false, time() - 1000, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
1424
  }
1425
 
1426
  if ( isset( $_COOKIE['bp-message-type'] ) ) {
1427
+ @setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
1428
  }
1429
  }
1430
  add_action( 'bp_actions', 'bp_core_setup_message', 5 );
1486
  *
1487
  * @since 1.0.0
1488
  *
 
1489
  * usermeta table.
1490
  *
1491
  * @return bool|null Returns false if there is nothing to do.
1514
  }
1515
 
1516
  // Get current time.
1517
+ $current_time = bp_core_current_time( true, 'timestamp' );
1518
 
1519
  // Use this action to detect the very first activity for a given member.
1520
  if ( empty( $activity ) ) {
1532
  }
1533
 
1534
  // If it's been more than 5 minutes, record a newer last-activity time.
1535
+ if ( empty( $activity ) || ( $current_time >= strtotime( '+5 minutes', $activity ) ) ) {
1536
+ bp_update_user_last_activity( $user_id, date( 'Y-m-d H:i:s', $current_time ) );
1537
  }
1538
  }
1539
  add_action( 'wp_head', 'bp_core_record_activity' );
1543
  *
1544
  * @since 1.0.0
1545
  *
 
1546
  * representation of the time elapsed.
1547
  *
1548
  * @param int|string $last_activity_date The date of last activity.
1593
  *
1594
  * @since 1.5.0
1595
  *
 
 
1596
  * @param string|bool $key The usermeta meta_key.
1597
  * @return string $key The usermeta meta_key.
1598
  */
1618
  * @since 1.5.0
1619
  *
1620
  * @see get_user_meta() For complete details about parameters and return values.
 
1621
  *
1622
  * @param int $user_id The ID of the user whose meta you're fetching.
1623
  * @param string $key The meta key to retrieve.
1639
  * @since 1.5.0
1640
  *
1641
  * @see update_user_meta() For complete details about parameters and return values.
 
1642
  *
1643
  * @param int $user_id The ID of the user whose meta you're setting.
1644
  * @param string $key The meta key to set.
1660
  * @since 1.5.0
1661
  *
1662
  * @see delete_user_meta() For complete details about parameters and return values.
 
1663
  *
1664
  * @param int $user_id The ID of the user whose meta you're deleting.
1665
  * @param string $key The meta key to delete.
1768
  return apply_filters( 'bp_use_embed_in_private_messages', !defined( 'BP_EMBED_DISABLE_PRIVATE_MESSAGES' ) || !BP_EMBED_DISABLE_PRIVATE_MESSAGES );
1769
  }
1770
 
1771
+ /**
1772
+ * Extracts media metadata from a given content.
1773
+ *
1774
+ * @since 2.6.0
1775
+ *
1776
+ * @param string $content The content to check.
1777
+ * @param string|int $type The type to check. Can also use a bitmask. See the class constants in the
1778
+ * BP_Media_Extractor class for more info.
1779
+ * @return array|bool If media exists, will return array of media metadata. Else, boolean false.
1780
+ */
1781
+ function bp_core_extract_media_from_content( $content = '', $type = 'all' ) {
1782
+ if ( is_string( $type ) ) {
1783
+ $class = new ReflectionClass( 'BP_Media_Extractor' );
1784
+ $bitmask = $class->getConstant( strtoupper( $type ) );
1785
+ } else {
1786
+ $bitmask = (int) $type;
1787
+ }
1788
+
1789
+ // Type isn't valid, so bail.
1790
+ if ( empty( $bitmask ) ) {
1791
+ return false;
1792
+ }
1793
+
1794
+ $x = new BP_Media_Extractor;
1795
+ $media = $x->extract( $content, $bitmask );
1796
+
1797
+ unset( $media['has'] );
1798
+ $retval = array_filter( $media );
1799
+
1800
+ return ! empty( $retval ) ? $retval : false;
1801
+ }
1802
+
1803
  /** Admin *********************************************************************/
1804
 
1805
  /**
1820
  *
1821
  * @since 1.5.0
1822
  *
 
 
 
1823
  *
1824
  * @param string $path Optional. The sub-path under /wp-admin to be
1825
  * appended to the admin URL.
1851
  *
1852
  * @since 1.5.0
1853
  *
 
 
 
1854
  * @return bool True if the BP admin screen should appear in the Network Admin,
1855
  * otherwise false.
1856
  */
1983
  *
1984
  * @since 1.5.0
1985
  *
 
 
1986
  * @return bool False when multiblog mode is disabled; true when enabled.
1987
  * Default: false.
1988
  */
2170
  *
2171
  * @since 1.6.0
2172
  *
 
 
2173
  * @param string $action Action nonce.
2174
  * @param string $query_arg Where to look for nonce in $_REQUEST.
2175
  * @return bool True if the nonce is verified, otherwise false.
2309
  // Default to WP and glotpress.
2310
  return load_plugin_textdomain( $domain );
2311
  }
2312
+ add_action( 'bp_core_loaded', 'bp_core_load_buddypress_textdomain' );
2313
 
2314
  /**
2315
  * A JavaScript-free implementation of the search functions in BuddyPress.
2387
  }
2388
  add_action( 'bp_init', 'bp_core_action_search_site', 7 );
2389
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2390
  /**
2391
  * Remove "prev" and "next" relational links from <head> on BuddyPress pages.
2392
  *
2402
  return;
2403
  }
2404
 
2405
+ remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10 );
2406
  }
2407
  add_action( 'bp_init', 'bp_remove_adjacent_posts_rel_link' );
2408
 
2441
  return $ext;
2442
  }
2443
 
2444
+ /**
2445
+ * Return a list of component information.
2446
+ *
2447
+ * @since 2.6.0
2448
+ *
2449
+ * @param string $type Optional; component type to fetch. Default value is 'all', or 'optional', 'retired', 'required'.
2450
+ * @return array Requested components' data.
2451
+ */
2452
+ function bp_core_get_components( $type = 'all' ) {
2453
+ $required_components = array(
2454
+ 'core' => array(
2455
+ 'title' => __( 'BuddyPress Core', 'buddypress' ),
2456
+ 'description' => __( 'It&#8216;s what makes <del>time travel</del> BuddyPress possible!', 'buddypress' )
2457
+ ),
2458
+ 'members' => array(
2459
+ 'title' => __( 'Community Members', 'buddypress' ),
2460
+ 'description' => __( 'Everything in a BuddyPress community revolves around its members.', 'buddypress' )
2461
+ ),
2462
+ );
2463
+
2464
+ $retired_components = array(
2465
+ 'forums' => array(
2466
+ 'title' => __( 'Group Forums', 'buddypress' ),
2467
+ 'description' => sprintf( __( 'BuddyPress Forums are retired. Use %s.', 'buddypress' ), '<a href="https://bbpress.org/">bbPress</a>' )
2468
+ ),
2469
+ );
2470
+
2471
+ $optional_components = array(
2472
+ 'xprofile' => array(
2473
+ 'title' => __( 'Extended Profiles', 'buddypress' ),
2474
+ 'description' => __( 'Customize your community with fully editable profile fields that allow your users to describe themselves.', 'buddypress' )
2475
+ ),
2476
+ 'settings' => array(
2477
+ 'title' => __( 'Account Settings', 'buddypress' ),
2478
+ 'description' => __( 'Allow your users to modify their account and notification settings directly from within their profiles.', 'buddypress' )
2479
+ ),
2480
+ 'friends' => array(
2481
+ 'title' => __( 'Friend Connections', 'buddypress' ),
2482
+ 'description' => __( 'Let your users make connections so they can track the activity of others and focus on the people they care about the most.', 'buddypress' )
2483
+ ),
2484
+ 'messages' => array(
2485
+ 'title' => __( 'Private Messaging', 'buddypress' ),
2486
+ 'description' => __( 'Allow your users to talk to each other directly and in private. Not just limited to one-on-one discussions, messages can be sent between any number of members.', 'buddypress' )
2487
+ ),
2488
+ 'activity' => array(
2489
+ 'title' => __( 'Activity Streams', 'buddypress' ),
2490
+ 'description' => __( 'Global, personal, and group activity streams with threaded commenting, direct posting, favoriting, and @mentions, all with full RSS feed and email notification support.', 'buddypress' )
2491
+ ),
2492
+ 'notifications' => array(
2493
+ 'title' => __( 'Notifications', 'buddypress' ),
2494
+ 'description' => __( 'Notify members of relevant activity with a toolbar bubble and/or via email, and allow them to customize their notification settings.', 'buddypress' )
2495
+ ),
2496
+ 'groups' => array(
2497
+ 'title' => __( 'User Groups', 'buddypress' ),
2498
+ 'description' => __( 'Groups allow your users to organize themselves into specific public, private or hidden sections with separate activity streams and member listings.', 'buddypress' )
2499
+ ),
2500
+ 'forums' => array(
2501
+ 'title' => __( 'Group Forums (Legacy)', 'buddypress' ),
2502
+ 'description' => __( 'Group forums allow for focused, bulletin-board style conversations.', 'buddypress' )
2503
+ ),
2504
+ 'blogs' => array(
2505
+ 'title' => __( 'Site Tracking', 'buddypress' ),
2506
+ 'description' => __( 'Record activity for new posts and comments from your site.', 'buddypress' )
2507
+ )
2508
+ );
2509
+
2510
+ // Add blogs tracking if multisite.
2511
+ if ( is_multisite() ) {
2512
+ $optional_components['blogs']['description'] = __( 'Record activity for new sites, posts, and comments across your network.', 'buddypress' );
2513
+ }
2514
+
2515
+ switch ( $type ) {
2516
+ case 'required' :
2517
+ $components = $required_components;
2518
+ break;
2519
+ case 'optional' :
2520
+ $components = $optional_components;
2521
+ break;
2522
+ case 'retired' :
2523
+ $components = $retired_components;
2524
+ break;
2525
+ case 'all' :
2526
+ default :
2527
+ $components = array_merge( $required_components, $optional_components, $retired_components );
2528
+ break;
2529
+ }
2530
+
2531
+ /**
2532
+ * Filters the list of component information.
2533
+ *
2534
+ * @since 2.6.0
2535
+ *
2536
+ * @param array $components Array of component information.
2537
+ * @param string $type Type of component list requested.
2538
+ * Possible values are 'all', 'optional', 'retired', 'required'.
2539
+ */
2540
+ return apply_filters( 'bp_core_get_components', $components, $type );
2541
+ }
2542
+
2543
  /** Nav Menu ******************************************************************/
2544
 
2545
  /**
2567
  return buddypress()->wp_nav_menu_items->loggedin;
2568
  }
2569
 
2570
+ // Pull up a list of items registered in BP's primary nav for the member.
2571
+ $bp_menu_items = buddypress()->members->nav->get_primary();
 
 
 
2572
 
2573
  // Some BP nav menu items will not be represented in bp_nav, because
2574
  // they are not real BP components. We add them manually here.
2696
  * @since 1.9.0
2697
  *
2698
  * @param string $slug The slug of the nav item: login, register, or one of the
2699
+ * slugs from the members navigation.
2700
  * @return string $nav_item_url The URL generated for the current user.
2701
  */
2702
  function bp_nav_menu_get_item_url( $slug ) {
2791
  *
2792
  * @since 2.3.0
2793
  *
2794
+ * @return bool|array
 
 
 
 
 
 
2795
  */
2796
  function bp_upload_dir() {
2797
  $bp = buddypress();
3289
  *
3290
  * @since 2.5.0
3291
  *
3292
+ * @param string $text Text to replace tokens in.
3293
+ * @param array $tokens Token names and replacement values for the $text.
3294
  * @return string
3295
  */
3296
  function bp_core_replace_tokens_in_text( $text, $tokens ) {
3327
 
3328
  /**
3329
  * Get a list of emails for populating the email post type.
3330
+ *
3331
  * @since 2.5.1
3332
  *
3333
  * @return array
3404
  /* translators: do not remove {} brackets or translate its contents. */
3405
  'post_content' => __( "Group details for the group &quot;<a href=\"{{{group.url}}}\">{{group.name}}</a>&quot; were updated:\n<blockquote>{{changed_text}}</blockquote>", 'buddypress' ),
3406
  /* translators: do not remove {} brackets or translate its contents. */
3407
+ 'post_excerpt' => __( "Group details for the group \"{{group.name}}\" were updated:\n\n{{changed_text}}\n\nTo view the group, visit: {{{group.url}}}", 'buddypress' ),
3408
  ),
3409
  'groups-invitation' => array(
3410
  /* translators: do not remove {} brackets or translate its contents. */
3412
  /* translators: do not remove {} brackets or translate its contents. */
3413
  'post_content' => __( "<a href=\"{{{inviter.url}}}\">{{inviter.name}}</a> has invited you to join the group: &quot;{{group.name}}&quot;.\n<a href=\"{{{invites.url}}}\">Go here to accept your invitation</a> or <a href=\"{{{group.url}}}\">visit the group</a> to learn more.", 'buddypress' ),
3414
  /* translators: do not remove {} brackets or translate its contents. */
3415
+ 'post_excerpt' => __( "{{inviter.name}} has invited you to join the group: \"{{group.name}}\".\n\nTo accept your invitation, visit: {{{invites.url}}}\n\nTo learn more about the group, visit: {{{group.url}}}.\nTo view {{inviter.name}}'s profile, visit: {{{inviter.url}}}", 'buddypress' ),
3416
  ),
3417
  'groups-member-promoted' => array(
3418
  /* translators: do not remove {} brackets or translate its contents. */
3420
  /* translators: do not remove {} brackets or translate its contents. */
3421
  'post_content' => __( "You have been promoted to <b>{{promoted_to}}</b> in the group &quot;<a href=\"{{{group.url}}}\">{{group.name}}</a>&quot;.", 'buddypress' ),
3422
  /* translators: do not remove {} brackets or translate its contents. */
3423
+ 'post_excerpt' => __( "You have been promoted to {{promoted_to}} in the group: \"{{group.name}}\".\n\nTo visit the group, go to: {{{group.url}}}", 'buddypress' ),
3424
  ),
3425
  'groups-membership-request' => array(
3426
  /* translators: do not remove {} brackets or translate its contents. */
3428
  /* translators: do not remove {} brackets or translate its contents. */
3429
  'post_content' => __( "<a href=\"{{{profile.url}}}\">{{requesting-user.name}}</a> wants to join the group &quot;{{group.name}}&quot;. As you are an administrator of this group, you must either accept or reject the membership request.\n\n<a href=\"{{{group-requests.url}}}\">Go here to manage this</a> and all other pending requests.", 'buddypress' ),
3430
  /* translators: do not remove {} brackets or translate its contents. */
3431
+ 'post_excerpt' => __( "{{requesting-user.name}} wants to join the group \"{{group.name}}\". As you are the administrator of this group, you must either accept or reject the membership request.\n\nTo manage this and all other pending requests, visit: {{{group-requests.url}}}\n\nTo view {{requesting-user.name}}'s profile, visit: {{{profile.url}}}", 'buddypress' ),
3432
  ),
3433
  'messages-unread' => array(
3434
  /* translators: do not remove {} brackets or translate its contents. */
3436
  /* translators: do not remove {} brackets or translate its contents. */
3437
  'post_content' => __( "{{sender.name}} sent you a new message: &quot;{{usersubject}}&quot;\n\n<blockquote>&quot;{{usermessage}}&quot;</blockquote>\n\n<a href=\"{{{message.url}}}\">Go to the discussion</a> to reply or catch up on the conversation.", 'buddypress' ),
3438
  /* translators: do not remove {} brackets or translate its contents. */
3439
+ 'post_excerpt' => __( "{{sender.name}} sent you a new message: \"{{usersubject}}\"\n\n\"{{usermessage}}\"\n\nGo to the discussion to reply or catch up on the conversation: {{{message.url}}}", 'buddypress' ),
3440
  ),
3441
  'settings-verify-email-change' => array(
3442
  /* translators: do not remove {} brackets or translate its contents. */
3443
  'post_title' => __( '[{{{site.name}}}] Verify your new email address', 'buddypress' ),
3444
  /* translators: do not remove {} brackets or translate its contents. */
3445
+ 'post_content' => __( "You recently changed the email address associated with your account on {{site.name}} to {{user.email}}. If this is correct, <a href=\"{{{verify.url}}}\">go here to confirm the change</a>.\n\nOtherwise, you can safely ignore and delete this email if you have changed your mind, or if you think you have received this email in error.", 'buddypress' ),
3446
  /* translators: do not remove {} brackets or translate its contents. */
3447
+ 'post_excerpt' => __( "You recently changed the email address associated with your account on {{site.name}} to {{user.email}}. If this is correct, go to the following link to confirm the change: {{{verify.url}}}\n\nOtherwise, you can safely ignore and delete this email if you have changed your mind, or if you think you have received this email in error.", 'buddypress' ),
3448
  ),
3449
  'groups-membership-request-accepted' => array(
3450
  /* translators: do not remove {} brackets or translate its contents. */
3452
  /* translators: do not remove {} brackets or translate its contents. */
3453
  'post_content' => __( "Your membership request for the group &quot;<a href=\"{{{group.url}}}\">{{group.name}}</a>&quot; has been accepted.", 'buddypress' ),
3454
  /* translators: do not remove {} brackets or translate its contents. */
3455
+ 'post_excerpt' => __( "Your membership request for the group \"{{group.name}}\" has been accepted.\n\nTo view the group, visit: {{{group.url}}}", 'buddypress' ),
3456
  ),
3457
  'groups-membership-request-rejected' => array(
3458
  /* translators: do not remove {} brackets or translate its contents. */
3460
  /* translators: do not remove {} brackets or translate its contents. */
3461
  'post_content' => __( "Your membership request for the group &quot;<a href=\"{{{group.url}}}\">{{group.name}}</a>&quot; has been rejected.", 'buddypress' ),
3462
  /* translators: do not remove {} brackets or translate its contents. */
3463
+ 'post_excerpt' => __( "Your membership request for the group \"{{group.name}}\" has been rejected.\n\nTo request membership again, visit: {{{group.url}}}", 'buddypress' ),
3464
  ),
3465
  );
3466
  }
3469
  * Get a list of emails for populating email type taxonomy terms.
3470
  *
3471
  * @since 2.5.1
3472
+ * @since 2.7.0 $field argument added.
3473
+ *
3474
+ * @param string $field Optional; defaults to "description" for backwards compatibility. Other values: "all".
3475
+ * @return array {
3476
+ * The array of email types and their schema.
3477
+ *
3478
+ * @type string $description The description of the action which causes this to trigger.
3479
+ * @type array $unsubscribe {
3480
+ * Replacing this with false indicates that a user cannot unsubscribe from this type.
3481
+ *
3482
+ * @type string $meta_key The meta_key used to toggle the email setting for this notification.
3483
+ * @type string $message The message shown when the user has successfully unsubscribed.
3484
+ * }
3485
+ */
3486
+ function bp_email_get_type_schema( $field = 'description' ) {
3487
+ $activity_comment = array(
3488
+ 'description' => __( 'A member has replied to an activity update that the recipient posted.', 'buddypress' ),
3489
+ 'unsubscribe' => array(
3490
+ 'meta_key' => 'notification_activity_new_reply',
3491
+ 'message' => __( 'You will no longer receive emails when someone replies to an update or comment you posted.', 'buddypress' ),
3492
+ ),
3493
+ );
3494
+
3495
+ $activity_comment_author = array(
3496
+ 'description' => __( 'A member has replied to a comment on an activity update that the recipient posted.', 'buddypress' ),
3497
+ 'unsubscribe' => array(
3498
+ 'meta_key' => 'notification_activity_new_reply',
3499
+ 'message' => __( 'You will no longer receive emails when someone replies to an update or comment you posted.', 'buddypress' ),
3500
+ ),
3501
+ );
3502
+
3503
+ $activity_at_message = array(
3504
+ 'description' => __( 'Recipient was mentioned in an activity update.', 'buddypress' ),
3505
+ 'unsubscribe' => array(
3506
+ 'meta_key' => 'notification_activity_new_mention',
3507
+ 'message' => __( 'You will no longer receive emails when someone mentions you in an update.', 'buddypress' ),
3508
+ ),
3509
+ );
3510
+
3511
+ $groups_at_message = array(
3512
+ 'description' => __( 'Recipient was mentioned in a group activity update.', 'buddypress' ),
3513
+ 'unsubscribe' => array(
3514
+ 'meta_key' => 'notification_activity_new_mention',
3515
+ 'message' => __( 'You will no longer receive emails when someone mentions you in an update.', 'buddypress' ),
3516
+ ),
3517
+ );
3518
+
3519
+ $core_user_registration = array(
3520
+ 'description' => __( 'Recipient has registered for an account.', 'buddypress' ),
3521
+ 'unsubscribe' => false,
3522
+ );
3523
+
3524
+ $core_user_registration_with_blog = array(
3525
+ 'description' => __( 'Recipient has registered for an account and site.', 'buddypress' ),
3526
+ 'unsubscribe' => false,
3527
+ );
3528
+
3529
+ $friends_request = array(
3530
+ 'description' => __( 'A member has sent a friend request to the recipient.', 'buddypress' ),
3531
+ 'unsubscribe' => array(
3532
+ 'meta_key' => 'notification_friends_friendship_request',
3533
+ 'message' => __( 'You will no longer receive emails when someone sends you a friend request.', 'buddypress' ),
3534
+ ),
3535
+ );
3536
+
3537
+ $friends_request_accepted = array(
3538
+ 'description' => __( 'Recipient has had a friend request accepted by a member.', 'buddypress' ),
3539
+ 'unsubscribe' => array(
3540
+ 'meta_key' => 'notification_friends_friendship_accepted',
3541
+ 'message' => __( 'You will no longer receive emails when someone accepts your friendship request.', 'buddypress' ),
3542
+ ),
3543
+ );
3544
+
3545
+ $groups_details_updated = array(
3546
+ 'description' => __( "A group's details were updated.", 'buddypress' ),
3547
+ 'unsubscribe' => array(
3548
+ 'meta_key' => 'notification_groups_group_updated',
3549
+ 'message' => __( 'You will no longer receive emails when one of your groups is updated.', 'buddypress' ),
3550
+ ),
3551
+ );
3552
+
3553
+ $groups_details_updated = array(
3554
+ 'description' => __( "A group's details were updated.", 'buddypress' ),
3555
+ 'unsubscribe' => array(
3556
+ 'meta_key' => 'notification_groups_group_updated',
3557
+ 'message' => __( 'You will no longer receive emails when one of your groups is updated.', 'buddypress' ),
3558
+ ),
3559
+ );
3560
+
3561
+ $groups_invitation = array(
3562
+ 'description' => __( 'A member has sent a group invitation to the recipient.', 'buddypress' ),
3563
+ 'unsubscribe' => array(
3564
+ 'meta_key' => 'notification_groups_invite',
3565
+ 'message' => __( 'You will no longer receive emails when you are invited to join a group.', 'buddypress' ),
3566
+ ),
3567
+ );
3568
+
3569
+ $groups_member_promoted = array(
3570
+ 'description' => __( "Recipient's status within a group has changed.", 'buddypress' ),
3571
+ 'unsubscribe' => array(
3572
+ 'meta_key' => 'notification_groups_admin_promotion',
3573
+ 'message' => __( 'You will no longer receive emails when you have been promoted in a group.', 'buddypress' ),
3574
+ ),
3575
+ );
3576
+
3577
+ $groups_member_promoted = array(
3578
+ 'description' => __( "Recipient's status within a group has changed.", 'buddypress' ),
3579
+ 'unsubscribe' => array(
3580
+ 'meta_key' => 'notification_groups_admin_promotion',
3581
+ 'message' => __( 'You will no longer receive emails when you have been promoted in a group.', 'buddypress' ),
3582
+ ),
3583
+ );
3584
+
3585
+ $groups_membership_request = array(
3586
+ 'description' => __( 'A member has requested permission to join a group.', 'buddypress' ),
3587
+ 'unsubscribe' => array(
3588
+ 'meta_key' => 'notification_groups_membership_request',
3589
+ 'message' => __( 'You will no longer receive emails when someone requests to be a member of your group.', 'buddypress' ),
3590
+ ),
3591
+ );
3592
+
3593
+ $messages_unread = array(
3594
+ 'description' => __( 'Recipient has received a private message.', 'buddypress' ),
3595
+ 'unsubscribe' => array(
3596
+ 'meta_key' => 'notification_messages_new_message',
3597
+ 'message' => __( 'You will no longer receive emails when someone sends you a message.', 'buddypress' ),
3598
+ ),
3599
+ );
3600
+
3601
+ $settings_verify_email_change = array(
3602
+ 'description' => __( 'Recipient has changed their email address.', 'buddypress' ),
3603
+ 'unsubscribe' => false,
3604
+ );
3605
+
3606
+ $groups_membership_request_accepted = array(
3607
+ 'description' => __( 'Recipient had requested to join a group, which was accepted.', 'buddypress' ),
3608
+ 'unsubscribe' => array(
3609
+ 'meta_key' => 'notification_membership_request_completed',
3610
+ 'message' => __( 'You will no longer receive emails when your request to join a group has been accepted or denied.', 'buddypress' ),
3611
+ ),
3612
+ );
3613
+
3614
+ $groups_membership_request_rejected = array(
3615
+ 'description' => __( 'Recipient had requested to join a group, which was rejected.', 'buddypress' ),
3616
+ 'unsubscribe' => array(
3617
+ 'meta_key' => 'notification_membership_request_completed',
3618
+ 'message' => __( 'You will no longer receive emails when your request to join a group has been accepted or denied.', 'buddypress' ),
3619
+ ),
3620
+ );
3621
+
3622
+ $types = array(
3623
+ 'activity-comment' => $activity_comment,
3624
+ 'activity-comment-author' => $activity_comment_author,
3625
+ 'activity-at-message' => $activity_at_message,
3626
+ 'groups-at-message' => $groups_at_message,
3627
+ 'core-user-registration' => $core_user_registration,
3628
+ 'core-user-registration-with-blog' => $core_user_registration_with_blog,
3629
+ 'friends-request' => $friends_request,
3630
+ 'friends-request-accepted' => $friends_request_accepted,
3631
+ 'groups-details-updated' => $groups_details_updated,
3632
+ 'groups-invitation' => $groups_invitation,
3633
+ 'groups-member-promoted' => $groups_member_promoted,
3634
+ 'groups-membership-request' => $groups_membership_request,
3635
+ 'messages-unread' => $messages_unread,
3636
+ 'settings-verify-email-change' => $settings_verify_email_change,
3637
+ 'groups-membership-request-accepted' => $groups_membership_request_accepted,
3638
+ 'groups-membership-request-rejected' => $groups_membership_request_rejected,
3639
+ );
3640
+
3641
+ if ( $field !== 'all' ) {
3642
+ return wp_list_pluck( $types, $field );
3643
+ } else {
3644
+ return $types;
3645
+ }
3646
+ }
3647
+
3648
+ /**
3649
+ * Handles unsubscribing user from notification emails.
3650
  *
3651
+ * @since 2.7.0
3652
  */
3653
+ function bp_email_unsubscribe_handler() {
3654
+ $emails = bp_email_get_type_schema( 'all' );
3655
+ $raw_email_type = ! empty( $_GET['nt'] ) ? $_GET['nt'] : '';
3656
+ $raw_hash = ! empty( $_GET['nh'] ) ? $_GET['nh'] : '';
3657
+ $raw_user_id = ! empty( $_GET['uid'] ) ? absint( $_GET['uid'] ) : 0;
3658
+ $new_hash = hash_hmac( 'sha1', "{$raw_email_type}:{$raw_user_id}", bp_email_get_salt() );
3659
+
3660
+ // Check required values.
3661
+ if ( ! $raw_user_id || ! $raw_email_type || ! $raw_hash || ! array_key_exists( $raw_email_type, $emails ) ) {
3662
+ $redirect_to = site_url( 'wp-login.php' );
3663
+ $result_msg = __( 'Something has gone wrong.', 'buddypress' );
3664
+ $unsub_msg = __( 'Please log in and go to your settings to unsubscribe from notification emails.', 'buddypress' );
3665
+
3666
+ // Check valid hash.
3667
+ } elseif ( ! hash_equals( $new_hash, $raw_hash ) ) {
3668
+ $redirect_to = site_url( 'wp-login.php' );
3669
+ $result_msg = __( 'Something has gone wrong.', 'buddypress' );
3670
+ $unsub_msg = __( 'Please log in and go to your settings to unsubscribe from notification emails.', 'buddypress' );
3671
+
3672
+ // Don't let authenticated users unsubscribe other users' email notifications.
3673
+ } elseif ( is_user_logged_in() && get_current_user_id() !== $raw_user_id ) {
3674
+ $result_msg = __( 'Something has gone wrong.', 'buddypress' );
3675
+ $unsub_msg = __( 'Please go to your notifications settings to unsubscribe from emails.', 'buddypress' );
3676
+
3677
+ if ( bp_is_active( 'settings' ) ) {
3678
+ $redirect_to = sprintf(
3679
+ '%s%s/notifications/',
3680
+ bp_core_get_user_domain( get_current_user_id() ),
3681
+ bp_get_settings_slug()
3682
+ );
3683
+ } else {
3684
+ $redirect_to = bp_core_get_user_domain( get_current_user_id() );
3685
+ }
3686
+
3687
+ } else {
3688
+ if ( bp_is_active( 'settings' ) ) {
3689
+ $redirect_to = sprintf(
3690
+ '%s%s/notifications/',
3691
+ bp_core_get_user_domain( $raw_user_id ),
3692
+ bp_get_settings_slug()
3693
+ );
3694
+ } else {
3695
+ $redirect_to = bp_core_get_user_domain( $raw_user_id );
3696
+ }
3697
+
3698
+ // Unsubscribe.
3699
+ $meta_key = $emails[ $raw_email_type ]['unsubscribe']['meta_key'];
3700
+ bp_update_user_meta( $raw_user_id, $meta_key, 'no' );
3701
+
3702
+ $result_msg = $emails[ $raw_email_type ]['unsubscribe']['message'];
3703
+ $unsub_msg = __( 'You can change this or any other email notification preferences in your email settings.', 'buddypress' );
3704
+ }
3705
+
3706
+ $message = sprintf(
3707
+ '%1$s <a href="%2$s">%3$s</a>',
3708
+ $result_msg,
3709
+ esc_url( $redirect_to ),
3710
+ esc_html( $unsub_msg )
3711
+ );
3712
+
3713
+ bp_core_add_message( $message );
3714
+ bp_core_redirect( bp_core_get_user_domain( $raw_user_id ) );
3715
+
3716
+ exit;
3717
+ }
3718
+
3719
+ /**
3720
+ * Creates unsubscribe link for notification emails.
3721
+ *
3722
+ * @since 2.7.0
3723
+ *
3724
+ * @param string $redirect_to The URL to which the unsubscribe query string is appended.
3725
+ * @param array $args {
3726
+ * Used to build unsubscribe query string.
3727
+ *
3728
+ * @type string $notification_type Which notification type is being sent.
3729
+ * @type string $user_id The ID of the user to whom the notification is sent.
3730
+ * @type string $redirect_to Optional. The url to which the user will be redirected. Default is the activity directory.
3731
+ * }
3732
+ * @return string The unsubscribe link.
3733
+ */
3734
+ function bp_email_get_unsubscribe_link( $args ) {
3735
+ $emails = bp_email_get_type_schema( 'all' );
3736
+
3737
+ if ( empty( $args['notification_type'] ) || ! array_key_exists( $args['notification_type'], $emails ) ) {
3738
+ return site_url( 'wp-login.php' );
3739
+ }
3740
+
3741
+ $email_type = $args['notification_type'];
3742
+ $redirect_to = ! empty( $args['redirect_to'] ) ? $args['redirect_to'] : site_url();
3743
+ $user_id = (int) $args['user_id'];
3744
+
3745
+ // Bail out if the activity type is not un-unsubscribable.
3746
+ if ( empty( $emails[ $email_type ]['unsubscribe'] ) ) {
3747
+ return '';
3748
+ }
3749
+
3750
+ $link = add_query_arg(
3751
+ array(
3752
+ 'action' => 'unsubscribe',
3753
+ 'nh' => hash_hmac( 'sha1', "{$email_type}:{$user_id}", bp_email_get_salt() ),
3754
+ 'nt' => $args['notification_type'],
3755
+ 'uid' => $user_id,
3756
+ ),
3757
+ $redirect_to
3758
  );
3759
+
3760
+ /**
3761
+ * Filters the unsubscribe link.
3762
+ *
3763
+ * @since 2.7.0
3764
+ */
3765
+ return apply_filters( 'bp_email_get_link', $link, $redirect_to, $args );
3766
+ }
3767
+
3768
+ /**
3769
+ * Get a persistent salt for email unsubscribe links.
3770
+ *
3771
+ * @since 2.7.0
3772
+ *
3773
+ * @return string|null Returns null if value isn't set, otherwise string.
3774
+ */
3775
+ function bp_email_get_salt() {
3776
+ return bp_get_option( 'bp-emails-unsubscribe-salt', null );
3777
  }
bp-core/bp-core-loader.php CHANGED
@@ -12,14 +12,10 @@
12
  // Exit if accessed directly.
13
  defined( 'ABSPATH' ) || exit;
14
 
15
- require dirname( __FILE__ ) . '/classes/class-bp-core.php';
16
-
17
  /**
18
- * Set up the BuddyPress Core component.
19
  *
20
  * @since 1.6.0
21
- *
22
- * @global BuddyPress $bp BuddyPress global settings object.
23
  */
24
  function bp_setup_core() {
25
  buddypress()->core = new BP_Core();
12
  // Exit if accessed directly.
13
  defined( 'ABSPATH' ) || exit;
14
 
 
 
15
  /**
16
+ * Set up the bp-core component.
17
  *
18
  * @since 1.6.0
 
 
19
  */
20
  function bp_setup_core() {
21
  buddypress()->core = new BP_Core();
bp-core/bp-core-moderation.php CHANGED
@@ -20,11 +20,6 @@ defined( 'ABSPATH' ) || exit;
20
  *
21
  * @since 1.6.0
22
  *
23
- * @uses current_user_can() To check if the current user can throttle.
24
- * @uses bp_get_option() To get the throttle time.
25
- * @uses get_transient() To get the last posted transient of the ip.
26
- * @uses get_user_meta() To get the last posted meta of the user.
27
- *
28
  * @param int $user_id User id to check for flood.
29
  * @return bool True if there is no flooding, false if there is.
30
  */
@@ -52,17 +47,15 @@ function bp_core_check_for_flood( $user_id = 0 ) {
52
  * Check for moderation keys and too many links.
53
  *
54
  * @since 1.6.0
 
55
  *
56
- * @uses bp_current_author_ip() To get current user IP address.
57
- * @uses bp_current_author_ua() To get current user agent.
58
- * @uses bp_current_user_can() Allow super admins to bypass blacklist.
59
- *
60
- * @param int $user_id Topic or reply author ID.
61
- * @param string $title The title of the content.
62
- * @param string $content The content being posted.
63
  * @return bool True if test is passed, false if fail.
64
  */
65
- function bp_core_check_for_moderation( $user_id = 0, $title = '', $content = '' ) {
66
 
67
  /**
68
  * Filters whether or not to bypass checking for moderation keys and too many links.
@@ -136,7 +129,11 @@ function bp_core_check_for_moderation( $user_id = 0, $title = '', $content = ''
136
 
137
  // Das ist zu viele links!
138
  if ( $num_links >= $max_links ) {
139
- return false;
 
 
 
 
140
  }
141
  }
142
 
@@ -173,9 +170,11 @@ function bp_core_check_for_moderation( $user_id = 0, $title = '', $content = ''
173
 
174
  // Check each user data for current word.
175
  if ( preg_match( $pattern, $post_data ) ) {
176
-
177
- // Post does not pass.
178
- return false;
 
 
179
  }
180
  }
181
  }
@@ -189,17 +188,17 @@ function bp_core_check_for_moderation( $user_id = 0, $title = '', $content = ''
189
  * Check for blocked keys.
190
  *
191
  * @since 1.6.0
 
192
  *
193
- * @uses bp_current_author_ip() To get current user IP address.
194
- * @uses bp_current_author_ua() To get current user agent.
195
- * @uses bp_current_user_can() Allow super admins to bypass blacklist.
196
  *
197
- * @param int $user_id Topic or reply author ID.
198
- * @param string $title The title of the content.
199
- * @param string $content The content being posted.
 
200
  * @return bool True if test is passed, false if fail.
201
  */
202
- function bp_core_check_for_blacklist( $user_id = 0, $title = '', $content = '' ) {
203
 
204
  /**
205
  * Filters whether or not to bypass checking for blocked keys.
@@ -284,9 +283,11 @@ function bp_core_check_for_blacklist( $user_id = 0, $title = '', $content = '' )
284
 
285
  // Check each user data for current word.
286
  if ( preg_match( $pattern, $post_data ) ) {
287
-
288
- // Post does not pass.
289
- return false;
 
 
290
  }
291
  }
292
  }
20
  *
21
  * @since 1.6.0
22
  *
 
 
 
 
 
23
  * @param int $user_id User id to check for flood.
24
  * @return bool True if there is no flooding, false if there is.
25
  */
47
  * Check for moderation keys and too many links.
48
  *
49
  * @since 1.6.0
50
+ * @since 2.6.0 Added $error_type parameter.
51
  *
52
+ * @param int $user_id User ID.
53
+ * @param string $title The title of the content.
54
+ * @param string $content The content being posted.
55
+ * @param string $error_type The error type to return. Either 'bool' or 'wp_error'.
 
 
 
56
  * @return bool True if test is passed, false if fail.
57
  */
58
+ function bp_core_check_for_moderation( $user_id = 0, $title = '', $content = '', $error_type = 'bool' ) {
59
 
60
  /**
61
  * Filters whether or not to bypass checking for moderation keys and too many links.
129
 
130
  // Das ist zu viele links!
131
  if ( $num_links >= $max_links ) {
132
+ if ( 'bool' === $error_type ) {
133
+ return false;
134
+ } else {
135
+ return new WP_Error( 'bp_moderation_too_many_links', __( 'You have posted too many links', 'buddypress' ) );
136
+ }
137
  }
138
  }
139
 
170
 
171
  // Check each user data for current word.
172
  if ( preg_match( $pattern, $post_data ) ) {
173
+ if ( 'bool' === $error_type ) {
174
+ return false;
175
+ } else {
176
+ return new WP_Error( 'bp_moderation_word_match', _x( 'You have posted an inappropriate word.', 'Comment moderation', 'buddypress' ) );
177
+ }
178
  }
179
  }
180
  }
188
  * Check for blocked keys.
189
  *
190
  * @since 1.6.0
191
+ * @since 2.6.0 Added $error_type parameter.
192
  *
193
+ * @todo Why don't we use wp_blacklist_check() for this?
 
 
194
  *
195
+ * @param int $user_id User ID.
196
+ * @param string $title The title of the content.
197
+ * @param string $content The content being posted.
198
+ * @param string $error_type The error type to return. Either 'bool' or 'wp_error'.
199
  * @return bool True if test is passed, false if fail.
200
  */
201
+ function bp_core_check_for_blacklist( $user_id = 0, $title = '', $content = '', $error_type = 'bool' ) {
202
 
203
  /**
204
  * Filters whether or not to bypass checking for blocked keys.
283
 
284
  // Check each user data for current word.
285
  if ( preg_match( $pattern, $post_data ) ) {
286
+ if ( 'bool' === $error_type ) {
287
+ return false;
288
+ } else {
289
+ return new WP_Error( 'bp_moderation_blacklist_match', _x( 'You have posted an inappropriate word.', 'Comment blacklist', 'buddypress' ) );
290
+ }
291
  }
292
  }
293
  }
bp-core/bp-core-options.php CHANGED
@@ -13,6 +13,9 @@ defined( 'ABSPATH' ) || exit;
13
  /**
14
  * Get the default site options and their values.
15
  *
 
 
 
16
  * @since 1.6.0
17
  *
18
  * @return array Filtered option names and values.
@@ -73,6 +76,9 @@ function bp_get_default_options() {
73
  // The ID for the current theme package.
74
  '_bp_theme_package_id' => 'legacy',
75
 
 
 
 
76
  /* Groups ************************************************************/
77
 
78
  // @todo Move this into the groups component
@@ -94,11 +100,14 @@ function bp_get_default_options() {
94
  // Force the BuddyBar.
95
  '_bp_force_buddybar' => false,
96
 
97
- /* Legacy theme *********************************************/
98
 
99
- // Whether to register the bp-default themes directory.
100
  '_bp_retain_bp_default' => false,
101
 
 
 
 
102
  /* Widgets **************************************************/
103
  'widget_bp_core_login_widget' => false,
104
  'widget_bp_core_members_widget' => false,
@@ -125,10 +134,6 @@ function bp_get_default_options() {
125
  * Non-destructive, so existing settings will not be overridden.
126
  *
127
  * @since 1.6.0
128
- *
129
- * @uses bp_get_default_options() To get default options.
130
- * @uses add_option() Adds default options.
131
- * @uses do_action() Calls 'bp_add_options'.
132
  */
133
  function bp_add_options() {
134
 
@@ -159,10 +164,6 @@ function bp_add_options() {
159
  * Currently unused.
160
  *
161
  * @since 1.6.0
162
- *
163
- * @uses bp_get_default_options() To get default options.
164
- * @uses delete_option() Removes default options.
165
- * @uses do_action() Calls 'bp_delete_options'.
166
  */
167
  function bp_delete_options() {
168
 
@@ -190,10 +191,6 @@ function bp_delete_options() {
190
  * Currently unused.
191
  *
192
  * @since 1.6.0
193
- *
194
- * @uses bp_get_default_options() To get default options.
195
- * @uses add_filter() To add filters to 'pre_option_{$key}'.
196
- * @uses do_action() Calls 'bp_add_option_filters'.
197
  */
198
  function bp_setup_option_filters() {
199
 
@@ -251,9 +248,7 @@ function bp_pre_get_option( $value = false ) {
251
  *
252
  * The 'bp_get_option' filter is primarily for backward-compatibility.
253
  *
254
- * @since 1.2.0
255
- *
256
- * @uses bp_get_root_blog_id()
257
  *
258
  * @param string $option_name The option to be retrieved.
259
  * @param string $default Optional. Default value to be returned if the option
@@ -266,7 +261,7 @@ function bp_get_option( $option_name, $default = '' ) {
266
  /**
267
  * Filters the option value for the requested option.
268
  *
269
- * @since 1.2.0
270
  *
271
  * @param mixed $value The value for the option.
272
  */
@@ -298,8 +293,6 @@ function bp_add_option( $option_name, $value ) {
298
  *
299
  * @since 1.5.0
300
  *
301
- * @uses bp_get_root_blog_id()
302
- *
303
  * @param string $option_name The option key to be set.
304
  * @param string $value The value to be set.
305
  * @return bool True on success, false on failure.
@@ -317,8 +310,6 @@ function bp_update_option( $option_name, $value ) {
317
  *
318
  * @since 1.5.0
319
  *
320
- * @uses bp_get_root_blog_id()
321
- *
322
  * @param string $option_name The option key to be deleted.
323
  * @return bool True on success, false on failure.
324
  */
@@ -426,61 +417,16 @@ function bp_core_get_root_options() {
426
  $root_blog_options_meta = array_merge( $root_blog_options_meta, $network_options_meta );
427
  }
428
 
429
- // Missing some options, so do some one-time fixing.
430
- if ( empty( $root_blog_options_meta ) || ( count( $root_blog_options_meta ) < count( $root_blog_option_keys ) ) ) {
431
-
432
- // Get a list of the keys that are already populated.
433
- $existing_options = array();
434
- foreach( $root_blog_options_meta as $already_option ) {
435
- $existing_options[$already_option->name] = $already_option->value;
436
- }
437
-
438
- // Unset the query - We'll be resetting it soon.
439
- unset( $root_blog_options_meta );
440
-
441
- // Loop through options.
442
- foreach ( $root_blog_options as $old_meta_key => $old_meta_default ) {
443
-
444
- if ( isset( $existing_options[$old_meta_key] ) ) {
445
- continue;
446
- }
447
-
448
- // Get old site option.
449
- if ( is_multisite() ) {
450
- $old_meta_value = get_site_option( $old_meta_key );
451
- }
452
-
453
- // No site option so look in root blog.
454
- if ( empty( $old_meta_value ) ) {
455
- $old_meta_value = bp_get_option( $old_meta_key, $old_meta_default );
456
- }
457
-
458
- // Update the root blog option.
459
- bp_update_option( $old_meta_key, $old_meta_value );
460
-
461
- // Update the global array.
462
- $root_blog_options_meta[$old_meta_key] = $old_meta_value;
463
-
464
- // Clear out the value for the next time around.
465
- unset( $old_meta_value );
466
- }
467
-
468
- $root_blog_options_meta = array_merge( $root_blog_options_meta, $existing_options );
469
- unset( $existing_options );
470
-
471
- // We're all matched up.
472
- } else {
473
- // Loop through our results and make them usable.
474
- foreach ( $root_blog_options_meta as $root_blog_option ) {
475
- $root_blog_options[$root_blog_option->name] = $root_blog_option->value;
476
- }
477
 
478
- // Copy the options no the return val.
479
- $root_blog_options_meta = $root_blog_options;
480
 
481
- // Clean up our temporary copy.
482
- unset( $root_blog_options );
483
- }
484
 
485
  wp_cache_set( 'root_blog_options', $root_blog_options_meta, 'bp' );
486
  }
@@ -504,7 +450,7 @@ function bp_core_get_root_options() {
504
  *
505
  * @since 2.3.0
506
  *
507
- * @param string $option Name of the option key.
508
  * @return mixed Value, if found.
509
  */
510
  function bp_core_get_root_option( $option ) {
@@ -529,8 +475,6 @@ function bp_core_get_root_option( $option ) {
529
  *
530
  * @since 1.6.0
531
  *
532
- * @uses bp_get_option() To get the profile sync option.
533
- *
534
  * @param bool $default Optional. Fallback value if not found in the database.
535
  * Default: true.
536
  * @return bool True if profile sync is enabled, otherwise false.
@@ -552,8 +496,6 @@ function bp_disable_profile_sync( $default = false ) {
552
  *
553
  * @since 1.6.0
554
  *
555
- * @uses bp_get_option() To get the logged out Toolbar option.
556
- *
557
  * @param bool $default Optional. Fallback value if not found in the database.
558
  * Default: true.
559
  * @return bool True if the admin bar should be hidden for logged-out users,
@@ -576,8 +518,6 @@ function bp_hide_loggedout_adminbar( $default = true ) {
576
  *
577
  * @since 1.6.0
578
  *
579
- * @uses bp_get_option() To get the avatar uploads option.
580
- *
581
  * @param bool $default Optional. Fallback value if not found in the database.
582
  * Default: true.
583
  * @return bool True if avatar uploads are disabled, otherwise false.
@@ -599,8 +539,6 @@ function bp_disable_avatar_uploads( $default = true ) {
599
  *
600
  * @since 2.4.0
601
  *
602
- * @uses bp_get_option() To get the cover image uploads option.
603
- *
604
  * @param bool $default Optional. Fallback value if not found in the database.
605
  * Default: false.
606
  * @return bool True if cover image uploads are disabled, otherwise false.
@@ -656,8 +594,6 @@ function bp_disable_group_avatar_uploads( $default = null ) {
656
  *
657
  * @since 2.4.0
658
  *
659
- * @uses bp_get_option() To get the group cover image uploads option.
660
- *
661
  * @param bool $default Optional. Fallback value if not found in the database.
662
  * Default: false.
663
  * @return bool True if group cover image uploads are disabled, otherwise false.
@@ -679,8 +615,6 @@ function bp_disable_group_cover_image_uploads( $default = false ) {
679
  *
680
  * @since 1.6.0
681
  *
682
- * @uses bp_get_option() To get the account deletion option.
683
- *
684
  * @param bool $default Optional. Fallback value if not found in the database.
685
  * Default: true.
686
  * @return bool True if users are able to delete their own accounts, otherwise
@@ -704,7 +638,6 @@ function bp_disable_account_deletion( $default = false ) {
704
  * @since 1.6.0
705
  *
706
  * @todo split and move into blog and forum components.
707
- * @uses bp_get_option() To get the blog/forum comments option.
708
  *
709
  * @param bool $default Optional. Fallback value if not found in the database.
710
  * Default: false.
@@ -729,7 +662,6 @@ function bp_disable_blogforum_comments( $default = false ) {
729
  * @since 1.6.0
730
  *
731
  * @todo Move into groups component.
732
- * @uses bp_get_option() To get the group creation.
733
  *
734
  * @param bool $default Optional. Fallback value if not found in the database.
735
  * Default: true.
@@ -752,8 +684,6 @@ function bp_restrict_group_creation( $default = true ) {
752
  *
753
  * @since 1.6.0
754
  *
755
- * @uses bp_get_option() To get the BuddyBar option.
756
- *
757
  * @param bool $default Optional. Fallback value if not found in the database.
758
  * Default: true.
759
  * @return bool True if the BuddyBar should be forced on, otherwise false.
@@ -785,8 +715,6 @@ function bp_group_forums_root_id( $default = '0' ) {
785
  *
786
  * @since 1.6.0
787
  *
788
- * @uses bp_get_option() To get the root forum ID from the database.
789
- *
790
  * @param bool|string $default Optional. Default: '0'.
791
  * @return int The ID of the group forums root forum.
792
  */
@@ -807,8 +735,6 @@ function bp_group_forums_root_id( $default = '0' ) {
807
  *
808
  * @since 1.6.0
809
  *
810
- * @uses bp_get_option() To get the group forums option.
811
- *
812
  * @param bool $default Optional. Fallback value if not found in the database.
813
  * Default: true.
814
  * @return bool True if group forums are active, otherwise false.
@@ -830,8 +756,6 @@ function bp_is_group_forums_active( $default = true ) {
830
  *
831
  * @since 1.6.0
832
  *
833
- * @uses bp_get_option() To get the Akismet option.
834
- *
835
  * @param bool $default Optional. Fallback value if not found in the database.
836
  * Default: true.
837
  * @return bool True if Akismet is enabled, otherwise false.
@@ -853,8 +777,6 @@ function bp_is_akismet_active( $default = true ) {
853
  *
854
  * @since 2.0.0
855
  *
856
- * @uses bp_get_option() To get the Heartbeat option.
857
- *
858
  * @param bool $default Optional. Fallback value if not found in the database.
859
  * Default: true.
860
  * @return bool True if Heartbeat refresh is enabled, otherwise false.
@@ -876,8 +798,6 @@ function bp_is_activity_heartbeat_active( $default = true ) {
876
  *
877
  * @since 1.7.0
878
  *
879
- * @uses get_option() To get the theme package option.
880
- *
881
  * @param string $default Optional. Fallback value if not found in the database.
882
  * Default: 'legacy'.
883
  * @return string ID of the theme package.
13
  /**
14
  * Get the default site options and their values.
15
  *
16
+ * Default values should not be set by calls to `get_option()` or `get_site_option()` due to
17
+ * these causing load order problems with `bp_core_clear_root_options_cache()`; see #BP7227.
18
+ *
19
  * @since 1.6.0
20
  *
21
  * @return array Filtered option names and values.
76
  // The ID for the current theme package.
77
  '_bp_theme_package_id' => 'legacy',
78
 
79
+ // Email unsubscribe salt.
80
+ 'bp-emails-unsubscribe-salt' => '',
81
+
82
  /* Groups ************************************************************/
83
 
84
  // @todo Move this into the groups component
100
  // Force the BuddyBar.
101
  '_bp_force_buddybar' => false,
102
 
103
+ /* Legacy *********************************************/
104
 
105
+ // Do not register the bp-default themes directory.
106
  '_bp_retain_bp_default' => false,
107
 
108
+ // Ignore deprecated code.
109
+ '_bp_ignore_deprecated_code' => true,
110
+
111
  /* Widgets **************************************************/
112
  'widget_bp_core_login_widget' => false,
113
  'widget_bp_core_members_widget' => false,
134
  * Non-destructive, so existing settings will not be overridden.
135
  *
136
  * @since 1.6.0
 
 
 
 
137
  */
138
  function bp_add_options() {
139
 
164
  * Currently unused.
165
  *
166
  * @since 1.6.0
 
 
 
 
167
  */
168
  function bp_delete_options() {
169
 
191
  * Currently unused.
192
  *
193
  * @since 1.6.0
 
 
 
 
194
  */
195
  function bp_setup_option_filters() {
196
 
248
  *
249
  * The 'bp_get_option' filter is primarily for backward-compatibility.
250
  *
251
+ * @since 1.5.0
 
 
252
  *
253
  * @param string $option_name The option to be retrieved.
254
  * @param string $default Optional. Default value to be returned if the option
261
  /**
262
  * Filters the option value for the requested option.
263
  *
264
+ * @since 1.5.0
265
  *
266
  * @param mixed $value The value for the option.
267
  */
293
  *
294
  * @since 1.5.0
295
  *
 
 
296
  * @param string $option_name The option key to be set.
297
  * @param string $value The value to be set.
298
  * @return bool True on success, false on failure.
310
  *
311
  * @since 1.5.0
312
  *
 
 
313
  * @param string $option_name The option key to be deleted.
314
  * @return bool True on success, false on failure.
315
  */
417
  $root_blog_options_meta = array_merge( $root_blog_options_meta, $network_options_meta );
418
  }
419
 
420
+ // Loop through our results and make them usable.
421
+ foreach ( $root_blog_options_meta as $root_blog_option ) {
422
+ $root_blog_options[$root_blog_option->name] = $root_blog_option->value;
423
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
424
 
425
+ // Copy the options no the return val.
426
+ $root_blog_options_meta = $root_blog_options;
427
 
428
+ // Clean up our temporary copy.
429
+ unset( $root_blog_options );
 
430
 
431
  wp_cache_set( 'root_blog_options', $root_blog_options_meta, 'bp' );
432
  }
450
  *
451
  * @since 2.3.0
452
  *
453
+ * @param string $option Name of the option key.
454
  * @return mixed Value, if found.
455
  */
456
  function bp_core_get_root_option( $option ) {
475
  *
476
  * @since 1.6.0
477
  *
 
 
478
  * @param bool $default Optional. Fallback value if not found in the database.
479
  * Default: true.
480
  * @return bool True if profile sync is enabled, otherwise false.
496
  *
497
  * @since 1.6.0
498
  *
 
 
499
  * @param bool $default Optional. Fallback value if not found in the database.
500
  * Default: true.
501
  * @return bool True if the admin bar should be hidden for logged-out users,
518
  *
519
  * @since 1.6.0
520
  *
 
 
521
  * @param bool $default Optional. Fallback value if not found in the database.
522
  * Default: true.
523
  * @return bool True if avatar uploads are disabled, otherwise false.
539
  *
540
  * @since 2.4.0
541
  *
 
 
542
  * @param bool $default Optional. Fallback value if not found in the database.
543
  * Default: false.
544
  * @return bool True if cover image uploads are disabled, otherwise false.
594
  *
595
  * @since 2.4.0
596
  *
 
 
597
  * @param bool $default Optional. Fallback value if not found in the database.
598
  * Default: false.
599
  * @return bool True if group cover image uploads are disabled, otherwise false.
615
  *
616
  * @since 1.6.0
617
  *
 
 
618
  * @param bool $default Optional. Fallback value if not found in the database.
619
  * Default: true.
620
  * @return bool True if users are able to delete their own accounts, otherwise
638
  * @since 1.6.0
639
  *
640
  * @todo split and move into blog and forum components.
 
641
  *
642
  * @param bool $default Optional. Fallback value if not found in the database.
643
  * Default: false.
662
  * @since 1.6.0
663
  *
664
  * @todo Move into groups component.
 
665
  *
666
  * @param bool $default Optional. Fallback value if not found in the database.
667
  * Default: true.
684
  *
685
  * @since 1.6.0
686
  *
 
 
687
  * @param bool $default Optional. Fallback value if not found in the database.
688
  * Default: true.
689
  * @return bool True if the BuddyBar should be forced on, otherwise false.
715
  *
716
  * @since 1.6.0
717
  *
 
 
718
  * @param bool|string $default Optional. Default: '0'.
719
  * @return int The ID of the group forums root forum.
720
  */
735
  *
736
  * @since 1.6.0
737
  *
 
 
738
  * @param bool $default Optional. Fallback value if not found in the database.
739
  * Default: true.
740
  * @return bool True if group forums are active, otherwise false.
756
  *
757
  * @since 1.6.0
758
  *
 
 
759
  * @param bool $default Optional. Fallback value if not found in the database.
760
  * Default: true.
761
  * @return bool True if Akismet is enabled, otherwise false.
777
  *
778
  * @since 2.0.0
779
  *
 
 
780
  * @param bool $default Optional. Fallback value if not found in the database.
781
  * Default: true.
782
  * @return bool True if Heartbeat refresh is enabled, otherwise false.
798
  *
799
  * @since 1.7.0
800
  *
 
 
801
  * @param string $default Optional. Fallback value if not found in the database.
802
  * Default: 'legacy'.
803
  * @return string ID of the theme package.
bp-core/bp-core-taxonomy.php CHANGED
@@ -21,7 +21,7 @@ defined( 'ABSPATH' ) || exit;
21
  */
22
  function bp_register_default_taxonomies() {
23
  // Member Type.
24
- register_taxonomy( 'bp_member_type', 'user', array(
25
  'public' => false,
26
  ) );
27
 
@@ -44,6 +44,30 @@ function bp_register_default_taxonomies() {
44
  }
45
  add_action( 'bp_register_taxonomies', 'bp_register_default_taxonomies' );
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  /**
48
  * Set taxonomy terms on a BuddyPress object.
49
  *
@@ -58,20 +82,34 @@ add_action( 'bp_register_taxonomies', 'bp_register_default_taxonomies' );
58
  * @return array Array of term taxonomy IDs.
59
  */
60
  function bp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) {
61
- $is_root_blog = bp_is_root_blog();
62
 
63
- if ( ! $is_root_blog ) {
64
- switch_to_blog( bp_get_root_blog_id() );
 
65
  bp_register_taxonomies();
 
66
  }
67
 
68
- $retval = wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
69
 
70
- if ( ! $is_root_blog ) {
71
  restore_current_blog();
72
  }
73
 
74
- return $retval;
 
 
 
 
 
 
 
 
 
 
 
 
75
  }
76
 
77
  /**
@@ -87,17 +125,28 @@ function bp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) {
87
  * @return array
88
  */
89
  function bp_get_object_terms( $object_ids, $taxonomies, $args = array() ) {
90
- $is_root_blog = bp_is_root_blog();
91
-
92
- if ( ! $is_root_blog ) {
93
- switch_to_blog( bp_get_root_blog_id() );
94
- bp_register_taxonomies();
95
  }
96
 
97
- $retval = wp_get_object_terms( $object_ids, $taxonomies, $args );
 
 
 
 
 
 
 
98
 
99
- if ( ! $is_root_blog ) {
100
- restore_current_blog();
 
 
 
 
101
  }
102
 
103
  return $retval;
@@ -116,18 +165,115 @@ function bp_get_object_terms( $object_ids, $taxonomies, $args = array() ) {
116
  * @return bool|WP_Error True on success, false or WP_Error on failure.
117
  */
118
  function bp_remove_object_terms( $object_id, $terms, $taxonomy ) {
119
- $is_root_blog = bp_is_root_blog();
120
 
121
- if ( ! $is_root_blog ) {
122
- switch_to_blog( bp_get_root_blog_id() );
 
123
  bp_register_taxonomies();
 
124
  }
125
 
126
  $retval = wp_remove_object_terms( $object_id, $terms, $taxonomy );
127
 
128
- if ( ! $is_root_blog ) {
129
  restore_current_blog();
130
  }
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  return $retval;
133
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  */
22
  function bp_register_default_taxonomies() {
23
  // Member Type.
24
+ register_taxonomy( bp_get_member_type_tax_name(), 'user', array(
25
  'public' => false,
26
  ) );
27
 
44
  }
45
  add_action( 'bp_register_taxonomies', 'bp_register_default_taxonomies' );
46
 
47
+ /**
48
+ * Gets the ID of the site that BP should use for taxonomy term storage.
49
+ *
50
+ * Defaults to the root blog ID.
51
+ *
52
+ * @since 2.6.0
53
+ *
54
+ * @param string $taxonomy Taxonomy slug to check for.
55
+ * @return int
56
+ */
57
+ function bp_get_taxonomy_term_site_id( $taxonomy = '' ) {
58
+ $site_id = bp_get_root_blog_id();
59
+
60
+ /**
61
+ * Filters the ID of the site where BP should store taxonomy terms.
62
+ *
63
+ * @since 2.6.0
64
+ *
65
+ * @param int $site_id Site ID to cehck for.
66
+ * @param string $taxonomy Taxonomy slug to check for.
67
+ */
68
+ return (int) apply_filters( 'bp_get_taxonomy_term_site_id', $site_id, $taxonomy );
69
+ }
70
+
71
  /**
72
  * Set taxonomy terms on a BuddyPress object.
73
  *
82
  * @return array Array of term taxonomy IDs.
83
  */
84
  function bp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) {
85
+ $site_id = bp_get_taxonomy_term_site_id( $taxonomy );
86
 
87
+ $switched = false;
88
+ if ( $site_id !== get_current_blog_id() ) {
89
+ switch_to_blog( $site_id );
90
  bp_register_taxonomies();
91
+ $switched = true;
92
  }
93
 
94
+ $tt_ids = wp_set_object_terms( $object_id, $terms, $taxonomy, $append );
95
 
96
+ if ( $switched ) {
97
  restore_current_blog();
98
  }
99
 
100
+ /**
101
+ * Fires when taxonomy terms have been set on BuddyPress objects.
102
+ *
103
+ * @since 2.7.0
104
+ *
105
+ * @param int $object_id Object ID.
106
+ * @param array $terms Term or terms to remove.
107
+ * @param array $tt_ids Array of term taxonomy IDs.
108
+ * @param string $taxonomy Taxonomy name.
109
+ */
110
+ do_action( 'bp_set_object_terms', $object_id, $terms, $tt_ids, $taxonomy );
111
+
112
+ return $tt_ids;
113
  }
114
 
115
  /**
125
  * @return array
126
  */
127
  function bp_get_object_terms( $object_ids, $taxonomies, $args = array() ) {
128
+ // Different taxonomies must be stored on different sites.
129
+ $taxonomy_site_map = array();
130
+ foreach ( (array) $taxonomies as $taxonomy ) {
131
+ $taxonomy_site_id = bp_get_taxonomy_term_site_id( $taxonomy );
132
+ $taxonomy_site_map[ $taxonomy_site_id ][] = $taxonomy;
133
  }
134
 
135
+ $retval = array();
136
+ foreach ( $taxonomy_site_map as $taxonomy_site_id => $site_taxonomies ) {
137
+ $switched = false;
138
+ if ( $taxonomy_site_id !== get_current_blog_id() ) {
139
+ switch_to_blog( $taxonomy_site_id );
140
+ bp_register_taxonomies();
141
+ $switched = true;
142
+ }
143
 
144
+ $site_terms = wp_get_object_terms( $object_ids, $site_taxonomies, $args );
145
+ $retval = array_merge( $retval, $site_terms );
146
+
147
+ if ( $switched ) {
148
+ restore_current_blog();
149
+ }
150
  }
151
 
152
  return $retval;
165
  * @return bool|WP_Error True on success, false or WP_Error on failure.
166
  */
167
  function bp_remove_object_terms( $object_id, $terms, $taxonomy ) {
168
+ $site_id = bp_get_taxonomy_term_site_id( $taxonomy );
169
 
170
+ $switched = false;
171
+ if ( $site_id !== get_current_blog_id() ) {
172
+ switch_to_blog( $site_id );
173
  bp_register_taxonomies();
174
+ $switched = true;
175
  }
176
 
177
  $retval = wp_remove_object_terms( $object_id, $terms, $taxonomy );
178
 
179
+ if ( $switched ) {
180
  restore_current_blog();
181
  }
182
 
183
+ /**
184
+ * Fires when taxonomy terms have been removed from BuddyPress objects.
185
+ *
186
+ * @since 2.7.0
187
+ *
188
+ * @param int $object_id Object ID.
189
+ * @param array $terms Term or terms to remove.
190
+ * @param string $taxonomy Taxonomy name.
191
+ */
192
+ do_action( 'bp_remove_object_terms', $object_id, $terms, $taxonomy );
193
+
194
+ return $retval;
195
+ }
196
+
197
+ /**
198
+ * Retrieve IDs of objects in valid taxonomies and terms for BuddyPress-related taxonomies.
199
+ *
200
+ * Note that object IDs are from the `bp_get_taxonomy_term_site_id()`, which on some
201
+ * multisite configurations may not be the same as the current site.
202
+ *
203
+ * @since 2.7.0
204
+ *
205
+ * @see get_objects_in_term() for a full description of function and parameters.
206
+ *
207
+ * @param int|array $term_ids Term id or array of term ids of terms that will be used.
208
+ * @param string|array $taxonomies String of taxonomy name or Array of string values of taxonomy names.
209
+ * @param array|string $args Change the order of the object_ids, either ASC or DESC.
210
+ *
211
+ * @return WP_Error|array If the taxonomy does not exist, then WP_Error will be returned. On success,
212
+ * the array can be empty, meaning that there are no $object_ids found. When
213
+ * object IDs are found, an array of those IDs will be returned.
214
+ */
215
+ function bp_get_objects_in_term( $term_ids, $taxonomies, $args = array() ) {
216
+ // Different taxonomies may be stored on different sites.
217
+ $taxonomy_site_map = array();
218
+ foreach ( (array) $taxonomies as $taxonomy ) {
219
+ $taxonomy_site_id = bp_get_taxonomy_term_site_id( $taxonomy );
220
+ $taxonomy_site_map[ $taxonomy_site_id ][] = $taxonomy;
221
+ }
222
+
223
+ $retval = array();
224
+ foreach ( $taxonomy_site_map as $taxonomy_site_id => $site_taxonomies ) {
225
+ $switched = false;
226
+ if ( $taxonomy_site_id !== get_current_blog_id() ) {
227
+ switch_to_blog( $taxonomy_site_id );
228
+ bp_register_taxonomies();
229
+ $switched = true;
230
+ }
231
+
232
+ $site_objects = get_objects_in_term( $term_ids, $site_taxonomies, $args );
233
+ $retval = array_merge( $retval, $site_objects );
234
+
235
+ if ( $switched ) {
236
+ restore_current_blog();
237
+ }
238
+ }
239
+
240
  return $retval;
241
  }
242
+
243
+ /**
244
+ * Get term data for terms in BuddyPress taxonomies.
245
+ *
246
+ * Note that term data is from the `bp_get_taxonomy_term_site_id()`, which on some
247
+ * multisite configurations may not be the same as the current site.
248
+ *
249
+ * @since 2.7.0
250
+ *
251
+ * @see get_term_by() for a full description of function and parameters.
252
+ *
253
+ * @param string $field Either 'slug', 'name', 'id' (term_id), or 'term_taxonomy_id'
254
+ * @param string|int $value Search for this term value
255
+ * @param string $taxonomy Taxonomy name. Optional, if `$field` is 'term_taxonomy_id'.
256
+ * @param string $output Constant OBJECT, ARRAY_A, or ARRAY_N
257
+ * @param string $filter Optional, default is raw or no WordPress defined filter will applied.
258
+ *
259
+ * @return WP_Term|bool WP_Term instance on success. Will return false if `$taxonomy` does not exist
260
+ * or `$term` was not found.
261
+ */
262
+ function bp_get_term_by( $field, $value, $taxonomy = '', $output = OBJECT, $filter = 'raw' ) {
263
+ $site_id = bp_get_taxonomy_term_site_id( $taxonomy );
264
+
265
+ $switched = false;
266
+ if ( $site_id !== get_current_blog_id() ) {
267
+ switch_to_blog( $site_id );
268
+ bp_register_taxonomies();
269
+ $switched = true;
270
+ }
271
+
272
+ $term = get_term_by( $field, $value, $taxonomy, $output, $filter );
273
+
274
+ if ( $switched ) {
275
+ restore_current_blog();
276
+ }
277
+
278
+ return $term;
279
+ }
bp-core/bp-core-template-loader.php CHANGED
@@ -19,10 +19,6 @@ defined( 'ABSPATH' ) || exit;
19
  *
20
  * @since 1.7.0
21
  *
22
- * @uses bp_locate_template()
23
- * @uses load_template()
24
- * @uses get_template_part()
25
- *
26
  * @param string $slug Template part slug. Used to generate filenames,
27
  * eg 'friends' for 'friends.php'.
28
  * @param string|null $name Optional. Template part name. Used to generate
@@ -65,6 +61,24 @@ function bp_get_template_part( $slug, $name = null ) {
65
  return bp_locate_template( $templates, true, false );
66
  }
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  /**
69
  * Retrieve the name of the highest priority template file that exists.
70
  *
@@ -83,6 +97,11 @@ function bp_get_template_part( $slug, $name = null ) {
83
  */
84
  function bp_locate_template( $template_names, $load = false, $require_once = true ) {
85
 
 
 
 
 
 
86
  // No file found yet.
87
  $located = false;
88
  $template_locations = bp_get_template_stack();
@@ -123,10 +142,6 @@ function bp_locate_template( $template_names, $load = false, $require_once = tru
123
  */
124
  do_action( 'bp_locate_template', $located, $template_name, $template_names, $template_locations, $load, $require_once );
125
 
126
- // Maybe load the template if one was located.
127
- $use_themes = defined( 'WP_USE_THEMES' ) && WP_USE_THEMES;
128
- $doing_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX;
129
-
130
  /**
131
  * Filter here to allow/disallow template loading.
132
  *
@@ -134,15 +149,58 @@ function bp_locate_template( $template_names, $load = false, $require_once = tru
134
  *
135
  * @param bool $value True to load the template, false otherwise.
136
  */
137
- $load_template = (bool) apply_filters( 'bp_locate_template_and_load', $use_themes || $doing_ajax );
138
 
139
- if ( $load_template && ( true == $load ) && ! empty( $located ) ) {
140
  load_template( $located, $require_once );
141
  }
142
 
143
  return $located;
144
  }
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  /**
147
  * Register a new template stack location.
148
  *
@@ -303,10 +361,6 @@ function bp_buffer_template_part( $slug, $name = null, $echo = true ) {
303
  *
304
  * @since 1.7.0
305
  *
306
- * @uses bp_set_theme_compat_templates()
307
- * @uses bp_locate_template()
308
- * @uses bp_set_theme_compat_template()
309
- *
310
  * @param string $type Filename without extension.
311
  * @param array $templates An optional list of template candidates.
312
  * @return string Full path to file.
@@ -517,7 +571,6 @@ function bp_is_template_included() {
517
  * @since 1.7.0
518
  *
519
  * @global string $pagenow
520
- * @uses bp_locate_template()
521
  */
522
  function bp_load_theme_functions() {
523
  global $pagenow, $wp_query;
19
  *
20
  * @since 1.7.0
21
  *
 
 
 
 
22
  * @param string $slug Template part slug. Used to generate filenames,
23
  * eg 'friends' for 'friends.php'.
24
  * @param string|null $name Optional. Template part name. Used to generate
61
  return bp_locate_template( $templates, true, false );
62
  }
63
 
64
+ /**
65
+ * Get an asset template part.
66
+ *
67
+ * Basically the same as {@link bp_get_template_part()}, but with 'assets/'
68
+ * prepended to the slug.
69
+ *
70
+ * @since 2.6.0
71
+ *
72
+ * @see bp_get_template_part() for full documentation.
73
+ *
74
+ * @param string $slug Template slug.
75
+ * @param string|null $name Template name.
76
+ * @return string
77
+ */
78
+ function bp_get_asset_template_part( $slug, $name = null ) {
79
+ return bp_get_template_part( "assets/{$slug}", $name );
80
+ }
81
+
82
  /**
83
  * Retrieve the name of the highest priority template file that exists.
84
  *
97
  */
98
  function bp_locate_template( $template_names, $load = false, $require_once = true ) {
99
 
100
+ // Bail when there are no templates to locate
101
+ if ( empty( $template_names ) ) {
102
+ return false;
103
+ }
104
+
105
  // No file found yet.
106
  $located = false;
107
  $template_locations = bp_get_template_stack();
142
  */
143
  do_action( 'bp_locate_template', $located, $template_name, $template_names, $template_locations, $load, $require_once );
144
 
 
 
 
 
145
  /**
146
  * Filter here to allow/disallow template loading.
147
  *
149
  *
150
  * @param bool $value True to load the template, false otherwise.
151
  */
152
+ $load_template = (bool) apply_filters( 'bp_locate_template_and_load', true );
153
 
154
+ if ( $load_template && $load && ! empty( $located ) ) {
155
  load_template( $located, $require_once );
156
  }
157
 
158
  return $located;
159
  }
160
 
161
+ /**
162
+ * Get file data of the highest priority asset that exists.
163
+ *
164
+ * Similar to {@link bp_locate_template()}, but for files like CSS and JS.
165
+ *
166
+ * @since 2.6.0
167
+ *
168
+ * @param string $filename Relative filename to search for.
169
+ * @return array|bool Array of asset data if one is located (includes absolute filepath and URI).
170
+ * Boolean false on failure.
171
+ */
172
+ function bp_locate_template_asset( $filename ) {
173
+ // Ensure assets can be located when running from /src/.
174
+ if ( defined( 'BP_SOURCE_SUBDIRECTORY' ) && 'src' === BP_SOURCE_SUBDIRECTORY ) {
175
+ $filename = str_replace( '.min', '', $filename );
176
+ }
177
+
178
+ // Use bp_locate_template() to find our asset.
179
+ $located = bp_locate_template( $filename, false );
180
+ if ( false === $located ) {
181
+ return false;
182
+ }
183
+
184
+ // Set up data array.
185
+ $data = array();
186
+ $data['file'] = $data['uri'] = $located;
187
+
188
+ $find = array(
189
+ get_theme_root(),
190
+ bp_get_theme_compat_dir()
191
+ );
192
+
193
+ $replace = array(
194
+ get_theme_root_uri(),
195
+ bp_get_theme_compat_url()
196
+ );
197
+
198
+ // Make sure URI path is relative to site URL.
199
+ $data['uri'] = str_replace( $find, $replace, $data['uri'] );
200
+
201
+ return $data;
202
+ }
203
+
204
  /**
205
  * Register a new template stack location.
206
  *
361
  *
362
  * @since 1.7.0
363
  *
 
 
 
 
364
  * @param string $type Filename without extension.
365
  * @param array $templates An optional list of template candidates.
366
  * @return string Full path to file.
571
  * @since 1.7.0
572
  *
573
  * @global string $pagenow
 
574
  */
575
  function bp_load_theme_functions() {
576
  global $pagenow, $wp_query;
bp-core/bp-core-template.php CHANGED
@@ -13,7 +13,7 @@ defined( 'ABSPATH' ) || exit;
13
  /**
14
  * Output the "options nav", the secondary-level single item navigation menu.
15
  *
16
- * Uses the $bp->bp_options_nav global to render out the sub navigation for the
17
  * current component. Each component adds to its sub navigation array within
18
  * its own setup_nav() function.
19
  *
@@ -26,7 +26,6 @@ defined( 'ABSPATH' ) || exit;
26
  *
27
  * @since 1.0.0
28
  *
29
- * @uses bp_get_user_nav() Renders the navigation for a profile of a currently
30
  * viewed user.
31
  *
32
  * @param string $parent_slug Options nav slug.
@@ -40,35 +39,50 @@ function bp_get_options_nav( $parent_slug = '' ) {
40
  $component_index = !empty( $bp->displayed_user ) ? bp_current_component() : bp_get_root_slug( bp_current_component() );
41
  $selected_item = bp_current_action();
42
 
 
43
  if ( ! bp_is_single_item() ) {
44
- if ( !isset( $bp->bp_options_nav[$component_index] ) || count( $bp->bp_options_nav[$component_index] ) < 1 ) {
 
 
 
 
 
 
 
45
  return false;
46
- } else {
47
- $the_index = $component_index;
48
  }
 
 
49
  } else {
50
  $current_item = bp_current_item();
 
51
 
 
52
  if ( ! empty( $parent_slug ) ) {
53
  $current_item = $parent_slug;
54
  $selected_item = bp_action_variable( 0 );
55
  }
56
 
57
- if ( !isset( $bp->bp_options_nav[$current_item] ) || count( $bp->bp_options_nav[$current_item] ) < 1 ) {
58
- return false;
 
59
  } else {
60
- $the_index = $current_item;
 
 
 
 
61
  }
62
  }
63
 
64
  // Loop through each navigation item.
65
- foreach ( (array) $bp->bp_options_nav[$the_index] as $subnav_item ) {
66
- if ( empty( $subnav_item['user_has_access'] ) ) {
67
  continue;
68
  }
69
 
70
  // If the current action or an action variable matches the nav item id, then add a highlight CSS class.
71
- if ( $subnav_item['slug'] == $selected_item ) {
72
  $selected = ' class="current selected"';
73
  } else {
74
  $selected = '';
@@ -88,7 +102,7 @@ function bp_get_options_nav( $parent_slug = '' ) {
88
  * @param array $subnav_item Submenu array item being displayed.
89
  * @param string $selected_item Current action.
90
  */
91
- echo apply_filters( 'bp_get_options_nav_' . $subnav_item['css_id'], '<li id="' . esc_attr( $subnav_item['css_id'] . '-' . $list_type . '-li' ) . '" ' . $selected . '><a id="' . esc_attr( $subnav_item['css_id'] ) . '" href="' . esc_url( $subnav_item['link'] ) . '">' . $subnav_item['name'] . '</a></li>', $subnav_item, $selected_item );
92
  }
93
  }
94
 
@@ -570,6 +584,71 @@ function bp_search_form_type_select() {
570
  return apply_filters( 'bp_search_form_type_select', $selection_box );
571
  }
572
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
573
  /**
574
  * Output the default text for the search box for a given component.
575
  *
@@ -769,14 +848,8 @@ function bp_button( $args = '' ) {
769
  * This function is borrowed from CakePHP v2.0, under the MIT license. See
770
  * http://book.cakephp.org/view/1469/Text#truncate-1625
771
  *
772
- * ### Options:
773
- *
774
- * - `ending` Will be used as Ending and appended to the trimmed string.
775
- * - `exact` If false, $text will not be cut mid-word.
776
- * - `html` If true, HTML tags would be handled correctly.
777
- * - `filter_shortcodes` If true, shortcodes will be stripped before truncating.
778
- *
779
  * @since 1.0.0
 
780
  *
781
  * @param string $text String to truncate.
782
  * @param int $length Optional. Length of returned string, including ellipsis.
@@ -791,6 +864,10 @@ function bp_button( $args = '' ) {
791
  * excerpt length. Default: true.
792
  * @type bool $filter_shortcodes If true, shortcodes will be stripped.
793
  * Default: true.
 
 
 
 
794
  * }
795
  * @return string Trimmed string.
796
  */
@@ -803,7 +880,9 @@ function bp_create_excerpt( $text, $length = 225, $options = array() ) {
803
  'ending' => __( ' [&hellip;]', 'buddypress' ),
804
  'exact' => false,
805
  'html' => true,
806
- 'filter_shortcodes' => $filter_shortcodes_default
 
 
807
  ), 'create_excerpt' );
808
 
809
  // Save the original text, to be passed along to the filter.
@@ -889,8 +968,28 @@ function bp_create_excerpt( $text, $length = 225, $options = array() ) {
889
  }
890
  }
891
  } else {
 
 
 
 
 
 
 
 
 
 
892
  if ( mb_strlen( $text ) <= $length ) {
893
- return $text;
 
 
 
 
 
 
 
 
 
 
894
  } else {
895
  $truncate = mb_substr( $text, 0, $length - mb_strlen( $ending ) );
896
  }
@@ -971,16 +1070,7 @@ function bp_create_excerpt( $text, $length = 225, $options = array() ) {
971
  }
972
  }
973
 
974
- /**
975
- * Filters the final generated excerpt.
976
- *
977
- * @since 1.1.0
978
- *
979
- * @param string $truncate Generated excerpt.
980
- * @param string $original_text Original text provided.
981
- * @param int $length Length of returned string, including ellipsis.
982
- * @param array $options Array of HTML attributes and options.
983
- */
984
  return apply_filters( 'bp_create_excerpt', $truncate, $original_text, $length, $options );
985
  }
986
  add_filter( 'bp_create_excerpt', 'stripslashes_deep' );
@@ -1468,7 +1558,6 @@ function bp_user_has_access() {
1468
  *
1469
  * @since 1.5.0
1470
  *
1471
- * @uses bp_get_search_slug()
1472
  */
1473
  function bp_search_slug() {
1474
  echo bp_get_search_slug();
@@ -1497,8 +1586,6 @@ function bp_search_slug() {
1497
  *
1498
  * @since 1.0.0
1499
  *
1500
- * @uses apply_filters() Filter 'bp_displayed_user_id' to change this value.
1501
- *
1502
  * @return int $id ID of the currently displayed user.
1503
  */
1504
  function bp_displayed_user_id() {
@@ -1522,8 +1609,6 @@ function bp_displayed_user_id() {
1522
  *
1523
  * @since 1.0.0
1524
  *
1525
- * @uses apply_filters() Filter 'bp_loggedin_user_id' to change this value.
1526
- *
1527
  * @return int ID of the logged-in user.
1528
  */
1529
  function bp_loggedin_user_id() {
@@ -2255,6 +2340,19 @@ function bp_is_user() {
2255
  return (bool) bp_displayed_user_id();
2256
  }
2257
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2258
  /**
2259
  * Is the current page a user's activity stream page?
2260
  *
@@ -2366,7 +2464,7 @@ function bp_is_user_change_avatar() {
2366
  *
2367
  * Eg http://example.com/members/joe/profile/change-cover-image/ (or a subpage thereof).
2368
  *
2369
- * @since 2.4.0
2370
  *
2371
  * @return bool True if the current page is a user's profile edit cover image page.
2372
  */
@@ -2588,7 +2686,7 @@ function bp_is_user_settings_profile() {
2588
  * @return True if the current page is the groups directory.
2589
  */
2590
  function bp_is_groups_directory() {
2591
- if ( bp_is_groups_component() && ! bp_current_action() && ! bp_current_item() ) {
2592
  return true;
2593
  }
2594
 
@@ -3010,24 +3108,36 @@ function bp_get_title_parts( $seplocation = 'right' ) {
3010
  // Set empty subnav name.
3011
  $component_subnav_name = '';
3012
 
 
 
 
 
 
3013
  // Use the component nav name.
3014
- if ( ! empty( $bp->bp_nav[$component_id] ) ) {
3015
- $component_name = _bp_strip_spans_from_title( $bp->bp_nav[ $component_id ]['name'] );
3016
 
3017
  // Fall back on the component ID.
3018
  } elseif ( ! empty( $bp->{$component_id}->id ) ) {
3019
  $component_name = ucwords( $bp->{$component_id}->id );
3020
  }
3021
 
3022
- // Append action name if we're on a member component sub-page.
3023
- if ( ! empty( $bp->bp_options_nav[ $component_id ] ) && ! empty( $bp->canonical_stack['action'] ) ) {
3024
- $component_subnav_name = wp_filter_object_list( $bp->bp_options_nav[ $component_id ], array( 'slug' => bp_current_action() ), 'and', 'name' );
 
 
3025
 
3026
- if ( ! empty( $component_subnav_name ) ) {
3027
- $component_subnav_name = array_shift( $component_subnav_name );
3028
  }
3029
  }
3030
 
 
 
 
 
 
3031
  // If on the user profile's landing page, just use the fullname.
3032
  if ( bp_is_current_component( $bp->default_component ) && ( bp_get_requested_url() === bp_displayed_user_domain() ) ) {
3033
  $bp_title_parts[] = $displayed_user_name;
@@ -3045,14 +3155,28 @@ function bp_get_title_parts( $seplocation = 'right' ) {
3045
  }
3046
  }
3047
 
3048
- // A single group.
3049
- } elseif ( bp_is_active( 'groups' ) && ! empty( $bp->groups->current_group ) && ! empty( $bp->bp_options_nav[ $bp->groups->current_group->slug ] ) ) {
3050
- $subnav = isset( $bp->bp_options_nav[ $bp->groups->current_group->slug ][ bp_current_action() ]['name'] ) ? $bp->bp_options_nav[ $bp->groups->current_group->slug ][ bp_current_action() ]['name'] : '';
3051
- $bp_title_parts = array( $bp->bp_options_title, $subnav );
3052
-
3053
- // A single item from a component other than groups.
3054
  } elseif ( bp_is_single_item() ) {
3055
- $bp_title_parts = array( $bp->bp_options_title, $bp->bp_options_nav[ bp_current_item() ][ bp_current_action() ]['name'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3056
 
3057
  // An index or directory.
3058
  } elseif ( bp_is_directory() ) {
@@ -3095,7 +3219,7 @@ function bp_get_title_parts( $seplocation = 'right' ) {
3095
  *
3096
  * @since 2.4.3
3097
  *
3098
- * @param array $bp_title_parts Current BuddyPress title parts
3099
  * @return array
3100
  */
3101
  return (array) apply_filters( 'bp_get_title_parts', $bp_title_parts );
@@ -3174,6 +3298,13 @@ function bp_the_body_class() {
3174
 
3175
  if ( bp_is_user() ) {
3176
  $bp_classes[] = 'bp-user';
 
 
 
 
 
 
 
3177
  }
3178
 
3179
  if ( ! bp_is_directory() ) {
@@ -3188,6 +3319,10 @@ function bp_the_body_class() {
3188
  if ( bp_is_user_activity() ) {
3189
  $bp_classes[] = 'my-activity';
3190
  }
 
 
 
 
3191
  }
3192
 
3193
  if ( bp_is_my_profile() ) {
@@ -3260,6 +3395,13 @@ function bp_the_body_class() {
3260
 
3261
  if ( bp_is_group() ) {
3262
  $bp_classes[] = 'group-' . groups_get_current_group()->slug;
 
 
 
 
 
 
 
3263
  }
3264
 
3265
  if ( bp_is_group_leave() ) {
@@ -3428,79 +3570,58 @@ function _bp_nav_menu_sort( $a, $b ) {
3428
  * Get the items registered in the primary and secondary BuddyPress navigation menus.
3429
  *
3430
  * @since 1.7.0
 
3431
  *
 
3432
  * @return array A multidimensional array of all navigation items.
3433
  */
3434
- function bp_get_nav_menu_items() {
3435
- $menus = $selected_menus = array();
3436
-
3437
- // Get the second level menus.
3438
- foreach ( (array) buddypress()->bp_options_nav as $parent_menu => $sub_menus ) {
3439
-
3440
- // The root menu's ID is "xprofile", but the Profile submenus are using "profile". See BP_Core::setup_nav().
3441
- if ( 'profile' === $parent_menu ) {
3442
- $parent_menu = 'xprofile';
3443
- }
3444
-
3445
- // Sort the items in this menu's navigation by their position property.
3446
- $second_level_menus = (array) $sub_menus;
3447
- usort( $second_level_menus, '_bp_nav_menu_sort' );
3448
-
3449
- // Iterate through the second level menus.
3450
- foreach( $second_level_menus as $sub_nav ) {
3451
-
3452
- // Skip items we don't have access to.
3453
- if ( empty( $sub_nav['user_has_access'] ) ) {
3454
- continue;
3455
- }
3456
-
3457
- // Add this menu.
3458
- $menu = new stdClass;
3459
- $menu->class = array( 'menu-child' );
3460
- $menu->css_id = $sub_nav['css_id'];
3461
- $menu->link = $sub_nav['link'];
3462
- $menu->name = $sub_nav['name'];
3463
- $menu->parent = $parent_menu; // Associate this sub nav with a top-level menu.
3464
-
3465
- // If we're viewing this item's screen, record that we need to mark its parent menu to be selected.
3466
- if ( $sub_nav['slug'] == bp_current_action() ) {
3467
- $menu->class[] = 'current-menu-item';
3468
- $selected_menus[] = $parent_menu;
3469
- }
3470
 
3471
- $menus[] = $menu;
3472
- }
3473
  }
3474
 
3475
- // Get the top-level menu parts (Friends, Groups, etc) and sort by their position property.
3476
- $top_level_menus = (array) buddypress()->bp_nav;
3477
- usort( $top_level_menus, '_bp_nav_menu_sort' );
3478
-
3479
- // Iterate through the top-level menus.
3480
- foreach ( $top_level_menus as $nav ) {
3481
-
3482
- // Skip items marked as user-specific if you're not on your own profile.
3483
- if ( empty( $nav['show_for_displayed_user'] ) && ! bp_core_can_edit_settings() ) {
3484
- continue;
3485
- }
3486
-
3487
  // Get the correct menu link. See https://buddypress.trac.wordpress.org/ticket/4624.
3488
- $link = bp_loggedin_user_domain() ? str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $nav['link'] ) : trailingslashit( bp_displayed_user_domain() . $nav['link'] );
3489
 
3490
  // Add this menu.
3491
  $menu = new stdClass;
3492
  $menu->class = array( 'menu-parent' );
3493
- $menu->css_id = $nav['css_id'];
3494
  $menu->link = $link;
3495
- $menu->name = $nav['name'];
3496
  $menu->parent = 0;
3497
 
3498
- // Check if we need to mark this menu as selected.
3499
- if ( in_array( $nav['css_id'], $selected_menus ) ) {
3500
- $menu->class[] = 'current-menu-parent';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3501
  }
3502
 
3503
  $menus[] = $menu;
 
 
 
 
3504
  }
3505
 
3506
  /**
@@ -3686,9 +3807,9 @@ function bp_nav_menu( $args = array() ) {
3686
  /**
3687
  * Prints the Recipient Salutation.
3688
  *
3689
- * @since 2.5.0
3690
  *
3691
- * @param array $settings Email Settings.
3692
  */
3693
  function bp_email_the_salutation( $settings = array() ) {
3694
  echo bp_email_get_salutation( $settings );
@@ -3697,9 +3818,9 @@ function bp_email_the_salutation( $settings = array() ) {
3697
  /**
3698
  * Gets the Recipient Salutation.
3699
  *
3700
- * @since 2.5.0
3701
  *
3702
- * @param array $settings Email Settings.
3703
  * @return string The Recipient Salutation.
3704
  */
3705
  function bp_email_get_salutation( $settings = array() ) {
@@ -3708,7 +3829,7 @@ function bp_email_the_salutation( $settings = array() ) {
3708
  /**
3709
  * Filters The Recipient Salutation inside the Email Template.
3710
  *
3711
- * @since 2.5.0
3712
  *
3713
  * @param string $value The Recipient Salutation.
3714
  * @param array $settings Email Settings.
13
  /**
14
  * Output the "options nav", the secondary-level single item navigation menu.
15
  *
16
+ * Uses the component's nav global to render out the sub navigation for the
17
  * current component. Each component adds to its sub navigation array within
18
  * its own setup_nav() function.
19
  *
26
  *
27
  * @since 1.0.0
28
  *
 
29
  * viewed user.
30
  *
31
  * @param string $parent_slug Options nav slug.
39
  $component_index = !empty( $bp->displayed_user ) ? bp_current_component() : bp_get_root_slug( bp_current_component() );
40
  $selected_item = bp_current_action();
41
 
42
+ // Default to the Members nav.
43
  if ( ! bp_is_single_item() ) {
44
+ // Set the parent slug, if not provided.
45
+ if ( empty( $parent_slug ) ) {
46
+ $parent_slug = $component_index;
47
+ }
48
+
49
+ $secondary_nav_items = $bp->members->nav->get_secondary( array( 'parent_slug' => $parent_slug ) );
50
+
51
+ if ( ! $secondary_nav_items ) {
52
  return false;
 
 
53
  }
54
+
55
+ // For a single item, try to use the component's nav.
56
  } else {
57
  $current_item = bp_current_item();
58
+ $single_item_component = bp_current_component();
59
 
60
+ // Adjust the selected nav item for the current single item if needed.
61
  if ( ! empty( $parent_slug ) ) {
62
  $current_item = $parent_slug;
63
  $selected_item = bp_action_variable( 0 );
64
  }
65
 
66
+ // If the nav is not defined by the parent component, look in the Members nav.
67
+ if ( ! isset( $bp->{$single_item_component}->nav ) ) {
68
+ $secondary_nav_items = $bp->members->nav->get_secondary( array( 'parent_slug' => $current_item ) );
69
  } else {
70
+ $secondary_nav_items = $bp->{$single_item_component}->nav->get_secondary( array( 'parent_slug' => $current_item ) );
71
+ }
72
+
73
+ if ( ! $secondary_nav_items ) {
74
+ return false;
75
  }
76
  }
77
 
78
  // Loop through each navigation item.
79
+ foreach ( $secondary_nav_items as $subnav_item ) {
80
+ if ( empty( $subnav_item->user_has_access ) ) {
81
  continue;
82
  }
83
 
84
  // If the current action or an action variable matches the nav item id, then add a highlight CSS class.
85
+ if ( $subnav_item->slug === $selected_item ) {
86
  $selected = ' class="current selected"';
87
  } else {
88
  $selected = '';
102
  * @param array $subnav_item Submenu array item being displayed.
103
  * @param string $selected_item Current action.
104
  */
105
+ echo apply_filters( 'bp_get_options_nav_' . $subnav_item->css_id, '<li id="' . esc_attr( $subnav_item->css_id . '-' . $list_type . '-li' ) . '" ' . $selected . '><a id="' . esc_attr( $subnav_item->css_id ) . '" href="' . esc_url( $subnav_item->link ) . '">' . $subnav_item->name . '</a></li>', $subnav_item, $selected_item );
106
  }
107
  }
108
 
584
  return apply_filters( 'bp_search_form_type_select', $selection_box );
585
  }
586
 
587
+ /**
588
+ * Output the 'name' attribute for search form input element.
589
+ *
590
+ * @since 2.7.0
591
+ *
592
+ * @param string $component See bp_get_search_input_name().
593
+ */
594
+ function bp_search_input_name( $component = '' ) {
595
+ echo esc_attr( bp_get_search_input_name( $component ) );
596
+ }
597
+
598
+ /**
599
+ * Get the 'name' attribute for the search form input element.
600
+ *
601
+ * @since 2.7.0
602
+ *
603
+ * @param string $component Component name. Defaults to current component.
604
+ * @return string Text for the 'name' attribute.
605
+ */
606
+ function bp_get_search_input_name( $component = '' ) {
607
+ if ( ! $component ) {
608
+ $component = bp_current_component();
609
+ }
610
+
611
+ $bp = buddypress();
612
+
613
+ $name = '';
614
+ if ( isset( $bp->{$component}->id ) ) {
615
+ $name = $bp->{$component}->id . '_search';
616
+ }
617
+
618
+ return $name;
619
+ }
620
+
621
+ /**
622
+ * Output the placeholder text for the search box for a given component.
623
+ *
624
+ * @since 2.7.0
625
+ *
626
+ * @param string $component See bp_get_search_placeholder().
627
+ */
628
+ function bp_search_placeholder( $component = '' ) {
629
+ echo esc_attr( bp_get_search_placeholder( $component ) );
630
+ }
631
+
632
+ /**
633
+ * Get the placeholder text for the search box for a given component.
634
+ *
635
+ * @since 2.7.0
636
+ *
637
+ * @param string $component Component name. Defaults to current component.
638
+ * @return string Placeholder text for the search field.
639
+ */
640
+ function bp_get_search_placeholder( $component = '' ) {
641
+ $query_arg = bp_core_get_component_search_query_arg( $component );
642
+
643
+ if ( $query_arg && ! empty( $_REQUEST[ $query_arg ] ) ) {
644
+ $placeholder = wp_unslash( $_REQUEST[ $query_arg ] );
645
+ } else {
646
+ $placeholder = bp_get_search_default_text( $component );
647
+ }
648
+
649
+ return $placeholder;
650
+ }
651
+
652
  /**
653
  * Output the default text for the search box for a given component.
654
  *
848
  * This function is borrowed from CakePHP v2.0, under the MIT license. See
849
  * http://book.cakephp.org/view/1469/Text#truncate-1625
850
  *
 
 
 
 
 
 
 
851
  * @since 1.0.0
852
+ * @since 2.6.0 Added 'strip_tags' and 'remove_links' as $options args.
853
  *
854
  * @param string $text String to truncate.
855
  * @param int $length Optional. Length of returned string, including ellipsis.
864
  * excerpt length. Default: true.
865
  * @type bool $filter_shortcodes If true, shortcodes will be stripped.
866
  * Default: true.
867
+ * @type bool $strip_tags If true, HTML tags will be stripped. Default: false.
868
+ * Only applicable if $html is set to false.
869
+ * @type bool $remove_links If true, URLs will be stripped. Default: false.
870
+ * Only applicable if $html is set to false.
871
  * }
872
  * @return string Trimmed string.
873
  */
880
  'ending' => __( ' [&hellip;]', 'buddypress' ),
881
  'exact' => false,
882
  'html' => true,
883
+ 'filter_shortcodes' => $filter_shortcodes_default,
884
+ 'strip_tags' => false,
885
+ 'remove_links' => false,
886
  ), 'create_excerpt' );
887
 
888
  // Save the original text, to be passed along to the filter.
968
  }
969
  }
970
  } else {
971
+ // Strip HTML tags if necessary.
972
+ if ( ! empty( $r['strip_tags'] ) ) {
973
+ $text = strip_tags( $text );
974
+ }
975
+
976
+ // Remove links if necessary.
977
+ if ( ! empty( $r['remove_links'] ) ) {
978
+ $text = preg_replace( '#^\s*(https?://[^\s"]+)\s*$#im', '', $text );
979
+ }
980
+
981
  if ( mb_strlen( $text ) <= $length ) {
982
+ /**
983
+ * Filters the final generated excerpt.
984
+ *
985
+ * @since 1.1.0
986
+ *
987
+ * @param string $truncate Generated excerpt.
988
+ * @param string $original_text Original text provided.
989
+ * @param int $length Length of returned string, including ellipsis.
990
+ * @param array $options Array of HTML attributes and options.
991
+ */
992
+ return apply_filters( 'bp_create_excerpt', $text, $original_text, $length, $options );
993
  } else {
994
  $truncate = mb_substr( $text, 0, $length - mb_strlen( $ending ) );
995
  }
1070
  }
1071
  }
1072
 
1073
+ /** This filter is documented in /bp-core/bp-core-template.php */
 
 
 
 
 
 
 
 
 
1074
  return apply_filters( 'bp_create_excerpt', $truncate, $original_text, $length, $options );
1075
  }
1076
  add_filter( 'bp_create_excerpt', 'stripslashes_deep' );
1558
  *
1559
  * @since 1.5.0
1560
  *
 
1561
  */
1562
  function bp_search_slug() {
1563
  echo bp_get_search_slug();
1586
  *
1587
  * @since 1.0.0
1588
  *
 
 
1589
  * @return int $id ID of the currently displayed user.
1590
  */
1591
  function bp_displayed_user_id() {
1609
  *
1610
  * @since 1.0.0
1611
  *
 
 
1612
  * @return int ID of the logged-in user.
1613
  */
1614
  function bp_loggedin_user_id() {
2340
  return (bool) bp_displayed_user_id();
2341
  }
2342
 
2343
+ /**
2344
+ * Is the current page a user custom front page?
2345
+ *
2346
+ * Will return true anytime there is a custom front page for the displayed user.
2347
+ *
2348
+ * @since 2.6.0
2349
+ *
2350
+ * @return bool True if the current page is a user custom front page.
2351
+ */
2352
+ function bp_is_user_front() {
2353
+ return (bool) ( bp_is_user() && bp_is_current_component( 'front' ) );
2354
+ }
2355
+
2356
  /**
2357
  * Is the current page a user's activity stream page?
2358
  *
2464
  *
2465
  * Eg http://example.com/members/joe/profile/change-cover-image/ (or a subpage thereof).
2466
  *
2467
+ * @since 2.4.0
2468
  *
2469
  * @return bool True if the current page is a user's profile edit cover image page.
2470
  */
2686
  * @return True if the current page is the groups directory.
2687
  */
2688
  function bp_is_groups_directory() {
2689
+ if ( bp_is_groups_component() && ! bp_is_group() && ( ! bp_current_action() || ( bp_action_variable() && bp_is_current_action( bp_get_groups_group_type_base() ) ) ) ) {
2690
  return true;
2691
  }
2692
 
3108
  // Set empty subnav name.
3109
  $component_subnav_name = '';
3110
 
3111
+ if ( ! empty( $bp->members->nav ) ) {
3112
+ $primary_nav_item = $bp->members->nav->get_primary( array( 'slug' => $component_id ), false );
3113
+ $primary_nav_item = reset( $primary_nav_item );
3114
+ }
3115
+
3116
  // Use the component nav name.
3117
+ if ( ! empty( $primary_nav_item->name ) ) {
3118
+ $component_name = _bp_strip_spans_from_title( $primary_nav_item->name );
3119
 
3120
  // Fall back on the component ID.
3121
  } elseif ( ! empty( $bp->{$component_id}->id ) ) {
3122
  $component_name = ucwords( $bp->{$component_id}->id );
3123
  }
3124
 
3125
+ if ( ! empty( $bp->members->nav ) ) {
3126
+ $secondary_nav_item = $bp->members->nav->get_secondary( array(
3127
+ 'parent_slug' => $component_id,
3128
+ 'slug' => bp_current_action()
3129
+ ), false );
3130
 
3131
+ if ( $secondary_nav_item ) {
3132
+ $secondary_nav_item = reset( $secondary_nav_item );
3133
  }
3134
  }
3135
 
3136
+ // Append action name if we're on a member component sub-page.
3137
+ if ( ! empty( $secondary_nav_item->name ) && ! empty( $bp->canonical_stack['action'] ) ) {
3138
+ $component_subnav_name = $secondary_nav_item->name;
3139
+ }
3140
+
3141
  // If on the user profile's landing page, just use the fullname.
3142
  if ( bp_is_current_component( $bp->default_component ) && ( bp_get_requested_url() === bp_displayed_user_domain() ) ) {
3143
  $bp_title_parts[] = $displayed_user_name;
3155
  }
3156
  }
3157
 
3158
+ // A single item from a component other than Members.
 
 
 
 
 
3159
  } elseif ( bp_is_single_item() ) {
3160
+ $component_id = bp_current_component();
3161
+
3162
+ if ( ! empty( $bp->{$component_id}->nav ) ) {
3163
+ $secondary_nav_item = $bp->{$component_id}->nav->get_secondary( array(
3164
+ 'parent_slug' => bp_current_item(),
3165
+ 'slug' => bp_current_action()
3166
+ ), false );
3167
+
3168
+ if ( $secondary_nav_item ) {
3169
+ $secondary_nav_item = reset( $secondary_nav_item );
3170
+ }
3171
+ }
3172
+
3173
+ $single_item_subnav = '';
3174
+
3175
+ if ( ! empty( $secondary_nav_item->name ) ) {
3176
+ $single_item_subnav = $secondary_nav_item->name;
3177
+ }
3178
+
3179
+ $bp_title_parts = array( $bp->bp_options_title, $single_item_subnav );
3180
 
3181
  // An index or directory.
3182
  } elseif ( bp_is_directory() ) {
3219
  *
3220
  * @since 2.4.3
3221
  *
3222
+ * @param array $bp_title_parts Current BuddyPress title parts.
3223
  * @return array
3224
  */
3225
  return (array) apply_filters( 'bp_get_title_parts', $bp_title_parts );
3298
 
3299
  if ( bp_is_user() ) {
3300
  $bp_classes[] = 'bp-user';
3301
+
3302
+ // Add current user member types.
3303
+ if ( $member_types = bp_get_member_type( bp_displayed_user_id(), false ) ) {
3304
+ foreach( $member_types as $member_type ) {
3305
+ $bp_classes[] = sprintf( 'member-type-%s', esc_attr( $member_type ) );
3306
+ }
3307
+ }
3308
  }
3309
 
3310
  if ( ! bp_is_directory() ) {
3319
  if ( bp_is_user_activity() ) {
3320
  $bp_classes[] = 'my-activity';
3321
  }
3322
+ } else {
3323
+ if ( bp_get_current_member_type() ) {
3324
+ $bp_classes[] = 'type';
3325
+ }
3326
  }
3327
 
3328
  if ( bp_is_my_profile() ) {
3395
 
3396
  if ( bp_is_group() ) {
3397
  $bp_classes[] = 'group-' . groups_get_current_group()->slug;
3398
+
3399
+ // Add current group types.
3400
+ if ( $group_types = bp_groups_get_group_type( bp_get_current_group_id(), false ) ) {
3401
+ foreach ( $group_types as $group_type ) {
3402
+ $bp_classes[] = sprintf( 'group-type-%s', esc_attr( $group_type ) );
3403
+ }
3404
+ }
3405
  }
3406
 
3407
  if ( bp_is_group_leave() ) {
3570
  * Get the items registered in the primary and secondary BuddyPress navigation menus.
3571
  *
3572
  * @since 1.7.0
3573
+ * @since 2.6.0 Introduced the `$component` parameter.
3574
  *
3575
+ * @param string $component Optional. Component whose nav items are being fetched.
3576
  * @return array A multidimensional array of all navigation items.
3577
  */
3578
+ function bp_get_nav_menu_items( $component = 'members' ) {
3579
+ $bp = buddypress();
3580
+ $menus = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3581
 
3582
+ if ( ! isset( $bp->{$component}->nav ) ) {
3583
+ return $menus;
3584
  }
3585
 
3586
+ // Get the item nav and build the menus.
3587
+ foreach ( $bp->{$component}->nav->get_item_nav() as $nav_menu ) {
 
 
 
 
 
 
 
 
 
 
3588
  // Get the correct menu link. See https://buddypress.trac.wordpress.org/ticket/4624.
3589
+ $link = bp_loggedin_user_domain() ? str_replace( bp_loggedin_user_domain(), bp_displayed_user_domain(), $nav_menu->link ) : trailingslashit( bp_displayed_user_domain() . $nav_menu->link );
3590
 
3591
  // Add this menu.
3592
  $menu = new stdClass;
3593
  $menu->class = array( 'menu-parent' );
3594
+ $menu->css_id = $nav_menu->css_id;
3595
  $menu->link = $link;
3596
+ $menu->name = $nav_menu->name;
3597
  $menu->parent = 0;
3598
 
3599
+ if ( ! empty( $nav_menu->children ) ) {
3600
+ $submenus = array();
3601
+
3602
+ foreach( $nav_menu->children as $sub_menu ) {
3603
+ $submenu = new stdClass;
3604
+ $submenu->class = array( 'menu-child' );
3605
+ $submenu->css_id = $sub_menu->css_id;
3606
+ $submenu->link = $sub_menu->link;
3607
+ $submenu->name = $sub_menu->name;
3608
+ $submenu->parent = $nav_menu->slug;
3609
+
3610
+ // If we're viewing this item's screen, record that we need to mark its parent menu to be selected.
3611
+ if ( $sub_menu->slug == bp_current_action() ) {
3612
+ $menu->class[] = 'current-menu-parent';
3613
+ $submenu->class[] = 'current-menu-item';
3614
+ }
3615
+
3616
+ $submenus[] = $submenu;
3617
+ }
3618
  }
3619
 
3620
  $menus[] = $menu;
3621
+
3622
+ if ( ! empty( $submenus ) ) {
3623
+ $menus = array_merge( $menus, $submenus );
3624
+ }
3625
  }
3626
 
3627
  /**
3807
  /**
3808
  * Prints the Recipient Salutation.
3809
  *
3810
+ * @since 2.5.0
3811
  *
3812
+ * @param array $settings Email Settings.
3813
  */
3814
  function bp_email_the_salutation( $settings = array() ) {
3815
  echo bp_email_get_salutation( $settings );
3818
  /**
3819
  * Gets the Recipient Salutation.
3820
  *
3821
+ * @since 2.5.0
3822
  *
3823
+ * @param array $settings Email Settings.
3824
  * @return string The Recipient Salutation.
3825
  */
3826
  function bp_email_get_salutation( $settings = array() ) {
3829
  /**
3830
  * Filters The Recipient Salutation inside the Email Template.
3831
  *
3832
+ * @since 2.5.0
3833
  *
3834
  * @param string $value The Recipient Salutation.
3835
  * @param array $settings Email Settings.
bp-core/bp-core-theme-compatibility.php CHANGED
@@ -22,10 +22,6 @@ defined( 'ABSPATH' ) || exit;
22
  * Don't try anything you're about to witness here, at home. Ever.
23
  */
24
 
25
- /** Base Class ****************************************************************/
26
-
27
- require dirname( __FILE__ ) . '/classes/class-bp-theme-compat.php';
28
-
29
  /** Functions *****************************************************************/
30
 
31
  /**
@@ -55,8 +51,6 @@ function bp_setup_theme_compat( $theme = '' ) {
55
  *
56
  * @since 1.7.0
57
  *
58
- * @uses apply_filters()
59
- *
60
  * @return string ID of the theme package in use.
61
  */
62
  function bp_get_theme_compat_id() {
@@ -79,8 +73,6 @@ function bp_get_theme_compat_id() {
79
  *
80
  * @since 1.7.0
81
  *
82
- * @uses apply_filters()
83
- *
84
  * @return string Name of the theme package currently in use.
85
  */
86
  function bp_get_theme_compat_name() {
@@ -103,8 +95,6 @@ function bp_get_theme_compat_name() {
103
  *
104
  * @since 1.7.0
105
  *
106
- * @uses apply_filters()
107
- *
108
  * @return string The version string of the theme package currently in use.
109
  */
110
  function bp_get_theme_compat_version() {
@@ -127,8 +117,6 @@ function bp_get_theme_compat_version() {
127
  *
128
  * @since 1.7.0
129
  *
130
- * @uses apply_filters()
131
- *
132
  * @return string The absolute path of the theme package currently in use.
133
  */
134
  function bp_get_theme_compat_dir() {
@@ -152,8 +140,6 @@ function bp_get_theme_compat_dir() {
152
  *
153
  * @since 1.7.0
154
  *
155
- * @uses apply_filters()
156
- *
157
  * @return string URL of the theme package currently in use.
158
  */
159
  function bp_get_theme_compat_url() {
@@ -176,8 +162,6 @@ function bp_get_theme_compat_url() {
176
  *
177
  * @since 1.9.0
178
  *
179
- * @uses bp_detect_theme_compat_with_current_theme()
180
- *
181
  * @return bool True if the current theme needs theme compatibility.
182
  */
183
  function bp_use_theme_compat_with_current_theme() {
@@ -329,8 +313,8 @@ function bp_set_theme_compat_original_template( $template = '' ) {
329
  *
330
  * @since 2.4.0
331
  *
332
- * @param string $theme_id The theme id (eg: legacy).
333
- * @param array $feature An associative array (eg: array( name => 'feature_name', 'settings' => array() )).
334
  */
335
  function bp_set_theme_compat_feature( $theme_id, $feature = array() ) {
336
  if ( empty( $theme_id ) || empty( $feature['name'] ) ) {
@@ -389,8 +373,8 @@ function bp_set_theme_compat_feature( $theme_id, $feature = array() ) {
389
  *
390
  * @since 2.4.0
391
  *
392
- * @param string $feature The feature (eg: cover_image).
393
- * @return object The feature settings.
394
  */
395
  function bp_get_theme_compat_feature( $feature = '' ) {
396
  // Get current theme compat theme.
@@ -407,7 +391,7 @@ function bp_get_theme_compat_feature( $feature = '' ) {
407
  }
408
 
409
  /**
410
- * Setup the theme's features
411
  *
412
  * Note: BP Legacy's buddypress-functions.php is not loaded in WP Administration
413
  * as it's loaded using bp_locate_template(). That's why this function is here.
@@ -656,7 +640,7 @@ function bp_theme_compat_reset_post( $args = array() ) {
656
  unset( $dummy );
657
 
658
  /**
659
- * Force the header back to 200 status if not a deliberate 404
660
  *
661
  * @see https://bbpress.trac.wordpress.org/ticket/1973
662
  */
@@ -676,28 +660,14 @@ function bp_theme_compat_reset_post( $args = array() ) {
676
  *
677
  * @since 1.7.0
678
  *
679
- * @uses bp_is_single_user() To check if page is single user.
680
- * @uses bp_get_single_user_template() To get user template.
681
- * @uses bp_is_single_user_edit() To check if page is single user edit.
682
- * @uses bp_get_single_user_edit_template() To get user edit template.
683
- * @uses bp_is_single_view() To check if page is single view.
684
- * @uses bp_get_single_view_template() To get view template.
685
- * @uses bp_is_forum_edit() To check if page is forum edit.
686
- * @uses bp_get_forum_edit_template() To get forum edit template.
687
- * @uses bp_is_topic_merge() To check if page is topic merge.
688
- * @uses bp_get_topic_merge_template() To get topic merge template.
689
- * @uses bp_is_topic_split() To check if page is topic split.
690
- * @uses bp_get_topic_split_template() To get topic split template.
691
- * @uses bp_is_topic_edit() To check if page is topic edit.
692
- * @uses bp_get_topic_edit_template() To get topic edit template.
693
- * @uses bp_is_reply_edit() To check if page is reply edit.
694
- * @uses bp_get_reply_edit_template() To get reply edit template.
695
- * @uses bp_set_theme_compat_template() To set the global theme compat template.
696
- *
697
  * @param string $template Template name.
698
  * @return string $template Template name.
699
  */
700
  function bp_template_include_theme_compat( $template = '' ) {
 
 
 
 
701
 
702
  // If the current theme doesn't need theme compat, bail at this point.
703
  if ( ! bp_use_theme_compat_with_current_theme() ) {
@@ -981,10 +951,12 @@ function bp_comments_open( $open, $post_id = 0 ) {
981
  function bp_theme_compat_toggle_is_page( $retval = '' ) {
982
  global $wp_query;
983
 
984
- $wp_query->is_page = false;
 
985
 
986
- // Set a switch so we know that we've toggled these WP_Query properties.
987
- buddypress()->theme_compat->is_page_toggled = true;
 
988
 
989
  return $retval;
990
  }
22
  * Don't try anything you're about to witness here, at home. Ever.
23
  */
24
 
 
 
 
 
25
  /** Functions *****************************************************************/
26
 
27
  /**
51
  *
52
  * @since 1.7.0
53
  *
 
 
54
  * @return string ID of the theme package in use.
55
  */
56
  function bp_get_theme_compat_id() {
73
  *
74
  * @since 1.7.0
75
  *
 
 
76
  * @return string Name of the theme package currently in use.
77
  */
78
  function bp_get_theme_compat_name() {
95
  *
96
  * @since 1.7.0
97
  *
 
 
98
  * @return string The version string of the theme package currently in use.
99
  */
100
  function bp_get_theme_compat_version() {
117
  *
118
  * @since 1.7.0
119
  *
 
 
120
  * @return string The absolute path of the theme package currently in use.
121
  */
122
  function bp_get_theme_compat_dir() {
140
  *
141
  * @since 1.7.0
142
  *
 
 
143
  * @return string URL of the theme package currently in use.
144
  */
145
  function bp_get_theme_compat_url() {
162
  *
163
  * @since 1.9.0
164
  *
 
 
165
  * @return bool True if the current theme needs theme compatibility.
166
  */
167
  function bp_use_theme_compat_with_current_theme() {
313
  *
314
  * @since 2.4.0
315
  *
316
+ * @param string $theme_id The theme id (eg: legacy).
317
+ * @param array $feature An associative array (eg: array( name => 'feature_name', 'settings' => array() )).
318
  */
319
  function bp_set_theme_compat_feature( $theme_id, $feature = array() ) {
320
  if ( empty( $theme_id ) || empty( $feature['name'] ) ) {
373
  *
374
  * @since 2.4.0
375
  *
376
+ * @param string $feature The feature (eg: cover_image).
377
+ * @return object The feature settings.
378
  */
379
  function bp_get_theme_compat_feature( $feature = '' ) {
380
  // Get current theme compat theme.
391
  }
392
 
393
  /**
394
+ * Setup the theme's features.
395
  *
396
  * Note: BP Legacy's buddypress-functions.php is not loaded in WP Administration
397
  * as it's loaded using bp_locate_template(). That's why this function is here.
640
  unset( $dummy );
641
 
642
  /**
643
+ * Force the header back to 200 status if not a deliberate 404.
644
  *
645
  * @see https://bbpress.trac.wordpress.org/ticket/1973
646
  */
660
  *
661
  * @since 1.7.0
662
  *
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
663
  * @param string $template Template name.
664
  * @return string $template Template name.
665
  */
666
  function bp_template_include_theme_compat( $template = '' ) {
667
+ // If embed template, bail.
668
+ if ( true === function_exists( 'is_embed' ) && is_embed() ) {
669
+ return $template;
670
+ }
671
 
672
  // If the current theme doesn't need theme compat, bail at this point.
673
  if ( ! bp_use_theme_compat_with_current_theme() ) {
951
  function bp_theme_compat_toggle_is_page( $retval = '' ) {
952
  global $wp_query;
953
 
954
+ if ( $wp_query->is_page ) {
955
+ $wp_query->is_page = false;
956
 
957
+ // Set a switch so we know that we've toggled these WP_Query properties.
958
+ buddypress()->theme_compat->is_page_toggled = true;
959
+ }
960
 
961
  return $retval;
962
  }
bp-core/bp-core-update.php CHANGED
@@ -17,9 +17,6 @@ defined( 'ABSPATH' ) || exit;
17
  *
18
  * @since 1.7.0
19
  *
20
- * @uses get_option()
21
- * @uses bp_get_db_version() To get BuddyPress's database version.
22
- *
23
  * @return bool True if this is a fresh BP install, otherwise false.
24
  */
25
  function bp_is_install() {
@@ -35,9 +32,6 @@ function bp_is_install() {
35
  *
36
  * @since 1.6.0
37
  *
38
- * @uses get_option()
39
- * @uses bp_get_db_version() To get BuddyPress's database version.
40
- *
41
  * @return bool True if update, otherwise false.
42
  */
43
  function bp_is_update() {
@@ -58,8 +52,6 @@ function bp_is_update() {
58
  *
59
  * @since 1.6.0
60
  *
61
- * @uses buddypress()
62
- *
63
  * @param string $basename BuddyPress basename.
64
  * @return bool True if activating BuddyPress, false if not.
65
  */
@@ -104,8 +96,6 @@ function bp_is_activation( $basename = '' ) {
104
  *
105
  * @since 1.6.0
106
  *
107
- * @uses buddypress()
108
- *
109
  * @param string $basename BuddyPress basename.
110
  * @return bool True if deactivating BuddyPress, false if not.
111
  */
@@ -149,9 +139,6 @@ function bp_is_deactivation( $basename = '' ) {
149
  * Update the BP version stored in the database to the current version.
150
  *
151
  * @since 1.6.0
152
- *
153
- * @uses bp_get_db_version() To get BuddyPress's database version.
154
- * @uses bp_update_option() To update BuddyPress's database version.
155
  */
156
  function bp_version_bump() {
157
  bp_update_option( '_bp_db_version', bp_get_db_version() );
@@ -204,10 +191,11 @@ function bp_version_updater() {
204
  'notifications' => 1,
205
  ) );
206
 
 
207
  require_once( buddypress()->plugin_dir . '/bp-core/admin/bp-core-admin-schema.php' );
208
  $switched_to_root_blog = false;
209
 
210
- // Make sure the current blog is set to the root blog
211
  if ( ! bp_is_root_blog() ) {
212
  switch_to_blog( bp_get_root_blog_id() );
213
  bp_register_taxonomies();
@@ -230,51 +218,56 @@ function bp_version_updater() {
230
  // Run the schema install to update tables.
231
  bp_core_install();
232
 
233
- // 1.5.0
234
  if ( $raw_db_version < 1801 ) {
235
  bp_update_to_1_5();
236
  bp_core_add_page_mappings( $default_components, 'delete' );
237
  }
238
 
239
- // 1.6.0
240
  if ( $raw_db_version < 6067 ) {
241
  bp_update_to_1_6();
242
  }
243
 
244
- // 1.9.0
245
  if ( $raw_db_version < 7553 ) {
246
  bp_update_to_1_9();
247
  }
248
 
249
- // 1.9.2
250
  if ( $raw_db_version < 7731 ) {
251
  bp_update_to_1_9_2();
252
  }
253
 
254
- // 2.0.0
255
  if ( $raw_db_version < 7892 ) {
256
  bp_update_to_2_0();
257
  }
258
 
259
- // 2.0.1
260
  if ( $raw_db_version < 8311 ) {
261
  bp_update_to_2_0_1();
262
  }
263
 
264
- // 2.2.0
265
  if ( $raw_db_version < 9181 ) {
266
  bp_update_to_2_2();
267
  }
268
 
269
- // 2.3.0
270
  if ( $raw_db_version < 9615 ) {
271
  bp_update_to_2_3();
272
  }
273
 
274
- // 2.5.0
275
  if ( $raw_db_version < 10440 ) {
276
  bp_update_to_2_5();
277
  }
 
 
 
 
 
278
  }
279
 
280
  /* All done! *************************************************************/
@@ -343,7 +336,7 @@ function bp_update_to_1_5() {
343
  }
344
 
345
  /**
346
- * Remove unused metadata from database when upgrading from < 1.6.
347
  *
348
  * Database update methods based on version numbers.
349
  *
@@ -392,7 +385,7 @@ function bp_update_to_1_9() {
392
  }
393
 
394
  /**
395
- * Perform database updates for BP 1.9.2
396
  *
397
  * In 1.9, BuddyPress stopped registering its theme directory when it detected
398
  * that bp-default (or a child theme) was not currently being used, in effect
@@ -401,6 +394,7 @@ function bp_update_to_1_9() {
401
  * bp-default would no longer be available, with no obvious way (outside of
402
  * a manual filter) to restore it. In 1.9.2, we add an option that flags
403
  * whether bp-default or a child theme is active at the time of upgrade; if so,
 
404
  * the theme directory will continue to be registered even if the theme is
405
  * deactivated temporarily. Thus, new installations will not see bp-default,
406
  * but legacy installations using the theme will continue to see it.
@@ -452,8 +446,6 @@ function bp_update_to_2_0() {
452
  * 2.0.1 database upgrade routine.
453
  *
454
  * @since 2.0.1
455
- *
456
- * @return void
457
  */
458
  function bp_update_to_2_0_1() {
459
 
@@ -513,13 +505,49 @@ function bp_update_to_2_5() {
513
  bp_core_install_emails();
514
  }
515
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  /**
517
  * Updates the component field for new_members type.
518
  *
519
  * @since 2.2.0
520
  *
521
  * @global $wpdb
522
- * @uses buddypress()
523
  */
524
  function bp_migrate_new_member_activity_component() {
525
  global $wpdb;
@@ -552,8 +580,6 @@ function bp_migrate_new_member_activity_component() {
552
  * Remove all hidden friendship activities.
553
  *
554
  * @since 2.2.0
555
- *
556
- * @uses bp_activity_delete() to delete the corresponding friendship activities.
557
  */
558
  function bp_cleanup_friendship_activities() {
559
  bp_activity_delete( array(
@@ -563,14 +589,61 @@ function bp_cleanup_friendship_activities() {
563
  ) );
564
  }
565
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
566
  /**
567
  * Redirect user to BP's What's New page on first page load after activation.
568
  *
569
  * @since 1.7.0
570
  *
571
  * @internal Used internally to redirect BuddyPress to the about page on activation.
572
- *
573
- * @uses set_transient() To drop the activation transient for 30 seconds.
574
  */
575
  function bp_add_activation_redirect() {
576
 
@@ -639,8 +712,6 @@ function bp_core_maybe_install_signups() {
639
  * Runs on BuddyPress activation.
640
  *
641
  * @since 1.6.0
642
- *
643
- * @uses do_action() Calls 'bp_activation' hook.
644
  */
645
  function bp_activation() {
646
 
@@ -653,13 +724,13 @@ function bp_activation() {
653
  /**
654
  * Fires during the activation of BuddyPress.
655
  *
656
- * Use as of (1.6.0)
657
  *
658
  * @since 1.6.0
659
  */
660
  do_action( 'bp_activation' );
661
 
662
- // @deprecated as of (1.6)
663
  do_action( 'bp_loader_activate' );
664
  }
665
 
@@ -669,8 +740,6 @@ function bp_activation() {
669
  * Runs on BuddyPress deactivation.
670
  *
671
  * @since 1.6.0
672
- *
673
- * @uses do_action() Calls 'bp_deactivation' hook.
674
  */
675
  function bp_deactivation() {
676
 
@@ -688,13 +757,13 @@ function bp_deactivation() {
688
  /**
689
  * Fires during the deactivation of BuddyPress.
690
  *
691
- * Use as of (1.6.0)
692
  *
693
  * @since 1.6.0
694
  */
695
  do_action( 'bp_deactivation' );
696
 
697
- // @deprecated as of (1.6)
698
  do_action( 'bp_loader_deactivate' );
699
  }
700
 
@@ -704,8 +773,6 @@ function bp_deactivation() {
704
  * Runs when uninstalling BuddyPress.
705
  *
706
  * @since 1.6.0
707
- *
708
- * @uses do_action() Calls 'bp_uninstall' hook.
709
  */
710
  function bp_uninstall() {
711
 
17
  *
18
  * @since 1.7.0
19
  *
 
 
 
20
  * @return bool True if this is a fresh BP install, otherwise false.
21
  */
22
  function bp_is_install() {
32
  *
33
  * @since 1.6.0
34
  *
 
 
 
35
  * @return bool True if update, otherwise false.
36
  */
37
  function bp_is_update() {
52
  *
53
  * @since 1.6.0
54
  *
 
 
55
  * @param string $basename BuddyPress basename.
56
  * @return bool True if activating BuddyPress, false if not.
57
  */
96
  *
97
  * @since 1.6.0
98
  *
 
 
99
  * @param string $basename BuddyPress basename.
100
  * @return bool True if deactivating BuddyPress, false if not.
101
  */
139
  * Update the BP version stored in the database to the current version.
140
  *
141
  * @since 1.6.0
 
 
 
142
  */
143
  function bp_version_bump() {
144
  bp_update_option( '_bp_db_version', bp_get_db_version() );
191
  'notifications' => 1,
192
  ) );
193
 
194
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
195
  require_once( buddypress()->plugin_dir . '/bp-core/admin/bp-core-admin-schema.php' );
196
  $switched_to_root_blog = false;
197
 
198
+ // Make sure the current blog is set to the root blog.
199
  if ( ! bp_is_root_blog() ) {
200
  switch_to_blog( bp_get_root_blog_id() );
201
  bp_register_taxonomies();
218
  // Run the schema install to update tables.
219
  bp_core_install();
220
 
221
+ // Version 1.5.0.
222
  if ( $raw_db_version < 1801 ) {
223
  bp_update_to_1_5();
224
  bp_core_add_page_mappings( $default_components, 'delete' );
225
  }
226
 
227
+ // Version 1.6.0.
228
  if ( $raw_db_version < 6067 ) {
229
  bp_update_to_1_6();
230
  }
231
 
232
+ // Version 1.9.0.
233
  if ( $raw_db_version < 7553 ) {
234
  bp_update_to_1_9();
235
  }
236
 
237
+ // Version 1.9.2.
238
  if ( $raw_db_version < 7731 ) {
239
  bp_update_to_1_9_2();
240
  }
241
 
242
+ // Version 2.0.0.
243
  if ( $raw_db_version < 7892 ) {
244
  bp_update_to_2_0();
245
  }
246
 
247
+ // Version 2.0.1.
248
  if ( $raw_db_version < 8311 ) {
249
  bp_update_to_2_0_1();
250
  }
251
 
252
+ // Version 2.2.0.
253
  if ( $raw_db_version < 9181 ) {
254
  bp_update_to_2_2();
255
  }
256
 
257
+ // Version 2.3.0.
258
  if ( $raw_db_version < 9615 ) {
259
  bp_update_to_2_3();
260
  }
261
 
262
+ // Version 2.5.0.
263
  if ( $raw_db_version < 10440 ) {
264
  bp_update_to_2_5();
265
  }
266
+
267
+ // Version 2.7.0.
268
+ if ( $raw_db_version < 11105 ) {
269
+ bp_update_to_2_7();
270
+ }
271
  }
272
 
273
  /* All done! *************************************************************/
336
  }
337
 
338
  /**
339
+ * Remove unused metadata from database when upgrading from < 1.6.0.
340
  *
341
  * Database update methods based on version numbers.
342
  *
385
  }
386
 
387
  /**
388
+ * Perform database updates for BP 1.9.2.
389
  *
390
  * In 1.9, BuddyPress stopped registering its theme directory when it detected
391
  * that bp-default (or a child theme) was not currently being used, in effect
394
  * bp-default would no longer be available, with no obvious way (outside of
395
  * a manual filter) to restore it. In 1.9.2, we add an option that flags
396
  * whether bp-default or a child theme is active at the time of upgrade; if so,
397
+ *
398
  * the theme directory will continue to be registered even if the theme is
399
  * deactivated temporarily. Thus, new installations will not see bp-default,
400
  * but legacy installations using the theme will continue to see it.
446
  * 2.0.1 database upgrade routine.
447
  *
448
  * @since 2.0.1
 
 
449
  */
450
  function bp_update_to_2_0_1() {
451
 
505
  bp_core_install_emails();
506
  }
507
 
508
+ /**
509
+ * 2.7.0 update routine.
510
+ *
511
+ * - Add email unsubscribe salt.
512
+ * - Save legacy directory titles to the corresponding WP pages.
513
+ * - Add ignore deprecated code option (false for updates).
514
+ *
515
+ * @since 2.7.0
516
+ */
517
+ function bp_update_to_2_7() {
518
+ bp_add_option( 'bp-emails-unsubscribe-salt', base64_encode( wp_generate_password( 64, true, true ) ) );
519
+
520
+ // Update post_titles
521
+ bp_migrate_directory_page_titles();
522
+
523
+ /*
524
+ * Add `parent_id` column to groups table.
525
+ * Also handled by `bp_core_install()`.
526
+ */
527
+ if ( bp_is_active( 'groups' ) ) {
528
+ bp_core_install_groups();
529
+
530
+ // Invalidate all cached group objects.
531
+ global $wpdb;
532
+ $bp = buddypress();
533
+
534
+ $group_ids = $wpdb->get_col( "SELECT id FROM {$bp->groups->table_name}" );
535
+
536
+ foreach ( $group_ids as $group_id ) {
537
+ wp_cache_delete( $group_id, 'bp_groups' );
538
+ }
539
+ }
540
+
541
+ // Do not ignore deprecated code for existing installs.
542
+ bp_add_option( '_bp_ignore_deprecated_code', false );
543
+ }
544
+
545
  /**
546
  * Updates the component field for new_members type.
547
  *
548
  * @since 2.2.0
549
  *
550
  * @global $wpdb
 
551
  */
552
  function bp_migrate_new_member_activity_component() {
553
  global $wpdb;
580
  * Remove all hidden friendship activities.
581
  *
582
  * @since 2.2.0
 
 
583
  */
584
  function bp_cleanup_friendship_activities() {
585
  bp_activity_delete( array(
589
  ) );
590
  }
591
 
592
+ /**
593
+ * Update WP pages so that their post_title matches the legacy component directory title.
594
+ *
595
+ * As of 2.7.0, component directory titles come from the `post_title` attribute of the corresponding WP post object,
596
+ * instead of being hardcoded. To ensure that directory titles don't change for existing installations, we update these
597
+ * WP posts with the formerly hardcoded titles.
598
+ *
599
+ * @since 2.7.0
600
+ */
601
+ function bp_migrate_directory_page_titles() {
602
+ $bp_pages = bp_core_get_directory_page_ids( 'all' );
603
+
604
+ $default_titles = bp_core_get_directory_page_default_titles();
605
+
606
+ $legacy_titles = array(
607
+ 'activity' => _x( 'Site-Wide Activity', 'component directory title', 'buddypress' ),
608
+ 'blogs' => _x( 'Sites', 'component directory title', 'buddypress' ),
609
+ 'groups' => _x( 'Groups', 'component directory title', 'buddypress' ),
610
+ 'members' => _x( 'Members', 'component directory title', 'buddypress' ),
611
+ );
612
+
613
+ foreach ( $bp_pages as $component => $page_id ) {
614
+ if ( ! isset( $legacy_titles[ $component ] ) ) {
615
+ continue;
616
+ }
617
+
618
+ $page = get_post( $page_id );
619
+ if ( ! $page ) {
620
+ continue;
621
+ }
622
+
623
+ // If the admin has changed the default title, don't touch it.
624
+ if ( isset( $default_titles[ $component ] ) && $default_titles[ $component ] !== $page->post_title ) {
625
+ continue;
626
+ }
627
+
628
+ // If the saved page title is the same as the legacy title, there's nothing to do.
629
+ if ( $legacy_titles[ $component ] == $page->post_title ) {
630
+ continue;
631
+ }
632
+
633
+ // Update the page with the legacy title.
634
+ wp_update_post( array(
635
+ 'ID' => $page_id,
636
+ 'post_title' => $legacy_titles[ $component ],
637
+ ) );
638
+ }
639
+ }
640
+
641
  /**
642
  * Redirect user to BP's What's New page on first page load after activation.
643
  *
644
  * @since 1.7.0
645
  *
646
  * @internal Used internally to redirect BuddyPress to the about page on activation.
 
 
647
  */
648
  function bp_add_activation_redirect() {
649
 
712
  * Runs on BuddyPress activation.
713
  *
714
  * @since 1.6.0
 
 
715
  */
716
  function bp_activation() {
717
 
724
  /**
725
  * Fires during the activation of BuddyPress.
726
  *
727
+ * Use as of 1.6.0.
728
  *
729
  * @since 1.6.0
730
  */
731
  do_action( 'bp_activation' );
732
 
733
+ // @deprecated as of 1.6.0
734
  do_action( 'bp_loader_activate' );
735
  }
736
 
740
  * Runs on BuddyPress deactivation.
741
  *
742
  * @since 1.6.0
 
 
743
  */
744
  function bp_deactivation() {
745
 
757
  /**
758
  * Fires during the deactivation of BuddyPress.
759
  *
760
+ * Use as of 1.6.0.
761
  *
762
  * @since 1.6.0
763
  */
764
  do_action( 'bp_deactivation' );
765
 
766
+ // @deprecated as of 1.6.0
767
  do_action( 'bp_loader_deactivate' );
768
  }
769
 
773
  * Runs when uninstalling BuddyPress.
774
  *
775
  * @since 1.6.0
 
 
776
  */
777
  function bp_uninstall() {
778
 
bp-core/bp-core-widgets.php CHANGED
@@ -10,14 +10,12 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- require dirname( __FILE__ ) . '/classes/class-bp-core-login-widget.php';
14
-
15
  /**
16
  * Register bp-core widgets.
17
  *
18
  * @since 1.0.0
19
  */
20
  function bp_core_register_widgets() {
21
- add_action('widgets_init', create_function('', 'return register_widget("BP_Core_Login_Widget");') );
22
  }
23
  add_action( 'bp_register_widgets', 'bp_core_register_widgets' );
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
13
  /**
14
  * Register bp-core widgets.
15
  *
16
  * @since 1.0.0
17
  */
18
  function bp_core_register_widgets() {
19
+ add_action( 'widgets_init', function() { register_widget( 'BP_Core_Login_Widget' ); } );
20
  }
21
  add_action( 'bp_register_widgets', 'bp_core_register_widgets' );
bp-core/bp-core-wpabstraction.php CHANGED
@@ -52,7 +52,6 @@ if ( !is_multisite() ) {
52
  * @param int $blog_id Blog ID to fetch for. Not used.
53
  * @param string $option_name Option name to fetch.
54
  * @param bool $default Whether or not default.
55
- *
56
  * @return mixed
57
  */
58
  function get_blog_option( $blog_id, $option_name, $default = false ) {
@@ -72,7 +71,6 @@ if ( !is_multisite() ) {
72
  * @param int $blog_id Blog ID to add for. Not used.
73
  * @param string $option_name Option name to add.
74
  * @param mixed $option_value Option value to add.
75
- *
76
  * @return mixed
77
  */
78
  function add_blog_option( $blog_id, $option_name, $option_value ) {
@@ -92,7 +90,6 @@ if ( !is_multisite() ) {
92
  * @param int $blog_id Blog ID to update for. Not used.
93
  * @param string $option_name Option name to update.
94
  * @param mixed $value Option value to update.
95
- *
96
  * @return mixed
97
  */
98
  function update_blog_option( $blog_id, $option_name, $value ) {
@@ -111,7 +108,6 @@ if ( !is_multisite() ) {
111
  *
112
  * @param int $blog_id Blog ID to delete for. Not used.
113
  * @param string $option_name Option name to delete.
114
- *
115
  * @return mixed
116
  */
117
  function delete_blog_option( $blog_id, $option_name ) {
@@ -130,7 +126,6 @@ if ( !is_multisite() ) {
130
  *
131
  * @param mixed $new_blog New blog to switch to. Not used.
132
  * @param null $deprecated Whether or not deprecated. Not used.
133
- *
134
  * @return int
135
  */
136
  function switch_to_blog( $new_blog, $deprecated = null ) {
@@ -165,7 +160,6 @@ if ( !is_multisite() ) {
165
  *
166
  * @param int $user_id ID of the user. Not used.
167
  * @param bool $all Whether or not to return all. Not used.
168
- *
169
  * @return false
170
  */
171
  function get_blogs_of_user( $user_id, $all = false ) {
@@ -186,7 +180,6 @@ if ( !is_multisite() ) {
186
  * @param mixed $pref Preference. Not used.
187
  * @param string $value Value. Not used.
188
  * @param null $deprecated Whether or not deprecated. Not used.
189
- *
190
  * @return true
191
  */
192
  function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
52
  * @param int $blog_id Blog ID to fetch for. Not used.
53
  * @param string $option_name Option name to fetch.
54
  * @param bool $default Whether or not default.
 
55
  * @return mixed
56
  */
57
  function get_blog_option( $blog_id, $option_name, $default = false ) {
71
  * @param int $blog_id Blog ID to add for. Not used.
72
  * @param string $option_name Option name to add.
73
  * @param mixed $option_value Option value to add.
 
74
  * @return mixed
75
  */
76
  function add_blog_option( $blog_id, $option_name, $option_value ) {
90
  * @param int $blog_id Blog ID to update for. Not used.
91
  * @param string $option_name Option name to update.
92
  * @param mixed $value Option value to update.
 
93
  * @return mixed
94
  */
95
  function update_blog_option( $blog_id, $option_name, $value ) {
108
  *
109
  * @param int $blog_id Blog ID to delete for. Not used.
110
  * @param string $option_name Option name to delete.
 
111
  * @return mixed
112
  */
113
  function delete_blog_option( $blog_id, $option_name ) {
126
  *
127
  * @param mixed $new_blog New blog to switch to. Not used.
128
  * @param null $deprecated Whether or not deprecated. Not used.
 
129
  * @return int
130
  */
131
  function switch_to_blog( $new_blog, $deprecated = null ) {
160
  *
161
  * @param int $user_id ID of the user. Not used.
162
  * @param bool $all Whether or not to return all. Not used.
 
163
  * @return false
164
  */
165
  function get_blogs_of_user( $user_id, $all = false ) {
180
  * @param mixed $pref Preference. Not used.
181
  * @param string $value Value. Not used.
182
  * @param null $deprecated Whether or not deprecated. Not used.
 
183
  * @return true
184
  */
185
  function update_blog_status( $blog_id, $pref, $value, $deprecated = null ) {
bp-core/classes/class-bp-admin.php CHANGED
@@ -82,9 +82,6 @@ class BP_Admin {
82
  *
83
  * @since 1.6.0
84
  *
85
- * @uses BP_Admin::setup_globals() Setup the globals needed.
86
- * @uses BP_Admin::includes() Include the required files.
87
- * @uses BP_Admin::setup_actions() Setup the hooks and actions.
88
  */
89
  public function __construct() {
90
  $this->setup_globals();
@@ -120,7 +117,6 @@ class BP_Admin {
120
  * @since 1.6.0
121
  */
122
  private function includes() {
123
- require( $this->admin_dir . 'bp-core-admin-classes.php' );
124
  require( $this->admin_dir . 'bp-core-admin-actions.php' );
125
  require( $this->admin_dir . 'bp-core-admin-settings.php' );
126
  require( $this->admin_dir . 'bp-core-admin-functions.php' );
@@ -134,8 +130,6 @@ class BP_Admin {
134
  *
135
  * @since 1.6.0
136
  *
137
- * @uses add_action() To add various actions.
138
- * @uses add_filter() To add various filters.
139
  */
140
  private function setup_actions() {
141
 
@@ -171,6 +165,10 @@ class BP_Admin {
171
  // On non-multisite, catch.
172
  add_action( 'load-users.php', 'bp_core_admin_user_manage_spammers' );
173
 
 
 
 
 
174
  /* Filters ***********************************************************/
175
 
176
  // Add link to settings page.
@@ -191,10 +189,6 @@ class BP_Admin {
191
  * Contextually hooked to site or network-admin depending on current configuration.
192
  *
193
  * @since 1.6.0
194
- *
195
- * @uses add_management_page() To add the Recount page in Tools section.
196
- * @uses add_options_page() To add the Forums settings page in Settings
197
- * section.
198
  */
199
  public function admin_menus() {
200
 
@@ -374,9 +368,6 @@ class BP_Admin {
374
  *
375
  * @since 1.6.0
376
  *
377
- * @uses add_settings_section() To add our own settings section.
378
- * @uses add_settings_field() To add various settings fields.
379
- * @uses register_setting() To register various settings.
380
  */
381
  public function register_admin_settings() {
382
 
@@ -612,76 +603,131 @@ class BP_Admin {
612
 
613
  <?php endif; ?>
614
 
615
- <div class="headline-feature">
616
- <h3 class="headline-title"><?php esc_html_e( 'Customizable BuddyPress Emails', 'buddypress' ); ?></h3>
 
 
617
 
618
- <div class="featured-image">
619
- <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/bp-emails-feature.png' ); ?>" alt="<?php esc_html_e( 'Change colors of the email template using the Customizer.', 'buddypress' ); ?>">
 
 
 
620
  </div>
 
621
 
622
- <p class="introduction"><?php _e( 'Keep your users coming back with beautiful and flexible email notifications.', 'buddypress' ); ?> </p>
623
- <p><?php _e( 'Edit the content of your emails, create new email templates, or change the design of the template in the Customizer. These are just a few of the customizations you can make to engage your users and increase their participation in your community with the new email features.', 'buddypress' ); ?> <a href="https://codex.buddypress.org/emails/"><?php esc_html_e( 'Learn more &rarr;', 'buddypress' ); ?></a></p>
624
 
625
- <div class="clear"></div>
626
- </div>
627
 
628
- <hr />
 
 
 
 
629
 
630
- <div class="bp-features-section">
 
 
 
 
 
 
 
 
631
 
632
- <div class="feature-section two-col">
633
- <div>
634
- <h3 class="feature-title"><?php esc_html_e( 'Post Type Comments Tracking', 'buddypress' ); ?></h3>
635
- <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/post-type.png' ); ?>" alt="<?php esc_attr_e( 'Registered post types', 'buddypress' ); ?>">
636
- <p><?php esc_html_e( 'New Activity functions help you track post type comments in sync with the Blogs component when activated.', 'buddypress' ); ?></p>
637
- </div>
638
- <div class="last-feature">
639
- <h3 class="feature-title"><?php esc_html_e( 'Twenty Twelve Companion Stylesheet', 'buddypress' ); ?></h3>
640
- <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/twentytwelve.png' ); ?>" alt="<?php esc_attr_e( 'BuddyPress styles Twenty Twelve', 'buddypress' ); ?>">
641
- <p><?php esc_html_e( 'BuddyPress components never looked so fine as they do now in the Twenty Twelve theme.', 'buddypress' ); ?></p>
642
- </div>
643
  </div>
644
 
645
- <div class="feature-section two-col">
646
- <div>
647
- <h3 class="feature-title"><?php esc_html_e( 'Support for Emojis', 'buddypress' ); ?></h3>
648
- <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/emoji-feature.png' ); ?>" alt="<?php esc_attr_e( 'Fun with Emojies', 'buddypress' ); ?>">
649
- <p><?php esc_html_e( 'Have fun and be merry! You can now use Emojis in activity updates, messages, and group descriptions.', 'buddypress' ); ?></p>
650
 
651
- </div>
652
- <div class="last-feature">
653
- <h3 class="feature-title"><?php esc_html_e( 'Autolink Settings for Profile Fields', 'buddypress' ); ?></h3>
654
- <img src="<?php echo esc_url( buddypress()->plugin_url . 'bp-core/admin/images/autolink-feature.png' ); ?>" alt="<?php esc_attr_e( 'Autolink settings in the profile fields panel', 'buddypress' ); ?>">
655
- <p><?php _e( 'Administrators can enable or disable autolink settings for each new profile field type.', 'buddypress' ); ?></p>
656
- </div>
657
  </div>
658
 
659
- </div>
 
 
 
 
660
 
661
- <div class="changelog">
662
- <h3 class="changelog-title"><?php esc_html_e( 'Under The Hood', 'buddypress' ); ?></h3>
 
 
 
663
 
664
- <div class="feature-section col two-col">
665
- <div>
666
- <h4 class="title"><?php esc_html_e( 'Localization Improvements', 'buddypress' ); ?></h4>
667
- <p><?php esc_html_e( 'We continue to improve on localization for translation editors so that BuddyPress will be available for everyone in their own language.', 'buddypress' ); ?></p>
668
- <h4 class="title"><?php esc_html_e( 'Accessibility Upgrades', 'buddypress' ); ?></h4>
669
- <p><?php esc_html_e( 'Continued improvements in the frontend and backend to make BuddyPress usable for everyone.', 'buddypress' ); ?></p>
670
- </div>
671
 
672
- <div class="last-feature">
673
- <h4 class="title"><?php esc_html_e( 'Enhanced Multisite Support', 'buddypress' ); ?></h4>
674
- <p><?php esc_html_e( 'BuddyPress is already primed for all multisite configurations available. We just made it better.', 'buddypress' ); ?></p>
675
- <h4 class="title"><?php esc_html_e( 'Developer Reference', 'buddypress' ); ?></h4>
676
- <p><?php esc_html_e( 'Regular updates to inline code documentation make it easier for developers to understand how BuddyPress works.', 'buddypress' ); ?></p>
677
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
678
  </div>
679
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
680
  </div>
681
 
682
- <p><?php _ex( 'Learn more:', 'About screen, website links', 'buddypress' ); ?> <a href="https://buddypress.org/blog/"><?php _ex( 'News', 'About screen, link to project blog', 'buddypress' ); ?></a> &bullet; <a href="https://buddypress.org/support/"><?php _ex( 'Support', 'About screen, link to support site', 'buddypress' ); ?></a> &bullet; <a href="https://codex.buddypress.org/"><?php _ex( 'Documentation', 'About screen, link to documentation', 'buddypress' ); ?></a> &bullet; <a href="https://bpdevel.wordpress.com/"><?php _ex( 'Development Blog', 'About screen, link to development blog', 'buddypress' ); ?></a></p>
 
683
 
684
- <p><?php _ex( 'Twitter:', 'official Twitter accounts:', 'buddypress' ); ?> <a href="https://twitter.com/buddypress/"><?php _ex( 'BuddyPress', '@buddypress twitter account name', 'buddypress' ); ?></a> &bullet; <a href="https://twitter.com/bptrac/"><?php _ex( 'Trac', '@bptrac twitter account name', 'buddypress' ); ?></a> &bullet; <a href="https://twitter.com/buddypressdev/"><?php _ex( 'Development', '@buddypressdev twitter account name', 'buddypress' ); ?></a></p>
 
685
 
686
  </div>
687
 
@@ -710,7 +756,7 @@ class BP_Admin {
710
  <h3 class="wp-people-group"><?php _e( 'Project Leaders', 'buddypress' ); ?></h3>
711
  <ul class="wp-people-group " id="wp-people-group-project-leaders">
712
  <li class="wp-person" id="wp-person-johnjamesjacoby">
713
- <a class="web" href="https://profiles.wordpress.org/johnjamesjacoby"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/81ec16063d89b162d55efe72165c105f?s=60">
714
  John James Jacoby</a>
715
  <span class="title"><?php _e( 'Project Lead', 'buddypress' ); ?></span>
716
  </li>
@@ -726,8 +772,13 @@ class BP_Admin {
726
  </li>
727
  </ul>
728
 
729
- <h3 class="wp-people-group"><?php _e( 'Core Team', 'buddypress' ); ?></h3>
730
  <ul class="wp-people-group " id="wp-people-group-core-team">
 
 
 
 
 
731
  <li class="wp-person" id="wp-person-r-a-y">
732
  <a class="web" href="https://profiles.wordpress.org/r-a-y"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/3bfa556a62b5bfac1012b6ba5f42ebfa?s=60">
733
  Ray</a>
@@ -738,11 +789,6 @@ class BP_Admin {
738
  Mathieu Viet</a>
739
  <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span>
740
  </li>
741
- <li class="wp-person" id="wp-person-mercime">
742
- <a class="web" href="https://profiles.wordpress.org/mercime"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/fae451be6708241627983570a1a1817a?s=60">
743
- Mercime</a>
744
- <span class="title"><?php _e( 'Navigator', 'buddypress' ); ?></span>
745
- </li>
746
  <li class="wp-person" id="wp-person-dcavins">
747
  <a class="web" href="https://profiles.wordpress.org/dcavins"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/a5fa7e83d59cb45ebb616235a176595a?s=60">
748
  David Cavins</a>
@@ -758,22 +804,25 @@ class BP_Admin {
758
  Hugo</a>
759
  <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span>
760
  </li>
761
- </ul>
762
-
763
- <h3 class="wp-people-group"><?php _e( '&#x1f31f;Recent Rockstars&#x1f31f;', 'buddypress' ); ?></h3>
764
- <ul class="wp-people-group " id="wp-people-group-rockstars">
765
  <li class="wp-person" id="wp-person-henry-wright">
766
  <a class="web" href="https://profiles.wordpress.org/henry.wright"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/0da2f1a9340d6af196b870f6c107a248?s=60">
767
  Henry Wright</a>
 
768
  </li>
769
  <li class="wp-person" id="wp-person-danbp">
770
  <a class="web" href="https://profiles.wordpress.org/danbp"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/0deae2e7003027fbf153500cd3fa5501?s=60">
771
  danbp</a>
 
772
  </li>
773
  <li class="wp-person" id="wp-person-shanebp">
774
  <a class="web" href="https://profiles.wordpress.org/shanebp"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/ffd294ab5833ba14aaf175f9acc71cc4?s=60">
775
  shanebp</a>
 
776
  </li>
 
 
 
 
777
  <li class="wp-person" id="wp-person-netweb">
778
  <a class="web" href="https://profiles.wordpress.org/netweb"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/97e1620b501da675315ba7cfb740e80f?s=60">
779
  Stephen Edgar</a>
@@ -782,45 +831,68 @@ class BP_Admin {
782
  <a class="web" href="https://profiles.wordpress.org/dimensionmedia"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/7735aada1ec39d0c1118bd92ed4551f1?s=60">
783
  David Bisset</a>
784
  </li>
785
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
786
  </ul>
787
 
788
  <h3 class="wp-people-group"><?php printf( esc_html__( 'Contributors to BuddyPress %s', 'buddypress' ), self::display_version() ); ?></h3>
789
  <p class="wp-credits-list">
 
 
790
  <a href="https://profiles.wordpress.org/boonebgorges/">Boone B Gorges (boonebgorges)</a>,
791
  <a href="https://profiles.wordpress.org/sbrajesh/">Brajesh Singh (sbrajesh)</a>,
792
- <a href="https://profiles.wordpress.org/thebrandonallen/">Brandon Allen (thebrandonallen)</a>,
793
  <a href="https://profiles.wordpress.org/needle/">Christian Wach (needle)</a>,
794
- <a href="https://profiles.wordpress.org/timersys/">Damian (timersys)</a>,
795
- <a href="https://profiles.wordpress.org/danbrellis/">danbrellis</a>,
796
  <a href="https://profiles.wordpress.org/dcavins/">David Cavins (dcavins)</a>,
 
797
  <a href="https://profiles.wordpress.org/wpdennis/">Dennis (wpdennis)</a>,
798
- <a href="https://profiles.wordpress.org/wdfee/">Fee (wdfee)</a>,
799
- <a href="https://profiles.wordpress.org/garrett-eclipse/">Garrett Hyder (garrett-eclipse)</a>,
800
- <a href="https://profiles.wordpress.org/Mamaduka/">George Mamadashvili (Mamaduka)</a>,
801
  <a href="https://profiles.wordpress.org/henrywright/">Henry Wright (henry.wright)</a>,
 
802
  <a href="https://profiles.wordpress.org/hnla/">Hugo (hnla)</a>,
803
- <a href="https://profiles.wordpress.org/jeffsayre/">Jeff Sayre (jeffsayre)</a>,
804
  <a href="https://profiles.wordpress.org/johnjamesjacoby/">John James Jacoby (johnjamesjacoby)</a>,
805
- <a href="https://profiles.wordpress.org/Jonnyauk/">Jonnyauk</a>,
806
- <a href="https://profiles.wordpress.org/joost-abrahams/">Joost Abrahams (joost-abrahams)</a>,
807
- <a href="https://profiles.wordpress.org/kennibc/">kennibc</a>,
808
- <a href="https://profiles.wordpress.org/sooskriszta/">OC2PS (sooskriszta)</a>,
809
  <a href="https://profiles.wordpress.org/Offereins">Laurens Offereins (Offereins)</a>,
810
- <a href="https://profiles.wordpress.org/LenLay/">LenLay</a>,
811
  <a href="https://profiles.wordpress.org/imath/">Mathieu Viet (imath)</a>,
812
  <a href="https://profiles.wordpress.org/mercime/">mercime</a>,
813
  <a href="https://profiles.wordpress.org/tw2113/">Michael Beckwith (tw2113)</a>,
814
- <a href="https://profiles.wordpress.org/modemlooper/">modemlooper</a>,
 
815
  <a href="https://profiles.wordpress.org/DJPaul/">Paul Gibbs (DJPaul)</a>,
816
- <a href="https://profiles.wordpress.org/ramiy/">Rami Yushuvaev (ramiy)</a>,
817
  <a href="https://profiles.wordpress.org/r-a-y/">r-a-y</a>,
818
- <a href="https://profiles.wordpress.org/shanebp/">shanebp</a>,
819
- <a href="https://profiles.wordpress.org/slaffik/">Slava UA (slaffik)</a>,
820
- <a href="https://profiles.wordpress.org/jozik/">Srdjan (jozik)</a>,
 
821
  <a href="https://profiles.wordpress.org/netweb/">Stephen Edgar (netweb)</a>,
822
- <a href="https://profiles.wordpress.org/timeuser/">timeuser</a>,
823
- <a href="https://profiles.wordpress.org/vnd/">vnd</a>.
 
 
 
 
824
  </p>
825
 
826
  <h3 class="wp-people-group"><?php _e( '&#x1f496;With our thanks to these Open Source projects&#x1f496;', 'buddypress' ); ?></h3>
@@ -828,9 +900,12 @@ class BP_Admin {
828
  <a href="https://github.com/ichord/At.js">At.js</a>,
829
  <a href="https://bbpress.org">bbPress</a>,
830
  <a href="https://github.com/ichord/Caret.js">Caret.js</a>,
831
- <a href="http://tedgoas.github.io/Cerberus/">Cerberus</a>,
 
832
  <a href="https://github.com/carhartl/jquery-cookie">jquery.cookie</a>,
 
833
  <a href="https://www.mediawiki.org/wiki/MediaWiki">MediaWiki</a>,
 
834
  <a href="https://wordpress.org">WordPress</a>.
835
  </p>
836
 
@@ -848,7 +923,7 @@ class BP_Admin {
848
 
849
  // Switch welcome text based on whether this is a new installation or not.
850
  $welcome_text = ( self::is_new_install() )
851
- ? __( 'Thank you for installing BuddyPress! BuddyPress helps you build any type of community website using WordPress, with member profiles, activity streams, user groups, messaging, and more.', 'buddypress' )
852
  : __( 'Thank you for updating! BuddyPress %s has many new features that you will enjoy.', 'buddypress' );
853
 
854
  ?>
@@ -891,6 +966,47 @@ class BP_Admin {
891
  <?php
892
  }
893
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
894
  /** Helpers ***************************************************************/
895
 
896
  /**
82
  *
83
  * @since 1.6.0
84
  *
 
 
 
85
  */
86
  public function __construct() {
87
  $this->setup_globals();
117
  * @since 1.6.0
118
  */
119
  private function includes() {
 
120
  require( $this->admin_dir . 'bp-core-admin-actions.php' );
121
  require( $this->admin_dir . 'bp-core-admin-settings.php' );
122
  require( $this->admin_dir . 'bp-core-admin-functions.php' );
130
  *
131
  * @since 1.6.0
132
  *
 
 
133
  */
134
  private function setup_actions() {
135
 
165
  // On non-multisite, catch.
166
  add_action( 'load-users.php', 'bp_core_admin_user_manage_spammers' );
167
 
168
+ // Emails.
169
+ add_filter( 'manage_' . bp_get_email_post_type() . '_posts_columns', array( $this, 'emails_register_situation_column' ) );
170
+ add_action( 'manage_' . bp_get_email_post_type() . '_posts_custom_column', array( $this, 'emails_display_situation_column_data' ), 10, 2 );
171
+
172
  /* Filters ***********************************************************/
173
 
174
  // Add link to settings page.
189
  * Contextually hooked to site or network-admin depending on current configuration.
190
  *
191
  * @since 1.6.0
 
 
 
 
192
  */
193
  public function admin_menus() {
194
 
368
  *
369
  * @since 1.6.0
370
  *
 
 
 
371
  */
372
  public function register_admin_settings() {
373
 
603
 
604
  <?php endif; ?>
605
 
606
+ <div class="bp-headline-feature">
607
+ <div class="bp-headline">
608
+ <span class="dashicons dashicons-list-view" aria-hidden="true"></span>
609
+ <h3 class="headline-title"><?php esc_html_e( 'Groups Query Overhaul', 'buddypress' ); ?></h3>
610
 
611
+ <p class="introduction"><?php
612
+ /* translators: %s: URL to the development post about this feature */
613
+ printf( __( 'Huge performance improvements on sites using persistent caching. <a href="%s">Learn more about the Groups Query rewrite</a>.', 'buddypress' ),
614
+ 'https://bpdevel.wordpress.com/2016/09/19/group-queries-have-been-rewritten-for-bp-2-7/' );
615
+ ?></p>
616
  </div>
617
+ </div>
618
 
619
+ <div class="bp-features-section">
 
620
 
621
+ <h3 class="headline-title"><?php esc_html_e( 'For Developers &amp; Site Builders', 'buddypress' ); ?></h3>
 
622
 
623
+ <div class="bp-feature">
624
+ <span class="dashicons dashicons-calendar" aria-hidden="true"></span>
625
+ <h4 class="feature-title"><?php esc_html_e( 'Improved Profile Date Field', 'buddypress' ); ?></h4>
626
+ <p><?php _e( 'New Date Field settings, "Date format" and "Range", make it easier for site administrators to decide how date-based data will be collected and displayed.', 'buddypress' ); ?></p>
627
+ </div>
628
 
629
+ <div class="bp-feature opposite">
630
+ <span class="dashicons dashicons-groups" aria-hidden="true"></span>
631
+ <h4 class="feature-title"><?php esc_html_e( 'Group Types Integration in Templates', 'buddypress' ); ?></h4>
632
+ <p><?php
633
+ /* translators: %s: URL to the BuddyPress Codex article */
634
+ printf( __( 'Enable developers to show Group Types on the front end as well as control where the group type information is rendered. <a href="%s">Learn how to implement this feature</a>.', 'buddypress' ),
635
+ 'https://codex.buddypress.org/developer/group-types/' );
636
+ ?></p>
637
+ </div>
638
 
639
+ <div class="bp-feature">
640
+ <span class="dashicons dashicons-admin-multisite" aria-hidden="true"></span>
641
+ <h4 class="feature-title"><?php esc_html_e( 'Use the Site Icon as Your Site&#8217;s Profile Photo', 'buddypress' ); ?></h4>
642
+ <p><?php
643
+ /* translators: %s: URL to the WordPress Codex article */
644
+ printf( __( 'BuddyPress sets the site admin&#8217;s profile photo as the default site profile photo on the Sites Directory page. You can now <a href="%s">use the Site Icon introduced in WordPress 4.3</a> instead.', 'buddypress' ),
645
+ 'https://codex.wordpress.org/Creating_a_Favicon#WordPress_Version_4.3_or_later' );
646
+ ?></p>
 
 
 
647
  </div>
648
 
649
+ <div class="bp-feature opposite">
650
+ <span class="dashicons dashicons-filter" aria-hidden="true"></span>
651
+ <h4 class="title"><?php esc_html_e( 'Member Type and Group Type Filters in Users and Groups Admin Screens', 'buddypress' ); ?></h4>
652
+ <p><?php esc_html_e( 'Easily filter your members and groups by type and set types in bulk on the users and groups list tables in the dashboard.', 'buddypress' ); ?></p>
653
+ </div>
654
 
655
+ <div class="bp-feature">
656
+ <span class="dashicons dashicons-clock" aria-hidden="true"></span>
657
+ <h4 class="feature-title"><?php esc_html_e( 'Localized Timestamps', 'buddypress' ); ?></h4>
658
+ <p><?php esc_html_e( 'Fix inaccurate timestamps due to time zones or page caching with new client-side timestamp handling.', 'buddypress' ); ?></p>
 
 
659
  </div>
660
 
661
+ <div class="bp-feature opposite">
662
+ <span class="dashicons dashicons-email" aria-hidden="true"></span>
663
+ <h4 class="feature-title"><?php esc_html_e( 'Links to Unsubscribe from Emails', 'buddypress' ); ?></h4>
664
+ <p><?php esc_html_e( 'Improve user experience by facilitating the removal of any or all subscriptions via new email tokens and unsubscribe links.', 'buddypress' ); ?></p>
665
+ </div>
666
 
667
+ <div class="bp-feature">
668
+ <span class="dashicons dashicons-admin-page" aria-hidden="true"></span>
669
+ <h4 class="title"><?php esc_html_e( 'Use WP Page Names for Headings of BP Directory Pages', 'buddypress' ); ?></h4>
670
+ <p><?php esc_html_e( 'Whatever you choose as the title of your Activity, Sites, Members, or Groups directory pages on the back end, is what you&#8217;ll get as the heading on the front end.', 'buddypress' ); ?></p>
671
+ </div>
672
 
673
+ <div class="bp-feature opposite">
674
+ <span class="dashicons dashicons-universal-access" aria-hidden="true"></span>
675
+ <h4 class="title"><?php esc_html_e( 'Accessibility Updates for the Front End and Back End', 'buddypress' ); ?></h4>
676
+ <p><?php esc_html_e( 'Continued improvements for universal access help make BuddyPress back- and front-end screens usable for everyone (and on more devices).', 'buddypress' ); ?></p>
677
+ </div>
 
 
678
 
679
+ <div class="bp-feature">
680
+ <span class="dashicons dashicons-screenoptions" aria-hidden="true"></span>
681
+ <h4 class="title"><?php
682
+ /* translators: %s: BP_Button */
683
+ printf( __( 'Refactored %s Class to Accept New Arguments', 'buddypress' ), '<code>BP_Button</code>' );
684
+ ?></h4>
685
+ <p><?php esc_html_e( 'Provides developers with improved syntax and more control over the rendering of buttons.', 'buddypress' ); ?></p>
686
+ </div>
687
+
688
+ <div class="bp-feature opposite">
689
+ <span class="dashicons dashicons-image-filter" aria-hidden="true"></span>
690
+ <h4 class="title"><?php esc_html_e( 'Improvements to a Single Group&#8217;s Management Screens', 'buddypress' ); ?></h4>
691
+ <p><?php esc_html_e( 'Improved markup, new modular group management templates, and a new member search form are just some of the enhancements added to the single group admin screens.', 'buddypress' ); ?></p>
692
+ </div>
693
+
694
+ <div class="bp-feature">
695
+ <span class="dashicons dashicons-groups" aria-hidden="true"></span>
696
+ <h4 class="title"><?php
697
+ /* translators: %s: parent_id */
698
+ printf( __( 'Support for Querying for Groups by New Column %s', 'buddypress' ), '<code>parent_id</code>' );
699
+ ?></h4>
700
+ <p><?php esc_html_e( 'Query support for hierarchical groups makes it much easier for developers to add custom front-end functionality.', 'buddypress' ); ?></p>
701
  </div>
702
 
703
+ <div class="bp-feature opposite">
704
+ <span class="dashicons dashicons-chart-bar" aria-hidden="true"></span>
705
+ <h4 class="title"><?php esc_html_e( 'Many, Many Performance Improvements', 'buddypress' ); ?></h4>
706
+ <p><?php
707
+ /* translators: %s: bp_get_user_groups() */
708
+ printf( __( 'Improved performance by removing extra database queries, adding new cache calls, and removing the number of loops in %s.', 'buddypress' ), '<code>bp_get_user_groups()</code>' );
709
+ ?></p>
710
+ </div>
711
+
712
+
713
+ <div class="clear"></div>
714
+ </div>
715
+
716
+ <div class="bp-changelog-section">
717
+ <h3 class="changelog-title"><?php esc_html_e( 'And so much more!', 'buddypress' ); ?></h3>
718
+ <p class="bp-changelog-url"><?php
719
+ /* translators: %s: URL to the BuddyPress Codex article */
720
+ printf( __( '<a href="%s">Changelog for BuddyPress 2.7.</a>', 'buddypress' ),
721
+ 'https://codex.buddypress.org/releases/version-2-7-0/' );
722
+ ?></p>
723
+
724
  </div>
725
 
726
+ <div class="bp-assets">
727
+ <p><?php _ex( 'Learn more:', 'About screen, website links', 'buddypress' ); ?> <a href="https://buddypress.org/blog/"><?php _ex( 'News', 'About screen, link to project blog', 'buddypress' ); ?></a> &bullet; <a href="https://buddypress.org/support/"><?php _ex( 'Support', 'About screen, link to support site', 'buddypress' ); ?></a> &bullet; <a href="https://codex.buddypress.org/"><?php _ex( 'Documentation', 'About screen, link to documentation', 'buddypress' ); ?></a> &bullet; <a href="https://bpdevel.wordpress.com/"><?php _ex( 'Development Blog', 'About screen, link to development blog', 'buddypress' ); ?></a></p>
728
 
729
+ <p><?php _ex( 'Twitter:', 'official Twitter accounts:', 'buddypress' ); ?> <a href="https://twitter.com/buddypress/"><?php _ex( 'BuddyPress', '@buddypress twitter account name', 'buddypress' ); ?></a> &bullet; <a href="https://twitter.com/bptrac/"><?php _ex( 'Trac', '@bptrac twitter account name', 'buddypress' ); ?></a> &bullet; <a href="https://twitter.com/buddypressdev/"><?php _ex( 'Development', '@buddypressdev twitter account name', 'buddypress' ); ?></a></p>
730
+ </div>
731
 
732
  </div>
733
 
756
  <h3 class="wp-people-group"><?php _e( 'Project Leaders', 'buddypress' ); ?></h3>
757
  <ul class="wp-people-group " id="wp-people-group-project-leaders">
758
  <li class="wp-person" id="wp-person-johnjamesjacoby">
759
+ <a class="web" href="https://profiles.wordpress.org/johnjamesjacoby"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/7a2644fb53ae2f7bfd7143b504af396c?s=60">
760
  John James Jacoby</a>
761
  <span class="title"><?php _e( 'Project Lead', 'buddypress' ); ?></span>
762
  </li>
772
  </li>
773
  </ul>
774
 
775
+ <h3 class="wp-people-group"><?php _e( 'BuddyPress Team', 'buddypress' ); ?></h3>
776
  <ul class="wp-people-group " id="wp-people-group-core-team">
777
+ <li class="wp-person" id="wp-person-mercime">
778
+ <a class="web" href="https://profiles.wordpress.org/mercime"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/fae451be6708241627983570a1a1817a?s=60">
779
+ Mercime</a>
780
+ <span class="title"><?php _e( '2.7 Release Lead', 'buddypress' ); ?></span>
781
+ </li>
782
  <li class="wp-person" id="wp-person-r-a-y">
783
  <a class="web" href="https://profiles.wordpress.org/r-a-y"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/3bfa556a62b5bfac1012b6ba5f42ebfa?s=60">
784
  Ray</a>
789
  Mathieu Viet</a>
790
  <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span>
791
  </li>
 
 
 
 
 
792
  <li class="wp-person" id="wp-person-dcavins">
793
  <a class="web" href="https://profiles.wordpress.org/dcavins"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/a5fa7e83d59cb45ebb616235a176595a?s=60">
794
  David Cavins</a>
804
  Hugo</a>
805
  <span class="title"><?php _e( 'Core Developer', 'buddypress' ); ?></span>
806
  </li>
 
 
 
 
807
  <li class="wp-person" id="wp-person-henry-wright">
808
  <a class="web" href="https://profiles.wordpress.org/henry.wright"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/0da2f1a9340d6af196b870f6c107a248?s=60">
809
  Henry Wright</a>
810
+ <span class="title"><?php _e( 'Community Support', 'buddypress' ); ?></span>
811
  </li>
812
  <li class="wp-person" id="wp-person-danbp">
813
  <a class="web" href="https://profiles.wordpress.org/danbp"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/0deae2e7003027fbf153500cd3fa5501?s=60">
814
  danbp</a>
815
+ <span class="title"><?php _e( 'Community Support', 'buddypress' ); ?></span>
816
  </li>
817
  <li class="wp-person" id="wp-person-shanebp">
818
  <a class="web" href="https://profiles.wordpress.org/shanebp"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/ffd294ab5833ba14aaf175f9acc71cc4?s=60">
819
  shanebp</a>
820
+ <span class="title"><?php _e( 'Community Support', 'buddypress' ); ?></span>
821
  </li>
822
+ </ul>
823
+
824
+ <h3 class="wp-people-group"><?php _e( '&#x1f31f;Recent Rockstars&#x1f31f;', 'buddypress' ); ?></h3>
825
+ <ul class="wp-people-group " id="wp-people-group-rockstars">
826
  <li class="wp-person" id="wp-person-netweb">
827
  <a class="web" href="https://profiles.wordpress.org/netweb"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/97e1620b501da675315ba7cfb740e80f?s=60">
828
  Stephen Edgar</a>
831
  <a class="web" href="https://profiles.wordpress.org/dimensionmedia"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/7735aada1ec39d0c1118bd92ed4551f1?s=60">
832
  David Bisset</a>
833
  </li>
834
+ <li class="wp-person" id="wp-person-offereins">
835
+ <a class="web" href="https://profiles.wordpress.org/Offereins"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/2404ed0a35bb41aedefd42b0a7be61c1?s=60">
836
+ Laurens Offereins</a>
837
+ </li>
838
+ <li class="wp-person" id="wp-person-garrett-eclipse">
839
+ <a class="web" href="https://profiles.wordpress.org/garrett-eclipse"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/7f68f24441c61514d5d0e1451bb5bc9d?s=60">
840
+ Garrett Hyder</a>
841
+ </li>
842
+ <li class="wp-person" id="wp-person-thebrandonallen">
843
+ <a class="web" href="https://profiles.wordpress.org/thebrandonallen"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/6d3f77bf3c9ca94c406dea401b566950?s=60">
844
+ Brandon Allen</a>
845
+ </li>
846
+ <li class="wp-person" id="wp-person-ramiy">
847
+ <a class="web" href="https://profiles.wordpress.org/ramiy"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/ce2a269e424156d79cb0c4e1d4d82db1?s=60">
848
+ Rami Yushuvaev</a>
849
+ </li>
850
+ <li class="wp-person" id="wp-person-slaffik">
851
+ <a class="web" href="https://profiles.wordpress.org/slaffik/"><img alt="" class="gravatar" src="//www.gravatar.com/avatar/61fb07ede3247b63f19015f200b3eb2c?s=60">
852
+ Slava Abakumov</a>
853
+ </li>
854
  </ul>
855
 
856
  <h3 class="wp-people-group"><?php printf( esc_html__( 'Contributors to BuddyPress %s', 'buddypress' ), self::display_version() ); ?></h3>
857
  <p class="wp-credits-list">
858
+ <a href="https://profiles.wordpress.org/jorbin/">Aaron Jorbin (jorbin)</a>,
859
+ <a href="https://profiles.wordpress.org/abwebstudio1/">abwebstudio1</a>,
860
  <a href="https://profiles.wordpress.org/boonebgorges/">Boone B Gorges (boonebgorges)</a>,
861
  <a href="https://profiles.wordpress.org/sbrajesh/">Brajesh Singh (sbrajesh)</a>,
 
862
  <a href="https://profiles.wordpress.org/needle/">Christian Wach (needle)</a>,
863
+ <a href="https://profiles.wordpress.org/danbp/">danbp</a>,
864
+ <a href="https://profiles.wordpress.org/danielhuesken/">Daniel Hüsken (danielhuesken)</a>,
865
  <a href="https://profiles.wordpress.org/dcavins/">David Cavins (dcavins)</a>,
866
+ <a href="https://profiles.wordpress.org/demon_ru/">demon_ru</a>,
867
  <a href="https://profiles.wordpress.org/wpdennis/">Dennis (wpdennis)</a>,
868
+ <a href="https://profiles.wordpress.org/ericlewis/">Eric Andrew Lewis (ericlewis)</a>,
 
 
869
  <a href="https://profiles.wordpress.org/henrywright/">Henry Wright (henry.wright)</a>,
870
+ <a href="https://profiles.wordpress.org/herbovec/">herbovec</a>,
871
  <a href="https://profiles.wordpress.org/hnla/">Hugo (hnla)</a>,
872
+ <a href="https://profiles.wordpress.org/jdgrimes/">J.D. Grimes (jdgrimes)</a>,
873
  <a href="https://profiles.wordpress.org/johnjamesjacoby/">John James Jacoby (johnjamesjacoby)</a>,
874
+ <a href="https://profiles.wordpress.org/dunhakdis/">Joseph G. (dunhakdis)</a>,
875
+ <a href="https://profiles.wordpress.org/kitsunesolar/">kitsunesolar</a>,
876
+ <a href="https://profiles.wordpress.org/lakrisgubben/">lakrisgubben</a>,
 
877
  <a href="https://profiles.wordpress.org/Offereins">Laurens Offereins (Offereins)</a>,
 
878
  <a href="https://profiles.wordpress.org/imath/">Mathieu Viet (imath)</a>,
879
  <a href="https://profiles.wordpress.org/mercime/">mercime</a>,
880
  <a href="https://profiles.wordpress.org/tw2113/">Michael Beckwith (tw2113)</a>,
881
+ <a href="https://profiles.wordpress.org/michaelbeil/">Michael Beil (michaelbeil)</a>,
882
+ <a href="https://profiles.wordpress.org/swissspidy/">Pascal Birchler (swissspidy)</a>,
883
  <a href="https://profiles.wordpress.org/DJPaul/">Paul Gibbs (DJPaul)</a>,
 
884
  <a href="https://profiles.wordpress.org/r-a-y/">r-a-y</a>,
885
+ <a href="https://profiles.wordpress.org/espellcaste/">Renato Alves (espellcaste)</a>,
886
+ <a href="https://profiles.wordpress.org/scharc/">scharc</a>,
887
+ <a href="https://profiles.wordpress.org/slaffik/">Slava Abakumov (slaffik)</a>,
888
+ <a href="https://profiles.wordpress.org/spenser4551/">spenser4551</a>,
889
  <a href="https://profiles.wordpress.org/netweb/">Stephen Edgar (netweb)</a>,
890
+ <a href="https://profiles.wordpress.org/svenl77/">Sven Lehnert (svenl77)</a>,
891
+ <a href="https://profiles.wordpress.org/tharsheblows/">tharsheblows</a>,
892
+ <a href="https://profiles.wordpress.org/thomaslhotta/">thomaslhotta</a>,
893
+ <a href="https://profiles.wordpress.org/tomas711/">tomas711</a>,
894
+ <a href="https://profiles.wordpress.org/venturavan2/">venturavan2</a>,
895
+ <a href="https://profiles.wordpress.org/wordpressrene/">wordpressrene</a>.
896
  </p>
897
 
898
  <h3 class="wp-people-group"><?php _e( '&#x1f496;With our thanks to these Open Source projects&#x1f496;', 'buddypress' ); ?></h3>
900
  <a href="https://github.com/ichord/At.js">At.js</a>,
901
  <a href="https://bbpress.org">bbPress</a>,
902
  <a href="https://github.com/ichord/Caret.js">Caret.js</a>,
903
+ <a href="https://tedgoas.github.io/Cerberus/">Cerberus</a>,
904
+ <a href="https://ionicons.com/">Ionicons</a>,
905
  <a href="https://github.com/carhartl/jquery-cookie">jquery.cookie</a>,
906
+ <a href="https://mattbradley.github.io/livestampjs/">Livestamp.js</a>,
907
  <a href="https://www.mediawiki.org/wiki/MediaWiki">MediaWiki</a>,
908
+ <a href="http://momentjs.com/">Moment.js</a>,
909
  <a href="https://wordpress.org">WordPress</a>.
910
  </p>
911
 
923
 
924
  // Switch welcome text based on whether this is a new installation or not.
925
  $welcome_text = ( self::is_new_install() )
926
+ ? __( 'Thank you for installing BuddyPress! BuddyPress helps site builders and WordPress developers add community features to their websites, with user profile fields, activity streams, messaging, and notifications.', 'buddypress' )
927
  : __( 'Thank you for updating! BuddyPress %s has many new features that you will enjoy.', 'buddypress' );
928
 
929
  ?>
966
  <?php
967
  }
968
 
969
+ /** Emails ****************************************************************/
970
+
971
+ /**
972
+ * Registers 'Situations' column on Emails dashboard page.
973
+ *
974
+ * @since 2.6.0
975
+ *
976
+ * @param array $columns Current column data.
977
+ * @return array
978
+ */
979
+ public function emails_register_situation_column( $columns = array() ) {
980
+ $situation = array(
981
+ 'situation' => _x( 'Situations', 'Email post type', 'buddypress' )
982
+ );
983
+
984
+ // Inject our 'Situations' column just before the last 'Date' column.
985
+ return array_slice( $columns, 0, -1, true ) + $situation + array_slice( $columns, -1, null, true );
986
+ }
987
+
988
+ /**
989
+ * Output column data for our custom 'Situations' column.
990
+ *
991
+ * @since 2.6.0
992
+ *
993
+ * @param string $column Current column name.
994
+ * @param int $post_id Current post ID.
995
+ */
996
+ public function emails_display_situation_column_data( $column = '', $post_id = 0 ) {
997
+ if ( 'situation' !== $column ) {
998
+ return;
999
+ }
1000
+
1001
+ // Grab email situations for the current post.
1002
+ $situations = wp_list_pluck( get_the_terms( $post_id, bp_get_email_tax_type() ), 'description' );
1003
+
1004
+ // Output each situation as a list item.
1005
+ echo '<ul><li>';
1006
+ echo implode( '</li><li>', $situations );
1007
+ echo '</li></ul>';
1008
+ }
1009
+
1010
  /** Helpers ***************************************************************/
1011
 
1012
  /**
bp-core/classes/class-bp-attachment-avatar.php CHANGED
@@ -25,8 +25,6 @@ class BP_Attachment_Avatar extends BP_Attachment {
25
  * @since 2.3.0
26
  *
27
  * @see BP_Attachment::__construct() for list of parameters
28
- * @uses bp_core_avatar_original_max_filesize()
29
- * @uses BP_Attachment::__construct()
30
  */
31
  public function __construct() {
32
  // Allowed avatar types.
@@ -63,11 +61,6 @@ class BP_Attachment_Avatar extends BP_Attachment {
63
  * Set Upload Dir data for avatars.
64
  *
65
  * @since 2.3.0
66
- *
67
- * @uses bp_core_avatar_upload_path()
68
- * @uses bp_core_avatar_url()
69
- * @uses bp_upload_dir()
70
- * @uses BP_Attachment::set_upload_dir()
71
  */
72
  public function set_upload_dir() {
73
  if ( bp_core_avatar_upload_path() && bp_core_avatar_url() ) {
@@ -87,10 +80,7 @@ class BP_Attachment_Avatar extends BP_Attachment {
87
  *
88
  * @since 2.3.0
89
  *
90
- * @uses bp_core_check_avatar_size()
91
- * @uses bp_core_check_avatar_type()
92
- *
93
- * @param array $file the temporary file attributes (before it has been moved).
94
  * @return array the file with extra errors if needed.
95
  */
96
  public function validate_upload( $file = array() ) {
@@ -118,8 +108,6 @@ class BP_Attachment_Avatar extends BP_Attachment {
118
  * @since 2.3.0
119
  * @since 2.4.0 Add the $ui_available_width parameter, to inform about the Avatar UI width.
120
  *
121
- * @uses bp_core_avatar_original_max_width()
122
- *
123
  * @param string $file The absolute path to the file.
124
  * @param int $ui_available_width Available width for the UI.
125
  * @return mixed
@@ -184,8 +172,6 @@ class BP_Attachment_Avatar extends BP_Attachment {
184
  *
185
  * @since 2.3.0
186
  *
187
- * @uses bp_core_avatar_full_width()
188
- * @uses bp_core_avatar_full_height()
189
  *
190
  * @param string $file the absolute path to the file.
191
  * @return bool
@@ -208,12 +194,6 @@ class BP_Attachment_Avatar extends BP_Attachment {
208
  * @since 2.3.0
209
  *
210
  * @see BP_Attachment::crop for the list of parameters
211
- * @uses bp_core_fetch_avatar()
212
- * @uses bp_core_delete_existing_avatar()
213
- * @uses bp_core_avatar_full_width()
214
- * @uses bp_core_avatar_full_height()
215
- * @uses bp_core_avatar_dimension()
216
- * @uses BP_Attachment::crop
217
  *
218
  * @param array $args Array of arguments for the cropping.
219
  * @return array The cropped avatars (full and thumb).
25
  * @since 2.3.0
26
  *
27
  * @see BP_Attachment::__construct() for list of parameters
 
 
28
  */
29
  public function __construct() {
30
  // Allowed avatar types.
61
  * Set Upload Dir data for avatars.
62
  *
63
  * @since 2.3.0
 
 
 
 
 
64
  */
65
  public function set_upload_dir() {
66
  if ( bp_core_avatar_upload_path() && bp_core_avatar_url() ) {
80
  *
81
  * @since 2.3.0
82
  *
83
+ * @param array $file the temporary file attributes (before it has been moved).
 
 
 
84
  * @return array the file with extra errors if needed.
85
  */
86
  public function validate_upload( $file = array() ) {
108
  * @since 2.3.0
109
  * @since 2.4.0 Add the $ui_available_width parameter, to inform about the Avatar UI width.
110
  *
 
 
111
  * @param string $file The absolute path to the file.
112
  * @param int $ui_available_width Available width for the UI.
113
  * @return mixed
172
  *
173
  * @since 2.3.0
174
  *
 
 
175
  *
176
  * @param string $file the absolute path to the file.
177
  * @return bool
194
  * @since 2.3.0
195
  *
196
  * @see BP_Attachment::crop for the list of parameters
 
 
 
 
 
 
197
  *
198
  * @param array $args Array of arguments for the cropping.
199
  * @return array The cropped avatars (full and thumb).
bp-core/classes/class-bp-attachment-cover-image.php CHANGED
@@ -1,291 +1,291 @@
1
- <?php
2
- /**
3
- * Core Cover Image attachment class.
4
- *
5
- * @package BuddyPress
6
- * @subpackage Core
7
- * @since 2.4.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * BP Attachment Cover Image class.
15
- *
16
- * Extends BP Attachment to manage the cover images uploads.
17
- *
18
- * @since 2.4.0
19
- */
20
- class BP_Attachment_Cover_Image extends BP_Attachment {
21
- /**
22
- * The constuctor.
23
- *
24
- * @since 2.4.0
25
- */
26
- public function __construct() {
27
- // Allowed cover image types & upload size.
28
- $allowed_types = bp_attachments_get_allowed_types( 'cover_image' );
29
- $max_upload_file_size = bp_attachments_get_max_upload_file_size( 'cover_image' );
30
-
31
- parent::__construct( array(
32
- 'action' => 'bp_cover_image_upload',
33
- 'file_input' => 'file',
34
- 'original_max_filesize' => $max_upload_file_size,
35
- 'base_dir' => bp_attachments_uploads_dir_get( 'dir' ),
36
- 'required_wp_files' => array( 'file', 'image' ),
37
-
38
- // Specific errors for cover images.
39
- 'upload_error_strings' => array(
40
- 11 => sprintf( __( 'That image is too big. Please upload one smaller than %s', 'buddypress' ), size_format( $max_upload_file_size ) ),
41
- 12 => sprintf( _n( 'Please upload only this file type: %s.', 'Please upload only these file types: %s.', count( $allowed_types ), 'buddypress' ), self::get_cover_image_types( $allowed_types ) ),
42
- ),
43
- ) );
44
- }
45
-
46
- /**
47
- * Gets the available cover image types.
48
- *
49
- * @since 2.4.0
50
- *
51
- * @param array $allowed_types Array of allowed cover image types.
52
- * @return string $value Comma-separated list of allowed cover image types.
53
- */
54
- public static function get_cover_image_types( $allowed_types = array() ) {
55
- $types = array_map( 'strtoupper', $allowed_types );
56
- $comma = _x( ',', 'cover image types separator', 'buddypress' );
57
- return join( $comma . ' ', $types );
58
- }
59
-
60
- /**
61
- * Cover image specific rules.
62
- *
63
- * Adds an error if the cover image size or type don't match BuddyPress needs.
64
- * The error code is the index of $upload_error_strings.
65
- *
66
- * @since 2.4.0
67
- *
68
- * @param array $file The temporary file attributes (before it has been moved).
69
- * @return array $file The file with extra errors if needed.
70
- */
71
- public function validate_upload( $file = array() ) {
72
- // Bail if already an error.
73
- if ( ! empty( $file['error'] ) ) {
74
- return $file;
75
- }
76
-
77
- // File size is too big.
78
- if ( $file['size'] > $this->original_max_filesize ) {
79
- $file['error'] = 11;
80
-
81
- // File is of invalid type.
82
- } elseif ( ! bp_attachments_check_filetype( $file['tmp_name'], $file['name'], bp_attachments_get_allowed_mimes( 'cover_image' ) ) ) {
83
- $file['error'] = 12;
84
- }
85
-
86
- // Return with error code attached.
87
- return $file;
88
- }
89
-
90
- /**
91
- * Set the directory when uploading a file.
92
- *
93
- * @since 2.4.0
94
- *
95
- * @param array $upload_dir The original Uploads dir.
96
- * @return array $value Upload data (path, url, basedir...).
97
- */
98
- public function upload_dir_filter( $upload_dir = array() ) {
99
- // Default values are for profiles.
100
- $object_id = bp_displayed_user_id();
101
-
102
- if ( empty( $object_id ) ) {
103
- $object_id = bp_loggedin_user_id();
104
- }
105
-
106
- $object_directory = 'members';
107
-
108
- // We're in a group, edit default values.
109
- if ( bp_is_group() || bp_is_group_create() ) {
110
- $object_id = bp_get_current_group_id();
111
- $object_directory = 'groups';
112
- }
113
-
114
- // Set the subdir.
115
- $subdir = '/' . $object_directory . '/' . $object_id . '/cover-image';
116
-
117
- /**
118
- * Filters the cover image upload directory.
119
- *
120
- * @since 2.4.0
121
- *
122
- * @param array $value Array containing the path, URL, and other helpful settings.
123
- * @param array $upload_dir The original Uploads dir.
124
- */
125
- return apply_filters( 'bp_attachments_cover_image_upload_dir', array(
126
- 'path' => $this->upload_path . $subdir,
127
- 'url' => $this->url . $subdir,
128
- 'subdir' => $subdir,
129
- 'basedir' => $this->upload_path,
130
- 'baseurl' => $this->url,
131
- 'error' => false
132
- ), $upload_dir );
133
- }
134
-
135
- /**
136
- * Adjust the cover image to fit with advised width & height.
137
- *
138
- * @since 2.4.0
139
- *
140
- * @param string $file The absolute path to the file.
141
- * @param array $dimensions Array of dimensions for the cover image.
142
- * @return mixed
143
- */
144
- public function fit( $file = '', $dimensions = array() ) {
145
- if ( empty( $dimensions['width'] ) || empty( $dimensions['height'] ) ) {
146
- return false;
147
- }
148
-
149
- // Get image size.
150
- $cover_data = parent::get_image_data( $file );
151
-
152
- // Init the edit args.
153
- $edit_args = array();
154
-
155
- // Do we need to resize the image?
156
- if ( ( isset( $cover_data['width'] ) && $cover_data['width'] > $dimensions['width'] ) ||
157
- ( isset( $cover_data['height'] ) && $cover_data['height'] > $dimensions['height'] ) ) {
158
- $edit_args = array(
159
- 'max_w' => $dimensions['width'],
160
- 'max_h' => $dimensions['height'],
161
- 'crop' => true,
162
- );
163
- }
164
-
165
- // Do we need to rotate the image?
166
- $angles = array(
167
- 3 => 180,
168
- 6 => -90,
169
- 8 => 90,
170
- );
171
-
172
- if ( isset( $cover_data['meta']['orientation'] ) && isset( $angles[ $cover_data['meta']['orientation'] ] ) ) {
173
- $edit_args['rotate'] = $angles[ $cover_data['meta']['orientation'] ];
174
- }
175
-
176
- // No need to edit the avatar, original file will be used.
177
- if ( empty( $edit_args ) ) {
178
- return false;
179
-
180
- // Add the file to the edit arguments.
181
- } else {
182
- $edit_args = array_merge( $edit_args, array( 'file' => $file, 'save' => false ) );
183
- }
184
-
185
- // Get the editor so that we can use a specific save method.
186
- $editor = parent::edit_image( 'cover_image', $edit_args );
187
-
188
- if ( is_wp_error( $editor ) ) {
189
- return $editor;
190
- } elseif ( ! is_a( $editor, 'WP_Image_Editor' ) ) {
191
- return false;
192
- }
193
-
194
- // Save the new image file.
195
- return $editor->save( $this->generate_filename( $file ) );
196
- }
197
-
198
- /**
199
- * Generate a filename for the cover image.
200
- *
201
- * @since 2.4.0
202
- *
203
- * @param string $file The absolute path to the file.
204
- * @return string $value The absolute path to the new file name.
205
- */
206
- public function generate_filename( $file = '' ) {
207
- if ( empty( $file ) || ! file_exists( $file ) ) {
208
- return false;
209
- }
210
-
211
- $info = pathinfo( $file );
212
- $ext = strtolower( $info['extension'] );
213
- $name = wp_unique_filename( $info['dirname'], uniqid() . "-bp-cover-image.$ext" );
214
-
215
- return trailingslashit( $info['dirname'] ) . $name;
216
- }
217
-
218
- /**
219
- * Build script datas for the Uploader UI.
220
- *
221
- * @since 2.4.0
222
- *
223
- * @return array The javascript localization data
224
- */
225
- public function script_data() {
226
- // Get default script data.
227
- $script_data = parent::script_data();
228
-
229
- if ( bp_is_user() ) {
230
- $item_id = bp_displayed_user_id();
231
-
232
- $script_data['bp_params'] = array(
233
- 'object' => 'user',
234
- 'item_id' => $item_id,
235
- 'has_cover_image' => bp_attachments_get_user_has_cover_image( $item_id ),
236
- 'nonces' => array(
237
- 'remove' => wp_create_nonce( 'bp_delete_cover_image' ),
238
- ),
239
- );
240
-
241
- // Set feedback messages.
242
- $script_data['feedback_messages'] = array(
243
- 1 => __( 'Your new cover image was uploaded successfully.', 'buddypress' ),
244
- 2 => __( 'There was a problem deleting your cover image. Please try again.', 'buddypress' ),
245
- 3 => __( 'Your cover image was deleted successfully!', 'buddypress' ),
246
- );
247
- } elseif ( bp_is_group() ) {
248
- $item_id = bp_get_current_group_id();
249
-
250
- $script_data['bp_params'] = array(
251
- 'object' => 'group',
252
- 'item_id' => bp_get_current_group_id(),
253
- 'has_cover_image' => bp_attachments_get_group_has_cover_image( $item_id ),
254
- 'nonces' => array(
255
- 'remove' => wp_create_nonce( 'bp_delete_cover_image' ),
256
- ),
257
- );
258
-
259
- // Set feedback messages.
260
- $script_data['feedback_messages'] = array(
261
- 1 => __( 'The group cover image was uploaded successfully.', 'buddypress' ),
262
- 2 => __( 'There was a problem deleting the group cover image. Please try again.', 'buddypress' ),
263
- 3 => __( 'The group cover image was deleted successfully!', 'buddypress' ),
264
- );
265
- } else {
266
-
267
- /**
268
- * Filters the cover image params to include specific BuddyPress params for your object.
269
- * e.g. Cover image for blogs single item.
270
- *
271
- * @since 2.4.0
272
- *
273
- * @param array $value The cover image specific BuddyPress parameters.
274
- */
275
- $script_data['bp_params'] = apply_filters( 'bp_attachment_cover_image_params', array() );
276
- }
277
-
278
- // Include our specific js & css.
279
- $script_data['extra_js'] = array( 'bp-cover-image' );
280
- $script_data['extra_css'] = array( 'bp-avatar' );
281
-
282
- /**
283
- * Filters the cover image script data.
284
- *
285
- * @since 2.4.0
286
- *
287
- * @param array $script_data Array of data for the cover image.
288
- */
289
- return apply_filters( 'bp_attachments_cover_image_script_data', $script_data );
290
- }
291
- }
1
+ <?php
2
+ /**
3
+ * Core Cover Image attachment class.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage Core
7
+ * @since 2.4.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ defined( 'ABSPATH' ) || exit;
12
+
13
+ /**
14
+ * BP Attachment Cover Image class.
15
+ *
16
+ * Extends BP Attachment to manage the cover images uploads.
17
+ *
18
+ * @since 2.4.0
19
+ */
20
+ class BP_Attachment_Cover_Image extends BP_Attachment {
21
+ /**
22
+ * The constuctor.
23
+ *
24
+ * @since 2.4.0
25
+ */
26
+ public function __construct() {
27
+ // Allowed cover image types & upload size.
28
+ $allowed_types = bp_attachments_get_allowed_types( 'cover_image' );
29
+ $max_upload_file_size = bp_attachments_get_max_upload_file_size( 'cover_image' );
30
+
31
+ parent::__construct( array(
32
+ 'action' => 'bp_cover_image_upload',
33
+ 'file_input' => 'file',
34
+ 'original_max_filesize' => $max_upload_file_size,
35
+ 'base_dir' => bp_attachments_uploads_dir_get( 'dir' ),
36
+ 'required_wp_files' => array( 'file', 'image' ),
37
+
38
+ // Specific errors for cover images.
39
+ 'upload_error_strings' => array(
40
+ 11 => sprintf( __( 'That image is too big. Please upload one smaller than %s', 'buddypress' ), size_format( $max_upload_file_size ) ),
41
+ 12 => sprintf( _n( 'Please upload only this file type: %s.', 'Please upload only these file types: %s.', count( $allowed_types ), 'buddypress' ), self::get_cover_image_types( $allowed_types ) ),
42
+ ),
43
+ ) );
44
+ }
45
+
46
+ /**
47
+ * Gets the available cover image types.
48
+ *
49
+ * @since 2.4.0
50
+ *
51
+ * @param array $allowed_types Array of allowed cover image types.
52
+ * @return string $value Comma-separated list of allowed cover image types.
53
+ */
54
+ public static function get_cover_image_types( $allowed_types = array() ) {
55
+ $types = array_map( 'strtoupper', $allowed_types );
56
+ $comma = _x( ',', 'cover image types separator', 'buddypress' );
57
+ return join( $comma . ' ', $types );
58
+ }
59
+
60
+ /**
61
+ * Cover image specific rules.
62
+ *
63
+ * Adds an error if the cover image size or type don't match BuddyPress needs.
64
+ * The error code is the index of $upload_error_strings.
65
+ *
66
+ * @since 2.4.0
67
+ *
68
+ * @param array $file The temporary file attributes (before it has been moved).
69
+ * @return array $file The file with extra errors if needed.
70
+ */
71
+ public function validate_upload( $file = array() ) {
72
+ // Bail if already an error.
73
+ if ( ! empty( $file['error'] ) ) {
74
+ return $file;
75
+ }
76
+
77
+ // File size is too big.
78
+ if ( $file['size'] > $this->original_max_filesize ) {
79
+ $file['error'] = 11;
80
+
81
+ // File is of invalid type.
82
+ } elseif ( ! bp_attachments_check_filetype( $file['tmp_name'], $file['name'], bp_attachments_get_allowed_mimes( 'cover_image' ) ) ) {
83
+ $file['error'] = 12;
84
+ }
85
+
86
+ // Return with error code attached.
87
+ return $file;
88
+ }
89
+
90
+ /**
91
+ * Set the directory when uploading a file.
92
+ *
93
+ * @since 2.4.0
94
+ *
95
+ * @param array $upload_dir The original Uploads dir.
96
+ * @return array $value Upload data (path, url, basedir...).
97
+ */
98
+ public function upload_dir_filter( $upload_dir = array() ) {
99
+ // Default values are for profiles.
100
+ $object_id = bp_displayed_user_id();
101
+
102
+ if ( empty( $object_id ) ) {
103
+ $object_id = bp_loggedin_user_id();
104
+ }
105
+
106
+ $object_directory = 'members';
107
+
108
+ // We're in a group, edit default values.
109
+ if ( bp_is_group() || bp_is_group_create() ) {
110
+ $object_id = bp_get_current_group_id();
111
+ $object_directory = 'groups';
112
+ }
113
+
114
+ // Set the subdir.
115
+ $subdir = '/' . $object_directory . '/' . $object_id . '/cover-image';
116
+
117
+ /**
118
+ * Filters the cover image upload directory.
119
+ *
120
+ * @since 2.4.0
121
+ *
122
+ * @param array $value Array containing the path, URL, and other helpful settings.
123
+ * @param array $upload_dir The original Uploads dir.
124
+ */
125
+ return apply_filters( 'bp_attachments_cover_image_upload_dir', array(
126
+ 'path' => $this->upload_path . $subdir,
127
+ 'url' => $this->url . $subdir,
128
+ 'subdir' => $subdir,
129
+ 'basedir' => $this->upload_path,
130
+ 'baseurl' => $this->url,
131
+ 'error' => false
132
+ ), $upload_dir );
133
+ }
134
+
135
+ /**
136
+ * Adjust the cover image to fit with advised width & height.
137
+ *
138
+ * @since 2.4.0
139
+ *
140
+ * @param string $file The absolute path to the file.
141
+ * @param array $dimensions Array of dimensions for the cover image.
142
+ * @return mixed
143
+ */
144
+ public function fit( $file = '', $dimensions = array() ) {
145
+ if ( empty( $dimensions['width'] ) || empty( $dimensions['height'] ) ) {
146
+ return false;
147
+ }
148
+
149
+ // Get image size.
150
+ $cover_data = parent::get_image_data( $file );
151
+
152
+ // Init the edit args.
153
+ $edit_args = array();
154
+
155
+ // Do we need to resize the image?
156
+ if ( ( isset( $cover_data['width'] ) && $cover_data['width'] > $dimensions['width'] ) ||
157
+ ( isset( $cover_data['height'] ) && $cover_data['height'] > $dimensions['height'] ) ) {
158
+ $edit_args = array(
159
+ 'max_w' => $dimensions['width'],
160
+ 'max_h' => $dimensions['height'],
161
+ 'crop' => true,
162
+ );
163
+ }
164
+
165
+ // Do we need to rotate the image?
166
+ $angles = array(
167
+ 3 => 180,
168
+ 6 => -90,
169
+ 8 => 90,
170
+ );
171
+
172
+ if ( isset( $cover_data['meta']['orientation'] ) && isset( $angles[ $cover_data['meta']['orientation'] ] ) ) {
173
+ $edit_args['rotate'] = $angles[ $cover_data['meta']['orientation'] ];
174
+ }
175
+
176
+ // No need to edit the avatar, original file will be used.
177
+ if ( empty( $edit_args ) ) {
178
+ return false;
179
+
180
+ // Add the file to the edit arguments.
181
+ } else {
182
+ $edit_args = array_merge( $edit_args, array( 'file' => $file, 'save' => false ) );
183
+ }
184
+
185
+ // Get the editor so that we can use a specific save method.
186
+ $editor = parent::edit_image( 'cover_image', $edit_args );
187
+
188
+ if ( is_wp_error( $editor ) ) {
189
+ return $editor;
190
+ } elseif ( ! is_a( $editor, 'WP_Image_Editor' ) ) {
191
+ return false;
192
+ }
193
+
194
+ // Save the new image file.
195
+ return $editor->save( $this->generate_filename( $file ) );
196
+ }
197
+
198
+ /**
199
+ * Generate a filename for the cover image.
200
+ *
201
+ * @since 2.4.0
202
+ *
203
+ * @param string $file The absolute path to the file.
204
+ * @return string $value The absolute path to the new file name.
205
+ */
206
+ public function generate_filename( $file = '' ) {
207
+ if ( empty( $file ) || ! file_exists( $file ) ) {
208
+ return false;
209
+ }
210
+
211
+ $info = pathinfo( $file );
212
+ $ext = strtolower( $info['extension'] );
213
+ $name = wp_unique_filename( $info['dirname'], uniqid() . "-bp-cover-image.$ext" );
214
+
215
+ return trailingslashit( $info['dirname'] ) . $name;
216
+ }
217
+
218
+ /**
219
+ * Build script datas for the Uploader UI.
220
+ *
221
+ * @since 2.4.0
222
+ *
223
+ * @return array The javascript localization data
224
+ */
225
+ public function script_data() {
226
+ // Get default script data.
227
+ $script_data = parent::script_data();
228
+
229
+ if ( bp_is_user() ) {
230
+ $item_id = bp_displayed_user_id();
231
+
232
+ $script_data['bp_params'] = array(
233
+ 'object' => 'user',
234
+ 'item_id' => $item_id,
235
+ 'has_cover_image' => bp_attachments_get_user_has_cover_image( $item_id ),
236
+ 'nonces' => array(
237
+ 'remove' => wp_create_nonce( 'bp_delete_cover_image' ),
238
+ ),
239
+ );
240
+
241
+ // Set feedback messages.
242
+ $script_data['feedback_messages'] = array(
243
+ 1 => __( 'Your new cover image was uploaded successfully.', 'buddypress' ),
244
+ 2 => __( 'There was a problem deleting your cover image. Please try again.', 'buddypress' ),
245
+ 3 => __( 'Your cover image was deleted successfully!', 'buddypress' ),
246
+ );
247
+ } elseif ( bp_is_group() ) {
248
+ $item_id = bp_get_current_group_id();
249
+
250
+ $script_data['bp_params'] = array(
251
+ 'object' => 'group',
252
+ 'item_id' => bp_get_current_group_id(),
253
+ 'has_cover_image' => bp_attachments_get_group_has_cover_image( $item_id ),
254
+ 'nonces' => array(
255
+ 'remove' => wp_create_nonce( 'bp_delete_cover_image' ),
256
+ ),
257
+ );
258
+
259
+ // Set feedback messages.
260
+ $script_data['feedback_messages'] = array(
261
+ 1 => __( 'The group cover image was uploaded successfully.', 'buddypress' ),
262
+ 2 => __( 'There was a problem deleting the group cover image. Please try again.', 'buddypress' ),
263
+ 3 => __( 'The group cover image was deleted successfully!', 'buddypress' ),
264
+ );
265
+ } else {
266
+
267
+ /**
268
+ * Filters the cover image params to include specific BuddyPress params for your object.
269
+ * e.g. Cover image for blogs single item.
270
+ *
271
+ * @since 2.4.0
272
+ *
273
+ * @param array $value The cover image specific BuddyPress parameters.
274
+ */
275
+ $script_data['bp_params'] = apply_filters( 'bp_attachment_cover_image_params', array() );
276
+ }
277
+
278
+ // Include our specific js & css.
279
+ $script_data['extra_js'] = array( 'bp-cover-image' );
280
+ $script_data['extra_css'] = array( 'bp-avatar' );
281
+
282
+ /**
283
+ * Filters the cover image script data.
284
+ *
285
+ * @since 2.4.0
286
+ *
287
+ * @param array $script_data Array of data for the cover image.
288
+ */
289
+ return apply_filters( 'bp_attachments_cover_image_script_data', $script_data );
290
+ }
291
+ }
bp-core/classes/class-bp-attachment.php CHANGED
@@ -50,11 +50,6 @@ abstract class BP_Attachment {
50
  *
51
  * @since 2.3.0
52
  * @since 2.4.0 Add the $upload_dir_filter_args argument to the $arguments array
53
- * @uses sanitize_key()
54
- * @uses wp_max_upload_size()
55
- * @uses bp_parse_args()
56
- * @uses BP_Attachment->set_upload_error_strings()
57
- * @uses BP_Attachment->set_upload_dir()
58
  *
59
  * @param array|string $args {
60
  * @type int $original_max_filesize Maximum file size in kilobytes. Defaults to php.ini settings.
@@ -115,7 +110,6 @@ abstract class BP_Attachment {
115
  *
116
  * @since 2.3.0
117
  *
118
- * @uses bp_upload_dir()
119
  */
120
  public function set_upload_dir() {
121
  // Set the directory, path, & url variables.
@@ -203,21 +197,17 @@ abstract class BP_Attachment {
203
  *
204
  * @since 2.3.0
205
  *
206
- * @uses wp_handle_upload() To upload the file
207
- * @uses add_filter() To temporarly overrides WordPress uploads data
208
- * @uses remove_filter() To stop overriding WordPress uploads data
209
- * @uses apply_filters() Call 'bp_attachment_upload_overrides' to include specific upload overrides
210
- *
211
- * @param array $file The appropriate entry the from $_FILES superglobal.
212
- * @param string $upload_dir_filter A specific filter to be applied to 'upload_dir' (optional).
213
- * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null.
214
  * @return array On success, returns an associative array of file attributes.
215
  * On failure, returns an array containing the error message
216
  * (eg: array( 'error' => $message ) )
217
  */
218
  public function upload( $file, $upload_dir_filter = '', $time = null ) {
219
  /**
220
- * Upload action and the file input name are required parameters
 
221
  * @see BP_Attachment:__construct()
222
  */
223
  if ( empty( $this->action ) || empty( $this->file_input ) ) {
@@ -283,11 +273,11 @@ abstract class BP_Attachment {
283
 
284
  // Restore WordPress Uploads data.
285
  if ( ! empty( $upload_dir_filter ) ) {
286
- remove_filter( 'upload_dir', $upload_dir_filter, 10, $this->upload_dir_filter_args );
287
  }
288
 
289
  // Remove the pre WordPress 4.0 static filter.
290
- remove_filter( 'wp_handle_upload_prefilter', array( $this, 'validate_upload' ), 10, 1 );
291
 
292
  // Finally return the uploaded file or the error.
293
  return $this->attachment;
@@ -303,7 +293,6 @@ abstract class BP_Attachment {
303
  *
304
  * @since 2.3.0
305
  *
306
- * @uses get_allowed_mime_types()
307
  */
308
  protected function validate_mime_types() {
309
  $wp_mimes = get_allowed_mime_types();
@@ -331,7 +320,7 @@ abstract class BP_Attachment {
331
  *
332
  * @since 2.3.0
333
  *
334
- * @param array $file The temporary file attributes (before it has been moved).
335
  * @return array The file.
336
  */
337
  public function validate_upload( $file = array() ) {
@@ -354,10 +343,9 @@ abstract class BP_Attachment {
354
  * @since 2.3.0
355
  * @since 2.4.0 Add the $upload_dir parameter to the method
356
  *
357
- * @uses apply_filters() call 'bp_attachment_upload_dir' to eventually override the upload location
358
  * regarding to context
359
  *
360
- * @param array $upload_dir The original Uploads dir.
361
  * @return array The upload directory data.
362
  */
363
  public function upload_dir_filter( $upload_dir = array() ) {
@@ -389,7 +377,6 @@ abstract class BP_Attachment {
389
  *
390
  * @since 2.3.0
391
  *
392
- * @uses wp_mkdir_p()
393
  */
394
  public function create_dir() {
395
  // Bail if no specific base dir is set.
@@ -426,7 +413,6 @@ abstract class BP_Attachment {
426
  * @type int $src_abs Optional. If the source crop points are absolute.
427
  * @type string $dst_file Optional. The destination file to write to.
428
  * }
429
- * @uses wp_crop_image()
430
  *
431
  * @return string|WP_Error New filepath on success, WP_Error on failure.
432
  */
@@ -536,9 +522,9 @@ abstract class BP_Attachment {
536
  /**
537
  * Get full data for an image
538
  *
539
- * @since 2.4.0
540
  *
541
- * @param string $file Absolute path to the uploaded image.
542
  * @return bool|array An associate array containing the width, height and metadatas.
543
  * False in case an important image attribute is missing.
544
  */
@@ -588,9 +574,9 @@ abstract class BP_Attachment {
588
  /**
589
  * Filter here to add/remove/edit data to the image full data
590
  *
591
- * @since 2.4.0
592
  *
593
- * @param array $image_data An associate array containing the width, height and metadatas.
594
  */
595
  return apply_filters( 'bp_attachments_get_image_data', $image_data );
596
  }
@@ -598,7 +584,7 @@ abstract class BP_Attachment {
598
  /**
599
  * Edit an image file to resize it or rotate it
600
  *
601
- * @since 2.4.0
602
  *
603
  * @param string $attachment_type The attachment type (eg: avatar or cover_image). Required.
604
  * @param array $args {
50
  *
51
  * @since 2.3.0
52
  * @since 2.4.0 Add the $upload_dir_filter_args argument to the $arguments array
 
 
 
 
 
53
  *
54
  * @param array|string $args {
55
  * @type int $original_max_filesize Maximum file size in kilobytes. Defaults to php.ini settings.
110
  *
111
  * @since 2.3.0
112
  *
 
113
  */
114
  public function set_upload_dir() {
115
  // Set the directory, path, & url variables.
197
  *
198
  * @since 2.3.0
199
  *
200
+ * @param array $file The appropriate entry the from $_FILES superglobal.
201
+ * @param string $upload_dir_filter A specific filter to be applied to 'upload_dir' (optional).
202
+ * @param string|null $time Optional. Time formatted in 'yyyy/mm'. Default null.
 
 
 
 
 
203
  * @return array On success, returns an associative array of file attributes.
204
  * On failure, returns an array containing the error message
205
  * (eg: array( 'error' => $message ) )
206
  */
207
  public function upload( $file, $upload_dir_filter = '', $time = null ) {
208
  /**
209
+ * Upload action and the file input name are required parameters.
210
+ *
211
  * @see BP_Attachment:__construct()
212
  */
213
  if ( empty( $this->action ) || empty( $this->file_input ) ) {
273
 
274
  // Restore WordPress Uploads data.
275
  if ( ! empty( $upload_dir_filter ) ) {
276
+ remove_filter( 'upload_dir', $upload_dir_filter, 10 );
277
  }
278
 
279
  // Remove the pre WordPress 4.0 static filter.
280
+ remove_filter( 'wp_handle_upload_prefilter', array( $this, 'validate_upload' ), 10 );
281
 
282
  // Finally return the uploaded file or the error.
283
  return $this->attachment;
293
  *
294
  * @since 2.3.0
295
  *
 
296
  */
297
  protected function validate_mime_types() {
298
  $wp_mimes = get_allowed_mime_types();
320
  *
321
  * @since 2.3.0
322
  *
323
+ * @param array $file The temporary file attributes (before it has been moved).
324
  * @return array The file.
325
  */
326
  public function validate_upload( $file = array() ) {
343
  * @since 2.3.0
344
  * @since 2.4.0 Add the $upload_dir parameter to the method
345
  *
 
346
  * regarding to context
347
  *
348
+ * @param array $upload_dir The original Uploads dir.
349
  * @return array The upload directory data.
350
  */
351
  public function upload_dir_filter( $upload_dir = array() ) {
377
  *
378
  * @since 2.3.0
379
  *
 
380
  */
381
  public function create_dir() {
382
  // Bail if no specific base dir is set.
413
  * @type int $src_abs Optional. If the source crop points are absolute.
414
  * @type string $dst_file Optional. The destination file to write to.
415
  * }
 
416
  *
417
  * @return string|WP_Error New filepath on success, WP_Error on failure.
418
  */
522
  /**
523
  * Get full data for an image
524
  *
525
+ * @since 2.4.0
526
  *
527
+ * @param string $file Absolute path to the uploaded image.
528
  * @return bool|array An associate array containing the width, height and metadatas.
529
  * False in case an important image attribute is missing.
530
  */
574
  /**
575
  * Filter here to add/remove/edit data to the image full data
576
  *
577
+ * @since 2.4.0
578
  *
579
+ * @param array $image_data An associate array containing the width, height and metadatas.
580
  */
581
  return apply_filters( 'bp_attachments_get_image_data', $image_data );
582
  }
584
  /**
585
  * Edit an image file to resize it or rotate it
586
  *
587
+ * @since 2.4.0
588
  *
589
  * @param string $attachment_type The attachment type (eg: avatar or cover_image). Required.
590
  * @param array $args {
bp-core/classes/class-bp-button.php CHANGED
@@ -14,35 +14,35 @@ defined( 'ABSPATH' ) || exit;
14
  * API to create BuddyPress buttons.
15
  *
16
  * @since 1.2.6
 
 
 
 
17
  *
18
  * @param array $args {
19
  * Array of arguments.
20
  *
21
  * @type string $id String describing the button type.
22
- * @type string $component The name of the component the button belongs to.
23
- * Default: 'core'.
24
- * @type bool $must_be_logged_in Optional. Does the user need to be logged
25
- * in to see this button? Default: true.
26
- * @type bool $block_self Optional. True if the button should be hidden
27
- * when a user is viewing his own profile.
28
- * Default: true.
29
- * @type string|bool $wrapper Optional. HTML element type that should wrap
30
- * the button: 'div', 'span', 'p', or 'li'.
31
- * False for no wrapper at all. Default: 'div'.
32
- * @type string $wrapper_id Optional. DOM ID of the button wrapper element.
33
- * Default: ''.
34
- * @type string $wrapper_class Optional. DOM class of the button wrapper
35
- * element. Default: ''.
36
- * @type string $link_href Optional. Destination link of the button.
37
- * Default: ''.
38
- * @type string $link_class Optional. DOM class of the button. Default: ''.
39
- * @type string $link_id Optional. DOM ID of the button. Default: ''.
40
- * @type string $link_rel Optional. DOM 'rel' attribute of the button.
41
- * Default: ''.
42
- * @type string $link_title Optional. Title attribute of the button.
43
- * Default: ''.
44
- * @type string $link_text Optional. Text to appear on the button.
45
- * Default: ''.
46
  * }
47
  */
48
  class BP_Button {
@@ -52,6 +52,8 @@ class BP_Button {
52
  /**
53
  * The button ID.
54
  *
 
 
55
  * @var string
56
  */
57
  public $id = '';
@@ -59,6 +61,8 @@ class BP_Button {
59
  /**
60
  * The name of the component that the button belongs to.
61
  *
 
 
62
  * @var string
63
  */
64
  public $component = 'core';
@@ -66,6 +70,8 @@ class BP_Button {
66
  /**
67
  * Does the user need to be logged in to see this button?
68
  *
 
 
69
  * @var bool
70
  */
71
  public $must_be_logged_in = true;
@@ -73,22 +79,88 @@ class BP_Button {
73
  /**
74
  * Whether the button should be hidden when viewing your own profile.
75
  *
 
 
76
  * @var bool
77
  */
78
  public $block_self = true;
79
 
80
  /** Wrapper ***************************************************************/
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  /**
83
  * The type of DOM element to use for a wrapper.
84
  *
85
- * @var string|bool 'div', 'span', 'p', 'li', or false for no wrapper.
 
 
 
86
  */
87
  public $wrapper = 'div';
88
 
89
  /**
90
  * The DOM class of the button wrapper.
91
  *
 
 
 
92
  * @var string
93
  */
94
  public $wrapper_class = '';
@@ -96,15 +168,19 @@ class BP_Button {
96
  /**
97
  * The DOM ID of the button wrapper.
98
  *
 
 
 
99
  * @var string
100
  */
101
  public $wrapper_id = '';
102
 
103
- /** Button ****************************************************************/
104
-
105
  /**
106
  * The destination link of the button.
107
  *
 
 
 
108
  * @var string
109
  */
110
  public $link_href = '';
@@ -112,6 +188,9 @@ class BP_Button {
112
  /**
113
  * The DOM class of the button link.
114
  *
 
 
 
115
  * @var string
116
  */
117
  public $link_class = '';
@@ -119,6 +198,9 @@ class BP_Button {
119
  /**
120
  * The DOM ID of the button link.
121
  *
 
 
 
122
  * @var string
123
  */
124
  public $link_id = '';
@@ -126,6 +208,9 @@ class BP_Button {
126
  /**
127
  * The DOM rel value of the button link.
128
  *
 
 
 
129
  * @var string
130
  */
131
  public $link_rel = '';
@@ -133,22 +218,12 @@ class BP_Button {
133
  /**
134
  * Title of the button link.
135
  *
136
- * @var string
137
- */
138
- public $link_title = '';
139
-
140
- /**
141
- * The contents of the button link.
142
  *
143
  * @var string
144
  */
145
- public $link_text = '';
146
-
147
- /** HTML result
148
- *
149
- * @var string
150
- */
151
- public $contents = '';
152
 
153
  /** Methods ***************************************************************/
154
 
@@ -163,76 +238,95 @@ class BP_Button {
163
 
164
  $r = wp_parse_args( $args, get_class_vars( __CLASS__ ) );
165
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  // Required button properties.
167
  $this->id = $r['id'];
168
  $this->component = $r['component'];
169
  $this->must_be_logged_in = (bool) $r['must_be_logged_in'];
170
  $this->block_self = (bool) $r['block_self'];
171
- $this->wrapper = $r['wrapper'];
172
 
173
- // $id and $component are required
174
- if ( empty( $r['id'] ) || empty( $r['component'] ) )
175
- return false;
176
-
177
- // No button if component is not active.
178
- if ( ! bp_is_active( $this->component ) )
179
  return false;
 
180
 
181
  // No button for guests if must be logged in.
182
- if ( true == $this->must_be_logged_in && ! is_user_logged_in() )
183
  return false;
 
184
 
185
  // The block_self property.
186
  if ( true == $this->block_self ) {
187
- // No button if you are the current user in a members loop
188
- // This condition takes precedence, because members loops
189
- // can be found on user profiles.
 
 
 
190
  if ( bp_get_member_user_id() ) {
191
  if ( is_user_logged_in() && bp_loggedin_user_id() == bp_get_member_user_id() ) {
192
  return false;
193
  }
194
 
195
- // No button if viewing your own profile (and not in
196
- // a members loop).
197
  } elseif ( bp_is_my_profile() ) {
198
  return false;
199
  }
200
  }
201
 
202
- // Wrapper properties.
203
- if ( false !== $this->wrapper ) {
204
-
205
- // Wrapper ID.
206
- if ( !empty( $r['wrapper_id'] ) ) {
207
- $this->wrapper_id = ' id="' . $r['wrapper_id'] . '"';
208
  }
209
 
210
- // Wrapper class.
211
- if ( !empty( $r['wrapper_class'] ) ) {
212
- $this->wrapper_class = ' class="generic-button ' . $r['wrapper_class'] . '"';
213
- } else {
214
- $this->wrapper_class = ' class="generic-button"';
 
215
  }
216
 
 
 
 
 
 
 
217
  // Set before and after.
218
- $before = '<' . $r['wrapper'] . $this->wrapper_class . $this->wrapper_id . '>';
219
- $after = '</' . $r['wrapper'] . '>';
220
 
221
- // No wrapper.
222
  } else {
223
  $before = $after = '';
224
  }
225
 
226
- // Link properties.
227
- if ( !empty( $r['link_id'] ) ) $this->link_id = ' id="' . $r['link_id'] . '"';
228
- if ( !empty( $r['link_href'] ) ) $this->link_href = ' href="' . $r['link_href'] . '"';
229
- if ( !empty( $r['link_title'] ) ) $this->link_title = ' title="' . $r['link_title'] . '"';
230
- if ( !empty( $r['link_rel'] ) ) $this->link_rel = ' rel="' . $r['link_rel'] . '"';
231
- if ( !empty( $r['link_class'] ) ) $this->link_class = ' class="' . $r['link_class'] . '"';
232
- if ( !empty( $r['link_text'] ) ) $this->link_text = $r['link_text'];
 
 
 
233
 
234
  // Build the button.
235
- $this->contents = $before . '<a'. $this->link_href . $this->link_title . $this->link_id . $this->link_rel . $this->link_class . '>' . $this->link_text . '</a>' . $after;
236
 
237
  /**
238
  * Filters the button based on class parameters.
@@ -241,15 +335,76 @@ class BP_Button {
241
  * allows button to be manipulated externally.
242
  *
243
  * @since 1.2.6
 
244
  *
245
  * @param string $contents HTML being used for the button.
246
  * @param BP_Button $this Current BP_Button instance.
247
  * @param string $before HTML appended before the actual button.
248
  * @param string $after HTML appended after the actual button.
 
249
  */
250
- $this->contents = apply_filters( 'bp_button_' . $this->component . '_' . $this->id, $this->contents, $this, $before, $after );
251
  }
252
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  /**
254
  * Return the markup for the generated button.
255
  *
14
  * API to create BuddyPress buttons.
15
  *
16
  * @since 1.2.6
17
+ * @since 2.7.0 Introduced $parent_element, $parent_attr, $button_element, $button_attr as
18
+ * $args parameters.
19
+ * Deprecated $wrapper, $wrapper_id, $wrapper_class, $link_href, $link_class,
20
+ * $link_id, $link_rel, $link_title as $args params.
21
  *
22
  * @param array $args {
23
  * Array of arguments.
24
  *
25
  * @type string $id String describing the button type.
26
+ * @type string $component The name of the component the button belongs to. Default: 'core'.
27
+ * @type bool $must_be_logged_in Optional. Does the user need to be logged in to see this button? Default:
28
+ * true.
29
+ * @type bool $block_self Optional. True if the button should be hidden when a user is viewing his
30
+ * own profile. Default: true.
31
+ * @type string $parent_element Optional. Parent element to wrap button around. Default: 'div'.
32
+ * @type array $parent_attr Optional. Element attributes for parent element. Set whatever attributes
33
+ * like 'id', 'class' as array keys.
34
+ * @type string $button_element Optional. Button element. Default: 'a'.
35
+ * @type array $button_attr Optional. Button attributes. Set whatever attributes like 'id', 'class' as
36
+ * array keys.
37
+ * @type string $link_text Optional. Text to appear on the button. Default: ''.
38
+ * @type string|bool $wrapper Deprecated. Use $parent_element instead.
39
+ * @type string $wrapper_id Deprecated. Use $parent_attr and set 'id' as array key.
40
+ * @type string $wrapper_class Deprecated. Use $parent_attr and set 'class' as array key.
41
+ * @type string $link_href Deprecated. Use $button_attr and set 'href' as array key.
42
+ * @type string $link_class Deprecated. Use $button_attr and set 'class' as array key.
43
+ * @type string $link_id Deprecated. Use $button_attr and set 'id' as array key.
44
+ * @type string $link_rel Deprecated. Use $button_attr and set 'rel' as array key.
45
+ * @type string $link_title Deprecated. Use $button_attr and set 'title' as array key.
 
 
 
 
46
  * }
47
  */
48
  class BP_Button {
52
  /**
53
  * The button ID.
54
  *
55
+ * @since 1.2.6
56
+ *
57
  * @var string
58
  */
59
  public $id = '';
61
  /**
62
  * The name of the component that the button belongs to.
63
  *
64
+ * @since 1.2.6
65
+ *
66
  * @var string
67
  */
68
  public $component = 'core';
70
  /**
71
  * Does the user need to be logged in to see this button?
72
  *
73
+ * @since 1.2.6
74
+ *
75
  * @var bool
76
  */
77
  public $must_be_logged_in = true;
79
  /**
80
  * Whether the button should be hidden when viewing your own profile.
81
  *
82
+ * @since 1.2.6
83
+ *
84
  * @var bool
85
  */
86
  public $block_self = true;
87
 
88
  /** Wrapper ***************************************************************/
89
 
90
+ /**
91
+ * Parent element to wrap button around.
92
+ *
93
+ * @since 2.7.0
94
+ *
95
+ * @var string Default: 'div'.
96
+ */
97
+ public $parent_element = '';
98
+
99
+ /**
100
+ * Element attributes for parent element.
101
+ *
102
+ * @since 2.7.0
103
+ *
104
+ * @var array Set whatever attributes like 'id', 'class' as array key.
105
+ */
106
+ public $parent_attr = array();
107
+
108
+ /** Button ****************************************************************/
109
+
110
+ /**
111
+ * Button element.
112
+ *
113
+ * @since 2.7.0
114
+ *
115
+ * @var string Default: 'a'.
116
+ */
117
+ public $button_element = 'a';
118
+
119
+ /**
120
+ * Button attributes.
121
+ *
122
+ * @since 2.7.0
123
+ *
124
+ * @var array Set whatever attributes like 'id', 'href' as array key.
125
+ */
126
+ public $button_attr = array();
127
+
128
+ /**
129
+ * The contents of the button link.
130
+ *
131
+ * @since 1.2.6
132
+ *
133
+ * @var string
134
+ */
135
+ public $link_text = '';
136
+
137
+ /**
138
+ * HTML result.
139
+ *
140
+ * @since 1.2.6
141
+ *
142
+ * @var string
143
+ */
144
+ public $contents = '';
145
+
146
+ /** Deprecated ***********************************************************/
147
+
148
  /**
149
  * The type of DOM element to use for a wrapper.
150
  *
151
+ * @since 1.2.6
152
+ * @deprecated 2.7.0 Use $parent_element instead.
153
+ *
154
+ * @var string|bool
155
  */
156
  public $wrapper = 'div';
157
 
158
  /**
159
  * The DOM class of the button wrapper.
160
  *
161
+ * @since 1.2.6
162
+ * @deprecated 2.7.0 Set 'class' key in $parent_attr instead.
163
+ *
164
  * @var string
165
  */
166
  public $wrapper_class = '';
168
  /**
169
  * The DOM ID of the button wrapper.
170
  *
171
+ * @since 1.2.6
172
+ * @deprecated 2.7.0 Set 'id' key in $parent_attr instead.
173
+ *
174
  * @var string
175
  */
176
  public $wrapper_id = '';
177
 
 
 
178
  /**
179
  * The destination link of the button.
180
  *
181
+ * @since 1.2.6
182
+ * @deprecated 2.7.0 Set 'href' key in $button_attr instead.
183
+ *
184
  * @var string
185
  */
186
  public $link_href = '';
188
  /**
189
  * The DOM class of the button link.
190
  *
191
+ * @since 1.2.6
192
+ * @deprecated 2.7.0 Set 'class' key in $button_attr instead.
193
+ *
194
  * @var string
195
  */
196
  public $link_class = '';
198
  /**
199
  * The DOM ID of the button link.
200
  *
201
+ * @since 1.2.6
202
+ * @deprecated 2.7.0 Set 'id' key in $button_attr instead.
203
+ *
204
  * @var string
205
  */
206
  public $link_id = '';
208
  /**
209
  * The DOM rel value of the button link.
210
  *
211
+ * @since 1.2.6
212
+ * @deprecated 2.7.0 Set 'rel' key in $button_attr instead.
213
+ *
214
  * @var string
215
  */
216
  public $link_rel = '';
218
  /**
219
  * Title of the button link.
220
  *
221
+ * @since 1.2.6
222
+ * @deprecated 2.7.0 Set 'title' key in $button_attr instead.
 
 
 
 
223
  *
224
  * @var string
225
  */
226
+ public $link_title = '';
 
 
 
 
 
 
227
 
228
  /** Methods ***************************************************************/
229
 
238
 
239
  $r = wp_parse_args( $args, get_class_vars( __CLASS__ ) );
240
 
241
+ // Backward compatibility with deprecated parameters.
242
+ $r = $this->backward_compatibility_args( $r );
243
+
244
+ // Deprecated. Subject to removal in a future release.
245
+ $this->wrapper = $r['wrapper'];
246
+ if ( !empty( $r['link_id'] ) ) $this->link_id = ' id="' . $r['link_id'] . '"';
247
+ if ( !empty( $r['link_href'] ) ) $this->link_href = ' href="' . $r['link_href'] . '"';
248
+ if ( !empty( $r['link_title'] ) ) $this->link_title = ' title="' . $r['link_title'] . '"';
249
+ if ( !empty( $r['link_rel'] ) ) $this->link_rel = ' rel="' . $r['link_rel'] . '"';
250
+ if ( !empty( $r['link_class'] ) ) $this->link_class = ' class="' . $r['link_class'] . '"';
251
+ if ( !empty( $r['link_text'] ) ) $this->link_text = $r['link_text'];
252
+
253
  // Required button properties.
254
  $this->id = $r['id'];
255
  $this->component = $r['component'];
256
  $this->must_be_logged_in = (bool) $r['must_be_logged_in'];
257
  $this->block_self = (bool) $r['block_self'];
 
258
 
259
+ // $id and $component are required and component must be active.
260
+ if ( empty( $r['id'] ) || empty( $r['component'] ) || ! bp_is_active( $this->component ) ) {
 
 
 
 
261
  return false;
262
+ }
263
 
264
  // No button for guests if must be logged in.
265
+ if ( true == $this->must_be_logged_in && ! is_user_logged_in() ) {
266
  return false;
267
+ }
268
 
269
  // The block_self property.
270
  if ( true == $this->block_self ) {
271
+ /*
272
+ * No button if you are the current user in a members loop.
273
+ *
274
+ * This condition takes precedence, because members loops can be found on user
275
+ * profiles.
276
+ */
277
  if ( bp_get_member_user_id() ) {
278
  if ( is_user_logged_in() && bp_loggedin_user_id() == bp_get_member_user_id() ) {
279
  return false;
280
  }
281
 
282
+ // No button if viewing your own profile (and not in a members loop).
 
283
  } elseif ( bp_is_my_profile() ) {
284
  return false;
285
  }
286
  }
287
 
288
+ // Should we use a parent element?
289
+ if ( ! empty( $r['parent_element'] ) ) {
290
+ if ( ! isset( $r['parent_attr']['class'] ) ) {
291
+ $r['parent_attr']['class'] = '';
 
 
292
  }
293
 
294
+ // Always add 'generic-button' class.
295
+ if ( false === strpos( $r['parent_attr']['class'], 'generic-button' ) ) {
296
+ if ( ! empty( $r['parent_attr']['class'] ) ) {
297
+ $r['parent_attr']['class'] .= ' ';
298
+ }
299
+ $r['parent_attr']['class'] .= 'generic-button';
300
  }
301
 
302
+ // Render parent element attributes.
303
+ $parent_elem = new BP_Core_HTML_Element( array(
304
+ 'element' => $r['parent_element'],
305
+ 'attr' => $r['parent_attr']
306
+ ) );
307
+
308
  // Set before and after.
309
+ $before = $parent_elem->get( 'open_tag' );
310
+ $after = $parent_elem->get( 'close_tag' );
311
 
312
+ // No parent element.
313
  } else {
314
  $before = $after = '';
315
  }
316
 
317
+ // Button properties.
318
+ $button = '';
319
+ if ( ! empty( $r['button_element'] ) ) {
320
+ $button = new BP_Core_HTML_Element( array(
321
+ 'element' => $r['button_element'],
322
+ 'attr' => $r['button_attr'],
323
+ 'inner_html' => ! empty( $r['link_text'] ) ? $r['link_text'] : ''
324
+ ) );
325
+ $button = $button->contents();
326
+ }
327
 
328
  // Build the button.
329
+ $this->contents = $before . $button . $after;
330
 
331
  /**
332
  * Filters the button based on class parameters.
335
  * allows button to be manipulated externally.
336
  *
337
  * @since 1.2.6
338
+ * @since 2.7.0 Added $r as a parameter.
339
  *
340
  * @param string $contents HTML being used for the button.
341
  * @param BP_Button $this Current BP_Button instance.
342
  * @param string $before HTML appended before the actual button.
343
  * @param string $after HTML appended after the actual button.
344
+ * @param array $r Parsed button arguments.
345
  */
346
+ $this->contents = apply_filters( 'bp_button_' . $this->component . '_' . $this->id, $this->contents, $this, $before, $after, $r );
347
  }
348
 
349
+
350
+ /**
351
+ * Provide backward compatibility for deprecated button arguments.
352
+ *
353
+ * @since 2.7.0.
354
+ *
355
+ * @param array $r See {@link BP_Button} class for full documentation.
356
+ * @return array
357
+ */
358
+ protected function backward_compatibility_args( $r = array() ) {
359
+ // Array of deprecated arguments.
360
+ $backpat_args = array(
361
+ 'wrapper', 'wrapper_class', 'wrapper_id',
362
+ 'link_href', 'link_class', 'link_id', 'link_rel', 'link_title'
363
+ );
364
+
365
+ foreach ( $backpat_args as $prop ) {
366
+ if ( empty( $r[ $prop ] ) ) {
367
+ continue;
368
+ }
369
+
370
+ $parent = $child = false;
371
+ $sep = strpos( $prop, '_' );
372
+
373
+ // Check if this is an attribute.
374
+ if ( false !== $sep ) {
375
+ $child = true;
376
+ $parent = substr( $prop, 0, $sep );
377
+ } else {
378
+ $parent = $prop;
379
+ }
380
+
381
+ if ( 'wrapper' === $parent ) {
382
+ $parent = 'parent';
383
+ } else {
384
+ $parent = 'button';
385
+ }
386
+
387
+ // Set element.
388
+ if ( false === $child && empty( $r[ "{$parent}_element" ] ) ) {
389
+ $r[ "{$parent}_element" ] = $r[ $prop ];
390
+
391
+ // Set attributes.
392
+ } elseif ( true === $child ) {
393
+ $new_prop = substr( $prop, strpos( $prop, '_' ) +1 );
394
+ if ( empty( $r[ "{$parent}_attr" ] ) ) {
395
+ $r[ "{$parent}_attr" ] = array();
396
+ }
397
+
398
+ if ( empty( $r[ "{$parent}_attr" ][ $new_prop ] ) ) {
399
+ $r[ "{$parent}_attr" ][ $new_prop ] = $r[ $prop ];
400
+ }
401
+ }
402
+ }
403
+
404
+ return $r;
405
+ }
406
+
407
+
408
  /**
409
  * Return the markup for the generated button.
410
  *
bp-core/classes/class-bp-component.php CHANGED
@@ -206,8 +206,6 @@ class BP_Component {
206
  *
207
  * @since 1.5.0
208
  *
209
- * @uses apply_filters() Calls 'bp_{@link bp_Component::name}_id'.
210
- * @uses apply_filters() Calls 'bp_{@link bp_Component::name}_slug'.
211
  *
212
  * @param array $args {
213
  * All values are optional.
@@ -350,7 +348,6 @@ class BP_Component {
350
  *
351
  * @since 1.5.0
352
  *
353
- * @uses do_action() Calls 'bp_{@link bp_Component::name}includes'.
354
  *
355
  * @param array $includes An array of file names, or file name chunks,
356
  * to be parsed and then included.
@@ -401,8 +398,6 @@ class BP_Component {
401
  *
402
  * @since 1.5.0
403
  *
404
- * @uses add_action() To add various actions.
405
- * @uses do_action() Calls 'bp_{@link BP_Component::name}setup_actions'.
406
  */
407
  public function setup_actions() {
408
 
@@ -489,12 +484,12 @@ class BP_Component {
489
 
490
  // No sub nav items without a main nav item.
491
  if ( !empty( $main_nav ) ) {
492
- bp_core_new_nav_item( $main_nav );
493
 
494
  // Sub nav items are not required.
495
  if ( !empty( $sub_nav ) ) {
496
  foreach( (array) $sub_nav as $nav ) {
497
- bp_core_new_subnav_item( $nav );
498
  }
499
  }
500
  }
@@ -598,7 +593,6 @@ class BP_Component {
598
  *
599
  * @since 1.5.0
600
  *
601
- * @uses do_action() Calls 'bp_{@link bp_Component::name}_setup_title'.
602
  */
603
  public function setup_title() {
604
 
@@ -617,7 +611,6 @@ class BP_Component {
617
  *
618
  * @since 2.2.0
619
  *
620
- * @uses do_action() Calls 'bp_setup_{@link bp_Component::name}_cache_groups'.
621
  */
622
  public function setup_cache_groups() {
623
 
@@ -723,7 +716,6 @@ class BP_Component {
723
  *
724
  * @since 1.5.0
725
  *
726
- * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_post_types'.
727
  */
728
  public function register_post_types() {
729
 
@@ -742,7 +734,6 @@ class BP_Component {
742
  *
743
  * @since 1.5.0
744
  *
745
- * @uses do_action() Calls 'bp_{@link bp_Component::name}_register_taxonomies'.
746
  */
747
  public function register_taxonomies() {
748
 
@@ -761,7 +752,6 @@ class BP_Component {
761
  *
762
  * @since 1.5.0
763
  *
764
- * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_rewrite_tags'.
765
  */
766
  public function add_rewrite_tags() {
767
 
@@ -780,7 +770,6 @@ class BP_Component {
780
  *
781
  * @since 1.9.0
782
  *
783
- * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_rewrite_rules'.
784
  */
785
  public function add_rewrite_rules() {
786
 
@@ -799,7 +788,6 @@ class BP_Component {
799
  *
800
  * @since 1.9.0
801
  *
802
- * @uses do_action() Calls 'bp_{@link bp_Component::name}_add_permastruct'.
803
  */
804
  public function add_permastructs() {
805
 
@@ -818,7 +806,6 @@ class BP_Component {
818
  *
819
  * @since 1.9.0
820
  *
821
- * @uses do_action() Calls 'bp_{@link bp_Component::name}_parse_query'.
822
  *
823
  * @param object $query The main WP_Query.
824
  */
@@ -841,7 +828,6 @@ class BP_Component {
841
  *
842
  * @since 1.5.0
843
  *
844
- * @uses do_action() Calls 'bp_{@link bp_Component::name}_generate_rewrite_rules'.
845
  */
846
  public function generate_rewrite_rules() {
847
 
206
  *
207
  * @since 1.5.0
208
  *
 
 
209
  *
210
  * @param array $args {
211
  * All values are optional.
348
  *
349
  * @since 1.5.0
350
  *
 
351
  *
352
  * @param array $includes An array of file names, or file name chunks,
353
  * to be parsed and then included.
398
  *
399
  * @since 1.5.0
400
  *
 
 
401
  */
402
  public function setup_actions() {
403
 
484
 
485
  // No sub nav items without a main nav item.
486
  if ( !empty( $main_nav ) ) {
487
+ bp_core_new_nav_item( $main_nav, 'members' );
488
 
489
  // Sub nav items are not required.
490
  if ( !empty( $sub_nav ) ) {
491
  foreach( (array) $sub_nav as $nav ) {
492
+ bp_core_new_subnav_item( $nav, 'members' );
493
  }
494
  }
495
  }
593
  *
594
  * @since 1.5.0
595
  *
 
596
  */
597
  public function setup_title() {
598
 
611
  *
612
  * @since 2.2.0
613
  *
 
614
  */
615
  public function setup_cache_groups() {
616
 
716
  *
717
  * @since 1.5.0
718
  *
 
719
  */
720
  public function register_post_types() {
721
 
734
  *
735
  * @since 1.5.0
736
  *
 
737
  */
738
  public function register_taxonomies() {
739
 
752
  *
753
  * @since 1.5.0
754
  *
 
755
  */
756
  public function add_rewrite_tags() {
757
 
770
  *
771
  * @since 1.9.0
772
  *
 
773
  */
774
  public function add_rewrite_rules() {
775
 
788
  *
789
  * @since 1.9.0
790
  *
 
791
  */
792
  public function add_permastructs() {
793
 
806
  *
807
  * @since 1.9.0
808
  *
 
809
  *
810
  * @param object $query The main WP_Query.
811
  */
828
  *
829
  * @since 1.5.0
830
  *
 
831
  */
832
  public function generate_rewrite_rules() {
833
 
bp-core/classes/class-bp-core-bp-nav-backcompat.php ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Backward compatibility for the $bp->bp_nav global.
4
+ *
5
+ * @since 2.6.0
6
+ */
7
+
8
+ // Exit if accessed directly.
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * bp_nav backward compatibility class.
13
+ *
14
+ * This class is used to provide backward compatibility for extensions that access and modify
15
+ * the $bp->bp_nav global.
16
+ *
17
+ * @since 2.6.0
18
+ */
19
+ class BP_Core_BP_Nav_BackCompat implements ArrayAccess {
20
+ /**
21
+ * Nav items.
22
+ *
23
+ * @since 2.6.0
24
+ * @access public
25
+ * @var array
26
+ */
27
+ public $backcompat_nav = array();
28
+
29
+ /**
30
+ * Component to which nav items belong.
31
+ *
32
+ * @since 2.6.0
33
+ * @access public
34
+ * @var array
35
+ */
36
+ public $component;
37
+
38
+ /**
39
+ * Constructor.
40
+ *
41
+ * @since 2.6.0
42
+ *
43
+ * @param array $backcompat_nav Optional. Array of nav items.
44
+ */
45
+ public function __construct( $backcompat_nav = array() ) {
46
+ foreach ( $backcompat_nav as $key => $value ) {
47
+ if ( is_array( $value ) ) {
48
+ $this->backcompat_nav[ $key ] = new self( $value );
49
+ } else {
50
+ $this->backcompat_nav[ $key ] = $value;
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Assign a value to the nav array at the specified offset.
57
+ *
58
+ * @since 2.6.0
59
+ *
60
+ * @param mixed $offset Array offset.
61
+ * @param array $value Nav item.
62
+ */
63
+ public function offsetSet( $offset, $value ) {
64
+ _doing_it_wrong(
65
+ 'bp_nav',
66
+ __( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ),
67
+ '2.6.0'
68
+ );
69
+
70
+ $bp = buddypress();
71
+
72
+ if ( is_array( $value ) ) {
73
+ $value = new self( $value );
74
+ }
75
+
76
+ if ( $offset !== null ) {
77
+ // Temporarily set the backcompat_nav.
78
+ $this->backcompat_nav[ $offset ] = $value;
79
+
80
+ $args = $this->to_array();
81
+ if ( isset( $args['parent_slug'] ) ) {
82
+ $this->get_component_nav( $args['parent_slug'] )->edit_nav( $args, $args['slug'], $args['parent_slug'] );
83
+ } elseif ( isset( $args['slug'] ) ) {
84
+ $bp->members->nav->edit_nav( $args, $args['slug'] );
85
+ }
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Get a value of the nav array at the specified offset.
91
+ *
92
+ * @since 2.6.0
93
+ *
94
+ * @param mixed $offset Array offset.
95
+ * @return BP_Core_BP_Nav_BackCompat
96
+ */
97
+ public function offsetGet( $offset ) {
98
+ _doing_it_wrong(
99
+ 'bp_nav',
100
+ __( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ),
101
+ '2.6.0'
102
+ );
103
+
104
+ // if ( ! isset( $this->backcompat_nav[ $offset ] ) ) {
105
+ $nav = $this->get_nav( $offset );
106
+ if ( $nav && isset( $nav[ $offset ] ) ) {
107
+ $this->backcompat_nav[ $offset ] = new self( $nav[ $offset ] );
108
+ }
109
+ // }
110
+
111
+ return $this->backcompat_nav[ $offset ];
112
+ }
113
+
114
+ /**
115
+ * Check whether nav array has a value at the specified offset.
116
+ *
117
+ * @since 2.6.0
118
+ *
119
+ * @param mixed $offset Array offset.
120
+ * @return bool
121
+ */
122
+ public function offsetExists( $offset ) {
123
+ _doing_it_wrong(
124
+ 'bp_nav',
125
+ __( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ),
126
+ '2.6.0'
127
+ );
128
+
129
+ if ( isset( $this->backcompat_nav[ $offset ] ) ) {
130
+ return true;
131
+ }
132
+
133
+ $nav = $this->get_nav( $offset );
134
+ if ( $nav && isset( $nav[ $offset ] ) ) {
135
+ return true;
136
+ }
137
+
138
+ return false;
139
+ }
140
+
141
+ /**
142
+ * Unset a nav array value at the specified offset.
143
+ *
144
+ * @since 2.6.0
145
+ *
146
+ * @param mixed $offset Array offset.
147
+ */
148
+ public function offsetUnset( $offset ) {
149
+ _doing_it_wrong(
150
+ 'bp_nav',
151
+ __( 'The bp_nav and bp_options_nav globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ),
152
+ '2.6.0'
153
+ );
154
+
155
+ // For top-level nav items, the backcompat nav hasn't yet been initialized.
156
+ if ( ! isset( $this->backcompat_nav[ $offset ] ) ) {
157
+ buddypress()->members->nav->delete_nav( $offset );
158
+ unset( $this->backcompat_nav[ $offset ] );
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Set the component to which the nav belongs.
164
+ *
165
+ * @since 2.6.0
166
+ *
167
+ * @param string $component
168
+ */
169
+ public function set_component( $component ) {
170
+ $this->component = $component;
171
+ }
172
+
173
+ /**
174
+ * Get the component to which the a nav item belongs.
175
+ *
176
+ * We use the following heuristic to guess, based on an offset, which component the item belongs to:
177
+ * - If this is a group, and the offset is the same as the current group's slug, it's a group nav item.
178
+ * - Otherwise, it's a member nav item.
179
+ *
180
+ * @since 2.6.0
181
+ *
182
+ * @param mixed $offset Array offset.
183
+ * @return string
184
+ */
185
+ public function get_component( $offset = '' ) {
186
+ if ( ! isset( $this->component ) ) {
187
+ if ( bp_is_active( 'groups' ) && $offset === bp_get_current_group_slug() ) {
188
+ $this->component = 'groups';
189
+ } else {
190
+ $this->component = 'members';
191
+ }
192
+ }
193
+
194
+ return $this->component;
195
+ }
196
+
197
+ /**
198
+ * Reset the cached nav items.
199
+ *
200
+ * Called when the nav API removes items from the nav array.
201
+ *
202
+ * @since 2.6.0
203
+ */
204
+ public function reset() {
205
+ $this->backcompat_nav = array();
206
+ }
207
+
208
+ /**
209
+ * Get the nav object corresponding to the specified offset.
210
+ *
211
+ * @since 2.6.0
212
+ *
213
+ * @param mixed $offset Array offset.
214
+ * @return bool|array
215
+ */
216
+ protected function get_nav( $offset ) {
217
+ $bp = buddypress();
218
+
219
+ $component_nav = $this->get_component_nav( $offset );
220
+ $primary_nav = $component_nav->get_primary( array( 'slug' => $offset ), false );
221
+
222
+ $nav = array();
223
+
224
+ if ( empty( $primary_nav ) ) {
225
+ return $nav;
226
+ }
227
+
228
+ foreach ( $primary_nav as $item ) {
229
+ $nav[ $item->slug ] = (array) $item;
230
+ }
231
+
232
+ return $nav;
233
+ }
234
+
235
+ /**
236
+ * Get the BP_Core_Nav object corresponding to the component, based on a nav item name.
237
+ *
238
+ * The way bp_nav was previously organized makes it impossible to know for sure which component's nav is
239
+ * being referenced by a given nav item name. We guess in the following manner:
240
+ * - If we're looking at a group, and the nav item name (`$offset`) is the same as the slug of the current
241
+ * group, we assume that the proper component nav is 'groups'.
242
+ * - Otherwise, fall back on 'members'.
243
+ *
244
+ * @since 2.6.0
245
+ *
246
+ * @param string $offset Nav item name.
247
+ * @return BP_Core_Nav
248
+ */
249
+ protected function get_component_nav( $offset = '' ) {
250
+ $component = $this->get_component( $offset );
251
+
252
+ $bp = buddypress();
253
+ if ( ! isset( $bp->{$component}->nav ) ) {
254
+ return false;
255
+ }
256
+
257
+ return $bp->{$component}->nav;
258
+ }
259
+
260
+ /**
261
+ * Get the nav data, formatted as a flat array.
262
+ *
263
+ * @since 2.6.0
264
+ *
265
+ * @return array
266
+ */
267
+ protected function to_array() {
268
+ return $this->backcompat_nav;
269
+ }
270
+ }
bp-core/classes/class-bp-core-bp-options-nav-backcompat.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Backward compatibility for the $bp->bp_options_nav global.
4
+ *
5
+ * @since 2.6.0
6
+ */
7
+
8
+ // Exit if accessed directly.
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * bp_options_nav backward compatibility class.
13
+ *
14
+ * This class is used to provide backward compatibility for extensions that access and modify
15
+ * the $bp->bp_options_nav global.
16
+ *
17
+ * @since 2.6.0
18
+ */
19
+ class BP_Core_BP_Options_Nav_BackCompat extends BP_Core_BP_Nav_BackCompat {
20
+ /**
21
+ * Parent slug of the current nav item.
22
+ *
23
+ * @since 2.6.0
24
+ * @access protected
25
+ * @var string
26
+ */
27
+ protected $parent_slug = '';
28
+
29
+ /**
30
+ * Get a value of the nav array at the specified offset.
31
+ *
32
+ * @since 2.6.0
33
+ *
34
+ * @param mixed $offset Array offset.
35
+ * @return BP_Core_BP_Nav_BackCompat
36
+ */
37
+ public function offsetGet( $offset ) {
38
+ _doing_it_wrong(
39
+ 'bp_nav',
40
+ __( 'These globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ),
41
+ '2.6.0'
42
+ );
43
+
44
+ if ( empty( $this->backcompat_nav[ $offset ] ) ) {
45
+ $nav = $this->get_nav( $offset );
46
+ if ( $nav ) {
47
+ $subnavs = $this->get_component_nav( $offset )->get_secondary( array( 'parent_slug' => $offset ) );
48
+ $subnav_keyed = array();
49
+ if ( $subnavs ) {
50
+ foreach ( $subnavs as $subnav ) {
51
+ $subnav_keyed[ $subnav->slug ] = (array) $subnav;
52
+ }
53
+ }
54
+
55
+ $subnav_object = new self( $subnav_keyed );
56
+ $subnav_object->set_component( $this->get_component() );
57
+ $subnav_object->set_parent_slug( $offset );
58
+
59
+ $this->backcompat_nav[ $offset ] = $subnav_object;
60
+ }
61
+ }
62
+
63
+ if ( isset( $this->backcompat_nav[ $offset ] ) ) {
64
+ return $this->backcompat_nav[ $offset ];
65
+ }
66
+
67
+ return false;
68
+ }
69
+
70
+ /**
71
+ * Unset a nav array value at the specified offset.
72
+ *
73
+ * @since 2.6.0
74
+ *
75
+ * @param mixed $offset Array offset.
76
+ */
77
+ public function offsetUnset( $offset ) {
78
+ _doing_it_wrong(
79
+ 'bp_nav',
80
+ __( 'These globals should not be used directly and are deprecated. Please use the BuddyPress nav functions instead.', 'buddypress' ),
81
+ '2.6.0'
82
+ );
83
+
84
+ $this->get_component_nav( $offset )->delete_nav( $offset, $this->get_parent_slug() );
85
+
86
+ // Clear the cached nav.
87
+ unset( $this->backcompat_nav[ $offset ] );
88
+ }
89
+
90
+ /**
91
+ * Get the parent slug of the current nav item.
92
+ *
93
+ * @since 2.6.0
94
+ *
95
+ * @return string
96
+ */
97
+ public function get_parent_slug() {
98
+ return $this->parent_slug;
99
+ }
100
+
101
+ /**
102
+ * Set the parent slug of the current nav item.
103
+ *
104
+ * @since 2.6.0
105
+ */
106
+ public function set_parent_slug( $slug ) {
107
+ $this->parent_slug = $slug;
108
+ }
109
+
110
+ /**
111
+ * Get the nav object corresponding to the specified offset.
112
+ *
113
+ * @since 2.6.0
114
+ *
115
+ * @param mixed $offset Array offset.
116
+ * @return bool|array
117
+ */
118
+ public function get_nav( $offset ) {
119
+ $nav = parent::get_nav( $offset );
120
+
121
+ if ( ! $nav ) {
122
+ $component_nav = $this->get_component_nav( $offset );
123
+ $secondary_nav = $component_nav->get_secondary( array( 'slug' => $offset ), false );
124
+
125
+ $nav = array();
126
+
127
+ if ( empty( $primary_nav ) ) {
128
+ return $nav;
129
+ }
130
+
131
+ foreach ( $primary_nav as $item ) {
132
+ $nav[ $item->slug ] = (array) $item;
133
+ }
134
+ }
135
+
136
+ return $nav;
137
+ }
138
+ }
bp-core/classes/class-bp-core-html-element.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Core component classes.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage Core
7
+ * @since 2.7.0
8
+ */
9
+
10
+ /**
11
+ * Generate markup for an HTML element.
12
+ *
13
+ * @since 2.7.0
14
+ */
15
+ class BP_Core_HTML_Element {
16
+ /**
17
+ * Open tag for an element.
18
+ *
19
+ * This would include attributes if applicable. eg. '<a href="" class="">'
20
+ *
21
+ * @since 2.7.0
22
+ *
23
+ * @var string
24
+ */
25
+ public $open_tag = '';
26
+
27
+ /**
28
+ * Inner HTML for an element.
29
+ *
30
+ * For example, this could be anchor text within an <a> element.
31
+ *
32
+ * @since 2.7.0
33
+ *
34
+ * @var string
35
+ */
36
+ public $inner_html = '';
37
+
38
+ /**
39
+ * Closing tag for an element.
40
+ *
41
+ * For example, "</a>".
42
+ *
43
+ * @since 2.7.0
44
+ *
45
+ * @var string
46
+ */
47
+ public $close_tag = '';
48
+
49
+ /**
50
+ * Constructor.
51
+ *
52
+ * @since 2.7.0
53
+ *
54
+ * @param array $r {
55
+ * An array of arguments.
56
+ * @type string $element The element to render. eg. 'a' for the anchor element.
57
+ * @type array $attr Optional. The element's attributes set as key/value pairs. eg.
58
+ * array( 'href' => 'http://example.com', 'class' => 'my-class' )
59
+ * @type string $inner_html Optional. The inner HTML for the element if applicable. Please note that
60
+ * this isn't sanitized, so you should use your own sanitization routine
61
+ * before using this parameter.
62
+ * }
63
+ */
64
+ public function __construct( $r = array() ) {
65
+ $elem = sanitize_html_class( $r['element'] );
66
+ if ( empty( $elem ) ) {
67
+ return;
68
+ }
69
+
70
+ // Render attributes.
71
+ $attributes = '';
72
+ foreach( (array) $r['attr'] as $attr => $val ) {
73
+ // If attribute is empty, skip.
74
+ if ( empty( $val ) ) {
75
+ continue;
76
+ }
77
+
78
+ if ( 'href' === $attr || 'formaction' === $attr || 'src' === $attr ) {
79
+ $val = esc_url( $val );
80
+ } elseif ( 'id' === $attr ) {
81
+ $val = sanitize_html_class( $val );
82
+ } else {
83
+ $val = esc_attr( $val );
84
+ }
85
+
86
+ $attributes .= sprintf( '%s="%s" ', sanitize_html_class( $attr ), $val );
87
+ }
88
+
89
+ // <input> / <img> is self-closing.
90
+ if ( 'input' === $elem || 'img' === $elem ) {
91
+ $this->open_tag = sprintf( '<%1$s %2$s />', $elem, $attributes );
92
+
93
+ // All other elements.
94
+ } else {
95
+ $this->open_tag = sprintf( '<%1$s %2$s>', $elem, $attributes );
96
+ $this->inner_html = ! empty( $r['inner_html'] ) ? $r['inner_html'] : '';
97
+ $this->close_tag = sprintf( '</%1$s>', $elem );
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Returns a property from this class.
103
+ *
104
+ * @since 2.7.0
105
+ *
106
+ * @param string $prop Property name. Either 'open_tag', 'inner_html', 'close_tag'.
107
+ * @return string
108
+ */
109
+ public function get( $prop = '' ) {
110
+ if ( ! isset( $this->{$prop} ) ) {
111
+ return '';
112
+ }
113
+
114
+ return $this->{$prop};
115
+ }
116
+
117
+ /**
118
+ * Returns full contents of HTML element.
119
+ *
120
+ * @since 2.7.0
121
+ *
122
+ * @return string
123
+ */
124
+ public function contents() {
125
+ return $this->open_tag . $this->inner_html . $this->close_tag;
126
+ }
127
+ }
bp-core/classes/class-bp-core-login-widget.php CHANGED
@@ -27,8 +27,9 @@ class BP_Core_Login_Widget extends WP_Widget {
27
  false,
28
  _x( '(BuddyPress) Log In', 'Title of the login widget', 'buddypress' ),
29
  array(
30
- 'description' => __( 'Show a Log In form to logged-out visitors, and a Log Out link to those who are logged in.', 'buddypress' ),
31
- 'classname' => 'widget_bp_core_login_widget buddypress widget',
 
32
  )
33
  );
34
  }
@@ -116,7 +117,7 @@ class BP_Core_Login_Widget extends WP_Widget {
116
 
117
  <?php if ( bp_get_signup_allowed() ) : ?>
118
 
119
- <span class="bp-login-widget-register-link"><a href="<?php echo esc_url( bp_get_signup_page() ); ?>" title="<?php esc_attr_e( 'Register for a new account', 'buddypress' ); ?>"><?php _e( 'Register', 'buddypress' ); ?></a></span>
120
 
121
  <?php endif; ?>
122
 
27
  false,
28
  _x( '(BuddyPress) Log In', 'Title of the login widget', 'buddypress' ),
29
  array(
30
+ 'description' => __( 'Show a Log In form to logged-out visitors, and a Log Out link to those who are logged in.', 'buddypress' ),
31
+ 'classname' => 'widget_bp_core_login_widget buddypress widget',
32
+ 'customize_selective_refresh' => true,
33
  )
34
  );
35
  }
117
 
118
  <?php if ( bp_get_signup_allowed() ) : ?>
119
 
120
+ <span class="bp-login-widget-register-link"><a href="<?php echo esc_url( bp_get_signup_page() ); ?>"><?php _e( 'Register', 'buddypress' ); ?></a></span>
121
 
122
  <?php endif; ?>
123
 
bp-core/classes/class-bp-core-nav-item.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Exit if accessed directly.
4
+ defined( 'ABSPATH' ) || exit;
5
+
6
+ /**
7
+ * Navigation item.
8
+ *
9
+ * @since 2.6.0
10
+ */
11
+ class BP_Core_Nav_Item extends ArrayObject {
12
+ public function __construct( $data ) {
13
+ parent::__construct( $data, ArrayObject::ARRAY_AS_PROPS );
14
+ }
15
+ }
bp-core/classes/class-bp-core-nav.php ADDED
@@ -0,0 +1,402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Core component class.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage Core
7
+ * @since 2.6.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ defined( 'ABSPATH' ) || exit;
12
+
13
+ /**
14
+ * BuddyPress Nav.
15
+ *
16
+ * This class is used to build each component's navigation.
17
+ *
18
+ * @since 2.6.0
19
+ */
20
+ class BP_Core_Nav {
21
+ /**
22
+ * An associative array containing the nav items for the object ID.
23
+ *
24
+ * @since 2.6.0
25
+ * @var array
26
+ */
27
+ protected $nav;
28
+
29
+ /**
30
+ * The current object ID.
31
+ *
32
+ * @since 2.6.0
33
+ * @var int
34
+ */
35
+ private $object_id;
36
+
37
+ /**
38
+ * Initializes the Nav belonging to the specified object.
39
+ *
40
+ * @since 2.6.0
41
+ *
42
+ * @param int $object_id The item ID to build the nav for. Default is the displayed user ID.
43
+ */
44
+ public function __construct( $object_id = 0 ) {
45
+ if ( empty( $object_id ) ) {
46
+ $this->object_id = (int) bp_displayed_user_id();
47
+ } else {
48
+ $this->object_id = (int) $object_id;
49
+ }
50
+
51
+ $this->nav[ $this->object_id ] = array();
52
+ }
53
+
54
+ /**
55
+ * Checks whether a nav item is set.
56
+ *
57
+ * @since 2.6.0
58
+ *
59
+ * @param string $key The requested nav slug.
60
+ * @return bool True if the nav item is set, false otherwise.
61
+ */
62
+ public function __isset( $key ) {
63
+ return isset( $this->nav[ $this->object_id ][ $key ] );
64
+ }
65
+
66
+ /**
67
+ * Gets a nav item.
68
+ *
69
+ * @since 2.6.0
70
+ *
71
+ * @param string $key The requested nav slug.
72
+ * @return mixed The value corresponding to the requested nav item.
73
+ */
74
+ public function __get( $key ) {
75
+ if ( ! isset( $this->nav[ $this->object_id ][ $key ] ) ) {
76
+ $this->nav[ $this->object_id ][ $key ] = null;
77
+ }
78
+
79
+ return $this->nav[ $this->object_id ][ $key ];
80
+ }
81
+
82
+ /**
83
+ * Sets a nav item.
84
+ *
85
+ * @since 2.6.0
86
+ *
87
+ * @param string $key The requested nav slug.
88
+ * @param mixed $value The value of the nav item.
89
+ */
90
+ public function __set( $key, $value ) {
91
+ if ( is_array( $value ) ) {
92
+ $value['primary'] = true;
93
+ }
94
+
95
+ $this->nav[ $this->object_id ][ $key ] = new BP_Core_Nav_Item( $value );
96
+ }
97
+
98
+ /**
99
+ * Gets a specific nav item or array of nav items.
100
+ *
101
+ * @since 2.6.0
102
+ *
103
+ * @param string $key The nav item slug to get. Optional.
104
+ * @return mixed An array of nav item, a single nav item, or null if none found.
105
+ */
106
+ public function get( $key = '' ) {
107
+ $return = null;
108
+
109
+ // Return the requested nav item.
110
+ if ( ! empty( $key ) ) {
111
+ if ( ! isset( $this->nav[ $this->object_id ][ $key ] ) ) {
112
+ $return = null;
113
+ } else {
114
+ $return = $this->nav[ $this->object_id ][ $key ];
115
+ }
116
+
117
+ // Return all nav item items.
118
+ } else {
119
+ $return = $this->nav[ $this->object_id ];
120
+ }
121
+
122
+ return $return;
123
+ }
124
+
125
+ /**
126
+ * Adds a new nav item.
127
+ *
128
+ * @since 2.6.0
129
+ *
130
+ * @param array $args The nav item's arguments.
131
+ * @return BP_Core_Nav_Item
132
+ */
133
+ public function add_nav( $args ) {
134
+ if ( empty( $args['slug'] ) ) {
135
+ return false;
136
+ }
137
+
138
+ // We have a child and the parent exists.
139
+ if ( ! empty( $args['parent_slug'] ) ) {
140
+ $slug = $args['parent_slug'] . '/' . $args['slug'];
141
+ $args['secondary'] = true;
142
+
143
+ // This is a parent.
144
+ } else {
145
+ $slug = $args['slug'];
146
+ $args['primary'] = true;
147
+ }
148
+
149
+ // Add to the nav.
150
+ $this->nav[ $this->object_id ][ $slug ] = new BP_Core_Nav_Item( $args );
151
+
152
+ return $this->nav[ $this->object_id ][ $slug ];
153
+ }
154
+
155
+ /**
156
+ * Edits a nav item.
157
+ *
158
+ * @since 2.6.0
159
+ *
160
+ * @param array $args The nav item's arguments.
161
+ * @param string $slug The slug of the nav item.
162
+ * @param string $parent_slug The slug of the parent nav item (required to edit a child).
163
+ * @return BP_Core_Nav_Item
164
+ */
165
+ public function edit_nav( $args = array(), $slug = '', $parent_slug = '' ) {
166
+ if ( empty( $slug ) ) {
167
+ return false;
168
+ }
169
+
170
+ // We're editing a parent!
171
+ if ( empty( $parent_slug ) ) {
172
+ $nav_items = $this->get_primary( array( 'slug' => $slug ), false );
173
+
174
+ if ( ! $nav_items ) {
175
+ return false;
176
+ }
177
+
178
+ $nav_item = reset( $nav_items );
179
+ $this->nav[ $this->object_id ][ $slug ] = new BP_Core_Nav_Item( wp_parse_args( $args, (array) $nav_item ) );
180
+
181
+ // Return the edited object.
182
+ return $this->nav[ $this->object_id ][ $slug ];
183
+
184
+ // We're editing a child.
185
+ } else {
186
+ $sub_items = $this->get_secondary( array( 'parent_slug' => $parent_slug, 'slug' => $slug ), false );
187
+
188
+ if ( ! $sub_items ) {
189
+ return false;
190
+ }
191
+
192
+ $sub_item = reset( $sub_items );
193
+
194
+ $params = wp_parse_args( $args, (array) $sub_item );
195
+
196
+ // When we have parents, it's for life, we can't change them!
197
+ if ( empty( $params['parent_slug'] ) || $parent_slug !== $params['parent_slug'] ) {
198
+ return false;
199
+ }
200
+
201
+ $this->nav[ $this->object_id ][ $parent_slug . '/' . $slug ] = new BP_Core_Nav_Item( $params );
202
+
203
+ // Return the edited object.
204
+ return $this->nav[ $this->object_id ][ $parent_slug . '/' . $slug ];
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Unset an item or a subitem of the nav.
210
+ *
211
+ * @since 2.6.0
212
+ *
213
+ * @param string $slug The slug of the main item.
214
+ * @param string $parent_slug The slug of the sub item.
215
+ * @return bool|callable|array False on failure, the screen function(s) on success.
216
+ */
217
+ public function delete_nav( $slug = '', $parent_slug = '' ) {
218
+
219
+ // Bail if slug is empty
220
+ if ( empty( $slug ) ) {
221
+ return false;
222
+ }
223
+
224
+ // We're deleting a child
225
+ if ( ! empty( $parent_slug ) ) {
226
+
227
+ // Validate the subnav
228
+ $sub_items = $this->get_secondary( array( 'parent_slug' => $parent_slug, 'slug' => $slug ), false );
229
+
230
+ if ( ! $sub_items ) {
231
+ return false;
232
+ }
233
+
234
+ $sub_item = reset( $sub_items );
235
+
236
+ if ( empty( $sub_item->slug ) ) {
237
+ return false;
238
+ }
239
+
240
+ // Delete the child
241
+ unset( $this->nav[ $this->object_id ][ $parent_slug . '/' . $slug ] );
242
+
243
+ // Return the deleted item's screen function
244
+ return array( $sub_item->screen_function );
245
+
246
+ // We're deleting a parent
247
+ } else {
248
+ // Validate the nav
249
+ $nav_items = $this->get_primary( array( 'slug' => $slug ), false );
250
+
251
+ if ( ! $nav_items ) {
252
+ return false;
253
+ }
254
+
255
+ $nav_item = reset( $nav_items );
256
+
257
+ if ( empty( $nav_item->slug ) ) {
258
+ return false;
259
+ }
260
+
261
+ $screen_functions = array( $nav_item->screen_function );
262
+
263
+ // Life's unfair, children won't survive the parent :(
264
+ $sub_items = $this->get_secondary( array( 'parent_slug' => $nav_item->slug ), false );
265
+
266
+ if ( ! empty( $sub_items ) ) {
267
+ foreach ( $sub_items as $sub_item ) {
268
+ $screen_functions[] = $sub_item->screen_function;
269
+
270
+ // Delete the child
271
+ unset( $this->nav[ $this->object_id ][ $nav_item->slug . '/' . $sub_item->slug ] );
272
+ }
273
+ }
274
+
275
+ // Delete the parent.
276
+ unset( $this->nav[ $this->object_id ][ $nav_item->slug ] );
277
+
278
+ // Return the deleted item's screen functions.
279
+ return $screen_functions;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Sorts a list of nav items.
285
+ *
286
+ * @since 2.6.0
287
+ *
288
+ * @param array $items The nav items to sort.
289
+ * @return array
290
+ */
291
+ public function sort_nav( $items ) {
292
+ $sorted = array();
293
+
294
+ foreach ( $items as $item ) {
295
+ // Default position
296
+ $position = 99;
297
+
298
+ if ( isset( $item->position ) ) {
299
+ $position = (int) $item->position;
300
+ }
301
+
302
+ // If position is already taken, move to the first next available
303
+ if ( isset( $sorted[ $position ] ) ) {
304
+ $sorted_keys = array_keys( $sorted );
305
+
306
+ do {
307
+ $position += 1;
308
+ } while ( in_array( $position, $sorted_keys ) );
309
+ }
310
+
311
+ $sorted[ $position ] = $item;
312
+ }
313
+
314
+ ksort( $sorted );
315
+ return $sorted;
316
+ }
317
+
318
+ /**
319
+ * Gets the primary nav items.
320
+ *
321
+ * @since 2.6.0
322
+ *
323
+ * @param array $args Filters to select the specific primary items. See wp_list_filter().
324
+ * @param bool $sort True to sort the nav items. False otherwise.
325
+ * @return array The list of primary objects nav
326
+ */
327
+ public function get_primary( $args = array(), $sort = true ) {
328
+ $params = wp_parse_args( $args, array( 'primary' => true ) );
329
+
330
+ // This parameter is not overridable.
331
+ if ( empty( $params['primary'] ) ) {
332
+ return false;
333
+ }
334
+
335
+ $primary_nav = wp_list_filter( $this->nav[ $this->object_id ], $params );
336
+
337
+ if ( ! $primary_nav ) {
338
+ return false;
339
+ }
340
+
341
+ if ( true !== $sort ) {
342
+ return $primary_nav;
343
+ }
344
+
345
+ return $this->sort_nav( $primary_nav );
346
+ }
347
+
348
+ /**
349
+ * Gets the secondary nav items.
350
+ *
351
+ * @since 2.6.0
352
+ *
353
+ * @param array $args Filters to select the specific secondary items. See wp_list_filter().
354
+ * @param bool $sort True to sort the nav items. False otherwise.
355
+ * @return array The list of secondary objects nav
356
+ */
357
+ public function get_secondary( $args = array(), $sort = true ) {
358
+ $params = wp_parse_args( $args, array( 'parent_slug' => '' ) );
359
+
360
+ // No need to search children if the parent is not set.
361
+ if ( empty( $params['parent_slug'] ) && empty( $params['secondary'] ) ) {
362
+ return false;
363
+ }
364
+
365
+ $secondary_nav = wp_list_filter( $this->nav[ $this->object_id ], $params );
366
+
367
+ if ( ! $secondary_nav ) {
368
+ return false;
369
+ }
370
+
371
+ if ( true !== $sort ) {
372
+ return $secondary_nav;
373
+ }
374
+
375
+ return $this->sort_nav( $secondary_nav );
376
+ }
377
+
378
+ /**
379
+ * Gets a nested list of visible nav items.
380
+ *
381
+ * @since 2.6.0
382
+ *
383
+ * @return array The list of visible nav items.
384
+ */
385
+ public function get_item_nav() {
386
+ $primary_nav_items = $this->get_primary( array( 'show_for_displayed_user' => true ) );
387
+
388
+ if ( $primary_nav_items ) {
389
+ foreach( $primary_nav_items as $key_nav => $primary_nav ) {
390
+ // Try to get the children.
391
+ $children = $this->get_secondary( array( 'parent_slug' => $primary_nav->slug, 'user_has_access' => true ) );
392
+
393
+ if ( $children ) {
394
+ $primary_nav_items[ $key_nav ] = clone $primary_nav;
395
+ $primary_nav_items[ $key_nav ]->children = $children;
396
+ }
397
+ }
398
+ }
399
+
400
+ return $primary_nav_items;
401
+ }
402
+ }
bp-core/classes/class-bp-core-oembed-extension.php ADDED
@@ -0,0 +1,622 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Core component classes.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage Core
7
+ * @since 2.6.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ defined( 'ABSPATH' ) || exit;
12
+
13
+ /**
14
+ * API for responding and returning a custom oEmbed request.
15
+ *
16
+ * @since 2.6.0
17
+ */
18
+ abstract class BP_Core_oEmbed_Extension {
19
+
20
+ /** START PROPERTIES ****************************************************/
21
+
22
+ /**
23
+ * (required) The slug endpoint.
24
+ *
25
+ * Should be your component id.
26
+ *
27
+ * @since 2.6.0
28
+ *
29
+ * @var string
30
+ */
31
+ public $slug_endpoint = '';
32
+
33
+ /** END PROPERTIES ******************************************************/
34
+
35
+ /**
36
+ * Constructor.
37
+ */
38
+ final public function __construct() {
39
+ $this->setup_properties();
40
+
41
+ // Some rudimentary logic checking.
42
+ if ( empty( $this->slug_endpoint ) ) {
43
+ return;
44
+ }
45
+
46
+ $this->setup_hooks();
47
+ $this->custom_hooks();
48
+ }
49
+
50
+ /** REQUIRED METHODS ****************************************************/
51
+
52
+ /**
53
+ * Add content for your oEmbed response here.
54
+ *
55
+ * @since 2.6.0
56
+ */
57
+ abstract protected function content();
58
+
59
+ /**
60
+ * Add a check for when you are on the page you want to oEmbed.
61
+ *
62
+ * You'll want to return a boolean here. eg. bp_is_single_activity().
63
+ *
64
+ * @since 2.6.0
65
+ *
66
+ * @return bool
67
+ */
68
+ abstract protected function is_page();
69
+
70
+ /**
71
+ * Validate the URL to see if it matches your item ID.
72
+ *
73
+ * @since 2.6.0
74
+ *
75
+ * @param string $url URL to validate.
76
+ * @return int Your item ID
77
+ */
78
+ abstract protected function validate_url_to_item_id( $url );
79
+
80
+ /**
81
+ * Set the oEmbed response data.
82
+ *
83
+ * @since 2.6.0
84
+ *
85
+ * @param int $item_id Your item ID to do checks against.
86
+ * @return array Should contain 'content', 'title', 'author_url', 'author_name' as array
87
+ * keys. 'author_url' and 'author_name' is optional; the rest are required.
88
+ */
89
+ abstract protected function set_oembed_response_data( $item_id );
90
+
91
+ /**
92
+ * Sets the fallback HTML for the oEmbed response.
93
+ *
94
+ * In a WordPress oEmbed item, the fallback HTML is a <blockquote>. This is
95
+ * usually hidden after the <iframe> is loaded.
96
+ *
97
+ * @since 2.6.0
98
+ *
99
+ * @param int $item_id Your item ID to do checks against.
100
+ * @return string Fallback HTML you want to output.
101
+ */
102
+ abstract protected function set_fallback_html( $item_id );
103
+
104
+ /** OPTIONAL METHODS ****************************************************/
105
+
106
+ /**
107
+ * If your oEmbed endpoint requires additional arguments, set them here.
108
+ *
109
+ * @see register_rest_route() View the $args parameter for more info.
110
+ *
111
+ * @since 2.6.0
112
+ *
113
+ * @return array
114
+ */
115
+ protected function set_route_args() {
116
+ return array();
117
+ }
118
+
119
+ /**
120
+ * Set the iframe title.
121
+ *
122
+ * If not set, this will fallback to WP's 'Embedded WordPress Post'.
123
+ *
124
+ * @since 2.6.0
125
+ *
126
+ * @param int $item_id The item ID to do checks for.
127
+ */
128
+ protected function set_iframe_title( $item_id ) {}
129
+
130
+ /**
131
+ * Do what you need to do here to initialize any custom hooks.
132
+ *
133
+ * @since 2.6.0
134
+ */
135
+ protected function custom_hooks() {}
136
+
137
+ /**
138
+ * Set permalink for oEmbed link discovery.
139
+ *
140
+ * This method will be called on the page we want to oEmbed. In most cases,
141
+ * you will not need to override this method. However, if you need to, do
142
+ * override in your extended class.
143
+ *
144
+ * @since 2.6.0
145
+ */
146
+ protected function set_permalink() {
147
+ $url = bp_get_requested_url();
148
+
149
+ // Remove querystring from bp_get_requested_url().
150
+ if ( false !== strpos( bp_get_requested_url(), '?' ) ) {
151
+ $url = substr( bp_get_requested_url(), 0, strpos( bp_get_requested_url(), '?' ) );
152
+ }
153
+
154
+ return $url;
155
+ }
156
+
157
+ /** HELPERS *************************************************************/
158
+
159
+ /**
160
+ * Get the item ID when filtering the oEmbed HTML.
161
+ *
162
+ * Should only be used during the 'embed_html' hook.
163
+ *
164
+ * @since 2.6.0
165
+ */
166
+ protected function get_item_id() {
167
+ return $this->is_page() ? $this->validate_url_to_item_id( $this->set_permalink() ) : buddypress()->{$this->slug_endpoint}->embedid_in_progress;
168
+ }
169
+
170
+ /** SET UP **************************************************************/
171
+
172
+ /**
173
+ * Set up properties.
174
+ *
175
+ * @since 2.6.0
176
+ */
177
+ protected function setup_properties() {
178
+ $this->slug_endpoint = sanitize_title( $this->slug_endpoint );
179
+ }
180
+
181
+ /**
182
+ * Hooks! We do the dirty work here, so you don't have to! :)
183
+ *
184
+ * More hooks are available in the setup_template_parts() method.
185
+ *
186
+ * @since 2.6.0
187
+ */
188
+ protected function setup_hooks() {
189
+ add_action( 'rest_api_init', array( $this, 'register_route' ) );
190
+ add_action( 'bp_embed_content', array( $this, 'inject_content' ) );
191
+
192
+ add_filter( 'embed_template', array( $this, 'setup_template_parts' ) );
193
+ add_filter( 'post_embed_url', array( $this, 'filter_embed_url' ) );
194
+ add_filter( 'embed_html', array( $this, 'filter_embed_html' ) );
195
+ add_filter( 'oembed_discovery_links', array( $this, 'add_oembed_discovery_links' ) );
196
+ add_filter( 'rest_pre_serve_request', array( $this, 'oembed_xml_request' ), 20, 4 );
197
+ }
198
+
199
+ /** HOOKS ***************************************************************/
200
+
201
+ /**
202
+ * Register the oEmbed REST API route.
203
+ *
204
+ * @since 2.6.0
205
+ */
206
+ public function register_route() {
207
+ /** This filter is documented in wp-includes/class-wp-oembed-controller.php */
208
+ $maxwidth = apply_filters( 'oembed_default_width', 600 );
209
+
210
+ // Required arguments.
211
+ $args = array(
212
+ 'url' => array(
213
+ 'required' => true,
214
+ 'sanitize_callback' => 'esc_url_raw',
215
+ ),
216
+ 'format' => array(
217
+ 'default' => 'json',
218
+ 'sanitize_callback' => 'wp_oembed_ensure_format',
219
+ ),
220
+ 'maxwidth' => array(
221
+ 'default' => $maxwidth,
222
+ 'sanitize_callback' => 'absint',
223
+ )
224
+ );
225
+
226
+ // Merge custom arguments here.
227
+ $args = $args + (array) $this->set_route_args();
228
+
229
+ register_rest_route( 'oembed/1.0', "/embed/{$this->slug_endpoint}", array(
230
+ array(
231
+ 'methods' => WP_REST_Server::READABLE,
232
+ 'callback' => array( $this, 'get_item' ),
233
+ 'args' => $args
234
+ ),
235
+ ) );
236
+ }
237
+
238
+ /**
239
+ * Set up custom embed template parts for BuddyPress use.
240
+ *
241
+ * @since 2.6.0
242
+ *
243
+ * @param string $template File path to current embed template.
244
+ * @return string
245
+ */
246
+ public function setup_template_parts( $template ) {
247
+ // Determine if we're on our BP page.
248
+ if ( ! $this->is_page() || is_404() ) {
249
+ return $template;
250
+ }
251
+
252
+ // Set up some BP-specific embed template overrides.
253
+ add_action( 'get_template_part_embed', array( $this, 'content_buffer_start' ), -999, 2 );
254
+ add_action( 'get_footer', array( $this, 'content_buffer_end' ), -999 );
255
+
256
+ // Return the original WP embed template.
257
+ return $template;
258
+ }
259
+
260
+ /**
261
+ * Start object buffer.
262
+ *
263
+ * We're going to override WP's get_template_part( 'embed, 'content' ) call
264
+ * and inject our own template for BuddyPress use.
265
+ *
266
+ * @since 2.6.0
267
+ *
268
+ * @param string $slug Template slug.
269
+ * @param string $name Template name.
270
+ */
271
+ public function content_buffer_start( $slug, $name ) {
272
+ if ( 'embed' !== $slug || 'content' !== $name ) {
273
+ return;
274
+ }
275
+
276
+ // Start the buffer to wipe out get_template_part( 'embed, 'content' ).
277
+ ob_start();
278
+ }
279
+
280
+ /**
281
+ * End object buffer.
282
+ *
283
+ * We're going to override WP's get_template_part( 'embed, 'content' ) call
284
+ * and inject our own template for BuddyPress use.
285
+ *
286
+ * @since 2.6.0
287
+ *
288
+ * @param string $name Template name.
289
+ */
290
+ public function content_buffer_end( $name ) {
291
+ if ( 'embed' !== $name || is_404() ) {
292
+ return;
293
+ }
294
+
295
+ // Wipe out get_template_part( 'embed, 'content' ).
296
+ ob_end_clean();
297
+
298
+ // Start our custom BuddyPress embed template!
299
+ echo '<div ';
300
+ post_class( 'wp-embed' );
301
+ echo '>';
302
+
303
+ // Template part for our embed header.
304
+ bp_get_asset_template_part( 'embeds/header', bp_current_component() );
305
+
306
+ /**
307
+ * Inject BuddyPress embed content on this hook.
308
+ *
309
+ * You shouldn't really need to use this if you extend the
310
+ * {@link BP_oEmbed_Component} class.
311
+ *
312
+ * @since 2.6.0
313
+ */
314
+ do_action( 'bp_embed_content' );
315
+
316
+ // Template part for our embed footer.
317
+ bp_get_asset_template_part( 'embeds/footer', bp_current_component() );
318
+
319
+ echo '</div>';
320
+ }
321
+
322
+ /**
323
+ * Adds oEmbed discovery links on single activity pages.
324
+ *
325
+ * @since 2.6.0
326
+ *
327
+ * @param string $retval Current discovery links.
328
+ * @return string
329
+ */
330
+ public function add_oembed_discovery_links( $retval ) {
331
+ if ( ! $this->is_page() ) {
332
+ return $retval;
333
+ }
334
+
335
+ $permalink = $this->set_permalink();
336
+ if ( empty( $permalink ) ) {
337
+ return $retval;
338
+ }
339
+
340
+ add_filter( 'rest_url' , array( $this, 'filter_rest_url' ) );
341
+
342
+ $retval = '<link rel="alternate" type="application/json+oembed" href="' . esc_url( get_oembed_endpoint_url( $permalink ) ) . '" />' . "\n";
343
+
344
+ if ( class_exists( 'SimpleXMLElement' ) ) {
345
+ $retval .= '<link rel="alternate" type="text/xml+oembed" href="' . esc_url( get_oembed_endpoint_url( $permalink, 'xml' ) ) . '" />' . "\n";
346
+ }
347
+
348
+ remove_filter( 'rest_url' , array( $this, 'filter_rest_url' ) );
349
+
350
+ return $retval;
351
+ }
352
+
353
+ /**
354
+ * Fetch our oEmbed response data to return.
355
+ *
356
+ * A simplified version of {@link get_oembed_response_data()}.
357
+ *
358
+ * @since 2.6.0
359
+ *
360
+ * @link http://oembed.com/ View the 'Response parameters' section for more details.
361
+ *
362
+ * @param array $item Custom oEmbed response data.
363
+ * @param int $width The requested width.
364
+ * @return array
365
+ */
366
+ protected function get_oembed_response_data( $item, $width ) {
367
+ $data = wp_parse_args( $item, array(
368
+ 'version' => '1.0',
369
+ 'provider_name' => get_bloginfo( 'name' ),
370
+ 'provider_url' => get_home_url(),
371
+ 'author_name' => get_bloginfo( 'name' ),
372
+ 'author_url' => get_home_url(),
373
+ 'title' => ucfirst( $this->slug_endpoint ),
374
+ 'type' => 'rich',
375
+ ) );
376
+
377
+ /** This filter is documented in /wp-includes/embed.php */
378
+ $min_max_width = apply_filters( 'oembed_min_max_width', array(
379
+ 'min' => 200,
380
+ 'max' => 600
381
+ ) );
382
+
383
+ $width = min( max( $min_max_width['min'], $width ), $min_max_width['max'] );
384
+ $height = max( ceil( $width / 16 * 9 ), 200 );
385
+
386
+ $data['width'] = absint( $width );
387
+ $data['height'] = absint( $height );
388
+
389
+ // Set 'html' parameter.
390
+ if ( 'video' === $data['type'] || 'rich' === $data['type'] ) {
391
+ // Fake a WP post so we can use get_post_embed_html().
392
+ $post = new stdClass;
393
+ $post->post_content = $data['content'];
394
+ $post->post_title = $data['title'];
395
+
396
+ $data['html'] = get_post_embed_html( $data['width'], $data['height'], $post );
397
+ }
398
+
399
+ // Remove temporary parameters.
400
+ unset( $data['content'] );
401
+
402
+ return $data;
403
+ }
404
+
405
+ /**
406
+ * Callback for the API endpoint.
407
+ *
408
+ * Returns the JSON object for the item.
409
+ *
410
+ * @since 2.6.0
411
+ *
412
+ * @param WP_REST_Request $request Full data about the request.
413
+ * @return WP_Error|array oEmbed response data or WP_Error on failure.
414
+ */
415
+ public function get_item( $request ) {
416
+ $url = $request['url'];
417
+
418
+ $data = false;
419
+
420
+ $item_id = (int) $this->validate_url_to_item_id( $url );
421
+
422
+ if ( ! empty( $item_id ) ) {
423
+ // Add markers to tell that we're embedding a single activity.
424
+ // This is needed for various oEmbed response data filtering.
425
+ if ( empty( buddypress()->{$this->slug_endpoint} ) ) {
426
+ buddypress()->{$this->slug_endpoint} = new stdClass;
427
+ }
428
+ buddypress()->{$this->slug_endpoint}->embedurl_in_progress = $url;
429
+ buddypress()->{$this->slug_endpoint}->embedid_in_progress = $item_id;
430
+
431
+ // Save custom route args as well.
432
+ $custom_args = array_keys( (array) $this->set_route_args() );
433
+ if ( ! empty( $custom_args ) ) {
434
+ buddypress()->{$this->slug_endpoint}->embedargs_in_progress = array();
435
+
436
+ foreach( $custom_args as $arg ) {
437
+ if ( isset( $request[ $arg ] ) ) {
438
+ buddypress()->{$this->slug_endpoint}->embedargs_in_progress[ $arg ] = $request[ $arg ];
439
+ }
440
+ }
441
+ }
442
+
443
+ // Grab custom oEmbed response data.
444
+ $item = $this->set_oembed_response_data( $item_id );
445
+
446
+ // Set oEmbed response data.
447
+ $data = $this->get_oembed_response_data( $item, $request['maxwidth'] );
448
+ }
449
+
450
+ if ( ! $data ) {
451
+ return new WP_Error( 'oembed_invalid_url', get_status_header_desc( 404 ), array( 'status' => 404 ) );
452
+ }
453
+
454
+ return $data;
455
+ }
456
+
457
+ /**
458
+ * If oEmbed request wants XML, return XML instead of JSON.
459
+ *
460
+ * Basically a copy of {@link _oembed_rest_pre_serve_request()}. Unfortunate
461
+ * that we have to duplicate this just for a URL check.
462
+ *
463
+ * @since 2.6.0
464
+ *
465
+ * @param bool $served Whether the request has already been served.
466
+ * @param WP_HTTP_ResponseInterface $result Result to send to the client. Usually a WP_REST_Response.
467
+ * @param WP_REST_Request $request Request used to generate the response.
468
+ * @param WP_REST_Server $server Server instance.
469
+ * @return bool
470
+ */
471
+ public function oembed_xml_request( $served, $result, $request, $server ) {
472
+ $params = $request->get_params();
473
+
474
+ if ( ! isset( $params['format'] ) || 'xml' !== $params['format'] ) {
475
+ return $served;
476
+ }
477
+
478
+ // Validate URL against our oEmbed endpoint. If not valid, bail.
479
+ // This is our mod to _oembed_rest_pre_serve_request().
480
+ $query_params = $request->get_query_params();
481
+ if ( false === $this->validate_url_to_item_id( $query_params['url'] ) ) {
482
+ return $served;
483
+ }
484
+
485
+ // Embed links inside the request.
486
+ $data = $server->response_to_data( $result, false );
487
+
488
+ if ( ! class_exists( 'SimpleXMLElement' ) ) {
489
+ status_header( 501 );
490
+ die( get_status_header_desc( 501 ) );
491
+ }
492
+
493
+ $result = _oembed_create_xml( $data );
494
+
495
+ // Bail if there's no XML.
496
+ if ( ! $result ) {
497
+ status_header( 501 );
498
+ return get_status_header_desc( 501 );
499
+ }
500
+
501
+ if ( ! headers_sent() ) {
502
+ $server->send_header( 'Content-Type', 'text/xml; charset=' . get_option( 'blog_charset' ) );
503
+ }
504
+
505
+ echo $result;
506
+
507
+ return true;
508
+ }
509
+
510
+ /**
511
+ * Pass our BuddyPress activity permalink for embedding.
512
+ *
513
+ * @since 2.6.0
514
+ *
515
+ * @see bp_activity_embed_rest_route_callback()
516
+ *
517
+ * @param string $retval Current embed URL.
518
+ * @return string
519
+ */
520
+ public function filter_embed_url( $retval ) {
521
+ if ( false === isset( buddypress()->{$this->slug_endpoint}->embedurl_in_progress ) && ! $this->is_page() ) {
522
+ return $retval;
523
+ }
524
+
525
+ $url = $this->is_page() ? $this->set_permalink() : buddypress()->{$this->slug_endpoint}->embedurl_in_progress;
526
+ $url = trailingslashit( $url );
527
+
528
+ // This is for the 'WordPress Embed' block
529
+ // @see bp_activity_embed_comments_button().
530
+ if ( 'the_permalink' !== current_filter() ) {
531
+ $url = add_query_arg( 'embed', 'true', trailingslashit( $url ) );
532
+
533
+ // Add custom route args to iframe.
534
+ if ( ! empty( buddypress()->{$this->slug_endpoint}->embedargs_in_progress ) ) {
535
+ foreach( buddypress()->{$this->slug_endpoint}->embedargs_in_progress as $key => $value ) {
536
+ $url = add_query_arg( $key, $value, $url );
537
+ }
538
+ }
539
+ }
540
+
541
+ return $url;
542
+ }
543
+
544
+ /**
545
+ * Filters the embed HTML for our BP oEmbed endpoint.
546
+ *
547
+ * @since 2.6.0
548
+ *
549
+ * @param string $retval Current embed HTML.
550
+ * @return string
551
+ */
552
+ public function filter_embed_html( $retval ) {
553
+ if ( false === isset( buddypress()->{$this->slug_endpoint}->embedurl_in_progress ) && ! $this->is_page() ) {
554
+ return $retval;
555
+ }
556
+
557
+ $url = $this->set_permalink();
558
+
559
+ $item_id = $this->is_page() ? $this->validate_url_to_item_id( $url ) : buddypress()->{$this->slug_endpoint}->embedid_in_progress;
560
+
561
+ // Change 'Embedded WordPress Post' to custom title.
562
+ $custom_title = $this->set_iframe_title( $item_id );
563
+ if ( ! empty( $custom_title ) ) {
564
+ $title_pos = strpos( $retval, 'title=' ) + 7;
565
+ $title_end_pos = strpos( $retval, '"', $title_pos );
566
+
567
+ $retval = substr_replace( $retval, esc_attr( $custom_title ), $title_pos, $title_end_pos - $title_pos );
568
+ }
569
+
570
+ // Add 'max-width' CSS attribute to IFRAME.
571
+ // This will make our oEmbeds responsive.
572
+ if ( false === strpos( $retval, 'style="max-width' ) ) {
573
+ $retval = str_replace( '<iframe', '<iframe style="max-width:100%"', $retval );
574
+ }
575
+
576
+ // Remove default <blockquote>.
577
+ $retval = substr( $retval, strpos( $retval, '</blockquote>' ) + 13 );
578
+
579
+ // Set up new fallback HTML
580
+ // @todo Maybe use KSES?
581
+ $fallback_html = $this->set_fallback_html( $item_id );
582
+
583
+ /**
584
+ * Dynamic filter to return BP oEmbed HTML.
585
+ *
586
+ * @since 2.6.0
587
+ *
588
+ * @var string $retval
589
+ */
590
+ return apply_filters( "bp_{$this->slug_endpoint}_embed_html", $fallback_html . $retval );
591
+ }
592
+
593
+ /**
594
+ * Append our custom slug endpoint to oEmbed endpoint URL.
595
+ *
596
+ * Meant to be used as a filter on 'rest_url' before any call to
597
+ * {@link get_oembed_endpoint_url()} is used.
598
+ *
599
+ * @since 2.6.0
600
+ *
601
+ * @see add_oembed_discovery_links()
602
+ *
603
+ * @param string $retval Current oEmbed endpoint URL.
604
+ * @return string
605
+ */
606
+ public function filter_rest_url( $retval = '' ) {
607
+ return $retval . "/{$this->slug_endpoint}";
608
+ }
609
+
610
+ /**
611
+ * Inject content into the embed template.
612
+ *
613
+ * @since 2.6.0
614
+ */
615
+ public function inject_content() {
616
+ if ( ! $this->is_page() ) {
617
+ return;
618
+ }
619
+
620
+ $this->content();
621
+ }
622
+ }
bp-core/classes/class-bp-core-sort-by-key-callback.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Callback class for bp_sort_by_key().
5
- *
6
- * Used in place of an anonymous closure.
7
- *
8
- * Developers should not use this class directly, as it may be removed once support for PHP 5.2 is dropped.
9
- *
10
- * @ignore
11
- *
12
- * @since 2.5.0
13
- */
14
- class BP_Core_Sort_By_Key_Callback {
15
- /**
16
- * Object/array index to use for sorting.
17
- *
18
- * @since 2.5.0
19
- * @var mixed
20
- */
21
- protected $key;
22
-
23
- /**
24
- * Sort type.
25
- *
26
- * @since 2.5.0
27
- * @var string
28
- */
29
- protected $type;
30
-
31
- /**
32
- * Constructor.
33
- *
34
- * @since 2.5.0
35
- *
36
- * @param mixed $key Object or array index to use for sorting.
37
- * @param string $type Sort type.
38
- */
39
- public function __construct( $key, $type ) {
40
- $this->key = $key;
41
- $this->type = $type;
42
- }
43
-
44
- /**
45
- * Sort callback.
46
- *
47
- * @since 2.5.0
48
- *
49
- * @param $a object|array
50
- * @param $b object|array
51
- * @return int
52
- */
53
- public function sort_callback( $a, $b ) {
54
- $values = array( 0 => false, 1 => false, );
55
- $func_args = func_get_args();
56
- foreach ( $func_args as $indexi => $index ) {
57
- if ( isset( $index->{$this->key} ) ) {
58
- $values[ $indexi ] = $index->{$this->key};
59
- } elseif ( isset( $index[ $this->key ] ) ) {
60
- $values[ $indexi ] = $index[ $this->key ];
61
- }
62
- }
63
-
64
- if ( isset( $values[0], $values[1] ) ) {
65
- if ( 'num' === $this->type ) {
66
- $cmp = $values[0] - $values[1];
67
- } else {
68
- $cmp = strcmp( $values[0], $values[1] );
69
- }
70
-
71
- if ( 0 > $cmp ) {
72
- $retval = -1;
73
- } elseif ( 0 < $cmp ) {
74
- $retval = 1;
75
- } else {
76
- $retval = 0;
77
- }
78
- return $retval;
79
- } else {
80
- return 0;
81
- }
82
- }
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core/classes/class-bp-core-user.php CHANGED
@@ -146,18 +146,6 @@ class BP_Core_User {
146
 
147
  /**
148
  * Populate the instantiated class with data based on the User ID provided.
149
- *
150
- * @uses bp_core_get_userurl() Returns the URL with no HTML markup for
151
- * a user based on their user id.
152
- * @uses bp_core_get_userlink() Returns a HTML formatted link for a
153
- * user with the user's full name as the link text.
154
- * @uses bp_core_get_user_email() Returns the email address for the
155
- * user based on user ID.
156
- * @uses bp_get_user_meta() BP function returns the value of passed
157
- * usermeta name from usermeta table.
158
- * @uses bp_core_fetch_avatar() Returns HTML formatted avatar for a user
159
- * @uses bp_profile_last_updated_date() Returns the last updated date
160
- * for a user.
161
  */
162
  public function populate() {
163
 
@@ -823,6 +811,13 @@ class BP_Core_User {
823
  $retval = array();
824
  foreach ( $user_ids as $user_id ) {
825
  $retval[ $user_id ] = wp_cache_get( $user_id, 'bp_last_activity' );
 
 
 
 
 
 
 
826
  }
827
 
828
  return $retval;
@@ -917,6 +912,16 @@ class BP_Core_User {
917
  // Set cache.
918
  wp_cache_set( $user_id, $activity[ $user_id ], 'bp_last_activity' );
919
 
 
 
 
 
 
 
 
 
 
 
920
  return $updated;
921
  }
922
 
@@ -934,7 +939,7 @@ class BP_Core_User {
934
 
935
  $existing = self::get_last_activity( $user_id );
936
 
937
- if ( empty( $existing ) ) {
938
  return false;
939
  }
940
 
146
 
147
  /**
148
  * Populate the instantiated class with data based on the User ID provided.
 
 
 
 
 
 
 
 
 
 
 
 
149
  */
150
  public function populate() {
151
 
811
  $retval = array();
812
  foreach ( $user_ids as $user_id ) {
813
  $retval[ $user_id ] = wp_cache_get( $user_id, 'bp_last_activity' );
814
+
815
+ if ( isset( $retval['user_id'] ) ) {
816
+ $retval[ $user_id ]['user_id'] = (int) $retval[ $user_id ]['user_id'];
817
+ }
818
+ if ( isset( $retval['activity_id'] ) ) {
819
+ $retval[ $user_id ]['activity_id'] = (int) $retval[ $user_id ]['activity_id'];
820
+ }
821
  }
822
 
823
  return $retval;
912
  // Set cache.
913
  wp_cache_set( $user_id, $activity[ $user_id ], 'bp_last_activity' );
914
 
915
+ /**
916
+ * Fires when a user's last_activity value has been updated.
917
+ *
918
+ * @since 2.7.0
919
+ *
920
+ * @param int $user_id ID of the user.
921
+ * @param string $time Last activity timestamp, in 'Y-m-d H:i:s' format.
922
+ */
923
+ do_action( 'bp_core_user_updated_last_activity', $user_id, $time );
924
+
925
  return $updated;
926
  }
927
 
939
 
940
  $existing = self::get_last_activity( $user_id );
941
 
942
+ if ( empty( $existing ) || empty( $existing[ $user_id ]['activity_id'] ) ) {
943
  return false;
944
  }
945
 
bp-core/classes/class-bp-core.php CHANGED
@@ -24,7 +24,6 @@ class BP_Core extends BP_Component {
24
  *
25
  * @since 1.5.0
26
  *
27
- * @uses BP_Core::bootstrap()
28
  */
29
  public function __construct() {
30
  parent::start(
@@ -254,6 +253,10 @@ class BP_Core extends BP_Component {
254
  // bp-notifications instead.
255
  $bp->core->table_name_notifications = $bp->table_prefix . 'bp_notifications';
256
 
 
 
 
 
257
  /**
258
  * Used to determine if user has admin rights on current content. If the
259
  * logged in user is viewing their own profile and wants to delete
24
  *
25
  * @since 1.5.0
26
  *
 
27
  */
28
  public function __construct() {
29
  parent::start(
253
  // bp-notifications instead.
254
  $bp->core->table_name_notifications = $bp->table_prefix . 'bp_notifications';
255
 
256
+ // Backward compatibility for plugins modifying the legacy bp_nav and bp_options_nav global properties.
257
+ $bp->bp_nav = new BP_Core_BP_Nav_BackCompat();
258
+ $bp->bp_options_nav = new BP_Core_BP_Options_Nav_BackCompat();
259
+
260
  /**
261
  * Used to determine if user has admin rights on current content. If the
262
  * logged in user is viewing their own profile and wants to delete
bp-core/classes/class-bp-email-recipient.php CHANGED
@@ -55,19 +55,23 @@ class BP_Email_Recipient {
55
  public function __construct( $email_or_user, $name = '' ) {
56
  $name = sanitize_text_field( $name );
57
 
58
- // User ID, WP_User object.
59
- if ( is_int( $email_or_user ) || is_object( $email_or_user ) ) {
60
- $this->user_object = is_object( $email_or_user ) ? $email_or_user : get_user_by( 'id', $email_or_user );
61
-
62
- if ( $this->user_object ) {
63
- // This is escaped with esc_html in bp_core_get_user_displayname()
64
- $name = wp_specialchars_decode( bp_core_get_user_displayname( $this->user_object->ID ), ENT_QUOTES );
 
 
 
65
 
66
- $this->address = $this->user_object->user_email;
67
- $this->name = sanitize_text_field( $name );
 
68
  }
69
 
70
- // Array, address, and name.
71
  } else {
72
  if ( ! is_array( $email_or_user ) ) {
73
  $email_or_user = array( $email_or_user => $name );
@@ -80,11 +84,30 @@ class BP_Email_Recipient {
80
  $address = key( $email_or_user );
81
  $name = current( $email_or_user );
82
  }
 
83
 
84
- if ( is_email( $address ) ) {
85
- $this->address = sanitize_email( $address );
86
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
 
 
88
  $this->name = $name;
89
  }
90
 
55
  public function __construct( $email_or_user, $name = '' ) {
56
  $name = sanitize_text_field( $name );
57
 
58
+ // User ID, email address or WP_User object.
59
+ if ( is_int( $email_or_user ) || ( is_string( $email_or_user ) && is_email( $email_or_user ) ) || is_object( $email_or_user ) ) {
60
+ // We already have a WP user.
61
+ if ( is_object( $email_or_user ) ) {
62
+ $this->user_object = $email_or_user;
63
+
64
+ // Query for WP user by user ID.
65
+ } elseif ( is_int( $email_or_user ) ) {
66
+ $this->user_object = get_user_by( 'id', $email_or_user );
67
+ }
68
 
69
+ // Set email address.
70
+ if ( empty( $this->user_object ) && is_email( $email_or_user ) ) {
71
+ $address = $email_or_user;
72
  }
73
 
74
+ // Array or miscellaneous string.
75
  } else {
76
  if ( ! is_array( $email_or_user ) ) {
77
  $email_or_user = array( $email_or_user => $name );
84
  $address = key( $email_or_user );
85
  $name = current( $email_or_user );
86
  }
87
+ }
88
 
89
+ // Set address if we have one.
90
+ if ( ! empty( $address ) ) {
91
+ $this->address = sanitize_email( $address );
92
+ }
93
+
94
+ // Still no user object; try to query user by email address.
95
+ if ( empty( $this->user_object ) ) {
96
+ $this->get_user( 'search-email' );
97
+ }
98
+
99
+ // We have a user object; so set address and name from DB.
100
+ if ( $this->user_object ) {
101
+ // This is escaped with esc_html in bp_core_get_user_displayname()
102
+ $wp_name = wp_specialchars_decode( bp_core_get_user_displayname( $this->user_object->ID ), ENT_QUOTES );
103
+
104
+ $this->address = $this->user_object->user_email;
105
+ $this->name = sanitize_text_field( $wp_name );
106
+
107
+ }
108
 
109
+ // Custom name override.
110
+ if ( $name ) {
111
  $this->name = $name;
112
  }
113
 
bp-core/classes/class-bp-embed.php CHANGED
@@ -75,11 +75,6 @@ class BP_Embed extends WP_Embed {
75
  * enabled, then the URL will be passed to {@link BP_Embed::parse_oembed()}
76
  * for oEmbed parsing.
77
  *
78
- * @uses wp_parse_args()
79
- * @uses wp_embed_defaults()
80
- * @uses current_user_can()
81
- * @uses _wp_oembed_get_object()
82
- * @uses WP_Embed::maybe_make_link()
83
  *
84
  * @param array $attr Shortcode attributes.
85
  * @param string $url The URL attempting to be embeded.
@@ -174,11 +169,7 @@ class BP_Embed extends WP_Embed {
174
  *
175
  * View an example to add support in {@link bp_activity_embed()}.
176
  *
177
- * @uses apply_filters() Filters cache.
178
- * @uses do_action() To save cache.
179
- * @uses wp_oembed_get() Connects to oEmbed provider and returns HTML
180
  * on success.
181
- * @uses WP_Embed::maybe_make_link() Process URL for hyperlinking on
182
  * oEmbed failure.
183
  *
184
  * @param int $id ID to do the caching for.
75
  * enabled, then the URL will be passed to {@link BP_Embed::parse_oembed()}
76
  * for oEmbed parsing.
77
  *
 
 
 
 
 
78
  *
79
  * @param array $attr Shortcode attributes.
80
  * @param string $url The URL attempting to be embeded.
169
  *
170
  * View an example to add support in {@link bp_activity_embed()}.
171
  *
 
 
 
172
  * on success.
 
173
  * oEmbed failure.
174
  *
175
  * @param int $id ID to do the caching for.
bp-core/classes/class-bp-media-extractor.php CHANGED
@@ -469,7 +469,7 @@ class BP_Media_Extractor {
469
  if ( ! empty( $matches[2] ) ) {
470
  foreach ( $matches[2] as $i => $shortcode_name ) {
471
  $attrs = shortcode_parse_atts( $matches[3][ $i ] );
472
- $attrs = ( ! $attrs ) ? array() : $attrs;
473
 
474
  $shortcode = array();
475
  $shortcode['attributes'] = $attrs; // Attributes.
469
  if ( ! empty( $matches[2] ) ) {
470
  foreach ( $matches[2] as $i => $shortcode_name ) {
471
  $attrs = shortcode_parse_atts( $matches[3][ $i ] );
472
+ $attrs = ( ! $attrs ) ? array() : (array) $attrs;
473
 
474
  $shortcode = array();
475
  $shortcode['attributes'] = $attrs; // Attributes.
bp-core/classes/class-bp-phpmailer.php CHANGED
@@ -27,7 +27,18 @@ class BP_PHPMailer implements BP_Email_Delivery {
27
  public function bp_email( BP_Email $email ) {
28
  static $phpmailer = null;
29
 
30
- if ( $phpmailer === null ) {
 
 
 
 
 
 
 
 
 
 
 
31
  if ( ! class_exists( 'PHPMailer' ) ) {
32
  require_once ABSPATH . WPINC . '/class-phpmailer.php';
33
  require_once ABSPATH . WPINC . '/class-smtp.php';
27
  public function bp_email( BP_Email $email ) {
28
  static $phpmailer = null;
29
 
30
+ /**
31
+ * Filter PHPMailer object to use.
32
+ *
33
+ * Specify an alternative version of PHPMailer to use instead of WordPress' default.
34
+ *
35
+ * @since 2.8.0
36
+ *
37
+ * @param null|PHPMailer $phpmailer The phpmailer class.
38
+ */
39
+ $phpmailer = apply_filters( 'bp_phpmailer_object', $phpmailer );
40
+
41
+ if ( ! ( $phpmailer instanceof PHPMailer ) ) {
42
  if ( ! class_exists( 'PHPMailer' ) ) {
43
  require_once ABSPATH . WPINC . '/class-phpmailer.php';
44
  require_once ABSPATH . WPINC . '/class-smtp.php';
bp-core/classes/class-bp-theme-compat.php CHANGED
@@ -50,7 +50,7 @@ class BP_Theme_Compat {
50
  *
51
  * @param array $properties Array of properties for BP_Theme_Compat.
52
  */
53
- public function __construct( Array $properties = array() ) {
54
  $this->_data = $properties;
55
  }
56
 
50
  *
51
  * @param array $properties Array of properties for BP_Theme_Compat.
52
  */
53
+ public function __construct( Array $properties = array() ) {
54
  $this->_data = $properties;
55
  }
56
 
bp-core/classes/class-bp-user-query.php CHANGED
@@ -247,7 +247,7 @@ class BP_User_Query {
247
  // Setup the main SQL query container.
248
  $sql = array(
249
  'select' => '',
250
- 'where' => array(),
251
  'orderby' => '',
252
  'order' => '',
253
  'limit' => ''
@@ -364,7 +364,11 @@ class BP_User_Query {
364
  // 'include' - User ids to include in the results.
365
  $include = false !== $include ? wp_parse_id_list( $include ) : array();
366
  $include_ids = $this->get_include_ids( $include );
367
- if ( ! empty( $include_ids ) ) {
 
 
 
 
368
  $include_ids = implode( ',', wp_parse_id_list( $include_ids ) );
369
  $sql['where'][] = "u.{$this->uid_name} IN ({$include_ids})";
370
  }
@@ -591,11 +595,14 @@ class BP_User_Query {
591
  // Match up to the user ids from the main query.
592
  foreach ( $this->user_ids as $key => $uid ) {
593
  if ( isset( $r[ $uid ] ) ) {
 
 
 
594
  $this->results[ $uid ] = $r[ $uid ];
595
 
596
  // The BP template functions expect an 'id'
597
  // (as opposed to 'ID') property.
598
- $this->results[ $uid ]->id = $uid;
599
 
600
  // Remove user ID from original user_ids property.
601
  } else {
@@ -780,7 +787,7 @@ class BP_User_Query {
780
 
781
  $tax_query = new WP_Tax_Query( array(
782
  array(
783
- 'taxonomy' => 'bp_member_type',
784
  'field' => 'name',
785
  'operator' => $operator,
786
  'terms' => $types,
@@ -788,18 +795,15 @@ class BP_User_Query {
788
  ) );
789
 
790
  // Switch to the root blog, where member type taxonomies live.
 
791
  $switched = false;
792
- if ( ! bp_is_root_blog() ) {
793
- switch_to_blog( bp_get_root_blog_id() );
794
  $switched = true;
795
  }
796
 
797
  $sql_clauses = $tax_query->get_sql( 'u', $this->uid_name );
798
 
799
- if ( $switched ) {
800
- restore_current_blog();
801
- }
802
-
803
  $clause = '';
804
 
805
  // The no_results clauses are the same between IN and NOT IN.
@@ -815,6 +819,10 @@ class BP_User_Query {
815
  $clause = "u.{$this->uid_name} IN ( SELECT object_id FROM $wpdb->term_relationships WHERE {$matches[0]} )";
816
  }
817
 
 
 
 
 
818
  return $clause;
819
  }
820
  }
247
  // Setup the main SQL query container.
248
  $sql = array(
249
  'select' => '',
250
+ 'where' => array('1=1'),
251
  'orderby' => '',
252
  'order' => '',
253
  'limit' => ''
364
  // 'include' - User ids to include in the results.
365
  $include = false !== $include ? wp_parse_id_list( $include ) : array();
366
  $include_ids = $this->get_include_ids( $include );
367
+
368
+ // An array containing nothing but 0 should always fail.
369
+ if ( 1 === count( $include_ids ) && 0 == reset( $include_ids ) ) {
370
+ $sql['where'][] = $this->no_results['where'];
371
+ } elseif ( ! empty( $include_ids ) ) {
372
  $include_ids = implode( ',', wp_parse_id_list( $include_ids ) );
373
  $sql['where'][] = "u.{$this->uid_name} IN ({$include_ids})";
374
  }
595
  // Match up to the user ids from the main query.
596
  foreach ( $this->user_ids as $key => $uid ) {
597
  if ( isset( $r[ $uid ] ) ) {
598
+ $r[ $uid ]->ID = (int) $uid;
599
+ $r[ $uid ]->user_status = (int) $r[ $uid ]->user_status;
600
+
601
  $this->results[ $uid ] = $r[ $uid ];
602
 
603
  // The BP template functions expect an 'id'
604
  // (as opposed to 'ID') property.
605
+ $this->results[ $uid ]->id = (int) $uid;
606
 
607
  // Remove user ID from original user_ids property.
608
  } else {
787
 
788
  $tax_query = new WP_Tax_Query( array(
789
  array(
790
+ 'taxonomy' => bp_get_member_type_tax_name(),
791
  'field' => 'name',
792
  'operator' => $operator,
793
  'terms' => $types,
795
  ) );
796
 
797
  // Switch to the root blog, where member type taxonomies live.
798
+ $site_id = bp_get_taxonomy_term_site_id( bp_get_member_type_tax_name() );
799
  $switched = false;
800
+ if ( $site_id !== get_current_blog_id() ) {
801
+ switch_to_blog( $site_id );
802
  $switched = true;
803
  }
804
 
805
  $sql_clauses = $tax_query->get_sql( 'u', $this->uid_name );
806
 
 
 
 
 
807
  $clause = '';
808
 
809
  // The no_results clauses are the same between IN and NOT IN.
819
  $clause = "u.{$this->uid_name} IN ( SELECT object_id FROM $wpdb->term_relationships WHERE {$matches[0]} )";
820
  }
821
 
822
+ if ( $switched ) {
823
+ restore_current_blog();
824
+ }
825
+
826
  return $clause;
827
  }
828
  }
bp-core/classes/class-bp-walker-category-checklist.php CHANGED
@@ -84,7 +84,7 @@ class BP_Walker_Category_Checklist extends Walker {
84
  } else {
85
  /** This filter is documented in wp-includes/category-template.php */
86
  $output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
87
- '<label class="selectit"><input value="' . $category->slug . '" type="checkbox" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' .
88
  checked( in_array( $category->term_id, $args['selected_cats'] ), true, false ) .
89
  disabled( empty( $args['disabled'] ), false, false ) . ' /> ' .
90
  esc_html( apply_filters( 'the_category', $category->description ) ) . '</label>';
84
  } else {
85
  /** This filter is documented in wp-includes/category-template.php */
86
  $output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" .
87
+ '<label for="in-'.$taxonomy.'-' . $category->term_id . '" class="selectit"><input value="' . $category->slug . '" type="checkbox" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' .
88
  checked( in_array( $category->term_id, $args['selected_cats'] ), true, false ) .
89
  disabled( empty( $args['disabled'] ), false, false ) . ' /> ' .
90
  esc_html( apply_filters( 'the_category', $category->description ) ) . '</label>';
bp-core/classes/class-bp-walker-nav-menu.php CHANGED
@@ -55,9 +55,7 @@ class BP_Walker_Nav_Menu extends Walker_Nav_Menu {
55
  * @return string See {@link Walker::walk()}.
56
  */
57
  public function walk( $elements, $max_depth ) {
58
- $func_args = func_get_args();
59
-
60
- $args = array_slice( $func_args, 2 );
61
  $output = '';
62
 
63
  if ( $max_depth < -1 ) // Invalid parameter.
55
  * @return string See {@link Walker::walk()}.
56
  */
57
  public function walk( $elements, $max_depth ) {
58
+ $args = array_slice( func_get_args(), 2 );
 
 
59
  $output = '';
60
 
61
  if ( $max_depth < -1 ) // Invalid parameter.
bp-core/css/admin-bar-rtl.css CHANGED
@@ -24,7 +24,7 @@
24
  #wpadminbar .quicklinks li#wp-admin-bar-my-account a span.count,
25
  #wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a span.count,
26
  #wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications {
27
- background: #21759B;
28
  color: #fff;
29
  text-shadow: none;
30
  display: inline;
@@ -44,7 +44,7 @@
44
  }
45
 
46
  #wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications.alert {
47
- background-color: #1fb3dd;
48
  color: #fff;
49
  }
50
 
@@ -56,3 +56,16 @@
56
  height: 64px;
57
  width: 64px;
58
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  #wpadminbar .quicklinks li#wp-admin-bar-my-account a span.count,
25
  #wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a span.count,
26
  #wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications {
27
+ background: #21759b;
28
  color: #fff;
29
  text-shadow: none;
30
  display: inline;
44
  }
45
 
46
  #wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications.alert {
47
+ background-color: #21759b;
48
  color: #fff;
49
  }
50
 
56
  height: 64px;
57
  width: 64px;
58
  }
59
+
60
+ /* Remove additional arrows from appearing on the BuddyPress' `my_account_menu`
61
+ * on large screens. Add back arrows for screen widths 600px and lower.
62
+ */
63
+ #wpadminbar .wp-admin-bar-arrow-right {
64
+ display: none;
65
+ }
66
+
67
+ @media screen and (max-width: 600px) {
68
+ #wpadminbar .wp-admin-bar-arrow-right {
69
+ display: block;
70
+ }
71
+ }
bp-core/css/admin-bar-rtl.min.css CHANGED
@@ -1 +1 @@
1
- #wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar>a img,#wpadminbar .quicklinks li#wp-admin-bar-user-admin-with-avatar>a img{width:16px;height:16px;display:inline;border:1px solid #999;vertical-align:middle;margin:-2px -5px 0 10px;padding:0;background:#eee;float:none}#wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar ul,#wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar ul ul{right:0}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications,#wpadminbar .quicklinks li#wp-admin-bar-my-account a span.count,#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a span.count{background:#21759B;color:#fff;text-shadow:none;display:inline;padding:2px 5px;font-size:10px;font-weight:700;-moz-border-radius:10px;-khtml-border-radius:10px;-webkit-border-radius:10px;border-radius:10px}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications{background:#ddd;color:#333;margin:0}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications.alert{background-color:#1fb3dd;color:#fff}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications>a{padding:0 .5em}#wp-admin-bar-user-info img.avatar{height:64px;width:64px}
1
+ #wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar>a img,#wpadminbar .quicklinks li#wp-admin-bar-user-admin-with-avatar>a img{width:16px;height:16px;display:inline;border:1px solid #999;vertical-align:middle;margin:-2px -5px 0 10px;padding:0;background:#eee;float:none}#wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar ul,#wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar ul ul{right:0}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications,#wpadminbar .quicklinks li#wp-admin-bar-my-account a span.count,#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a span.count{background:#21759b;color:#fff;text-shadow:none;display:inline;padding:2px 5px;font-size:10px;font-weight:700;-moz-border-radius:10px;-khtml-border-radius:10px;-webkit-border-radius:10px;border-radius:10px}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications{background:#ddd;color:#333;margin:0}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications.alert{background-color:#21759b;color:#fff}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications>a{padding:0 .5em}#wp-admin-bar-user-info img.avatar{height:64px;width:64px}#wpadminbar .wp-admin-bar-arrow-right{display:none}@media screen and (max-width:600px){#wpadminbar .wp-admin-bar-arrow-right{display:block}}
bp-core/css/admin-bar.css CHANGED
@@ -24,7 +24,7 @@
24
  #wpadminbar .quicklinks li#wp-admin-bar-my-account a span.count,
25
  #wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a span.count,
26
  #wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications {
27
- background: #21759B;
28
  color: #fff;
29
  text-shadow: none;
30
  display: inline;
@@ -44,7 +44,7 @@
44
  }
45
 
46
  #wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications.alert {
47
- background-color: #1fb3dd;
48
  color: #fff;
49
  }
50
 
@@ -56,3 +56,16 @@
56
  height: 64px;
57
  width: 64px;
58
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  #wpadminbar .quicklinks li#wp-admin-bar-my-account a span.count,
25
  #wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a span.count,
26
  #wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications {
27
+ background: #21759b;
28
  color: #fff;
29
  text-shadow: none;
30
  display: inline;
44
  }
45
 
46
  #wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications.alert {
47
+ background-color: #21759b;
48
  color: #fff;
49
  }
50
 
56
  height: 64px;
57
  width: 64px;
58
  }
59
+
60
+ /* Remove additional arrows from appearing on the BuddyPress' `my_account_menu`
61
+ * on large screens. Add back arrows for screen widths 600px and lower.
62
+ */
63
+ #wpadminbar .wp-admin-bar-arrow-right {
64
+ display: none;
65
+ }
66
+
67
+ @media screen and (max-width: 600px) {
68
+ #wpadminbar .wp-admin-bar-arrow-right {
69
+ display: block;
70
+ }
71
+ }
bp-core/css/admin-bar.min.css CHANGED
@@ -1 +1 @@
1
- #wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar>a img,#wpadminbar .quicklinks li#wp-admin-bar-user-admin-with-avatar>a img{width:16px;height:16px;display:inline;border:1px solid #999;vertical-align:middle;margin:-2px 10px 0 -5px;padding:0;background:#eee;float:none}#wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar ul,#wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar ul ul{left:0}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications,#wpadminbar .quicklinks li#wp-admin-bar-my-account a span.count,#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a span.count{background:#21759B;color:#fff;text-shadow:none;display:inline;padding:2px 5px;font-size:10px;font-weight:700;-moz-border-radius:10px;-khtml-border-radius:10px;-webkit-border-radius:10px;border-radius:10px}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications{background:#ddd;color:#333;margin:0}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications.alert{background-color:#1fb3dd;color:#fff}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications>a{padding:0 .5em}#wp-admin-bar-user-info img.avatar{height:64px;width:64px}
1
+ #wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar>a img,#wpadminbar .quicklinks li#wp-admin-bar-user-admin-with-avatar>a img{width:16px;height:16px;display:inline;border:1px solid #999;vertical-align:middle;margin:-2px 10px 0 -5px;padding:0;background:#eee;float:none}#wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar ul,#wpadminbar .quicklinks li#wp-admin-bar-group-admin-with-avatar ul ul{left:0}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications,#wpadminbar .quicklinks li#wp-admin-bar-my-account a span.count,#wpadminbar .quicklinks li#wp-admin-bar-my-account-with-avatar a span.count{background:#21759b;color:#fff;text-shadow:none;display:inline;padding:2px 5px;font-size:10px;font-weight:700;-moz-border-radius:10px;-khtml-border-radius:10px;-webkit-border-radius:10px;border-radius:10px}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications{background:#ddd;color:#333;margin:0}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications #ab-pending-notifications.alert{background-color:#21759b;color:#fff}#wpadminbar .quicklinks li#wp-admin-bar-bp-notifications>a{padding:0 .5em}#wp-admin-bar-user-info img.avatar{height:64px;width:64px}#wpadminbar .wp-admin-bar-arrow-right{display:none}@media screen and (max-width:600px){#wpadminbar .wp-admin-bar-arrow-right{display:block}}
bp-core/css/avatar-rtl.css CHANGED
@@ -142,7 +142,17 @@ div.bp-avatar-nav {
142
 
143
  .drag-drop .drag-drop-inside p.drag-drop-buttons {
144
  margin: auto;
145
- text-align: auto;
 
 
 
 
 
 
 
 
 
 
146
  }
147
 
148
  .drag-drop #drag-drop-area {
@@ -164,8 +174,12 @@ div.bp-avatar-nav {
164
  display: block;
165
  }
166
 
 
 
 
 
167
  .drag-drop .drag-drop-inside p {
168
- color: #aaa;
169
  font-size: 110%;
170
  margin: 5px 0;
171
  text-align: center;
142
 
143
  .drag-drop .drag-drop-inside p.drag-drop-buttons {
144
  margin: auto;
145
+ text-align: inherit;
146
+ }
147
+
148
+ .moxie-shim.moxie-shim-html5 {
149
+ top: 108px !important;
150
+ right: 40.1% !important;
151
+ width: 12em;
152
+ }
153
+
154
+ .moxie-shim.moxie-shim-html5 input {
155
+ cursor: pointer;
156
  }
157
 
158
  .drag-drop #drag-drop-area {
174
  display: block;
175
  }
176
 
177
+ p.drag-drop-buttons input#bp-browse-button {
178
+ width: 12em;
179
+ }
180
+
181
  .drag-drop .drag-drop-inside p {
182
+ color: #767676;
183
  font-size: 110%;
184
  margin: 5px 0;
185
  text-align: center;
bp-core/css/avatar-rtl.min.css CHANGED
@@ -1 +1 @@
1
- div.bp-avatar-status,div.bp-cover-image-status{clear:both;margin:1em 0}div.bp-avatar-status p.updated,div.bp-cover-image-status p.updated{display:block;padding:10px 15px}div.bp-avatar-status p.success,div.bp-cover-image-status p.success{background-color:#efc;border:1px solid #591;color:#250}div.bp-avatar-status p.error,div.bp-cover-image-status p.error{background-color:#fdc;border:1px solid #a00;color:#800}div.bp-avatar-status .bp-progress,div.bp-cover-image-status .bp-progress{background:0 0;border:1px solid #d1d1d1;float:left;height:22px;line-height:2em;margin:6px 0 2px 10px;padding:0;overflow:hidden;width:200px}div.bp-avatar-status .bp-bar,div.bp-cover-image-status .bp-bar{background-color:#c3ff88;width:0;height:100%;z-index:9}.bp-uploader-progress div.error{background-color:#fdc;border:1px solid #a00;color:#800;display:block;font-size:90%;padding:10px 15px}#buddypress p.warning,body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning{background-color:#ffd;border:1px solid #cb2;color:#440;display:block;font-size:90%;margin:1em 0;padding:10px 15px}div.bp-avatar-nav{background:0 0;clear:both;margin:10px 0;overflow:hidden}.avatar-nav-items{margin:0;padding:0}.bp-avatar-nav .avatar-nav-items li.avatar-nav-item{float:right!important;margin:0;list-style:none}.avatar-nav-items li a{display:block;padding:5px 10px;text-decoration:none}.bp-avatar-nav ul:after,.bp-avatar-nav ul:before{content:" ";display:table}.bp-avatar-nav ul:after{clear:both}.bp-avatar-nav ul{border-bottom:1px solid #ccc;margin-bottom:10px}.bp-avatar-nav ul.avatar-nav-items li.current{border:1px solid #ccc;border-bottom-color:#fff;border-top-right-radius:4px;border-top-left-radius:4px;margin-bottom:-1px}.bp-avatar-nav li.current a{background:0 0;color:inherit;font-weight:700;opacity:.8;outline:0}#drag-drop-area{border:4px dashed #bbb;height:200px}.drag-drop.drag-over #drag-drop-area{border-color:#83b4d8}.drag-drop-inside p{display:none}.drag-drop-inside p.drag-drop-buttons{margin-top:80px;text-align:center}.drag-drop .drag-drop-inside p.drag-drop-buttons{margin:auto;text-align:auto}.drag-drop #drag-drop-area{box-sizing:border-box;display:table;height:100%;width:100%}.drag-drop .drag-drop-inside{display:table-cell;padding:40px 0;text-align:center;vertical-align:middle}.drag-drop .drag-drop-inside p,.drag-drop-inside p.drag-drop-buttons{display:block}.drag-drop .drag-drop-inside p{color:#aaa;font-size:110%;margin:5px 0;text-align:center}.drag-drop-inside p.drag-drop-info{margin-top:0}@supports (-ms-accelerator:true){.drag-drop-inside p.drag-drop-info{display:block}}#avatar-to-crop{margin:0 auto 20px;text-align:right}#bp-webcam-avatar #avatar-to-crop{float:right;margin:0 0 20px}#avatar-to-crop .jcrop-holder{margin:0 auto}.avatar-crop-management{clear:right;overflow:hidden;padding-top:20px;text-align:center}#bp-webcam-avatar .avatar-crop-management{clear:none;float:none;overflow:visible;padding-top:0;width:auto}#avatar-crop-pane{margin:0 auto;overflow:hidden}#bp-webcam-avatar #avatar-to-crop{border:1px solid #eee;max-width:100%;width:100%}@media screen and (min-width:801px){#bp-webcam-avatar #avatar-to-crop{max-width:64%;width:64%}}#avatar-crop-actions a{display:block}#bp-webcam-avatar #avatar-crop-actions{float:right;margin:0 0 20px;width:50%}#avatar-crop-actions a.button{margin-top:10px}#bp-webcam-avatar #avatar-crop-actions a.button{display:block;margin:0 0 5px;padding:4px 0;width:100%}#avatar-crop-pane canvas,#avatar-crop-pane img,#avatar-to-crop img,#avatar-upload-form img,#create-group-form img,#group-settings-form img{border:none!important;max-width:none!important}#bp-webcam-avatar video{float:right;margin-bottom:0;max-width:100%;width:100%;-webkit-transform:scaleX(-1);transform:scaleX(-1)}#bp-webcam-avatar #avatar-crop-pane{border:2px dashed #bbb;clear:right;float:left;margin:0 0 10px 40px;overflow:hidden}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{max-width:150px;max-height:150px}#avatar-crop-pane canvas{height:auto;width:100%;max-width:100%}.group-avatar .bp-avatar .avatar-crop-management{margin-right:0;padding-top:0;width:auto}.bp-avatar .item{overflow:hidden}.bp-avatar .avatar-crop-management.adjust{float:right;clear:none;padding-top:0}.bp-avatar #avatar-to-crop.adjust{float:right;margin-left:20px}@media screen and (max-width:480px){#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions,#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{float:none}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{margin:0 auto 10px}#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions{width:auto}}@media screen and (min-width:801px){#bp-webcam-avatar .avatar-crop-management{clear:none;float:left}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{float:none;margin:0 auto 10px}#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions{float:right;width:100%}}body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent{height:95%!important;width:95%!important}body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.updated,body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.updated,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning{display:block;padding:10px 15px}.wp-admin #TB_window .bp-avatar #avatar-to-crop{float:right;margin:0}.wp-admin #TB_window .bp-avatar #bp-webcam-avatar #avatar-to-crop{margin-bottom:20px}@media screen and (min-width:783px){.wp-admin #TB_window .bp-avatar .avatar-crop-management{clear:none;float:right;margin-right:20px;padding-top:0;text-align:center}}.wp-admin #TB_window .bp-avatar #avatar-to-crop video{width:100%}.wp-admin #TB_window .bp-avatar .avatar-crop-management a.button{height:auto;line-height:inherit}@media screen and (min-width:810px){.wp-admin #TB_window .bp-avatar #bp-webcam-avatar #avatar-to-crop{max-width:none;width:76%}.wp-admin #TB_window #bp-webcam-avatar .avatar-crop-management{max-width:none;width:auto}}
1
+ div.bp-avatar-status,div.bp-cover-image-status{clear:both;margin:1em 0}div.bp-avatar-status p.updated,div.bp-cover-image-status p.updated{display:block;padding:10px 15px}div.bp-avatar-status p.success,div.bp-cover-image-status p.success{background-color:#efc;border:1px solid #591;color:#250}div.bp-avatar-status p.error,div.bp-cover-image-status p.error{background-color:#fdc;border:1px solid #a00;color:#800}div.bp-avatar-status .bp-progress,div.bp-cover-image-status .bp-progress{background:0 0;border:1px solid #d1d1d1;float:left;height:22px;line-height:2em;margin:6px 0 2px 10px;padding:0;overflow:hidden;width:200px}div.bp-avatar-status .bp-bar,div.bp-cover-image-status .bp-bar{background-color:#c3ff88;width:0;height:100%;z-index:9}.bp-uploader-progress div.error{background-color:#fdc;border:1px solid #a00;color:#800;display:block;font-size:90%;padding:10px 15px}#buddypress p.warning,body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning{background-color:#ffd;border:1px solid #cb2;color:#440;display:block;font-size:90%;margin:1em 0;padding:10px 15px}div.bp-avatar-nav{background:0 0;clear:both;margin:10px 0;overflow:hidden}.avatar-nav-items{margin:0;padding:0}.bp-avatar-nav .avatar-nav-items li.avatar-nav-item{float:right!important;margin:0;list-style:none}.avatar-nav-items li a{display:block;padding:5px 10px;text-decoration:none}.bp-avatar-nav ul:after,.bp-avatar-nav ul:before{content:" ";display:table}.bp-avatar-nav ul:after{clear:both}.bp-avatar-nav ul{border-bottom:1px solid #ccc;margin-bottom:10px}.bp-avatar-nav ul.avatar-nav-items li.current{border:1px solid #ccc;border-bottom-color:#fff;border-top-right-radius:4px;border-top-left-radius:4px;margin-bottom:-1px}.bp-avatar-nav li.current a{background:0 0;color:inherit;font-weight:700;opacity:.8;outline:0}#drag-drop-area{border:4px dashed #bbb;height:200px}.drag-drop.drag-over #drag-drop-area{border-color:#83b4d8}.drag-drop-inside p{display:none}.drag-drop-inside p.drag-drop-buttons{margin-top:80px;text-align:center}.drag-drop .drag-drop-inside p.drag-drop-buttons{margin:auto;text-align:inherit}.moxie-shim.moxie-shim-html5{top:108px!important;right:40.1%!important;width:12em}.moxie-shim.moxie-shim-html5 input{cursor:pointer}.drag-drop #drag-drop-area{box-sizing:border-box;display:table;height:100%;width:100%}.drag-drop .drag-drop-inside{display:table-cell;padding:40px 0;text-align:center;vertical-align:middle}.drag-drop .drag-drop-inside p,.drag-drop-inside p.drag-drop-buttons{display:block}p.drag-drop-buttons input#bp-browse-button{width:12em}.drag-drop .drag-drop-inside p{color:#767676;font-size:110%;margin:5px 0;text-align:center}.drag-drop-inside p.drag-drop-info{margin-top:0}@supports (-ms-accelerator:true){.drag-drop-inside p.drag-drop-info{display:block}}#avatar-to-crop{margin:0 auto 20px;text-align:right}#bp-webcam-avatar #avatar-to-crop{float:right;margin:0 0 20px}#avatar-to-crop .jcrop-holder{margin:0 auto}.avatar-crop-management{clear:right;overflow:hidden;padding-top:20px;text-align:center}#bp-webcam-avatar .avatar-crop-management{clear:none;float:none;overflow:visible;padding-top:0;width:auto}#avatar-crop-pane{margin:0 auto;overflow:hidden}#bp-webcam-avatar #avatar-to-crop{border:1px solid #eee;max-width:100%;width:100%}@media screen and (min-width:801px){#bp-webcam-avatar #avatar-to-crop{max-width:64%;width:64%}}#avatar-crop-actions a{display:block}#bp-webcam-avatar #avatar-crop-actions{float:right;margin:0 0 20px;width:50%}#avatar-crop-actions a.button{margin-top:10px}#bp-webcam-avatar #avatar-crop-actions a.button{display:block;margin:0 0 5px;padding:4px 0;width:100%}#avatar-crop-pane canvas,#avatar-crop-pane img,#avatar-to-crop img,#avatar-upload-form img,#create-group-form img,#group-settings-form img{border:none!important;max-width:none!important}#bp-webcam-avatar video{float:right;margin-bottom:0;max-width:100%;width:100%;-webkit-transform:scaleX(-1);transform:scaleX(-1)}#bp-webcam-avatar #avatar-crop-pane{border:2px dashed #bbb;clear:right;float:left;margin:0 0 10px 40px;overflow:hidden}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{max-width:150px;max-height:150px}#avatar-crop-pane canvas{height:auto;width:100%;max-width:100%}.group-avatar .bp-avatar .avatar-crop-management{margin-right:0;padding-top:0;width:auto}.bp-avatar .item{overflow:hidden}.bp-avatar .avatar-crop-management.adjust{float:right;clear:none;padding-top:0}.bp-avatar #avatar-to-crop.adjust{float:right;margin-left:20px}@media screen and (max-width:480px){#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions,#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{float:none}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{margin:0 auto 10px}#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions{width:auto}}@media screen and (min-width:801px){#bp-webcam-avatar .avatar-crop-management{clear:none;float:left}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{float:none;margin:0 auto 10px}#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions{float:right;width:100%}}body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent{height:95%!important;width:95%!important}body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.updated,body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.updated,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning{display:block;padding:10px 15px}.wp-admin #TB_window .bp-avatar #avatar-to-crop{float:right;margin:0}.wp-admin #TB_window .bp-avatar #bp-webcam-avatar #avatar-to-crop{margin-bottom:20px}@media screen and (min-width:783px){.wp-admin #TB_window .bp-avatar .avatar-crop-management{clear:none;float:right;margin-right:20px;padding-top:0;text-align:center}}.wp-admin #TB_window .bp-avatar #avatar-to-crop video{width:100%}.wp-admin #TB_window .bp-avatar .avatar-crop-management a.button{height:auto;line-height:inherit}@media screen and (min-width:810px){.wp-admin #TB_window .bp-avatar #bp-webcam-avatar #avatar-to-crop{max-width:none;width:76%}.wp-admin #TB_window #bp-webcam-avatar .avatar-crop-management{max-width:none;width:auto}}
bp-core/css/avatar.css CHANGED
@@ -142,7 +142,17 @@ div.bp-avatar-nav {
142
 
143
  .drag-drop .drag-drop-inside p.drag-drop-buttons {
144
  margin: auto;
145
- text-align: auto;
 
 
 
 
 
 
 
 
 
 
146
  }
147
 
148
  .drag-drop #drag-drop-area {
@@ -164,8 +174,12 @@ div.bp-avatar-nav {
164
  display: block;
165
  }
166
 
 
 
 
 
167
  .drag-drop .drag-drop-inside p {
168
- color: #aaa;
169
  font-size: 110%;
170
  margin: 5px 0;
171
  text-align: center;
142
 
143
  .drag-drop .drag-drop-inside p.drag-drop-buttons {
144
  margin: auto;
145
+ text-align: inherit;
146
+ }
147
+
148
+ .moxie-shim.moxie-shim-html5 {
149
+ top: 108px !important;
150
+ left: 40.1% !important;
151
+ width: 12em;
152
+ }
153
+
154
+ .moxie-shim.moxie-shim-html5 input {
155
+ cursor: pointer;
156
  }
157
 
158
  .drag-drop #drag-drop-area {
174
  display: block;
175
  }
176
 
177
+ p.drag-drop-buttons input#bp-browse-button {
178
+ width: 12em;
179
+ }
180
+
181
  .drag-drop .drag-drop-inside p {
182
+ color: #767676;
183
  font-size: 110%;
184
  margin: 5px 0;
185
  text-align: center;
bp-core/css/avatar.min.css CHANGED
@@ -1 +1 @@
1
- div.bp-avatar-status,div.bp-cover-image-status{clear:both;margin:1em 0}div.bp-avatar-status p.updated,div.bp-cover-image-status p.updated{display:block;padding:10px 15px}div.bp-avatar-status p.success,div.bp-cover-image-status p.success{background-color:#efc;border:1px solid #591;color:#250}div.bp-avatar-status p.error,div.bp-cover-image-status p.error{background-color:#fdc;border:1px solid #a00;color:#800}div.bp-avatar-status .bp-progress,div.bp-cover-image-status .bp-progress{background:0 0;border:1px solid #d1d1d1;float:right;height:22px;line-height:2em;margin:6px 10px 2px 0;padding:0;overflow:hidden;width:200px}div.bp-avatar-status .bp-bar,div.bp-cover-image-status .bp-bar{background-color:#c3ff88;width:0;height:100%;z-index:9}.bp-uploader-progress div.error{background-color:#fdc;border:1px solid #a00;color:#800;display:block;font-size:90%;padding:10px 15px}#buddypress p.warning,body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning{background-color:#ffd;border:1px solid #cb2;color:#440;display:block;font-size:90%;margin:1em 0;padding:10px 15px}div.bp-avatar-nav{background:0 0;clear:both;margin:10px 0;overflow:hidden}.avatar-nav-items{margin:0;padding:0}.bp-avatar-nav .avatar-nav-items li.avatar-nav-item{float:left!important;margin:0;list-style:none}.avatar-nav-items li a{display:block;padding:5px 10px;text-decoration:none}.bp-avatar-nav ul:after,.bp-avatar-nav ul:before{content:" ";display:table}.bp-avatar-nav ul:after{clear:both}.bp-avatar-nav ul{border-bottom:1px solid #ccc;margin-bottom:10px}.bp-avatar-nav ul.avatar-nav-items li.current{border:1px solid #ccc;border-bottom-color:#fff;border-top-left-radius:4px;border-top-right-radius:4px;margin-bottom:-1px}.bp-avatar-nav li.current a{background:0 0;color:inherit;font-weight:700;opacity:.8;outline:0}#drag-drop-area{border:4px dashed #bbb;height:200px}.drag-drop.drag-over #drag-drop-area{border-color:#83b4d8}.drag-drop-inside p{display:none}.drag-drop-inside p.drag-drop-buttons{margin-top:80px;text-align:center}.drag-drop .drag-drop-inside p.drag-drop-buttons{margin:auto;text-align:auto}.drag-drop #drag-drop-area{box-sizing:border-box;display:table;height:100%;width:100%}.drag-drop .drag-drop-inside{display:table-cell;padding:40px 0;text-align:center;vertical-align:middle}.drag-drop .drag-drop-inside p,.drag-drop-inside p.drag-drop-buttons{display:block}.drag-drop .drag-drop-inside p{color:#aaa;font-size:110%;margin:5px 0;text-align:center}.drag-drop-inside p.drag-drop-info{margin-top:0}@supports (-ms-accelerator:true){.drag-drop-inside p.drag-drop-info{display:block}}#avatar-to-crop{margin:0 auto 20px;text-align:left}#bp-webcam-avatar #avatar-to-crop{float:left;margin:0 0 20px}#avatar-to-crop .jcrop-holder{margin:0 auto}.avatar-crop-management{clear:left;overflow:hidden;padding-top:20px;text-align:center}#bp-webcam-avatar .avatar-crop-management{clear:none;float:none;overflow:visible;padding-top:0;width:auto}#avatar-crop-pane{margin:0 auto;overflow:hidden}#bp-webcam-avatar #avatar-to-crop{border:1px solid #eee;max-width:100%;width:100%}@media screen and (min-width:801px){#bp-webcam-avatar #avatar-to-crop{max-width:64%;width:64%}}#avatar-crop-actions a{display:block}#bp-webcam-avatar #avatar-crop-actions{float:left;margin:0 0 20px;width:50%}#avatar-crop-actions a.button{margin-top:10px}#bp-webcam-avatar #avatar-crop-actions a.button{display:block;margin:0 0 5px;padding:4px 0;width:100%}#avatar-crop-pane canvas,#avatar-crop-pane img,#avatar-to-crop img,#avatar-upload-form img,#create-group-form img,#group-settings-form img{border:none!important;max-width:none!important}#bp-webcam-avatar video{float:left;margin-bottom:0;max-width:100%;width:100%;-webkit-transform:scaleX(-1);transform:scaleX(-1)}#bp-webcam-avatar #avatar-crop-pane{border:2px dashed #bbb;clear:left;float:right;margin:0 40px 10px 0;overflow:hidden}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{max-width:150px;max-height:150px}#avatar-crop-pane canvas{height:auto;width:100%;max-width:100%}.group-avatar .bp-avatar .avatar-crop-management{margin-left:0;padding-top:0;width:auto}.bp-avatar .item{overflow:hidden}.bp-avatar .avatar-crop-management.adjust{float:left;clear:none;padding-top:0}.bp-avatar #avatar-to-crop.adjust{float:left;margin-right:20px}@media screen and (max-width:480px){#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions,#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{float:none}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{margin:0 auto 10px}#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions{width:auto}}@media screen and (min-width:801px){#bp-webcam-avatar .avatar-crop-management{clear:none;float:right}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{float:none;margin:0 auto 10px}#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions{float:left;width:100%}}body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent{height:95%!important;width:95%!important}body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.updated,body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.updated,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning{display:block;padding:10px 15px}.wp-admin #TB_window .bp-avatar #avatar-to-crop{float:left;margin:0}.wp-admin #TB_window .bp-avatar #bp-webcam-avatar #avatar-to-crop{margin-bottom:20px}@media screen and (min-width:783px){.wp-admin #TB_window .bp-avatar .avatar-crop-management{clear:none;float:left;margin-left:20px;padding-top:0;text-align:center}}.wp-admin #TB_window .bp-avatar #avatar-to-crop video{width:100%}.wp-admin #TB_window .bp-avatar .avatar-crop-management a.button{height:auto;line-height:inherit}@media screen and (min-width:810px){.wp-admin #TB_window .bp-avatar #bp-webcam-avatar #avatar-to-crop{max-width:none;width:76%}.wp-admin #TB_window #bp-webcam-avatar .avatar-crop-management{max-width:none;width:auto}}
1
+ div.bp-avatar-status,div.bp-cover-image-status{clear:both;margin:1em 0}div.bp-avatar-status p.updated,div.bp-cover-image-status p.updated{display:block;padding:10px 15px}div.bp-avatar-status p.success,div.bp-cover-image-status p.success{background-color:#efc;border:1px solid #591;color:#250}div.bp-avatar-status p.error,div.bp-cover-image-status p.error{background-color:#fdc;border:1px solid #a00;color:#800}div.bp-avatar-status .bp-progress,div.bp-cover-image-status .bp-progress{background:0 0;border:1px solid #d1d1d1;float:right;height:22px;line-height:2em;margin:6px 10px 2px 0;padding:0;overflow:hidden;width:200px}div.bp-avatar-status .bp-bar,div.bp-cover-image-status .bp-bar{background-color:#c3ff88;width:0;height:100%;z-index:9}.bp-uploader-progress div.error{background-color:#fdc;border:1px solid #a00;color:#800;display:block;font-size:90%;padding:10px 15px}#buddypress p.warning,body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning{background-color:#ffd;border:1px solid #cb2;color:#440;display:block;font-size:90%;margin:1em 0;padding:10px 15px}div.bp-avatar-nav{background:0 0;clear:both;margin:10px 0;overflow:hidden}.avatar-nav-items{margin:0;padding:0}.bp-avatar-nav .avatar-nav-items li.avatar-nav-item{float:left!important;margin:0;list-style:none}.avatar-nav-items li a{display:block;padding:5px 10px;text-decoration:none}.bp-avatar-nav ul:after,.bp-avatar-nav ul:before{content:" ";display:table}.bp-avatar-nav ul:after{clear:both}.bp-avatar-nav ul{border-bottom:1px solid #ccc;margin-bottom:10px}.bp-avatar-nav ul.avatar-nav-items li.current{border:1px solid #ccc;border-bottom-color:#fff;border-top-left-radius:4px;border-top-right-radius:4px;margin-bottom:-1px}.bp-avatar-nav li.current a{background:0 0;color:inherit;font-weight:700;opacity:.8;outline:0}#drag-drop-area{border:4px dashed #bbb;height:200px}.drag-drop.drag-over #drag-drop-area{border-color:#83b4d8}.drag-drop-inside p{display:none}.drag-drop-inside p.drag-drop-buttons{margin-top:80px;text-align:center}.drag-drop .drag-drop-inside p.drag-drop-buttons{margin:auto;text-align:inherit}.moxie-shim.moxie-shim-html5{top:108px!important;left:40.1%!important;width:12em}.moxie-shim.moxie-shim-html5 input{cursor:pointer}.drag-drop #drag-drop-area{box-sizing:border-box;display:table;height:100%;width:100%}.drag-drop .drag-drop-inside{display:table-cell;padding:40px 0;text-align:center;vertical-align:middle}.drag-drop .drag-drop-inside p,.drag-drop-inside p.drag-drop-buttons{display:block}p.drag-drop-buttons input#bp-browse-button{width:12em}.drag-drop .drag-drop-inside p{color:#767676;font-size:110%;margin:5px 0;text-align:center}.drag-drop-inside p.drag-drop-info{margin-top:0}@supports (-ms-accelerator:true){.drag-drop-inside p.drag-drop-info{display:block}}#avatar-to-crop{margin:0 auto 20px;text-align:left}#bp-webcam-avatar #avatar-to-crop{float:left;margin:0 0 20px}#avatar-to-crop .jcrop-holder{margin:0 auto}.avatar-crop-management{clear:left;overflow:hidden;padding-top:20px;text-align:center}#bp-webcam-avatar .avatar-crop-management{clear:none;float:none;overflow:visible;padding-top:0;width:auto}#avatar-crop-pane{margin:0 auto;overflow:hidden}#bp-webcam-avatar #avatar-to-crop{border:1px solid #eee;max-width:100%;width:100%}@media screen and (min-width:801px){#bp-webcam-avatar #avatar-to-crop{max-width:64%;width:64%}}#avatar-crop-actions a{display:block}#bp-webcam-avatar #avatar-crop-actions{float:left;margin:0 0 20px;width:50%}#avatar-crop-actions a.button{margin-top:10px}#bp-webcam-avatar #avatar-crop-actions a.button{display:block;margin:0 0 5px;padding:4px 0;width:100%}#avatar-crop-pane canvas,#avatar-crop-pane img,#avatar-to-crop img,#avatar-upload-form img,#create-group-form img,#group-settings-form img{border:none!important;max-width:none!important}#bp-webcam-avatar video{float:left;margin-bottom:0;max-width:100%;width:100%;-webkit-transform:scaleX(-1);transform:scaleX(-1)}#bp-webcam-avatar #avatar-crop-pane{border:2px dashed #bbb;clear:left;float:right;margin:0 40px 10px 0;overflow:hidden}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{max-width:150px;max-height:150px}#avatar-crop-pane canvas{height:auto;width:100%;max-width:100%}.group-avatar .bp-avatar .avatar-crop-management{margin-left:0;padding-top:0;width:auto}.bp-avatar .item{overflow:hidden}.bp-avatar .avatar-crop-management.adjust{float:left;clear:none;padding-top:0}.bp-avatar #avatar-to-crop.adjust{float:left;margin-right:20px}@media screen and (max-width:480px){#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions,#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{float:none}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{margin:0 auto 10px}#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions{width:auto}}@media screen and (min-width:801px){#bp-webcam-avatar .avatar-crop-management{clear:none;float:right}#bp-webcam-avatar .avatar-crop-management #avatar-crop-pane{float:none;margin:0 auto 10px}#bp-webcam-avatar .avatar-crop-management #avatar-crop-actions{float:left;width:100%}}body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent{height:95%!important;width:95%!important}body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.updated,body.profile_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.updated,body.users_page_bp-profile-edit.modal-open #TB_ajaxContent p.warning{display:block;padding:10px 15px}.wp-admin #TB_window .bp-avatar #avatar-to-crop{float:left;margin:0}.wp-admin #TB_window .bp-avatar #bp-webcam-avatar #avatar-to-crop{margin-bottom:20px}@media screen and (min-width:783px){.wp-admin #TB_window .bp-avatar .avatar-crop-management{clear:none;float:left;margin-left:20px;padding-top:0;text-align:center}}.wp-admin #TB_window .bp-avatar #avatar-to-crop video{width:100%}.wp-admin #TB_window .bp-avatar .avatar-crop-management a.button{height:auto;line-height:inherit}@media screen and (min-width:810px){.wp-admin #TB_window .bp-avatar #bp-webcam-avatar #avatar-to-crop{max-width:none;width:76%}.wp-admin #TB_window #bp-webcam-avatar .avatar-crop-management{max-width:none;width:auto}}
bp-core/css/buddybar-rtl.css CHANGED
@@ -86,7 +86,7 @@ body#bp-default #admin-bar-logo {
86
  padding: 0;
87
  float: right;
88
  position: relative;
89
- background: url('../images/admin-menu-arrow.gif') 12% 53% no-repeat;
90
  padding-left: 11px;
91
  }
92
  #wp-admin-bar ul li.no-arrow {
@@ -121,9 +121,9 @@ body#bp-default #admin-bar-logo {
121
  -webkit-box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
122
  -moz-border-radius: 3px;
123
  -webkit-border-radius: 3px;
124
- -moz-border-radius-topleft: 0;
125
- -webkit-border-top-right-radius: 0;
126
  -moz-border-radius-topright: 0;
 
 
127
  -webkit-border-top-left-radius: 0;
128
  }
129
  #wp-admin-bar ul li > ul {
86
  padding: 0;
87
  float: right;
88
  position: relative;
89
+ background: url('../images/admin-menu-arrow.gif') 88% 53% no-repeat;
90
  padding-left: 11px;
91
  }
92
  #wp-admin-bar ul li.no-arrow {
121
  -webkit-box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
122
  -moz-border-radius: 3px;
123
  -webkit-border-radius: 3px;
 
 
124
  -moz-border-radius-topright: 0;
125
+ -webkit-border-top-right-radius: 0;
126
+ -moz-border-radius-topleft: 0;
127
  -webkit-border-top-left-radius: 0;
128
  }
129
  #wp-admin-bar ul li > ul {
bp-core/css/buddybar-rtl.min.css CHANGED
@@ -1 +1 @@
1
- #admin-bar-logo,#wp-admin-bar li a{font-size:11px;text-decoration:none}#wp-admin-bar ul li ul a,#wp-admin-bar ul li ul li:hover ul li a{color:#eee}#wp-admin-bar ul li ul li ul li:hover a,#wp-admin-bar ul li ul li:hover a{color:#fff}body:not(.wp-admin){padding-top:25px!important}#wp-admin-bar{position:fixed;top:0;right:0;height:25px;font-size:11px;width:100%;z-index:9999}#wp-admin-bar .padder{position:relative;padding:0;width:100%;margin:0 auto;background:url(../images/60pc_black.png);height:25px}body#bp-default #wp-admin-bar .padder{max-width:1250px}#wp-admin-bar *{z-index:999}#wp-admin-bar div#admin-bar-logo{position:absolute;top:5px;right:10px}#wp-admin-bar a img,#wp-admin-bar li.alt{border:none}#wp-admin-bar li{list-style:none;margin:0;padding:0;line-height:100%;text-align:right}#wp-admin-bar li a{padding:7px 15px;color:#eee}#wp-admin-bar li.no-arrow a{padding-left:15px}#wp-admin-bar ul li ul li a span{display:none}#wp-admin-bar li.hover,#wp-admin-bar li:hover{position:static}#admin-bar-logo{float:right;font-weight:700;padding:5px 8px;margin:0;color:#fff}body#bp-default #admin-bar-logo{padding:2px 8px}#wp-admin-bar ul{margin:0;list-style:none;line-height:1;cursor:pointer;height:auto;padding:0}#wp-admin-bar ul li{padding:0 0 0 11px;float:right;position:relative;background:url(../images/admin-menu-arrow.gif) 12% 53% no-repeat}#wp-admin-bar ul li.no-arrow{background:0 0;padding-left:0}#wp-admin-bar ul li ul li{background-image:none;float:right;width:174px;margin:0}#wp-admin-bar ul li.align-right{position:absolute;left:0}#wp-admin-bar ul li a{display:block}#wp-admin-bar ul.main-nav li ul li.sfhover,#wp-admin-bar ul.main-nav li.sfhover,#wp-admin-bar ul.main-nav li:hover{background-color:#333}#wp-admin-bar ul li ul{position:absolute;width:185px;right:-999em;margin-right:0;background:#333;border:1px solid #222;-moz-box-shadow:0 4px 8px rgba(0,0,0,.1);-webkit-box-shadow:0 4px 8px rgba(0,0,0,.1);-moz-border-radius:3px;-webkit-border-radius:0 0 3px 3px;-moz-border-radius-topleft:0;-moz-border-radius-topright:0}#wp-admin-bar ul li>ul{border-top:none}#wp-admin-bar ul li div.admin-bar-clear{clear:both}#wp-admin-bar ul.main-nav li ul li.sfhover,#wp-admin-bar ul.main-nav li ul li:hover{background-color:#222}#wp-admin-bar ul li ul ul{margin:-25px 184px 0 0;-moz-border-radius:3px;-webkit-border-radius:3px}#wp-admin-bar ul li ul li.sfhover ul,#wp-admin-bar ul li ul li:hover ul,#wp-admin-bar ul li.sfhover ul,#wp-admin-bar ul li:hover ul{right:auto}#wp-admin-bar ul li.align-right:hover ul{left:0}#wp-admin-bar li.sfhover ul li ul,#wp-admin-bar ul li:hover ul ul{right:-999em}#wp-admin-bar img.avatar{float:right;margin-left:8px}#wp-admin-bar span.activity{display:block;margin-right:34px;padding:0}#wp-admin-bar ul.author-list li a{height:17px}#wp-admin-bar ul li#bp-adminbar-notifications-menu a span{padding:0 6px;margin-right:2px;background:#fff;color:#000;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#wp-admin-bar-user-info img.avatar{height:64px;width:64px}
1
+ #admin-bar-logo,#wp-admin-bar li a{font-size:11px;text-decoration:none}#wp-admin-bar ul li ul a,#wp-admin-bar ul li ul li:hover ul li a{color:#eee}#wp-admin-bar ul li ul li ul li:hover a,#wp-admin-bar ul li ul li:hover a{color:#fff}body:not(.wp-admin){padding-top:25px!important}#wp-admin-bar{position:fixed;top:0;right:0;height:25px;font-size:11px;width:100%;z-index:9999}#wp-admin-bar .padder{position:relative;padding:0;width:100%;margin:0 auto;background:url(../images/60pc_black.png);height:25px}body#bp-default #wp-admin-bar .padder{max-width:1250px}#wp-admin-bar *{z-index:999}#wp-admin-bar div#admin-bar-logo{position:absolute;top:5px;right:10px}#wp-admin-bar a img,#wp-admin-bar li.alt{border:none}#wp-admin-bar li{list-style:none;margin:0;padding:0;line-height:100%;text-align:right}#wp-admin-bar li a{padding:7px 15px;color:#eee}#wp-admin-bar li.no-arrow a{padding-left:15px}#wp-admin-bar ul li ul li a span{display:none}#wp-admin-bar li.hover,#wp-admin-bar li:hover{position:static}#admin-bar-logo{float:right;font-weight:700;padding:5px 8px;margin:0;color:#fff}body#bp-default #admin-bar-logo{padding:2px 8px}#wp-admin-bar ul{margin:0;list-style:none;line-height:1;cursor:pointer;height:auto;padding:0}#wp-admin-bar ul li{padding:0 0 0 11px;float:right;position:relative;background:url(../images/admin-menu-arrow.gif) 88% 53% no-repeat}#wp-admin-bar ul li.no-arrow{background:0 0;padding-left:0}#wp-admin-bar ul li ul li{background-image:none;float:right;width:174px;margin:0}#wp-admin-bar ul li.align-right{position:absolute;left:0}#wp-admin-bar ul li a{display:block}#wp-admin-bar ul.main-nav li ul li.sfhover,#wp-admin-bar ul.main-nav li.sfhover,#wp-admin-bar ul.main-nav li:hover{background-color:#333}#wp-admin-bar ul li ul{position:absolute;width:185px;right:-999em;margin-right:0;background:#333;border:1px solid #222;-moz-box-shadow:0 4px 8px rgba(0,0,0,.1);-webkit-box-shadow:0 4px 8px rgba(0,0,0,.1);-moz-border-radius:3px;-webkit-border-radius:0 0 3px 3px;-moz-border-radius-topright:0;-moz-border-radius-topleft:0}#wp-admin-bar ul li>ul{border-top:none}#wp-admin-bar ul li div.admin-bar-clear{clear:both}#wp-admin-bar ul.main-nav li ul li.sfhover,#wp-admin-bar ul.main-nav li ul li:hover{background-color:#222}#wp-admin-bar ul li ul ul{margin:-25px 184px 0 0;-moz-border-radius:3px;-webkit-border-radius:3px}#wp-admin-bar ul li ul li.sfhover ul,#wp-admin-bar ul li ul li:hover ul,#wp-admin-bar ul li.sfhover ul,#wp-admin-bar ul li:hover ul{right:auto}#wp-admin-bar ul li.align-right:hover ul{left:0}#wp-admin-bar li.sfhover ul li ul,#wp-admin-bar ul li:hover ul ul{right:-999em}#wp-admin-bar img.avatar{float:right;margin-left:8px}#wp-admin-bar span.activity{display:block;margin-right:34px;padding:0}#wp-admin-bar ul.author-list li a{height:17px}#wp-admin-bar ul li#bp-adminbar-notifications-menu a span{padding:0 6px;margin-right:2px;background:#fff;color:#000;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}#wp-admin-bar-user-info img.avatar{height:64px;width:64px}
bp-core/deprecated/1.2.php CHANGED
@@ -16,8 +16,6 @@
16
  *
17
  * @param array $args
18
  *
19
- * @uses BP_Activity_Activity::get() {@link BP_Activity_Activity}
20
- *
21
  * @return object $activity The activity/activities object
22
  */
23
  function bp_activity_get_sitewide( $args = '' ) {
16
  *
17
  * @param array $args
18
  *
 
 
19
  * @return object $activity The activity/activities object
20
  */
21
  function bp_activity_get_sitewide( $args = '' ) {
bp-core/deprecated/1.7.php CHANGED
@@ -15,7 +15,6 @@ defined( 'ABSPATH' ) || exit;
15
  *
16
  * @since 1.6.0
17
  * @deprecated 1.7.0
18
- * @uses bp_get_maintenance_mode() To get the BuddyPress maintenance mode
19
  */
20
  function bp_maintenance_mode() {
21
  echo bp_get_maintenance_mode();
15
  *
16
  * @since 1.6.0
17
  * @deprecated 1.7.0
 
18
  */
19
  function bp_maintenance_mode() {
20
  echo bp_get_maintenance_mode();
bp-core/deprecated/2.5.php CHANGED
@@ -62,7 +62,7 @@ function bp_core_deprecated_email_filters( $value, $property, $transform, $email
62
  'settings-verify-email-change',
63
  );
64
 
65
- remove_filter( 'bp_email_get_property', 'bp_core_deprecated_email_filters', 20, 4 );
66
  $email_type = $email->get( 'type' );
67
  $tokens = $email->get( 'tokens' );
68
  add_filter( 'bp_email_get_property', 'bp_core_deprecated_email_filters', 20, 4 );
@@ -701,7 +701,7 @@ function bp_core_deprecated_email_actions( $delivery_status, $email ) {
701
  'settings-verify-email-change',
702
  );
703
 
704
- remove_action( 'bp_send_email_success', 'bp_core_deprecated_email_actions', 20, 2 );
705
  $email_content = $email->get( 'content' );
706
  $email_subject = $email->get( 'subject' );
707
  $email_type = $email->get( 'type' );
62
  'settings-verify-email-change',
63
  );
64
 
65
+ remove_filter( 'bp_email_get_property', 'bp_core_deprecated_email_filters', 20 );
66
  $email_type = $email->get( 'type' );
67
  $tokens = $email->get( 'tokens' );
68
  add_filter( 'bp_email_get_property', 'bp_core_deprecated_email_filters', 20, 4 );
701
  'settings-verify-email-change',
702
  );
703
 
704
+ remove_action( 'bp_send_email_success', 'bp_core_deprecated_email_actions', 20 );
705
  $email_content = $email->get( 'content' );
706
  $email_subject = $email->get( 'subject' );
707
  $email_type = $email->get( 'type' );
bp-core/deprecated/2.6.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Deprecated functions.
4
+ *
5
+ * @deprecated 2.6.0
6
+ */
7
+
8
+ // Exit if accessed directly.
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Print the generation time in the footer of the site.
13
+ *
14
+ * @since 1.0.0
15
+ * @deprecated 2.6.0
16
+ */
17
+ function bp_core_print_generation_time() {
18
+ ?>
19
+
20
+ <!-- Generated in <?php timer_stop(1); ?> seconds. (<?php echo get_num_queries(); ?> q) -->
21
+
22
+ <?php
23
+ }
24
+
25
+ /**
26
+ * Sort the navigation menu items.
27
+ *
28
+ * The sorting is split into a separate function because it can only happen
29
+ * after all plugins have had a chance to register their navigation items.
30
+ *
31
+ * @since 1.0.0
32
+ * @deprecated 2.6.0
33
+ *
34
+ * @return bool|null Returns false on failure.
35
+ */
36
+ function bp_core_sort_nav_items() {
37
+ _deprecated_function( __FUNCTION__, '2.6' );
38
+ }
39
+
40
+ /**
41
+ * Sort all subnavigation arrays.
42
+ *
43
+ * @since 1.1.0
44
+ * @deprecated 2.6.0
45
+ *
46
+ * @return bool|null Returns false on failure.
47
+ */
48
+ function bp_core_sort_subnav_items() {
49
+ _deprecated_function( __FUNCTION__, '2.6' );
50
+ }
bp-core/deprecated/2.7.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Deprecated functions.
4
+ *
5
+ * @deprecated 2.7.0
6
+ */
7
+
8
+ // Exit if accessed directly.
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Get the DB schema to use for BuddyPress components.
13
+ *
14
+ * @since 1.1.0
15
+ * @deprecated 2.7.0
16
+ *
17
+ * @return string The default database character-set, if set.
18
+ */
19
+ function bp_core_set_charset() {
20
+ global $wpdb;
21
+
22
+ _deprecated_function( __FUNCTION__, '2.7', 'wpdb::get_charset_collate()' );
23
+
24
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
25
+ return !empty( $wpdb->charset ) ? "DEFAULT CHARACTER SET {$wpdb->charset}" : '';
26
+ }
bp-core/deprecated/2.8.php ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Deprecated functions.
4
+ *
5
+ * @deprecated 2.8.0
6
+ */
7
+
8
+ // Exit if accessed directly.
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Determines whether the current installation is running PHP 5.3 or greater.
13
+ *
14
+ * BuddyPress 2.8 introduces a minimum PHP requirement of PHP 5.3.
15
+ *
16
+ * @since 2.7.0
17
+ * @deprecated 2.8.0
18
+ *
19
+ * @return bool
20
+ */
21
+ function bp_core_admin_is_running_php53_or_greater() {
22
+ return version_compare( PHP_VERSION, '5.3', '>=' );
23
+ }
24
+
25
+ /**
26
+ * Replaces WP's default update notice on plugins.php with an error message, when site is not running PHP 5.3 or greater.
27
+ *
28
+ * Originally hooked to 'load-plugins.php' with priority 100.
29
+ *
30
+ * @since 2.7.0
31
+ * @deprecated 2.8.0
32
+ */
33
+ function bp_core_admin_maybe_disable_update_row_for_php53_requirement() {
34
+ if ( bp_core_admin_is_running_php53_or_greater() ) {
35
+ return;
36
+ }
37
+
38
+ $loader = basename( constant( 'BP_PLUGIN_DIR' ) ) . '/bp-loader.php';
39
+
40
+ remove_action( "after_plugin_row_{$loader}", 'wp_plugin_update_row', 10 );
41
+ add_action( "after_plugin_row_{$loader}", 'bp_core_admin_php52_plugin_row', 10, 2 );
42
+ }
43
+
44
+ /**
45
+ * On the "Dashboard > Updates" page, remove BuddyPress from plugins list if PHP < 5.3.
46
+ *
47
+ * Originally hooked to 'load-update-core.php'.
48
+ *
49
+ * @since 2.7.0
50
+ * @deprecated 2.8.0
51
+ */
52
+ function bp_core_admin_maybe_remove_from_update_core() {
53
+ if ( bp_core_admin_is_running_php53_or_greater() ) {
54
+ return;
55
+ }
56
+
57
+ // Add filter to remove BP from the update plugins list.
58
+ add_filter( 'site_transient_update_plugins', 'bp_core_admin_remove_buddypress_from_update_transient' );
59
+ }
60
+
61
+ /**
62
+ * Filter callback to remove BuddyPress from the update plugins list.
63
+ *
64
+ * Attached to the 'site_transient_update_plugins' filter.
65
+ *
66
+ * @since 2.7.0
67
+ * @deprecated 2.8.0
68
+ *
69
+ * @param object $retval Object of plugin update data.
70
+ * @return object
71
+ */
72
+ function bp_core_admin_remove_buddypress_from_update_transient( $retval ) {
73
+ $loader = basename( constant( 'BP_PLUGIN_DIR' ) ) . '/bp-loader.php';
74
+
75
+ // Remove BP from update plugins list.
76
+ if ( isset( $retval->response[ $loader ] ) ) {
77
+ unset( $retval->response[ $loader ] );
78
+ }
79
+
80
+ return $retval;
81
+ }
82
+
83
+ /**
84
+ * Outputs a replacement for WP's default update notice, when site is not running PHP 5.3 or greater.
85
+ *
86
+ * When we see that a site is not running PHP 5.3 and is trying to update to
87
+ * BP 2.8+, we replace WP's default notice with our own, which both provides a
88
+ * link to our documentation of the requirement, and removes the link that
89
+ * allows a single plugin to be updated.
90
+ *
91
+ * @since 2.7.0
92
+ * @deprecated 2.8.0
93
+ *
94
+ * @param string $file Plugin filename. buddypress/bp-loader.php.
95
+ * @param array $plugin_data Data about the BuddyPress plugin, as returned by the
96
+ * plugins API.
97
+ */
98
+ function bp_core_admin_php52_plugin_row( $file, $plugin_data ) {
99
+ if ( is_multisite() && ! is_network_admin() ) {
100
+ return;
101
+ }
102
+
103
+ $current = get_site_transient( 'update_plugins' );
104
+ if ( ! isset( $current->response[ $file ] ) ) {
105
+ return false;
106
+ }
107
+
108
+ $response = $current->response[ $file ];
109
+
110
+ // No need to do this if update is for < BP 2.8.
111
+ if ( version_compare( $response->new_version, '2.8', '<' ) ) {
112
+ return false;
113
+ }
114
+
115
+ $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
116
+
117
+ if ( is_network_admin() ) {
118
+ $active_class = is_plugin_active_for_network( $file ) ? ' active' : '';
119
+ } else {
120
+ $active_class = is_plugin_active( $file ) ? ' active' : '';
121
+ }
122
+
123
+ // WP 4.6 uses different markup for the plugin row notice.
124
+ if ( function_exists( 'wp_get_ext_types' ) ) {
125
+ $p = '<p>%s</p>';
126
+
127
+ // WP < 4.6.
128
+ } else {
129
+ $p = '%s';
130
+
131
+ // Ugh.
132
+ $active_class .= ' not-shiny';
133
+ }
134
+
135
+ echo '<tr class="plugin-update-tr' . $active_class . '" id="' . esc_attr( $response->slug . '-update' ) . '" data-slug="' . esc_attr( $response->slug ) . '" data-plugin="' . esc_attr( $file ) . '"><td colspan="' . esc_attr( $wp_list_table->get_column_count() ) . '" class="plugin-update colspanchange"><div class="update-message inline notice notice-error notice-alt">';
136
+
137
+ printf( $p,
138
+ esc_html__( 'A BuddyPress update is available, but your system is not compatible.', 'buddypress' ) . ' ' .
139
+ sprintf( __( 'See <a href="%s">the Codex guide</a> for more information.', 'buddypress' ), 'https://codex.buddypress.org/getting-started/buddypress-2-8-will-require-php-5-3/' )
140
+ );
141
+
142
+ echo '</div></td></tr>';
143
+
144
+ /*
145
+ * JavaScript to disable the bulk upgrade checkbox.
146
+ * See WP_Plugins_List_Table::single_row().
147
+ */
148
+ $checkbox_id = 'checkbox_' . md5( $plugin_data['Name'] );
149
+ echo "<script type='text/javascript'>document.getElementById('$checkbox_id').disabled = true;</script>";
150
+ }
151
+
152
+ /**
153
+ * Add an admin notice to installations that are not running PHP 5.3+.
154
+ *
155
+ * @since 2.7.0
156
+ * @deprecated 2.8.0
157
+ */
158
+ function bp_core_admin_php53_admin_notice() {
159
+ // If not on the Plugins page, stop now.
160
+ if ( 'plugins' !== get_current_screen()->parent_base ) {
161
+ return;
162
+ }
163
+
164
+ if ( ! current_user_can( 'update_core' ) ) {
165
+ return;
166
+ }
167
+
168
+ if ( bp_core_admin_is_running_php53_or_greater() ) {
169
+ return;
170
+ }
171
+
172
+ $notice_id = 'bp28-php53';
173
+ if ( bp_get_option( "bp-dismissed-notice-$notice_id" ) ) {
174
+ return;
175
+ }
176
+
177
+ $bp = buddypress();
178
+ $min = bp_core_get_minified_asset_suffix();
179
+
180
+ wp_enqueue_script(
181
+ 'bp-dismissible-admin-notices',
182
+ "{$bp->plugin_url}bp-core/admin/js/dismissible-admin-notices{$min}.js",
183
+ array( 'jquery' ),
184
+ bp_get_version(),
185
+ true
186
+ );
187
+
188
+ $php_version = PHP_VERSION;
189
+
190
+ ?>
191
+
192
+ <div id="message" class="error notice is-dismissible bp-is-dismissible" data-noticeid="<?php echo esc_attr( $notice_id ); ?>">
193
+ <p><strong><?php esc_html_e( 'Your site is not ready for BuddyPress 2.8.', 'buddypress' ); ?></strong></p>
194
+ <p><?php printf( esc_html__( 'Your site is currently running PHP version %s, while BuddyPress 2.8 will require version 5.3+.', 'buddypress' ), $php_version ); ?> <?php printf( __( 'See <a href="%s">the Codex guide</a> for more information.', 'buddypress' ), 'https://codex.buddypress.org/getting-started/buddypress-2-8-will-require-php-5-3/' ); ?></p>
195
+ <?php wp_nonce_field( "bp-dismissible-notice-$notice_id", "bp-dismissible-nonce-$notice_id" ); ?>
196
+ </div>
197
+ <?php
198
+ }
199
+
bp-core/images/mystery-group-50.png ADDED
Binary file
bp-core/images/mystery-group.png ADDED
Binary file
bp-core/js/avatar.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
  window.bp=window.bp||{},function(a,b){"undefined"!=typeof BP_Uploader&&(bp.Models=bp.Models||{},bp.Collections=bp.Collections||{},bp.Views=bp.Views||{},bp.Avatar={start:function(){var a=this;this.removeLegacyUI(),this.views=new Backbone.Collection,this.jcropapi={},this.warning=null,this.setupNav(),this.avatars=bp.Uploader.filesUploaded,this.Attachment=new Backbone.Model,bp.Uploader.filesQueue.on("reset",this.cropView,this),b("body.wp-admin").on("tb_unload","#TB_window",function(){a.resetViews()}),b("body.wp-admin").on("click",".bp-xprofile-avatar-user-edit",function(){a.resetViews()})},removeLegacyUI:function(){b("#avatar-upload-form").length?(b("#avatar-upload").remove(),b("#avatar-upload-form p").remove()):b("#group-settings-form").length?(b("#group-settings-form p").each(function(a){0!==a&&b(this).remove()}),b("#delete-group-avatar-button").length&&b("#delete-group-avatar-button").remove()):b("#group-create-body").length?(b(".main-column p #file").remove(),b(".main-column p #upload").remove()):b("#bp_xprofile_user_admin_avatar a.bp-xprofile-avatar-user-admin").length&&b("#bp_xprofile_user_admin_avatar a.bp-xprofile-avatar-user-admin").remove()},setView:function(a){switch(_.isUndefined(this.views.models)||_.each(this.views.models,function(a){a.get("view").remove()},this),this.views.reset(),_.isUndefined(this.avatars)||this.avatars.reset(),_.isEmpty(this.jcropapi)||(this.jcropapi.destroy(),this.jcropapi={}),a){case"upload":this.uploaderView();break;case"delete":this.deleteView()}},resetViews:function(){this.nav.trigger("bp-avatar-view:changed","upload"),_.each(this.navItems.models,function(a){"upload"===a.id?a.set({active:1}):a.set({active:0})})},setupNav:function(){var a,b,c=this;this.navItems=new Backbone.Collection,_.each(BP_Uploader.settings.nav,function(d,e){_.isObject(d)&&(b=0,0===e&&(a=d.id,b=1),c.navItems.add({id:d.id,name:d.caption,href:"#",active:b,hide:_.isUndefined(d.hide)?0:d.hide}))}),this.nav=new bp.Views.Nav({collection:this.navItems}),this.nav.inject(".bp-avatar-nav"),this.setView(a),this.nav.on("bp-avatar-view:changed",_.bind(this.setView,this))},uploaderView:function(){bp.Uploader.filesQueue.on("add",this.uploadProgress,this);var a=new bp.Views.Uploader;this.views.add({id:"upload",view:a}),a.inject(".bp-avatar")},uploadProgress:function(){var a=new bp.Views.uploaderStatus({collection:bp.Uploader.filesQueue});_.isUndefined(this.views.get("status"))?this.views.add({id:"status",view:a}):this.views.set({id:"status",view:a}),a.inject(".bp-avatar-status")},cropView:function(){var a;if(!_.isEmpty(this.avatars.models)){_.isUndefined(this.views.get("status"))||(a=this.views.get("status"),a.get("view").remove(),this.views.remove({id:"status",view:a}));var b=new bp.Views.Avatars({collection:this.avatars});this.views.add({id:"crop",view:b}),b.inject(".bp-avatar")}},setAvatar:function(a){var c,d=this;_.isUndefined(this.views.get("crop"))||(_.isEmpty(this.jcropapi)||(this.jcropapi.destroy(),this.jcropapi={}),c=this.views.get("crop"),c.get("view").remove(),this.views.remove({id:"crop",view:c})),bp.ajax.post("bp_avatar_set",{json:!0,original_file:a.get("url"),crop_w:a.get("w"),crop_h:a.get("h"),crop_x:a.get("x"),crop_y:a.get("y"),item_id:a.get("item_id"),object:a.get("object"),type:_.isUndefined(a.get("type"))?"crop":a.get("type"),nonce:a.get("nonces").set}).done(function(c){var e=new bp.Views.AvatarStatus({value:BP_Uploader.strings.feedback_messages[c.feedback_code],type:"success"});d.views.add({id:"status",view:e}),e.inject(".bp-avatar-status"),b("."+a.get("object")+"-"+c.item_id+"-avatar").each(function(){b(this).prop("src",c.avatar)}),bp.Avatar.navItems.get("delete").set({hide:0}),d.Attachment.set(_.extend(_.pick(a.attributes,["object","item_id"]),{url:c.avatar,action:"uploaded"}))}).fail(function(a){var b=BP_Uploader.strings.default_error;_.isUndefined(a)||(b=BP_Uploader.strings.feedback_messages[a.feedback_code]);var c=new bp.Views.AvatarStatus({value:b,type:"error"});d.views.add({id:"status",view:c}),c.inject(".bp-avatar-status")})},deleteView:function(){var a=new Backbone.Model(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,"object","item_id","nonces")),b=new bp.Views.DeleteAvatar({model:a});this.views.add({id:"delete",view:b}),b.inject(".bp-avatar")},deleteAvatar:function(a){var c,d=this;_.isUndefined(this.views.get("delete"))||(c=this.views.get("delete"),c.get("view").remove(),this.views.remove({id:"delete",view:c})),bp.ajax.post("bp_avatar_delete",{json:!0,item_id:a.get("item_id"),object:a.get("object"),nonce:a.get("nonces").remove}).done(function(c){var e=new bp.Views.AvatarStatus({value:BP_Uploader.strings.feedback_messages[c.feedback_code],type:"success"});d.views.add({id:"status",view:e}),e.inject(".bp-avatar-status"),b("."+a.get("object")+"-"+c.item_id+"-avatar").each(function(){b(this).prop("src",c.avatar)}),bp.Avatar.navItems.get("delete").set({active:0,hide:1}),d.Attachment.set(_.extend(_.pick(a.attributes,["object","item_id"]),{url:c.avatar,action:"deleted"}))}).fail(function(a){var b=BP_Uploader.strings.default_error;_.isUndefined(a)||(b=BP_Uploader.strings.feedback_messages[a.feedback_code]);var c=new bp.Views.AvatarStatus({value:b,type:"error"});d.views.add({id:"status",view:c}),c.inject(".bp-avatar-status")})},removeWarning:function(){_.isNull(this.warning)||this.warning.remove()},displayWarning:function(a){this.removeWarning(),this.warning=new bp.Views.uploaderWarning({value:a}),this.warning.inject(".bp-avatar-status")}},bp.Views.Nav=bp.View.extend({tagName:"ul",className:"avatar-nav-items",events:{"click .bp-avatar-nav-item":"toggleView"},initialize:function(){var a=_.findWhere(this.collection.models,{id:"delete"});1!==a.get("hide")&&bp.Avatar.displayWarning(BP_Uploader.strings.has_avatar_warning),_.each(this.collection.models,this.addNavItem,this),this.collection.on("change:hide",this.showHideNavItem,this)},addNavItem:function(a){1!==a.get("hide")&&this.views.add(new bp.Views.NavItem({model:a}))},showHideNavItem:function(a){var b=null;_.each(this.views._views[""],function(c){1===c.model.get("hide")&&c.remove(),a.get("id")===c.model.get("id")&&(b=!0)}),_.isBoolean(b)||this.addNavItem(a)},toggleView:function(a){a.preventDefault(),bp.Avatar.removeWarning();var c=b(a.target).data("nav");_.each(this.collection.models,function(a){a.id===c?(a.set({active:1}),this.trigger("bp-avatar-view:changed",a.id)):a.set({active:0})},this)}}),bp.Views.NavItem=bp.View.extend({tagName:"li",className:"avatar-nav-item",template:bp.template("bp-avatar-nav"),initialize:function(){1===this.model.get("active")&&(this.el.className+=" current"),this.el.id+="bp-avatar-"+this.model.get("id"),this.model.on("change:active",this.setCurrentNav,this)},setCurrentNav:function(a){1===a.get("active")?this.$el.addClass("current"):this.$el.removeClass("current")}}),bp.Views.Avatars=bp.View.extend({className:"items",initialize:function(){_.each(this.collection.models,this.addItemView,this)},addItemView:function(a){var b={full_h:150,full_w:150};_.isUndefined(BP_Uploader.settings.crop.full_h)||_.isUndefined(BP_Uploader.settings.crop.full_w)||(b.full_h=BP_Uploader.settings.crop.full_h,b.full_w=BP_Uploader.settings.crop.full_w),a.set(_.extend(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,"object","item_id","nonces"),b)),this.views.add(new bp.Views.Avatar({model:a}))}}),bp.Views.Avatar=bp.View.extend({className:"item",template:bp.template("bp-avatar-item"),events:{"click .avatar-crop-submit":"cropAvatar"},initialize:function(){_.defaults(this.options,{full_h:BP_Uploader.settings.crop.full_h,full_w:BP_Uploader.settings.crop.full_w,aspectRatio:1}),!1!==this.model.get("feedback")&&bp.Avatar.displayWarning(this.model.get("feedback")),this.on("ready",this.initCropper)},initCropper:function(){var a,c,d,e,f,g,h=this,i=this.$el.find("#avatar-to-crop img"),j=this.$el.width(),k={};_.isUndefined(this.options.full_h)||_.isUndefined(this.options.full_w)||(this.options.aspectRatio=this.options.full_w/this.options.full_h),k.w=this.model.get("width"),k.h=this.model.get("height"),this.options.full_w+k.w+20<j&&(b("#avatar-to-crop").addClass("adjust"),this.$el.find(".avatar-crop-management").addClass("adjust")),k.h<=k.w?(a=Math.round(k.h/4),f=g=Math.round(k.h/2),c=f+a,d=(k.w-g)/2,e=g+d):(d=Math.round(k.w/4),f=g=Math.round(k.w/2),e=g+d,a=(k.h-f)/2,c=f+a),i.Jcrop({onChange:_.bind(h.showPreview,h),onSelect:_.bind(h.showPreview,h),aspectRatio:h.options.aspectRatio,setSelect:[d,a,e,c]},function(){bp.Avatar.jcropapi=this})},cropAvatar:function(a){a.preventDefault(),bp.Avatar.setAvatar(this.model)},showPreview:function(a){if(a.w&&a.h&&parseInt(a.w,10)>0){var c=this.options.full_w,d=this.options.full_h,e=c/a.w,f=d/a.h;this.model.set({x:a.x,y:a.y,w:a.w,h:a.h}),b("#avatar-crop-preview").css({maxWidth:"none",width:Math.round(e*this.model.get("width"))+"px",height:Math.round(f*this.model.get("height"))+"px",marginLeft:"-"+Math.round(e*this.model.get("x"))+"px",marginTop:"-"+Math.round(f*this.model.get("y"))+"px"})}}}),bp.Views.AvatarStatus=bp.View.extend({tagName:"p",className:"updated",id:"bp-avatar-feedback",initialize:function(){this.el.className+=" "+this.options.type,this.value=this.options.value},render:function(){return this.$el.html(this.value),this}}),bp.Views.DeleteAvatar=bp.View.extend({tagName:"div",id:"bp-delete-avatar-container",template:bp.template("bp-avatar-delete"),events:{"click #bp-delete-avatar":"deleteAvatar"},deleteAvatar:function(a){a.preventDefault(),bp.Avatar.deleteAvatar(this.model)}}),bp.Avatar.start())}(bp,jQuery);
 
1
  window.bp=window.bp||{},function(a,b){"undefined"!=typeof BP_Uploader&&(bp.Models=bp.Models||{},bp.Collections=bp.Collections||{},bp.Views=bp.Views||{},bp.Avatar={start:function(){var a=this;this.removeLegacyUI(),this.views=new Backbone.Collection,this.jcropapi={},this.warning=null,this.setupNav(),this.avatars=bp.Uploader.filesUploaded,this.Attachment=new Backbone.Model,bp.Uploader.filesQueue.on("reset",this.cropView,this),b("body.wp-admin").on("tb_unload","#TB_window",function(){a.resetViews()}),b("body.wp-admin").on("click",".bp-xprofile-avatar-user-edit",function(){a.resetViews()})},removeLegacyUI:function(){b("#avatar-upload-form").length?(b("#avatar-upload").remove(),b("#avatar-upload-form p").remove()):b("#group-settings-form").length?(b("#group-settings-form p").each(function(a){0!==a&&b(this).remove()}),b("#delete-group-avatar-button").length&&b("#delete-group-avatar-button").remove()):b("#group-create-body").length?(b(".main-column p #file").remove(),b(".main-column p #upload").remove()):b("#bp_xprofile_user_admin_avatar a.bp-xprofile-avatar-user-admin").length&&b("#bp_xprofile_user_admin_avatar a.bp-xprofile-avatar-user-admin").remove()},setView:function(a){switch(_.isUndefined(this.views.models)||_.each(this.views.models,function(a){a.get("view").remove()},this),this.views.reset(),_.isUndefined(this.avatars)||this.avatars.reset(),_.isEmpty(this.jcropapi)||(this.jcropapi.destroy(),this.jcropapi={}),a){case"upload":this.uploaderView();break;case"delete":this.deleteView()}},resetViews:function(){this.nav.trigger("bp-avatar-view:changed","upload"),_.each(this.navItems.models,function(a){"upload"===a.id?a.set({active:1}):a.set({active:0})})},setupNav:function(){var a,b,c=this;this.navItems=new Backbone.Collection,_.each(BP_Uploader.settings.nav,function(d,e){_.isObject(d)&&(b=0,0===e&&(a=d.id,b=1),c.navItems.add({id:d.id,name:d.caption,href:"#",active:b,hide:_.isUndefined(d.hide)?0:d.hide}))}),this.nav=new bp.Views.Nav({collection:this.navItems}),this.nav.inject(".bp-avatar-nav"),this.setView(a),this.nav.on("bp-avatar-view:changed",_.bind(this.setView,this))},uploaderView:function(){bp.Uploader.filesQueue.on("add",this.uploadProgress,this);var a=new bp.Views.Uploader;this.views.add({id:"upload",view:a}),a.inject(".bp-avatar")},uploadProgress:function(){var a=new bp.Views.uploaderStatus({collection:bp.Uploader.filesQueue});_.isUndefined(this.views.get("status"))?this.views.add({id:"status",view:a}):this.views.set({id:"status",view:a}),a.inject(".bp-avatar-status")},cropView:function(){var a;if(!_.isEmpty(this.avatars.models)){_.isUndefined(this.views.get("status"))||(a=this.views.get("status"),a.get("view").remove(),this.views.remove({id:"status",view:a}));var b=new bp.Views.Avatars({collection:this.avatars});this.views.add({id:"crop",view:b}),b.inject(".bp-avatar")}},setAvatar:function(a){var c,d=this;_.isUndefined(this.views.get("crop"))||(_.isEmpty(this.jcropapi)||(this.jcropapi.destroy(),this.jcropapi={}),c=this.views.get("crop"),c.get("view").remove(),this.views.remove({id:"crop",view:c})),bp.ajax.post("bp_avatar_set",{json:!0,original_file:a.get("url"),crop_w:a.get("w"),crop_h:a.get("h"),crop_x:a.get("x"),crop_y:a.get("y"),item_id:a.get("item_id"),object:a.get("object"),type:_.isUndefined(a.get("type"))?"crop":a.get("type"),nonce:a.get("nonces").set}).done(function(c){var e=new bp.Views.AvatarStatus({value:BP_Uploader.strings.feedback_messages[c.feedback_code],type:"success"});d.views.add({id:"status",view:e}),e.inject(".bp-avatar-status"),b("."+a.get("object")+"-"+c.item_id+"-avatar").each(function(){b(this).prop("src",c.avatar)}),bp.Avatar.navItems.get("delete").set({hide:0}),d.Attachment.set(_.extend(_.pick(a.attributes,["object","item_id"]),{url:c.avatar,action:"uploaded"}))}).fail(function(a){var b=BP_Uploader.strings.default_error;_.isUndefined(a)||(b=BP_Uploader.strings.feedback_messages[a.feedback_code]);var c=new bp.Views.AvatarStatus({value:b,type:"error"});d.views.add({id:"status",view:c}),c.inject(".bp-avatar-status")})},deleteView:function(){var a=new Backbone.Model(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,"object","item_id","nonces")),b=new bp.Views.DeleteAvatar({model:a});this.views.add({id:"delete",view:b}),b.inject(".bp-avatar")},deleteAvatar:function(a){var c,d=this;_.isUndefined(this.views.get("delete"))||(c=this.views.get("delete"),c.get("view").remove(),this.views.remove({id:"delete",view:c})),bp.ajax.post("bp_avatar_delete",{json:!0,item_id:a.get("item_id"),object:a.get("object"),nonce:a.get("nonces").remove}).done(function(c){var e=new bp.Views.AvatarStatus({value:BP_Uploader.strings.feedback_messages[c.feedback_code],type:"success"});d.views.add({id:"status",view:e}),e.inject(".bp-avatar-status"),b("."+a.get("object")+"-"+c.item_id+"-avatar").each(function(){b(this).prop("src",c.avatar)}),bp.Avatar.navItems.get("delete").set({active:0,hide:1}),d.Attachment.set(_.extend(_.pick(a.attributes,["object","item_id"]),{url:c.avatar,action:"deleted"}))}).fail(function(a){var b=BP_Uploader.strings.default_error;_.isUndefined(a)||(b=BP_Uploader.strings.feedback_messages[a.feedback_code]);var c=new bp.Views.AvatarStatus({value:b,type:"error"});d.views.add({id:"status",view:c}),c.inject(".bp-avatar-status")})},removeWarning:function(){_.isNull(this.warning)||this.warning.remove()},displayWarning:function(a){this.removeWarning(),this.warning=new bp.Views.uploaderWarning({value:a}),this.warning.inject(".bp-avatar-status")}},bp.Views.Nav=bp.View.extend({tagName:"ul",className:"avatar-nav-items",events:{"click .bp-avatar-nav-item":"toggleView"},initialize:function(){var a=_.findWhere(this.collection.models,{id:"delete"});1!==a.get("hide")&&bp.Avatar.displayWarning(BP_Uploader.strings.has_avatar_warning),_.each(this.collection.models,this.addNavItem,this),this.collection.on("change:hide",this.showHideNavItem,this)},addNavItem:function(a){1!==a.get("hide")&&this.views.add(new bp.Views.NavItem({model:a}))},showHideNavItem:function(a){var b=null;_.each(this.views._views[""],function(c){1===c.model.get("hide")&&c.remove(),a.get("id")===c.model.get("id")&&(b=!0)}),_.isBoolean(b)||this.addNavItem(a)},toggleView:function(a){a.preventDefault(),bp.Avatar.removeWarning();var c=b(a.target).data("nav");_.each(this.collection.models,function(a){a.id===c?(a.set({active:1}),this.trigger("bp-avatar-view:changed",a.id)):a.set({active:0})},this)}}),bp.Views.NavItem=bp.View.extend({tagName:"li",className:"avatar-nav-item",template:bp.template("bp-avatar-nav"),initialize:function(){1===this.model.get("active")&&(this.el.className+=" current"),this.el.id+="bp-avatar-"+this.model.get("id"),this.model.on("change:active",this.setCurrentNav,this)},setCurrentNav:function(a){1===a.get("active")?this.$el.addClass("current"):this.$el.removeClass("current")}}),bp.Views.Avatars=bp.View.extend({className:"items",initialize:function(){_.each(this.collection.models,this.addItemView,this)},addItemView:function(a){var b={full_h:150,full_w:150};_.isUndefined(BP_Uploader.settings.crop.full_h)||_.isUndefined(BP_Uploader.settings.crop.full_w)||(b.full_h=BP_Uploader.settings.crop.full_h,b.full_w=BP_Uploader.settings.crop.full_w),a.set(_.extend(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,"object","item_id","nonces"),b)),this.views.add(new bp.Views.Avatar({model:a}))}}),bp.Views.Avatar=bp.View.extend({className:"item",template:bp.template("bp-avatar-item"),events:{"click .avatar-crop-submit":"cropAvatar"},initialize:function(){_.defaults(this.options,{full_h:BP_Uploader.settings.crop.full_h,full_w:BP_Uploader.settings.crop.full_w,aspectRatio:1}),!1!==this.model.get("feedback")&&bp.Avatar.displayWarning(this.model.get("feedback")),this.on("ready",this.initCropper)},initCropper:function(){var a,c,d,e,f,g,h=this,i=this.$el.find("#avatar-to-crop img"),j=this.$el.width(),k={};_.isUndefined(this.options.full_h)||_.isUndefined(this.options.full_w)||(this.options.aspectRatio=this.options.full_w/this.options.full_h),k.w=this.model.get("width"),k.h=this.model.get("height"),this.options.full_w+k.w+20<j&&(b("#avatar-to-crop").addClass("adjust"),this.$el.find(".avatar-crop-management").addClass("adjust")),k.h<=k.w?(a=Math.round(k.h/4),f=g=Math.round(k.h/2),c=f+a,d=(k.w-g)/2,e=g+d):(d=Math.round(k.w/4),f=g=Math.round(k.w/2),e=g+d,a=(k.h-f)/2,c=f+a),i.Jcrop({onChange:_.bind(h.showPreview,h),onSelect:_.bind(h.showPreview,h),aspectRatio:h.options.aspectRatio,setSelect:[d,a,e,c]},function(){bp.Avatar.jcropapi=this})},cropAvatar:function(a){a.preventDefault(),bp.Avatar.setAvatar(this.model)},showPreview:function(a){if(a.w&&a.h&&parseInt(a.w,10)>0){var c=this.options.full_w,d=this.options.full_h,e=c/a.w,f=d/a.h;this.model.set({x:a.x,y:a.y,w:a.w,h:a.h}),b("#avatar-crop-preview").css({maxWidth:"none",width:Math.round(e*this.model.get("width"))+"px",height:Math.round(f*this.model.get("height"))+"px",marginLeft:"-"+Math.round(e*this.model.get("x"))+"px",marginTop:"-"+Math.round(f*this.model.get("y"))+"px"})}}}),bp.Views.AvatarStatus=bp.View.extend({tagName:"p",className:"updated",id:"bp-avatar-feedback",initialize:function(){this.el.className+=" "+this.options.type,this.value=this.options.value},render:function(){return this.$el.html(this.value),this}}),bp.Views.DeleteAvatar=bp.View.extend({tagName:"div",id:"bp-delete-avatar-container",template:bp.template("bp-avatar-delete"),events:{"click #bp-delete-avatar":"deleteAvatar"},deleteAvatar:function(a){a.preventDefault(),bp.Avatar.deleteAvatar(this.model)}}),bp.Avatar.start())}(bp,jQuery);
bp-core/js/bp-plupload.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
- window.wp=window.wp||{},window.bp=window.bp||{},function(a,b){"undefined"!=typeof BP_Uploader&&(_.extend(bp,_.pick(wp,"Backbone","ajax","template")),bp.Models=bp.Models||{},bp.Collections=bp.Collections||{},bp.Views=bp.Views||{},bp.Uploader={},bp.Uploader.uploader=function(){var a=this,c=-1!==navigator.userAgent.indexOf("Trident/")||-1!==navigator.userAgent.indexOf("MSIE ");return this.params=BP_Uploader.settings,this.strings=BP_Uploader.strings,this.supports={upload:this.params.browser.supported},this.supported=this.supports.upload,this.supported?(c||"flash"!==plupload.predictRuntime(this.params.defaults)||this.params.defaults.required_features&&this.params.defaults.required_features.hasOwnProperty("send_binary_string")||(this.params.defaults.required_features=this.params.defaults.required_features||{},this.params.defaults.required_features.send_binary_string=!0),this.uploader=new plupload.Uploader(this.params.defaults),this.uploader.bind("Init",function(c){var d=b("#"+a.params.defaults.container),e=b("#"+a.params.defaults.drop_element);"html4"===c.runtime&&(c.settings.multipart_params.html4=!0),"bp_avatar_upload"===c.settings.multipart_params.action&&(c.settings.multipart_params.bp_params.ui_available_width=d.width()),c.features.dragdrop&&!a.params.browser.mobile?(d.addClass("drag-drop"),e.bind("dragover.wp-uploader",function(){d.addClass("drag-over")}).bind("dragleave.wp-uploader, drop.wp-uploader",function(){d.removeClass("drag-over")})):(d.removeClass("drag-drop"),e.unbind(".wp-uploader"))}),this.uploader.init(),this.feedback=function(a,b,c){!_.isNull(c)&&c.item&&c.item.clear(),bp.Uploader.filesError.unshift({message:a,data:b,file:c})},this.uploader.bind("FilesAdded",function(c,d){var e=104857600,f=parseInt(c.settings.max_file_size,10),g=this;if(!c.settings.multi_selection&&d.length>1){for(var h in d)c.removeFile(d[h]);return void b(a).trigger("bp-uploader-warning",a.strings.unique_file_warning)}_.each(d,function(a){var b;plupload.FAILED!==a.status&&(f>e&&a.size>e&&"html5"!==c.runtime?g.uploadSizeError(c,a,!0):(b=_.extend({id:a.id,file:a,uploading:!0,date:new Date,filename:a.name},_.pick(a,"loaded","size","percent")),a.item=new bp.Models.File(b),bp.Uploader.filesQueue.add(a.item)))}),c.refresh(),c.start()}),this.uploader.bind("UploadProgress",function(a,b){b.item.set(_.pick(b,"loaded","percent"))}),this.uploader.bind("FileUploaded",function(b,c,d){var e=a.strings.default_error;try{d=JSON.parse(d.response)}catch(f){return a.feedback(e,f,c)}return!_.isObject(d)||_.isUndefined(d.success)?a.feedback(e,null,c):d.success?(_.each(["file","loaded","size","percent"],function(a){c.item.unset(a)}),c.item.set(_.extend(d.data,{uploading:!1})),void bp.Uploader.filesUploaded.add(c.item)):(d.data&&d.data.message&&(e=d.data.message),a.feedback(e,d.data,c))}),this.uploader.bind("BeforeUpload",function(c,d){b(a).trigger("bp-uploader-new-upload",c,d)}),this.uploader.bind("UploadComplete",function(c,d){b(a).trigger("bp-uploader-upload-complete",c,d),bp.Uploader.filesQueue.reset()}),void this.uploader.bind("Error",function(c,d){var e,f=a.strings.default_error,g={FAILED:a.strings.upload_failed,FILE_EXTENSION_ERROR:a.strings.invalid_filetype,IMAGE_FORMAT_ERROR:a.strings.not_an_image,IMAGE_MEMORY_ERROR:a.strings.image_memory_exceeded,IMAGE_DIMENSIONS_ERROR:a.strings.image_dimensions_exceeded,GENERIC_ERROR:a.strings.upload_failed,IO_ERROR:a.strings.io_error,HTTP_ERROR:a.strings.http_error,SECURITY_ERROR:a.strings.security_error,FILE_SIZE_ERROR:a.strings.file_exceeds_size_limit.replace("%s",d.file.name)};for(e in g)if(d.code===plupload[e]){f=g[e];break}b(a).trigger("bp-uploader-warning",f),c.refresh()})):void(BP_Uploader=void 0)},bp.Models.File=Backbone.Model.extend({file:{}}),b.extend(bp.Uploader,{filesQueue:new Backbone.Collection,filesUploaded:new Backbone.Collection,filesError:new Backbone.Collection}),bp.View=bp.Backbone.View.extend({inject:function(a){this.render(),b(a).html(this.el),this.views.ready()},prepare:function(){return!_.isUndefined(this.model)&&_.isFunction(this.model.toJSON)?this.model.toJSON():{}}}),bp.Views.Uploader=bp.View.extend({className:"bp-uploader-window",template:bp.template("upload-window"),defaults:_.pick(BP_Uploader.settings.defaults,"container","drop_element","browse_button"),initialize:function(){this.warnings=[],this.model=new Backbone.Model(this.defaults),this.on("ready",this.initUploader)},initUploader:function(){this.uploader=new bp.Uploader.uploader,b(this.uploader).on("bp-uploader-warning",_.bind(this.setWarning,this)),b(this.uploader).on("bp-uploader-new-upload",_.bind(this.resetWarning,this))},setWarning:function(a,b){if(!_.isUndefined(b)){var c=new bp.Views.uploaderWarning({value:b}).render();this.warnings.push(c),this.$el.after(c.el)}},resetWarning:function(){0!==this.warnings.length&&(_.each(this.warnings,function(a){a.remove()}),this.warnings=[])}}),bp.Views.uploaderWarning=bp.View.extend({tagName:"p",className:"warning",initialize:function(){this.value=this.options.value},render:function(){return this.$el.html(this.value),this}}),bp.Views.uploaderStatus=bp.View.extend({className:"files",initialize:function(){_.each(this.collection.models,this.addFile,this),this.collection.on("change:percent",this.progress,this),bp.Uploader.filesError.on("add",this.feedback,this)},addFile:function(a){this.views.add(new bp.Views.uploaderProgress({model:a}))},progress:function(a){_.isUndefined(a.get("percent"))||b("#"+a.get("id")+" .bp-progress .bp-bar").css("width",a.get("percent")+"%")},feedback:function(a){_.isUndefined(a.get("message"))||_.isUndefined(a.get("file"))||b("#"+a.get("file").id).html(a.get("message")).addClass("error")}}),bp.Views.uploaderProgress=bp.View.extend({className:"bp-uploader-progress",template:bp.template("progress-window")}))}(bp,jQuery);
1
+ window.wp=window.wp||{},window.bp=window.bp||{},function(a,b){"undefined"!=typeof BP_Uploader&&(_.extend(bp,_.pick(wp,"Backbone","ajax","template")),bp.Models=bp.Models||{},bp.Collections=bp.Collections||{},bp.Views=bp.Views||{},bp.Uploader={},bp.Uploader.uploader=function(){var a=this,c=navigator.userAgent.indexOf("Trident/")!==-1||navigator.userAgent.indexOf("MSIE ")!==-1;return this.params=BP_Uploader.settings,this.strings=BP_Uploader.strings,this.supports={upload:this.params.browser.supported},this.supported=this.supports.upload,this.supported?(c||"flash"!==plupload.predictRuntime(this.params.defaults)||this.params.defaults.required_features&&this.params.defaults.required_features.hasOwnProperty("send_binary_string")||(this.params.defaults.required_features=this.params.defaults.required_features||{},this.params.defaults.required_features.send_binary_string=!0),this.uploader=new plupload.Uploader(this.params.defaults),this.uploader.bind("Init",function(c){var d=b("#"+a.params.defaults.container),e=b("#"+a.params.defaults.drop_element);"html4"===c.runtime&&(c.settings.multipart_params.html4=!0),"bp_avatar_upload"===c.settings.multipart_params.action&&(c.settings.multipart_params.bp_params.ui_available_width=d.width()),c.features.dragdrop&&!a.params.browser.mobile?(d.addClass("drag-drop"),e.bind("dragover.wp-uploader",function(){d.addClass("drag-over")}).bind("dragleave.wp-uploader, drop.wp-uploader",function(){d.removeClass("drag-over")})):(d.removeClass("drag-drop"),e.unbind(".wp-uploader"))}),this.uploader.init(),this.feedback=function(a,b,c){!_.isNull(c)&&c.item&&c.item.clear(),bp.Uploader.filesError.unshift({message:a,data:b,file:c})},this.uploader.bind("FilesAdded",function(c,d){var e=104857600,f=parseInt(c.settings.max_file_size,10),g=this;if(!c.settings.multi_selection&&d.length>1){for(var h in d)c.removeFile(d[h]);return void b(a).trigger("bp-uploader-warning",a.strings.unique_file_warning)}_.each(d,function(a){var b;plupload.FAILED!==a.status&&(f>e&&a.size>e&&"html5"!==c.runtime?g.uploadSizeError(c,a,!0):(b=_.extend({id:a.id,file:a,uploading:!0,date:new Date,filename:a.name},_.pick(a,"loaded","size","percent")),a.item=new bp.Models.File(b),bp.Uploader.filesQueue.add(a.item)))}),c.refresh(),c.start()}),this.uploader.bind("UploadProgress",function(a,b){b.item.set(_.pick(b,"loaded","percent"))}),this.uploader.bind("FileUploaded",function(b,c,d){var e=a.strings.default_error;try{d=JSON.parse(d.response)}catch(b){return a.feedback(e,b,c)}return!_.isObject(d)||_.isUndefined(d.success)?a.feedback(e,null,c):d.success?(_.each(["file","loaded","size","percent"],function(a){c.item.unset(a)}),c.item.set(_.extend(d.data,{uploading:!1})),void bp.Uploader.filesUploaded.add(c.item)):(d.data&&d.data.message&&(e=d.data.message),a.feedback(e,d.data,c))}),this.uploader.bind("BeforeUpload",function(c,d){b(a).trigger("bp-uploader-new-upload",c,d)}),this.uploader.bind("UploadComplete",function(c,d){b(a).trigger("bp-uploader-upload-complete",c,d),bp.Uploader.filesQueue.reset()}),void this.uploader.bind("Error",function(c,d){var e,f=a.strings.default_error,g={FAILED:a.strings.upload_failed,FILE_EXTENSION_ERROR:a.strings.invalid_filetype,IMAGE_FORMAT_ERROR:a.strings.not_an_image,IMAGE_MEMORY_ERROR:a.strings.image_memory_exceeded,IMAGE_DIMENSIONS_ERROR:a.strings.image_dimensions_exceeded,GENERIC_ERROR:a.strings.upload_failed,IO_ERROR:a.strings.io_error,HTTP_ERROR:a.strings.http_error,SECURITY_ERROR:a.strings.security_error,FILE_SIZE_ERROR:a.strings.file_exceeds_size_limit.replace("%s",d.file.name)};for(e in g)if(d.code===plupload[e]){f=g[e];break}b(a).trigger("bp-uploader-warning",f),c.refresh()})):void(BP_Uploader=void 0)},bp.Models.File=Backbone.Model.extend({file:{}}),b.extend(bp.Uploader,{filesQueue:new Backbone.Collection,filesUploaded:new Backbone.Collection,filesError:new Backbone.Collection}),bp.View=bp.Backbone.View.extend({inject:function(a){this.render(),b(a).html(this.el),this.views.ready()},prepare:function(){return!_.isUndefined(this.model)&&_.isFunction(this.model.toJSON)?this.model.toJSON():{}}}),bp.Views.Uploader=bp.View.extend({className:"bp-uploader-window",template:bp.template("upload-window"),defaults:_.pick(BP_Uploader.settings.defaults,"container","drop_element","browse_button"),initialize:function(){this.warnings=[],this.model=new Backbone.Model(this.defaults),this.on("ready",this.initUploader)},initUploader:function(){this.uploader=new bp.Uploader.uploader,b(this.uploader).on("bp-uploader-warning",_.bind(this.setWarning,this)),b(this.uploader).on("bp-uploader-new-upload",_.bind(this.resetWarning,this))},setWarning:function(a,b){if(!_.isUndefined(b)){var c=new bp.Views.uploaderWarning({value:b}).render();this.warnings.push(c),this.$el.after(c.el)}},resetWarning:function(){0!==this.warnings.length&&(_.each(this.warnings,function(a){a.remove()}),this.warnings=[])}}),bp.Views.uploaderWarning=bp.View.extend({tagName:"p",className:"warning",initialize:function(){this.value=this.options.value},render:function(){return this.$el.html(this.value),this}}),bp.Views.uploaderStatus=bp.View.extend({className:"files",initialize:function(){_.each(this.collection.models,this.addFile,this),this.collection.on("change:percent",this.progress,this),bp.Uploader.filesError.on("add",this.feedback,this)},addFile:function(a){this.views.add(new bp.Views.uploaderProgress({model:a}))},progress:function(a){_.isUndefined(a.get("percent"))||b("#"+a.get("id")+" .bp-progress .bp-bar").css("width",a.get("percent")+"%")},feedback:function(a){_.isUndefined(a.get("message"))||_.isUndefined(a.get("file"))||b("#"+a.get("file").id).html(a.get("message")).addClass("error")}}),bp.Views.uploaderProgress=bp.View.extend({className:"bp-uploader-progress",template:bp.template("progress-window")}))}(bp,jQuery);
 
bp-core/js/confirm.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
- jQuery(document).ready(function(){jQuery("a.confirm").click(function(){return confirm(BP_Confirm.are_you_sure)?!0:!1})});
1
+ jQuery(document).ready(function(){jQuery("a.confirm").click(function(){return!!confirm(BP_Confirm.are_you_sure)})});
 
bp-core/js/cover-image.js CHANGED
@@ -1,277 +1,277 @@
1
- /* global bp, BP_Uploader, _, Backbone */
2
-
3
- window.bp = window.bp || {};
4
-
5
- ( function( exports, $ ) {
6
-
7
- // Bail if not set
8
- if ( typeof BP_Uploader === 'undefined' ) {
9
- return;
10
- }
11
-
12
- bp.Models = bp.Models || {};
13
- bp.Collections = bp.Collections || {};
14
- bp.Views = bp.Views || {};
15
-
16
- bp.CoverImage = {
17
- start: function() {
18
-
19
- // Init some vars
20
- this.views = new Backbone.Collection();
21
- this.warning = null;
22
-
23
- // The Cover Image Attachment object.
24
- this.Attachment = new Backbone.Model();
25
-
26
- // Set up views
27
- this.uploaderView();
28
-
29
- // Inform about the needed dimensions
30
- this.displayWarning( BP_Uploader.strings.cover_image_warnings.dimensions );
31
-
32
- // Set up the delete view if needed
33
- if ( true === BP_Uploader.settings.defaults.multipart_params.bp_params.has_cover_image ) {
34
- this.deleteView();
35
- }
36
- },
37
-
38
- uploaderView: function() {
39
- // Listen to the Queued uploads
40
- bp.Uploader.filesQueue.on( 'add', this.uploadProgress, this );
41
-
42
- // Create the BuddyPress Uploader
43
- var uploader = new bp.Views.Uploader();
44
-
45
- // Add it to views
46
- this.views.add( { id: 'upload', view: uploader } );
47
-
48
- // Display it
49
- uploader.inject( '.bp-cover-image' );
50
- },
51
-
52
- uploadProgress: function() {
53
- // Create the Uploader status view
54
- var coverImageUploadProgress = new bp.Views.coverImageUploadProgress( { collection: bp.Uploader.filesQueue } );
55
-
56
- if ( ! _.isUndefined( this.views.get( 'status' ) ) ) {
57
- this.views.set( { id: 'status', view: coverImageUploadProgress } );
58
- } else {
59
- this.views.add( { id: 'status', view: coverImageUploadProgress } );
60
- }
61
-
62
- // Display it
63
- coverImageUploadProgress.inject( '.bp-cover-image-status' );
64
- },
65
-
66
- deleteView: function() {
67
- // Create the delete model
68
- var delete_model = new Backbone.Model( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
69
- ['object', 'item_id', 'nonces']
70
- ) );
71
-
72
- // Do not add it if already there!
73
- if ( ! _.isUndefined( this.views.get( 'delete' ) ) ) {
74
- return;
75
- }
76
-
77
- // Create the delete view
78
- var deleteView = new bp.Views.DeleteCoverImage( { model: delete_model } );
79
-
80
- // Add it to views
81
- this.views.add( { id: 'delete', view: deleteView } );
82
-
83
- // Display it
84
- deleteView.inject( '.bp-cover-image-manage' );
85
- },
86
-
87
- deleteCoverImage: function( model ) {
88
- var self = this,
89
- deleteView;
90
-
91
- // Remove the delete view
92
- if ( ! _.isUndefined( this.views.get( 'delete' ) ) ) {
93
- deleteView = this.views.get( 'delete' );
94
- deleteView.get( 'view' ).remove();
95
- this.views.remove( { id: 'delete', view: deleteView } );
96
- }
97
-
98
- // Remove the cover image !
99
- bp.ajax.post( 'bp_cover_image_delete', {
100
- json: true,
101
- item_id: model.get( 'item_id' ),
102
- object: model.get( 'object' ),
103
- nonce: model.get( 'nonces' ).remove
104
- } ).done( function( response ) {
105
- var coverImageStatus = new bp.Views.CoverImageStatus( {
106
- value : BP_Uploader.strings.feedback_messages[ response.feedback_code ],
107
- type : 'success'
108
- } );
109
-
110
- self.views.add( {
111
- id : 'status',
112
- view : coverImageStatus
113
- } );
114
-
115
- coverImageStatus.inject( '.bp-cover-image-status' );
116
-
117
- // Reset the header of the page
118
- if ( '' === response.reset_url ) {
119
- $( '#header-cover-image' ).css( {
120
- 'background-image': 'none'
121
- } );
122
- } else {
123
- $( '#header-cover-image' ).css( {
124
- 'background-image': 'url( ' + response.reset_url + ' )'
125
- } );
126
- }
127
-
128
- // Reset the has_cover_image bp_param
129
- BP_Uploader.settings.defaults.multipart_params.bp_params.has_cover_image = false;
130
-
131
- /**
132
- * Reset the Attachment object
133
- *
134
- * You can run extra actions once the cover image is set using:
135
- * bp.CoverImage.Attachment.on( 'change:url', function( data ) { your code } );
136
- *
137
- * In this case data.attributes will include the default url for the
138
- * cover image (most of the time: ''), the object and the item_id concerned.
139
- */
140
- self.Attachment.set( _.extend(
141
- _.pick( model.attributes, ['object', 'item_id'] ),
142
- { url: response.reset_url, action: 'deleted' }
143
- ) );
144
-
145
- } ).fail( function( response ) {
146
- var feedback = BP_Uploader.strings.default_error;
147
- if ( ! _.isUndefined( response ) ) {
148
- feedback = BP_Uploader.strings.feedback_messages[ response.feedback_code ];
149
- }
150
-
151
- var coverImageStatus = new bp.Views.CoverImageStatus( {
152
- value : feedback,
153
- type : 'error'
154
- } );
155
-
156
- self.views.add( {
157
- id : 'status',
158
- view : coverImageStatus
159
- } );
160
-
161
- coverImageStatus.inject( '.bp-cover-image-status' );
162
-
163
- // Put back the delete view
164
- bp.CoverImage.deleteView();
165
- } );
166
- },
167
-
168
- removeWarning: function() {
169
- if ( ! _.isNull( this.warning ) ) {
170
- this.warning.remove();
171
- }
172
- },
173
-
174
- displayWarning: function( message ) {
175
- this.removeWarning();
176
-
177
- this.warning = new bp.Views.uploaderWarning( {
178
- value: message
179
- } );
180
-
181
- this.warning.inject( '.bp-cover-image-status' );
182
- }
183
- };
184
-
185
- // Custom Uploader Files view
186
- bp.Views.coverImageUploadProgress = bp.Views.uploaderStatus.extend( {
187
- className: 'files',
188
-
189
- initialize: function() {
190
- bp.Views.uploaderStatus.prototype.initialize.apply( this, arguments );
191
-
192
- this.collection.on( 'change:url', this.uploadResult, this );
193
- },
194
-
195
- uploadResult: function( model ) {
196
- var message, type;
197
-
198
- if ( ! _.isUndefined( model.get( 'url' ) ) ) {
199
-
200
- // Image is too small
201
- if ( 0 === model.get( 'feedback_code' ) ) {
202
- message = BP_Uploader.strings.cover_image_warnings.dimensions;
203
- type = 'warning';
204
-
205
- // Success, Rock n roll!
206
- } else {
207
- message = BP_Uploader.strings.feedback_messages[ model.get( 'feedback_code' ) ];
208
- type = 'success';
209
- }
210
-
211
- this.views.set( '.bp-uploader-progress', new bp.Views.CoverImageStatus( {
212
- value : message,
213
- type : type
214
- } ) );
215
-
216
- // Update the header of the page
217
- $( '#header-cover-image' ).css( {
218
- 'background-image': 'url( ' + model.get( 'url' ) + ' )'
219
- } );
220
-
221
- // Add the delete view
222
- bp.CoverImage.deleteView();
223
-
224
- /**
225
- * Set the Attachment object
226
- *
227
- * You can run extra actions once the cover image is set using:
228
- * bp.CoverImage.Attachment.on( 'change:url', function( data ) { your code } );
229
- *
230
- * In this case data.attributes will include the url to the newly
231
- * uploaded cover image, the object and the item_id concerned.
232
- */
233
- bp.CoverImage.Attachment.set( _.extend(
234
- _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params, ['object', 'item_id'] ),
235
- { url: model.get( 'url' ), action: 'uploaded' }
236
- ) );
237
- }
238
- }
239
- } );
240
-
241
- // BuddyPress Cover Image Feedback view
242
- bp.Views.CoverImageStatus = bp.View.extend( {
243
- tagName: 'p',
244
- className: 'updated',
245
- id: 'bp-cover-image-feedback',
246
-
247
- initialize: function() {
248
- this.el.className += ' ' + this.options.type;
249
- this.value = this.options.value;
250
- },
251
-
252
- render: function() {
253
- this.$el.html( this.value );
254
- return this;
255
- }
256
- } );
257
-
258
- // BuddyPress Cover Image Delete view
259
- bp.Views.DeleteCoverImage = bp.View.extend( {
260
- tagName: 'div',
261
- id: 'bp-delete-cover-image-container',
262
- template: bp.template( 'bp-cover-image-delete' ),
263
-
264
- events: {
265
- 'click #bp-delete-cover-image': 'deleteCoverImage'
266
- },
267
-
268
- deleteCoverImage: function( event ) {
269
- event.preventDefault();
270
-
271
- bp.CoverImage.deleteCoverImage( this.model );
272
- }
273
- } );
274
-
275
- bp.CoverImage.start();
276
-
277
- })( bp, jQuery );
1
+ /* global bp, BP_Uploader, _, Backbone */
2
+
3
+ window.bp = window.bp || {};
4
+
5
+ ( function( exports, $ ) {
6
+
7
+ // Bail if not set
8
+ if ( typeof BP_Uploader === 'undefined' ) {
9
+ return;
10
+ }
11
+
12
+ bp.Models = bp.Models || {};
13
+ bp.Collections = bp.Collections || {};
14
+ bp.Views = bp.Views || {};
15
+
16
+ bp.CoverImage = {
17
+ start: function() {
18
+
19
+ // Init some vars
20
+ this.views = new Backbone.Collection();
21
+ this.warning = null;
22
+
23
+ // The Cover Image Attachment object.
24
+ this.Attachment = new Backbone.Model();
25
+
26
+ // Set up views
27
+ this.uploaderView();
28
+
29
+ // Inform about the needed dimensions
30
+ this.displayWarning( BP_Uploader.strings.cover_image_warnings.dimensions );
31
+
32
+ // Set up the delete view if needed
33
+ if ( true === BP_Uploader.settings.defaults.multipart_params.bp_params.has_cover_image ) {
34
+ this.deleteView();
35
+ }
36
+ },
37
+
38
+ uploaderView: function() {
39
+ // Listen to the Queued uploads
40
+ bp.Uploader.filesQueue.on( 'add', this.uploadProgress, this );
41
+
42
+ // Create the BuddyPress Uploader
43
+ var uploader = new bp.Views.Uploader();
44
+
45
+ // Add it to views
46
+ this.views.add( { id: 'upload', view: uploader } );
47
+
48
+ // Display it
49
+ uploader.inject( '.bp-cover-image' );
50
+ },
51
+
52
+ uploadProgress: function() {
53
+ // Create the Uploader status view
54
+ var coverImageUploadProgress = new bp.Views.coverImageUploadProgress( { collection: bp.Uploader.filesQueue } );
55
+
56
+ if ( ! _.isUndefined( this.views.get( 'status' ) ) ) {
57
+ this.views.set( { id: 'status', view: coverImageUploadProgress } );
58
+ } else {
59
+ this.views.add( { id: 'status', view: coverImageUploadProgress } );
60
+ }
61
+
62
+ // Display it
63
+ coverImageUploadProgress.inject( '.bp-cover-image-status' );
64
+ },
65
+
66
+ deleteView: function() {
67
+ // Create the delete model
68
+ var delete_model = new Backbone.Model( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
69
+ ['object', 'item_id', 'nonces']
70
+ ) );
71
+
72
+ // Do not add it if already there!
73
+ if ( ! _.isUndefined( this.views.get( 'delete' ) ) ) {
74
+ return;
75
+ }
76
+
77
+ // Create the delete view
78
+ var deleteView = new bp.Views.DeleteCoverImage( { model: delete_model } );
79
+
80
+ // Add it to views
81
+ this.views.add( { id: 'delete', view: deleteView } );
82
+
83
+ // Display it
84
+ deleteView.inject( '.bp-cover-image-manage' );
85
+ },
86
+
87
+ deleteCoverImage: function( model ) {
88
+ var self = this,
89
+ deleteView;
90
+
91
+ // Remove the delete view
92
+ if ( ! _.isUndefined( this.views.get( 'delete' ) ) ) {
93
+ deleteView = this.views.get( 'delete' );
94
+ deleteView.get( 'view' ).remove();
95
+ this.views.remove( { id: 'delete', view: deleteView } );
96
+ }
97
+
98
+ // Remove the cover image !
99
+ bp.ajax.post( 'bp_cover_image_delete', {
100
+ json: true,
101
+ item_id: model.get( 'item_id' ),
102
+ object: model.get( 'object' ),
103
+ nonce: model.get( 'nonces' ).remove
104
+ } ).done( function( response ) {
105
+ var coverImageStatus = new bp.Views.CoverImageStatus( {
106
+ value : BP_Uploader.strings.feedback_messages[ response.feedback_code ],
107
+ type : 'success'
108
+ } );
109
+
110
+ self.views.add( {
111
+ id : 'status',
112
+ view : coverImageStatus
113
+ } );
114
+
115
+ coverImageStatus.inject( '.bp-cover-image-status' );
116
+
117
+ // Reset the header of the page
118
+ if ( '' === response.reset_url ) {
119
+ $( '#header-cover-image' ).css( {
120
+ 'background-image': 'none'
121
+ } );
122
+ } else {
123
+ $( '#header-cover-image' ).css( {
124
+ 'background-image': 'url( ' + response.reset_url + ' )'
125
+ } );
126
+ }
127
+
128
+ // Reset the has_cover_image bp_param
129
+ BP_Uploader.settings.defaults.multipart_params.bp_params.has_cover_image = false;
130
+
131
+ /**
132
+ * Reset the Attachment object
133
+ *
134
+ * You can run extra actions once the cover image is set using:
135
+ * bp.CoverImage.Attachment.on( 'change:url', function( data ) { your code } );
136
+ *
137
+ * In this case data.attributes will include the default url for the
138
+ * cover image (most of the time: ''), the object and the item_id concerned.
139
+ */
140
+ self.Attachment.set( _.extend(
141
+ _.pick( model.attributes, ['object', 'item_id'] ),
142
+ { url: response.reset_url, action: 'deleted' }
143
+ ) );
144
+
145
+ } ).fail( function( response ) {
146
+ var feedback = BP_Uploader.strings.default_error;
147
+ if ( ! _.isUndefined( response ) ) {
148
+ feedback = BP_Uploader.strings.feedback_messages[ response.feedback_code ];
149
+ }
150
+
151
+ var coverImageStatus = new bp.Views.CoverImageStatus( {
152
+ value : feedback,
153
+ type : 'error'
154
+ } );
155
+
156
+ self.views.add( {
157
+ id : 'status',
158
+ view : coverImageStatus
159
+ } );
160
+
161
+ coverImageStatus.inject( '.bp-cover-image-status' );
162
+
163
+ // Put back the delete view
164
+ bp.CoverImage.deleteView();
165
+ } );
166
+ },
167
+
168
+ removeWarning: function() {
169
+ if ( ! _.isNull( this.warning ) ) {
170
+ this.warning.remove();
171
+ }
172
+ },
173
+
174
+ displayWarning: function( message ) {
175
+ this.removeWarning();
176
+
177
+ this.warning = new bp.Views.uploaderWarning( {
178
+ value: message
179
+ } );
180
+
181
+ this.warning.inject( '.bp-cover-image-status' );
182
+ }
183
+ };
184
+
185
+ // Custom Uploader Files view
186
+ bp.Views.coverImageUploadProgress = bp.Views.uploaderStatus.extend( {
187
+ className: 'files',
188
+
189
+ initialize: function() {
190
+ bp.Views.uploaderStatus.prototype.initialize.apply( this, arguments );
191
+
192
+ this.collection.on( 'change:url', this.uploadResult, this );
193
+ },
194
+
195
+ uploadResult: function( model ) {
196
+ var message, type;
197
+
198
+ if ( ! _.isUndefined( model.get( 'url' ) ) ) {
199
+
200
+ // Image is too small
201
+ if ( 0 === model.get( 'feedback_code' ) ) {
202
+ message = BP_Uploader.strings.cover_image_warnings.dimensions;
203
+ type = 'warning';
204
+
205
+ // Success, Rock n roll!
206
+ } else {
207
+ message = BP_Uploader.strings.feedback_messages[ model.get( 'feedback_code' ) ];
208
+ type = 'success';
209
+ }
210
+
211
+ this.views.set( '.bp-uploader-progress', new bp.Views.CoverImageStatus( {
212
+ value : message,
213
+ type : type
214
+ } ) );
215
+
216
+ // Update the header of the page
217
+ $( '#header-cover-image' ).css( {
218
+ 'background-image': 'url( ' + model.get( 'url' ) + ' )'
219
+ } );
220
+
221
+ // Add the delete view
222
+ bp.CoverImage.deleteView();
223
+
224
+ /**
225
+ * Set the Attachment object
226
+ *
227
+ * You can run extra actions once the cover image is set using:
228
+ * bp.CoverImage.Attachment.on( 'change:url', function( data ) { your code } );
229
+ *
230
+ * In this case data.attributes will include the url to the newly
231
+ * uploaded cover image, the object and the item_id concerned.
232
+ */
233
+ bp.CoverImage.Attachment.set( _.extend(
234
+ _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params, ['object', 'item_id'] ),
235
+ { url: model.get( 'url' ), action: 'uploaded' }
236
+ ) );
237
+ }
238
+ }
239
+ } );
240
+
241
+ // BuddyPress Cover Image Feedback view
242
+ bp.Views.CoverImageStatus = bp.View.extend( {
243
+ tagName: 'p',
244
+ className: 'updated',
245
+ id: 'bp-cover-image-feedback',
246
+
247
+ initialize: function() {
248
+ this.el.className += ' ' + this.options.type;
249
+ this.value = this.options.value;
250
+ },
251
+
252
+ render: function() {
253
+ this.$el.html( this.value );
254
+ return this;
255
+ }
256
+ } );
257
+
258
+ // BuddyPress Cover Image Delete view
259
+ bp.Views.DeleteCoverImage = bp.View.extend( {
260
+ tagName: 'div',
261
+ id: 'bp-delete-cover-image-container',
262
+ template: bp.template( 'bp-cover-image-delete' ),
263
+
264
+ events: {
265
+ 'click #bp-delete-cover-image': 'deleteCoverImage'
266
+ },
267
+
268
+ deleteCoverImage: function( event ) {
269
+ event.preventDefault();
270
+
271
+ bp.CoverImage.deleteCoverImage( this.model );
272
+ }
273
+ } );
274
+
275
+ bp.CoverImage.start();
276
+
277
+ })( bp, jQuery );
bp-core/js/cover-image.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
  window.bp=window.bp||{},function(a,b){"undefined"!=typeof BP_Uploader&&(bp.Models=bp.Models||{},bp.Collections=bp.Collections||{},bp.Views=bp.Views||{},bp.CoverImage={start:function(){this.views=new Backbone.Collection,this.warning=null,this.Attachment=new Backbone.Model,this.uploaderView(),this.displayWarning(BP_Uploader.strings.cover_image_warnings.dimensions),!0===BP_Uploader.settings.defaults.multipart_params.bp_params.has_cover_image&&this.deleteView()},uploaderView:function(){bp.Uploader.filesQueue.on("add",this.uploadProgress,this);var a=new bp.Views.Uploader;this.views.add({id:"upload",view:a}),a.inject(".bp-cover-image")},uploadProgress:function(){var a=new bp.Views.coverImageUploadProgress({collection:bp.Uploader.filesQueue});_.isUndefined(this.views.get("status"))?this.views.add({id:"status",view:a}):this.views.set({id:"status",view:a}),a.inject(".bp-cover-image-status")},deleteView:function(){var a=new Backbone.Model(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,["object","item_id","nonces"]));if(_.isUndefined(this.views.get("delete"))){var b=new bp.Views.DeleteCoverImage({model:a});this.views.add({id:"delete",view:b}),b.inject(".bp-cover-image-manage")}},deleteCoverImage:function(a){var c,d=this;_.isUndefined(this.views.get("delete"))||(c=this.views.get("delete"),c.get("view").remove(),this.views.remove({id:"delete",view:c})),bp.ajax.post("bp_cover_image_delete",{json:!0,item_id:a.get("item_id"),object:a.get("object"),nonce:a.get("nonces").remove}).done(function(c){var e=new bp.Views.CoverImageStatus({value:BP_Uploader.strings.feedback_messages[c.feedback_code],type:"success"});d.views.add({id:"status",view:e}),e.inject(".bp-cover-image-status"),""===c.reset_url?b("#header-cover-image").css({"background-image":"none"}):b("#header-cover-image").css({"background-image":"url( "+c.reset_url+" )"}),BP_Uploader.settings.defaults.multipart_params.bp_params.has_cover_image=!1,d.Attachment.set(_.extend(_.pick(a.attributes,["object","item_id"]),{url:c.reset_url,action:"deleted"}))}).fail(function(a){var b=BP_Uploader.strings.default_error;_.isUndefined(a)||(b=BP_Uploader.strings.feedback_messages[a.feedback_code]);var c=new bp.Views.CoverImageStatus({value:b,type:"error"});d.views.add({id:"status",view:c}),c.inject(".bp-cover-image-status"),bp.CoverImage.deleteView()})},removeWarning:function(){_.isNull(this.warning)||this.warning.remove()},displayWarning:function(a){this.removeWarning(),this.warning=new bp.Views.uploaderWarning({value:a}),this.warning.inject(".bp-cover-image-status")}},bp.Views.coverImageUploadProgress=bp.Views.uploaderStatus.extend({className:"files",initialize:function(){bp.Views.uploaderStatus.prototype.initialize.apply(this,arguments),this.collection.on("change:url",this.uploadResult,this)},uploadResult:function(a){var c,d;_.isUndefined(a.get("url"))||(0===a.get("feedback_code")?(c=BP_Uploader.strings.cover_image_warnings.dimensions,d="warning"):(c=BP_Uploader.strings.feedback_messages[a.get("feedback_code")],d="success"),this.views.set(".bp-uploader-progress",new bp.Views.CoverImageStatus({value:c,type:d})),b("#header-cover-image").css({"background-image":"url( "+a.get("url")+" )"}),bp.CoverImage.deleteView(),bp.CoverImage.Attachment.set(_.extend(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,["object","item_id"]),{url:a.get("url"),action:"uploaded"})))}}),bp.Views.CoverImageStatus=bp.View.extend({tagName:"p",className:"updated",id:"bp-cover-image-feedback",initialize:function(){this.el.className+=" "+this.options.type,this.value=this.options.value},render:function(){return this.$el.html(this.value),this}}),bp.Views.DeleteCoverImage=bp.View.extend({tagName:"div",id:"bp-delete-cover-image-container",template:bp.template("bp-cover-image-delete"),events:{"click #bp-delete-cover-image":"deleteCoverImage"},deleteCoverImage:function(a){a.preventDefault(),bp.CoverImage.deleteCoverImage(this.model)}}),bp.CoverImage.start())}(bp,jQuery);
 
1
  window.bp=window.bp||{},function(a,b){"undefined"!=typeof BP_Uploader&&(bp.Models=bp.Models||{},bp.Collections=bp.Collections||{},bp.Views=bp.Views||{},bp.CoverImage={start:function(){this.views=new Backbone.Collection,this.warning=null,this.Attachment=new Backbone.Model,this.uploaderView(),this.displayWarning(BP_Uploader.strings.cover_image_warnings.dimensions),!0===BP_Uploader.settings.defaults.multipart_params.bp_params.has_cover_image&&this.deleteView()},uploaderView:function(){bp.Uploader.filesQueue.on("add",this.uploadProgress,this);var a=new bp.Views.Uploader;this.views.add({id:"upload",view:a}),a.inject(".bp-cover-image")},uploadProgress:function(){var a=new bp.Views.coverImageUploadProgress({collection:bp.Uploader.filesQueue});_.isUndefined(this.views.get("status"))?this.views.add({id:"status",view:a}):this.views.set({id:"status",view:a}),a.inject(".bp-cover-image-status")},deleteView:function(){var a=new Backbone.Model(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,["object","item_id","nonces"]));if(_.isUndefined(this.views.get("delete"))){var b=new bp.Views.DeleteCoverImage({model:a});this.views.add({id:"delete",view:b}),b.inject(".bp-cover-image-manage")}},deleteCoverImage:function(a){var c,d=this;_.isUndefined(this.views.get("delete"))||(c=this.views.get("delete"),c.get("view").remove(),this.views.remove({id:"delete",view:c})),bp.ajax.post("bp_cover_image_delete",{json:!0,item_id:a.get("item_id"),object:a.get("object"),nonce:a.get("nonces").remove}).done(function(c){var e=new bp.Views.CoverImageStatus({value:BP_Uploader.strings.feedback_messages[c.feedback_code],type:"success"});d.views.add({id:"status",view:e}),e.inject(".bp-cover-image-status"),""===c.reset_url?b("#header-cover-image").css({"background-image":"none"}):b("#header-cover-image").css({"background-image":"url( "+c.reset_url+" )"}),BP_Uploader.settings.defaults.multipart_params.bp_params.has_cover_image=!1,d.Attachment.set(_.extend(_.pick(a.attributes,["object","item_id"]),{url:c.reset_url,action:"deleted"}))}).fail(function(a){var b=BP_Uploader.strings.default_error;_.isUndefined(a)||(b=BP_Uploader.strings.feedback_messages[a.feedback_code]);var c=new bp.Views.CoverImageStatus({value:b,type:"error"});d.views.add({id:"status",view:c}),c.inject(".bp-cover-image-status"),bp.CoverImage.deleteView()})},removeWarning:function(){_.isNull(this.warning)||this.warning.remove()},displayWarning:function(a){this.removeWarning(),this.warning=new bp.Views.uploaderWarning({value:a}),this.warning.inject(".bp-cover-image-status")}},bp.Views.coverImageUploadProgress=bp.Views.uploaderStatus.extend({className:"files",initialize:function(){bp.Views.uploaderStatus.prototype.initialize.apply(this,arguments),this.collection.on("change:url",this.uploadResult,this)},uploadResult:function(a){var c,d;_.isUndefined(a.get("url"))||(0===a.get("feedback_code")?(c=BP_Uploader.strings.cover_image_warnings.dimensions,d="warning"):(c=BP_Uploader.strings.feedback_messages[a.get("feedback_code")],d="success"),this.views.set(".bp-uploader-progress",new bp.Views.CoverImageStatus({value:c,type:d})),b("#header-cover-image").css({"background-image":"url( "+a.get("url")+" )"}),bp.CoverImage.deleteView(),bp.CoverImage.Attachment.set(_.extend(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,["object","item_id"]),{url:a.get("url"),action:"uploaded"})))}}),bp.Views.CoverImageStatus=bp.View.extend({tagName:"p",className:"updated",id:"bp-cover-image-feedback",initialize:function(){this.el.className+=" "+this.options.type,this.value=this.options.value},render:function(){return this.$el.html(this.value),this}}),bp.Views.DeleteCoverImage=bp.View.extend({tagName:"div",id:"bp-delete-cover-image-container",template:bp.template("bp-cover-image-delete"),events:{"click #bp-delete-cover-image":"deleteCoverImage"},deleteCoverImage:function(a){a.preventDefault(),bp.CoverImage.deleteCoverImage(this.model)}}),bp.CoverImage.start())}(bp,jQuery);
bp-core/js/jquery-query.min.js CHANGED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
  function bp_get_querystring(a){var b=location.search.split(a+"=")[1];return b?decodeURIComponent(b.split("&")[0]):null}
 
1
  function bp_get_querystring(a){var b=location.search.split(a+"=")[1];return b?decodeURIComponent(b.split("&")[0]):null}
bp-core/js/jquery.atwho.min.js DELETED
@@ -1,2 +0,0 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
- !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return a.returnExportsGlobal=b(c)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){var b,c,d,e,f,g,h,i=[].slice;c=function(){function b(b){this.current_flag=null,this.controllers={},this.alias_maps={},this.$inputor=a(b),this.setIframe(),this.listen()}return b.prototype.createContainer=function(b){return 0===(this.$el=a("#atwho-container",b)).length?a(b.body).append(this.$el=a("<div id='atwho-container'></div>")):void 0},b.prototype.setIframe=function(a,b){var c;return null==b&&(b=!1),a?(this.window=a.contentWindow,this.document=a.contentDocument||this.window.document,this.iframe=a):(this.document=document,this.window=window,this.iframe=null),(this.iframeStandalone=b)?(null!=(c=this.$el)&&c.remove(),this.createContainer(this.document)):this.createContainer(document)},b.prototype.controller=function(a){var b,c,d,e;if(this.alias_maps[a])c=this.controllers[this.alias_maps[a]];else{e=this.controllers;for(d in e)if(b=e[d],d===a){c=b;break}}return c?c:this.controllers[this.current_flag]},b.prototype.set_context_for=function(a){return this.current_flag=a,this},b.prototype.reg=function(a,b){var c,e;return c=(e=this.controllers)[a]||(e[a]=new d(this,a)),b.alias&&(this.alias_maps[b.alias]=a),c.init(b),this},b.prototype.listen=function(){return this.$inputor.on("keyup.atwhoInner",function(a){return function(b){return a.on_keyup(b)}}(this)).on("keydown.atwhoInner",function(a){return function(b){return a.on_keydown(b)}}(this)).on("scroll.atwhoInner",function(a){return function(b){var c;return null!=(c=a.controller())?c.view.hide(b):void 0}}(this)).on("blur.atwhoInner",function(a){return function(b){var c;return(c=a.controller())?c.view.hide(b,c.get_opt("display_timeout")):void 0}}(this)).on("click.atwhoInner",function(a){return function(b){return a.dispatch()}}(this))},b.prototype.shutdown=function(){var a,b,c;c=this.controllers;for(b in c)a=c[b],a.destroy(),delete this.controllers[b];return this.$inputor.off(".atwhoInner"),this.$el.remove()},b.prototype.dispatch=function(){return a.map(this.controllers,function(a){return function(b){var c;return(c=b.get_opt("delay"))?(clearTimeout(a.delayedCallback),a.delayedCallback=setTimeout(function(){return b.look_up()?a.set_context_for(b.at):void 0},c)):b.look_up()?a.set_context_for(b.at):void 0}}(this))},b.prototype.on_keyup=function(b){var c;switch(b.keyCode){case f.ESC:b.preventDefault(),null!=(c=this.controller())&&c.view.hide();break;case f.DOWN:case f.UP:case f.CTRL:a.noop();break;case f.P:case f.N:b.ctrlKey||this.dispatch();break;default:this.dispatch()}},b.prototype.on_keydown=function(b){var c,d;if(c=null!=(d=this.controller())?d.view:void 0,c&&c.visible())switch(b.keyCode){case f.ESC:b.preventDefault(),c.hide(b);break;case f.UP:b.preventDefault(),c.prev();break;case f.DOWN:b.preventDefault(),c.next();break;case f.P:if(!b.ctrlKey)return;b.preventDefault(),c.prev();break;case f.N:if(!b.ctrlKey)return;b.preventDefault(),c.next();break;case f.TAB:case f.ENTER:if(!c.visible())return;b.preventDefault(),c.choose(b);break;default:a.noop()}},b}(),d=function(){function b(b,c){this.app=b,this.at=c,this.$inputor=this.app.$inputor,this.id=this.$inputor[0].id||this.uid(),this.setting=null,this.query=null,this.pos=0,this.cur_rect=null,this.range=null,0===(this.$el=a("#atwho-ground-"+this.id,this.app.$el)).length&&this.app.$el.append(this.$el=a("<div id='atwho-ground-"+this.id+"'></div>")),this.model=new g(this),this.view=new h(this)}return b.prototype.uid=function(){return(Math.random().toString(16)+"000000000").substr(2,8)+(new Date).getTime()},b.prototype.init=function(b){return this.setting=a.extend({},this.setting||a.fn.atwho["default"],b),this.view.init(),this.model.reload(this.setting.data)},b.prototype.destroy=function(){return this.trigger("beforeDestroy"),this.model.destroy(),this.view.destroy(),this.$el.remove()},b.prototype.call_default=function(){var b,c,d;d=arguments[0],b=2<=arguments.length?i.call(arguments,1):[];try{return e[d].apply(this,b)}catch(f){return c=f,a.error(""+c+" Or maybe At.js doesn't have function "+d)}},b.prototype.trigger=function(a,b){var c,d;return null==b&&(b=[]),b.push(this),c=this.get_opt("alias"),d=c?""+a+"-"+c+".atwho":""+a+".atwho",this.$inputor.trigger(d,b)},b.prototype.callbacks=function(a){return this.get_opt("callbacks")[a]||e[a]},b.prototype.get_opt=function(a,b){var c;try{return this.setting[a]}catch(d){return c=d,null}},b.prototype.content=function(){var a;if(this.$inputor.is("textarea, input"))return this.$inputor.val();if(a=this.mark_range())return(a.startContainer.textContent||"").slice(0,a.startOffset)},b.prototype.catch_query=function(){var a,b,c,d,e,f;return b=this.content(),a=this.$inputor.caret("pos",{iframe:this.app.iframe}),f=b.slice(0,a),d=this.callbacks("matcher").call(this,this.at,f,this.get_opt("start_with_space")),"string"==typeof d&&d.length<=this.get_opt("max_len",20)?(e=a-d.length,c=e+d.length,this.pos=e,d={text:d,head_pos:e,end_pos:c},this.trigger("matched",[this.at,d.text])):(d=null,this.view.hide()),this.query=d},b.prototype.rect=function(){var b,c,d;if(b=this.$inputor.caret("offset",this.pos-1,{iframe:this.app.iframe}))return this.app.iframe&&!this.app.iframeStandalone&&(c=a(this.app.iframe).offset(),b.left+=c.left,b.top+=c.top),this.$inputor.is("[contentEditable]")&&(b=this.cur_rect||(this.cur_rect=b)),d=this.app.document.selection?0:2,{left:b.left,top:b.top,bottom:b.top+b.height+d}},b.prototype.reset_rect=function(){return this.$inputor.is("[contentEditable]")?this.cur_rect=null:void 0},b.prototype.mark_range=function(){var a;if(this.$inputor.is("[contentEditable]"))return this.app.window.getSelection&&(a=this.app.window.getSelection()).rangeCount>0?this.range=a.getRangeAt(0):this.app.document.selection?this.ie8_range=this.app.document.selection.createRange():void 0},b.prototype.insert_content_for=function(b){var c,d,e;return d=b.data("value"),e=this.get_opt("insert_tpl"),this.$inputor.is("textarea, input")||!e?d:(c=a.extend({},b.data("item-data"),{"atwho-data-value":d,"atwho-at":this.at}),this.callbacks("tpl_eval").call(this,e,c))},b.prototype.insert=function(b,c){var d,e,f,g,h,i,j,k,l,m,n,o;if(d=this.$inputor,l=this.callbacks("inserting_wrapper").call(this,d,b,this.get_opt("suffix")),d.is("textarea, input"))i=d.val(),j=i.slice(0,Math.max(this.query.head_pos-this.at.length,0)),k=""+j+l+i.slice(this.query.end_pos||0),d.val(k),d.caret("pos",j.length+l.length,{iframe:this.app.iframe});else if(g=this.range){for(f=g.startOffset-(this.query.end_pos-this.query.head_pos)-this.at.length,g.setStart(g.endContainer,Math.max(f,0)),g.setEnd(g.endContainer,g.endOffset),g.deleteContents(),o=a(l,this.app.document),m=0,n=o.length;n>m;m++)e=o[m],g.insertNode(e),g.setEndAfter(e),g.collapse(!1);h=this.app.window.getSelection(),h.removeAllRanges(),h.addRange(g)}else(g=this.ie8_range)&&(g.moveStart("character",this.query.end_pos-this.query.head_pos-this.at.length),g.pasteHTML(l),g.collapse(!1),g.select());return d.is(":focus")||d.focus(),d.change()},b.prototype.render_view=function(a){var b;return b=this.get_opt("search_key"),a=this.callbacks("sorter").call(this,this.query.text,a.slice(0,1001),b),this.view.render(a.slice(0,this.get_opt("limit")))},b.prototype.look_up=function(){var b,c;if(b=this.catch_query())return c=function(a){return a&&a.length>0?this.render_view(a):this.view.hide()},this.model.query(b.text,a.proxy(c,this)),b},b}(),g=function(){function b(a){this.context=a,this.at=this.context.at,this.storage=this.context.$inputor}return b.prototype.destroy=function(){return this.storage.data(this.at,null)},b.prototype.saved=function(){return this.fetch()>0},b.prototype.query=function(a,b){var c,d,e;return c=this.fetch(),d=this.context.get_opt("search_key"),c=this.context.callbacks("filter").call(this.context,a,c,d)||[],e=this.context.callbacks("remote_filter"),c.length>0||!e&&0===c.length?b(c):e.call(this.context,a,b)},b.prototype.fetch=function(){return this.storage.data(this.at)||[]},b.prototype.save=function(a){return this.storage.data(this.at,this.context.callbacks("before_save").call(this.context,a||[]))},b.prototype.load=function(a){return!this.saved()&&a?this._load(a):void 0},b.prototype.reload=function(a){return this._load(a)},b.prototype._load=function(b){return"string"==typeof b?a.ajax(b,{dataType:"json"}).done(function(a){return function(b){return a.save(b)}}(this)):this.save(b)},b}(),h=function(){function b(b){this.context=b,this.$el=a("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>"),this.timeout_id=null,this.context.$el.append(this.$el),this.bind_event()}return b.prototype.init=function(){var a;return a=this.context.get_opt("alias")||this.context.at.charCodeAt(0),this.$el.attr({id:"at-view-"+a})},b.prototype.destroy=function(){return this.$el.remove()},b.prototype.bind_event=function(){var b;return b=this.$el.find("ul"),b.on("mouseenter.atwho-view","li",function(c){return b.find(".cur").removeClass("cur"),a(c.currentTarget).addClass("cur")}).on("click.atwho-view","li",function(c){return function(d){return b.find(".cur").removeClass("cur"),a(d.currentTarget).addClass("cur"),c.choose(d),d.preventDefault()}}(this))},b.prototype.visible=function(){return this.$el.is(":visible")},b.prototype.choose=function(a){var b,c;return(b=this.$el.find(".cur")).length&&(c=this.context.insert_content_for(b),this.context.insert(this.context.callbacks("before_insert").call(this.context,c,b),b),this.context.trigger("inserted",[b,a]),this.hide(a)),this.context.get_opt("hide_without_suffix")?this.stop_showing=!0:void 0},b.prototype.reposition=function(b){var c,d,e,f;return f=this.context.app.iframeStandalone?this.context.app.window:window,b.bottom+this.$el.height()-a(f).scrollTop()>a(f).height()&&(b.bottom=b.top-this.$el.height()),b.left>(d=a(f).width()-this.$el.width()-5)&&(b.left=d),c={left:b.left,top:b.bottom},null!=(e=this.context.callbacks("before_reposition"))&&e.call(this.context,c),this.$el.offset(c),this.context.trigger("reposition",[c])},b.prototype.next=function(){var a,b;return a=this.$el.find(".cur").removeClass("cur"),b=a.next(),b.length||(b=this.$el.find("li:first")),b.addClass("cur"),this.$el.animate({scrollTop:Math.max(0,a.innerHeight()*(b.index()+2)-this.$el.height())},150)},b.prototype.prev=function(){var a,b;return a=this.$el.find(".cur").removeClass("cur"),b=a.prev(),b.length||(b=this.$el.find("li:last")),b.addClass("cur"),this.$el.animate({scrollTop:Math.max(0,a.innerHeight()*(b.index()+2)-this.$el.height())},150)},b.prototype.show=function(){var a;return this.stop_showing?void(this.stop_showing=!1):(this.context.mark_range(),this.visible()||(this.$el.show(),this.$el.scrollTop(0),this.context.trigger("shown")),(a=this.context.rect())?this.reposition(a):void 0)},b.prototype.hide=function(a,b){var c;if(this.visible())return isNaN(b)?(this.context.reset_rect(),this.$el.hide(),this.context.trigger("hidden",[a])):(c=function(a){return function(){return a.hide()}}(this),clearTimeout(this.timeout_id),this.timeout_id=setTimeout(c,b))},b.prototype.render=function(b){var c,d,e,f,g,h,i;if(!(a.isArray(b)&&b.length>0))return void this.hide();for(this.$el.find("ul").empty(),d=this.$el.find("ul"),g=this.context.get_opt("tpl"),h=0,i=b.length;i>h;h++)e=b[h],e=a.extend({},e,{"atwho-at":this.context.at}),f=this.context.callbacks("tpl_eval").call(this.context,g,e),c=a(this.context.callbacks("highlighter").call(this.context,f,this.context.query.text)),c.data("item-data",e),d.append(c);return this.show(),this.context.get_opt("highlight_first")?d.find("li:first").addClass("cur"):void 0},b}(),f={DOWN:40,UP:38,ESC:27,TAB:9,ENTER:13,CTRL:17,P:80,N:78},e={before_save:function(b){var c,d,e,f;if(!a.isArray(b))return b;for(f=[],d=0,e=b.length;e>d;d++)c=b[d],a.isPlainObject(c)?f.push(c):f.push({name:c});return f},matcher:function(a,b,c){var d,e,f,g;return a=a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),c&&(a="(?:^|\\s)"+a),f=decodeURI("%C3%80"),g=decodeURI("%C3%BF"),e=new RegExp(""+a+"([A-Za-z"+f+"-"+g+"0-9_+-]*)$|"+a+"([^\\x00-\\xff]*)$","gi"),d=e.exec(b),d?d[2]||d[1]:null},filter:function(a,b,c){var d,e,f,g;for(g=[],e=0,f=b.length;f>e;e++)d=b[e],~new String(d[c]).toLowerCase().indexOf(a.toLowerCase())&&g.push(d);return g},remote_filter:null,sorter:function(a,b,c){var d,e,f,g;if(!a)return b;for(g=[],e=0,f=b.length;f>e;e++)d=b[e],d.atwho_order=new String(d[c]).toLowerCase().indexOf(a.toLowerCase()),d.atwho_order>-1&&g.push(d);return g.sort(function(a,b){return a.atwho_order-b.atwho_order})},tpl_eval:function(a,b){var c;try{return a.replace(/\$\{([^\}]*)\}/g,function(a,c,d){return b[c]})}catch(d){return c=d,""}},highlighter:function(a,b){var c;return b?(c=new RegExp(">\\s*(\\w*?)("+b.replace("+","\\+")+")(\\w*)\\s*<","ig"),a.replace(c,function(a,b,c,d){return"> "+b+"<strong>"+c+"</strong>"+d+" <"})):a},before_insert:function(a,b){return a},inserting_wrapper:function(a,b,c){var d;return c=""===c?c:c||" ",a.is("textarea, input")?""+b+c:"true"===a.attr("contentEditable")?(c=" "===c?"&nbsp;":c,/firefox/i.test(navigator.userAgent)?d="<span>"+b+c+"</span>":(c="<span contenteditable='false'>"+c+"</span>",d="<span contenteditable='false'>"+b+c+"</span>"),this.app.document.selection&&(d="<span contenteditable='true'>"+b+"</span>"),d+"<span></span>"):void 0}},b={load:function(a,b){var c;return(c=this.controller(a))?c.model.load(b):void 0},setIframe:function(a,b){return this.setIframe(a,b),null},run:function(){return this.dispatch()},destroy:function(){return this.shutdown(),this.$inputor.data("atwho",null)}},a.fn.atwho=function(d){var e,f;return f=arguments,e=null,this.filter('textarea, input, [contenteditable=""], [contenteditable=true]').each(function(){var g,h;return(h=(g=a(this)).data("atwho"))||g.data("atwho",h=new c(this)),"object"!=typeof d&&d?b[d]&&h?e=b[d].apply(h,Array.prototype.slice.call(f,1)):a.error("Method "+d+" does not exist on jQuery.caret"):h.reg(d.at,d)}),e||this},a.fn.atwho["default"]={at:void 0,alias:void 0,data:null,tpl:"<li data-value='${atwho-at}${name}'>${name}</li>",insert_tpl:"<span id='${id}'>${atwho-data-value}</span>",callbacks:e,search_key:"name",suffix:void 0,hide_without_suffix:!1,start_with_space:!0,highlight_first:!0,limit:5,max_len:20,display_timeout:300,delay:null}});
 
 
bp-core/js/{jquery-cookie.js → vendor/jquery-cookie.js} RENAMED
File without changes
bp-core/js/{jquery-cookie.min.js → vendor/jquery-cookie.min.js} RENAMED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
- !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}});
1
+ !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(a){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;n<o;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0!==a.cookie(b)&&(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}});
 
bp-core/js/{jquery-scroll-to.js → vendor/jquery-scroll-to.js} RENAMED
File without changes
bp-core/js/{jquery-scroll-to.min.js → vendor/jquery-scroll-to.min.js} RENAMED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
- !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(b){return a.isFunction(b)||"object"==typeof b?b:{top:b,left:b}}var c=a.scrollTo=function(b,c,d){return a(window).scrollTo(b,c,d)};return c.defaults={axis:"xy",duration:parseFloat(a.fn.jquery)>=1.3?0:1,limit:!0},c.window=function(){return a(window)._scrollable()},a.fn._scrollable=function(){return this.map(function(){var b=this,c=!b.nodeName||-1!==a.inArray(b.nodeName.toLowerCase(),["iframe","#document","html","body"]);if(!c)return b;var d=(b.contentWindow||b).document||b.ownerDocument||b;return/webkit/i.test(navigator.userAgent)||"BackCompat"===d.compatMode?d.body:d.documentElement})},a.fn.scrollTo=function(d,e,f){return"object"==typeof e&&(f=e,e=0),"function"==typeof f&&(f={onAfter:f}),"max"===d&&(d=9e9),f=a.extend({},c.defaults,f),e=e||f.duration,f.queue=f.queue&&f.axis.length>1,f.queue&&(e/=2),f.offset=b(f.offset),f.over=b(f.over),this._scrollable().each(function(){function g(a){j.animate(l,e,f.easing,a&&function(){a.call(this,k,f)})}if(null!==d){var h,i=this,j=a(i),k=d,l={},m=j.is("html,body");switch(typeof k){case"number":case"string":if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(k)){k=b(k);break}if(k=m?a(k):a(k,this),!k.length)return;case"object":(k.is||k.style)&&(h=(k=a(k)).offset())}var n=a.isFunction(f.offset)&&f.offset(i,k)||f.offset;a.each(f.axis.split(""),function(a,b){var d="x"===b?"Left":"Top",e=d.toLowerCase(),o="scroll"+d,p=i[o],q=c.max(i,b);if(h)l[o]=h[e]+(m?0:p-j.offset()[e]),f.margin&&(l[o]-=parseInt(k.css("margin"+d))||0,l[o]-=parseInt(k.css("border"+d+"Width"))||0),l[o]+=n[e]||0,f.over[e]&&(l[o]+=k["x"===b?"width":"height"]()*f.over[e]);else{var r=k[e];l[o]=r.slice&&"%"===r.slice(-1)?parseFloat(r)/100*q:r}f.limit&&/^\d+$/.test(l[o])&&(l[o]=l[o]<=0?0:Math.min(l[o],q)),!a&&f.queue&&(p!==l[o]&&g(f.onAfterFirst),delete l[o])}),g(f.onAfter)}}).end()},c.max=function(b,c){var d="x"===c?"Width":"Height",e="scroll"+d;if(!a(b).is("html,body"))return b[e]-a(b)[d.toLowerCase()]();var f="client"+d,g=b.ownerDocument.documentElement,h=b.ownerDocument.body;return Math.max(g[e],h[e])-Math.min(g[f],h[f])},c});
1
+ !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(b){return a.isFunction(b)||"object"==typeof b?b:{top:b,left:b}}var c=a.scrollTo=function(b,c,d){return a(window).scrollTo(b,c,d)};return c.defaults={axis:"xy",duration:parseFloat(a.fn.jquery)>=1.3?0:1,limit:!0},c.window=function(){return a(window)._scrollable()},a.fn._scrollable=function(){return this.map(function(){var b=this,c=!b.nodeName||a.inArray(b.nodeName.toLowerCase(),["iframe","#document","html","body"])!==-1;if(!c)return b;var d=(b.contentWindow||b).document||b.ownerDocument||b;return/webkit/i.test(navigator.userAgent)||"BackCompat"===d.compatMode?d.body:d.documentElement})},a.fn.scrollTo=function(d,e,f){return"object"==typeof e&&(f=e,e=0),"function"==typeof f&&(f={onAfter:f}),"max"===d&&(d=9e9),f=a.extend({},c.defaults,f),e=e||f.duration,f.queue=f.queue&&f.axis.length>1,f.queue&&(e/=2),f.offset=b(f.offset),f.over=b(f.over),this._scrollable().each(function(){function g(a){j.animate(l,e,f.easing,a&&function(){a.call(this,k,f)})}if(null!==d){var h,i=this,j=a(i),k=d,l={},m=j.is("html,body");switch(typeof k){case"number":case"string":if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(k)){k=b(k);break}if(k=m?a(k):a(k,this),!k.length)return;case"object":(k.is||k.style)&&(h=(k=a(k)).offset())}var n=a.isFunction(f.offset)&&f.offset(i,k)||f.offset;a.each(f.axis.split(""),function(a,b){var d="x"===b?"Left":"Top",e=d.toLowerCase(),o="scroll"+d,p=i[o],q=c.max(i,b);if(h)l[o]=h[e]+(m?0:p-j.offset()[e]),f.margin&&(l[o]-=parseInt(k.css("margin"+d))||0,l[o]-=parseInt(k.css("border"+d+"Width"))||0),l[o]+=n[e]||0,f.over[e]&&(l[o]+=k["x"===b?"width":"height"]()*f.over[e]);else{var r=k[e];l[o]=r.slice&&"%"===r.slice(-1)?parseFloat(r)/100*q:r}f.limit&&/^\d+$/.test(l[o])&&(l[o]=l[o]<=0?0:Math.min(l[o],q)),!a&&f.queue&&(p!==l[o]&&g(f.onAfterFirst),delete l[o])}),g(f.onAfter)}}).end()},c.max=function(b,c){var d="x"===c?"Width":"Height",e="scroll"+d;if(!a(b).is("html,body"))return b[e]-a(b)[d.toLowerCase()]();var f="client"+d,g=b.ownerDocument.documentElement,h=b.ownerDocument.body;return Math.max(g[e],h[e])-Math.min(g[f],h[f])},c});
 
bp-core/js/{jquery.atwho.js → vendor/jquery.atwho.js} RENAMED
File without changes
bp-core/js/vendor/jquery.atwho.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return a.returnExportsGlobal=b(c)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){var b,c,d,e,f,g,h,i=[].slice;c=function(){function b(b){this.current_flag=null,this.controllers={},this.alias_maps={},this.$inputor=a(b),this.setIframe(),this.listen()}return b.prototype.createContainer=function(b){if(0===(this.$el=a("#atwho-container",b)).length)return a(b.body).append(this.$el=a("<div id='atwho-container'></div>"))},b.prototype.setIframe=function(a,b){var c;return null==b&&(b=!1),a?(this.window=a.contentWindow,this.document=a.contentDocument||this.window.document,this.iframe=a):(this.document=document,this.window=window,this.iframe=null),(this.iframeStandalone=b)?(null!=(c=this.$el)&&c.remove(),this.createContainer(this.document)):this.createContainer(document)},b.prototype.controller=function(a){var b,c,d,e;if(this.alias_maps[a])c=this.controllers[this.alias_maps[a]];else{e=this.controllers;for(d in e)if(b=e[d],d===a){c=b;break}}return c?c:this.controllers[this.current_flag]},b.prototype.set_context_for=function(a){return this.current_flag=a,this},b.prototype.reg=function(a,b){var c,e;return c=(e=this.controllers)[a]||(e[a]=new d(this,a)),b.alias&&(this.alias_maps[b.alias]=a),c.init(b),this},b.prototype.listen=function(){return this.$inputor.on("keyup.atwhoInner",function(a){return function(b){return a.on_keyup(b)}}(this)).on("keydown.atwhoInner",function(a){return function(b){return a.on_keydown(b)}}(this)).on("scroll.atwhoInner",function(a){return function(b){var c;return null!=(c=a.controller())?c.view.hide(b):void 0}}(this)).on("blur.atwhoInner",function(a){return function(b){var c;if(c=a.controller())return c.view.hide(b,c.get_opt("display_timeout"))}}(this)).on("click.atwhoInner",function(a){return function(b){return a.dispatch()}}(this))},b.prototype.shutdown=function(){var a,b,c;c=this.controllers;for(b in c)a=c[b],a.destroy(),delete this.controllers[b];return this.$inputor.off(".atwhoInner"),this.$el.remove()},b.prototype.dispatch=function(){return a.map(this.controllers,function(a){return function(b){var c;return(c=b.get_opt("delay"))?(clearTimeout(a.delayedCallback),a.delayedCallback=setTimeout(function(){if(b.look_up())return a.set_context_for(b.at)},c)):b.look_up()?a.set_context_for(b.at):void 0}}(this))},b.prototype.on_keyup=function(b){var c;switch(b.keyCode){case f.ESC:b.preventDefault(),null!=(c=this.controller())&&c.view.hide();break;case f.DOWN:case f.UP:case f.CTRL:a.noop();break;case f.P:case f.N:b.ctrlKey||this.dispatch();break;default:this.dispatch()}},b.prototype.on_keydown=function(b){var c,d;if(c=null!=(d=this.controller())?d.view:void 0,c&&c.visible())switch(b.keyCode){case f.ESC:b.preventDefault(),c.hide(b);break;case f.UP:b.preventDefault(),c.prev();break;case f.DOWN:b.preventDefault(),c.next();break;case f.P:if(!b.ctrlKey)return;b.preventDefault(),c.prev();break;case f.N:if(!b.ctrlKey)return;b.preventDefault(),c.next();break;case f.TAB:case f.ENTER:if(!c.visible())return;b.preventDefault(),c.choose(b);break;default:a.noop()}},b}(),d=function(){function b(b,c){this.app=b,this.at=c,this.$inputor=this.app.$inputor,this.id=this.$inputor[0].id||this.uid(),this.setting=null,this.query=null,this.pos=0,this.cur_rect=null,this.range=null,0===(this.$el=a("#atwho-ground-"+this.id,this.app.$el)).length&&this.app.$el.append(this.$el=a("<div id='atwho-ground-"+this.id+"'></div>")),this.model=new g(this),this.view=new h(this)}return b.prototype.uid=function(){return(Math.random().toString(16)+"000000000").substr(2,8)+(new Date).getTime()},b.prototype.init=function(b){return this.setting=a.extend({},this.setting||a.fn.atwho.default,b),this.view.init(),this.model.reload(this.setting.data)},b.prototype.destroy=function(){return this.trigger("beforeDestroy"),this.model.destroy(),this.view.destroy(),this.$el.remove()},b.prototype.call_default=function(){var b,c,d;d=arguments[0],b=2<=arguments.length?i.call(arguments,1):[];try{return e[d].apply(this,b)}catch(b){return c=b,a.error(""+c+" Or maybe At.js doesn't have function "+d)}},b.prototype.trigger=function(a,b){var c,d;return null==b&&(b=[]),b.push(this),c=this.get_opt("alias"),d=c?""+a+"-"+c+".atwho":""+a+".atwho",this.$inputor.trigger(d,b)},b.prototype.callbacks=function(a){return this.get_opt("callbacks")[a]||e[a]},b.prototype.get_opt=function(a,b){var c;try{return this.setting[a]}catch(a){return c=a,null}},b.prototype.content=function(){var a;if(this.$inputor.is("textarea, input"))return this.$inputor.val();if(a=this.mark_range())return(a.startContainer.textContent||"").slice(0,a.startOffset)},b.prototype.catch_query=function(){var a,b,c,d,e,f;return b=this.content(),a=this.$inputor.caret("pos",{iframe:this.app.iframe}),f=b.slice(0,a),d=this.callbacks("matcher").call(this,this.at,f,this.get_opt("start_with_space")),"string"==typeof d&&d.length<=this.get_opt("max_len",20)?(e=a-d.length,c=e+d.length,this.pos=e,d={text:d,head_pos:e,end_pos:c},this.trigger("matched",[this.at,d.text])):(d=null,this.view.hide()),this.query=d},b.prototype.rect=function(){var b,c,d;if(b=this.$inputor.caret("offset",this.pos-1,{iframe:this.app.iframe}))return this.app.iframe&&!this.app.iframeStandalone&&(c=a(this.app.iframe).offset(),b.left+=c.left,b.top+=c.top),this.$inputor.is("[contentEditable]")&&(b=this.cur_rect||(this.cur_rect=b)),d=this.app.document.selection?0:2,{left:b.left,top:b.top,bottom:b.top+b.height+d}},b.prototype.reset_rect=function(){if(this.$inputor.is("[contentEditable]"))return this.cur_rect=null},b.prototype.mark_range=function(){var a;if(this.$inputor.is("[contentEditable]"))return this.app.window.getSelection&&(a=this.app.window.getSelection()).rangeCount>0?this.range=a.getRangeAt(0):this.app.document.selection?this.ie8_range=this.app.document.selection.createRange():void 0},b.prototype.insert_content_for=function(b){var c,d,e;return d=b.data("value"),e=this.get_opt("insert_tpl"),this.$inputor.is("textarea, input")||!e?d:(c=a.extend({},b.data("item-data"),{"atwho-data-value":d,"atwho-at":this.at}),this.callbacks("tpl_eval").call(this,e,c))},b.prototype.insert=function(b,c){var d,e,f,g,h,i,j,k,l,m,n,o;if(d=this.$inputor,l=this.callbacks("inserting_wrapper").call(this,d,b,this.get_opt("suffix")),d.is("textarea, input"))i=d.val(),j=i.slice(0,Math.max(this.query.head_pos-this.at.length,0)),k=""+j+l+i.slice(this.query.end_pos||0),d.val(k),d.caret("pos",j.length+l.length,{iframe:this.app.iframe});else if(g=this.range){for(f=g.startOffset-(this.query.end_pos-this.query.head_pos)-this.at.length,g.setStart(g.endContainer,Math.max(f,0)),g.setEnd(g.endContainer,g.endOffset),g.deleteContents(),o=a(l,this.app.document),m=0,n=o.length;m<n;m++)e=o[m],g.insertNode(e),g.setEndAfter(e),g.collapse(!1);h=this.app.window.getSelection(),h.removeAllRanges(),h.addRange(g)}else(g=this.ie8_range)&&(g.moveStart("character",this.query.end_pos-this.query.head_pos-this.at.length),g.pasteHTML(l),g.collapse(!1),g.select());return d.is(":focus")||d.focus(),d.change()},b.prototype.render_view=function(a){var b;return b=this.get_opt("search_key"),a=this.callbacks("sorter").call(this,this.query.text,a.slice(0,1001),b),this.view.render(a.slice(0,this.get_opt("limit")))},b.prototype.look_up=function(){var b,c;if(b=this.catch_query())return c=function(a){return a&&a.length>0?this.render_view(a):this.view.hide()},this.model.query(b.text,a.proxy(c,this)),b},b}(),g=function(){function b(a){this.context=a,this.at=this.context.at,this.storage=this.context.$inputor}return b.prototype.destroy=function(){return this.storage.data(this.at,null)},b.prototype.saved=function(){return this.fetch()>0},b.prototype.query=function(a,b){var c,d,e;return c=this.fetch(),d=this.context.get_opt("search_key"),c=this.context.callbacks("filter").call(this.context,a,c,d)||[],e=this.context.callbacks("remote_filter"),c.length>0||!e&&0===c.length?b(c):e.call(this.context,a,b)},b.prototype.fetch=function(){return this.storage.data(this.at)||[]},b.prototype.save=function(a){return this.storage.data(this.at,this.context.callbacks("before_save").call(this.context,a||[]))},b.prototype.load=function(a){if(!this.saved()&&a)return this._load(a)},b.prototype.reload=function(a){return this._load(a)},b.prototype._load=function(b){return"string"==typeof b?a.ajax(b,{dataType:"json"}).done(function(a){return function(b){return a.save(b)}}(this)):this.save(b)},b}(),h=function(){function b(b){this.context=b,this.$el=a("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>"),this.timeout_id=null,this.context.$el.append(this.$el),this.bind_event()}return b.prototype.init=function(){var a;return a=this.context.get_opt("alias")||this.context.at.charCodeAt(0),this.$el.attr({id:"at-view-"+a})},b.prototype.destroy=function(){return this.$el.remove()},b.prototype.bind_event=function(){var b;return b=this.$el.find("ul"),b.on("mouseenter.atwho-view","li",function(c){return b.find(".cur").removeClass("cur"),a(c.currentTarget).addClass("cur")}).on("click.atwho-view","li",function(c){return function(d){return b.find(".cur").removeClass("cur"),a(d.currentTarget).addClass("cur"),c.choose(d),d.preventDefault()}}(this))},b.prototype.visible=function(){return this.$el.is(":visible")},b.prototype.choose=function(a){var b,c;if((b=this.$el.find(".cur")).length&&(c=this.context.insert_content_for(b),this.context.insert(this.context.callbacks("before_insert").call(this.context,c,b),b),this.context.trigger("inserted",[b,a]),this.hide(a)),this.context.get_opt("hide_without_suffix"))return this.stop_showing=!0},b.prototype.reposition=function(b){var c,d,e,f;return f=this.context.app.iframeStandalone?this.context.app.window:window,b.bottom+this.$el.height()-a(f).scrollTop()>a(f).height()&&(b.bottom=b.top-this.$el.height()),b.left>(d=a(f).width()-this.$el.width()-5)&&(b.left=d),c={left:b.left,top:b.bottom},null!=(e=this.context.callbacks("before_reposition"))&&e.call(this.context,c),this.$el.offset(c),this.context.trigger("reposition",[c])},b.prototype.next=function(){var a,b;return a=this.$el.find(".cur").removeClass("cur"),b=a.next(),b.length||(b=this.$el.find("li:first")),b.addClass("cur"),this.$el.animate({scrollTop:Math.max(0,a.innerHeight()*(b.index()+2)-this.$el.height())},150)},b.prototype.prev=function(){var a,b;return a=this.$el.find(".cur").removeClass("cur"),b=a.prev(),b.length||(b=this.$el.find("li:last")),b.addClass("cur"),this.$el.animate({scrollTop:Math.max(0,a.innerHeight()*(b.index()+2)-this.$el.height())},150)},b.prototype.show=function(){var a;return this.stop_showing?void(this.stop_showing=!1):(this.context.mark_range(),this.visible()||(this.$el.show(),this.$el.scrollTop(0),this.context.trigger("shown")),(a=this.context.rect())?this.reposition(a):void 0)},b.prototype.hide=function(a,b){var c;if(this.visible())return isNaN(b)?(this.context.reset_rect(),this.$el.hide(),this.context.trigger("hidden",[a])):(c=function(a){return function(){return a.hide()}}(this),clearTimeout(this.timeout_id),this.timeout_id=setTimeout(c,b))},b.prototype.render=function(b){var c,d,e,f,g,h,i;if(!(a.isArray(b)&&b.length>0))return void this.hide();for(this.$el.find("ul").empty(),d=this.$el.find("ul"),g=this.context.get_opt("tpl"),h=0,i=b.length;h<i;h++)e=b[h],e=a.extend({},e,{"atwho-at":this.context.at}),f=this.context.callbacks("tpl_eval").call(this.context,g,e),c=a(this.context.callbacks("highlighter").call(this.context,f,this.context.query.text)),c.data("item-data",e),d.append(c);return this.show(),this.context.get_opt("highlight_first")?d.find("li:first").addClass("cur"):void 0},b}(),f={DOWN:40,UP:38,ESC:27,TAB:9,ENTER:13,CTRL:17,P:80,N:78},e={before_save:function(b){var c,d,e,f;if(!a.isArray(b))return b;for(f=[],d=0,e=b.length;d<e;d++)c=b[d],a.isPlainObject(c)?f.push(c):f.push({name:c});return f},matcher:function(a,b,c){var d,e,f,g;return a=a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),c&&(a="(?:^|\\s)"+a),f=decodeURI("%C3%80"),g=decodeURI("%C3%BF"),e=new RegExp(""+a+"([A-Za-z"+f+"-"+g+"0-9_+-]*)$|"+a+"([^\\x00-\\xff]*)$","gi"),d=e.exec(b),d?d[2]||d[1]:null},filter:function(a,b,c){var d,e,f,g;for(g=[],e=0,f=b.length;e<f;e++)d=b[e],~new String(d[c]).toLowerCase().indexOf(a.toLowerCase())&&g.push(d);return g},remote_filter:null,sorter:function(a,b,c){var d,e,f,g;if(!a)return b;for(g=[],e=0,f=b.length;e<f;e++)d=b[e],d.atwho_order=new String(d[c]).toLowerCase().indexOf(a.toLowerCase()),d.atwho_order>-1&&g.push(d);return g.sort(function(a,b){return a.atwho_order-b.atwho_order})},tpl_eval:function(a,b){var c;try{return a.replace(/\$\{([^\}]*)\}/g,function(a,c,d){return b[c]})}catch(a){return c=a,""}},highlighter:function(a,b){var c;return b?(c=new RegExp(">\\s*(\\w*?)("+b.replace("+","\\+")+")(\\w*)\\s*<","ig"),a.replace(c,function(a,b,c,d){return"> "+b+"<strong>"+c+"</strong>"+d+" <"})):a},before_insert:function(a,b){return a},inserting_wrapper:function(a,b,c){var d;return c=""===c?c:c||" ",a.is("textarea, input")?""+b+c:"true"===a.attr("contentEditable")?(c=" "===c?"&nbsp;":c,/firefox/i.test(navigator.userAgent)?d="<span>"+b+c+"</span>":(c="<span contenteditable='false'>"+c+"</span>",d="<span contenteditable='false'>"+b+c+"</span>"),this.app.document.selection&&(d="<span contenteditable='true'>"+b+"</span>"),d+"<span></span>"):void 0}},b={load:function(a,b){var c;if(c=this.controller(a))return c.model.load(b)},setIframe:function(a,b){return this.setIframe(a,b),null},run:function(){return this.dispatch()},destroy:function(){return this.shutdown(),this.$inputor.data("atwho",null)}},a.fn.atwho=function(d){var e,f;return f=arguments,e=null,this.filter('textarea, input, [contenteditable=""], [contenteditable=true]').each(function(){var g,h;return(h=(g=a(this)).data("atwho"))||g.data("atwho",h=new c(this)),"object"!=typeof d&&d?b[d]&&h?e=b[d].apply(h,Array.prototype.slice.call(f,1)):a.error("Method "+d+" does not exist on jQuery.caret"):h.reg(d.at,d)}),e||this},a.fn.atwho.default={at:void 0,alias:void 0,data:null,tpl:"<li data-value='${atwho-at}${name}'>${name}</li>",insert_tpl:"<span id='${id}'>${atwho-data-value}</span>",callbacks:e,search_key:"name",suffix:void 0,hide_without_suffix:!1,start_with_space:!0,highlight_first:!0,limit:5,max_len:20,display_timeout:300,delay:null}});
bp-core/js/{jquery.atwho.txt → vendor/jquery.atwho.txt} RENAMED
File without changes
bp-core/js/{jquery.caret.js → vendor/jquery.caret.js} RENAMED
File without changes
bp-core/js/{jquery.caret.min.js → vendor/jquery.caret.min.js} RENAMED
@@ -1,2 +1 @@
1
- /*! buddypress - v2.5.3 - 2016-05-24 5:17:45 PM UTC - https://wordpress.org/plugins/buddypress/ */
2
- !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return a.returnExportsGlobal=b(c)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){"use strict";var b,c,d,e,f,g,h,i,j,k,l;k="caret",b=function(){function b(a){this.$inputor=a,this.domInputor=this.$inputor[0]}return b.prototype.setPos=function(a){return this.domInputor},b.prototype.getIEPosition=function(){return this.getPosition()},b.prototype.getPosition=function(){var a,b;return b=this.getOffset(),a=this.$inputor.offset(),b.left-=a.left,b.top-=a.top,b},b.prototype.getOldIEPos=function(){var a,b;return b=h.selection.createRange(),a=h.body.createTextRange(),a.moveToElementText(this.domInputor),a.setEndPoint("EndToEnd",b),a.text.length},b.prototype.getPos=function(){var a,b,c;return(c=this.range())?(a=c.cloneRange(),a.selectNodeContents(this.domInputor),a.setEnd(c.endContainer,c.endOffset),b=a.toString().length,a.detach(),b):h.selection?this.getOldIEPos():void 0},b.prototype.getOldIEOffset=function(){var a,b;return a=h.selection.createRange().duplicate(),a.moveStart("character",-1),b=a.getBoundingClientRect(),{height:b.bottom-b.top,left:b.left,top:b.top}},b.prototype.getOffset=function(b){var c,d,e,f,g;return j.getSelection&&(e=this.range())?(e.endOffset-1>0&&e.endContainer===!this.domInputor&&(c=e.cloneRange(),c.setStart(e.endContainer,e.endOffset-1),c.setEnd(e.endContainer,e.endOffset),f=c.getBoundingClientRect(),d={height:f.height,left:f.left+f.width,top:f.top},c.detach()),d&&0!==(null!=d?d.height:void 0)||(c=e.cloneRange(),g=a(h.createTextNode("|")),c.insertNode(g[0]),c.selectNode(g[0]),f=c.getBoundingClientRect(),d={height:f.height,left:f.left,top:f.top},g.remove(),c.detach())):h.selection&&(d=this.getOldIEOffset()),d&&(d.top+=a(j).scrollTop(),d.left+=a(j).scrollLeft()),d},b.prototype.range=function(){var a;if(j.getSelection)return a=j.getSelection(),a.rangeCount>0?a.getRangeAt(0):null},b}(),c=function(){function b(a){this.$inputor=a,this.domInputor=this.$inputor[0]}return b.prototype.getIEPos=function(){var a,b,c,d,e,f,g;return b=this.domInputor,f=h.selection.createRange(),e=0,f&&f.parentElement()===b&&(d=b.value.replace(/\r\n/g,"\n"),c=d.length,g=b.createTextRange(),g.moveToBookmark(f.getBookmark()),a=b.createTextRange(),a.collapse(!1),e=g.compareEndPoints("StartToEnd",a)>-1?c:-g.moveStart("character",-c)),e},b.prototype.getPos=function(){return h.selection?this.getIEPos():this.domInputor.selectionStart},b.prototype.setPos=function(a){var b,c;return b=this.domInputor,h.selection?(c=b.createTextRange(),c.move("character",a),c.select()):b.setSelectionRange&&b.setSelectionRange(a,a),b},b.prototype.getIEOffset=function(a){var b,c,d,e;return c=this.domInputor.createTextRange(),a||(a=this.getPos()),c.move("character",a),d=c.boundingLeft,e=c.boundingTop,b=c.boundingHeight,{left:d,top:e,height:b}},b.prototype.getOffset=function(b){var c,d,e;return c=this.$inputor,h.selection?(d=this.getIEOffset(b),d.top+=a(j).scrollTop()+c.scrollTop(),d.left+=a(j).scrollLeft()+c.scrollLeft(),d):(d=c.offset(),e=this.getPosition(b),d={left:d.left+e.left-c.scrollLeft(),top:d.top+e.top-c.scrollTop(),height:e.height})},b.prototype.getPosition=function(a){var b,c,e,f,g,h,i;return b=this.$inputor,f=function(a){return a=a.replace(/<|>|`|"|&/g,"?").replace(/\r\n|\r|\n/g,"<br/>"),/firefox/i.test(navigator.userAgent)&&(a=a.replace(/\s/g,"&nbsp;")),a},void 0===a&&(a=this.getPos()),i=b.val().slice(0,a),e=b.val().slice(a),g="<span style='position: relative; display: inline;'>"+f(i)+"</span>",g+="<span id='caret' style='position: relative; display: inline;'>|</span>",g+="<span style='position: relative; display: inline;'>"+f(e)+"</span>",h=new d(b),c=h.create(g).rect()},b.prototype.getIEPosition=function(a){var b,c,d,e,f;return d=this.getIEOffset(a),c=this.$inputor.offset(),e=d.left-c.left,f=d.top-c.top,b=d.height,{left:e,top:f,height:b}},b}(),d=function(){function b(a){this.$inputor=a}return b.prototype.css_attr=["borderBottomWidth","borderLeftWidth","borderRightWidth","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","boxSizing","fontFamily","fontSize","fontWeight","height","letterSpacing","lineHeight","marginBottom","marginLeft","marginRight","marginTop","outlineWidth","overflow","overflowX","overflowY","paddingBottom","paddingLeft","paddingRight","paddingTop","textAlign","textOverflow","textTransform","whiteSpace","wordBreak","wordWrap"],b.prototype.mirrorCss=function(){var b,c=this;return b={position:"absolute",left:-9999,top:0,zIndex:-2e4},"TEXTAREA"===this.$inputor.prop("tagName")&&this.css_attr.push("width"),a.each(this.css_attr,function(a,d){return b[d]=c.$inputor.css(d)}),b},b.prototype.create=function(b){return this.$mirror=a("<div></div>"),this.$mirror.css(this.mirrorCss()),this.$mirror.html(b),this.$inputor.after(this.$mirror),this},b.prototype.rect=function(){var a,b,c;return a=this.$mirror.find("#caret"),b=a.position(),c={left:b.left,top:b.top,height:a.height()},this.$mirror.remove(),c},b}(),e={contentEditable:function(a){return!(!a[0].contentEditable||"true"!==a[0].contentEditable)}},g={pos:function(a){return a||0===a?this.setPos(a):this.getPos()},position:function(a){return h.selection?this.getIEPosition(a):this.getPosition(a)},offset:function(a){var b;return b=this.getOffset(a)}},h=null,j=null,i=null,l=function(a){var b;return(b=null!=a?a.iframe:void 0)?(i=b,j=b.contentWindow,h=b.contentDocument||j.document):(i=void 0,j=window,h=document)},f=function(a){var b;h=a[0].ownerDocument,j=h.defaultView||h.parentWindow;try{return i=j.frameElement}catch(c){b=c}},a.fn.caret=function(d,f,h){var i;return g[d]?(a.isPlainObject(f)?(l(f),f=void 0):l(h),i=e.contentEditable(this)?new b(this):new c(this),g[d].apply(i,[f])):a.error("Method "+d+" does not exist on jQuery.caret")},a.fn.caret.EditableCaret=b,a.fn.caret.InputCaret=c,a.fn.caret.Utils=e,a.fn.caret.apis=g});
1
+ !function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return a.returnExportsGlobal=b(c)}):"object"==typeof exports?module.exports=b(require("jquery")):b(jQuery)}(this,function(a){"use strict";var b,c,d,e,f,g,h,i,j,k,l;k="caret",b=function(){function b(a){this.$inputor=a,this.domInputor=this.$inputor[0]}return b.prototype.setPos=function(a){return this.domInputor},b.prototype.getIEPosition=function(){return this.getPosition()},b.prototype.getPosition=function(){var a,b;return b=this.getOffset(),a=this.$inputor.offset(),b.left-=a.left,b.top-=a.top,b},b.prototype.getOldIEPos=function(){var a,b;return b=h.selection.createRange(),a=h.body.createTextRange(),a.moveToElementText(this.domInputor),a.setEndPoint("EndToEnd",b),a.text.length},b.prototype.getPos=function(){var a,b,c;return(c=this.range())?(a=c.cloneRange(),a.selectNodeContents(this.domInputor),a.setEnd(c.endContainer,c.endOffset),b=a.toString().length,a.detach(),b):h.selection?this.getOldIEPos():void 0},b.prototype.getOldIEOffset=function(){var a,b;return a=h.selection.createRange().duplicate(),a.moveStart("character",-1),b=a.getBoundingClientRect(),{height:b.bottom-b.top,left:b.left,top:b.top}},b.prototype.getOffset=function(b){var c,d,e,f,g;return j.getSelection&&(e=this.range())?(e.endOffset-1>0&&e.endContainer===!this.domInputor&&(c=e.cloneRange(),c.setStart(e.endContainer,e.endOffset-1),c.setEnd(e.endContainer,e.endOffset),f=c.getBoundingClientRect(),d={height:f.height,left:f.left+f.width,top:f.top},c.detach()),d&&0!==(null!=d?d.height:void 0)||(c=e.cloneRange(),g=a(h.createTextNode("|")),c.insertNode(g[0]),c.selectNode(g[0]),f=c.getBoundingClientRect(),d={height:f.height,left:f.left,top:f.top},g.remove(),c.detach())):h.selection&&(d=this.getOldIEOffset()),d&&(d.top+=a(j).scrollTop(),d.left+=a(j).scrollLeft()),d},b.prototype.range=function(){var a;if(j.getSelection)return a=j.getSelection(),a.rangeCount>0?a.getRangeAt(0):null},b}(),c=function(){function b(a){this.$inputor=a,this.domInputor=this.$inputor[0]}return b.prototype.getIEPos=function(){var a,b,c,d,e,f,g;return b=this.domInputor,f=h.selection.createRange(),e=0,f&&f.parentElement()===b&&(d=b.value.replace(/\r\n/g,"\n"),c=d.length,g=b.createTextRange(),g.moveToBookmark(f.getBookmark()),a=b.createTextRange(),a.collapse(!1),e=g.compareEndPoints("StartToEnd",a)>-1?c:-g.moveStart("character",-c)),e},b.prototype.getPos=function(){return h.selection?this.getIEPos():this.domInputor.selectionStart},b.prototype.setPos=function(a){var b,c;return b=this.domInputor,h.selection?(c=b.createTextRange(),c.move("character",a),c.select()):b.setSelectionRange&&b.setSelectionRange(a,a),b},b.prototype.getIEOffset=function(a){var b,c,d,e;return c=this.domInputor.createTextRange(),a||(a=this.getPos()),c.move("character",a),d=c.boundingLeft,e=c.boundingTop,b=c.boundingHeight,{left:d,top:e,height:b}},b.prototype.getOffset=function(b){var c,d,e;return c=this.$inputor,h.selection?(d=this.getIEOffset(b),d.top+=a(j).scrollTop()+c.scrollTop(),d.left+=a(j).scrollLeft()+c.scrollLeft(),d):(d=c.offset(),e=this.getPosition(b),d={left:d.left+e.left-c.scrollLeft(),top:d.top+e.top-c.scrollTop(),height:e.height})},b.prototype.getPosition=function(a){var b,c,e,f,g,h,i;return b=this.$inputor,f=function(a){return a=a.replace(/<|>|`|"|&/g,"?").replace(/\r\n|\r|\n/g,"<br/>"),/firefox/i.test(navigator.userAgent)&&(a=a.replace(/\s/g,"&nbsp;")),a},void 0===a&&(a=this.getPos()),i=b.val().slice(0,a),e=b.val().slice(a),g="<span style='position: relative; display: inline;'>"+f(i)+"</span>",g+="<span id='caret' style='position: relative; display: inline;'>|</span>",g+="<span style='position: relative; display: inline;'>"+f(e)+"</span>",h=new d(b),c=h.create(g).rect()},b.prototype.getIEPosition=function(a){var b,c,d,e,f;return d=this.getIEOffset(a),c=this.$inputor.offset(),e=d.left-c.left,f=d.top-c.top,b=d.height,{left:e,top:f,height:b}},b}(),d=function(){function b(a){this.$inputor=a}return b.prototype.css_attr=["borderBottomWidth","borderLeftWidth","borderRightWidth","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","boxSizing","fontFamily","fontSize","fontWeight","height","letterSpacing","lineHeight","marginBottom","marginLeft","marginRight","marginTop","outlineWidth","overflow","overflowX","overflowY","paddingBottom","paddingLeft","paddingRight","paddingTop","textAlign","textOverflow","textTransform","whiteSpace","wordBreak","wordWrap"],b.prototype.mirrorCss=function(){var b,c=this;return b={position:"absolute",left:-9999,top:0,zIndex:-2e4},"TEXTAREA"===this.$inputor.prop("tagName")&&this.css_attr.push("width"),a.each(this.css_attr,function(a,d){return b[d]=c.$inputor.css(d)}),b},b.prototype.create=function(b){return this.$mirror=a("<div></div>"),this.$mirror.css(this.mirrorCss()),this.$mirror.html(b),this.$inputor.after(this.$mirror),this},b.prototype.rect=function(){var a,b,c;return a=this.$mirror.find("#caret"),b=a.position(),c={left:b.left,top:b.top,height:a.height()},this.$mirror.remove(),c},b}(),e={contentEditable:function(a){return!(!a[0].contentEditable||"true"!==a[0].contentEditable)}},g={pos:function(a){return a||0===a?this.setPos(a):this.getPos()},position:function(a){return h.selection?this.getIEPosition(a):this.getPosition(a)},offset:function(a){var b;return b=this.getOffset(a)}},h=null,j=null,i=null,l=function(a){var b;return(b=null!=a?a.iframe:void 0)?(i=b,j=b.contentWindow,h=b.contentDocument||j.document):(i=void 0,j=window,h=document)},f=function(a){var b;h=a[0].ownerDocument,j=h.defaultView||h.parentWindow;try{return i=j.frameElement}catch(a){b=a}},a.fn.caret=function(d,f,h){var i;return g[d]?(a.isPlainObject(f)?(l(f),f=void 0):l(h),i=e.contentEditable(this)?new b(this):new c(this),g[d].apply(i,[f])):a.error("Method "+d+" does not exist on jQuery.caret")},a.fn.caret.EditableCaret=b,a.fn.caret.InputCaret=c,a.fn.caret.Utils=e,a.fn.caret.apis=g});
 
bp-core/js/{jquery.caret.txt → vendor/jquery.caret.txt} RENAMED
File without changes
bp-core/js/vendor/livestamp.js ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Livestamp.js / v1.1.2 / (c) 2012 Matt Bradley / MIT License
2
+ (function($, moment) {
3
+ var updateInterval = 1e3,
4
+ paused = false,
5
+ $livestamps = $([]),
6
+
7
+ init = function() {
8
+ livestampGlobal.resume();
9
+ },
10
+
11
+ prep = function($el, timestamp) {
12
+ var oldData = $el.data('livestampdata');
13
+ if (typeof timestamp == 'number')
14
+ timestamp *= 1e3;
15
+
16
+ $el.removeAttr('data-livestamp')
17
+ .removeData('livestamp');
18
+
19
+ timestamp = moment(timestamp);
20
+ if (moment.isMoment(timestamp) && !isNaN(+timestamp)) {
21
+ var newData = $.extend({ }, { 'original': $el.contents() }, oldData);
22
+ newData.moment = moment(timestamp);
23
+
24
+ $el.data('livestampdata', newData).empty();
25
+ $livestamps.push($el[0]);
26
+ }
27
+ },
28
+
29
+ run = function() {
30
+ if (paused) return;
31
+ livestampGlobal.update();
32
+ setTimeout(run, updateInterval);
33
+ },
34
+
35
+ livestampGlobal = {
36
+ update: function() {
37
+ $('[data-livestamp]').each(function() {
38
+ var $this = $(this);
39
+ prep($this, $this.data('livestamp'));
40
+ });
41
+
42
+ var toRemove = [];
43
+ $livestamps.each(function() {
44
+ var $this = $(this),
45
+ data = $this.data('livestampdata');
46
+
47
+ if (data === undefined)
48
+ toRemove.push(this);
49
+ else if (moment.isMoment(data.moment)) {
50
+ var from = $this.html(),
51
+ to = data.moment.fromNow();
52
+
53
+ if (from != to) {
54
+ var e = $.Event('change.livestamp');
55
+ $this.trigger(e, [from, to]);
56
+ if (!e.isDefaultPrevented())
57
+ $this.html(to);
58
+ }
59
+ }
60
+ });
61
+
62
+ $livestamps = $livestamps.not(toRemove);
63
+ },
64
+
65
+ pause: function() {
66
+ paused = true;
67
+ },
68
+
69
+ resume: function() {
70
+ paused = false;
71
+ run();
72
+ },
73
+
74
+ interval: function(interval) {
75
+ if (interval === undefined)
76
+ return updateInterval;
77
+ updateInterval = interval;
78
+ }
79
+ },
80
+
81
+ livestampLocal = {
82
+ add: function($el, timestamp) {
83
+ if (typeof timestamp == 'number')
84
+ timestamp *= 1e3;
85
+ timestamp = moment(timestamp);
86
+
87
+ if (moment.isMoment(timestamp) && !isNaN(+timestamp)) {
88
+ $el.each(function() {
89
+ prep($(this), timestamp);
90
+ });
91
+ livestampGlobal.update();
92
+ }
93
+
94
+ return $el;
95
+ },
96
+
97
+ destroy: function($el) {
98
+ $livestamps = $livestamps.not($el);
99
+ $el.each(function() {
100
+ var $this = $(this),
101
+ data = $this.data('livestampdata');
102
+
103
+ if (data === undefined)
104
+ return $el;
105
+
106
+ $this
107
+ .html(data.original ? data.original : '')
108
+ .removeData('livestampdata');
109
+ });
110
+
111
+ return $el;
112
+ },
113
+
114
+ isLivestamp: function($el) {
115
+ return $el.data('livestampdata') !== undefined;
116
+ }
117
+ };
118
+
119
+ $.livestamp = livestampGlobal;
120
+ $(init);
121
+ $.fn.livestamp = function(method, options) {
122
+ if (!livestampLocal[method]) {
123
+ options = method;
124
+ method = 'add';
125
+ }
126
+
127
+ return livestampLocal[method](this, options);
128
+ };
129
+ })(jQuery, moment);
bp-core/js/vendor/livestamp.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){var c=1e3,d=!1,e=a([]),f=function(){i.resume()},g=function(c,d){var f=c.data("livestampdata");if("number"==typeof d&&(d*=1e3),c.removeAttr("data-livestamp").removeData("livestamp"),d=b(d),b.isMoment(d)&&!isNaN(+d)){var g=a.extend({},{original:c.contents()},f);g.moment=b(d),c.data("livestampdata",g).empty(),e.push(c[0])}},h=function(){d||(i.update(),setTimeout(h,c))},i={update:function(){a("[data-livestamp]").each(function(){var b=a(this);g(b,b.data("livestamp"))});var c=[];e.each(function(){var d=a(this),e=d.data("livestampdata");if(void 0===e)c.push(this);else if(b.isMoment(e.moment)){var f=d.html(),g=e.moment.fromNow();if(f!=g){var h=a.Event("change.livestamp");d.trigger(h,[f,g]),h.isDefaultPrevented()||d.html(g)}}}),e=e.not(c)},pause:function(){d=!0},resume:function(){d=!1,h()},interval:function(a){return void 0===a?c:void(c=a)}},j={add:function(c,d){return"number"==typeof d&&(d*=1e3),d=b(d),b.isMoment(d)&&!isNaN(+d)&&(c.each(function(){g(a(this),d)}),i.update()),c},destroy:function(b){return e=e.not(b),b.each(function(){var c=a(this),d=c.data("livestampdata");return void 0===d?b:void c.html(d.original?d.original:"").removeData("livestampdata")}),b},isLivestamp:function(a){return void 0!==a.data("livestampdata")}};a.livestamp=i,a(f),a.fn.livestamp=function(a,b){return j[a]||(b=a,a="add"),j[a](this,b)}}(jQuery,moment);
bp-core/js/vendor/moment-js/locale/af.js ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Afrikaans [af]
3
+ //! author : Werner Mollentze : https://github.com/wernerm
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var af = moment.defineLocale('af', {
14
+ months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),
15
+ monthsShort : 'Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),
16
+ weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),
17
+ weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),
18
+ weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),
19
+ meridiemParse: /vm|nm/i,
20
+ isPM : function (input) {
21
+ return /^nm$/i.test(input);
22
+ },
23
+ meridiem : function (hours, minutes, isLower) {
24
+ if (hours < 12) {
25
+ return isLower ? 'vm' : 'VM';
26
+ } else {
27
+ return isLower ? 'nm' : 'NM';
28
+ }
29
+ },
30
+ longDateFormat : {
31
+ LT : 'HH:mm',
32
+ LTS : 'HH:mm:ss',
33
+ L : 'DD/MM/YYYY',
34
+ LL : 'D MMMM YYYY',
35
+ LLL : 'D MMMM YYYY HH:mm',
36
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
37
+ },
38
+ calendar : {
39
+ sameDay : '[Vandag om] LT',
40
+ nextDay : '[Môre om] LT',
41
+ nextWeek : 'dddd [om] LT',
42
+ lastDay : '[Gister om] LT',
43
+ lastWeek : '[Laas] dddd [om] LT',
44
+ sameElse : 'L'
45
+ },
46
+ relativeTime : {
47
+ future : 'oor %s',
48
+ past : '%s gelede',
49
+ s : '\'n paar sekondes',
50
+ m : '\'n minuut',
51
+ mm : '%d minute',
52
+ h : '\'n uur',
53
+ hh : '%d ure',
54
+ d : '\'n dag',
55
+ dd : '%d dae',
56
+ M : '\'n maand',
57
+ MM : '%d maande',
58
+ y : '\'n jaar',
59
+ yy : '%d jaar'
60
+ },
61
+ ordinalParse: /\d{1,2}(ste|de)/,
62
+ ordinal : function (number) {
63
+ return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter
64
+ },
65
+ week : {
66
+ dow : 1, // Maandag is die eerste dag van die week.
67
+ doy : 4 // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
68
+ }
69
+ });
70
+
71
+ return af;
72
+
73
+ }));
bp-core/js/vendor/moment-js/locale/af.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("af",{months:"Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mrt_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des".split("_"),weekdays:"Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag".split("_"),weekdaysShort:"Son_Maa_Din_Woe_Don_Vry_Sat".split("_"),weekdaysMin:"So_Ma_Di_Wo_Do_Vr_Sa".split("_"),meridiemParse:/vm|nm/i,isPM:function(a){return/^nm$/i.test(a)},meridiem:function(a,b,c){return a<12?c?"vm":"VM":c?"nm":"NM"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Vandag om] LT",nextDay:"[Môre om] LT",nextWeek:"dddd [om] LT",lastDay:"[Gister om] LT",lastWeek:"[Laas] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oor %s",past:"%s gelede",s:"'n paar sekondes",m:"'n minuut",mm:"%d minute",h:"'n uur",hh:"%d ure",d:"'n dag",dd:"%d dae",M:"'n maand",MM:"%d maande",y:"'n jaar",yy:"%d jaar"},ordinalParse:/\d{1,2}(ste|de)/,ordinal:function(a){return a+(1===a||8===a||a>=20?"ste":"de")},week:{dow:1,doy:4}});return b});
bp-core/js/vendor/moment-js/locale/ar-ly.js ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Arabic (Lybia) [ar-ly]
3
+ //! author : Ali Hmer: https://github.com/kikoanis
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var symbolMap = {
14
+ '1': '1',
15
+ '2': '2',
16
+ '3': '3',
17
+ '4': '4',
18
+ '5': '5',
19
+ '6': '6',
20
+ '7': '7',
21
+ '8': '8',
22
+ '9': '9',
23
+ '0': '0'
24
+ }, pluralForm = function (n) {
25
+ return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
26
+ }, plurals = {
27
+ s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
28
+ m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
29
+ h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
30
+ d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
31
+ M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
32
+ y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
33
+ }, pluralize = function (u) {
34
+ return function (number, withoutSuffix, string, isFuture) {
35
+ var f = pluralForm(number),
36
+ str = plurals[u][pluralForm(number)];
37
+ if (f === 2) {
38
+ str = str[withoutSuffix ? 0 : 1];
39
+ }
40
+ return str.replace(/%d/i, number);
41
+ };
42
+ }, months = [
43
+ 'يناير',
44
+ 'فبراير',
45
+ 'مارس',
46
+ 'أبريل',
47
+ 'مايو',
48
+ 'يونيو',
49
+ 'يوليو',
50
+ 'أغسطس',
51
+ 'سبتمبر',
52
+ 'أكتوبر',
53
+ 'نوفمبر',
54
+ 'ديسمبر'
55
+ ];
56
+
57
+ var ar_ly = moment.defineLocale('ar-ly', {
58
+ months : months,
59
+ monthsShort : months,
60
+ weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
61
+ weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
62
+ weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
63
+ weekdaysParseExact : true,
64
+ longDateFormat : {
65
+ LT : 'HH:mm',
66
+ LTS : 'HH:mm:ss',
67
+ L : 'D/\u200FM/\u200FYYYY',
68
+ LL : 'D MMMM YYYY',
69
+ LLL : 'D MMMM YYYY HH:mm',
70
+ LLLL : 'dddd D MMMM YYYY HH:mm'
71
+ },
72
+ meridiemParse: /ص|م/,
73
+ isPM : function (input) {
74
+ return 'م' === input;
75
+ },
76
+ meridiem : function (hour, minute, isLower) {
77
+ if (hour < 12) {
78
+ return 'ص';
79
+ } else {
80
+ return 'م';
81
+ }
82
+ },
83
+ calendar : {
84
+ sameDay: '[اليوم عند الساعة] LT',
85
+ nextDay: '[غدًا عند الساعة] LT',
86
+ nextWeek: 'dddd [عند الساعة] LT',
87
+ lastDay: '[أمس عند الساعة] LT',
88
+ lastWeek: 'dddd [عند الساعة] LT',
89
+ sameElse: 'L'
90
+ },
91
+ relativeTime : {
92
+ future : 'بعد %s',
93
+ past : 'منذ %s',
94
+ s : pluralize('s'),
95
+ m : pluralize('m'),
96
+ mm : pluralize('m'),
97
+ h : pluralize('h'),
98
+ hh : pluralize('h'),
99
+ d : pluralize('d'),
100
+ dd : pluralize('d'),
101
+ M : pluralize('M'),
102
+ MM : pluralize('M'),
103
+ y : pluralize('y'),
104
+ yy : pluralize('y')
105
+ },
106
+ preparse: function (string) {
107
+ return string.replace(/\u200f/g, '').replace(/،/g, ',');
108
+ },
109
+ postformat: function (string) {
110
+ return string.replace(/\d/g, function (match) {
111
+ return symbolMap[match];
112
+ }).replace(/,/g, '،');
113
+ },
114
+ week : {
115
+ dow : 6, // Saturday is the first day of the week.
116
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
117
+ }
118
+ });
119
+
120
+ return ar_ly;
121
+
122
+ }));
bp-core/js/vendor/moment-js/locale/ar-ly.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b={1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},c=function(a){return 0===a?0:1===a?1:2===a?2:a%100>=3&&a%100<=10?3:a%100>=11?4:5},d={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},e=function(a){return function(b,e,f,g){var h=c(b),i=d[a][c(b)];return 2===h&&(i=i[e?0:1]),i.replace(/%d/i,b)}},f=["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],g=a.defineLocale("ar-ly",{months:f,monthsShort:f,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return a<12?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:e("s"),m:e("m"),mm:e("m"),h:e("h"),hh:e("h"),d:e("d"),dd:e("d"),M:e("M"),MM:e("M"),y:e("y"),yy:e("y")},preparse:function(a){return a.replace(/\u200f/g,"").replace(/،/g,",")},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return g});
bp-core/js/vendor/moment-js/locale/ar-ma.js ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Arabic (Morocco) [ar-ma]
3
+ //! author : ElFadili Yassine : https://github.com/ElFadiliY
4
+ //! author : Abdel Said : https://github.com/abdelsaid
5
+
6
+ ;(function (global, factory) {
7
+ typeof exports === 'object' && typeof module !== 'undefined'
8
+ && typeof require === 'function' ? factory(require('../moment')) :
9
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
10
+ factory(global.moment)
11
+ }(this, function (moment) { 'use strict';
12
+
13
+
14
+ var ar_ma = moment.defineLocale('ar-ma', {
15
+ months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
16
+ monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),
17
+ weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
18
+ weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),
19
+ weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
20
+ weekdaysParseExact : true,
21
+ longDateFormat : {
22
+ LT : 'HH:mm',
23
+ LTS : 'HH:mm:ss',
24
+ L : 'DD/MM/YYYY',
25
+ LL : 'D MMMM YYYY',
26
+ LLL : 'D MMMM YYYY HH:mm',
27
+ LLLL : 'dddd D MMMM YYYY HH:mm'
28
+ },
29
+ calendar : {
30
+ sameDay: '[اليوم على الساعة] LT',
31
+ nextDay: '[غدا على الساعة] LT',
32
+ nextWeek: 'dddd [على الساعة] LT',
33
+ lastDay: '[أمس على الساعة] LT',
34
+ lastWeek: 'dddd [على الساعة] LT',
35
+ sameElse: 'L'
36
+ },
37
+ relativeTime : {
38
+ future : 'في %s',
39
+ past : 'منذ %s',
40
+ s : 'ثوان',
41
+ m : 'دقيقة',
42
+ mm : '%d دقائق',
43
+ h : 'ساعة',
44
+ hh : '%d ساعات',
45
+ d : 'يوم',
46
+ dd : '%d أيام',
47
+ M : 'شهر',
48
+ MM : '%d أشهر',
49
+ y : 'سنة',
50
+ yy : '%d سنوات'
51
+ },
52
+ week : {
53
+ dow : 6, // Saturday is the first day of the week.
54
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
55
+ }
56
+ });
57
+
58
+ return ar_ma;
59
+
60
+ }));
bp-core/js/vendor/moment-js/locale/ar-ma.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("ar-ma",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:6,doy:12}});return b});
bp-core/js/vendor/moment-js/locale/ar-sa.js ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Arabic (Saudi Arabia) [ar-sa]
3
+ //! author : Suhail Alkowaileet : https://github.com/xsoh
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var symbolMap = {
14
+ '1': '١',
15
+ '2': '٢',
16
+ '3': '٣',
17
+ '4': '٤',
18
+ '5': '٥',
19
+ '6': '٦',
20
+ '7': '٧',
21
+ '8': '٨',
22
+ '9': '٩',
23
+ '0': '٠'
24
+ }, numberMap = {
25
+ '١': '1',
26
+ '٢': '2',
27
+ '٣': '3',
28
+ '٤': '4',
29
+ '٥': '5',
30
+ '٦': '6',
31
+ '٧': '7',
32
+ '٨': '8',
33
+ '٩': '9',
34
+ '٠': '0'
35
+ };
36
+
37
+ var ar_sa = moment.defineLocale('ar-sa', {
38
+ months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
39
+ monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
40
+ weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
41
+ weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
42
+ weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
43
+ weekdaysParseExact : true,
44
+ longDateFormat : {
45
+ LT : 'HH:mm',
46
+ LTS : 'HH:mm:ss',
47
+ L : 'DD/MM/YYYY',
48
+ LL : 'D MMMM YYYY',
49
+ LLL : 'D MMMM YYYY HH:mm',
50
+ LLLL : 'dddd D MMMM YYYY HH:mm'
51
+ },
52
+ meridiemParse: /ص|م/,
53
+ isPM : function (input) {
54
+ return 'م' === input;
55
+ },
56
+ meridiem : function (hour, minute, isLower) {
57
+ if (hour < 12) {
58
+ return 'ص';
59
+ } else {
60
+ return 'م';
61
+ }
62
+ },
63
+ calendar : {
64
+ sameDay: '[اليوم على الساعة] LT',
65
+ nextDay: '[غدا على الساعة] LT',
66
+ nextWeek: 'dddd [على الساعة] LT',
67
+ lastDay: '[أمس على الساعة] LT',
68
+ lastWeek: 'dddd [على الساعة] LT',
69
+ sameElse: 'L'
70
+ },
71
+ relativeTime : {
72
+ future : 'في %s',
73
+ past : 'منذ %s',
74
+ s : 'ثوان',
75
+ m : 'دقيقة',
76
+ mm : '%d دقائق',
77
+ h : 'ساعة',
78
+ hh : '%d ساعات',
79
+ d : 'يوم',
80
+ dd : '%d أيام',
81
+ M : 'شهر',
82
+ MM : '%d أشهر',
83
+ y : 'سنة',
84
+ yy : '%d سنوات'
85
+ },
86
+ preparse: function (string) {
87
+ return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
88
+ return numberMap[match];
89
+ }).replace(/،/g, ',');
90
+ },
91
+ postformat: function (string) {
92
+ return string.replace(/\d/g, function (match) {
93
+ return symbolMap[match];
94
+ }).replace(/,/g, '،');
95
+ },
96
+ week : {
97
+ dow : 6, // Saturday is the first day of the week.
98
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
99
+ }
100
+ });
101
+
102
+ return ar_sa;
103
+
104
+ }));
bp-core/js/vendor/moment-js/locale/ar-sa.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=a.defineLocale("ar-sa",{months:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return a<12?"ص":"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(a){return a.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return d});
bp-core/js/vendor/moment-js/locale/ar-tn.js ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Arabic (Tunisia) [ar-tn]
3
+ //! author : Nader Toukabri : https://github.com/naderio
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var ar_tn = moment.defineLocale('ar-tn', {
14
+ months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
15
+ monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),
16
+ weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
17
+ weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
18
+ weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),
19
+ weekdaysParseExact : true,
20
+ longDateFormat: {
21
+ LT: 'HH:mm',
22
+ LTS: 'HH:mm:ss',
23
+ L: 'DD/MM/YYYY',
24
+ LL: 'D MMMM YYYY',
25
+ LLL: 'D MMMM YYYY HH:mm',
26
+ LLLL: 'dddd D MMMM YYYY HH:mm'
27
+ },
28
+ calendar: {
29
+ sameDay: '[اليوم على الساعة] LT',
30
+ nextDay: '[غدا على الساعة] LT',
31
+ nextWeek: 'dddd [على الساعة] LT',
32
+ lastDay: '[أمس على الساعة] LT',
33
+ lastWeek: 'dddd [على الساعة] LT',
34
+ sameElse: 'L'
35
+ },
36
+ relativeTime: {
37
+ future: 'في %s',
38
+ past: 'منذ %s',
39
+ s: 'ثوان',
40
+ m: 'دقيقة',
41
+ mm: '%d دقائق',
42
+ h: 'ساعة',
43
+ hh: '%d ساعات',
44
+ d: 'يوم',
45
+ dd: '%d أيام',
46
+ M: 'شهر',
47
+ MM: '%d أشهر',
48
+ y: 'سنة',
49
+ yy: '%d سنوات'
50
+ },
51
+ week: {
52
+ dow: 1, // Monday is the first day of the week.
53
+ doy: 4 // The week that contains Jan 4th is the first week of the year.
54
+ }
55
+ });
56
+
57
+ return ar_tn;
58
+
59
+ }));
bp-core/js/vendor/moment-js/locale/ar-tn.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("ar-tn",{months:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}});return b});
bp-core/js/vendor/moment-js/locale/ar.js ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Arabic [ar]
3
+ //! author : Abdel Said: https://github.com/abdelsaid
4
+ //! author : Ahmed Elkhatib
5
+ //! author : forabi https://github.com/forabi
6
+
7
+ ;(function (global, factory) {
8
+ typeof exports === 'object' && typeof module !== 'undefined'
9
+ && typeof require === 'function' ? factory(require('../moment')) :
10
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
11
+ factory(global.moment)
12
+ }(this, function (moment) { 'use strict';
13
+
14
+
15
+ var symbolMap = {
16
+ '1': '١',
17
+ '2': '٢',
18
+ '3': '٣',
19
+ '4': '٤',
20
+ '5': '٥',
21
+ '6': '٦',
22
+ '7': '٧',
23
+ '8': '٨',
24
+ '9': '٩',
25
+ '0': '٠'
26
+ }, numberMap = {
27
+ '١': '1',
28
+ '٢': '2',
29
+ '٣': '3',
30
+ '٤': '4',
31
+ '٥': '5',
32
+ '٦': '6',
33
+ '٧': '7',
34
+ '٨': '8',
35
+ '٩': '9',
36
+ '٠': '0'
37
+ }, pluralForm = function (n) {
38
+ return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;
39
+ }, plurals = {
40
+ s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],
41
+ m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],
42
+ h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],
43
+ d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],
44
+ M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],
45
+ y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']
46
+ }, pluralize = function (u) {
47
+ return function (number, withoutSuffix, string, isFuture) {
48
+ var f = pluralForm(number),
49
+ str = plurals[u][pluralForm(number)];
50
+ if (f === 2) {
51
+ str = str[withoutSuffix ? 0 : 1];
52
+ }
53
+ return str.replace(/%d/i, number);
54
+ };
55
+ }, months = [
56
+ 'كانون الثاني يناير',
57
+ 'شباط فبراير',
58
+ 'آذار مارس',
59
+ 'نيسان أبريل',
60
+ 'أيار مايو',
61
+ 'حزيران يونيو',
62
+ 'تموز يوليو',
63
+ 'آب أغسطس',
64
+ 'أيلول سبتمبر',
65
+ 'تشرين الأول أكتوبر',
66
+ 'تشرين الثاني نوفمبر',
67
+ 'كانون الأول ديسمبر'
68
+ ];
69
+
70
+ var ar = moment.defineLocale('ar', {
71
+ months : months,
72
+ monthsShort : months,
73
+ weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),
74
+ weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),
75
+ weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),
76
+ weekdaysParseExact : true,
77
+ longDateFormat : {
78
+ LT : 'HH:mm',
79
+ LTS : 'HH:mm:ss',
80
+ L : 'D/\u200FM/\u200FYYYY',
81
+ LL : 'D MMMM YYYY',
82
+ LLL : 'D MMMM YYYY HH:mm',
83
+ LLLL : 'dddd D MMMM YYYY HH:mm'
84
+ },
85
+ meridiemParse: /ص|م/,
86
+ isPM : function (input) {
87
+ return 'م' === input;
88
+ },
89
+ meridiem : function (hour, minute, isLower) {
90
+ if (hour < 12) {
91
+ return 'ص';
92
+ } else {
93
+ return 'م';
94
+ }
95
+ },
96
+ calendar : {
97
+ sameDay: '[اليوم عند الساعة] LT',
98
+ nextDay: '[غدًا عند الساعة] LT',
99
+ nextWeek: 'dddd [عند الساعة] LT',
100
+ lastDay: '[أمس عند الساعة] LT',
101
+ lastWeek: 'dddd [عند الساعة] LT',
102
+ sameElse: 'L'
103
+ },
104
+ relativeTime : {
105
+ future : 'بعد %s',
106
+ past : 'منذ %s',
107
+ s : pluralize('s'),
108
+ m : pluralize('m'),
109
+ mm : pluralize('m'),
110
+ h : pluralize('h'),
111
+ hh : pluralize('h'),
112
+ d : pluralize('d'),
113
+ dd : pluralize('d'),
114
+ M : pluralize('M'),
115
+ MM : pluralize('M'),
116
+ y : pluralize('y'),
117
+ yy : pluralize('y')
118
+ },
119
+ preparse: function (string) {
120
+ return string.replace(/\u200f/g, '').replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {
121
+ return numberMap[match];
122
+ }).replace(/،/g, ',');
123
+ },
124
+ postformat: function (string) {
125
+ return string.replace(/\d/g, function (match) {
126
+ return symbolMap[match];
127
+ }).replace(/,/g, '،');
128
+ },
129
+ week : {
130
+ dow : 6, // Saturday is the first day of the week.
131
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
132
+ }
133
+ });
134
+
135
+ return ar;
136
+
137
+ }));
bp-core/js/vendor/moment-js/locale/ar.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},c={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},d=function(a){return 0===a?0:1===a?1:2===a?2:a%100>=3&&a%100<=10?3:a%100>=11?4:5},e={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},f=function(a){return function(b,c,f,g){var h=d(b),i=e[a][d(b)];return 2===h&&(i=i[c?0:1]),i.replace(/%d/i,b)}},g=["كانون الثاني يناير","شباط فبراير","آذار مارس","نيسان أبريل","أيار مايو","حزيران يونيو","تموز يوليو","آب أغسطس","أيلول سبتمبر","تشرين الأول أكتوبر","تشرين الثاني نوفمبر","كانون الأول ديسمبر"],h=a.defineLocale("ar",{months:g,monthsShort:g,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(a){return"م"===a},meridiem:function(a,b,c){return a<12?"ص":"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:f("s"),m:f("m"),mm:f("m"),h:f("h"),hh:f("h"),d:f("d"),dd:f("d"),M:f("M"),MM:f("M"),y:f("y"),yy:f("y")},preparse:function(a){return a.replace(/\u200f/g,"").replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(a){return c[a]}).replace(/،/g,",")},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]}).replace(/,/g,"،")},week:{dow:6,doy:12}});return h});
bp-core/js/vendor/moment-js/locale/az.js ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Azerbaijani [az]
3
+ //! author : topchiyev : https://github.com/topchiyev
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var suffixes = {
14
+ 1: '-inci',
15
+ 5: '-inci',
16
+ 8: '-inci',
17
+ 70: '-inci',
18
+ 80: '-inci',
19
+ 2: '-nci',
20
+ 7: '-nci',
21
+ 20: '-nci',
22
+ 50: '-nci',
23
+ 3: '-üncü',
24
+ 4: '-üncü',
25
+ 100: '-üncü',
26
+ 6: '-ncı',
27
+ 9: '-uncu',
28
+ 10: '-uncu',
29
+ 30: '-uncu',
30
+ 60: '-ıncı',
31
+ 90: '-ıncı'
32
+ };
33
+
34
+ var az = moment.defineLocale('az', {
35
+ months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),
36
+ monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),
37
+ weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),
38
+ weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),
39
+ weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),
40
+ weekdaysParseExact : true,
41
+ longDateFormat : {
42
+ LT : 'HH:mm',
43
+ LTS : 'HH:mm:ss',
44
+ L : 'DD.MM.YYYY',
45
+ LL : 'D MMMM YYYY',
46
+ LLL : 'D MMMM YYYY HH:mm',
47
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
48
+ },
49
+ calendar : {
50
+ sameDay : '[bugün saat] LT',
51
+ nextDay : '[sabah saat] LT',
52
+ nextWeek : '[gələn həftə] dddd [saat] LT',
53
+ lastDay : '[dünən] LT',
54
+ lastWeek : '[keçən həftə] dddd [saat] LT',
55
+ sameElse : 'L'
56
+ },
57
+ relativeTime : {
58
+ future : '%s sonra',
59
+ past : '%s əvvəl',
60
+ s : 'birneçə saniyyə',
61
+ m : 'bir dəqiqə',
62
+ mm : '%d dəqiqə',
63
+ h : 'bir saat',
64
+ hh : '%d saat',
65
+ d : 'bir gün',
66
+ dd : '%d gün',
67
+ M : 'bir ay',
68
+ MM : '%d ay',
69
+ y : 'bir il',
70
+ yy : '%d il'
71
+ },
72
+ meridiemParse: /gecə|səhər|gündüz|axşam/,
73
+ isPM : function (input) {
74
+ return /^(gündüz|axşam)$/.test(input);
75
+ },
76
+ meridiem : function (hour, minute, isLower) {
77
+ if (hour < 4) {
78
+ return 'gecə';
79
+ } else if (hour < 12) {
80
+ return 'səhər';
81
+ } else if (hour < 17) {
82
+ return 'gündüz';
83
+ } else {
84
+ return 'axşam';
85
+ }
86
+ },
87
+ ordinalParse: /\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,
88
+ ordinal : function (number) {
89
+ if (number === 0) { // special case for zero
90
+ return number + '-ıncı';
91
+ }
92
+ var a = number % 10,
93
+ b = number % 100 - a,
94
+ c = number >= 100 ? 100 : null;
95
+ return number + (suffixes[a] || suffixes[b] || suffixes[c]);
96
+ },
97
+ week : {
98
+ dow : 1, // Monday is the first day of the week.
99
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
100
+ }
101
+ });
102
+
103
+ return az;
104
+
105
+ }));
bp-core/js/vendor/moment-js/locale/az.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b={1:"-inci",5:"-inci",8:"-inci",70:"-inci",80:"-inci",2:"-nci",7:"-nci",20:"-nci",50:"-nci",3:"-üncü",4:"-üncü",100:"-üncü",6:"-ncı",9:"-uncu",10:"-uncu",30:"-uncu",60:"-ıncı",90:"-ıncı"},c=a.defineLocale("az",{months:"yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),monthsShort:"yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),weekdays:"Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"),weekdaysShort:"Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"),weekdaysMin:"Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[sabah saat] LT",nextWeek:"[gələn həftə] dddd [saat] LT",lastDay:"[dünən] LT",lastWeek:"[keçən həftə] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s əvvəl",s:"birneçə saniyyə",m:"bir dəqiqə",mm:"%d dəqiqə",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir il",yy:"%d il"},meridiemParse:/gecə|səhər|gündüz|axşam/,isPM:function(a){return/^(gündüz|axşam)$/.test(a)},meridiem:function(a,b,c){return a<4?"gecə":a<12?"səhər":a<17?"gündüz":"axşam"},ordinalParse:/\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,ordinal:function(a){if(0===a)return a+"-ıncı";var c=a%10,d=a%100-c,e=a>=100?100:null;return a+(b[c]||b[d]||b[e])},week:{dow:1,doy:7}});return c});
bp-core/js/vendor/moment-js/locale/be.js ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Belarusian [be]
3
+ //! author : Dmitry Demidov : https://github.com/demidov91
4
+ //! author: Praleska: http://praleska.pro/
5
+ //! Author : Menelion Elensúle : https://github.com/Oire
6
+
7
+ ;(function (global, factory) {
8
+ typeof exports === 'object' && typeof module !== 'undefined'
9
+ && typeof require === 'function' ? factory(require('../moment')) :
10
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
11
+ factory(global.moment)
12
+ }(this, function (moment) { 'use strict';
13
+
14
+
15
+ function plural(word, num) {
16
+ var forms = word.split('_');
17
+ return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);
18
+ }
19
+ function relativeTimeWithPlural(number, withoutSuffix, key) {
20
+ var format = {
21
+ 'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',
22
+ 'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',
23
+ 'dd': 'дзень_дні_дзён',
24
+ 'MM': 'месяц_месяцы_месяцаў',
25
+ 'yy': 'год_гады_гадоў'
26
+ };
27
+ if (key === 'm') {
28
+ return withoutSuffix ? 'хвіліна' : 'хвіліну';
29
+ }
30
+ else if (key === 'h') {
31
+ return withoutSuffix ? 'гадзіна' : 'гадзіну';
32
+ }
33
+ else {
34
+ return number + ' ' + plural(format[key], +number);
35
+ }
36
+ }
37
+
38
+ var be = moment.defineLocale('be', {
39
+ months : {
40
+ format: 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_'),
41
+ standalone: 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_')
42
+ },
43
+ monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),
44
+ weekdays : {
45
+ format: 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_'),
46
+ standalone: 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),
47
+ isFormat: /\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/
48
+ },
49
+ weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
50
+ weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),
51
+ longDateFormat : {
52
+ LT : 'HH:mm',
53
+ LTS : 'HH:mm:ss',
54
+ L : 'DD.MM.YYYY',
55
+ LL : 'D MMMM YYYY г.',
56
+ LLL : 'D MMMM YYYY г., HH:mm',
57
+ LLLL : 'dddd, D MMMM YYYY г., HH:mm'
58
+ },
59
+ calendar : {
60
+ sameDay: '[Сёння ў] LT',
61
+ nextDay: '[Заўтра ў] LT',
62
+ lastDay: '[Учора ў] LT',
63
+ nextWeek: function () {
64
+ return '[У] dddd [ў] LT';
65
+ },
66
+ lastWeek: function () {
67
+ switch (this.day()) {
68
+ case 0:
69
+ case 3:
70
+ case 5:
71
+ case 6:
72
+ return '[У мінулую] dddd [ў] LT';
73
+ case 1:
74
+ case 2:
75
+ case 4:
76
+ return '[У мінулы] dddd [ў] LT';
77
+ }
78
+ },
79
+ sameElse: 'L'
80
+ },
81
+ relativeTime : {
82
+ future : 'праз %s',
83
+ past : '%s таму',
84
+ s : 'некалькі секунд',
85
+ m : relativeTimeWithPlural,
86
+ mm : relativeTimeWithPlural,
87
+ h : relativeTimeWithPlural,
88
+ hh : relativeTimeWithPlural,
89
+ d : 'дзень',
90
+ dd : relativeTimeWithPlural,
91
+ M : 'месяц',
92
+ MM : relativeTimeWithPlural,
93
+ y : 'год',
94
+ yy : relativeTimeWithPlural
95
+ },
96
+ meridiemParse: /ночы|раніцы|дня|вечара/,
97
+ isPM : function (input) {
98
+ return /^(дня|вечара)$/.test(input);
99
+ },
100
+ meridiem : function (hour, minute, isLower) {
101
+ if (hour < 4) {
102
+ return 'ночы';
103
+ } else if (hour < 12) {
104
+ return 'раніцы';
105
+ } else if (hour < 17) {
106
+ return 'дня';
107
+ } else {
108
+ return 'вечара';
109
+ }
110
+ },
111
+ ordinalParse: /\d{1,2}-(і|ы|га)/,
112
+ ordinal: function (number, period) {
113
+ switch (period) {
114
+ case 'M':
115
+ case 'd':
116
+ case 'DDD':
117
+ case 'w':
118
+ case 'W':
119
+ return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';
120
+ case 'D':
121
+ return number + '-га';
122
+ default:
123
+ return number;
124
+ }
125
+ },
126
+ week : {
127
+ dow : 1, // Monday is the first day of the week.
128
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
129
+ }
130
+ });
131
+
132
+ return be;
133
+
134
+ }));
bp-core/js/vendor/moment-js/locale/be.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";function b(a,b){var c=a.split("_");return b%10===1&&b%100!==11?c[0]:b%10>=2&&b%10<=4&&(b%100<10||b%100>=20)?c[1]:c[2]}function c(a,c,d){var e={mm:c?"хвіліна_хвіліны_хвілін":"хвіліну_хвіліны_хвілін",hh:c?"гадзіна_гадзіны_гадзін":"гадзіну_гадзіны_гадзін",dd:"дзень_дні_дзён",MM:"месяц_месяцы_месяцаў",yy:"год_гады_гадоў"};return"m"===d?c?"хвіліна":"хвіліну":"h"===d?c?"гадзіна":"гадзіну":a+" "+b(e[d],+a)}var d=a.defineLocale("be",{months:{format:"студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня".split("_"),standalone:"студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань".split("_")},monthsShort:"студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж".split("_"),weekdays:{format:"нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу".split("_"),standalone:"нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота".split("_"),isFormat:/\[ ?[Вв] ?(?:мінулую|наступную)? ?\] ?dddd/},weekdaysShort:"нд_пн_ат_ср_чц_пт_сб".split("_"),weekdaysMin:"нд_пн_ат_ср_чц_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., HH:mm",LLLL:"dddd, D MMMM YYYY г., HH:mm"},calendar:{sameDay:"[Сёння ў] LT",nextDay:"[Заўтра ў] LT",lastDay:"[Учора ў] LT",nextWeek:function(){return"[У] dddd [ў] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[У мінулую] dddd [ў] LT";case 1:case 2:case 4:return"[У мінулы] dddd [ў] LT"}},sameElse:"L"},relativeTime:{future:"праз %s",past:"%s таму",s:"некалькі секунд",m:c,mm:c,h:c,hh:c,d:"дзень",dd:c,M:"месяц",MM:c,y:"год",yy:c},meridiemParse:/ночы|раніцы|дня|вечара/,isPM:function(a){return/^(дня|вечара)$/.test(a)},meridiem:function(a,b,c){return a<4?"ночы":a<12?"раніцы":a<17?"дня":"вечара"},ordinalParse:/\d{1,2}-(і|ы|га)/,ordinal:function(a,b){switch(b){case"M":case"d":case"DDD":case"w":case"W":return a%10!==2&&a%10!==3||a%100===12||a%100===13?a+"-ы":a+"-і";case"D":return a+"-га";default:return a}},week:{dow:1,doy:7}});return d});
bp-core/js/vendor/moment-js/locale/bg.js ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Bulgarian [bg]
3
+ //! author : Krasen Borisov : https://github.com/kraz
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var bg = moment.defineLocale('bg', {
14
+ months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),
15
+ monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),
16
+ weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),
17
+ weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),
18
+ weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
19
+ longDateFormat : {
20
+ LT : 'H:mm',
21
+ LTS : 'H:mm:ss',
22
+ L : 'D.MM.YYYY',
23
+ LL : 'D MMMM YYYY',
24
+ LLL : 'D MMMM YYYY H:mm',
25
+ LLLL : 'dddd, D MMMM YYYY H:mm'
26
+ },
27
+ calendar : {
28
+ sameDay : '[Днес в] LT',
29
+ nextDay : '[Утре в] LT',
30
+ nextWeek : 'dddd [в] LT',
31
+ lastDay : '[Вчера в] LT',
32
+ lastWeek : function () {
33
+ switch (this.day()) {
34
+ case 0:
35
+ case 3:
36
+ case 6:
37
+ return '[В изминалата] dddd [в] LT';
38
+ case 1:
39
+ case 2:
40
+ case 4:
41
+ case 5:
42
+ return '[В изминалия] dddd [в] LT';
43
+ }
44
+ },
45
+ sameElse : 'L'
46
+ },
47
+ relativeTime : {
48
+ future : 'след %s',
49
+ past : 'преди %s',
50
+ s : 'няколко секунди',
51
+ m : 'минута',
52
+ mm : '%d минути',
53
+ h : 'час',
54
+ hh : '%d часа',
55
+ d : 'ден',
56
+ dd : '%d дни',
57
+ M : 'месец',
58
+ MM : '%d месеца',
59
+ y : 'година',
60
+ yy : '%d години'
61
+ },
62
+ ordinalParse: /\d{1,2}-(ев|ен|ти|ви|ри|ми)/,
63
+ ordinal : function (number) {
64
+ var lastDigit = number % 10,
65
+ last2Digits = number % 100;
66
+ if (number === 0) {
67
+ return number + '-ев';
68
+ } else if (last2Digits === 0) {
69
+ return number + '-ен';
70
+ } else if (last2Digits > 10 && last2Digits < 20) {
71
+ return number + '-ти';
72
+ } else if (lastDigit === 1) {
73
+ return number + '-ви';
74
+ } else if (lastDigit === 2) {
75
+ return number + '-ри';
76
+ } else if (lastDigit === 7 || lastDigit === 8) {
77
+ return number + '-ми';
78
+ } else {
79
+ return number + '-ти';
80
+ }
81
+ },
82
+ week : {
83
+ dow : 1, // Monday is the first day of the week.
84
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
85
+ }
86
+ });
87
+
88
+ return bg;
89
+
90
+ }));
bp-core/js/vendor/moment-js/locale/bg.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("bg",{months:"януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),monthsShort:"янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),weekdays:"неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),weekdaysShort:"нед_пон_вто_сря_чет_пет_съб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[Днес в] LT",nextDay:"[Утре в] LT",nextWeek:"dddd [в] LT",lastDay:"[Вчера в] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[В изминалата] dddd [в] LT";case 1:case 2:case 4:case 5:return"[В изминалия] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"след %s",past:"преди %s",s:"няколко секунди",m:"минута",mm:"%d минути",h:"час",hh:"%d часа",d:"ден",dd:"%d дни",M:"месец",MM:"%d месеца",y:"година",yy:"%d години"},ordinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(a){var b=a%10,c=a%100;return 0===a?a+"-ев":0===c?a+"-ен":c>10&&c<20?a+"-ти":1===b?a+"-ви":2===b?a+"-ри":7===b||8===b?a+"-ми":a+"-ти"},week:{dow:1,doy:7}});return b});
bp-core/js/vendor/moment-js/locale/bn.js ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Bengali [bn]
3
+ //! author : Kaushik Gandhi : https://github.com/kaushikgandhi
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var symbolMap = {
14
+ '1': '১',
15
+ '2': '২',
16
+ '3': '৩',
17
+ '4': '৪',
18
+ '5': '৫',
19
+ '6': '৬',
20
+ '7': '৭',
21
+ '8': '৮',
22
+ '9': '৯',
23
+ '0': '০'
24
+ },
25
+ numberMap = {
26
+ '১': '1',
27
+ '২': '2',
28
+ '৩': '3',
29
+ '৪': '4',
30
+ '৫': '5',
31
+ '৬': '6',
32
+ '৭': '7',
33
+ '৮': '8',
34
+ '৯': '9',
35
+ '০': '0'
36
+ };
37
+
38
+ var bn = moment.defineLocale('bn', {
39
+ months : 'জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),
40
+ monthsShort : 'জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে'.split('_'),
41
+ weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার'.split('_'),
42
+ weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি'.split('_'),
43
+ weekdaysMin : 'রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি'.split('_'),
44
+ longDateFormat : {
45
+ LT : 'A h:mm সময়',
46
+ LTS : 'A h:mm:ss সময়',
47
+ L : 'DD/MM/YYYY',
48
+ LL : 'D MMMM YYYY',
49
+ LLL : 'D MMMM YYYY, A h:mm সময়',
50
+ LLLL : 'dddd, D MMMM YYYY, A h:mm সময়'
51
+ },
52
+ calendar : {
53
+ sameDay : '[আজ] LT',
54
+ nextDay : '[আগামীকাল] LT',
55
+ nextWeek : 'dddd, LT',
56
+ lastDay : '[গতকাল] LT',
57
+ lastWeek : '[গত] dddd, LT',
58
+ sameElse : 'L'
59
+ },
60
+ relativeTime : {
61
+ future : '%s পরে',
62
+ past : '%s আগে',
63
+ s : 'কয়েক সেকেন্ড',
64
+ m : 'এক মিনিট',
65
+ mm : '%d মিনিট',
66
+ h : 'এক ঘন্টা',
67
+ hh : '%d ঘন্টা',
68
+ d : 'এক দিন',
69
+ dd : '%d দিন',
70
+ M : 'এক মাস',
71
+ MM : '%d মাস',
72
+ y : 'এক বছর',
73
+ yy : '%d বছর'
74
+ },
75
+ preparse: function (string) {
76
+ return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {
77
+ return numberMap[match];
78
+ });
79
+ },
80
+ postformat: function (string) {
81
+ return string.replace(/\d/g, function (match) {
82
+ return symbolMap[match];
83
+ });
84
+ },
85
+ meridiemParse: /রাত|সকাল|দুপুর|বিকাল|রাত/,
86
+ meridiemHour : function (hour, meridiem) {
87
+ if (hour === 12) {
88
+ hour = 0;
89
+ }
90
+ if ((meridiem === 'রাত' && hour >= 4) ||
91
+ (meridiem === 'দুপুর' && hour < 5) ||
92
+ meridiem === 'বিকাল') {
93
+ return hour + 12;
94
+ } else {
95
+ return hour;
96
+ }
97
+ },
98
+ meridiem : function (hour, minute, isLower) {
99
+ if (hour < 4) {
100
+ return 'রাত';
101
+ } else if (hour < 10) {
102
+ return 'সকাল';
103
+ } else if (hour < 17) {
104
+ return 'দুপুর';
105
+ } else if (hour < 20) {
106
+ return 'বিকাল';
107
+ } else {
108
+ return 'রাত';
109
+ }
110
+ },
111
+ week : {
112
+ dow : 0, // Sunday is the first day of the week.
113
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
114
+ }
115
+ });
116
+
117
+ return bn;
118
+
119
+ }));
bp-core/js/vendor/moment-js/locale/bn.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b={1:"১",2:"২",3:"৩",4:"৪",5:"৫",6:"৬",7:"৭",8:"৮",9:"৯",0:"০"},c={"১":"1","২":"2","৩":"3","৪":"4","৫":"5","৬":"6","৭":"7","৮":"8","৯":"9","০":"0"},d=a.defineLocale("bn",{months:"জানুয়ারী_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর".split("_"),monthsShort:"জানু_ফেব_মার্চ_এপ্র_মে_জুন_জুল_আগ_সেপ্ট_অক্টো_নভে_ডিসে".split("_"),weekdays:"রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার".split("_"),weekdaysShort:"রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি".split("_"),weekdaysMin:"রবি_সোম_মঙ্গ_বুধ_বৃহঃ_শুক্র_শনি".split("_"),longDateFormat:{LT:"A h:mm সময়",LTS:"A h:mm:ss সময়",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm সময়",LLLL:"dddd, D MMMM YYYY, A h:mm সময়"},calendar:{sameDay:"[আজ] LT",nextDay:"[আগামীকাল] LT",nextWeek:"dddd, LT",lastDay:"[গতকাল] LT",lastWeek:"[গত] dddd, LT",sameElse:"L"},relativeTime:{future:"%s পরে",past:"%s আগে",s:"কয়েক সেকেন্ড",m:"এক মিনিট",mm:"%d মিনিট",h:"এক ঘন্টা",hh:"%d ঘন্টা",d:"এক দিন",dd:"%d দিন",M:"এক মাস",MM:"%d মাস",y:"এক বছর",yy:"%d বছর"},preparse:function(a){return a.replace(/[১২৩৪৫৬৭৮৯০]/g,function(a){return c[a]})},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]})},meridiemParse:/রাত|সকাল|দুপুর|বিকাল|রাত/,meridiemHour:function(a,b){return 12===a&&(a=0),"রাত"===b&&a>=4||"দুপুর"===b&&a<5||"বিকাল"===b?a+12:a},meridiem:function(a,b,c){return a<4?"রাত":a<10?"সকাল":a<17?"দুপুর":a<20?"বিকাল":"রাত"},week:{dow:0,doy:6}});return d});
bp-core/js/vendor/moment-js/locale/bo.js ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Tibetan [bo]
3
+ //! author : Thupten N. Chakrishar : https://github.com/vajradog
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var symbolMap = {
14
+ '1': '༡',
15
+ '2': '༢',
16
+ '3': '༣',
17
+ '4': '༤',
18
+ '5': '༥',
19
+ '6': '༦',
20
+ '7': '༧',
21
+ '8': '༨',
22
+ '9': '༩',
23
+ '0': '༠'
24
+ },
25
+ numberMap = {
26
+ '༡': '1',
27
+ '༢': '2',
28
+ '༣': '3',
29
+ '༤': '4',
30
+ '༥': '5',
31
+ '༦': '6',
32
+ '༧': '7',
33
+ '༨': '8',
34
+ '༩': '9',
35
+ '༠': '0'
36
+ };
37
+
38
+ var bo = moment.defineLocale('bo', {
39
+ months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
40
+ monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),
41
+ weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),
42
+ weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
43
+ weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),
44
+ longDateFormat : {
45
+ LT : 'A h:mm',
46
+ LTS : 'A h:mm:ss',
47
+ L : 'DD/MM/YYYY',
48
+ LL : 'D MMMM YYYY',
49
+ LLL : 'D MMMM YYYY, A h:mm',
50
+ LLLL : 'dddd, D MMMM YYYY, A h:mm'
51
+ },
52
+ calendar : {
53
+ sameDay : '[དི་རིང] LT',
54
+ nextDay : '[སང་ཉིན] LT',
55
+ nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',
56
+ lastDay : '[ཁ་སང] LT',
57
+ lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',
58
+ sameElse : 'L'
59
+ },
60
+ relativeTime : {
61
+ future : '%s ལ་',
62
+ past : '%s སྔན་ལ',
63
+ s : 'ལམ་སང',
64
+ m : 'སྐར་མ་གཅིག',
65
+ mm : '%d སྐར་མ',
66
+ h : 'ཆུ་ཚོད་གཅིག',
67
+ hh : '%d ཆུ་ཚོད',
68
+ d : 'ཉིན་གཅིག',
69
+ dd : '%d ཉིན་',
70
+ M : 'ཟླ་བ་གཅིག',
71
+ MM : '%d ཟླ་བ',
72
+ y : 'ལོ་གཅིག',
73
+ yy : '%d ལོ'
74
+ },
75
+ preparse: function (string) {
76
+ return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {
77
+ return numberMap[match];
78
+ });
79
+ },
80
+ postformat: function (string) {
81
+ return string.replace(/\d/g, function (match) {
82
+ return symbolMap[match];
83
+ });
84
+ },
85
+ meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,
86
+ meridiemHour : function (hour, meridiem) {
87
+ if (hour === 12) {
88
+ hour = 0;
89
+ }
90
+ if ((meridiem === 'མཚན་མོ' && hour >= 4) ||
91
+ (meridiem === 'ཉིན་གུང' && hour < 5) ||
92
+ meridiem === 'དགོང་དག') {
93
+ return hour + 12;
94
+ } else {
95
+ return hour;
96
+ }
97
+ },
98
+ meridiem : function (hour, minute, isLower) {
99
+ if (hour < 4) {
100
+ return 'མཚན་མོ';
101
+ } else if (hour < 10) {
102
+ return 'ཞོགས་ཀས';
103
+ } else if (hour < 17) {
104
+ return 'ཉིན་གུང';
105
+ } else if (hour < 20) {
106
+ return 'དགོང་དག';
107
+ } else {
108
+ return 'མཚན་མོ';
109
+ }
110
+ },
111
+ week : {
112
+ dow : 0, // Sunday is the first day of the week.
113
+ doy : 6 // The week that contains Jan 1st is the first week of the year.
114
+ }
115
+ });
116
+
117
+ return bo;
118
+
119
+ }));
bp-core/js/vendor/moment-js/locale/bo.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b={1:"༡",2:"༢",3:"༣",4:"༤",5:"༥",6:"༦",7:"༧",8:"༨",9:"༩",0:"༠"},c={"༡":"1","༢":"2","༣":"3","༤":"4","༥":"5","༦":"6","༧":"7","༨":"8","༩":"9","༠":"0"},d=a.defineLocale("bo",{months:"ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ".split("_"),monthsShort:"ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ".split("_"),weekdays:"གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་".split("_"),weekdaysShort:"ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་".split("_"),weekdaysMin:"ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[དི་རིང] LT",nextDay:"[སང་ཉིན] LT",nextWeek:"[བདུན་ཕྲག་རྗེས་མ], LT",lastDay:"[ཁ་སང] LT",lastWeek:"[བདུན་ཕྲག་མཐའ་མ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ལ་",past:"%s སྔན་ལ",s:"ལམ་སང",m:"སྐར་མ་གཅིག",mm:"%d སྐར་མ",h:"ཆུ་ཚོད་གཅིག",hh:"%d ཆུ་ཚོད",d:"ཉིན་གཅིག",dd:"%d ཉིན་",M:"ཟླ་བ་གཅིག",MM:"%d ཟླ་བ",y:"ལོ་གཅིག",yy:"%d ལོ"},preparse:function(a){return a.replace(/[༡༢༣༤༥༦༧༨༩༠]/g,function(a){return c[a]})},postformat:function(a){return a.replace(/\d/g,function(a){return b[a]})},meridiemParse:/མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,meridiemHour:function(a,b){return 12===a&&(a=0),"མཚན་མོ"===b&&a>=4||"ཉིན་གུང"===b&&a<5||"དགོང་དག"===b?a+12:a},meridiem:function(a,b,c){return a<4?"མཚན་མོ":a<10?"ཞོགས་ཀས":a<17?"ཉིན་གུང":a<20?"དགོང་དག":"མཚན་མོ"},week:{dow:0,doy:6}});return d});
bp-core/js/vendor/moment-js/locale/br.js ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Breton [br]
3
+ //! author : Jean-Baptiste Le Duigou : https://github.com/jbleduigou
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ function relativeTimeWithMutation(number, withoutSuffix, key) {
14
+ var format = {
15
+ 'mm': 'munutenn',
16
+ 'MM': 'miz',
17
+ 'dd': 'devezh'
18
+ };
19
+ return number + ' ' + mutation(format[key], number);
20
+ }
21
+ function specialMutationForYears(number) {
22
+ switch (lastNumber(number)) {
23
+ case 1:
24
+ case 3:
25
+ case 4:
26
+ case 5:
27
+ case 9:
28
+ return number + ' bloaz';
29
+ default:
30
+ return number + ' vloaz';
31
+ }
32
+ }
33
+ function lastNumber(number) {
34
+ if (number > 9) {
35
+ return lastNumber(number % 10);
36
+ }
37
+ return number;
38
+ }
39
+ function mutation(text, number) {
40
+ if (number === 2) {
41
+ return softMutation(text);
42
+ }
43
+ return text;
44
+ }
45
+ function softMutation(text) {
46
+ var mutationTable = {
47
+ 'm': 'v',
48
+ 'b': 'v',
49
+ 'd': 'z'
50
+ };
51
+ if (mutationTable[text.charAt(0)] === undefined) {
52
+ return text;
53
+ }
54
+ return mutationTable[text.charAt(0)] + text.substring(1);
55
+ }
56
+
57
+ var br = moment.defineLocale('br', {
58
+ months : 'Genver_C\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),
59
+ monthsShort : 'Gen_C\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),
60
+ weekdays : 'Sul_Lun_Meurzh_Merc\'her_Yaou_Gwener_Sadorn'.split('_'),
61
+ weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),
62
+ weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),
63
+ weekdaysParseExact : true,
64
+ longDateFormat : {
65
+ LT : 'h[e]mm A',
66
+ LTS : 'h[e]mm:ss A',
67
+ L : 'DD/MM/YYYY',
68
+ LL : 'D [a viz] MMMM YYYY',
69
+ LLL : 'D [a viz] MMMM YYYY h[e]mm A',
70
+ LLLL : 'dddd, D [a viz] MMMM YYYY h[e]mm A'
71
+ },
72
+ calendar : {
73
+ sameDay : '[Hiziv da] LT',
74
+ nextDay : '[Warc\'hoazh da] LT',
75
+ nextWeek : 'dddd [da] LT',
76
+ lastDay : '[Dec\'h da] LT',
77
+ lastWeek : 'dddd [paset da] LT',
78
+ sameElse : 'L'
79
+ },
80
+ relativeTime : {
81
+ future : 'a-benn %s',
82
+ past : '%s \'zo',
83
+ s : 'un nebeud segondennoù',
84
+ m : 'ur vunutenn',
85
+ mm : relativeTimeWithMutation,
86
+ h : 'un eur',
87
+ hh : '%d eur',
88
+ d : 'un devezh',
89
+ dd : relativeTimeWithMutation,
90
+ M : 'ur miz',
91
+ MM : relativeTimeWithMutation,
92
+ y : 'ur bloaz',
93
+ yy : specialMutationForYears
94
+ },
95
+ ordinalParse: /\d{1,2}(añ|vet)/,
96
+ ordinal : function (number) {
97
+ var output = (number === 1) ? 'añ' : 'vet';
98
+ return number + output;
99
+ },
100
+ week : {
101
+ dow : 1, // Monday is the first day of the week.
102
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
103
+ }
104
+ });
105
+
106
+ return br;
107
+
108
+ }));
bp-core/js/vendor/moment-js/locale/br.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";function b(a,b,c){var d={mm:"munutenn",MM:"miz",dd:"devezh"};return a+" "+e(d[c],a)}function c(a){switch(d(a)){case 1:case 3:case 4:case 5:case 9:return a+" bloaz";default:return a+" vloaz"}}function d(a){return a>9?d(a%10):a}function e(a,b){return 2===b?f(a):a}function f(a){var b={m:"v",b:"v",d:"z"};return void 0===b[a.charAt(0)]?a:b[a.charAt(0)]+a.substring(1)}var g=a.defineLocale("br",{months:"Genver_C'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_C'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Merc'her_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"h[e]mm A",LTS:"h[e]mm:ss A",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY h[e]mm A",LLLL:"dddd, D [a viz] MMMM YYYY h[e]mm A"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warc'hoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Dec'h da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s 'zo",s:"un nebeud segondennoù",m:"ur vunutenn",mm:b,h:"un eur",hh:"%d eur",d:"un devezh",dd:b,M:"ur miz",MM:b,y:"ur bloaz",yy:c},ordinalParse:/\d{1,2}(añ|vet)/,ordinal:function(a){var b=1===a?"añ":"vet";return a+b},week:{dow:1,doy:4}});return g});
bp-core/js/vendor/moment-js/locale/bs.js ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Bosnian [bs]
3
+ //! author : Nedim Cholich : https://github.com/frontyard
4
+ //! based on (hr) translation by Bojan Marković
5
+
6
+ ;(function (global, factory) {
7
+ typeof exports === 'object' && typeof module !== 'undefined'
8
+ && typeof require === 'function' ? factory(require('../moment')) :
9
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
10
+ factory(global.moment)
11
+ }(this, function (moment) { 'use strict';
12
+
13
+
14
+ function translate(number, withoutSuffix, key) {
15
+ var result = number + ' ';
16
+ switch (key) {
17
+ case 'm':
18
+ return withoutSuffix ? 'jedna minuta' : 'jedne minute';
19
+ case 'mm':
20
+ if (number === 1) {
21
+ result += 'minuta';
22
+ } else if (number === 2 || number === 3 || number === 4) {
23
+ result += 'minute';
24
+ } else {
25
+ result += 'minuta';
26
+ }
27
+ return result;
28
+ case 'h':
29
+ return withoutSuffix ? 'jedan sat' : 'jednog sata';
30
+ case 'hh':
31
+ if (number === 1) {
32
+ result += 'sat';
33
+ } else if (number === 2 || number === 3 || number === 4) {
34
+ result += 'sata';
35
+ } else {
36
+ result += 'sati';
37
+ }
38
+ return result;
39
+ case 'dd':
40
+ if (number === 1) {
41
+ result += 'dan';
42
+ } else {
43
+ result += 'dana';
44
+ }
45
+ return result;
46
+ case 'MM':
47
+ if (number === 1) {
48
+ result += 'mjesec';
49
+ } else if (number === 2 || number === 3 || number === 4) {
50
+ result += 'mjeseca';
51
+ } else {
52
+ result += 'mjeseci';
53
+ }
54
+ return result;
55
+ case 'yy':
56
+ if (number === 1) {
57
+ result += 'godina';
58
+ } else if (number === 2 || number === 3 || number === 4) {
59
+ result += 'godine';
60
+ } else {
61
+ result += 'godina';
62
+ }
63
+ return result;
64
+ }
65
+ }
66
+
67
+ var bs = moment.defineLocale('bs', {
68
+ months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),
69
+ monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),
70
+ monthsParseExact: true,
71
+ weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),
72
+ weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),
73
+ weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),
74
+ weekdaysParseExact : true,
75
+ longDateFormat : {
76
+ LT : 'H:mm',
77
+ LTS : 'H:mm:ss',
78
+ L : 'DD.MM.YYYY',
79
+ LL : 'D. MMMM YYYY',
80
+ LLL : 'D. MMMM YYYY H:mm',
81
+ LLLL : 'dddd, D. MMMM YYYY H:mm'
82
+ },
83
+ calendar : {
84
+ sameDay : '[danas u] LT',
85
+ nextDay : '[sutra u] LT',
86
+ nextWeek : function () {
87
+ switch (this.day()) {
88
+ case 0:
89
+ return '[u] [nedjelju] [u] LT';
90
+ case 3:
91
+ return '[u] [srijedu] [u] LT';
92
+ case 6:
93
+ return '[u] [subotu] [u] LT';
94
+ case 1:
95
+ case 2:
96
+ case 4:
97
+ case 5:
98
+ return '[u] dddd [u] LT';
99
+ }
100
+ },
101
+ lastDay : '[jučer u] LT',
102
+ lastWeek : function () {
103
+ switch (this.day()) {
104
+ case 0:
105
+ case 3:
106
+ return '[prošlu] dddd [u] LT';
107
+ case 6:
108
+ return '[prošle] [subote] [u] LT';
109
+ case 1:
110
+ case 2:
111
+ case 4:
112
+ case 5:
113
+ return '[prošli] dddd [u] LT';
114
+ }
115
+ },
116
+ sameElse : 'L'
117
+ },
118
+ relativeTime : {
119
+ future : 'za %s',
120
+ past : 'prije %s',
121
+ s : 'par sekundi',
122
+ m : translate,
123
+ mm : translate,
124
+ h : translate,
125
+ hh : translate,
126
+ d : 'dan',
127
+ dd : translate,
128
+ M : 'mjesec',
129
+ MM : translate,
130
+ y : 'godinu',
131
+ yy : translate
132
+ },
133
+ ordinalParse: /\d{1,2}\./,
134
+ ordinal : '%d.',
135
+ week : {
136
+ dow : 1, // Monday is the first day of the week.
137
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
138
+ }
139
+ });
140
+
141
+ return bs;
142
+
143
+ }));
bp-core/js/vendor/moment-js/locale/bs.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";function b(a,b,c){var d=a+" ";switch(c){case"m":return b?"jedna minuta":"jedne minute";case"mm":return d+=1===a?"minuta":2===a||3===a||4===a?"minute":"minuta";case"h":return b?"jedan sat":"jednog sata";case"hh":return d+=1===a?"sat":2===a||3===a||4===a?"sata":"sati";case"dd":return d+=1===a?"dan":"dana";case"MM":return d+=1===a?"mjesec":2===a||3===a||4===a?"mjeseca":"mjeseci";case"yy":return d+=1===a?"godina":2===a||3===a||4===a?"godine":"godina"}}var c=a.defineLocale("bs",{months:"januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.".split("_"),monthsParseExact:!0,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",m:b,mm:b,h:b,hh:b,d:"dan",dd:b,M:"mjesec",MM:b,y:"godinu",yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}});return c});
bp-core/js/vendor/moment-js/locale/ca.js ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Catalan [ca]
3
+ //! author : Juan G. Hurtado : https://github.com/juanghurtado
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var ca = moment.defineLocale('ca', {
14
+ months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),
15
+ monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),
16
+ monthsParseExact : true,
17
+ weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),
18
+ weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),
19
+ weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),
20
+ weekdaysParseExact : true,
21
+ longDateFormat : {
22
+ LT : 'H:mm',
23
+ LTS : 'H:mm:ss',
24
+ L : 'DD/MM/YYYY',
25
+ LL : 'D MMMM YYYY',
26
+ LLL : 'D MMMM YYYY H:mm',
27
+ LLLL : 'dddd D MMMM YYYY H:mm'
28
+ },
29
+ calendar : {
30
+ sameDay : function () {
31
+ return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
32
+ },
33
+ nextDay : function () {
34
+ return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
35
+ },
36
+ nextWeek : function () {
37
+ return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
38
+ },
39
+ lastDay : function () {
40
+ return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
41
+ },
42
+ lastWeek : function () {
43
+ return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';
44
+ },
45
+ sameElse : 'L'
46
+ },
47
+ relativeTime : {
48
+ future : 'en %s',
49
+ past : 'fa %s',
50
+ s : 'uns segons',
51
+ m : 'un minut',
52
+ mm : '%d minuts',
53
+ h : 'una hora',
54
+ hh : '%d hores',
55
+ d : 'un dia',
56
+ dd : '%d dies',
57
+ M : 'un mes',
58
+ MM : '%d mesos',
59
+ y : 'un any',
60
+ yy : '%d anys'
61
+ },
62
+ ordinalParse: /\d{1,2}(r|n|t|è|a)/,
63
+ ordinal : function (number, period) {
64
+ var output = (number === 1) ? 'r' :
65
+ (number === 2) ? 'n' :
66
+ (number === 3) ? 'r' :
67
+ (number === 4) ? 't' : 'è';
68
+ if (period === 'w' || period === 'W') {
69
+ output = 'a';
70
+ }
71
+ return number + output;
72
+ },
73
+ week : {
74
+ dow : 1, // Monday is the first day of the week.
75
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
76
+ }
77
+ });
78
+
79
+ return ca;
80
+
81
+ }));
bp-core/js/vendor/moment-js/locale/ca.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("ca",{months:"gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),monthsShort:"gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:!0,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"Dg_Dl_Dt_Dc_Dj_Dv_Ds".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd D MMMM YYYY H:mm"},calendar:{sameDay:function(){return"[avui a "+(1!==this.hours()?"les":"la")+"] LT"},nextDay:function(){return"[demà a "+(1!==this.hours()?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(1!==this.hours()?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(1!==this.hours()?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(1!==this.hours()?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"fa %s",s:"uns segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},ordinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(a,b){var c=1===a?"r":2===a?"n":3===a?"r":4===a?"t":"è";return"w"!==b&&"W"!==b||(c="a"),a+c},week:{dow:1,doy:4}});return b});
bp-core/js/vendor/moment-js/locale/cs.js ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Czech [cs]
3
+ //! author : petrbela : https://github.com/petrbela
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),
14
+ monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');
15
+ function plural(n) {
16
+ return (n > 1) && (n < 5) && (~~(n / 10) !== 1);
17
+ }
18
+ function translate(number, withoutSuffix, key, isFuture) {
19
+ var result = number + ' ';
20
+ switch (key) {
21
+ case 's': // a few seconds / in a few seconds / a few seconds ago
22
+ return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';
23
+ case 'm': // a minute / in a minute / a minute ago
24
+ return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');
25
+ case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
26
+ if (withoutSuffix || isFuture) {
27
+ return result + (plural(number) ? 'minuty' : 'minut');
28
+ } else {
29
+ return result + 'minutami';
30
+ }
31
+ break;
32
+ case 'h': // an hour / in an hour / an hour ago
33
+ return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');
34
+ case 'hh': // 9 hours / in 9 hours / 9 hours ago
35
+ if (withoutSuffix || isFuture) {
36
+ return result + (plural(number) ? 'hodiny' : 'hodin');
37
+ } else {
38
+ return result + 'hodinami';
39
+ }
40
+ break;
41
+ case 'd': // a day / in a day / a day ago
42
+ return (withoutSuffix || isFuture) ? 'den' : 'dnem';
43
+ case 'dd': // 9 days / in 9 days / 9 days ago
44
+ if (withoutSuffix || isFuture) {
45
+ return result + (plural(number) ? 'dny' : 'dní');
46
+ } else {
47
+ return result + 'dny';
48
+ }
49
+ break;
50
+ case 'M': // a month / in a month / a month ago
51
+ return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';
52
+ case 'MM': // 9 months / in 9 months / 9 months ago
53
+ if (withoutSuffix || isFuture) {
54
+ return result + (plural(number) ? 'měsíce' : 'měsíců');
55
+ } else {
56
+ return result + 'měsíci';
57
+ }
58
+ break;
59
+ case 'y': // a year / in a year / a year ago
60
+ return (withoutSuffix || isFuture) ? 'rok' : 'rokem';
61
+ case 'yy': // 9 years / in 9 years / 9 years ago
62
+ if (withoutSuffix || isFuture) {
63
+ return result + (plural(number) ? 'roky' : 'let');
64
+ } else {
65
+ return result + 'lety';
66
+ }
67
+ break;
68
+ }
69
+ }
70
+
71
+ var cs = moment.defineLocale('cs', {
72
+ months : months,
73
+ monthsShort : monthsShort,
74
+ monthsParse : (function (months, monthsShort) {
75
+ var i, _monthsParse = [];
76
+ for (i = 0; i < 12; i++) {
77
+ // use custom parser to solve problem with July (červenec)
78
+ _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');
79
+ }
80
+ return _monthsParse;
81
+ }(months, monthsShort)),
82
+ shortMonthsParse : (function (monthsShort) {
83
+ var i, _shortMonthsParse = [];
84
+ for (i = 0; i < 12; i++) {
85
+ _shortMonthsParse[i] = new RegExp('^' + monthsShort[i] + '$', 'i');
86
+ }
87
+ return _shortMonthsParse;
88
+ }(monthsShort)),
89
+ longMonthsParse : (function (months) {
90
+ var i, _longMonthsParse = [];
91
+ for (i = 0; i < 12; i++) {
92
+ _longMonthsParse[i] = new RegExp('^' + months[i] + '$', 'i');
93
+ }
94
+ return _longMonthsParse;
95
+ }(months)),
96
+ weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
97
+ weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),
98
+ weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),
99
+ longDateFormat : {
100
+ LT: 'H:mm',
101
+ LTS : 'H:mm:ss',
102
+ L : 'DD.MM.YYYY',
103
+ LL : 'D. MMMM YYYY',
104
+ LLL : 'D. MMMM YYYY H:mm',
105
+ LLLL : 'dddd D. MMMM YYYY H:mm',
106
+ l : 'D. M. YYYY'
107
+ },
108
+ calendar : {
109
+ sameDay: '[dnes v] LT',
110
+ nextDay: '[zítra v] LT',
111
+ nextWeek: function () {
112
+ switch (this.day()) {
113
+ case 0:
114
+ return '[v neděli v] LT';
115
+ case 1:
116
+ case 2:
117
+ return '[v] dddd [v] LT';
118
+ case 3:
119
+ return '[ve středu v] LT';
120
+ case 4:
121
+ return '[ve čtvrtek v] LT';
122
+ case 5:
123
+ return '[v pátek v] LT';
124
+ case 6:
125
+ return '[v sobotu v] LT';
126
+ }
127
+ },
128
+ lastDay: '[včera v] LT',
129
+ lastWeek: function () {
130
+ switch (this.day()) {
131
+ case 0:
132
+ return '[minulou neděli v] LT';
133
+ case 1:
134
+ case 2:
135
+ return '[minulé] dddd [v] LT';
136
+ case 3:
137
+ return '[minulou středu v] LT';
138
+ case 4:
139
+ case 5:
140
+ return '[minulý] dddd [v] LT';
141
+ case 6:
142
+ return '[minulou sobotu v] LT';
143
+ }
144
+ },
145
+ sameElse: 'L'
146
+ },
147
+ relativeTime : {
148
+ future : 'za %s',
149
+ past : 'před %s',
150
+ s : translate,
151
+ m : translate,
152
+ mm : translate,
153
+ h : translate,
154
+ hh : translate,
155
+ d : translate,
156
+ dd : translate,
157
+ M : translate,
158
+ MM : translate,
159
+ y : translate,
160
+ yy : translate
161
+ },
162
+ ordinalParse : /\d{1,2}\./,
163
+ ordinal : '%d.',
164
+ week : {
165
+ dow : 1, // Monday is the first day of the week.
166
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
167
+ }
168
+ });
169
+
170
+ return cs;
171
+
172
+ }));
bp-core/js/vendor/moment-js/locale/cs.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";function b(a){return a>1&&a<5&&1!==~~(a/10)}function c(a,c,d,e){var f=a+" ";switch(d){case"s":return c||e?"pár sekund":"pár sekundami";case"m":return c?"minuta":e?"minutu":"minutou";case"mm":return c||e?f+(b(a)?"minuty":"minut"):f+"minutami";case"h":return c?"hodina":e?"hodinu":"hodinou";case"hh":return c||e?f+(b(a)?"hodiny":"hodin"):f+"hodinami";case"d":return c||e?"den":"dnem";case"dd":return c||e?f+(b(a)?"dny":"dní"):f+"dny";case"M":return c||e?"měsíc":"měsícem";case"MM":return c||e?f+(b(a)?"měsíce":"měsíců"):f+"měsíci";case"y":return c||e?"rok":"rokem";case"yy":return c||e?f+(b(a)?"roky":"let"):f+"lety"}}var d="leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),e="led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_"),f=a.defineLocale("cs",{months:d,monthsShort:e,monthsParse:function(a,b){var c,d=[];for(c=0;c<12;c++)d[c]=new RegExp("^"+a[c]+"$|^"+b[c]+"$","i");return d}(d,e),shortMonthsParse:function(a){var b,c=[];for(b=0;b<12;b++)c[b]=new RegExp("^"+a[b]+"$","i");return c}(e),longMonthsParse:function(a){var b,c=[];for(b=0;b<12;b++)c[b]=new RegExp("^"+a[b]+"$","i");return c}(d),weekdays:"neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),weekdaysShort:"ne_po_út_st_čt_pá_so".split("_"),weekdaysMin:"ne_po_út_st_čt_pá_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[zítra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v neděli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve středu v] LT";case 4:return"[ve čtvrtek v] LT";case 5:return"[v pátek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[včera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou neděli v] LT";case 1:case 2:return"[minulé] dddd [v] LT";case 3:return"[minulou středu v] LT";case 4:case 5:return"[minulý] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"před %s",s:c,m:c,mm:c,h:c,hh:c,d:c,dd:c,M:c,MM:c,y:c,yy:c},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return f});
bp-core/js/vendor/moment-js/locale/cv.js ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Chuvash [cv]
3
+ //! author : Anatoly Mironov : https://github.com/mirontoli
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var cv = moment.defineLocale('cv', {
14
+ months : 'кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав'.split('_'),
15
+ monthsShort : 'кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш'.split('_'),
16
+ weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун'.split('_'),
17
+ weekdaysShort : 'выр_тун_ытл_юн_кӗҫ_эрн_шӑм'.split('_'),
18
+ weekdaysMin : 'вр_тн_ыт_юн_кҫ_эр_шм'.split('_'),
19
+ longDateFormat : {
20
+ LT : 'HH:mm',
21
+ LTS : 'HH:mm:ss',
22
+ L : 'DD-MM-YYYY',
23
+ LL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]',
24
+ LLL : 'YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm',
25
+ LLLL : 'dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm'
26
+ },
27
+ calendar : {
28
+ sameDay: '[Паян] LT [сехетре]',
29
+ nextDay: '[Ыран] LT [сехетре]',
30
+ lastDay: '[Ӗнер] LT [сехетре]',
31
+ nextWeek: '[Ҫитес] dddd LT [сехетре]',
32
+ lastWeek: '[Иртнӗ] dddd LT [сехетре]',
33
+ sameElse: 'L'
34
+ },
35
+ relativeTime : {
36
+ future : function (output) {
37
+ var affix = /сехет$/i.exec(output) ? 'рен' : /ҫул$/i.exec(output) ? 'тан' : 'ран';
38
+ return output + affix;
39
+ },
40
+ past : '%s каялла',
41
+ s : 'пӗр-ик ҫеккунт',
42
+ m : 'пӗр минут',
43
+ mm : '%d минут',
44
+ h : 'пӗр сехет',
45
+ hh : '%d сехет',
46
+ d : 'пӗр кун',
47
+ dd : '%d кун',
48
+ M : 'пӗр уйӑх',
49
+ MM : '%d уйӑх',
50
+ y : 'пӗр ҫул',
51
+ yy : '%d ҫул'
52
+ },
53
+ ordinalParse: /\d{1,2}-мӗш/,
54
+ ordinal : '%d-мӗш',
55
+ week : {
56
+ dow : 1, // Monday is the first day of the week.
57
+ doy : 7 // The week that contains Jan 1st is the first week of the year.
58
+ }
59
+ });
60
+
61
+ return cv;
62
+
63
+ }));
bp-core/js/vendor/moment-js/locale/cv.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("cv",{months:"кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав".split("_"),monthsShort:"кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш".split("_"),weekdays:"вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун".split("_"),weekdaysShort:"выр_тун_ытл_юн_кӗҫ_эрн_шӑм".split("_"),weekdaysMin:"вр_тн_ыт_юн_кҫ_эр_шм".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]",LLL:"YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm",LLLL:"dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm"},calendar:{sameDay:"[Паян] LT [сехетре]",nextDay:"[Ыран] LT [сехетре]",lastDay:"[Ӗнер] LT [сехетре]",nextWeek:"[Ҫитес] dddd LT [сехетре]",lastWeek:"[Иртнӗ] dddd LT [сехетре]",sameElse:"L"},relativeTime:{future:function(a){var b=/сехет$/i.exec(a)?"рен":/ҫул$/i.exec(a)?"тан":"ран";return a+b},past:"%s каялла",s:"пӗр-ик ҫеккунт",m:"пӗр минут",mm:"%d минут",h:"пӗр сехет",hh:"%d сехет",d:"пӗр кун",dd:"%d кун",M:"пӗр уйӑх",MM:"%d уйӑх",y:"пӗр ҫул",yy:"%d ҫул"},ordinalParse:/\d{1,2}-мӗш/,ordinal:"%d-мӗш",week:{dow:1,doy:7}});return b});
bp-core/js/vendor/moment-js/locale/cy.js ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Welsh [cy]
3
+ //! author : Robert Allen : https://github.com/robgallen
4
+ //! author : https://github.com/ryangreaves
5
+
6
+ ;(function (global, factory) {
7
+ typeof exports === 'object' && typeof module !== 'undefined'
8
+ && typeof require === 'function' ? factory(require('../moment')) :
9
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
10
+ factory(global.moment)
11
+ }(this, function (moment) { 'use strict';
12
+
13
+
14
+ var cy = moment.defineLocale('cy', {
15
+ months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),
16
+ monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),
17
+ weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),
18
+ weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),
19
+ weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),
20
+ weekdaysParseExact : true,
21
+ // time formats are the same as en-gb
22
+ longDateFormat: {
23
+ LT: 'HH:mm',
24
+ LTS : 'HH:mm:ss',
25
+ L: 'DD/MM/YYYY',
26
+ LL: 'D MMMM YYYY',
27
+ LLL: 'D MMMM YYYY HH:mm',
28
+ LLLL: 'dddd, D MMMM YYYY HH:mm'
29
+ },
30
+ calendar: {
31
+ sameDay: '[Heddiw am] LT',
32
+ nextDay: '[Yfory am] LT',
33
+ nextWeek: 'dddd [am] LT',
34
+ lastDay: '[Ddoe am] LT',
35
+ lastWeek: 'dddd [diwethaf am] LT',
36
+ sameElse: 'L'
37
+ },
38
+ relativeTime: {
39
+ future: 'mewn %s',
40
+ past: '%s yn ôl',
41
+ s: 'ychydig eiliadau',
42
+ m: 'munud',
43
+ mm: '%d munud',
44
+ h: 'awr',
45
+ hh: '%d awr',
46
+ d: 'diwrnod',
47
+ dd: '%d diwrnod',
48
+ M: 'mis',
49
+ MM: '%d mis',
50
+ y: 'blwyddyn',
51
+ yy: '%d flynedd'
52
+ },
53
+ ordinalParse: /\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,
54
+ // traditional ordinal numbers above 31 are not commonly used in colloquial Welsh
55
+ ordinal: function (number) {
56
+ var b = number,
57
+ output = '',
58
+ lookup = [
59
+ '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed
60
+ 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed
61
+ ];
62
+ if (b > 20) {
63
+ if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {
64
+ output = 'fed'; // not 30ain, 70ain or 90ain
65
+ } else {
66
+ output = 'ain';
67
+ }
68
+ } else if (b > 0) {
69
+ output = lookup[b];
70
+ }
71
+ return number + output;
72
+ },
73
+ week : {
74
+ dow : 1, // Monday is the first day of the week.
75
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
76
+ }
77
+ });
78
+
79
+ return cy;
80
+
81
+ }));
bp-core/js/vendor/moment-js/locale/cy.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("cy",{months:"Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),monthsShort:"Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),weekdays:"Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),weekdaysShort:"Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),weekdaysMin:"Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Heddiw am] LT",nextDay:"[Yfory am] LT",nextWeek:"dddd [am] LT",lastDay:"[Ddoe am] LT",lastWeek:"dddd [diwethaf am] LT",sameElse:"L"},relativeTime:{future:"mewn %s",past:"%s yn ôl",s:"ychydig eiliadau",m:"munud",mm:"%d munud",h:"awr",hh:"%d awr",d:"diwrnod",dd:"%d diwrnod",M:"mis",MM:"%d mis",y:"blwyddyn",yy:"%d flynedd"},ordinalParse:/\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,ordinal:function(a){var b=a,c="",d=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"];return b>20?c=40===b||50===b||60===b||80===b||100===b?"fed":"ain":b>0&&(c=d[b]),a+c},week:{dow:1,doy:4}});return b});
bp-core/js/vendor/moment-js/locale/da.js ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Danish [da]
3
+ //! author : Ulrik Nielsen : https://github.com/mrbase
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var da = moment.defineLocale('da', {
14
+ months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),
15
+ monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),
16
+ weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),
17
+ weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),
18
+ weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),
19
+ longDateFormat : {
20
+ LT : 'HH:mm',
21
+ LTS : 'HH:mm:ss',
22
+ L : 'DD/MM/YYYY',
23
+ LL : 'D. MMMM YYYY',
24
+ LLL : 'D. MMMM YYYY HH:mm',
25
+ LLLL : 'dddd [d.] D. MMMM YYYY HH:mm'
26
+ },
27
+ calendar : {
28
+ sameDay : '[I dag kl.] LT',
29
+ nextDay : '[I morgen kl.] LT',
30
+ nextWeek : 'dddd [kl.] LT',
31
+ lastDay : '[I går kl.] LT',
32
+ lastWeek : '[sidste] dddd [kl] LT',
33
+ sameElse : 'L'
34
+ },
35
+ relativeTime : {
36
+ future : 'om %s',
37
+ past : '%s siden',
38
+ s : 'få sekunder',
39
+ m : 'et minut',
40
+ mm : '%d minutter',
41
+ h : 'en time',
42
+ hh : '%d timer',
43
+ d : 'en dag',
44
+ dd : '%d dage',
45
+ M : 'en måned',
46
+ MM : '%d måneder',
47
+ y : 'et år',
48
+ yy : '%d år'
49
+ },
50
+ ordinalParse: /\d{1,2}\./,
51
+ ordinal : '%d.',
52
+ week : {
53
+ dow : 1, // Monday is the first day of the week.
54
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
55
+ }
56
+ });
57
+
58
+ return da;
59
+
60
+ }));
bp-core/js/vendor/moment-js/locale/da.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tir_ons_tor_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd [d.] D. MMMM YYYY HH:mm"},calendar:{sameDay:"[I dag kl.] LT",nextDay:"[I morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[I går kl.] LT",lastWeek:"[sidste] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"få sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en måned",MM:"%d måneder",y:"et år",yy:"%d år"},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return b});
bp-core/js/vendor/moment-js/locale/de-at.js ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : German (Austria) [de-at]
3
+ //! author : lluchs : https://github.com/lluchs
4
+ //! author: Menelion Elensúle: https://github.com/Oire
5
+ //! author : Martin Groller : https://github.com/MadMG
6
+ //! author : Mikolaj Dadela : https://github.com/mik01aj
7
+
8
+ ;(function (global, factory) {
9
+ typeof exports === 'object' && typeof module !== 'undefined'
10
+ && typeof require === 'function' ? factory(require('../moment')) :
11
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
12
+ factory(global.moment)
13
+ }(this, function (moment) { 'use strict';
14
+
15
+
16
+ function processRelativeTime(number, withoutSuffix, key, isFuture) {
17
+ var format = {
18
+ 'm': ['eine Minute', 'einer Minute'],
19
+ 'h': ['eine Stunde', 'einer Stunde'],
20
+ 'd': ['ein Tag', 'einem Tag'],
21
+ 'dd': [number + ' Tage', number + ' Tagen'],
22
+ 'M': ['ein Monat', 'einem Monat'],
23
+ 'MM': [number + ' Monate', number + ' Monaten'],
24
+ 'y': ['ein Jahr', 'einem Jahr'],
25
+ 'yy': [number + ' Jahre', number + ' Jahren']
26
+ };
27
+ return withoutSuffix ? format[key][0] : format[key][1];
28
+ }
29
+
30
+ var de_at = moment.defineLocale('de-at', {
31
+ months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
32
+ monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
33
+ monthsParseExact : true,
34
+ weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
35
+ weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
36
+ weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
37
+ weekdaysParseExact : true,
38
+ longDateFormat : {
39
+ LT: 'HH:mm',
40
+ LTS: 'HH:mm:ss',
41
+ L : 'DD.MM.YYYY',
42
+ LL : 'D. MMMM YYYY',
43
+ LLL : 'D. MMMM YYYY HH:mm',
44
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
45
+ },
46
+ calendar : {
47
+ sameDay: '[heute um] LT [Uhr]',
48
+ sameElse: 'L',
49
+ nextDay: '[morgen um] LT [Uhr]',
50
+ nextWeek: 'dddd [um] LT [Uhr]',
51
+ lastDay: '[gestern um] LT [Uhr]',
52
+ lastWeek: '[letzten] dddd [um] LT [Uhr]'
53
+ },
54
+ relativeTime : {
55
+ future : 'in %s',
56
+ past : 'vor %s',
57
+ s : 'ein paar Sekunden',
58
+ m : processRelativeTime,
59
+ mm : '%d Minuten',
60
+ h : processRelativeTime,
61
+ hh : '%d Stunden',
62
+ d : processRelativeTime,
63
+ dd : processRelativeTime,
64
+ M : processRelativeTime,
65
+ MM : processRelativeTime,
66
+ y : processRelativeTime,
67
+ yy : processRelativeTime
68
+ },
69
+ ordinalParse: /\d{1,2}\./,
70
+ ordinal : '%d.',
71
+ week : {
72
+ dow : 1, // Monday is the first day of the week.
73
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
74
+ }
75
+ });
76
+
77
+ return de_at;
78
+
79
+ }));
bp-core/js/vendor/moment-js/locale/de-at.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";function b(a,b,c,d){var e={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?e[c][0]:e[c][1]}var c=a.defineLocale("de-at",{months:"Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:b,mm:"%d Minuten",h:b,hh:"%d Stunden",d:b,dd:b,M:b,MM:b,y:b,yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return c});
bp-core/js/vendor/moment-js/locale/de.js ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : German [de]
3
+ //! author : lluchs : https://github.com/lluchs
4
+ //! author: Menelion Elensúle: https://github.com/Oire
5
+ //! author : Mikolaj Dadela : https://github.com/mik01aj
6
+
7
+ ;(function (global, factory) {
8
+ typeof exports === 'object' && typeof module !== 'undefined'
9
+ && typeof require === 'function' ? factory(require('../moment')) :
10
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
11
+ factory(global.moment)
12
+ }(this, function (moment) { 'use strict';
13
+
14
+
15
+ function processRelativeTime(number, withoutSuffix, key, isFuture) {
16
+ var format = {
17
+ 'm': ['eine Minute', 'einer Minute'],
18
+ 'h': ['eine Stunde', 'einer Stunde'],
19
+ 'd': ['ein Tag', 'einem Tag'],
20
+ 'dd': [number + ' Tage', number + ' Tagen'],
21
+ 'M': ['ein Monat', 'einem Monat'],
22
+ 'MM': [number + ' Monate', number + ' Monaten'],
23
+ 'y': ['ein Jahr', 'einem Jahr'],
24
+ 'yy': [number + ' Jahre', number + ' Jahren']
25
+ };
26
+ return withoutSuffix ? format[key][0] : format[key][1];
27
+ }
28
+
29
+ var de = moment.defineLocale('de', {
30
+ months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),
31
+ monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),
32
+ monthsParseExact : true,
33
+ weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),
34
+ weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
35
+ weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
36
+ weekdaysParseExact : true,
37
+ longDateFormat : {
38
+ LT: 'HH:mm',
39
+ LTS: 'HH:mm:ss',
40
+ L : 'DD.MM.YYYY',
41
+ LL : 'D. MMMM YYYY',
42
+ LLL : 'D. MMMM YYYY HH:mm',
43
+ LLLL : 'dddd, D. MMMM YYYY HH:mm'
44
+ },
45
+ calendar : {
46
+ sameDay: '[heute um] LT [Uhr]',
47
+ sameElse: 'L',
48
+ nextDay: '[morgen um] LT [Uhr]',
49
+ nextWeek: 'dddd [um] LT [Uhr]',
50
+ lastDay: '[gestern um] LT [Uhr]',
51
+ lastWeek: '[letzten] dddd [um] LT [Uhr]'
52
+ },
53
+ relativeTime : {
54
+ future : 'in %s',
55
+ past : 'vor %s',
56
+ s : 'ein paar Sekunden',
57
+ m : processRelativeTime,
58
+ mm : '%d Minuten',
59
+ h : processRelativeTime,
60
+ hh : '%d Stunden',
61
+ d : processRelativeTime,
62
+ dd : processRelativeTime,
63
+ M : processRelativeTime,
64
+ MM : processRelativeTime,
65
+ y : processRelativeTime,
66
+ yy : processRelativeTime
67
+ },
68
+ ordinalParse: /\d{1,2}\./,
69
+ ordinal : '%d.',
70
+ week : {
71
+ dow : 1, // Monday is the first day of the week.
72
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
73
+ }
74
+ });
75
+
76
+ return de;
77
+
78
+ }));
bp-core/js/vendor/moment-js/locale/de.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";function b(a,b,c,d){var e={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[a+" Tage",a+" Tagen"],M:["ein Monat","einem Monat"],MM:[a+" Monate",a+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[a+" Jahre",a+" Jahren"]};return b?e[c][0]:e[c][1]}var c=a.defineLocale("de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:!0,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",m:b,mm:"%d Minuten",h:b,hh:"%d Stunden",d:b,dd:b,M:b,MM:b,y:b,yy:b},ordinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return c});
bp-core/js/vendor/moment-js/locale/dv.js ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Maldivian [dv]
3
+ //! author : Jawish Hameed : https://github.com/jawish
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var months = [
14
+ 'ޖެނުއަރީ',
15
+ 'ފެބްރުއަރީ',
16
+ 'މާރިޗު',
17
+ 'އޭޕްރީލު',
18
+ 'މޭ',
19
+ 'ޖޫން',
20
+ 'ޖުލައި',
21
+ 'އޯގަސްޓު',
22
+ 'ސެޕްޓެމްބަރު',
23
+ 'އޮކްޓޯބަރު',
24
+ 'ނޮވެމްބަރު',
25
+ 'ޑިސެމްބަރު'
26
+ ], weekdays = [
27
+ 'އާދިއްތަ',
28
+ 'ހޯމަ',
29
+ 'އަންގާރަ',
30
+ 'ބުދަ',
31
+ 'ބުރާސްފަތި',
32
+ 'ހުކުރު',
33
+ 'ހޮނިހިރު'
34
+ ];
35
+
36
+ var dv = moment.defineLocale('dv', {
37
+ months : months,
38
+ monthsShort : months,
39
+ weekdays : weekdays,
40
+ weekdaysShort : weekdays,
41
+ weekdaysMin : 'އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި'.split('_'),
42
+ longDateFormat : {
43
+
44
+ LT : 'HH:mm',
45
+ LTS : 'HH:mm:ss',
46
+ L : 'D/M/YYYY',
47
+ LL : 'D MMMM YYYY',
48
+ LLL : 'D MMMM YYYY HH:mm',
49
+ LLLL : 'dddd D MMMM YYYY HH:mm'
50
+ },
51
+ meridiemParse: /މކ|މފ/,
52
+ isPM : function (input) {
53
+ return 'މފ' === input;
54
+ },
55
+ meridiem : function (hour, minute, isLower) {
56
+ if (hour < 12) {
57
+ return 'މކ';
58
+ } else {
59
+ return 'މފ';
60
+ }
61
+ },
62
+ calendar : {
63
+ sameDay : '[މިއަދު] LT',
64
+ nextDay : '[މާދަމާ] LT',
65
+ nextWeek : 'dddd LT',
66
+ lastDay : '[އިއްޔެ] LT',
67
+ lastWeek : '[ފާއިތުވި] dddd LT',
68
+ sameElse : 'L'
69
+ },
70
+ relativeTime : {
71
+ future : 'ތެރޭގައި %s',
72
+ past : 'ކުރިން %s',
73
+ s : 'ސިކުންތުކޮޅެއް',
74
+ m : 'މިނިޓެއް',
75
+ mm : 'މިނިޓު %d',
76
+ h : 'ގަޑިއިރެއް',
77
+ hh : 'ގަޑިއިރު %d',
78
+ d : 'ދުވަހެއް',
79
+ dd : 'ދުވަސް %d',
80
+ M : 'މަހެއް',
81
+ MM : 'މަސް %d',
82
+ y : 'އަހަރެއް',
83
+ yy : 'އަހަރު %d'
84
+ },
85
+ preparse: function (string) {
86
+ return string.replace(/،/g, ',');
87
+ },
88
+ postformat: function (string) {
89
+ return string.replace(/,/g, '،');
90
+ },
91
+ week : {
92
+ dow : 7, // Sunday is the first day of the week.
93
+ doy : 12 // The week that contains Jan 1st is the first week of the year.
94
+ }
95
+ });
96
+
97
+ return dv;
98
+
99
+ }));
bp-core/js/vendor/moment-js/locale/dv.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=["ޖެނުއަރީ","ފެބްރުއަރީ","މާރިޗު","އޭޕްރީލު","މޭ","ޖޫން","ޖުލައި","އޯގަސްޓު","ސެޕްޓެމްބަރު","އޮކްޓޯބަރު","ނޮވެމްބަރު","ޑިސެމްބަރު"],c=["އާދިއްތަ","ހޯމަ","އަންގާރަ","ބުދަ","ބުރާސްފަތި","ހުކުރު","ހޮނިހިރު"],d=a.defineLocale("dv",{months:b,monthsShort:b,weekdays:c,weekdaysShort:c,weekdaysMin:"އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/މކ|މފ/,isPM:function(a){return"މފ"===a},meridiem:function(a,b,c){return a<12?"މކ":"މފ"},calendar:{sameDay:"[މިއަދު] LT",nextDay:"[މާދަމާ] LT",nextWeek:"dddd LT",lastDay:"[އިއްޔެ] LT",lastWeek:"[ފާއިތުވި] dddd LT",sameElse:"L"},relativeTime:{future:"ތެރޭގައި %s",past:"ކުރިން %s",s:"ސިކުންތުކޮޅެއް",m:"މިނިޓެއް",mm:"މިނިޓު %d",h:"ގަޑިއިރެއް",hh:"ގަޑިއިރު %d",d:"ދުވަހެއް",dd:"ދުވަސް %d",M:"މަހެއް",MM:"މަސް %d",y:"އަހަރެއް",yy:"އަހަރު %d"},preparse:function(a){return a.replace(/،/g,",")},postformat:function(a){return a.replace(/,/g,"،")},week:{dow:7,doy:12}});return d});
bp-core/js/vendor/moment-js/locale/el.js ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : Greek [el]
3
+ //! author : Aggelos Karalias : https://github.com/mehiel
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+ function isFunction(input) {
13
+ return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]';
14
+ }
15
+
16
+
17
+ var el = moment.defineLocale('el', {
18
+ monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),
19
+ monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),
20
+ months : function (momentToFormat, format) {
21
+ if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'
22
+ return this._monthsGenitiveEl[momentToFormat.month()];
23
+ } else {
24
+ return this._monthsNominativeEl[momentToFormat.month()];
25
+ }
26
+ },
27
+ monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),
28
+ weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),
29
+ weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),
30
+ weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),
31
+ meridiem : function (hours, minutes, isLower) {
32
+ if (hours > 11) {
33
+ return isLower ? 'μμ' : 'ΜΜ';
34
+ } else {
35
+ return isLower ? 'πμ' : 'ΠΜ';
36
+ }
37
+ },
38
+ isPM : function (input) {
39
+ return ((input + '').toLowerCase()[0] === 'μ');
40
+ },
41
+ meridiemParse : /[ΠΜ]\.?Μ?\.?/i,
42
+ longDateFormat : {
43
+ LT : 'h:mm A',
44
+ LTS : 'h:mm:ss A',
45
+ L : 'DD/MM/YYYY',
46
+ LL : 'D MMMM YYYY',
47
+ LLL : 'D MMMM YYYY h:mm A',
48
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
49
+ },
50
+ calendarEl : {
51
+ sameDay : '[Σήμερα {}] LT',
52
+ nextDay : '[Αύριο {}] LT',
53
+ nextWeek : 'dddd [{}] LT',
54
+ lastDay : '[Χθες {}] LT',
55
+ lastWeek : function () {
56
+ switch (this.day()) {
57
+ case 6:
58
+ return '[το προηγούμενο] dddd [{}] LT';
59
+ default:
60
+ return '[την προηγούμενη] dddd [{}] LT';
61
+ }
62
+ },
63
+ sameElse : 'L'
64
+ },
65
+ calendar : function (key, mom) {
66
+ var output = this._calendarEl[key],
67
+ hours = mom && mom.hours();
68
+ if (isFunction(output)) {
69
+ output = output.apply(mom);
70
+ }
71
+ return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));
72
+ },
73
+ relativeTime : {
74
+ future : 'σε %s',
75
+ past : '%s πριν',
76
+ s : 'λίγα δευτερόλεπτα',
77
+ m : 'ένα λεπτό',
78
+ mm : '%d λεπτά',
79
+ h : 'μία ώρα',
80
+ hh : '%d ώρες',
81
+ d : 'μία μέρα',
82
+ dd : '%d μέρες',
83
+ M : 'ένας μήνας',
84
+ MM : '%d μήνες',
85
+ y : 'ένας χρόνος',
86
+ yy : '%d χρόνια'
87
+ },
88
+ ordinalParse: /\d{1,2}η/,
89
+ ordinal: '%dη',
90
+ week : {
91
+ dow : 1, // Monday is the first day of the week.
92
+ doy : 4 // The week that contains Jan 4st is the first week of the year.
93
+ }
94
+ });
95
+
96
+ return el;
97
+
98
+ }));
bp-core/js/vendor/moment-js/locale/el.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";function b(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}var c=a.defineLocale("el",{monthsNominativeEl:"Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),monthsGenitiveEl:"Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),months:function(a,b){return/D/.test(b.substring(0,b.indexOf("MMMM")))?this._monthsGenitiveEl[a.month()]:this._monthsNominativeEl[a.month()]},monthsShort:"Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),weekdays:"Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),weekdaysShort:"Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),weekdaysMin:"Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),meridiem:function(a,b,c){return a>11?c?"μμ":"ΜΜ":c?"πμ":"ΠΜ"},isPM:function(a){return"μ"===(a+"").toLowerCase()[0]},meridiemParse:/[ΠΜ]\.?Μ?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[Σήμερα {}] LT",nextDay:"[Αύριο {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[Χθες {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[το προηγούμενο] dddd [{}] LT";default:return"[την προηγούμενη] dddd [{}] LT"}},sameElse:"L"},calendar:function(a,c){var d=this._calendarEl[a],e=c&&c.hours();return b(d)&&(d=d.apply(c)),d.replace("{}",e%12===1?"στη":"στις")},relativeTime:{future:"σε %s",past:"%s πριν",s:"λίγα δευτερόλεπτα",m:"ένα λεπτό",mm:"%d λεπτά",h:"μία ώρα",hh:"%d ώρες",d:"μία μέρα",dd:"%d μέρες",M:"ένας μήνας",MM:"%d μήνες",y:"ένας χρόνος",yy:"%d χρόνια"},ordinalParse:/\d{1,2}η/,ordinal:"%dη",week:{dow:1,doy:4}});return c});
bp-core/js/vendor/moment-js/locale/en-au.js ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : English (Australia) [en-au]
3
+ //! author : Jared Morse : https://github.com/jarcoal
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var en_au = moment.defineLocale('en-au', {
14
+ months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
15
+ monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
16
+ weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
17
+ weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
18
+ weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
19
+ longDateFormat : {
20
+ LT : 'h:mm A',
21
+ LTS : 'h:mm:ss A',
22
+ L : 'DD/MM/YYYY',
23
+ LL : 'D MMMM YYYY',
24
+ LLL : 'D MMMM YYYY h:mm A',
25
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
26
+ },
27
+ calendar : {
28
+ sameDay : '[Today at] LT',
29
+ nextDay : '[Tomorrow at] LT',
30
+ nextWeek : 'dddd [at] LT',
31
+ lastDay : '[Yesterday at] LT',
32
+ lastWeek : '[Last] dddd [at] LT',
33
+ sameElse : 'L'
34
+ },
35
+ relativeTime : {
36
+ future : 'in %s',
37
+ past : '%s ago',
38
+ s : 'a few seconds',
39
+ m : 'a minute',
40
+ mm : '%d minutes',
41
+ h : 'an hour',
42
+ hh : '%d hours',
43
+ d : 'a day',
44
+ dd : '%d days',
45
+ M : 'a month',
46
+ MM : '%d months',
47
+ y : 'a year',
48
+ yy : '%d years'
49
+ },
50
+ ordinalParse: /\d{1,2}(st|nd|rd|th)/,
51
+ ordinal : function (number) {
52
+ var b = number % 10,
53
+ output = (~~(number % 100 / 10) === 1) ? 'th' :
54
+ (b === 1) ? 'st' :
55
+ (b === 2) ? 'nd' :
56
+ (b === 3) ? 'rd' : 'th';
57
+ return number + output;
58
+ },
59
+ week : {
60
+ dow : 1, // Monday is the first day of the week.
61
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
62
+ }
63
+ });
64
+
65
+ return en_au;
66
+
67
+ }));
bp-core/js/vendor/moment-js/locale/en-au.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return b});
bp-core/js/vendor/moment-js/locale/en-ca.js ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : English (Canada) [en-ca]
3
+ //! author : Jonathan Abourbih : https://github.com/jonbca
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var en_ca = moment.defineLocale('en-ca', {
14
+ months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
15
+ monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
16
+ weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
17
+ weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
18
+ weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
19
+ longDateFormat : {
20
+ LT : 'h:mm A',
21
+ LTS : 'h:mm:ss A',
22
+ L : 'YYYY-MM-DD',
23
+ LL : 'MMMM D, YYYY',
24
+ LLL : 'MMMM D, YYYY h:mm A',
25
+ LLLL : 'dddd, MMMM D, YYYY h:mm A'
26
+ },
27
+ calendar : {
28
+ sameDay : '[Today at] LT',
29
+ nextDay : '[Tomorrow at] LT',
30
+ nextWeek : 'dddd [at] LT',
31
+ lastDay : '[Yesterday at] LT',
32
+ lastWeek : '[Last] dddd [at] LT',
33
+ sameElse : 'L'
34
+ },
35
+ relativeTime : {
36
+ future : 'in %s',
37
+ past : '%s ago',
38
+ s : 'a few seconds',
39
+ m : 'a minute',
40
+ mm : '%d minutes',
41
+ h : 'an hour',
42
+ hh : '%d hours',
43
+ d : 'a day',
44
+ dd : '%d days',
45
+ M : 'a month',
46
+ MM : '%d months',
47
+ y : 'a year',
48
+ yy : '%d years'
49
+ },
50
+ ordinalParse: /\d{1,2}(st|nd|rd|th)/,
51
+ ordinal : function (number) {
52
+ var b = number % 10,
53
+ output = (~~(number % 100 / 10) === 1) ? 'th' :
54
+ (b === 1) ? 'st' :
55
+ (b === 2) ? 'nd' :
56
+ (b === 3) ? 'rd' : 'th';
57
+ return number + output;
58
+ }
59
+ });
60
+
61
+ return en_ca;
62
+
63
+ }));
bp-core/js/vendor/moment-js/locale/en-ca.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}});return b});
bp-core/js/vendor/moment-js/locale/en-gb.js ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : English (United Kingdom) [en-gb]
3
+ //! author : Chris Gedrim : https://github.com/chrisgedrim
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var en_gb = moment.defineLocale('en-gb', {
14
+ months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
15
+ monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
16
+ weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
17
+ weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
18
+ weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
19
+ longDateFormat : {
20
+ LT : 'HH:mm',
21
+ LTS : 'HH:mm:ss',
22
+ L : 'DD/MM/YYYY',
23
+ LL : 'D MMMM YYYY',
24
+ LLL : 'D MMMM YYYY HH:mm',
25
+ LLLL : 'dddd, D MMMM YYYY HH:mm'
26
+ },
27
+ calendar : {
28
+ sameDay : '[Today at] LT',
29
+ nextDay : '[Tomorrow at] LT',
30
+ nextWeek : 'dddd [at] LT',
31
+ lastDay : '[Yesterday at] LT',
32
+ lastWeek : '[Last] dddd [at] LT',
33
+ sameElse : 'L'
34
+ },
35
+ relativeTime : {
36
+ future : 'in %s',
37
+ past : '%s ago',
38
+ s : 'a few seconds',
39
+ m : 'a minute',
40
+ mm : '%d minutes',
41
+ h : 'an hour',
42
+ hh : '%d hours',
43
+ d : 'a day',
44
+ dd : '%d days',
45
+ M : 'a month',
46
+ MM : '%d months',
47
+ y : 'a year',
48
+ yy : '%d years'
49
+ },
50
+ ordinalParse: /\d{1,2}(st|nd|rd|th)/,
51
+ ordinal : function (number) {
52
+ var b = number % 10,
53
+ output = (~~(number % 100 / 10) === 1) ? 'th' :
54
+ (b === 1) ? 'st' :
55
+ (b === 2) ? 'nd' :
56
+ (b === 3) ? 'rd' : 'th';
57
+ return number + output;
58
+ },
59
+ week : {
60
+ dow : 1, // Monday is the first day of the week.
61
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
62
+ }
63
+ });
64
+
65
+ return en_gb;
66
+
67
+ }));
bp-core/js/vendor/moment-js/locale/en-gb.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return b});
bp-core/js/vendor/moment-js/locale/en-ie.js ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : English (Ireland) [en-ie]
3
+ //! author : Chris Cartlidge : https://github.com/chriscartlidge
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var en_ie = moment.defineLocale('en-ie', {
14
+ months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
15
+ monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
16
+ weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
17
+ weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
18
+ weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
19
+ longDateFormat : {
20
+ LT : 'HH:mm',
21
+ LTS : 'HH:mm:ss',
22
+ L : 'DD-MM-YYYY',
23
+ LL : 'D MMMM YYYY',
24
+ LLL : 'D MMMM YYYY HH:mm',
25
+ LLLL : 'dddd D MMMM YYYY HH:mm'
26
+ },
27
+ calendar : {
28
+ sameDay : '[Today at] LT',
29
+ nextDay : '[Tomorrow at] LT',
30
+ nextWeek : 'dddd [at] LT',
31
+ lastDay : '[Yesterday at] LT',
32
+ lastWeek : '[Last] dddd [at] LT',
33
+ sameElse : 'L'
34
+ },
35
+ relativeTime : {
36
+ future : 'in %s',
37
+ past : '%s ago',
38
+ s : 'a few seconds',
39
+ m : 'a minute',
40
+ mm : '%d minutes',
41
+ h : 'an hour',
42
+ hh : '%d hours',
43
+ d : 'a day',
44
+ dd : '%d days',
45
+ M : 'a month',
46
+ MM : '%d months',
47
+ y : 'a year',
48
+ yy : '%d years'
49
+ },
50
+ ordinalParse: /\d{1,2}(st|nd|rd|th)/,
51
+ ordinal : function (number) {
52
+ var b = number % 10,
53
+ output = (~~(number % 100 / 10) === 1) ? 'th' :
54
+ (b === 1) ? 'st' :
55
+ (b === 2) ? 'nd' :
56
+ (b === 3) ? 'rd' : 'th';
57
+ return number + output;
58
+ },
59
+ week : {
60
+ dow : 1, // Monday is the first day of the week.
61
+ doy : 4 // The week that contains Jan 4th is the first week of the year.
62
+ }
63
+ });
64
+
65
+ return en_ie;
66
+
67
+ }));
bp-core/js/vendor/moment-js/locale/en-ie.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(a,b){"object"==typeof exports&&"undefined"!=typeof module&&"function"==typeof require?b(require("../moment")):"function"==typeof define&&define.amd?define(["../moment"],b):b(a.moment)}(this,function(a){"use strict";var b=a.defineLocale("en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},ordinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(a){var b=a%10,c=1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c},week:{dow:1,doy:4}});return b});
bp-core/js/vendor/moment-js/locale/en-nz.js ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! moment.js locale configuration
2
+ //! locale : English (New Zealand) [en-nz]
3
+ //! author : Luke McGregor : https://github.com/lukemcgregor
4
+
5
+ ;(function (global, factory) {
6
+ typeof exports === 'object' && typeof module !== 'undefined'
7
+ && typeof require === 'function' ? factory(require('../moment')) :
8
+ typeof define === 'function' && define.amd ? define(['../moment'], factory) :
9
+ factory(global.moment)
10
+ }(this, function (moment) { 'use strict';
11
+
12
+
13
+ var en_nz = moment.defineLocale('en-nz', {
14
+ months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),
15
+ monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),
16
+ weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),
17
+ weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),
18
+ weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),
19
+ longDateFormat : {
20
+ LT : 'h:mm A',
21
+ LTS : 'h:mm:ss A',
22
+ L : 'DD/MM/YYYY',
23
+ LL : 'D MMMM YYYY',
24
+ LLL : 'D MMMM YYYY h:mm A',
25
+ LLLL : 'dddd, D MMMM YYYY h:mm A'
26
+