BuddyPress - Version 6.0.0-beta1

Version Description

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

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

= 5.1.0 = See: https://codex.buddypress.org/releases/version-5-1-0/

= 5.0.0 = See: https://codex.buddypress.org/releases/version-5-0-0/

= 4.4.0 = See: https://codex.buddypress.org/releases/version-4-4-0/

= 4.3.0 = See: https://codex.buddypress.org/releases/version-4-3-0/

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

= 4.1.0 = See: https://codex.buddypress.org/releases/version-4-1-0/

= 4.0.0 = See: https://codex.buddypress.org/releases/version-4-0-0/

Download this release

Release Info

Developer imath
Plugin Icon 128x128 BuddyPress
Version 6.0.0-beta1
Comparing to
See all releases

Code changes from version 5.1.2 to 6.0.0-beta1

Files changed (221) hide show
  1. bp-activity/actions/feeds.php +17 -13
  2. bp-activity/admin/js/admin.js +20 -20
  3. bp-activity/bp-activity-admin.php +49 -14
  4. bp-activity/bp-activity-adminbar.php +2 -2
  5. bp-activity/bp-activity-akismet.php +1 -1
  6. bp-activity/bp-activity-embeds.php +7 -6
  7. bp-activity/bp-activity-filters.php +1 -1
  8. bp-activity/bp-activity-functions.php +74 -47
  9. bp-activity/bp-activity-notifications.php +26 -9
  10. bp-activity/bp-activity-template.php +23 -3
  11. bp-activity/classes/class-bp-activity-activity.php +32 -3
  12. bp-activity/classes/class-bp-activity-component.php +6 -2
  13. bp-activity/classes/class-bp-activity-list-table.php +79 -28
  14. bp-activity/classes/class-bp-akismet.php +35 -5
  15. bp-activity/classes/class-bp-rest-activity-endpoint.php +25 -2
  16. bp-activity/js/mentions.js +9 -9
  17. bp-activity/screens/permalink.php +2 -2
  18. bp-blogs/bp-blogs-activity.php +58 -31
  19. bp-blogs/bp-blogs-cache.php +1 -1
  20. bp-blogs/bp-blogs-functions.php +61 -46
  21. bp-blogs/bp-blogs-template.php +89 -26
  22. bp-blogs/classes/class-bp-blogs-blog.php +1 -1
  23. bp-blogs/classes/class-bp-blogs-component.php +28 -1
  24. bp-blogs/classes/class-bp-rest-attachments-blog-avatar-endpoint.php +300 -0
  25. bp-blogs/classes/class-bp-rest-blogs-endpoint.php +537 -0
  26. bp-blogs/screens/create.php +2 -4
  27. bp-core/admin/bp-core-admin-actions.php +1 -1
  28. bp-core/admin/bp-core-admin-components.php +54 -8
  29. bp-core/admin/bp-core-admin-functions.php +158 -103
  30. bp-core/admin/bp-core-admin-settings.php +28 -20
  31. bp-core/admin/bp-core-admin-slugs.php +17 -4
  32. bp-core/admin/bp-core-admin-tools.php +12 -2
  33. bp-core/admin/css/common-rtl.css +5 -0
  34. bp-core/admin/css/common-rtl.min.css +1 -1
  35. bp-core/admin/css/common.css +5 -0
  36. bp-core/admin/css/common.min.css +1 -1
  37. bp-core/bp-core-actions.php +1 -0
  38. bp-core/bp-core-admin.php +1 -0
  39. bp-core/bp-core-adminbar.php +1 -1
  40. bp-core/bp-core-attachments.php +114 -61
  41. bp-core/bp-core-avatars.php +18 -20
  42. bp-core/bp-core-blocks.php +81 -0
  43. bp-core/bp-core-cache.php +3 -3
  44. bp-core/bp-core-catchuri.php +1 -1
  45. bp-core/bp-core-cssjs.php +2 -2
  46. bp-core/bp-core-dependency.php +15 -1
  47. bp-core/bp-core-filters.php +18 -2
  48. bp-core/bp-core-functions.php +38 -37
  49. bp-core/bp-core-template-loader.php +2 -2
  50. bp-core/bp-core-template.php +41 -10
  51. bp-core/bp-core-theme-compatibility.php +4 -4
  52. bp-core/bp-core-wpabstraction.php +165 -0
  53. bp-core/classes/class-bp-admin.php +31 -17
  54. bp-core/classes/class-bp-attachment-avatar.php +7 -4
  55. bp-core/classes/class-bp-attachment-cover-image.php +7 -4
  56. bp-core/classes/class-bp-attachment.php +12 -2
  57. bp-core/classes/class-bp-block.php +197 -0
  58. bp-core/classes/class-bp-component.php +43 -3
  59. bp-core/classes/class-bp-core-nav.php +10 -10
  60. bp-core/classes/class-bp-core-user.php +45 -5
  61. bp-core/classes/class-bp-invitation.php +40 -40
  62. bp-core/classes/class-bp-media-extractor.php +8 -3
  63. bp-core/classes/class-bp-phpmailer.php +1 -1
  64. bp-core/classes/class-bp-recursive-query.php +3 -3
  65. bp-core/classes/class-bp-rest-attachments-group-avatar-endpoint.php +4 -489
  66. bp-core/classes/class-bp-rest-attachments-member-avatar-endpoint.php +4 -505
  67. bp-core/classes/class-bp-user-query.php +2 -2
  68. bp-core/classes/class-bp-walker-nav-menu.php +17 -10
  69. bp-core/classes/trait-attachments.php +165 -25
  70. bp-core/compat/php53/class-bp-compat-walker-nav-menu.php +0 -32
  71. bp-core/compat/php56/class-bp-compat-walker-nav-menu.php +0 -31
  72. bp-core/deprecated/1.2.php +12 -12
  73. bp-core/deprecated/1.5.php +18 -8
  74. bp-core/deprecated/1.6.php +8 -8
  75. bp-core/deprecated/1.7.php +2 -2
  76. bp-core/deprecated/1.9.php +22 -22
  77. bp-core/deprecated/2.0.php +1 -1
  78. bp-core/deprecated/2.1.php +40 -15
  79. bp-core/deprecated/2.2.php +3 -3
  80. bp-core/deprecated/2.5.php +2 -2
  81. bp-core/deprecated/2.8.php +11 -1
  82. bp-core/deprecated/3.0.php +10 -2
  83. bp-core/deprecated/6.0.php +159 -0
  84. bp-core/images/Jcrop.gif +0 -0
  85. bp-core/images/admin-menu-arrow.gif +0 -0
  86. bp-core/images/mystery-man-50.jpg +0 -0
  87. bp-core/images/mystery-man.jpg +0 -0
  88. bp-core/js/avatar.js +61 -61
  89. bp-core/js/avatar.min.js +1 -1
  90. bp-core/js/block-components.js +23 -0
  91. bp-core/js/bp-api-request.js +2 -2
  92. bp-core/js/bp-plupload.js +23 -23
  93. bp-core/js/cover-image.js +26 -26
  94. bp-core/js/vendor/jquery-cookie.js +5 -5
  95. bp-core/js/vendor/jquery-scroll-to.js +20 -20
  96. bp-core/js/vendor/jquery.atwho.js +1 -1
  97. bp-core/js/vendor/jquery.caret.js +1 -1
  98. bp-core/js/vendor/moment-js/moment.js +218 -218
  99. bp-core/js/webcam.js +24 -24
  100. bp-friends/bp-friends-activity.php +3 -1
  101. bp-friends/bp-friends-functions.php +16 -1
  102. bp-friends/bp-friends-notifications.php +11 -7
  103. bp-friends/bp-friends-template.php +40 -19
  104. bp-friends/classes/class-bp-friends-component.php +17 -1
  105. bp-friends/classes/class-bp-rest-friends-endpoint.php +924 -0
  106. bp-groups/actions/feed.php +6 -3
  107. bp-groups/bp-groups-activity.php +13 -2
  108. bp-groups/bp-groups-admin.php +7 -1
  109. bp-groups/bp-groups-adminbar.php +4 -2
  110. bp-groups/bp-groups-blocks.php +203 -0
  111. bp-groups/bp-groups-cssjs.php +3 -0
  112. bp-groups/bp-groups-functions.php +34 -8
  113. bp-groups/bp-groups-notifications.php +20 -5
  114. bp-groups/bp-groups-template.php +127 -91
  115. bp-groups/bp-groups-widgets.php +12 -2
  116. bp-groups/classes/class-bp-groups-component.php +77 -4
  117. bp-groups/classes/class-bp-groups-group-members-template.php +1 -0
  118. bp-groups/classes/class-bp-groups-invite-template.php +45 -7
  119. bp-groups/classes/class-bp-groups-list-table.php +78 -8
  120. bp-groups/classes/class-bp-groups-membership-requests-template.php +1 -0
  121. bp-groups/classes/class-bp-groups-widget.php +1 -0
  122. bp-groups/classes/class-bp-rest-attachments-group-avatar-endpoint.php +499 -0
  123. bp-groups/classes/class-bp-rest-attachments-group-cover-endpoint.php +432 -0
  124. bp-groups/classes/class-bp-rest-group-invites-endpoint.php +2 -4
  125. bp-groups/classes/class-bp-rest-group-membership-endpoint.php +25 -35
  126. bp-groups/classes/class-bp-rest-groups-endpoint.php +50 -7
  127. bp-groups/css/blocks/group-rtl.css +118 -0
  128. bp-groups/css/blocks/group-rtl.min.css +1 -0
  129. bp-groups/css/blocks/group.css +118 -0
  130. bp-groups/css/blocks/group.min.css +1 -0
  131. bp-groups/js/blocks/group.js +3 -0
  132. bp-groups/js/manage-members.js +1 -1
  133. bp-groups/js/manage-members.min.js +1 -1
  134. bp-groups/screens/user/invites.php +4 -2
  135. bp-loader.php +3 -3
  136. {bp-xprofile → bp-members}/actions/delete-avatar.php +6 -7
  137. bp-members/admin/css/admin-rtl.css +22 -14
  138. bp-members/admin/css/admin-rtl.min.css +1 -1
  139. bp-members/admin/css/admin.css +22 -14
  140. bp-members/admin/css/admin.min.css +1 -1
  141. bp-members/bp-members-activity.php +3 -1
  142. bp-members/bp-members-adminbar.php +9 -9
  143. bp-members/bp-members-blocks.php +194 -0
  144. bp-members/bp-members-functions.php +132 -5
  145. bp-members/bp-members-template.php +39 -1
  146. bp-members/classes/class-bp-members-admin.php +165 -9
  147. bp-members/classes/class-bp-members-component.php +264 -3
  148. bp-members/classes/class-bp-members-list-table.php +1 -0
  149. bp-members/classes/class-bp-members-ms-list-table.php +1 -0
  150. bp-members/classes/class-bp-rest-attachments-member-avatar-endpoint.php +515 -0
  151. bp-members/classes/class-bp-rest-attachments-member-cover-endpoint.php +430 -0
  152. bp-members/classes/class-bp-rest-members-endpoint.php +65 -18
  153. bp-members/classes/class-bp-rest-signup-endpoint.php +818 -0
  154. bp-members/css/blocks/member-rtl.css +110 -0
  155. bp-members/css/blocks/member-rtl.min.css +1 -0
  156. bp-members/css/blocks/member.css +110 -0
  157. bp-members/css/blocks/member.min.css +1 -0
  158. bp-members/js/blocks/member.js +3 -0
  159. {bp-xprofile → bp-members}/screens/change-avatar.php +27 -21
  160. bp-members/screens/change-cover-image.php +42 -0
  161. bp-members/screens/profile.php +1 -1
  162. bp-messages/actions/bulk-manage-star.php +3 -1
  163. bp-messages/bp-messages-functions.php +1 -0
  164. bp-messages/bp-messages-notifications.php +5 -1
  165. bp-messages/bp-messages-template.php +11 -1
  166. bp-messages/classes/class-bp-messages-box-template.php +2 -2
  167. bp-messages/classes/class-bp-messages-notices-list-table.php +5 -4
  168. bp-messages/classes/class-bp-messages-thread.php +1 -0
  169. bp-messages/classes/class-bp-rest-messages-endpoint.php +110 -88
  170. bp-messages/screens/view.php +4 -2
  171. bp-notifications/bp-notifications-adminbar.php +3 -3
  172. bp-notifications/bp-notifications-cache.php +1 -1
  173. bp-notifications/bp-notifications-functions.php +19 -3
  174. bp-notifications/bp-notifications-template.php +1 -0
  175. bp-settings/actions/delete-account.php +9 -2
  176. bp-settings/actions/general.php +1 -1
  177. bp-settings/bp-settings-template.php +18 -10
  178. bp-templates/bp-legacy/buddypress-functions.php +3 -0
  179. bp-templates/bp-legacy/buddypress/activity/comment.php +1 -1
  180. bp-templates/bp-legacy/buddypress/activity/entry.php +6 -1
  181. bp-templates/bp-legacy/buddypress/activity/index.php +41 -5
  182. bp-templates/bp-legacy/buddypress/activity/post-form.php +11 -5
  183. bp-templates/bp-legacy/buddypress/assets/emails/single-bp-email.php +3 -3
  184. bp-templates/bp-legacy/buddypress/blogs/index.php +14 -2
  185. bp-templates/bp-legacy/buddypress/groups/index.php +16 -2
  186. bp-templates/bp-legacy/buddypress/groups/single/request-membership.php +1 -1
  187. bp-templates/bp-legacy/buddypress/members/activate.php +6 -1
  188. bp-templates/bp-legacy/buddypress/members/register.php +1 -0
  189. bp-templates/bp-legacy/buddypress/members/single/groups/invites.php +10 -1
  190. bp-templates/bp-legacy/buddypress/members/single/messages/single.php +8 -2
  191. bp-templates/bp-legacy/buddypress/members/single/profile/edit.php +6 -1
  192. bp-templates/bp-legacy/buddypress/members/single/settings/data.php +12 -2
  193. bp-templates/bp-legacy/css/twentyfifteen.scss +0 -6
  194. bp-templates/bp-legacy/css/twentyseventeen-rtl.css +1 -1
  195. bp-templates/bp-legacy/css/twentyseventeen-rtl.min.css +1 -1
  196. bp-templates/bp-legacy/css/twentyseventeen.css +1 -1
  197. bp-templates/bp-legacy/css/twentyseventeen.min.css +1 -1
  198. bp-templates/bp-legacy/css/twentyseventeen.scss +4 -4
  199. bp-templates/bp-nouveau/buddypress-functions.php +19 -17
  200. bp-templates/bp-nouveau/buddypress/activity/index.php +2 -1
  201. bp-templates/bp-nouveau/buddypress/assets/emails/single-bp-email.php +1 -1
  202. bp-templates/bp-nouveau/buddypress/blogs/index.php +2 -1
  203. bp-templates/bp-nouveau/buddypress/common/js-templates/invites/index.php +2 -2
  204. bp-templates/bp-nouveau/buddypress/groups/groups-loop.php +1 -1
  205. bp-templates/bp-nouveau/buddypress/groups/index.php +2 -1
  206. bp-templates/bp-nouveau/buddypress/groups/single/cover-image-header.php +1 -1
  207. bp-templates/bp-nouveau/buddypress/groups/single/default-front.php +1 -0
  208. bp-templates/bp-nouveau/buddypress/groups/single/group-header.php +1 -1
  209. bp-templates/bp-nouveau/buddypress/groups/single/request-membership.php +1 -1
  210. bp-templates/bp-nouveau/buddypress/members/index.php +4 -1
  211. bp-templates/bp-nouveau/buddypress/members/members-loop.php +13 -11
  212. bp-templates/bp-nouveau/buddypress/members/single/default-front.php +1 -0
  213. bp-templates/bp-nouveau/buddypress/members/single/settings/general.php +6 -1
  214. bp-templates/bp-nouveau/common-styles/_bp_activity_entries.scss +1 -1
  215. bp-templates/bp-nouveau/common-styles/_bp_filters.scss +1 -1
  216. bp-templates/bp-nouveau/common-styles/_bp_generic_and_typography.scss +1 -4
  217. bp-templates/bp-nouveau/common-styles/_bp_layouts.scss +2 -3
  218. bp-templates/bp-nouveau/common-styles/_bp_members_loop.scss +8 -1
  219. bp-templates/bp-nouveau/common-styles/_bp_navigation.scss +0 -4
  220. bp-templates/bp-nouveau/css/buddypress-rtl.css +8 -6
  221. bp-templates/bp-nouveau/css/buddypress-rtl.min.css +0 -1
bp-activity/actions/feeds.php CHANGED
@@ -24,9 +24,8 @@ function bp_activity_action_sitewide_feed() {
24
  buddypress()->activity->feed = new BP_Activity_Feed( array(
25
  'id' => 'sitewide',
26
 
27
- /* translators: Sitewide activity RSS title - "[Site Name] | Site Wide Activity" */
28
  'title' => sprintf( __( '%s | Site-Wide Activity', 'buddypress' ), bp_get_site_name() ),
29
-
30
  'link' => bp_get_activity_directory_permalink(),
31
  'description' => __( 'Activity feed for the entire site.', 'buddypress' ),
32
  'activity_args' => 'display_comments=threaded'
@@ -50,10 +49,11 @@ function bp_activity_action_personal_feed() {
50
  buddypress()->activity->feed = new BP_Activity_Feed( array(
51
  'id' => 'personal',
52
 
53
- /* translators: Personal activity RSS title - "[Site Name] | [User Display Name] | Activity" */
54
- 'title' => sprintf( __( '%1$s | %2$s | Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
55
-
56
  'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() ),
 
 
57
  'description' => sprintf( __( 'Activity feed for %s.', 'buddypress' ), bp_get_displayed_user_fullname() ),
58
  'activity_args' => 'user_id=' . bp_displayed_user_id()
59
  ) );
@@ -76,10 +76,11 @@ function bp_activity_action_friends_feed() {
76
  buddypress()->activity->feed = new BP_Activity_Feed( array(
77
  'id' => 'friends',
78
 
79
- /* translators: Friends activity RSS title - "[Site Name] | [User Display Name] | Friends Activity" */
80
  'title' => sprintf( __( '%1$s | %2$s | Friends Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
81
-
82
  'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() ),
 
 
83
  'description' => sprintf( __( "Activity feed for %s's friends.", 'buddypress' ), bp_get_displayed_user_fullname() ),
84
  'activity_args' => 'scope=friends'
85
  ) );
@@ -106,10 +107,11 @@ function bp_activity_action_my_groups_feed() {
106
  buddypress()->activity->feed = new BP_Activity_Feed( array(
107
  'id' => 'mygroups',
108
 
109
- /* translators: Member groups activity RSS title - "[Site Name] | [User Display Name] | Groups Activity" */
110
  'title' => sprintf( __( '%1$s | %2$s | Group Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
111
-
112
  'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() ),
 
 
113
  'description' => sprintf( __( "Public group activity feed of which %s is a member.", 'buddypress' ), bp_get_displayed_user_fullname() ),
114
  'activity_args' => array(
115
  'object' => buddypress()->groups->id,
@@ -140,10 +142,11 @@ function bp_activity_action_mentions_feed() {
140
  buddypress()->activity->feed = new BP_Activity_Feed( array(
141
  'id' => 'mentions',
142
 
143
- /* translators: User mentions activity RSS title - "[Site Name] | [User Display Name] | Mentions" */
144
  'title' => sprintf( __( '%1$s | %2$s | Mentions', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
145
-
146
  'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/mentions/',
 
 
147
  'description' => sprintf( __( "Activity feed mentioning %s.", 'buddypress' ), bp_get_displayed_user_fullname() ),
148
  'activity_args' => array(
149
  'search_terms' => '@' . bp_core_get_username( bp_displayed_user_id() )
@@ -172,10 +175,11 @@ function bp_activity_action_favorites_feed() {
172
  buddypress()->activity->feed = new BP_Activity_Feed( array(
173
  'id' => 'favorites',
174
 
175
- /* translators: User activity favorites RSS title - "[Site Name] | [User Display Name] | Favorites" */
176
  'title' => sprintf( __( '%1$s | %2$s | Favorites', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
177
-
178
  'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/',
 
 
179
  'description' => sprintf( __( "Activity feed of %s's favorites.", 'buddypress' ), bp_get_displayed_user_fullname() ),
180
  'activity_args' => 'include=' . $fav_ids
181
  ) );
24
  buddypress()->activity->feed = new BP_Activity_Feed( array(
25
  'id' => 'sitewide',
26
 
27
+ /* translators: %s Site Name */
28
  'title' => sprintf( __( '%s | Site-Wide Activity', 'buddypress' ), bp_get_site_name() ),
 
29
  'link' => bp_get_activity_directory_permalink(),
30
  'description' => __( 'Activity feed for the entire site.', 'buddypress' ),
31
  'activity_args' => 'display_comments=threaded'
49
  buddypress()->activity->feed = new BP_Activity_Feed( array(
50
  'id' => 'personal',
51
 
52
+ /* translators: 1: Site Name. 2: User Display Name. */
53
+ 'title' => sprintf( _x( '%1$s | %2$s | Activity', 'Personal activity feed title', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
 
54
  'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() ),
55
+
56
+ /* translators: %s: User Display Name */
57
  'description' => sprintf( __( 'Activity feed for %s.', 'buddypress' ), bp_get_displayed_user_fullname() ),
58
  'activity_args' => 'user_id=' . bp_displayed_user_id()
59
  ) );
76
  buddypress()->activity->feed = new BP_Activity_Feed( array(
77
  'id' => 'friends',
78
 
79
+ /* translators: 1: Site Name 2: User Display Name */
80
  'title' => sprintf( __( '%1$s | %2$s | Friends Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
 
81
  'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() ),
82
+
83
+ /* translators: %s: User Display Name */
84
  'description' => sprintf( __( "Activity feed for %s's friends.", 'buddypress' ), bp_get_displayed_user_fullname() ),
85
  'activity_args' => 'scope=friends'
86
  ) );
107
  buddypress()->activity->feed = new BP_Activity_Feed( array(
108
  'id' => 'mygroups',
109
 
110
+ /* translators: 1: Site Name 2: User Display Name */
111
  'title' => sprintf( __( '%1$s | %2$s | Group Activity', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
 
112
  'link' => trailingslashit( bp_displayed_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() ),
113
+
114
+ /* translators: %s: User Display Name */
115
  'description' => sprintf( __( "Public group activity feed of which %s is a member.", 'buddypress' ), bp_get_displayed_user_fullname() ),
116
  'activity_args' => array(
117
  'object' => buddypress()->groups->id,
142
  buddypress()->activity->feed = new BP_Activity_Feed( array(
143
  'id' => 'mentions',
144
 
145
+ /* translators: 1: Site Name 2: User Display Name */
146
  'title' => sprintf( __( '%1$s | %2$s | Mentions', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
 
147
  'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/mentions/',
148
+
149
+ /* translators: %s: User Display Name */
150
  'description' => sprintf( __( "Activity feed mentioning %s.", 'buddypress' ), bp_get_displayed_user_fullname() ),
151
  'activity_args' => array(
152
  'search_terms' => '@' . bp_core_get_username( bp_displayed_user_id() )
175
  buddypress()->activity->feed = new BP_Activity_Feed( array(
176
  'id' => 'favorites',
177
 
178
+ /* translators: 1: Site Name 2: User Display Name */
179
  'title' => sprintf( __( '%1$s | %2$s | Favorites', 'buddypress' ), bp_get_site_name(), bp_get_displayed_user_fullname() ),
 
180
  'link' => bp_displayed_user_domain() . bp_get_activity_slug() . '/favorites/',
181
+
182
+ /* translators: %s: User Display Name */
183
  'description' => sprintf( __( "Activity feed of %s's favorites.", 'buddypress' ), bp_get_displayed_user_fullname() ),
184
  'activity_args' => 'include=' . $fav_ids
185
  ) );
bp-activity/admin/js/admin.js CHANGED
@@ -2,7 +2,7 @@
2
  (function( $ ) {
3
 
4
  /**
5
- * Activity reply object for the activity index screen
6
  *
7
  * @since 1.6.0
8
  */
@@ -18,7 +18,7 @@ var activityReply = {
18
  $(document).on( 'click', '#bp-activities-container a.cancel', activityReply.close );
19
  $(document).on( 'click', '#bp-activities-container a.save', activityReply.send );
20
 
21
- // Close textarea on escape
22
  $(document).on( 'keyup', '#bp-activities:visible', function( e ) {
23
  if ( 27 === e.which ) {
24
  activityReply.close();
@@ -32,7 +32,7 @@ var activityReply = {
32
  * @since 1.6.0
33
  */
34
  open : function() {
35
- // Hide the container row, and move it to the new location
36
  var box = $( '#bp-activities-container' ).hide();
37
  $( this ).parents( 'tr' ).after( box );
38
 
@@ -49,13 +49,13 @@ var activityReply = {
49
  * @since 1.6.0
50
  */
51
  close : function() {
52
- // Hide the container row
53
  $('#bp-activities-container').fadeOut( '200', function () {
54
 
55
- // Empty and unfocus the text area
56
  $( '#bp-activities' ).val( '' ).blur();
57
 
58
- // Remove any error message and disable the spinner
59
  $( '#bp-replysubmit .error' ).html( '' ).hide();
60
  $( '#bp-replysubmit .waiting' ).hide();
61
  });
@@ -69,27 +69,27 @@ var activityReply = {
69
  * @since 1.6.0
70
  */
71
  send : function() {
72
- // Hide any existing error message, and show the loading spinner
73
  $( '#bp-replysubmit .error' ).hide();
74
  $( '#bp-replysubmit .waiting' ).show();
75
 
76
- // Grab the nonce
77
  var reply = {};
78
  reply['_ajax_nonce-bp-activity-admin-reply'] = $( '#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]' ).val();
79
 
80
- // Get the rest of the data
81
  reply.action = 'bp-activity-admin-reply';
82
  reply.content = $( '#bp-activities' ).val();
83
  reply.parent_id = $( '#bp-activities-container' ).prev().data( 'parent_id' );
84
  reply.root_id = $( '#bp-activities-container' ).prev().data( 'root_id' );
85
 
86
- // Make the AJAX call
87
  $.ajax({
88
  data : reply,
89
  type : 'POST',
90
  url : ajaxurl,
91
 
92
- // Callbacks
93
  error : function( r ) { activityReply.error( r ); },
94
  success : function( r ) { activityReply.show( r ); }
95
  });
@@ -98,7 +98,7 @@ var activityReply = {
98
  },
99
 
100
  /**
101
- * send() error message handler
102
  *
103
  * @since 1.6.0
104
  */
@@ -116,14 +116,14 @@ var activityReply = {
116
  },
117
 
118
  /**
119
- * send() success handler
120
  *
121
  * @since 1.6.0
122
  */
123
  show : function ( xml ) {
124
  var bg, id, response;
125
 
126
- // Handle any errors in the response
127
  if ( typeof( xml ) === 'string' ) {
128
  activityReply.error( { 'responseText': xml } );
129
  return false;
@@ -139,17 +139,17 @@ var activityReply = {
139
  // Close and reset the reply row, and add the new Activity item into the list.
140
  $('#bp-activities-container').fadeOut( '200', function () {
141
 
142
- // Empty and unfocus the text area
143
  $( '#bp-activities' ).val( '' ).blur();
144
 
145
- // Remove any error message and disable the spinner
146
  $( '#bp-replysubmit .error' ).html( '' ).hide();
147
  $( '#bp-replysubmit .waiting' ).hide();
148
 
149
- // Insert new activity item
150
  $( '#bp-activities-container' ).before( response.data );
151
 
152
- // Get background colour and animate the flash
153
  id = $( '#activity-' + response.id );
154
  bg = id.closest( '.widefat' ).css( 'backgroundColor' );
155
  id.animate( { 'backgroundColor': '#CEB' }, 300 ).animate( { 'backgroundColor': bg }, 300 );
@@ -158,10 +158,10 @@ var activityReply = {
158
  };
159
 
160
  $(document).ready( function () {
161
- // Create the Activity reply object after domready event
162
  activityReply.init();
163
 
164
- // On the edit screen, unload the close/open toggle js for the action & content metaboxes
165
  $( '#bp_activity_action h3, #bp_activity_content h3' ).unbind( 'click' );
166
 
167
  // redo the post box toggles to reset the one made by comment.js in favor
2
  (function( $ ) {
3
 
4
  /**
5
+ * Activity reply object for the activity index screen.
6
  *
7
  * @since 1.6.0
8
  */
18
  $(document).on( 'click', '#bp-activities-container a.cancel', activityReply.close );
19
  $(document).on( 'click', '#bp-activities-container a.save', activityReply.send );
20
 
21
+ // Close textarea on escape.
22
  $(document).on( 'keyup', '#bp-activities:visible', function( e ) {
23
  if ( 27 === e.which ) {
24
  activityReply.close();
32
  * @since 1.6.0
33
  */
34
  open : function() {
35
+ // Hide the container row, and move it to the new location.
36
  var box = $( '#bp-activities-container' ).hide();
37
  $( this ).parents( 'tr' ).after( box );
38
 
49
  * @since 1.6.0
50
  */
51
  close : function() {
52
+ // Hide the container row.
53
  $('#bp-activities-container').fadeOut( '200', function () {
54
 
55
+ // Empty and unfocus the text area.
56
  $( '#bp-activities' ).val( '' ).blur();
57
 
58
+ // Remove any error message and disable the spinner.
59
  $( '#bp-replysubmit .error' ).html( '' ).hide();
60
  $( '#bp-replysubmit .waiting' ).hide();
61
  });
69
  * @since 1.6.0
70
  */
71
  send : function() {
72
+ // Hide any existing error message, and show the loading spinner.
73
  $( '#bp-replysubmit .error' ).hide();
74
  $( '#bp-replysubmit .waiting' ).show();
75
 
76
+ // Grab the nonce.
77
  var reply = {};
78
  reply['_ajax_nonce-bp-activity-admin-reply'] = $( '#bp-activities-container input[name="_ajax_nonce-bp-activity-admin-reply"]' ).val();
79
 
80
+ // Get the rest of the data.
81
  reply.action = 'bp-activity-admin-reply';
82
  reply.content = $( '#bp-activities' ).val();
83
  reply.parent_id = $( '#bp-activities-container' ).prev().data( 'parent_id' );
84
  reply.root_id = $( '#bp-activities-container' ).prev().data( 'root_id' );
85
 
86
+ // Make the AJAX call.
87
  $.ajax({
88
  data : reply,
89
  type : 'POST',
90
  url : ajaxurl,
91
 
92
+ // Callbacks.
93
  error : function( r ) { activityReply.error( r ); },
94
  success : function( r ) { activityReply.show( r ); }
95
  });
98
  },
99
 
100
  /**
101
+ * send() error message handler.
102
  *
103
  * @since 1.6.0
104
  */
116
  },
117
 
118
  /**
119
+ * send() success handler.
120
  *
121
  * @since 1.6.0
122
  */
123
  show : function ( xml ) {
124
  var bg, id, response;
125
 
126
+ // Handle any errors in the response.
127
  if ( typeof( xml ) === 'string' ) {
128
  activityReply.error( { 'responseText': xml } );
129
  return false;
139
  // Close and reset the reply row, and add the new Activity item into the list.
140
  $('#bp-activities-container').fadeOut( '200', function () {
141
 
142
+ // Empty and unfocus the text area.
143
  $( '#bp-activities' ).val( '' ).blur();
144
 
145
+ // Remove any error message and disable the spinner.
146
  $( '#bp-replysubmit .error' ).html( '' ).hide();
147
  $( '#bp-replysubmit .waiting' ).hide();
148
 
149
+ // Insert new activity item.
150
  $( '#bp-activities-container' ).before( response.data );
151
 
152
+ // Get background colour and animate the flash.
153
  id = $( '#activity-' + response.id );
154
  bg = id.closest( '.widefat' ).css( 'backgroundColor' );
155
  id.animate( { 'backgroundColor': '#CEB' }, 300 ).animate( { 'backgroundColor': bg }, 300 );
158
  };
159
 
160
  $(document).ready( function () {
161
+ // Create the Activity reply object after domready event.
162
  activityReply.init();
163
 
164
+ // On the edit screen, unload the close/open toggle js for the action & content metaboxes.
165
  $( '#bp_activity_action h3, #bp_activity_content h3' ).unbind( 'click' );
166
 
167
  // redo the post box toggles to reset the one made by comment.js in favor
bp-activity/bp-activity-admin.php CHANGED
@@ -29,8 +29,8 @@ function bp_activity_add_admin_menu() {
29
 
30
  // Add our screen.
31
  $hook = add_menu_page(
32
- _x( 'Activity', 'Admin Dashbord SWA page title', 'buddypress' ),
33
- _x( 'Activity', 'Admin Dashbord SWA menu', 'buddypress' ),
34
  'bp_moderate',
35
  'bp-activity',
36
  'bp_activity_admin',
@@ -75,7 +75,7 @@ function bp_activity_admin_reply() {
75
  $parent_id = ! empty( $_REQUEST['parent_id'] ) ? (int) $_REQUEST['parent_id'] : 0;
76
  $root_id = ! empty( $_REQUEST['root_id'] ) ? (int) $_REQUEST['root_id'] : 0;
77
 
78
- // $parent_id is required
79
  if ( empty( $parent_id ) )
80
  die( '-1' );
81
 
@@ -356,7 +356,7 @@ function bp_activity_admin_load() {
356
  check_admin_referer( 'spam-activity_' . $activity_ids[0] );
357
  }
358
 
359
- // Initialise counters for how many of each type of item we perform an action on.
360
  $deleted = $spammed = $unspammed = 0;
361
 
362
  // Store any errors that occurs when updating the database items.
@@ -660,7 +660,12 @@ function bp_activity_admin_edit() {
660
  do_action_ref_array( 'bp_activity_admin_edit', array( &$activity ) ); ?>
661
 
662
  <div class="wrap">
663
- <h1><?php printf( __( 'Editing Activity (ID #%s)', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) ); ?></h1>
 
 
 
 
 
664
 
665
  <?php if ( ! empty( $activity ) ) : ?>
666
 
@@ -761,7 +766,12 @@ function bp_activity_admin_edit_metabox_status( $item ) {
761
  $datef = __( 'M j, Y @ G:i', 'buddypress' );
762
  $date = date_i18n( $datef, strtotime( $item->date_recorded ) );
763
  ?>
764
- <span id="timestamp"><?php printf( __( 'Submitted on: %s', 'buddypress' ), '<strong>' . $date . '</strong>' ); ?></span>&nbsp;<a href="#edit_timestamp" class="edit-timestamp hide-if-no-js" tabindex='4'><?php _e( 'Edit', 'buddypress' ); ?></a>
 
 
 
 
 
765
 
766
  <div id='timestampdiv' class='hide-if-js'>
767
  <?php touch_time( 1, 0, 5 ); ?>
@@ -899,7 +909,16 @@ function bp_activity_admin_edit_metabox_type( $item ) {
899
  * of the list.
900
  */
901
  if ( ! isset( $actions[ $selected ] ) ) {
902
- _doing_it_wrong( __FUNCTION__, sprintf( __( 'This activity item has a type (%s) that is not registered using bp_activity_set_action(), so no label is available.', 'buddypress' ), $selected ), '2.0.0' );
 
 
 
 
 
 
 
 
 
903
  $actions[ $selected ] = $selected;
904
  }
905
 
@@ -973,11 +992,14 @@ function bp_activity_admin_index() {
973
  // Reindex array.
974
  $errors = array_values( $errors );
975
 
976
- if ( $deleted > 0 )
 
977
  $messages[] = sprintf( _n( '%s activity item has been permanently deleted.', '%s activity items have been permanently deleted.', $deleted, 'buddypress' ), number_format_i18n( $deleted ) );
 
978
 
979
  if ( ! empty( $errors ) ) {
980
  if ( 1 == count( $errors ) ) {
 
981
  $messages[] = sprintf( __( 'An error occurred when trying to update activity ID #%s.', 'buddypress' ), number_format_i18n( $errors[0] ) );
982
 
983
  } else {
@@ -986,7 +1008,7 @@ function bp_activity_admin_index() {
986
 
987
  // Display each error as a list item.
988
  foreach ( $errors as $error ) {
989
- // Translators: This is a bulleted list of item IDs.
990
  $error_msg .= '<li>' . sprintf( __( '#%s', 'buddypress' ), number_format_i18n( $error ) ) . '</li>';
991
  }
992
 
@@ -995,14 +1017,19 @@ function bp_activity_admin_index() {
995
  }
996
  }
997
 
998
- if ( $spammed > 0 )
 
999
  $messages[] = sprintf( _n( '%s activity item has been successfully spammed.', '%s activity items have been successfully spammed.', $spammed, 'buddypress' ), number_format_i18n( $spammed ) );
 
1000
 
1001
- if ( $unspammed > 0 )
 
1002
  $messages[] = sprintf( _n( '%s activity item has been successfully unspammed.', '%s activity items have been successfully unspammed.', $unspammed, 'buddypress' ), number_format_i18n( $unspammed ) );
 
1003
 
1004
- if ( $updated > 0 )
1005
  $messages[] = __( 'The activity item has been updated successfully.', 'buddypress' );
 
1006
  }
1007
 
1008
  // Prepare the activity items for display.
@@ -1020,13 +1047,21 @@ function bp_activity_admin_index() {
1020
  <div class="wrap">
1021
  <h1>
1022
  <?php if ( !empty( $_REQUEST['aid'] ) ) : ?>
1023
- <?php printf( __( 'Activity related to ID #%s', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) ); ?>
 
 
 
1024
  <?php else : ?>
1025
  <?php _ex( 'Activity', 'Admin SWA page', 'buddypress' ); ?>
1026
  <?php endif; ?>
1027
 
1028
  <?php if ( !empty( $_REQUEST['s'] ) ) : ?>
1029
- <span class="subtitle"><?php printf( __( 'Search results for &#8220;%s&#8221;', 'buddypress' ), wp_html_excerpt( esc_html( stripslashes( $_REQUEST['s'] ) ), 50 ) ); ?></span>
 
 
 
 
 
1030
  <?php endif; ?>
1031
  </h1>
1032
 
29
 
30
  // Add our screen.
31
  $hook = add_menu_page(
32
+ _x( 'Activity', 'Admin Dashboard SWA page title', 'buddypress' ),
33
+ _x( 'Activity', 'Admin Dashboard SWA menu', 'buddypress' ),
34
  'bp_moderate',
35
  'bp-activity',
36
  'bp_activity_admin',
75
  $parent_id = ! empty( $_REQUEST['parent_id'] ) ? (int) $_REQUEST['parent_id'] : 0;
76
  $root_id = ! empty( $_REQUEST['root_id'] ) ? (int) $_REQUEST['root_id'] : 0;
77
 
78
+ // $parent_id is required.
79
  if ( empty( $parent_id ) )
80
  die( '-1' );
81
 
356
  check_admin_referer( 'spam-activity_' . $activity_ids[0] );
357
  }
358
 
359
+ // Initialize counters for how many of each type of item we perform an action on.
360
  $deleted = $spammed = $unspammed = 0;
361
 
362
  // Store any errors that occurs when updating the database items.
660
  do_action_ref_array( 'bp_activity_admin_edit', array( &$activity ) ); ?>
661
 
662
  <div class="wrap">
663
+ <h1>
664
+ <?php
665
+ /* translators: %s: the activity ID */
666
+ printf( __( 'Editing Activity (ID #%s)', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) );
667
+ ?>
668
+ </h1>
669
 
670
  <?php if ( ! empty( $activity ) ) : ?>
671
 
766
  $datef = __( 'M j, Y @ G:i', 'buddypress' );
767
  $date = date_i18n( $datef, strtotime( $item->date_recorded ) );
768
  ?>
769
+ <span id="timestamp">
770
+ <?php
771
+ /* translators: %s: the date the activity was submitted on */
772
+ printf( __( 'Submitted on: %s', 'buddypress' ), '<strong>' . $date . '</strong>' );
773
+ ?>
774
+ </span>&nbsp;<a href="#edit_timestamp" class="edit-timestamp hide-if-no-js" tabindex='4'><?php _e( 'Edit', 'buddypress' ); ?></a>
775
 
776
  <div id='timestampdiv' class='hide-if-js'>
777
  <?php touch_time( 1, 0, 5 ); ?>
909
  * of the list.
910
  */
911
  if ( ! isset( $actions[ $selected ] ) ) {
912
+ _doing_it_wrong(
913
+ __FUNCTION__,
914
+ sprintf(
915
+ /* translators: %s: the name of the activity type */
916
+ __( 'This activity item has a type (%s) that is not registered using bp_activity_set_action(), so no label is available.', 'buddypress' ),
917
+ $selected
918
+ ),
919
+ '2.0.0'
920
+ );
921
+
922
  $actions[ $selected ] = $selected;
923
  }
924
 
992
  // Reindex array.
993
  $errors = array_values( $errors );
994
 
995
+ if ( $deleted > 0 ) {
996
+ /* translators: %s: the number of permanently deleted activities */
997
  $messages[] = sprintf( _n( '%s activity item has been permanently deleted.', '%s activity items have been permanently deleted.', $deleted, 'buddypress' ), number_format_i18n( $deleted ) );
998
+ }
999
 
1000
  if ( ! empty( $errors ) ) {
1001
  if ( 1 == count( $errors ) ) {
1002
+ /* translators: %s: the ID of the activity which errored during an update */
1003
  $messages[] = sprintf( __( 'An error occurred when trying to update activity ID #%s.', 'buddypress' ), number_format_i18n( $errors[0] ) );
1004
 
1005
  } else {
1008
 
1009
  // Display each error as a list item.
1010
  foreach ( $errors as $error ) {
1011
+ /* Translators: %s: the activity ID */
1012
  $error_msg .= '<li>' . sprintf( __( '#%s', 'buddypress' ), number_format_i18n( $error ) ) . '</li>';
1013
  }
1014
 
1017
  }
1018
  }
1019
 
1020
+ if ( $spammed > 0 ) {
1021
+ /* translators: %s: the number of activities successfully marked as spam */
1022
  $messages[] = sprintf( _n( '%s activity item has been successfully spammed.', '%s activity items have been successfully spammed.', $spammed, 'buddypress' ), number_format_i18n( $spammed ) );
1023
+ }
1024
 
1025
+ if ( $unspammed > 0 ) {
1026
+ /* translators: %s: the number of activities successfully marked as ham */
1027
  $messages[] = sprintf( _n( '%s activity item has been successfully unspammed.', '%s activity items have been successfully unspammed.', $unspammed, 'buddypress' ), number_format_i18n( $unspammed ) );
1028
+ }
1029
 
1030
+ if ( $updated > 0 ) {
1031
  $messages[] = __( 'The activity item has been updated successfully.', 'buddypress' );
1032
+ }
1033
  }
1034
 
1035
  // Prepare the activity items for display.
1047
  <div class="wrap">
1048
  <h1>
1049
  <?php if ( !empty( $_REQUEST['aid'] ) ) : ?>
1050
+ <?php
1051
+ /* translators: %s: the activity ID */
1052
+ printf( __( 'Activity related to ID #%s', 'buddypress' ), number_format_i18n( (int) $_REQUEST['aid'] ) );
1053
+ ?>
1054
  <?php else : ?>
1055
  <?php _ex( 'Activity', 'Admin SWA page', 'buddypress' ); ?>
1056
  <?php endif; ?>
1057
 
1058
  <?php if ( !empty( $_REQUEST['s'] ) ) : ?>
1059
+ <span class="subtitle">
1060
+ <?php
1061
+ /* translators: %s: the activity search terms */
1062
+ printf( __( 'Search results for &#8220;%s&#8221;', 'buddypress' ), wp_html_excerpt( esc_html( stripslashes( $_REQUEST['s'] ) ), 50 ) );
1063
+ ?>
1064
+ </span>
1065
  <?php endif; ?>
1066
  </h1>
1067
 
bp-activity/bp-activity-adminbar.php CHANGED
@@ -26,7 +26,7 @@ function bp_activity_admin_menu() {
26
  return;
27
  }
28
 
29
- // Only show this menu to super admins
30
  if ( ! bp_current_user_can( 'bp_moderate' ) ) {
31
  return;
32
  }
@@ -38,7 +38,7 @@ function bp_activity_admin_menu() {
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 ),
26
  return;
27
  }
28
 
29
+ // Only show this menu to super admins.
30
  if ( ! bp_current_user_can( 'bp_moderate' ) ) {
31
  return;
32
  }
38
  ), bp_get_admin_url( 'admin.php' ) );
39
 
40
  // Add the top-level Edit Activity button.
41
+ $wp_admin_bar->add_node( array(
42
  'id' => 'activity-admin',
43
  'title' => __( 'Edit Activity', 'buddypress' ),
44
  'href' => esc_url( $activity_edit_link ),
bp-activity/bp-activity-akismet.php CHANGED
@@ -60,7 +60,7 @@ function bp_activity_akismet_delete_old_metadata() {
60
  // Enforce a minimum of 1 day.
61
  $interval = max( 1, absint( $interval ) );
62
 
63
- // _bp_akismet_submission meta values are large, so expire them after $interval days regardless of the activity status
64
  $sql = $wpdb->prepare( "SELECT a.id FROM {$bp->activity->table_name} a LEFT JOIN {$bp->activity->table_name_meta} m ON a.id = m.activity_id WHERE m.meta_key = %s AND DATE_SUB(%s, INTERVAL {$interval} DAY) > a.date_recorded LIMIT 10000", '_bp_akismet_submission', current_time( 'mysql', 1 ) );
65
  $activity_ids = $wpdb->get_col( $sql );
66
 
60
  // Enforce a minimum of 1 day.
61
  $interval = max( 1, absint( $interval ) );
62
 
63
+ // _bp_akismet_submission meta values are large, so expire them after $interval days regardless of the activity status.
64
  $sql = $wpdb->prepare( "SELECT a.id FROM {$bp->activity->table_name} a LEFT JOIN {$bp->activity->table_name_meta} m ON a.id = m.activity_id WHERE m.meta_key = %s AND DATE_SUB(%s, INTERVAL {$interval} DAY) > a.date_recorded LIMIT 10000", '_bp_akismet_submission', current_time( 'mysql', 1 ) );
65
  $activity_ids = $wpdb->get_col( $sql );
66
 
bp-activity/bp-activity-embeds.php CHANGED
@@ -100,7 +100,7 @@ function bp_activity_embed_has_activity( $activity_id = 0 ) {
100
  $activity = (array) $activities_template->activities;
101
  $activity = reset( $activity );
102
 
103
- // No need to requery if we already got the embed activity
104
  if ( (int) $activity_id === $activity->id ) {
105
  return $activities_template->has_activities();
106
  }
@@ -234,10 +234,10 @@ function bp_activity_embed_media() {
234
  $thumbnail = $oembed->thumbnail_url;
235
 
236
  /* Non-oEmbed standard attributes */
237
- // Mixcloud
238
  } elseif ( isset( $oembed->image ) ) {
239
  $thumbnail = $oembed->image;
240
- // ReverbNation
241
  } elseif ( isset( $oembed->{'thumbnail-url'} ) ) {
242
  $thumbnail = $oembed->{'thumbnail-url'};
243
  }
@@ -261,7 +261,7 @@ EOD;
261
  $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 );
262
  }
263
 
264
- // Thumb width
265
  $thumb_width = isset( $oembed->thumbnail_width ) && 'photo' !== $oembed->type && (int) $oembed->thumbnail_width < 550 ? (int) $oembed->thumbnail_width : $width;
266
 
267
  $float_width = 350;
@@ -274,17 +274,18 @@ EOD;
274
  $caption .= sprintf( '<p class="caption-title"><strong>%s</strong></p>', apply_filters( 'single_post_title', $oembed->title ) );
275
  }
276
 
277
- // Show description (non-oEmbed standard)
278
  if ( isset( $oembed->description ) ) {
279
  $caption .= sprintf( '<div class="caption-description">%s</div>', apply_filters( 'bp_activity_get_embed_excerpt', $oembed->description ) );
280
  }
281
 
282
  // Show author info.
283
  if ( isset( $oembed->provider_name ) && isset( $oembed->author_name ) ) {
284
- /* translators: By [oEmbed author] on [oEmbed provider]. eg. By BuddyPress on YouTube. */
285
  $anchor_text = sprintf( __( 'By %1$s on %2$s', 'buddypress' ), $oembed->author_name, $oembed->provider_name );
286
 
287
  } elseif ( isset( $oembed->provider_name ) ) {
 
288
  $anchor_text = sprintf( __( 'View on %s', 'buddypress' ), $oembed->provider_name );
289
  }
290
 
100
  $activity = (array) $activities_template->activities;
101
  $activity = reset( $activity );
102
 
103
+ // No need to requery if we already got the embed activity.
104
  if ( (int) $activity_id === $activity->id ) {
105
  return $activities_template->has_activities();
106
  }
234
  $thumbnail = $oembed->thumbnail_url;
235
 
236
  /* Non-oEmbed standard attributes */
237
+ // Mixcloud.
238
  } elseif ( isset( $oembed->image ) ) {
239
  $thumbnail = $oembed->image;
240
+ // ReverbNation.
241
  } elseif ( isset( $oembed->{'thumbnail-url'} ) ) {
242
  $thumbnail = $oembed->{'thumbnail-url'};
243
  }
261
  $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 );
262
  }
263
 
264
+ // Thumb width.
265
  $thumb_width = isset( $oembed->thumbnail_width ) && 'photo' !== $oembed->type && (int) $oembed->thumbnail_width < 550 ? (int) $oembed->thumbnail_width : $width;
266
 
267
  $float_width = 350;
274
  $caption .= sprintf( '<p class="caption-title"><strong>%s</strong></p>', apply_filters( 'single_post_title', $oembed->title ) );
275
  }
276
 
277
+ // Show description (non-oEmbed standard).
278
  if ( isset( $oembed->description ) ) {
279
  $caption .= sprintf( '<div class="caption-description">%s</div>', apply_filters( 'bp_activity_get_embed_excerpt', $oembed->description ) );
280
  }
281
 
282
  // Show author info.
283
  if ( isset( $oembed->provider_name ) && isset( $oembed->author_name ) ) {
284
+ /* translators: 1: oEmbed author. 2: oEmbed provider. eg. By BuddyPress on YouTube. */
285
  $anchor_text = sprintf( __( 'By %1$s on %2$s', 'buddypress' ), $oembed->author_name, $oembed->provider_name );
286
 
287
  } elseif ( isset( $oembed->provider_name ) ) {
288
+ /* translators: %s: oEmbed provider. */
289
  $anchor_text = sprintf( __( 'View on %s', 'buddypress' ), $oembed->provider_name );
290
  }
291
 
bp-activity/bp-activity-filters.php CHANGED
@@ -615,7 +615,7 @@ function bp_activity_heartbeat_strings( $strings = array() ) {
615
  */
616
  $heartbeat_settings = apply_filters( 'heartbeat_settings', array() );
617
  if ( ! empty( $heartbeat_settings['interval'] ) ) {
618
- // 'Fast' is 5
619
  $global_pulse = is_numeric( $heartbeat_settings['interval'] ) ? absint( $heartbeat_settings['interval'] ) : 5;
620
  }
621
 
615
  */
616
  $heartbeat_settings = apply_filters( 'heartbeat_settings', array() );
617
  if ( ! empty( $heartbeat_settings['interval'] ) ) {
618
+ // 'Fast' is 5.
619
  $global_pulse = is_numeric( $heartbeat_settings['interval'] ) ? absint( $heartbeat_settings['interval'] ) : 5;
620
  }
621
 
bp-activity/bp-activity-functions.php CHANGED
@@ -522,12 +522,12 @@ function bp_activity_get_post_type_tracking_args( $post_type ) {
522
  $post_type_activity->new_post_type_action_ms = $post_type_object->labels->bp_activity_new_post_ms;
523
  }
524
 
525
- // If the post type supports comments and has a comment action id, build the comments tracking args
526
  if ( $post_type_support_comments && ! empty( $post_type_activity->comment_action_id ) ) {
527
- // Init a new container for the activity type for comments
528
  $post_type_activity->comments_tracking = new stdClass();
529
 
530
- // Build the activity type for comments
531
  $post_type_activity->comments_tracking->component_id = $post_type_activity->component_id;
532
  $post_type_activity->comments_tracking->action_id = $post_type_activity->comment_action_id;
533
 
@@ -597,9 +597,9 @@ function bp_activity_get_post_types_tracking_args() {
597
  $track_post_type = bp_activity_get_post_type_tracking_args( $post_type );
598
 
599
  if ( ! empty( $track_post_type ) ) {
600
- // Set the post type comments tracking args
601
  if ( ! empty( $track_post_type->comments_tracking->action_id ) ) {
602
- // Used to check support for comment tracking by activity type (new_post_type_comment)
603
  $track_post_type->comments_tracking->comments_tracking = true;
604
 
605
  // Used to be able to find the post type this activity type is associated to.
@@ -607,7 +607,7 @@ function bp_activity_get_post_types_tracking_args() {
607
 
608
  $post_types_tracking_args[ $track_post_type->comments_tracking->action_id ] = $track_post_type->comments_tracking;
609
 
610
- // Used to check support for comment tracking by activity type (new_post_type)
611
  $track_post_type->comments_tracking = true;
612
  }
613
 
@@ -650,7 +650,7 @@ function bp_activity_type_supports( $activity_type = '', $feature = '' ) {
650
  * eg. 'new_blog_post' and 'new_blog_comment' will both return true.
651
  */
652
  case 'post-type-comment-tracking' :
653
- // Set the activity track global if not set yet
654
  if ( empty( $bp->activity->track ) ) {
655
  $bp->activity->track = bp_activity_get_post_types_tracking_args();
656
  }
@@ -726,7 +726,7 @@ function bp_activity_post_type_get_tracking_arg( $activity_type, $arg = '' ) {
726
 
727
  $bp = buddypress();
728
 
729
- // Set the activity track global if not set yet
730
  if ( empty( $bp->activity->track ) ) {
731
  $bp->activity->track = bp_activity_get_post_types_tracking_args();
732
  }
@@ -1277,7 +1277,22 @@ function bp_activity_remove_all_user_data( $user_id = 0 ) {
1277
  do_action( 'bp_activity_remove_all_user_data', $user_id );
1278
  }
1279
  add_action( 'wpmu_delete_user', 'bp_activity_remove_all_user_data' );
1280
- add_action( 'delete_user', 'bp_activity_remove_all_user_data' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1281
 
1282
  /**
1283
  * Mark all of the user's activity as spam.
@@ -1523,7 +1538,11 @@ function bp_activity_generate_action_string( $activity ) {
1523
  * @return string $action
1524
  */
1525
  function bp_activity_format_activity_action_activity_update( $action, $activity ) {
1526
- $action = sprintf( esc_html__( '%s posted an update', 'buddypress' ), bp_core_get_userlink( $activity->user_id ) );
 
 
 
 
1527
 
1528
  /**
1529
  * Filters the formatted activity action update string.
@@ -1546,7 +1565,11 @@ function bp_activity_format_activity_action_activity_update( $action, $activity
1546
  * @return string $action
1547
  */
1548
  function bp_activity_format_activity_action_activity_comment( $action, $activity ) {
1549
- $action = sprintf( esc_html__( '%s posted a new activity comment', 'buddypress' ), bp_core_get_userlink( $activity->user_id ) );
 
 
 
 
1550
 
1551
  /**
1552
  * Filters the formatted activity action comment string.
@@ -1597,13 +1620,14 @@ function bp_activity_format_activity_action_custom_post_type_post( $action, $act
1597
  if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_action_ms ) ) {
1598
  $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_action_ms, $user_link, esc_url( $post_url ), $blog_link );
1599
  } else {
1600
-
1601
  $action = sprintf( esc_html_x( '%1$s wrote a new %2$s, on the site %3$s', 'Activity Custom Post Type post action', 'buddypress' ), $user_link, $post_link, $blog_link );
1602
  }
1603
  } else {
1604
  if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_action ) ) {
1605
  $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_action, $user_link, $post_url );
1606
  } else {
 
1607
  $action = sprintf( esc_html_x( '%1$s wrote a new %2$s', 'Activity Custom Post Type post action', 'buddypress' ), $user_link, $post_link );
1608
  }
1609
  }
@@ -1650,12 +1674,14 @@ function bp_activity_format_activity_action_custom_post_type_comment( $action, $
1650
  if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_comment_action_ms ) ) {
1651
  $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_comment_action_ms, $user_link, $activity->primary_link, $blog_link );
1652
  } else {
 
1653
  $action = sprintf( esc_html_x( '%1$s commented on the %2$s, on the site %3$s', 'Activity Custom Post Type comment action', 'buddypress' ), $user_link, $post_link, $blog_link );
1654
  }
1655
  } else {
1656
  if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_comment_action ) ) {
1657
  $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_comment_action, $user_link, $activity->primary_link );
1658
  } else {
 
1659
  $action = sprintf( esc_html_x( '%1$s commented on the %2$s', 'Activity Custom Post Type post comment action', 'buddypress' ), $user_link, $post_link );
1660
  }
1661
  }
@@ -1702,17 +1728,17 @@ function bp_activity_get( $args = '' ) {
1702
  'max' => false, // Maximum number of results to return.
1703
  'fields' => 'all',
1704
  'page' => 1, // Page 1 without a per_page will result in no pagination.
1705
- 'per_page' => false, // results per page
1706
- 'sort' => 'DESC', // sort ASC or DESC
1707
  'display_comments' => false, // False for no comments. 'stream' for within stream display, 'threaded' for below each activity item.
1708
 
1709
- 'search_terms' => false, // Pass search terms as a string
1710
- 'meta_query' => false, // Filter by activity meta. See WP_Meta_Query for format
1711
  'date_query' => false, // Filter by date. See first parameter of WP_Date_Query for format.
1712
  'filter_query' => false,
1713
  'show_hidden' => false, // Show activity items that are hidden site-wide?
1714
  'exclude' => false, // Comma-separated list of activity IDs to exclude.
1715
- 'in' => false, // Comma-separated list or array of activity IDs to which you
1716
  // want to limit the query.
1717
  'spam' => 'ham_only', // 'ham_only' (default), 'spam_only' or 'all'.
1718
  'update_meta_cache' => true,
@@ -1788,7 +1814,7 @@ function bp_activity_get_specific( $args = '' ) {
1788
  'page' => 1, // Page 1 without a per_page will result in no pagination.
1789
  'per_page' => false, // Results per page.
1790
  'show_hidden' => true, // When fetching specific items, show all.
1791
- 'sort' => 'DESC', // Sort ASC or DESC
1792
  'spam' => 'ham_only', // Retrieve items marked as spam.
1793
  'update_meta_cache' => true,
1794
  ), 'activity_get_specific' );
@@ -1861,8 +1887,8 @@ function bp_activity_add( $args = '' ) {
1861
 
1862
  $r = bp_parse_args( $args, array(
1863
  'id' => false, // Pass an existing activity ID to update an existing entry.
1864
- 'action' => '', // The activity action - e.g. "Jon Doe posted an update"
1865
- 'content' => '', // Optional: The content of the activity item e.g. "BuddyPress is awesome guys!"
1866
  'component' => false, // The name/ID of the component e.g. groups, profile, mycomponent.
1867
  'type' => false, // The activity type e.g. activity_update, profile_updated.
1868
  'primary_link' => '', // Optional: The primary URL for this item in RSS feeds (defaults to activity permalink).
@@ -2298,20 +2324,20 @@ function bp_activity_post_type_unpublish( $post_id = 0, $post = null ) {
2298
  * @return null|WP_Error|bool|int The ID of the activity on success. False on error.
2299
  */
2300
  function bp_activity_post_type_comment( $comment_id = 0, $is_approved = true, $activity_post_object = null ) {
2301
- // Get the users comment
2302
  $post_type_comment = get_comment( $comment_id );
2303
 
2304
- // Don't record activity if the comment hasn't been approved
2305
  if ( empty( $is_approved ) ) {
2306
  return false;
2307
  }
2308
 
2309
- // Don't record activity if no email address has been included
2310
  if ( empty( $post_type_comment->comment_author_email ) ) {
2311
  return false;
2312
  }
2313
 
2314
- // Don't record activity if the comment has already been marked as spam
2315
  if ( 'spam' === $is_approved ) {
2316
  return false;
2317
  }
@@ -2319,18 +2345,18 @@ function bp_activity_post_type_comment( $comment_id = 0, $is_approved = true, $a
2319
  // Get the user by the comment author email.
2320
  $user = get_user_by( 'email', $post_type_comment->comment_author_email );
2321
 
2322
- // If user isn't registered, don't record activity
2323
  if ( empty( $user ) ) {
2324
  return false;
2325
  }
2326
 
2327
- // Get the user_id
2328
  $user_id = (int) $user->ID;
2329
 
2330
- // Get blog and post data
2331
  $blog_id = get_current_blog_id();
2332
 
2333
- // Get the post
2334
  $post_type_comment->post = get_post( $post_type_comment->comment_post_ID );
2335
 
2336
  if ( ! is_a( $post_type_comment->post, 'WP_Post' ) ) {
@@ -2346,25 +2372,25 @@ function bp_activity_post_type_comment( $comment_id = 0, $is_approved = true, $a
2346
  */
2347
  $is_post_status_not_allowed = (bool) apply_filters( 'bp_activity_post_type_is_post_status_allowed', 'publish' !== $post_type_comment->post->post_status || ! empty( $post_type_comment->post->post_password ) );
2348
 
2349
- // If this is a password protected post, or not a public post don't record the comment
2350
  if ( $is_post_status_not_allowed ) {
2351
  return false;
2352
  }
2353
 
2354
- // Set post type
2355
  $post_type = $post_type_comment->post->post_type;
2356
 
2357
  if ( empty( $activity_post_object ) ) {
2358
  // Get the post type tracking args.
2359
  $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
2360
 
2361
- // Bail if the activity type does not exist
2362
  if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
2363
  return false;
2364
  }
2365
  }
2366
 
2367
- // Set the $activity_comment_object
2368
  $activity_comment_object = $activity_post_object->comments_tracking;
2369
 
2370
  /**
@@ -2503,13 +2529,13 @@ function bp_activity_post_type_remove_comment( $comment_id = 0, $activity_post_o
2503
  // Get the post type tracking args.
2504
  $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
2505
 
2506
- // Bail if the activity type does not exist
2507
  if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
2508
  return false;
2509
  }
2510
  }
2511
 
2512
- // Set the $activity_comment_object
2513
  $activity_comment_object = $activity_post_object->comments_tracking;
2514
 
2515
  if ( empty( $activity_comment_object->action_id ) ) {
@@ -3417,7 +3443,8 @@ function bp_activity_create_summary( $content, $activity ) {
3417
  if ( $use_media_type === 'embeds' ) {
3418
  $summary .= PHP_EOL . PHP_EOL . $extracted_media['url'];
3419
  } elseif ( $use_media_type === 'images' ) {
3420
- $summary .= sprintf( ' <img src="%s">', esc_url( $extracted_media['url'] ) );
 
3421
  } elseif ( in_array( $use_media_type, array( 'audio', 'videos' ), true ) ) {
3422
  $summary .= PHP_EOL . PHP_EOL . $extracted_media['original']; // Full shortcode.
3423
  }
@@ -4032,16 +4059,16 @@ function bp_activity_transition_post_type_comment_status( $new_status, $old_stat
4032
  // Get the post type tracking args.
4033
  $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
4034
 
4035
- // Bail if the activity type does not exist
4036
  if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
4037
  return false;
4038
 
4039
- // Set the $activity_comment_object
4040
  } else {
4041
  $activity_comment_object = $activity_post_object->comments_tracking;
4042
  }
4043
 
4044
- // Init an empty activity ID
4045
  $activity_id = 0;
4046
 
4047
  /**
@@ -4065,7 +4092,7 @@ function bp_activity_transition_post_type_comment_status( $new_status, $old_stat
4065
  $action = 'ham_activity';
4066
  }
4067
 
4068
- // Get the activity
4069
  if ( bp_disable_blogforum_comments() ) {
4070
  $activity_id = bp_activity_get_activity_id( array(
4071
  'component' => $activity_comment_object->component_id,
@@ -4093,7 +4120,7 @@ function bp_activity_transition_post_type_comment_status( $new_status, $old_stat
4093
  return false;
4094
  }
4095
 
4096
- // Check activity item exists
4097
  if ( empty( $activity_id ) ) {
4098
  // If no activity exists, but the comment has been approved, record it into the activity table.
4099
  if ( 'approved' == $new_status ) {
@@ -4103,20 +4130,20 @@ function bp_activity_transition_post_type_comment_status( $new_status, $old_stat
4103
  return;
4104
  }
4105
 
4106
- // Create an activity object
4107
  $activity = new BP_Activity_Activity( $activity_id );
4108
  if ( empty( $activity->component ) ) {
4109
  return;
4110
  }
4111
 
4112
- // Spam/ham the activity if it's not already in that state
4113
  if ( 'spam_activity' === $action && ! $activity->is_spam ) {
4114
  bp_activity_mark_as_spam( $activity );
4115
  } elseif ( 'ham_activity' == $action) {
4116
  bp_activity_mark_as_ham( $activity );
4117
  }
4118
 
4119
- // Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated
4120
  $post_type_comment_action = $activity_comment_object->action_id;
4121
  $comment_akismet_history = function ( $activity_types ) use ( $post_type_comment_action ) {
4122
  $activity_types[] = $post_type_comment_action;
@@ -4125,16 +4152,16 @@ function bp_activity_transition_post_type_comment_status( $new_status, $old_stat
4125
  };
4126
  add_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
4127
 
4128
- // Make sure the activity change won't edit the comment if sync is on
4129
  remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
4130
 
4131
- // Save the updated activity
4132
  $activity->save();
4133
 
4134
- // Restore the action
4135
  add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
4136
 
4137
- // Remove the "new_blog_comment" activity type whitelist so we don't break anything
4138
  remove_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
4139
  }
4140
  add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
522
  $post_type_activity->new_post_type_action_ms = $post_type_object->labels->bp_activity_new_post_ms;
523
  }
524
 
525
+ // If the post type supports comments and has a comment action id, build the comments tracking args.
526
  if ( $post_type_support_comments && ! empty( $post_type_activity->comment_action_id ) ) {
527
+ // Init a new container for the activity type for comments.
528
  $post_type_activity->comments_tracking = new stdClass();
529
 
530
+ // Build the activity type for comments.
531
  $post_type_activity->comments_tracking->component_id = $post_type_activity->component_id;
532
  $post_type_activity->comments_tracking->action_id = $post_type_activity->comment_action_id;
533
 
597
  $track_post_type = bp_activity_get_post_type_tracking_args( $post_type );
598
 
599
  if ( ! empty( $track_post_type ) ) {
600
+ // Set the post type comments tracking args.
601
  if ( ! empty( $track_post_type->comments_tracking->action_id ) ) {
602
+ // Used to check support for comment tracking by activity type (new_post_type_comment).
603
  $track_post_type->comments_tracking->comments_tracking = true;
604
 
605
  // Used to be able to find the post type this activity type is associated to.
607
 
608
  $post_types_tracking_args[ $track_post_type->comments_tracking->action_id ] = $track_post_type->comments_tracking;
609
 
610
+ // Used to check support for comment tracking by activity type (new_post_type).
611
  $track_post_type->comments_tracking = true;
612
  }
613
 
650
  * eg. 'new_blog_post' and 'new_blog_comment' will both return true.
651
  */
652
  case 'post-type-comment-tracking' :
653
+ // Set the activity track global if not set yet.
654
  if ( empty( $bp->activity->track ) ) {
655
  $bp->activity->track = bp_activity_get_post_types_tracking_args();
656
  }
726
 
727
  $bp = buddypress();
728
 
729
+ // Set the activity track global if not set yet.
730
  if ( empty( $bp->activity->track ) ) {
731
  $bp->activity->track = bp_activity_get_post_types_tracking_args();
732
  }
1277
  do_action( 'bp_activity_remove_all_user_data', $user_id );
1278
  }
1279
  add_action( 'wpmu_delete_user', 'bp_activity_remove_all_user_data' );
1280
+
1281
+ /**
1282
+ * Deletes user activity data on the 'delete_user' hook.
1283
+ *
1284
+ * @since 6.0.0
1285
+ *
1286
+ * @param int $user_id The ID of the deleted user.
1287
+ */
1288
+ function bp_activity_remove_all_user_data_on_delete_user( $user_id ) {
1289
+ if ( ! bp_remove_user_data_on_delete_user_hook( 'activity', $user_id ) ) {
1290
+ return;
1291
+ }
1292
+
1293
+ bp_activity_remove_all_user_data( $user_id );
1294
+ }
1295
+ add_action( 'delete_user', 'bp_activity_remove_all_user_data_on_delete_user' );
1296
 
1297
  /**
1298
  * Mark all of the user's activity as spam.
1538
  * @return string $action
1539
  */
1540
  function bp_activity_format_activity_action_activity_update( $action, $activity ) {
1541
+ $action = sprintf(
1542
+ /* translators: %s: the activity author user link */
1543
+ esc_html__( '%s posted an update', 'buddypress' ),
1544
+ bp_core_get_userlink( $activity->user_id )
1545
+ );
1546
 
1547
  /**
1548
  * Filters the formatted activity action update string.
1565
  * @return string $action
1566
  */
1567
  function bp_activity_format_activity_action_activity_comment( $action, $activity ) {
1568
+ $action = sprintf(
1569
+ /* translators: %s: the activity author user link */
1570
+ esc_html__( '%s posted a new activity comment', 'buddypress' ),
1571
+ bp_core_get_userlink( $activity->user_id )
1572
+ );
1573
 
1574
  /**
1575
  * Filters the formatted activity action comment string.
1620
  if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_action_ms ) ) {
1621
  $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_action_ms, $user_link, esc_url( $post_url ), $blog_link );
1622
  } else {
1623
+ /* translators: 1: the activity author user link. 2: the post link. 3: the blog link. */
1624
  $action = sprintf( esc_html_x( '%1$s wrote a new %2$s, on the site %3$s', 'Activity Custom Post Type post action', 'buddypress' ), $user_link, $post_link, $blog_link );
1625
  }
1626
  } else {
1627
  if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_action ) ) {
1628
  $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_action, $user_link, $post_url );
1629
  } else {
1630
+ /* translators: 1: the activity author user link. 2: the post link. */
1631
  $action = sprintf( esc_html_x( '%1$s wrote a new %2$s', 'Activity Custom Post Type post action', 'buddypress' ), $user_link, $post_link );
1632
  }
1633
  }
1674
  if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_comment_action_ms ) ) {
1675
  $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_comment_action_ms, $user_link, $activity->primary_link, $blog_link );
1676
  } else {
1677
+ /* translators: 1: the activity author user link. 2: the post link. 3: the blog link. */
1678
  $action = sprintf( esc_html_x( '%1$s commented on the %2$s, on the site %3$s', 'Activity Custom Post Type comment action', 'buddypress' ), $user_link, $post_link, $blog_link );
1679
  }
1680
  } else {
1681
  if ( ! empty( $bp->activity->track[ $activity->type ]->new_post_type_comment_action ) ) {
1682
  $action = sprintf( $bp->activity->track[ $activity->type ]->new_post_type_comment_action, $user_link, $activity->primary_link );
1683
  } else {
1684
+ /* translators: 1: the activity author user link. 2: the post link. */
1685
  $action = sprintf( esc_html_x( '%1$s commented on the %2$s', 'Activity Custom Post Type post comment action', 'buddypress' ), $user_link, $post_link );
1686
  }
1687
  }
1728
  'max' => false, // Maximum number of results to return.
1729
  'fields' => 'all',
1730
  'page' => 1, // Page 1 without a per_page will result in no pagination.
1731
+ 'per_page' => false, // results per page.
1732
+ 'sort' => 'DESC', // sort ASC or DESC.
1733
  'display_comments' => false, // False for no comments. 'stream' for within stream display, 'threaded' for below each activity item.
1734
 
1735
+ 'search_terms' => false, // Pass search terms as a string.
1736
+ 'meta_query' => false, // Filter by activity meta. See WP_Meta_Query for format.
1737
  'date_query' => false, // Filter by date. See first parameter of WP_Date_Query for format.
1738
  'filter_query' => false,
1739
  'show_hidden' => false, // Show activity items that are hidden site-wide?
1740
  'exclude' => false, // Comma-separated list of activity IDs to exclude.
1741
+ 'in' => false, // Comma-separated list or array of activity IDs to which you.
1742
  // want to limit the query.
1743
  'spam' => 'ham_only', // 'ham_only' (default), 'spam_only' or 'all'.
1744
  'update_meta_cache' => true,
1814
  'page' => 1, // Page 1 without a per_page will result in no pagination.
1815
  'per_page' => false, // Results per page.
1816
  'show_hidden' => true, // When fetching specific items, show all.
1817
+ 'sort' => 'DESC', // Sort ASC or DESC.
1818
  'spam' => 'ham_only', // Retrieve items marked as spam.
1819
  'update_meta_cache' => true,
1820
  ), 'activity_get_specific' );
1887
 
1888
  $r = bp_parse_args( $args, array(
1889
  'id' => false, // Pass an existing activity ID to update an existing entry.
1890
+ 'action' => '', // The activity action - e.g. "Jon Doe posted an update".
1891
+ 'content' => '', // Optional: The content of the activity item e.g. "BuddyPress is awesome guys!".
1892
  'component' => false, // The name/ID of the component e.g. groups, profile, mycomponent.
1893
  'type' => false, // The activity type e.g. activity_update, profile_updated.
1894
  'primary_link' => '', // Optional: The primary URL for this item in RSS feeds (defaults to activity permalink).
2324
  * @return null|WP_Error|bool|int The ID of the activity on success. False on error.
2325
  */
2326
  function bp_activity_post_type_comment( $comment_id = 0, $is_approved = true, $activity_post_object = null ) {
2327
+ // Get the users comment.
2328
  $post_type_comment = get_comment( $comment_id );
2329
 
2330
+ // Don't record activity if the comment hasn't been approved.
2331
  if ( empty( $is_approved ) ) {
2332
  return false;
2333
  }
2334
 
2335
+ // Don't record activity if no email address has been included.
2336
  if ( empty( $post_type_comment->comment_author_email ) ) {
2337
  return false;
2338
  }
2339
 
2340
+ // Don't record activity if the comment has already been marked as spam.
2341
  if ( 'spam' === $is_approved ) {
2342
  return false;
2343
  }
2345
  // Get the user by the comment author email.
2346
  $user = get_user_by( 'email', $post_type_comment->comment_author_email );
2347
 
2348
+ // If user isn't registered, don't record activity.
2349
  if ( empty( $user ) ) {
2350
  return false;
2351
  }
2352
 
2353
+ // Get the user_id.
2354
  $user_id = (int) $user->ID;
2355
 
2356
+ // Get blog and post data.
2357
  $blog_id = get_current_blog_id();
2358
 
2359
+ // Get the post.
2360
  $post_type_comment->post = get_post( $post_type_comment->comment_post_ID );
2361
 
2362
  if ( ! is_a( $post_type_comment->post, 'WP_Post' ) ) {
2372
  */
2373
  $is_post_status_not_allowed = (bool) apply_filters( 'bp_activity_post_type_is_post_status_allowed', 'publish' !== $post_type_comment->post->post_status || ! empty( $post_type_comment->post->post_password ) );
2374
 
2375
+ // If this is a password protected post, or not a public post don't record the comment.
2376
  if ( $is_post_status_not_allowed ) {
2377
  return false;
2378
  }
2379
 
2380
+ // Set post type.
2381
  $post_type = $post_type_comment->post->post_type;
2382
 
2383
  if ( empty( $activity_post_object ) ) {
2384
  // Get the post type tracking args.
2385
  $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
2386
 
2387
+ // Bail if the activity type does not exist.
2388
  if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
2389
  return false;
2390
  }
2391
  }
2392
 
2393
+ // Set the $activity_comment_object.
2394
  $activity_comment_object = $activity_post_object->comments_tracking;
2395
 
2396
  /**
2529
  // Get the post type tracking args.
2530
  $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
2531
 
2532
+ // Bail if the activity type does not exist.
2533
  if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
2534
  return false;
2535
  }
2536
  }
2537
 
2538
+ // Set the $activity_comment_object.
2539
  $activity_comment_object = $activity_post_object->comments_tracking;
2540
 
2541
  if ( empty( $activity_comment_object->action_id ) ) {
3443
  if ( $use_media_type === 'embeds' ) {
3444
  $summary .= PHP_EOL . PHP_EOL . $extracted_media['url'];
3445
  } elseif ( $use_media_type === 'images' ) {
3446
+ $extracted_media_url = isset( $extracted_media['url'] ) ? $extracted_media['url'] : '';
3447
+ $summary .= sprintf( ' <img src="%s">', esc_url( $extracted_media_url ) );
3448
  } elseif ( in_array( $use_media_type, array( 'audio', 'videos' ), true ) ) {
3449
  $summary .= PHP_EOL . PHP_EOL . $extracted_media['original']; // Full shortcode.
3450
  }
4059
  // Get the post type tracking args.
4060
  $activity_post_object = bp_activity_get_post_type_tracking_args( $post_type );
4061
 
4062
+ // Bail if the activity type does not exist.
4063
  if ( empty( $activity_post_object->comments_tracking->action_id ) ) {
4064
  return false;
4065
 
4066
+ // Set the $activity_comment_object.
4067
  } else {
4068
  $activity_comment_object = $activity_post_object->comments_tracking;
4069
  }
4070
 
4071
+ // Init an empty activity ID.
4072
  $activity_id = 0;
4073
 
4074
  /**
4092
  $action = 'ham_activity';
4093
  }
4094
 
4095
+ // Get the activity.
4096
  if ( bp_disable_blogforum_comments() ) {
4097
  $activity_id = bp_activity_get_activity_id( array(
4098
  'component' => $activity_comment_object->component_id,
4120
  return false;
4121
  }
4122
 
4123
+ // Check activity item exists.
4124
  if ( empty( $activity_id ) ) {
4125
  // If no activity exists, but the comment has been approved, record it into the activity table.
4126
  if ( 'approved' == $new_status ) {
4130
  return;
4131
  }
4132
 
4133
+ // Create an activity object.
4134
  $activity = new BP_Activity_Activity( $activity_id );
4135
  if ( empty( $activity->component ) ) {
4136
  return;
4137
  }
4138
 
4139
+ // Spam/ham the activity if it's not already in that state.
4140
  if ( 'spam_activity' === $action && ! $activity->is_spam ) {
4141
  bp_activity_mark_as_spam( $activity );
4142
  } elseif ( 'ham_activity' == $action) {
4143
  bp_activity_mark_as_ham( $activity );
4144
  }
4145
 
4146
+ // Add "new_post_type_comment" to the whitelisted activity types, so that the activity's Akismet history is generated.
4147
  $post_type_comment_action = $activity_comment_object->action_id;
4148
  $comment_akismet_history = function ( $activity_types ) use ( $post_type_comment_action ) {
4149
  $activity_types[] = $post_type_comment_action;
4152
  };
4153
  add_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
4154
 
4155
+ // Make sure the activity change won't edit the comment if sync is on.
4156
  remove_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
4157
 
4158
+ // Save the updated activity.
4159
  $activity->save();
4160
 
4161
+ // Restore the action.
4162
  add_action( 'bp_activity_before_save', 'bp_blogs_sync_activity_edit_to_post_comment', 20 );
4163
 
4164
+ // Remove the "new_blog_comment" activity type whitelist so we don't break anything.
4165
  remove_filter( 'bp_akismet_get_activity_types', $comment_akismet_history );
4166
  }
4167
  add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
bp-activity/bp-activity-notifications.php CHANGED
@@ -34,13 +34,17 @@ function bp_activity_format_notifications( $action, $item_id, $secondary_item_id
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;
@@ -51,11 +55,15 @@ function bp_activity_format_notifications( $action, $item_id, $secondary_item_id
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( 'rid', (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;
@@ -66,11 +74,15 @@ function bp_activity_format_notifications( $action, $item_id, $secondary_item_id
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( 'crid', (int) $id, bp_activity_get_permalink( $activity_id ) );
 
 
74
  $text = sprintf( __( '%1$s replied to one of your activity comments', 'buddypress' ), $user_fullname );
75
  }
76
  break;
@@ -396,14 +408,19 @@ function bp_activity_screen_notification_settings() {
396
  <?php if ( bp_activity_do_mentions() ) : ?>
397
  <tr id="activity-notification-settings-mentions">
398
  <td>&nbsp;</td>
399
- <td><?php printf( __( 'A member mentions you in an update using "@%s"', 'buddypress' ), bp_core_get_username( bp_displayed_user_id() ) ) ?></td>
 
 
 
 
 
400
  <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
401
  /* translators: accessibility text */
402
- _e( 'Yes, send email', 'buddypress' );
403
  ?></label></td>
404
  <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
405
  /* translators: accessibility text */
406
- _e( 'No, do not send email', 'buddypress' );
407
  ?></label></td>
408
  </tr>
409
  <?php endif; ?>
@@ -413,11 +430,11 @@ function bp_activity_screen_notification_settings() {
413
  <td><?php _e( "A member replies to an update or comment you've posted", 'buddypress' ) ?></td>
414
  <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
415
  /* translators: accessibility text */
416
- _e( 'Yes, send email', 'buddypress' );
417
  ?></label></td>
418
  <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
419
  /* translators: accessibility text */
420
- _e( 'No, do not send email', 'buddypress' );
421
  ?></label></td>
422
  </tr>
423
 
34
  case 'new_at_mention':
35
  $action_filter = 'at_mentions';
36
  $link = bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/';
37
+
38
+ /* translators: %s: the current user display name */
39
+ $title = sprintf( __( '@%s Mentions', 'buddypress' ), bp_get_loggedin_user_username() );
40
+ $amount = 'single';
41
 
42
  if ( (int) $total_items > 1 ) {
43
+ /* translators: 1: the number of activity mentions */
44
  $text = sprintf( __( 'You have %1$d new mentions', 'buddypress' ), (int) $total_items );
45
  $amount = 'multiple';
46
  } else {
47
+ /* translators: 1: the user display name */
48
  $text = sprintf( __( '%1$s mentioned you', 'buddypress' ), $user_fullname );
49
  }
50
  break;
55
  $amount = 'single';
56
 
57
  if ( (int) $total_items > 1 ) {
58
+ $link = add_query_arg( 'type', $action, $link );
59
+
60
+ /* translators: 1: the number of activity replies */
61
  $text = sprintf( __( 'You have %1$d new replies', 'buddypress' ), (int) $total_items );
62
  $amount = 'multiple';
63
  } else {
64
  $link = add_query_arg( 'rid', (int) $id, bp_activity_get_permalink( $activity_id ) );
65
+
66
+ /* translators: 1: the user display name */
67
  $text = sprintf( __( '%1$s commented on one of your updates', 'buddypress' ), $user_fullname );
68
  }
69
  break;
74
  $amount = 'single';
75
 
76
  if ( (int) $total_items > 1 ) {
77
+ $link = add_query_arg( 'type', $action, $link );
78
+
79
+ /* translators: 1: the number of activity comment replies */
80
  $text = sprintf( __( 'You have %1$d new comment replies', 'buddypress' ), (int) $total_items );
81
  $amount = 'multiple';
82
  } else {
83
  $link = add_query_arg( 'crid', (int) $id, bp_activity_get_permalink( $activity_id ) );
84
+
85
+ /* translators: 1: the user display name */
86
  $text = sprintf( __( '%1$s replied to one of your activity comments', 'buddypress' ), $user_fullname );
87
  }
88
  break;
408
  <?php if ( bp_activity_do_mentions() ) : ?>
409
  <tr id="activity-notification-settings-mentions">
410
  <td>&nbsp;</td>
411
+ <td>
412
+ <?php
413
+ /* translators: %s: the displayed user username */
414
+ printf( __( 'A member mentions you in an update using "@%s"', 'buddypress' ), bp_core_get_username( bp_displayed_user_id() ) );
415
+ ?>
416
+ </td>
417
  <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
418
  /* translators: accessibility text */
419
+ esc_html_e( 'Yes, send email', 'buddypress' );
420
  ?></label></td>
421
  <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
422
  /* translators: accessibility text */
423
+ esc_html_e( 'No, do not send email', 'buddypress' );
424
  ?></label></td>
425
  </tr>
426
  <?php endif; ?>
430
  <td><?php _e( "A member replies to an update or comment you've posted", 'buddypress' ) ?></td>
431
  <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
432
  /* translators: accessibility text */
433
+ esc_html_e( 'Yes, send email', 'buddypress' );
434
  ?></label></td>
435
  <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
436
  /* translators: accessibility text */
437
+ esc_html_e( 'No, do not send email', 'buddypress' );
438
  ?></label></td>
439
  </tr>
440
 
bp-activity/bp-activity-template.php CHANGED
@@ -452,6 +452,7 @@ function bp_activity_pagination_count() {
452
  if ( 1 == $activities_template->total_activity_count ) {
453
  $message = __( 'Viewing 1 item', 'buddypress' );
454
  } else {
 
455
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s item', 'Viewing %1$s - %2$s of %3$s items', $activities_template->total_activity_count, 'buddypress' ), $from_num, $to_num, $total );
456
  }
457
 
@@ -1034,7 +1035,11 @@ function bp_activity_avatar( $args = '' ) {
1034
  $dn_default = isset( $current_activity_item->display_name ) ? $current_activity_item->display_name : '';
1035
 
1036
  // Prepend some descriptive text to alt.
1037
- $alt_default = !empty( $dn_default ) ? sprintf( __( 'Profile picture of %s', 'buddypress' ), $dn_default ) : __( 'Profile picture', 'buddypress' );
 
 
 
 
1038
 
1039
  $defaults = array(
1040
  'alt' => $alt_default,
@@ -1182,6 +1187,7 @@ function bp_activity_secondary_avatar( $args = '' ) {
1182
  $alt = __( 'Group logo', 'buddypress' );
1183
 
1184
  if ( ! empty( $name ) ) {
 
1185
  $alt = sprintf( __( 'Group logo of %s', 'buddypress' ), $name );
1186
  }
1187
  }
@@ -1193,6 +1199,7 @@ function bp_activity_secondary_avatar( $args = '' ) {
1193
  $link = home_url();
1194
 
1195
  if ( empty( $alt ) ) {
 
1196
  $alt = sprintf( __( 'Profile picture of the author of the site %s', 'buddypress' ), get_blog_option( $item_id, 'blogname' ) );
1197
  }
1198
 
@@ -1203,6 +1210,7 @@ function bp_activity_secondary_avatar( $args = '' ) {
1203
  $link = bp_core_get_userlink( $item_id, false, true );
1204
 
1205
  if ( empty( $alt ) ) {
 
1206
  $alt = sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $activities_template->activity->secondary_item_id ) );
1207
  }
1208
 
@@ -1214,6 +1222,7 @@ function bp_activity_secondary_avatar( $args = '' ) {
1214
  $link = bp_core_get_userlink( $item_id, false, true );
1215
 
1216
  if ( empty( $alt ) ) {
 
1217
  $alt = sprintf( __( 'Profile picture of %s', 'buddypress' ), $activities_template->activity->display_name );
1218
  }
1219
 
@@ -1306,6 +1315,7 @@ function bp_activity_action( $args = array() ) {
1306
  * Return the activity action.
1307
  *
1308
  * @since 1.2.0
 
1309
  *
1310
  * @global object $activities_template {@link BP_Activity_Template}
1311
  *
@@ -1344,8 +1354,9 @@ function bp_activity_action( $args = array() ) {
1344
  * Filters the activity action after the action has been inserted as meta.
1345
  *
1346
  * @since 1.2.0
 
1347
  *
1348
- * @param array $value Array containing the current action, the current activity, and the $args array passed into the function.
1349
  */
1350
  return apply_filters_ref_array( 'bp_get_activity_action', array(
1351
  $action,
@@ -2169,7 +2180,16 @@ function bp_activity_comment_count() {
2169
 
2170
  // Deprecated notice about $args.
2171
  if ( ! empty( $deprecated ) ) {
2172
- _deprecated_argument( __FUNCTION__, '1.2', sprintf( __( '%1$s no longer accepts arguments. See the inline documentation at %2$s for more details.', 'buddypress' ), __FUNCTION__, __FILE__ ) );
 
 
 
 
 
 
 
 
 
2173
  }
2174
 
2175
  // Get the count using the purpose-built recursive function.
452
  if ( 1 == $activities_template->total_activity_count ) {
453
  $message = __( 'Viewing 1 item', 'buddypress' );
454
  } else {
455
+ /* translators: 1: the from number item. 2: the to number item. 3: the total number of items. */
456
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s item', 'Viewing %1$s - %2$s of %3$s items', $activities_template->total_activity_count, 'buddypress' ), $from_num, $to_num, $total );
457
  }
458
 
1035
  $dn_default = isset( $current_activity_item->display_name ) ? $current_activity_item->display_name : '';
1036
 
1037
  // Prepend some descriptive text to alt.
1038
+ $alt_default = __( 'Profile picture', 'buddypress' );
1039
+ if ( ! empty( $dn_default ) ) {
1040
+ /* translators: %s: member name */
1041
+ $alt_default = sprintf( __( 'Profile picture of %s', 'buddypress' ), $dn_default );
1042
+ }
1043
 
1044
  $defaults = array(
1045
  'alt' => $alt_default,
1187
  $alt = __( 'Group logo', 'buddypress' );
1188
 
1189
  if ( ! empty( $name ) ) {
1190
+ /* translators: %s: the Group name */
1191
  $alt = sprintf( __( 'Group logo of %s', 'buddypress' ), $name );
1192
  }
1193
  }
1199
  $link = home_url();
1200
 
1201
  if ( empty( $alt ) ) {
1202
+ /* translators: %s: the blog name */
1203
  $alt = sprintf( __( 'Profile picture of the author of the site %s', 'buddypress' ), get_blog_option( $item_id, 'blogname' ) );
1204
  }
1205
 
1210
  $link = bp_core_get_userlink( $item_id, false, true );
1211
 
1212
  if ( empty( $alt ) ) {
1213
+ /* translators: %s: member name */
1214
  $alt = sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $activities_template->activity->secondary_item_id ) );
1215
  }
1216
 
1222
  $link = bp_core_get_userlink( $item_id, false, true );
1223
 
1224
  if ( empty( $alt ) ) {
1225
+ /* translators: %s: member name */
1226
  $alt = sprintf( __( 'Profile picture of %s', 'buddypress' ), $activities_template->activity->display_name );
1227
  }
1228
 
1315
  * Return the activity action.
1316
  *
1317
  * @since 1.2.0
1318
+ * @since 1.7.0 Introduce function parameter, $args.
1319
  *
1320
  * @global object $activities_template {@link BP_Activity_Template}
1321
  *
1354
  * Filters the activity action after the action has been inserted as meta.
1355
  *
1356
  * @since 1.2.0
1357
+ * @since 1.7.0 Now passes a 3rd parameter, $r, an array of arguments from the function.
1358
  *
1359
+ * @param array $value Array containing the current action, the current activity, and the $r array passed into the function.
1360
  */
1361
  return apply_filters_ref_array( 'bp_get_activity_action', array(
1362
  $action,
2180
 
2181
  // Deprecated notice about $args.
2182
  if ( ! empty( $deprecated ) ) {
2183
+ _deprecated_argument(
2184
+ __FUNCTION__,
2185
+ '1.2',
2186
+ sprintf(
2187
+ /* translators: 1: the name of the function. 2: the name of the file. */
2188
+ __( '%1$s no longer accepts arguments. See the inline documentation at %2$s for more details.', 'buddypress' ),
2189
+ __FUNCTION__,
2190
+ __FILE__
2191
+ )
2192
+ );
2193
  }
2194
 
2195
  // Get the count using the purpose-built recursive function.
bp-activity/classes/class-bp-activity-activity.php CHANGED
@@ -268,15 +268,35 @@ class BP_Activity_Activity {
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 ) ) {
281
  $this->primary_link = bp_loggedin_user_domain();
282
  }
@@ -364,7 +384,16 @@ class BP_Activity_Activity {
364
 
365
  // Backward compatibility with old method of passing arguments.
366
  if ( !is_array( $args ) || count( $function_args ) > 1 ) {
367
- _deprecated_argument( __METHOD__, '1.6', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
 
 
 
 
 
 
 
 
 
368
 
369
  $old_args_keys = array(
370
  0 => 'max',
268
  return false;
269
  } else {
270
  if ( empty( $this->component ) ) {
271
+ $this->errors->add( 'bp_activity_missing_component', __( 'You need to define a component parameter to insert activity.', 'buddypress' ) );
272
  } else {
273
+ $this->errors->add( 'bp_activity_missing_type', __( 'You need to define a type parameter to insert activity.', 'buddypress' ) );
274
  }
275
 
276
  return $this->errors;
277
  }
278
  }
279
 
280
+ /**
281
+ * Use this filter to make the content of your activity required.
282
+ *
283
+ * @since 6.0.0
284
+ *
285
+ * @param bool $value True if the content of the activity type is required.
286
+ * False otherwise.
287
+ * @param string $type The type of the activity we are about to insert.
288
+ */
289
+ $type_requires_content = (bool) apply_filters( 'bp_activity_type_requires_content', $this->type === 'activity_update', $this->type );
290
+ if ( $type_requires_content && ! $this->content ) {
291
+ if ( 'bool' === $this->error_type ) {
292
+ return false;
293
+ } else {
294
+ $this->errors->add( 'bp_activity_missing_content', __( 'Please enter some content to post.', 'buddypress' ) );
295
+
296
+ return $this->errors;
297
+ }
298
+ }
299
+
300
  if ( empty( $this->primary_link ) ) {
301
  $this->primary_link = bp_loggedin_user_domain();
302
  }
384
 
385
  // Backward compatibility with old method of passing arguments.
386
  if ( !is_array( $args ) || count( $function_args ) > 1 ) {
387
+ _deprecated_argument(
388
+ __METHOD__,
389
+ '1.6',
390
+ sprintf(
391
+ /* translators: 1: the name of the method. 2: the name of the file. */
392
+ __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ),
393
+ __METHOD__,
394
+ __FILE__
395
+ )
396
+ );
397
 
398
  $old_args_keys = array(
399
  0 => 'max',
bp-activity/classes/class-bp-activity-component.php CHANGED
@@ -71,7 +71,7 @@ class BP_Activity_Component extends BP_Component {
71
  $includes[] = 'akismet';
72
  }
73
 
74
- // Embeds
75
  if ( bp_is_active( $this->id, 'embeds' ) ) {
76
  $includes[] = 'embeds';
77
  }
@@ -431,7 +431,11 @@ class BP_Activity_Component extends BP_Component {
431
  $bp->bp_options_avatar = bp_core_fetch_avatar( array(
432
  'item_id' => bp_displayed_user_id(),
433
  'type' => 'thumb',
434
- 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() )
 
 
 
 
435
  ) );
436
  $bp->bp_options_title = bp_get_displayed_user_fullname();
437
  }
71
  $includes[] = 'akismet';
72
  }
73
 
74
+ // Embeds.
75
  if ( bp_is_active( $this->id, 'embeds' ) ) {
76
  $includes[] = 'embeds';
77
  }
431
  $bp->bp_options_avatar = bp_core_fetch_avatar( array(
432
  'item_id' => bp_displayed_user_id(),
433
  'type' => 'thumb',
434
+ 'alt' => sprintf(
435
+ /* translators: %s: member name */
436
+ __( 'Profile picture of %s', 'buddypress' ),
437
+ bp_get_displayed_user_fullname()
438
+ ),
439
  ) );
440
  $bp->bp_options_title = bp_get_displayed_user_fullname();
441
  }
bp-activity/classes/class-bp-activity-list-table.php CHANGED
@@ -38,6 +38,14 @@ class BP_Activity_List_Table extends WP_List_Table {
38
  */
39
  public $spam_count = 0;
40
 
 
 
 
 
 
 
 
 
41
  /**
42
  * Store activity-to-user-ID mappings for use in the In Response To column.
43
  *
@@ -97,23 +105,18 @@ class BP_Activity_List_Table extends WP_List_Table {
97
  $per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) );
98
 
99
  // Check if we're on the "Spam" view.
100
- if ( !empty( $_REQUEST['activity_status'] ) && 'spam' == $_REQUEST['activity_status'] ) {
101
  $spam = 'spam_only';
102
  $this->view = 'spam';
103
  }
104
 
105
- // Sort order.
106
- if ( !empty( $_REQUEST['order'] ) && 'desc' != $_REQUEST['order'] )
107
- $sort = 'ASC';
108
-
109
- // Order by.
110
- /*if ( !empty( $_REQUEST['orderby'] ) ) {
111
- }*/
112
-
113
  // Filter.
114
  if ( ! empty( $_REQUEST['activity_type'] ) ) {
115
  $filter = array( 'action' => $_REQUEST['activity_type'] );
116
 
 
 
 
117
  /**
118
  * Filter here to override the filter with a filter query
119
  *
@@ -124,22 +127,30 @@ class BP_Activity_List_Table extends WP_List_Table {
124
  $has_filter_query = apply_filters( 'bp_activity_list_table_filter_activity_type_items', $filter );
125
 
126
  if ( ! empty( $has_filter_query['filter_query'] ) ) {
127
- // Reset the filter
128
  $filter = array();
129
 
130
- // And use the filter query instead
131
  $filter_query = $has_filter_query['filter_query'];
132
  }
133
  }
134
 
135
  // Are we doing a search?
136
- if ( !empty( $_REQUEST['s'] ) )
137
  $search_terms = $_REQUEST['s'];
138
 
 
 
 
 
139
  // Check if user has clicked on a specific activity (if so, fetch only that, and any related, activity).
140
- if ( !empty( $_REQUEST['aid'] ) )
141
  $include_id = (int) $_REQUEST['aid'];
142
 
 
 
 
 
143
  // Get the spam total (ignoring any search query or filter).
144
  $spams = bp_activity_get( array(
145
  'display_comments' => 'stream',
@@ -160,7 +171,6 @@ class BP_Activity_List_Table extends WP_List_Table {
160
  'search_terms' => $search_terms,
161
  'filter_query' => $filter_query,
162
  'show_hidden' => true,
163
- // 'sort' => $sort,
164
  'spam' => $spam,
165
  'count_total' => 'count_query',
166
  ) );
@@ -184,7 +194,7 @@ class BP_Activity_List_Table extends WP_List_Table {
184
  }
185
 
186
  // Set raw data to display.
187
- $this->items = $new_activities;
188
 
189
  // Store information needed for handling table pagination.
190
  $this->set_pagination_args( array(
@@ -195,6 +205,25 @@ class BP_Activity_List_Table extends WP_List_Table {
195
 
196
  // Don't truncate activity items; bp_activity_truncate_entry() needs to be used inside a BP_Activity_Template loop.
197
  remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  }
199
 
200
  /**
@@ -309,12 +338,34 @@ class BP_Activity_List_Table extends WP_List_Table {
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>
317
- <li class="spam"><a href="<?php echo esc_url( add_query_arg( array( 'activity_status' => 'spam' ), $url_base ) ); ?>" class="<?php if ( 'spam' == $this->view ) echo 'current'; ?>"><?php printf( __( 'Spam <span class="count">(%s)</span>', 'buddypress' ), number_format_i18n( $this->spam_count ) ); ?></a></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
 
319
  <?php
320
 
@@ -553,6 +604,7 @@ class BP_Activity_List_Table extends WP_List_Table {
553
  if ( isset( $actions[ $item['type'] ] ) ) {
554
  echo $actions[ $item['type'] ];
555
  } else {
 
556
  printf( __( 'Unregistered action - %s', 'buddypress' ), $item['type'] );
557
  }
558
  }
@@ -645,21 +697,20 @@ class BP_Activity_List_Table extends WP_List_Table {
645
  // End timestamp.
646
  echo '</div>';
647
 
 
 
648
  // Get activity content - if not set, use the action.
649
  if ( ! empty( $item['content'] ) ) {
650
- $activity = new BP_Activity_Activity( $item['id'] );
651
-
652
  /** This filter is documented in bp-activity/bp-activity-template.php */
653
  $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'], &$activity ) );
654
  } else {
655
- /**
656
- * Filters current activity item action.
657
- *
658
- * @since 1.2.0
659
- *
660
- * @var array $item Array index holding current activity item action.
661
- */
662
- $content = apply_filters_ref_array( 'bp_get_activity_action', array( $item['action'] ) );
663
  }
664
 
665
  /**
38
  */
39
  public $spam_count = 0;
40
 
41
+ /**
42
+ * Total number of activities.
43
+ *
44
+ * @since 6.0.0
45
+ * @var int $all_count
46
+ */
47
+ public $all_count = 0;
48
+
49
  /**
50
  * Store activity-to-user-ID mappings for use in the In Response To column.
51
  *
105
  $per_page = $this->get_items_per_page( str_replace( '-', '_', "{$this->screen->id}_per_page" ) );
106
 
107
  // Check if we're on the "Spam" view.
108
+ if ( ! empty( $_REQUEST['activity_status'] ) && 'spam' === $_REQUEST['activity_status'] ) {
109
  $spam = 'spam_only';
110
  $this->view = 'spam';
111
  }
112
 
 
 
 
 
 
 
 
 
113
  // Filter.
114
  if ( ! empty( $_REQUEST['activity_type'] ) ) {
115
  $filter = array( 'action' => $_REQUEST['activity_type'] );
116
 
117
+ // Set the view as a filtered one.
118
+ $this->view = 'filtered';
119
+
120
  /**
121
  * Filter here to override the filter with a filter query
122
  *
127
  $has_filter_query = apply_filters( 'bp_activity_list_table_filter_activity_type_items', $filter );
128
 
129
  if ( ! empty( $has_filter_query['filter_query'] ) ) {
130
+ // Reset the filter.
131
  $filter = array();
132
 
133
+ // And use the filter query instead.
134
  $filter_query = $has_filter_query['filter_query'];
135
  }
136
  }
137
 
138
  // Are we doing a search?
139
+ if ( ! empty( $_REQUEST['s'] ) ) {
140
  $search_terms = $_REQUEST['s'];
141
 
142
+ // Set the view as a search request.
143
+ $this->view = 'search';
144
+ }
145
+
146
  // Check if user has clicked on a specific activity (if so, fetch only that, and any related, activity).
147
+ if ( ! empty( $_REQUEST['aid'] ) ) {
148
  $include_id = (int) $_REQUEST['aid'];
149
 
150
+ // Set the view as a single activity.
151
+ $this->view = 'single';
152
+ }
153
+
154
  // Get the spam total (ignoring any search query or filter).
155
  $spams = bp_activity_get( array(
156
  'display_comments' => 'stream',
171
  'search_terms' => $search_terms,
172
  'filter_query' => $filter_query,
173
  'show_hidden' => true,
 
174
  'spam' => $spam,
175
  'count_total' => 'count_query',
176
  ) );
194
  }
195
 
196
  // Set raw data to display.
197
+ $this->items = $new_activities;
198
 
199
  // Store information needed for handling table pagination.
200
  $this->set_pagination_args( array(
205
 
206
  // Don't truncate activity items; bp_activity_truncate_entry() needs to be used inside a BP_Activity_Template loop.
207
  remove_filter( 'bp_get_activity_content_body', 'bp_activity_truncate_entry', 5 );
208
+
209
+ // Set the Total number of activities.
210
+ if ( 'all' === $this->view ) {
211
+ $this->all_count = (int) $activities['total'];
212
+
213
+ // Only perform a query if not on the main list view.
214
+ } elseif ( 'single' !== $this->view ) {
215
+ $count_activities = bp_activity_get(
216
+ array(
217
+ 'fields' => 'ids',
218
+ 'show_hidden' => true,
219
+ 'count_total' => 'count_query',
220
+ )
221
+ );
222
+
223
+ if ( $count_activities['total'] ) {
224
+ $this->all_count = (int) $count_activities['total'];
225
+ }
226
+ }
227
  }
228
 
229
  /**
338
 
339
  <h2 class="screen-reader-text"><?php
340
  /* translators: accessibility text */
341
+ esc_html_e( 'Filter activities list', 'buddypress' );
342
  ?></h2>
343
 
344
  <ul class="subsubsub">
345
+ <li class="all">
346
+ <a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( 'all' === $this->view ) echo 'current'; ?>">
347
+ <?php printf(
348
+ /* translators: %s is the placeholder for the count html tag `<span class="count"/>` */
349
+ esc_html__( 'All %s', 'buddypress' ),
350
+ sprintf(
351
+ '<span class="count">(%s)</span>',
352
+ number_format_i18n( $this->all_count )
353
+ )
354
+ ); ?>
355
+ </a> |
356
+ </li>
357
+ <li class="spam">
358
+ <a href="<?php echo esc_url( add_query_arg( array( 'activity_status' => 'spam' ), $url_base ) ); ?>" class="<?php if ( 'spam' === $this->view ) echo 'current'; ?>">
359
+ <?php printf(
360
+ /* translators: %s is the placeholder for the count html tag `<span class="count"/>` */
361
+ esc_html__( 'Spam %s', 'buddypress' ),
362
+ sprintf(
363
+ '<span class="count">(%s)</span>',
364
+ number_format_i18n( $this->spam_count )
365
+ )
366
+ ); ?>
367
+ </a>
368
+ </li>
369
 
370
  <?php
371
 
604
  if ( isset( $actions[ $item['type'] ] ) ) {
605
  echo $actions[ $item['type'] ];
606
  } else {
607
+ /* translators: %s: the name of the activity type */
608
  printf( __( 'Unregistered action - %s', 'buddypress' ), $item['type'] );
609
  }
610
  }
697
  // End timestamp.
698
  echo '</div>';
699
 
700
+ $activity = new BP_Activity_Activity( $item['id'] );
701
+
702
  // Get activity content - if not set, use the action.
703
  if ( ! empty( $item['content'] ) ) {
 
 
704
  /** This filter is documented in bp-activity/bp-activity-template.php */
705
  $content = apply_filters_ref_array( 'bp_get_activity_content_body', array( $item['content'], &$activity ) );
706
  } else {
707
+ // Emulate bp_get_activity_action().
708
+ $r = array(
709
+ 'no_timestamp' => false,
710
+ );
711
+
712
+ /** This filter is documented in bp-activity/bp-activity-template.php */
713
+ $content = apply_filters_ref_array( 'bp_get_activity_action', array( $item['action'], &$activity, $r ) );
 
714
  }
715
 
716
  /**
bp-activity/classes/class-bp-akismet.php CHANGED
@@ -92,10 +92,13 @@ class BP_Akismet {
92
  } else {
93
  $who = bp_activity_get_meta( $activity['id'], '_bp_akismet_user' );
94
 
95
- if ( 'true' == $user_result )
 
96
  $desc = sprintf( __( 'Flagged as spam by %s', 'buddypress' ), $who );
97
- else
 
98
  $desc = sprintf( __( 'Un-spammed by %s', 'buddypress' ), $who );
 
99
  }
100
 
101
  // Add a History item to the hover links, just after Edit.
@@ -442,7 +445,16 @@ class BP_Akismet {
442
  if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
443
  return;
444
 
445
- $this->update_activity_history( $activity->id, sprintf( __( '%s reported this activity as spam', 'buddypress' ), bp_get_loggedin_user_username() ), 'report-spam' );
 
 
 
 
 
 
 
 
 
446
  bp_activity_update_meta( $activity->id, '_bp_akismet_user_result', 'true' );
447
  bp_activity_update_meta( $activity->id, '_bp_akismet_user', bp_get_loggedin_user_username() );
448
  }
@@ -459,7 +471,16 @@ class BP_Akismet {
459
  if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
460
  return;
461
 
462
- $this->update_activity_history( $activity->id, sprintf( __( '%s reported this activity as not spam', 'buddypress' ), bp_get_loggedin_user_username() ), 'report-ham' );
 
 
 
 
 
 
 
 
 
463
  bp_activity_update_meta( $activity->id, '_bp_akismet_user_result', 'false' );
464
  bp_activity_update_meta( $activity->id, '_bp_akismet_user', bp_get_loggedin_user_username() );
465
  }
@@ -493,7 +514,15 @@ class BP_Akismet {
493
  // Uh oh, something's gone horribly wrong. Unexpected result.
494
  } else {
495
  bp_activity_update_meta( $activity->id, '_bp_akismet_error', bp_core_current_time() );
496
- $this->update_activity_history( $activity->id, sprintf( __( 'Akismet was unable to check this item (response: %s), will automatically retry again later.', 'buddypress' ), $this->last_activity->akismet_submission['bp_as_result'] ), 'check-error' );
 
 
 
 
 
 
 
 
497
  }
498
 
499
  // Record the original data which was submitted to Akismet for checking.
@@ -618,6 +647,7 @@ class BP_Akismet {
618
  return;
619
 
620
  echo '<div class="akismet-history"><div>';
 
621
  printf( _x( '%1$s &mdash; %2$s', 'x hours ago - akismet cleared this item', 'buddypress' ), '<span>' . bp_core_time_since( $history[2] ) . '</span>', esc_html( $history[1] ) );
622
  echo '</div></div>';
623
  }
92
  } else {
93
  $who = bp_activity_get_meta( $activity['id'], '_bp_akismet_user' );
94
 
95
+ if ( 'true' == $user_result ) {
96
+ /* translators: %s: the name of the user */
97
  $desc = sprintf( __( 'Flagged as spam by %s', 'buddypress' ), $who );
98
+ } else {
99
+ /* translators: %s: the name of the user */
100
  $desc = sprintf( __( 'Un-spammed by %s', 'buddypress' ), $who );
101
+ }
102
  }
103
 
104
  // Add a History item to the hover links, just after Edit.
445
  if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
446
  return;
447
 
448
+ $this->update_activity_history(
449
+ $activity->id,
450
+ sprintf(
451
+ /* translators: %s: the current user username */
452
+ __( '%s reported this activity as spam', 'buddypress' ),
453
+ bp_get_loggedin_user_username()
454
+ ),
455
+ 'report-spam'
456
+ );
457
+
458
  bp_activity_update_meta( $activity->id, '_bp_akismet_user_result', 'true' );
459
  bp_activity_update_meta( $activity->id, '_bp_akismet_user', bp_get_loggedin_user_username() );
460
  }
471
  if ( !in_array( $activity->type, BP_Akismet::get_activity_types() ) )
472
  return;
473
 
474
+ $this->update_activity_history(
475
+ $activity->id,
476
+ sprintf(
477
+ /* translators: %s: the current user username */
478
+ __( '%s reported this activity as not spam', 'buddypress' ),
479
+ bp_get_loggedin_user_username()
480
+ ),
481
+ 'report-ham'
482
+ );
483
+
484
  bp_activity_update_meta( $activity->id, '_bp_akismet_user_result', 'false' );
485
  bp_activity_update_meta( $activity->id, '_bp_akismet_user', bp_get_loggedin_user_username() );
486
  }
514
  // Uh oh, something's gone horribly wrong. Unexpected result.
515
  } else {
516
  bp_activity_update_meta( $activity->id, '_bp_akismet_error', bp_core_current_time() );
517
+ $this->update_activity_history(
518
+ $activity->id,
519
+ sprintf(
520
+ /* translators: %s the akismet result */
521
+ __( 'Akismet was unable to check this item (response: %s), will automatically retry again later.', 'buddypress' ),
522
+ $this->last_activity->akismet_submission['bp_as_result']
523
+ ),
524
+ 'check-error'
525
+ );
526
  }
527
 
528
  // Record the original data which was submitted to Akismet for checking.
647
  return;
648
 
649
  echo '<div class="akismet-history"><div>';
650
+ /* translators: 1: the human diff time. 2: the akismet history data. */
651
  printf( _x( '%1$s &mdash; %2$s', 'x hours ago - akismet cleared this item', 'buddypress' ), '<span>' . bp_core_time_since( $history[2] ) . '</span>', esc_html( $history[1] ) );
652
  echo '</div></div>';
653
  }
bp-activity/classes/class-bp-rest-activity-endpoint.php CHANGED
@@ -140,6 +140,7 @@ class BP_REST_Activity_Endpoint extends WP_REST_Controller {
140
  'display_comments' => $request['display_comments'],
141
  'site_id' => $request['site_id'],
142
  'group_id' => $request['group_id'],
 
143
  'count_total' => true,
144
  'fields' => 'all',
145
  'show_hidden' => false,
@@ -193,6 +194,10 @@ class BP_REST_Activity_Endpoint extends WP_REST_Controller {
193
  }
194
  }
195
 
 
 
 
 
196
  if ( isset( $request['type'] ) ) {
197
  $args['filter']['action'] = $request['type'];
198
  }
@@ -278,6 +283,16 @@ class BP_REST_Activity_Endpoint extends WP_REST_Controller {
278
  public function get_item( $request ) {
279
  $activity = $this->get_activity_object( $request );
280
 
 
 
 
 
 
 
 
 
 
 
281
  $retval = array(
282
  $this->prepare_response_for_collection(
283
  $this->prepare_item_for_response( $activity, $request )
@@ -1391,7 +1406,7 @@ class BP_REST_Activity_Endpoint extends WP_REST_Controller {
1391
 
1392
  $avatar_properties['full'] = array(
1393
  'context' => array( 'view', 'edit' ),
1394
- /* translators: Full image size for the member Avatar */
1395
  'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),
1396
  'type' => 'string',
1397
  'format' => 'uri',
@@ -1399,7 +1414,7 @@ class BP_REST_Activity_Endpoint extends WP_REST_Controller {
1399
 
1400
  $avatar_properties['thumb'] = array(
1401
  'context' => array( 'view', 'edit' ),
1402
- /* translators: Thumb imaze size for the member Avatar */
1403
  'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),
1404
  'type' => 'string',
1405
  'format' => 'uri',
@@ -1484,6 +1499,14 @@ class BP_REST_Activity_Endpoint extends WP_REST_Controller {
1484
  'validate_callback' => 'rest_validate_request_arg',
1485
  );
1486
 
 
 
 
 
 
 
 
 
1487
  $params['group_id'] = array(
1488
  'description' => __( 'Limit result set to items created by a specific group.', 'buddypress' ),
1489
  'default' => 0,
140
  'display_comments' => $request['display_comments'],
141
  'site_id' => $request['site_id'],
142
  'group_id' => $request['group_id'],
143
+ 'scope' => $request['scope'],
144
  'count_total' => true,
145
  'fields' => 'all',
146
  'show_hidden' => false,
194
  }
195
  }
196
 
197
+ if ( empty( $request['scope'] ) ) {
198
+ $args['scope'] = false;
199
+ }
200
+
201
  if ( isset( $request['type'] ) ) {
202
  $args['filter']['action'] = $request['type'];
203
  }
283
  public function get_item( $request ) {
284
  $activity = $this->get_activity_object( $request );
285
 
286
+ if ( empty( $activity->id ) ) {
287
+ return new WP_Error(
288
+ 'bp_rest_invalid_id',
289
+ __( 'Invalid activity ID.', 'buddypress' ),
290
+ array(
291
+ 'status' => 404,
292
+ )
293
+ );
294
+ }
295
+
296
  $retval = array(
297
  $this->prepare_response_for_collection(
298
  $this->prepare_item_for_response( $activity, $request )
1406
 
1407
  $avatar_properties['full'] = array(
1408
  'context' => array( 'view', 'edit' ),
1409
+ /* translators: 1: Full avatar width in pixels. 2: Full avatar height in pixels */
1410
  'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),
1411
  'type' => 'string',
1412
  'format' => 'uri',
1414
 
1415
  $avatar_properties['thumb'] = array(
1416
  'context' => array( 'view', 'edit' ),
1417
+ /* translators: 1: Thumb avatar width in pixels. 2: Thumb avatar height in pixels */
1418
  'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),
1419
  'type' => 'string',
1420
  'format' => 'uri',
1499
  'validate_callback' => 'rest_validate_request_arg',
1500
  );
1501
 
1502
+ $params['scope'] = array(
1503
+ 'description' => __( 'Limit result set to items with a specific scope.', 'buddypress' ),
1504
+ 'type' => 'string',
1505
+ 'enum' => array( 'just-me', 'friends', 'groups', 'favorites', 'mentions' ),
1506
+ 'sanitize_callback' => 'sanitize_text_field',
1507
+ 'validate_callback' => 'rest_validate_request_arg',
1508
+ );
1509
+
1510
  $params['group_id'] = array(
1511
  'description' => __( 'Limit result set to items created by a specific group.', 'buddypress' ),
1512
  'default' => 0,
bp-activity/js/mentions.js CHANGED
@@ -87,7 +87,7 @@ window.bp = window.bp || {};
87
  * @since 2.1.0
88
  */
89
  before_reposition: function( offset ) {
90
- // get the iframe, if any, already applied with atwho
91
  var caret,
92
  line,
93
  iframeOffset,
@@ -109,7 +109,7 @@ window.bp = window.bp || {};
109
  caret = this.$inputor.caret( 'offset' );
110
  }
111
 
112
- // If the caret is past horizontal half, then flip it, yo
113
  if ( caret.left > ( $body.width() / 2 ) ) {
114
  $view.addClass( 'right' );
115
  move = caret.left - offset.left - this.view.$el.width();
@@ -118,15 +118,15 @@ window.bp = window.bp || {};
118
  move = caret.left - offset.left + 1;
119
  }
120
 
121
- // If we're on a small screen, scroll to caret
122
  if ( $body.width() <= 400 ) {
123
  $( document ).scrollTop( caret.top - 6 );
124
  }
125
 
126
- // New position is under the caret (never above) and positioned to follow
127
- // Dynamic sizing based on the input area (remove 'px' from end)
128
  line = parseInt( this.$inputor.css( 'line-height' ).substr( 0, this.$inputor.css( 'line-height' ).length - 2 ), 10 );
129
- if ( !line || line < 5 ) { // sanity check, and catch no line-height
130
  line = 19;
131
  }
132
 
@@ -135,11 +135,11 @@ window.bp = window.bp || {};
135
  },
136
 
137
  /**
138
- * Override default behaviour which inserts junk tags in the WordPress Visual editor.
139
  *
140
  * @param {unknown} $inputor Element which we're inserting content into.
141
- * @param {string) content The content that will be inserted.
142
- * @param {string) suffix Applied to the end of the content string.
143
  * @return {string}
144
  * @since 2.1.0
145
  */
87
  * @since 2.1.0
88
  */
89
  before_reposition: function( offset ) {
90
+ // get the iframe, if any, already applied with atwho.js library.
91
  var caret,
92
  line,
93
  iframeOffset,
109
  caret = this.$inputor.caret( 'offset' );
110
  }
111
 
112
+ // If the caret is past horizontal half, then flip it, yo.
113
  if ( caret.left > ( $body.width() / 2 ) ) {
114
  $view.addClass( 'right' );
115
  move = caret.left - offset.left - this.view.$el.width();
118
  move = caret.left - offset.left + 1;
119
  }
120
 
121
+ // If we're on a small screen, scroll to caret.
122
  if ( $body.width() <= 400 ) {
123
  $( document ).scrollTop( caret.top - 6 );
124
  }
125
 
126
+ // New position is under the caret (never above) and positioned to follow.
127
+ // Dynamic sizing based on the input area (remove 'px' from end).
128
  line = parseInt( this.$inputor.css( 'line-height' ).substr( 0, this.$inputor.css( 'line-height' ).length - 2 ), 10 );
129
+ if ( !line || line < 5 ) { // Sanity check, and catch no line-height.
130
  line = 19;
131
  }
132
 
135
  },
136
 
137
  /**
138
+ * Override default behavior which inserts junk tags in the WordPress Visual editor.
139
  *
140
  * @param {unknown} $inputor Element which we're inserting content into.
141
+ * @param {string} content The content that will be inserted.
142
+ * @param {string} suffix Applied to the end of the content string.
143
  * @return {string}
144
  * @since 2.1.0
145
  */
bp-activity/screens/permalink.php CHANGED
@@ -26,7 +26,7 @@ function bp_activity_action_permalink_router() {
26
  // Get the activity details.
27
  $activity = bp_activity_get_specific( array( 'activity_ids' => bp_action_variable( 0 ), 'show_hidden' => true ) );
28
 
29
- // 404 if activity does not exist
30
  if ( empty( $activity['activities'][0] ) ) {
31
  bp_do_404();
32
  return;
@@ -106,7 +106,7 @@ function bp_activity_screen_single_activity_permalink() {
106
  'spam' => 'ham_only',
107
  ) );
108
 
109
- // 404 if activity does not exist
110
  if ( empty( $activity['activities'][0] ) || bp_action_variables() ) {
111
  bp_do_404();
112
  return;
26
  // Get the activity details.
27
  $activity = bp_activity_get_specific( array( 'activity_ids' => bp_action_variable( 0 ), 'show_hidden' => true ) );
28
 
29
+ // 404 if activity does not exist.
30
  if ( empty( $activity['activities'][0] ) ) {
31
  bp_do_404();
32
  return;
106
  'spam' => 'ham_only',
107
  ) );
108
 
109
+ // 404 if activity does not exist.
110
  if ( empty( $activity['activities'][0] ) || bp_action_variables() ) {
111
  bp_do_404();
112
  return;
bp-blogs/bp-blogs-activity.php CHANGED
@@ -127,7 +127,12 @@ function bp_blogs_format_activity_action_new_blog( $action, $activity ) {
127
  $blog_url = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
128
  $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
129
 
130
- $action = sprintf( esc_html__( '%s created the site %s', 'buddypress' ), bp_core_get_userlink( $activity->user_id ), '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' );
 
 
 
 
 
131
 
132
  // Legacy filter - requires the BP_Blogs_Blog object.
133
  if ( has_filter( 'bp_blogs_activity_created_blog_action' ) ) {
@@ -230,15 +235,26 @@ function bp_blogs_format_activity_action_new_blog_post( $action, $activity ) {
230
  }
231
 
232
  // Build the 'post link' part of the activity action string.
233
- $post_link = '<a href="' . esc_url( $post_url ) . '">' . esc_html( $post_title ) . '</a>';
234
 
235
  $user_link = bp_core_get_userlink( $activity->user_id );
236
 
237
  // Build the complete activity action string.
238
  if ( is_multisite() ) {
239
- $action = sprintf( esc_html__( '%1$s wrote a new post, %2$s, on the site %3$s', 'buddypress' ), $user_link, $post_link, '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' );
 
 
 
 
 
 
240
  } else {
241
- $action = sprintf( esc_html__( '%1$s wrote a new post, %2$s', 'buddypress' ), $user_link, $post_link );
 
 
 
 
 
242
  }
243
 
244
  // Legacy filter - requires the post object.
@@ -287,7 +303,7 @@ function bp_blogs_format_activity_action_new_blog_comment( $action, $activity )
287
 
288
  $blog_url = false;
289
 
290
- // Try to get the blog url from the activity object
291
  if ( isset( $activity->blog_url ) ) {
292
  $blog_url = $activity->blog_url;
293
  } else {
@@ -296,7 +312,7 @@ function bp_blogs_format_activity_action_new_blog_comment( $action, $activity )
296
 
297
  $blog_name = false;
298
 
299
- // Try to get the blog name from the activity object
300
  if ( isset( $activity->blog_name ) ) {
301
  $blog_name = $activity->blog_name;
302
  } else {
@@ -313,7 +329,7 @@ function bp_blogs_format_activity_action_new_blog_comment( $action, $activity )
313
 
314
  $post_url = false;
315
 
316
- // Try to get the post url from the activity object
317
  if ( isset( $activity->post_url ) ) {
318
  $post_url = $activity->post_url;
319
 
@@ -328,11 +344,11 @@ function bp_blogs_format_activity_action_new_blog_comment( $action, $activity )
328
 
329
  $post_title = false;
330
 
331
- // Should be the case when the comment has just been published
332
  if ( isset( $activity->post_title ) ) {
333
  $post_title = $activity->post_title;
334
 
335
- // If activity already exists try to get the post title from activity meta
336
  } elseif ( ! empty( $activity->id ) ) {
337
  $post_title = bp_activity_get_meta( $activity->id, 'post_title' );
338
  }
@@ -362,9 +378,20 @@ function bp_blogs_format_activity_action_new_blog_comment( $action, $activity )
362
  $user_link = bp_core_get_userlink( $activity->user_id );
363
 
364
  if ( is_multisite() ) {
365
- $action = sprintf( esc_html__( '%1$s commented on the post, %2$s, on the site %3$s', 'buddypress' ), $user_link, $post_link, '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>' );
 
 
 
 
 
 
366
  } else {
367
- $action = sprintf( esc_html__( '%1$s commented on the post, %2$s', 'buddypress' ), $user_link, $post_link );
 
 
 
 
 
368
  }
369
 
370
  // Legacy filter - requires the comment object.
@@ -789,7 +816,7 @@ function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_
789
  $user = bp_core_get_core_userdata( $params['user_id'] );
790
  }
791
 
792
- // Get associated post type and set default comment parent
793
  $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
794
  $comment_parent = 0;
795
 
@@ -805,7 +832,7 @@ function bp_blogs_sync_add_from_activity_comment( $comment_id, $params, $parent_
805
  'comment_author_email' => $user->user_email,
806
  'comment_author_url' => bp_core_get_user_domain( $params['user_id'], $user->user_nicename, $user->user_login ),
807
  'comment_content' => $params['content'],
808
- 'comment_type' => '', // Could be interesting to add 'buddypress' here...
809
  'comment_parent' => (int) $comment_parent,
810
  'user_id' => $params['user_id'],
811
  'comment_approved' => 1
@@ -909,7 +936,7 @@ function bp_blogs_sync_delete_from_activity_comment( $retval, $parent_activity_i
909
  $activity_ids = bp_activity_recurse_comments_activity_ids( $activity );
910
  $activity_ids[] = $activity_id;
911
 
912
- // Handle multisite
913
  // switch to the blog where the comment was made.
914
  switch_to_blog( $parent_activity->item_id );
915
 
@@ -923,7 +950,7 @@ function bp_blogs_sync_delete_from_activity_comment( $retval, $parent_activity_i
923
  // emulate bp_activity_delete_comment().
924
  BP_Activity_Activity::rebuild_activity_comment_tree( $parent_activity_id );
925
 
926
- // Avoid the error message although the comments were successfully deleted
927
  $deleted = true;
928
 
929
  // We're overriding the default bp_activity_delete_comment() functionality
@@ -946,10 +973,10 @@ function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $acti
946
  return;
947
  }
948
 
949
- // fetch parent activity item
950
  $parent_activity = new BP_Activity_Activity( $activity->item_id );
951
 
952
- // if parent activity isn't a post type having the buddypress-activity support for comments, stop now!
953
  if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
954
  return;
955
  }
@@ -971,11 +998,11 @@ function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $acti
971
  // Handle multisite.
972
  switch_to_blog( $parent_activity->item_id );
973
 
974
- // Get the comment status
975
  $post_comment_status = wp_get_comment_status( $post_comment_id );
976
  $old_comment_status = $post_comment_status;
977
 
978
- // No need to edit the activity, as it's the activity who's updating the comment
979
  remove_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10 );
980
  remove_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10 );
981
 
@@ -995,7 +1022,7 @@ function bp_blogs_sync_activity_edit_to_post_comment( BP_Activity_Activity $acti
995
  }
996
  }
997
 
998
- // Restore actions
999
  add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
1000
  add_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10, 4 );
1001
 
@@ -1054,15 +1081,15 @@ function bp_blogs_new_blog_comment_query_backpat( $args ) {
1054
  return $args;
1055
  }
1056
 
1057
- // Get the associated post type
1058
  $post_type = bp_activity_post_type_get_tracking_arg( $args['action'], 'post_type' );
1059
 
1060
- // Bail if this is not an activity associated with a post type
1061
  if ( empty( $post_type ) ) {
1062
  return $args;
1063
  }
1064
 
1065
- // Bail if this is an activity about posts and not comments
1066
  if ( bp_activity_post_type_get_tracking_arg( $args['action'], 'comment_action_id' ) ) {
1067
  return $args;
1068
  }
@@ -1235,7 +1262,7 @@ function bp_blogs_disable_activity_commenting( $retval ) {
1235
 
1236
  // It's a post type supporting comment tracking.
1237
  if ( bp_activity_type_supports( $type, 'post-type-comment-tracking' ) ) {
1238
- // The activity type is supporting comments or replies
1239
  if ( bp_activity_type_supports( $type, 'post-type-comment-reply' ) ) {
1240
  // Setup some globals we'll need to reference later.
1241
  bp_blogs_setup_activity_loop_globals( $activities_template->activity );
@@ -1250,7 +1277,7 @@ function bp_blogs_disable_activity_commenting( $retval ) {
1250
  if ( isset( buddypress()->blogs->comment_moderation[ bp_get_activity_id() ] ) && buddypress()->blogs->comment_moderation[ bp_get_activity_id() ] ) {
1251
  $retval = false;
1252
  }
1253
- // The activity type does not support comments or replies
1254
  } else {
1255
  $retval = false;
1256
  }
@@ -1285,7 +1312,7 @@ function bp_blogs_post_type_comments_avoid_duplicates( $retval ) {
1285
  return $retval;
1286
  }
1287
 
1288
- // Check the parent activity
1289
  $parent_activity = new BP_Activity_Activity( bp_get_activity_item_id() );
1290
 
1291
  if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
@@ -1438,15 +1465,15 @@ function bp_blogs_activity_comment_single_action( $retval, $activity ) {
1438
  if ( ! empty( $blog_comment_id ) ) {
1439
  $bp = buddypress();
1440
 
1441
- // Check if a comment action id is set for the parent activity
1442
  $comment_action_id = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'comment_action_id' );
1443
 
1444
- // Use the action string callback for the activity type
1445
  if ( ! empty( $comment_action_id ) ) {
1446
  // Fake a 'new_{post_type}_comment' by cloning the activity object.
1447
  $object = clone $activity;
1448
 
1449
- // Set the type of the activity to be a comment about a post type
1450
  $object->type = $comment_action_id;
1451
 
1452
  // Use the blog ID as the item_id.
@@ -1455,10 +1482,10 @@ function bp_blogs_activity_comment_single_action( $retval, $activity ) {
1455
  // Use comment ID as the secondary_item_id.
1456
  $object->secondary_item_id = $blog_comment_id;
1457
 
1458
- // Get the format callback for this activity comment
1459
  $format_callback = bp_activity_post_type_get_tracking_arg( $comment_action_id, 'format_callback' );
1460
 
1461
- // now format the activity action using the 'new_{post_type}_comment' action callback
1462
  if ( is_callable( $format_callback ) ) {
1463
  $retval = call_user_func_array( $format_callback, array( '', $object ) );
1464
  }
127
  $blog_url = bp_blogs_get_blogmeta( $activity->item_id, 'url' );
128
  $blog_name = bp_blogs_get_blogmeta( $activity->item_id, 'name' );
129
 
130
+ $action = sprintf(
131
+ /* translators: 1: the activity user link. 2: the blog link. */
132
+ esc_html__( '%1$s created the site %2$s', 'buddypress' ),
133
+ bp_core_get_userlink( $activity->user_id ),
134
+ '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>'
135
+ );
136
 
137
  // Legacy filter - requires the BP_Blogs_Blog object.
138
  if ( has_filter( 'bp_blogs_activity_created_blog_action' ) ) {
235
  }
236
 
237
  // Build the 'post link' part of the activity action string.
238
+ $post_link = '<a href="' . esc_url( $post_url ) . '">' . esc_html( $post_title ) . '</a>';
239
 
240
  $user_link = bp_core_get_userlink( $activity->user_id );
241
 
242
  // Build the complete activity action string.
243
  if ( is_multisite() ) {
244
+ $action = sprintf(
245
+ /* translators: 1: the activity user link. 2: the post link. 3: the blog link. */
246
+ esc_html_x( '%1$s wrote a new post, %2$s, on the site %3$s', '`new_blog_post` activity action', 'buddypress' ),
247
+ $user_link,
248
+ $post_link,
249
+ '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>'
250
+ );
251
  } else {
252
+ $action = sprintf(
253
+ /* translators: 1: the activity user link. 2: the post link. */
254
+ esc_html_x( '%1$s wrote a new post, %2$s', '`new_blog_post` activity action', 'buddypress' ),
255
+ $user_link,
256
+ $post_link
257
+ );
258
  }
259
 
260
  // Legacy filter - requires the post object.
303
 
304
  $blog_url = false;
305
 
306
+ // Try to get the blog url from the activity object.
307
  if ( isset( $activity->blog_url ) ) {
308
  $blog_url = $activity->blog_url;
309
  } else {
312
 
313
  $blog_name = false;
314
 
315
+ // Try to get the blog name from the activity object.
316
  if ( isset( $activity->blog_name ) ) {
317
  $blog_name = $activity->blog_name;
318
  } else {
329
 
330
  $post_url = false;
331
 
332
+ // Try to get the post url from the activity object.
333
  if ( isset( $activity->post_url ) ) {
334
  $post_url = $activity->post_url;
335
 
344
 
345
  $post_title = false;
346
 
347
+ // Should be the case when the comment has just been published.
348
  if ( isset( $activity->post_title ) ) {
349
  $post_title = $activity->post_title;
350
 
351
+ // If activity already exists try to get the post title from activity meta.
352
  } elseif ( ! empty( $activity->id ) ) {
353
  $post_title = bp_activity_get_meta( $activity->id, 'post_title' );
354
  }
378
  $user_link = bp_core_get_userlink( $activity->user_id );
379
 
380
  if ( is_multisite() ) {
381
+ $action = sprintf(
382
+ /* translators: 1: the activity user link. 2: the post link. 3: the blog link. */
383
+ esc_html_x( '%1$s commented on the post, %2$s, on the site %3$s', '`new_blog_comment` activity action', 'buddypress' ),
384
+ $user_link,
385
+ $post_link,
386
+ '<a href="' . esc_url( $blog_url ) . '">' . esc_html( $blog_name ) . '</a>'
387
+ );
388
  } else {
389
+ $action = sprintf(
390
+ /* translators: 1: the activity user link. 2: the post link. */
391
+ esc_html_x( '%1$s commented on the post, %2$s', '`new_blog_comment` activity action', 'buddypress' ),
392
+ $user_link,
393
+ $post_link
394
+ );
395
  }
396
 
397
  // Legacy filter - requires the comment object.
816
  $user = bp_core_get_core_userdata( $params['user_id'] );
817
  }
818
 
819
+ // Get associated post type and set default comment parent.
820
  $post_type = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' );
821
  $comment_parent = 0;
822
 
832
  'comment_author_email' => $user->user_email,
833
  'comment_author_url' => bp_core_get_user_domain( $params['user_id'], $user->user_nicename, $user->user_login ),
834
  'comment_content' => $params['content'],
835
+ 'comment_type' => '', // Could be interesting to add 'BuddyPress' here...
836
  'comment_parent' => (int) $comment_parent,
837
  'user_id' => $params['user_id'],
838
  'comment_approved' => 1
936
  $activity_ids = bp_activity_recurse_comments_activity_ids( $activity );
937
  $activity_ids[] = $activity_id;
938
 
939
+ // Handle multisite.
940
  // switch to the blog where the comment was made.
941
  switch_to_blog( $parent_activity->item_id );
942
 
950
  // emulate bp_activity_delete_comment().
951
  BP_Activity_Activity::rebuild_activity_comment_tree( $parent_activity_id );
952
 
953
+ // Avoid the error message although the comments were successfully deleted.
954
  $deleted = true;
955
 
956
  // We're overriding the default bp_activity_delete_comment() functionality
973
  return;
974
  }
975
 
976
+ // Fetch parent activity item.
977
  $parent_activity = new BP_Activity_Activity( $activity->item_id );
978
 
979
+ // If parent activity isn't a post type having the buddypress-activity support for comments, stop now!
980
  if ( ! bp_activity_type_supports( $parent_activity->type, 'post-type-comment-tracking' ) ) {
981
  return;
982
  }
998
  // Handle multisite.
999
  switch_to_blog( $parent_activity->item_id );
1000
 
1001
+ // Get the comment status.
1002
  $post_comment_status = wp_get_comment_status( $post_comment_id );
1003
  $old_comment_status = $post_comment_status;
1004
 
1005
+ // No need to edit the activity, as it's the activity who's updating the comment.
1006
  remove_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10 );
1007
  remove_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10 );
1008
 
1022
  }
1023
  }
1024
 
1025
+ // Restore actions.
1026
  add_action( 'transition_comment_status', 'bp_activity_transition_post_type_comment_status', 10, 3 );
1027
  add_action( 'bp_activity_post_type_comment', 'bp_blogs_comment_sync_activity_comment', 10, 4 );
1028
 
1081
  return $args;
1082
  }
1083
 
1084
+ // Get the associated post type.
1085
  $post_type = bp_activity_post_type_get_tracking_arg( $args['action'], 'post_type' );
1086
 
1087
+ // Bail if this is not an activity associated with a post type.
1088
  if ( empty( $post_type ) ) {
1089
  return $args;
1090
  }
1091
 
1092
+ // Bail if this is an activity about posts and not comments.
1093
  if ( bp_activity_post_type_get_tracking_arg( $args['action'], 'comment_action_id' ) ) {
1094
  return $args;
1095
  }
1262
 
1263
  // It's a post type supporting comment tracking.
1264
  if ( bp_activity_type_supports( $type, 'post-type-comment-tracking' ) ) {
1265
+ // The activity type is supporting comments or replies.
1266
  if ( bp_activity_type_supports( $type, 'post-type-comment-reply' ) ) {
1267
  // Setup some globals we'll need to reference later.
1268
  bp_blogs_setup_activity_loop_globals( $activities_template->activity );
1277
  if ( isset( buddypress()->blogs->comment_moderation[ bp_get_activity_id() ] ) && buddypress()->blogs->comment_moderation[ bp_get_activity_id() ] ) {
1278
  $retval = false;
1279
  }
1280
+ // The activity type does not support comments or replies.
1281
  } else {
1282
  $retval = false;
1283
  }
1312
  return $retval;
1313
  }
1314
 
1315
+ // Check the parent activity.
1316
  $parent_activity = new BP_Activity_Activity( bp_get_activity_item_id() );
1317
 
1318
  if ( isset( $parent_activity->type ) && bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'post_type' ) ) {
1465
  if ( ! empty( $blog_comment_id ) ) {
1466
  $bp = buddypress();
1467
 
1468
+ // Check if a comment action id is set for the parent activity.
1469
  $comment_action_id = bp_activity_post_type_get_tracking_arg( $parent_activity->type, 'comment_action_id' );
1470
 
1471
+ // Use the action string callback for the activity type.
1472
  if ( ! empty( $comment_action_id ) ) {
1473
  // Fake a 'new_{post_type}_comment' by cloning the activity object.
1474
  $object = clone $activity;
1475
 
1476
+ // Set the type of the activity to be a comment about a post type.
1477
  $object->type = $comment_action_id;
1478
 
1479
  // Use the blog ID as the item_id.
1482
  // Use comment ID as the secondary_item_id.
1483
  $object->secondary_item_id = $blog_comment_id;
1484
 
1485
+ // Get the format callback for this activity comment.
1486
  $format_callback = bp_activity_post_type_get_tracking_arg( $comment_action_id, 'format_callback' );
1487
 
1488
+ // Now format the activity action using the 'new_{post_type}_comment' action callback.
1489
  if ( is_callable( $format_callback ) ) {
1490
  $retval = call_user_func_array( $format_callback, array( '', $object ) );
1491
  }
bp-blogs/bp-blogs-cache.php CHANGED
@@ -53,7 +53,7 @@ function bp_blogs_clear_blog_object_cache( $blog_id = 0, $user_id = 0 ) {
53
 
54
  // List actions to clear object caches on.
55
  add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_clear_blog_object_cache', 10, 2 );
56
- add_action( 'wpmu_new_blog', 'bp_blogs_clear_blog_object_cache', 10, 2 );
57
  add_action( 'bp_blogs_remove_blog', 'bp_blogs_clear_blog_object_cache' );
58
 
59
  // List actions to clear super cached pages on, if super cache is installed.
53
 
54
  // List actions to clear object caches on.
55
  add_action( 'bp_blogs_remove_blog_for_user', 'bp_blogs_clear_blog_object_cache', 10, 2 );
56
+ add_action( 'bp_insert_site', 'bp_blogs_clear_blog_object_cache', 10, 2 );
57
  add_action( 'bp_blogs_remove_blog', 'bp_blogs_clear_blog_object_cache' );
58
 
59
  // List actions to clear super cached pages on, if super cache is installed.
bp-blogs/bp-blogs-functions.php CHANGED
@@ -45,13 +45,13 @@ function bp_blogs_get_blogs( $args = '' ) {
45
 
46
  // Parse query arguments.
47
  $r = bp_parse_args( $args, array(
48
- 'type' => 'active', // 'active', 'alphabetical', 'newest', or 'random'
49
- 'include_blog_ids' => false, // Array of blog IDs to include
50
- 'user_id' => false, // Limit to blogs this user can post to
51
- 'search_terms' => false, // Limit to blogs matching these search terms
52
- 'per_page' => 20, // The number of results to return per page
53
- 'page' => 1, // The page to return if limiting per page
54
- 'update_meta_cache' => true // Whether to pre-fetch blogmeta
55
  ), 'blogs_get_blogs' );
56
 
57
  // Get the blogs.
@@ -106,34 +106,34 @@ function bp_blogs_record_existing_blogs( $args = 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 ( bp_is_large_install() ) {
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})";
@@ -161,9 +161,9 @@ function bp_blogs_record_existing_blogs( $args = array() ) {
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
  }
@@ -192,24 +192,24 @@ function bp_blogs_record_existing_blogs( $args = array() ) {
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(
@@ -222,7 +222,7 @@ function bp_blogs_record_existing_blogs( $args = array() ) {
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
  }
@@ -411,7 +411,7 @@ function bp_blogs_record_blog( $blog_id, $user_id, $no_activity = false ) {
411
  */
412
  do_action_ref_array( 'bp_blogs_new_blog', array( &$recorded_blog, $is_private, $is_recorded, $no_activity ) );
413
  }
414
- add_action( 'wpmu_new_blog', 'bp_blogs_record_blog', 10, 2 );
415
 
416
  /**
417
  * Update blog name in BuddyPress blogmeta table.
@@ -726,14 +726,14 @@ function bp_blogs_comment_sync_activity_comment( &$activity_id, $comment = null,
726
  // Set the current blog id.
727
  $blog_id = get_current_blog_id();
728
 
729
- // These activity metadatas are used to build the new_blog_comment action string
730
  if ( ! empty( $activity_id ) && ! empty( $activity_args['item_id'] ) && 'new_blog_comment' === $activity_post_object->comment_action_id ) {
731
- // add some post info in activity meta
732
  bp_activity_update_meta( $activity_id, 'post_title', $comment->post->post_title );
733
  bp_activity_update_meta( $activity_id, 'post_url', esc_url_raw( add_query_arg( 'p', $comment->post->ID, home_url( '/' ) ) ) );
734
  }
735
 
736
- // Sync comment - activity comment
737
  if ( ! bp_disable_blogforum_comments() ) {
738
 
739
  if ( ! empty( $_REQUEST['action'] ) ) {
@@ -749,7 +749,7 @@ function bp_blogs_comment_sync_activity_comment( &$activity_id, $comment = null,
749
  }
750
 
751
  if ( isset( $activity_post_object->action_id ) && isset( $activity_post_object->component_id ) ) {
752
- // find the parent 'new_post_type' activity entry
753
  $parent_activity_id = bp_activity_get_activity_id( array(
754
  'component' => $activity_post_object->component_id,
755
  'type' => $activity_post_object->action_id,
@@ -763,20 +763,20 @@ function bp_blogs_comment_sync_activity_comment( &$activity_id, $comment = null,
763
  }
764
  }
765
 
766
- // we found the parent activity entry
767
- // so let's go ahead and reconfigure some activity args
768
  if ( ! empty( $parent_activity_id ) ) {
769
- // set the parent activity entry ID
770
  $activity_args['activity_id'] = $parent_activity_id;
771
 
772
- // now see if the WP parent comment has a BP activity ID
773
  $comment_parent = 0;
774
  if ( ! empty( $comment->comment_parent ) ) {
775
  $comment_parent = get_comment_meta( $comment->comment_parent, 'bp_activity_comment_id', true );
776
  }
777
 
778
  // WP parent comment does not have a BP activity ID
779
- // so set to 'new_' . post_type activity ID
780
  if ( empty( $comment_parent ) ) {
781
  $comment_parent = $parent_activity_id;
782
  }
@@ -784,24 +784,24 @@ function bp_blogs_comment_sync_activity_comment( &$activity_id, $comment = null,
784
  $activity_args['parent_id'] = $comment_parent;
785
  $activity_args['skip_notification'] = true;
786
 
787
- // could not find corresponding parent activity entry
788
- // so wipe out $args array
789
  } else {
790
  $activity_args = array();
791
  }
792
 
793
- // Record in activity streams
794
  if ( ! empty( $activity_args ) ) {
795
  $activity_id = bp_activity_new_comment( $activity_args );
796
 
797
  if ( empty( $activity_args['id'] ) ) {
798
- // The activity metadata to inform about the corresponding comment ID
799
  bp_activity_update_meta( $activity_id, "bp_blogs_{$comment->post->post_type}_comment_id", $comment->comment_ID );
800
 
801
- // The comment metadata to inform about the corresponding activity ID
802
  add_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', $activity_id );
803
 
804
- // These activity metadatas are used to build the new_blog_comment action string
805
  if ( 'new_blog_comment' === $activity_post_object->comment_action_id ) {
806
  bp_activity_update_meta( $activity_id, 'post_title', $comment->post->post_title );
807
  bp_activity_update_meta( $activity_id, 'post_url', esc_url_raw( add_query_arg( 'p', $comment->post->ID, home_url( '/' ) ) ) );
@@ -994,7 +994,7 @@ function bp_blogs_remove_blog( $blog_id ) {
994
  */
995
  do_action( 'bp_blogs_remove_blog', $blog_id );
996
  }
997
- add_action( 'delete_blog', 'bp_blogs_remove_blog' );
998
 
999
  /**
1000
  * Remove a blog from the tracker for a specific user.
@@ -1054,32 +1054,32 @@ function bp_blogs_post_type_remove_comment( $deleted, $comment_id, $activity_pos
1054
  * child post comments and associated activity comments.
1055
  */
1056
  if ( ! empty( $activity_id ) ) {
1057
- // fetch the activity comments for the activity item
1058
  $activity = bp_activity_get( array(
1059
  'in' => $activity_id,
1060
  'display_comments' => 'stream',
1061
  'spam' => 'all',
1062
  ) );
1063
 
1064
- // get all activity comment IDs for the pending deleted item
1065
  if ( ! empty( $activity['activities'] ) ) {
1066
  $activity_ids = bp_activity_recurse_comments_activity_ids( $activity );
1067
  $activity_ids[] = $activity_id;
1068
 
1069
- // delete activity items
1070
  foreach ( $activity_ids as $activity_id ) {
1071
  bp_activity_delete( array(
1072
  'id' => $activity_id
1073
  ) );
1074
  }
1075
 
1076
- // remove associated blog comments
1077
  bp_blogs_remove_associated_blog_comments( $activity_ids );
1078
 
1079
- // rebuild activity comment tree
1080
  BP_Activity_Activity::rebuild_activity_comment_tree( $activity['activities'][0]->item_id );
1081
 
1082
- // Set the result
1083
  $deleted = true;
1084
  }
1085
  }
@@ -1218,7 +1218,7 @@ function bp_blogs_remove_data_for_blog( $blog_id ) {
1218
  */
1219
  do_action( 'bp_blogs_remove_data_for_blog', $blog_id );
1220
  }
1221
- add_action( 'delete_blog', 'bp_blogs_remove_data_for_blog', 1 );
1222
 
1223
  /**
1224
  * Get all of a user's blogs, as tracked by BuddyPress.
@@ -1433,9 +1433,24 @@ function bp_blogs_remove_data( $user_id ) {
1433
  do_action( 'bp_blogs_remove_data', $user_id );
1434
  }
1435
  add_action( 'wpmu_delete_user', 'bp_blogs_remove_data' );
1436
- add_action( 'delete_user', 'bp_blogs_remove_data' );
1437
  add_action( 'bp_make_spam_user', 'bp_blogs_remove_data' );
1438
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1439
  /**
1440
  * Restore all blog associations for a given user.
1441
  *
45
 
46
  // Parse query arguments.
47
  $r = bp_parse_args( $args, array(
48
+ 'type' => 'active', // 'active', 'alphabetical', 'newest', or 'random'.
49
+ 'include_blog_ids' => false, // Array of blog IDs to include.
50
+ 'user_id' => false, // Limit to blogs this user can post to.
51
+ 'search_terms' => false, // Limit to blogs matching these search terms.
52
+ 'per_page' => 20, // The number of results to return per page.
53
+ 'page' => 1, // The page to return if limiting per page.
54
+ 'update_meta_cache' => true // Whether to pre-fetch blogmeta.
55
  ), 'blogs_get_blogs' );
56
 
57
  // Get the blogs.
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 ( bp_is_large_install() ) {
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})";
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
  }
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(
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
  }
411
  */
412
  do_action_ref_array( 'bp_blogs_new_blog', array( &$recorded_blog, $is_private, $is_recorded, $no_activity ) );
413
  }
414
+ add_action( 'bp_insert_site', 'bp_blogs_record_blog', 10, 2 );
415
 
416
  /**
417
  * Update blog name in BuddyPress blogmeta table.
726
  // Set the current blog id.
727
  $blog_id = get_current_blog_id();
728
 
729
+ // These activity metadatas are used to build the new_blog_comment action string.
730
  if ( ! empty( $activity_id ) && ! empty( $activity_args['item_id'] ) && 'new_blog_comment' === $activity_post_object->comment_action_id ) {
731
+ // Add some post info in activity meta.
732
  bp_activity_update_meta( $activity_id, 'post_title', $comment->post->post_title );
733
  bp_activity_update_meta( $activity_id, 'post_url', esc_url_raw( add_query_arg( 'p', $comment->post->ID, home_url( '/' ) ) ) );
734
  }
735
 
736
+ // Sync comment - activity comment.
737
  if ( ! bp_disable_blogforum_comments() ) {
738
 
739
  if ( ! empty( $_REQUEST['action'] ) ) {
749
  }
750
 
751
  if ( isset( $activity_post_object->action_id ) && isset( $activity_post_object->component_id ) ) {
752
+ // Find the parent 'new_post_type' activity entry.
753
  $parent_activity_id = bp_activity_get_activity_id( array(
754
  'component' => $activity_post_object->component_id,
755
  'type' => $activity_post_object->action_id,
763
  }
764
  }
765
 
766
+ // We found the parent activity entry
767
+ // so let's go ahead and reconfigure some activity args.
768
  if ( ! empty( $parent_activity_id ) ) {
769
+ // Set the parent activity entry ID.
770
  $activity_args['activity_id'] = $parent_activity_id;
771
 
772
+ // Now see if the WP parent comment has a BP activity ID.
773
  $comment_parent = 0;
774
  if ( ! empty( $comment->comment_parent ) ) {
775
  $comment_parent = get_comment_meta( $comment->comment_parent, 'bp_activity_comment_id', true );
776
  }
777
 
778
  // WP parent comment does not have a BP activity ID
779
+ // so set to 'new_' . post_type activity ID.
780
  if ( empty( $comment_parent ) ) {
781
  $comment_parent = $parent_activity_id;
782
  }
784
  $activity_args['parent_id'] = $comment_parent;
785
  $activity_args['skip_notification'] = true;
786
 
787
+ // Could not find corresponding parent activity entry
788
+ // so wipe out $args array.
789
  } else {
790
  $activity_args = array();
791
  }
792
 
793
+ // Record in activity streams.
794
  if ( ! empty( $activity_args ) ) {
795
  $activity_id = bp_activity_new_comment( $activity_args );
796
 
797
  if ( empty( $activity_args['id'] ) ) {
798
+ // The activity metadata to inform about the corresponding comment ID.
799
  bp_activity_update_meta( $activity_id, "bp_blogs_{$comment->post->post_type}_comment_id", $comment->comment_ID );
800
 
801
+ // The comment metadata to inform about the corresponding activity ID.
802
  add_comment_meta( $comment->comment_ID, 'bp_activity_comment_id', $activity_id );
803
 
804
+ // These activity metadatas are used to build the new_blog_comment action string.
805
  if ( 'new_blog_comment' === $activity_post_object->comment_action_id ) {
806
  bp_activity_update_meta( $activity_id, 'post_title', $comment->post->post_title );
807
  bp_activity_update_meta( $activity_id, 'post_url', esc_url_raw( add_query_arg( 'p', $comment->post->ID, home_url( '/' ) ) ) );
994
  */
995
  do_action( 'bp_blogs_remove_blog', $blog_id );
996
  }
997
+ add_action( 'bp_delete_site', 'bp_blogs_remove_blog' );
998
 
999
  /**
1000
  * Remove a blog from the tracker for a specific user.
1054
  * child post comments and associated activity comments.
1055
  */
1056
  if ( ! empty( $activity_id ) ) {
1057
+ // Fetch the activity comments for the activity item.
1058
  $activity = bp_activity_get( array(
1059
  'in' => $activity_id,
1060
  'display_comments' => 'stream',
1061
  'spam' => 'all',
1062
  ) );
1063
 
1064
+ // Get all activity comment IDs for the pending deleted item.
1065
  if ( ! empty( $activity['activities'] ) ) {
1066
  $activity_ids = bp_activity_recurse_comments_activity_ids( $activity );
1067
  $activity_ids[] = $activity_id;
1068
 
1069
+ // Delete activity items.
1070
  foreach ( $activity_ids as $activity_id ) {
1071
  bp_activity_delete( array(
1072
  'id' => $activity_id
1073
  ) );
1074
  }
1075
 
1076
+ // Remove associated blog comments.
1077
  bp_blogs_remove_associated_blog_comments( $activity_ids );
1078
 
1079
+ // Rebuild activity comment tree.
1080
  BP_Activity_Activity::rebuild_activity_comment_tree( $activity['activities'][0]->item_id );
1081
 
1082
+ // Set the result.
1083
  $deleted = true;
1084
  }
1085
  }
1218
  */
1219
  do_action( 'bp_blogs_remove_data_for_blog', $blog_id );
1220
  }
1221
+ add_action( 'bp_delete_site', 'bp_blogs_remove_data_for_blog', 1 );
1222
 
1223
  /**
1224
  * Get all of a user's blogs, as tracked by BuddyPress.
1433
  do_action( 'bp_blogs_remove_data', $user_id );
1434
  }
1435
  add_action( 'wpmu_delete_user', 'bp_blogs_remove_data' );
 
1436
  add_action( 'bp_make_spam_user', 'bp_blogs_remove_data' );
1437
 
1438
+ /**
1439
+ * Deletes user XProfile data on the 'delete_user' hook.
1440
+ *
1441
+ * @since 6.0.0
1442
+ *
1443
+ * @param int $user_id The ID of the deleted user.
1444
+ */
1445
+ function bp_blogs_remove_data_on_delete_user( $user_id ) {
1446
+ if ( ! bp_remove_user_data_on_delete_user_hook( 'blogs', $user_id ) ) {
1447
+ return;
1448
+ }
1449
+
1450
+ bp_blogs_remove_data( $user_id );
1451
+ }
1452
+ add_action( 'delete_user', 'bp_blogs_remove_data_on_delete_user' );
1453
+
1454
  /**
1455
  * Restore all blog associations for a given user.
1456
  *
bp-blogs/bp-blogs-template.php CHANGED
@@ -242,6 +242,7 @@ function bp_get_blogs_pagination_count() {
242
  if ( 1 == $blogs_template->total_blog_count ) {
243
  $message = __( 'Viewing 1 site', 'buddypress' );
244
  } else {
 
245
  $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 );
246
  }
247
 
@@ -301,6 +302,7 @@ function bp_blog_avatar( $args = '' ) {
301
  * admin. Filter 'bp_get_blog_avatar_' . $blog_id to customize.
302
  *
303
  * @since 2.4.0 Introduced `$title` argument.
 
304
  *
305
  * @see bp_core_fetch_avatar() For a description of arguments and
306
  * return values.
@@ -309,13 +311,15 @@ function bp_blog_avatar( $args = '' ) {
309
  * Arguments are listed here with an explanation of their defaults.
310
  * For more information about the arguments, see
311
  * {@link bp_core_fetch_avatar()}.
312
- * @type string $alt Default: 'Profile picture of site author [user name]'.
313
- * @type string $class Default: 'avatar'.
314
- * @type string $type Default: 'full'.
315
- * @type int|bool $width Default: false.
316
- * @type int|bool $height Default: false.
317
- * @type bool $id Currently unused.
318
- * @type bool $no_grav Default: true.
 
 
319
  * }
320
  * @return string User avatar string.
321
  */
@@ -328,7 +332,24 @@ function bp_blog_avatar( $args = '' ) {
328
  return false;
329
  }
330
 
331
- $author_displayname = bp_core_get_user_displayname( $blogs_template->blog->admin_user_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
 
333
  // Parse the arguments.
334
  $r = bp_parse_args( $args, array(
@@ -337,18 +358,22 @@ function bp_blog_avatar( $args = '' ) {
337
  'height' => false,
338
  'class' => 'avatar',
339
  'id' => false,
340
- 'alt' => sprintf( __( 'Profile picture of site author %s', 'buddypress' ), esc_attr( $author_displayname ) ),
341
- 'no_grav' => true,
 
 
 
 
342
  ) );
343
 
344
  // Use site icon if available.
345
  $avatar = '';
346
- if ( bp_is_active( 'blogs', 'site-icon' ) && function_exists( 'has_site_icon' ) ) {
347
- $site_icon = bp_blogs_get_blogmeta( bp_get_blog_id(), "site_icon_url_{$r['type']}" );
348
 
349
  // Never attempted to fetch site icon before; do it now!
350
  if ( '' === $site_icon ) {
351
- switch_to_blog( bp_get_blog_id() );
352
 
353
  // Fetch the other size first.
354
  if ( 'full' === $r['type'] ) {
@@ -366,7 +391,7 @@ function bp_blog_avatar( $args = '' ) {
366
  }
367
 
368
  // Sync site icon for other size to blogmeta.
369
- bp_blogs_update_blogmeta( bp_get_blog_id(), "site_icon_url_{$save_size}", $site_icon );
370
 
371
  // Now, fetch the size we want.
372
  if ( 0 !== $site_icon ) {
@@ -375,7 +400,7 @@ function bp_blog_avatar( $args = '' ) {
375
  }
376
 
377
  // Sync site icon to blogmeta.
378
- bp_blogs_update_blogmeta( bp_get_blog_id(), "site_icon_url_{$r['type']}", $site_icon );
379
 
380
  restore_current_blog();
381
  }
@@ -388,11 +413,17 @@ function bp_blog_avatar( $args = '' ) {
388
  $size = (int) $r['width'];
389
  }
390
 
 
 
 
 
 
 
391
  $avatar = sprintf( '<img src="%1$s" class="%2$s" width="%3$s" height="%3$s" alt="%4$s" />',
392
  esc_url( $site_icon ),
393
  esc_attr( "{$r['class']} avatar-{$size}" ),
394
  esc_attr( $size ),
395
- sprintf( esc_attr__( 'Site icon for %s', 'buddypress' ), bp_get_blog_name() )
396
  );
397
  }
398
  }
@@ -400,7 +431,7 @@ function bp_blog_avatar( $args = '' ) {
400
  // Fallback to user ID avatar.
401
  if ( '' === $avatar ) {
402
  $avatar = bp_core_fetch_avatar( array(
403
- 'item_id' => $blogs_template->blog->admin_user_id,
404
  // 'avatar_dir' => 'blog-avatars',
405
  // 'object' => 'blog',
406
  'type' => $r['type'],
@@ -408,7 +439,8 @@ function bp_blog_avatar( $args = '' ) {
408
  'css_id' => $r['id'],
409
  'class' => $r['class'],
410
  'width' => $r['width'],
411
- 'height' => $r['height']
 
412
  ) );
413
  }
414
 
@@ -420,7 +452,7 @@ function bp_blog_avatar( $args = '' ) {
420
  * This filter is deprecated as of BuddyPress 1.5 and may be removed in a future version.
421
  * Use the 'bp_get_blog_avatar' filter instead.
422
  */
423
- $avatar = apply_filters( 'bp_get_blog_avatar_' . $blogs_template->blog->blog_id, $avatar );
424
 
425
  /**
426
  * Filters a blog's avatar.
@@ -432,7 +464,7 @@ function bp_blog_avatar( $args = '' ) {
432
  * @param int $blog_id ID of the blog whose avatar is being displayed.
433
  * @param array $r Array of arguments used when fetching avatar.
434
  */
435
- return apply_filters( 'bp_get_blog_avatar', $avatar, $blogs_template->blog->blog_id, $r );
436
  }
437
 
438
  function bp_blog_permalink() {
@@ -621,7 +653,8 @@ function bp_blog_last_active( $args = array() ) {
621
 
622
  // Backwards compatibility for anyone forcing a 'true' active_format.
623
  if ( true === $r['active_format'] ) {
624
- $r['active_format'] = __( 'active %s', 'buddypress' );
 
625
  }
626
 
627
  // Blog has been posted to at least once.
@@ -686,7 +719,11 @@ function bp_blog_latest_post( $args = array() ) {
686
  *
687
  * @param string $retval Title of the latest post.
688
  */
689
- $retval = sprintf( __( 'Latest Post: %s', 'buddypress' ), '<a href="' . $blogs_template->blog->latest_post->guid . '">' . apply_filters( 'the_title', $retval ) . '</a>' );
 
 
 
 
690
  } else {
691
 
692
  /** This filter is documented in bp-blogs/bp-blogs-template.php */
@@ -1224,6 +1261,7 @@ function bp_blogs_confirm_blog_signup( $domain, $path, $blog_title, $user_name,
1224
  <?php printf(
1225
  '%s %s',
1226
  sprintf(
 
1227
  __( '%s is your new site.', 'buddypress' ),
1228
  sprintf( '<a href="%s">%s</a>', esc_url( $blog_url ), esc_url( $blog_url ) )
1229
  ),
@@ -1282,9 +1320,30 @@ function bp_blogs_blog_tabs() {
1282
  } ?>
1283
 
1284
  <ul class="content-header-nav">
1285
- <li<?php if ( bp_is_current_action( 'my-blogs' ) || !bp_current_action() ) : ?> class="current"<?php endif; ?>><a href="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_blogs_slug() . '/my-blogs' ); ?>"><?php printf( __( "%s's Sites", 'buddypress' ), bp_get_displayed_user_fullname() ); ?></a></li>
1286
- <li<?php if ( bp_is_current_action( 'recent-posts' ) ) : ?> class="current"<?php endif; ?>><a href="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_blogs_slug() . '/recent-posts' ); ?>"><?php printf( __( "%s's Recent Posts", 'buddypress' ), bp_get_displayed_user_fullname() ); ?></a></li>
1287
- <li<?php if ( bp_is_current_action( 'recent-comments' ) ) : ?> class="current"<?php endif; ?>><a href="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_blogs_slug() . '/recent-comments' ); ?>"><?php printf( __( "%s's Recent Comments", 'buddypress' ), bp_get_displayed_user_fullname() ); ?></a></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1288
  </ul>
1289
 
1290
  <?php
@@ -1528,7 +1587,11 @@ function bp_blogs_get_profile_stats( $args = '' ) {
1528
  }
1529
 
1530
  // If blogs exist, show some formatted output.
1531
- $r['output'] = $r['before'] . sprintf( _n( '%s site', '%s sites', $r['blogs'], 'buddypress' ), '<strong>' . $r['blogs'] . '</strong>' ) . $r['after'];
 
 
 
 
1532
  }
1533
  }
1534
 
242
  if ( 1 == $blogs_template->total_blog_count ) {
243
  $message = __( 'Viewing 1 site', 'buddypress' );
244
  } else {
245
+ /* translators: 1: the site from number. 2: the site to number. 3: the total number of sites. */
246
  $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 );
247
  }
248
 
302
  * admin. Filter 'bp_get_blog_avatar_' . $blog_id to customize.
303
  *
304
  * @since 2.4.0 Introduced `$title` argument.
305
+ * @since 6.0.0 Introduced the `$blog_id` & `$admin_user_id` arguments.
306
  *
307
  * @see bp_core_fetch_avatar() For a description of arguments and
308
  * return values.
311
  * Arguments are listed here with an explanation of their defaults.
312
  * For more information about the arguments, see
313
  * {@link bp_core_fetch_avatar()}.
314
+ * @type string $alt Default: 'Profile picture of site author [user name]'.
315
+ * @type string $class Default: 'avatar'.
316
+ * @type string $type Default: 'full'.
317
+ * @type int|bool $width Default: false.
318
+ * @type int|bool $height Default: false.
319
+ * @type bool $id Currently unused.
320
+ * @type bool $no_grav Default: false.
321
+ * @type int $blog_id The blog ID. Default: O.
322
+ * @type int $admin_user_id The Blog Admin user ID. Default: 0.
323
  * }
324
  * @return string User avatar string.
325
  */
332
  return false;
333
  }
334
 
335
+ // Set default values.
336
+ $author_displayname = '';
337
+ $admin_user_id = 0;
338
+ $blog_id = 0;
339
+
340
+ if ( ! $blogs_template && isset( $args['admin_user_id'] ) && $args['admin_user_id'] ) {
341
+ $admin_user_id = (int) $args['admin_user_id'];
342
+ $author_displayname = bp_core_get_user_displayname( $admin_user_id );
343
+ } else {
344
+ $admin_user_id = $blogs_template->blog->admin_user_id;
345
+ $author_displayname = bp_core_get_user_displayname( $blogs_template->blog->admin_user_id );
346
+ }
347
+
348
+ if ( ! $blogs_template && isset( $args['blog_id'] ) && $args['blog_id'] ) {
349
+ $blog_id = (int) $args['blog_id'];
350
+ } else {
351
+ $blog_id = bp_get_blog_id();
352
+ }
353
 
354
  // Parse the arguments.
355
  $r = bp_parse_args( $args, array(
358
  'height' => false,
359
  'class' => 'avatar',
360
  'id' => false,
361
+ 'alt' => sprintf(
362
+ /* translators: %s: the author display name */
363
+ __( 'Profile picture of site author %s', 'buddypress' ),
364
+ esc_attr( $author_displayname )
365
+ ),
366
+ 'no_grav' => false,
367
  ) );
368
 
369
  // Use site icon if available.
370
  $avatar = '';
371
+ if ( bp_is_active( 'blogs', 'site-icon' ) ) {
372
+ $site_icon = bp_blogs_get_blogmeta( $blog_id, "site_icon_url_{$r['type']}" );
373
 
374
  // Never attempted to fetch site icon before; do it now!
375
  if ( '' === $site_icon ) {
376
+ switch_to_blog( $blog_id );
377
 
378
  // Fetch the other size first.
379
  if ( 'full' === $r['type'] ) {
391
  }
392
 
393
  // Sync site icon for other size to blogmeta.
394
+ bp_blogs_update_blogmeta( $blog_id, "site_icon_url_{$save_size}", $site_icon );
395
 
396
  // Now, fetch the size we want.
397
  if ( 0 !== $site_icon ) {
400
  }
401
 
402
  // Sync site icon to blogmeta.
403
+ bp_blogs_update_blogmeta( $blog_id, "site_icon_url_{$r['type']}", $site_icon );
404
 
405
  restore_current_blog();
406
  }
413
  $size = (int) $r['width'];
414
  }
415
 
416
+ $alt_attribute = __( 'Site icon for the blog', 'buddypress' );
417
+ if ( $blogs_template ) {
418
+ /* translators: %s is the placeholder for the name of the blog */
419
+ $alt_attribute = sprintf( __( 'Site icon for %s', 'buddypress' ), bp_get_blog_name() );
420
+ }
421
+
422
  $avatar = sprintf( '<img src="%1$s" class="%2$s" width="%3$s" height="%3$s" alt="%4$s" />',
423
  esc_url( $site_icon ),
424
  esc_attr( "{$r['class']} avatar-{$size}" ),
425
  esc_attr( $size ),
426
+ esc_attr( $alt_attribute )
427
  );
428
  }
429
  }
431
  // Fallback to user ID avatar.
432
  if ( '' === $avatar ) {
433
  $avatar = bp_core_fetch_avatar( array(
434
+ 'item_id' => $admin_user_id,
435
  // 'avatar_dir' => 'blog-avatars',
436
  // 'object' => 'blog',
437
  'type' => $r['type'],
439
  'css_id' => $r['id'],
440
  'class' => $r['class'],
441
  'width' => $r['width'],
442
+ 'height' => $r['height'],
443
+ 'no_grav' => $r['no_grav'],
444
  ) );
445
  }
446
 
452
  * This filter is deprecated as of BuddyPress 1.5 and may be removed in a future version.
453
  * Use the 'bp_get_blog_avatar' filter instead.
454
  */
455
+ $avatar = apply_filters( 'bp_get_blog_avatar_' . $blog_id, $avatar );
456
 
457
  /**
458
  * Filters a blog's avatar.
464
  * @param int $blog_id ID of the blog whose avatar is being displayed.
465
  * @param array $r Array of arguments used when fetching avatar.
466
  */
467
+ return apply_filters( 'bp_get_blog_avatar', $avatar, $blog_id, $r );
468
  }
469
 
470
  function bp_blog_permalink() {
653
 
654
  // Backwards compatibility for anyone forcing a 'true' active_format.
655
  if ( true === $r['active_format'] ) {
656
+ /* translators: %s: human time diff of the last time the site was active. */
657
+ $r['active_format'] = _x( 'active %s', 'last time the site was active', 'buddypress' );
658
  }
659
 
660
  // Blog has been posted to at least once.
719
  *
720
  * @param string $retval Title of the latest post.
721
  */
722
+ $retval = sprintf(
723
+ /* translators: %s: the title of the latest post */
724
+ __( 'Latest Post: %s', 'buddypress' ),
725
+ '<a href="' . $blogs_template->blog->latest_post->guid . '">' . apply_filters( 'the_title', $retval ) . '</a>'
726
+ );
727
  } else {
728
 
729
  /** This filter is documented in bp-blogs/bp-blogs-template.php */
1261
  <?php printf(
1262
  '%s %s',
1263
  sprintf(
1264
+ /* translators: %s: the link of the new site */
1265
  __( '%s is your new site.', 'buddypress' ),
1266
  sprintf( '<a href="%s">%s</a>', esc_url( $blog_url ), esc_url( $blog_url ) )
1267
  ),
1320
  } ?>
1321
 
1322
  <ul class="content-header-nav">
1323
+ <li<?php if ( bp_is_current_action( 'my-blogs' ) || !bp_current_action() ) : ?> class="current"<?php endif; ?>>
1324
+ <a href="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_blogs_slug() . '/my-blogs' ); ?>">
1325
+ <?php
1326
+ /* translators: %s: the User Display Name */
1327
+ printf( __( "%s's Sites", 'buddypress' ), bp_get_displayed_user_fullname() );
1328
+ ?>
1329
+ </a>
1330
+ </li>
1331
+ <li<?php if ( bp_is_current_action( 'recent-posts' ) ) : ?> class="current"<?php endif; ?>>
1332
+ <a href="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_blogs_slug() . '/recent-posts' ); ?>">
1333
+ <?php
1334
+ /* translators: %s: the User Display Name */
1335
+ printf( __( "%s's Recent Posts", 'buddypress' ), bp_get_displayed_user_fullname() );
1336
+ ?>
1337
+ </a>
1338
+ </li>
1339
+ <li<?php if ( bp_is_current_action( 'recent-comments' ) ) : ?> class="current"<?php endif; ?>>
1340
+ <a href="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_blogs_slug() . '/recent-comments' ); ?>">
1341
+ <?php
1342
+ /* translators: %s: the User Display Name */
1343
+ printf( __( "%s's Recent Comments", 'buddypress' ), bp_get_displayed_user_fullname() );
1344
+ ?>
1345
+ </a>
1346
+ </li>
1347
  </ul>
1348
 
1349
  <?php
1587
  }
1588
 
1589
  // If blogs exist, show some formatted output.
1590
+ $r['output'] = $r['before'];
1591
+
1592
+ /* translators: %s: the number of blogs */
1593
+ $r['output'] .= sprintf( _n( '%s site', '%s sites', $r['blogs'], 'buddypress' ), '<strong>' . $r['blogs'] . '</strong>' );
1594
+ $r['output'] .= $r['after'];
1595
  }
1596
  }
1597
 
bp-blogs/classes/class-bp-blogs-blog.php CHANGED
@@ -86,7 +86,7 @@ class BP_Blogs_Blog {
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
  *
86
  $this->user_id = apply_filters( 'bp_blogs_blog_user_id_before_save', $this->user_id, $this->id );
87
 
88
  /**
89
+ * Filters the blog ID before save.
90
  *
91
  * @since 1.0.0
92
  *
bp-blogs/classes/class-bp-blogs-component.php CHANGED
@@ -329,7 +329,11 @@ class BP_Blogs_Component extends BP_Component {
329
  $bp->bp_options_avatar = bp_core_fetch_avatar( array(
330
  'item_id' => bp_displayed_user_id(),
331
  'type' => 'thumb',
332
- 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() )
 
 
 
 
333
  ) );
334
  $bp->bp_options_title = bp_get_displayed_user_fullname();
335
  }
@@ -352,4 +356,27 @@ class BP_Blogs_Component extends BP_Component {
352
 
353
  parent::setup_cache_groups();
354
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  }
329
  $bp->bp_options_avatar = bp_core_fetch_avatar( array(
330
  'item_id' => bp_displayed_user_id(),
331
  'type' => 'thumb',
332
+ 'alt' => sprintf(
333
+ /* translators: %s: member name */
334
+ _( 'Profile picture of %s', 'buddypress' ),
335
+ bp_get_displayed_user_fullname()
336
+ ),
337
  ) );
338
  $bp->bp_options_title = bp_get_displayed_user_fullname();
339
  }
356
 
357
  parent::setup_cache_groups();
358
  }
359
+
360
+ /**
361
+ * Init the BP REST API.
362
+ *
363
+ * @since 6.0.0
364
+ *
365
+ * @param array $controllers Optional. See BP_Component::rest_api_init() for
366
+ * description.
367
+ */
368
+ public function rest_api_init( $controllers = array() ) {
369
+ if ( is_multisite() ) {
370
+ $controllers = array(
371
+ 'BP_REST_Blogs_Endpoint',
372
+ );
373
+
374
+ // Support to Blog Avatar.
375
+ if ( bp_is_active( 'blogs', 'site-icon' ) ) {
376
+ $controllers[] = 'BP_REST_Attachments_Blog_Avatar_Endpoint';
377
+ }
378
+ }
379
+
380
+ parent::rest_api_init( $controllers );
381
+ }
382
  }
bp-blogs/classes/class-bp-rest-attachments-blog-avatar-endpoint.php ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Attachments_Blog_Avatar_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 6.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Blog avatar endpoints.
13
+ *
14
+ * @since 6.0.0
15
+ */
16
+ class BP_REST_Attachments_Blog_Avatar_Endpoint extends WP_REST_Controller {
17
+
18
+ use BP_REST_Attachments;
19
+
20
+ /**
21
+ * Reuse some parts of the BP_REST_Blogs_Endpoint class.
22
+ *
23
+ * @since 6.0.0
24
+ *
25
+ * @var BP_REST_Blogs_Endpoint
26
+ */
27
+ protected $blogs_endpoint;
28
+
29
+ /**
30
+ * Constructor.
31
+ *
32
+ * @since 6.0.0
33
+ */
34
+ public function __construct() {
35
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
36
+ $this->rest_base = buddypress()->blogs->id;
37
+ $this->blogs_endpoint = new BP_REST_Blogs_Endpoint();
38
+ }
39
+
40
+ /**
41
+ * Register the component routes.
42
+ *
43
+ * @since 6.0.0
44
+ */
45
+ public function register_routes() {
46
+ register_rest_route(
47
+ $this->namespace,
48
+ '/' . $this->rest_base . '/(?P<id>[\d]+)/avatar',
49
+ array(
50
+ 'args' => array(
51
+ 'id' => array(
52
+ 'description' => __( 'A unique numeric ID for the blog.', 'buddypress' ),
53
+ 'type' => 'integer',
54
+ ),
55
+ ),
56
+ array(
57
+ 'methods' => WP_REST_Server::READABLE,
58
+ 'callback' => array( $this, 'get_item' ),
59
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
60
+ 'args' => $this->get_item_collection_params(),
61
+ ),
62
+ 'schema' => array( $this, 'get_item_schema' ),
63
+ )
64
+ );
65
+ }
66
+
67
+ /**
68
+ * Fetch an existing blog avatar.
69
+ *
70
+ * @since 6.0.0
71
+ *
72
+ * @param WP_REST_Request $request Full details about the request.
73
+ * @return WP_REST_Response|WP_Error
74
+ */
75
+ public function get_item( $request ) {
76
+
77
+ // Check if user exists and it is valid.
78
+ $admin_user_admin = $request['user_id'];
79
+ if ( 0 !== $admin_user_admin ) {
80
+ $user = get_user_by( 'id', $admin_user_admin );
81
+ if ( ! $user instanceof WP_User ) {
82
+ return new WP_Error(
83
+ 'bp_rest_blog_avatar_get_item_user_failed',
84
+ __( 'There was a problem confirming if the user ID provided is valid.', 'buddypress' ),
85
+ array(
86
+ 'status' => 500,
87
+ )
88
+ );
89
+ }
90
+
91
+ $admin_user_admin = $user->ID;
92
+ }
93
+
94
+ $args = array();
95
+ foreach ( array( 'full', 'thumb' ) as $type ) {
96
+ $args[ $type ] = bp_get_blog_avatar(
97
+ array(
98
+ 'type' => $type,
99
+ 'blog_id' => $request['id'],
100
+ 'admin_user_id' => $admin_user_admin,
101
+ 'alt' => $request['alt'],
102
+ 'no_grav' => (bool) $request['no_grav'],
103
+ )
104
+ );
105
+ }
106
+
107
+ // Get the avatar object.
108
+ $avatar = $this->get_avatar_object( $args );
109
+
110
+ if ( ! $avatar->full && ! $avatar->thumb ) {
111
+ return new WP_Error(
112
+ 'bp_rest_attachments_blog_avatar_no_image',
113
+ __( 'Sorry, there was a problem fetching the blog avatar.', 'buddypress' ),
114
+ array(
115
+ 'status' => 500,
116
+ )
117
+ );
118
+ }
119
+
120
+ $retval = array(
121
+ $this->prepare_response_for_collection(
122
+ $this->prepare_item_for_response( $avatar, $request )
123
+ ),
124
+ );
125
+
126
+ $response = rest_ensure_response( $retval );
127
+
128
+ /**
129
+ * Fires after a blog avatar is fetched via the REST API.
130
+ *
131
+ * @since 6.0.0
132
+ *
133
+ * @param stdClass $avatar The avatar object.
134
+ * @param WP_REST_Response $response The response data.
135
+ * @param WP_REST_Request $request The request sent to the API.
136
+ */
137
+ do_action( 'bp_rest_attachments_blog_avatar_get_item', $avatar, $response, $request );
138
+
139
+ return $response;
140
+ }
141
+
142
+ /**
143
+ * Checks if a given request has access to get a blog avatar.
144
+ *
145
+ * @since 6.0.0
146
+ *
147
+ * @param WP_REST_Request $request Full details about the request.
148
+ * @return bool|WP_Error
149
+ */
150
+ public function get_item_permissions_check( $request ) {
151
+ $retval = true;
152
+ $blog = $this->blogs_endpoint->get_blog_object( $request['id'] );
153
+
154
+ if ( true === $retval && ! is_object( $blog ) ) {
155
+ $retval = new WP_Error(
156
+ 'bp_rest_blog_invalid_id',
157
+ __( 'Invalid group ID.', 'buddypress' ),
158
+ array(
159
+ 'status' => 404,
160
+ )
161
+ );
162
+ }
163
+
164
+ if ( true === $retval && ! buddypress()->avatar->show_avatars ) {
165
+ $retval = new WP_Error(
166
+ 'bp_rest_attachments_blog_avatar_disabled',
167
+ __( 'Sorry, blog avatar is disabled.', 'buddypress' ),
168
+ array(
169
+ 'status' => 500,
170
+ )
171
+ );
172
+ }
173
+
174
+ /**
175
+ * Filter the blog avatar `get_item` permissions check.
176
+ *
177
+ * @since 6.0.0
178
+ *
179
+ * @param bool|WP_Error $retval Returned value.
180
+ * @param WP_REST_Request $request The request sent to the API.
181
+ */
182
+ return apply_filters( 'bp_rest_attachments_blog_avatar_get_item_permissions_check', $retval, $request );
183
+ }
184
+
185
+ /**
186
+ * Prepares avatar data to return as an object.
187
+ *
188
+ * @since 6.0.0
189
+ *
190
+ * @param stdClass $avatar Avatar object.
191
+ * @param WP_REST_Request $request Full details about the request.
192
+ * @return WP_REST_Response
193
+ */
194
+ public function prepare_item_for_response( $avatar, $request ) {
195
+ $data = array(
196
+ 'full' => $avatar->full,
197
+ 'thumb' => $avatar->thumb,
198
+ );
199
+
200
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
201
+ $data = $this->add_additional_fields_to_object( $data, $request );
202
+ $data = $this->filter_response_by_context( $data, $context );
203
+ $response = rest_ensure_response( $data );
204
+
205
+ /**
206
+ * Filter a blog avatar value returned from the API.
207
+ *
208
+ * @since 6.0.0
209
+ *
210
+ * @param WP_REST_Response $response Response.
211
+ * @param WP_REST_Request $request Request used to generate the response.
212
+ * @param object $avatar Avatar object.
213
+ */
214
+ return apply_filters( 'bp_rest_attachments_blog_avatar_prepare_value', $response, $request, $avatar );
215
+ }
216
+
217
+ /**
218
+ * Get the blog avatar schema, conforming to JSON Schema.
219
+ *
220
+ * @since 6.0.0
221
+ *
222
+ * @return array
223
+ */
224
+ public function get_item_schema() {
225
+ $schema = array(
226
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
227
+ 'title' => 'bp_attachments_blog_avatar',
228
+ 'type' => 'object',
229
+ 'properties' => array(
230
+ 'full' => array(
231
+ 'context' => array( 'view', 'edit' ),
232
+ 'description' => __( 'Full size of the image file.', 'buddypress' ),
233
+ 'type' => 'string',
234
+ 'format' => 'uri',
235
+ 'readonly' => true,
236
+ ),
237
+ 'thumb' => array(
238
+ 'context' => array( 'view', 'edit' ),
239
+ 'description' => __( 'Thumb size of the image file.', 'buddypress' ),
240
+ 'type' => 'string',
241
+ 'format' => 'uri',
242
+ 'readonly' => true,
243
+ ),
244
+ ),
245
+ );
246
+
247
+ /**
248
+ * Filters the blog avatar schema.
249
+ *
250
+ * @param string $schema The endpoint schema.
251
+ */
252
+ return apply_filters( 'bp_rest_attachments_blog_avatar_schema', $this->add_additional_fields_schema( $schema ) );
253
+ }
254
+
255
+ /**
256
+ * Get the query params for the `get_item`.
257
+ *
258
+ * @since 6.0.0
259
+ *
260
+ * @return array
261
+ */
262
+ public function get_item_collection_params() {
263
+ $params = parent::get_collection_params();
264
+ $params['context']['default'] = 'view';
265
+
266
+ // Removing unused params.
267
+ unset( $params['search'], $params['page'], $params['per_page'] );
268
+
269
+ $params['alt'] = array(
270
+ 'description' => __( 'The alt attribute for the <img> element.', 'buddypress' ),
271
+ 'default' => '',
272
+ 'type' => 'string',
273
+ 'sanitize_callback' => 'sanitize_text_field',
274
+ 'validate_callback' => 'rest_validate_request_arg',
275
+ );
276
+
277
+ $params['user_id'] = array(
278
+ 'description' => __( 'The Blog admin user ID to avatar fallback.', 'buddypress' ),
279
+ 'default' => 0,
280
+ 'type' => 'integer',
281
+ 'sanitize_callback' => 'absint',
282
+ 'validate_callback' => 'rest_validate_request_arg',
283
+ );
284
+
285
+ $params['no_grav'] = array(
286
+ 'description' => __( 'Whether to disable the default Gravatar fallback.', 'buddypress' ),
287
+ 'default' => false,
288
+ 'type' => 'boolean',
289
+ 'sanitize_callback' => 'rest_sanitize_boolean',
290
+ 'validate_callback' => 'rest_validate_request_arg',
291
+ );
292
+
293
+ /**
294
+ * Filters the item collection query params.
295
+ *
296
+ * @param array $params Query params.
297
+ */
298
+ return apply_filters( 'bp_rest_attachments_blog_avatar_collection_params', $params );
299
+ }
300
+ }
bp-blogs/classes/class-bp-rest-blogs-endpoint.php ADDED
@@ -0,0 +1,537 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Blogs_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 6.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Blogs endpoints.
13
+ *
14
+ * Use /blogs/
15
+ * Use /blogs/{id}
16
+ *
17
+ * @since 6.0.0
18
+ */
19
+ class BP_REST_Blogs_Endpoint extends WP_REST_Controller {
20
+
21
+ /**
22
+ * Constructor.
23
+ *
24
+ * @since 6.0.0
25
+ */
26
+ public function __construct() {
27
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
28
+ $this->rest_base = buddypress()->blogs->id;
29
+ }
30
+
31
+ /**
32
+ * Register the component routes.
33
+ *
34
+ * @since 6.0.0
35
+ */
36
+ public function register_routes() {
37
+ register_rest_route(
38
+ $this->namespace,
39
+ '/' . $this->rest_base,
40
+ array(
41
+ array(
42
+ 'methods' => WP_REST_Server::READABLE,
43
+ 'callback' => array( $this, 'get_items' ),
44
+ 'permission_callback' => array( $this, 'get_items_permissions_check' ),
45
+ 'args' => $this->get_collection_params(),
46
+ ),
47
+ 'schema' => array( $this, 'get_item_schema' ),
48
+ )
49
+ );
50
+
51
+ register_rest_route(
52
+ $this->namespace,
53
+ '/' . $this->rest_base . '/(?P<id>[\d]+)',
54
+ array(
55
+ 'args' => array(
56
+ 'id' => array(
57
+ 'description' => __( 'A unique numeric ID for the Blog.', 'buddypress' ),
58
+ 'type' => 'integer',
59
+ ),
60
+ ),
61
+ array(
62
+ 'methods' => WP_REST_Server::READABLE,
63
+ 'callback' => array( $this, 'get_item' ),
64
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
65
+ 'args' => array(
66
+ 'context' => $this->get_context_param(
67
+ array(
68
+ 'default' => 'view',
69
+ )
70
+ ),
71
+ ),
72
+ ),
73
+ 'schema' => array( $this, 'get_item_schema' ),
74
+ )
75
+ );
76
+ }
77
+
78
+ /**
79
+ * Retrieve Blogs.
80
+ *
81
+ * @since 6.0.0
82
+ *
83
+ * @param WP_REST_Request $request Full details about the request.
84
+ * @return WP_REST_Response
85
+ */
86
+ public function get_items( $request ) {
87
+ $args = array(
88
+ 'type' => $request['type'],
89
+ 'include_blog_ids' => $request['include'],
90
+ 'user_id' => $request['user_id'],
91
+ 'search_terms' => $request['search'],
92
+ 'page' => $request['page'],
93
+ 'per_page' => $request['per_page'],
94
+ );
95
+
96
+ /**
97
+ * Filter the query arguments for the request.
98
+ *
99
+ * @since 6.0.0
100
+ *
101
+ * @param array $args Key value array of query var to query value.
102
+ * @param WP_REST_Request $request The request sent to the API.
103
+ */
104
+ $args = apply_filters( 'bp_rest_blogs_get_items_query_args', $args, $request );
105
+
106
+ // false is the default value for some args.
107
+ foreach ( $args as $key => $value ) {
108
+ if ( empty( $value ) ) {
109
+ $args[ $key ] = false;
110
+ }
111
+ }
112
+
113
+ // Check if user is valid.
114
+ if ( 0 !== $request['user_id'] ) {
115
+ $user = get_user_by( 'id', $request['user_id'] );
116
+ if ( ! $user instanceof WP_User ) {
117
+ return new WP_Error(
118
+ 'bp_rest_blogs_get_items_user_failed',
119
+ __( 'There was a problem confirming if user ID provided is a valid one.', 'buddypress' ),
120
+ array(
121
+ 'status' => 500,
122
+ )
123
+ );
124
+ }
125
+ }
126
+
127
+ // Actually, query it.
128
+ $blogs = bp_blogs_get_blogs( $args );
129
+
130
+ $retval = array();
131
+ foreach ( (array) $blogs['blogs'] as $blog ) {
132
+ $retval[] = $this->prepare_response_for_collection(
133
+ $this->prepare_item_for_response( $blog, $request )
134
+ );
135
+ }
136
+
137
+ $response = rest_ensure_response( $retval );
138
+ $response = bp_rest_response_add_total_headers( $response, $blogs['total'], $args['per_page'] );
139
+
140
+ /**
141
+ * Fires after blogs are fetched via the REST API.
142
+ *
143
+ * @since 6.0.0
144
+ *
145
+ * @param array $blogs Fetched blogs.
146
+ * @param WP_REST_Response $response The response data.
147
+ * @param WP_REST_Request $request The request sent to the API.
148
+ */
149
+ do_action( 'bp_rest_blogs_get_items', $blogs, $response, $request );
150
+
151
+ return $response;
152
+ }
153
+
154
+ /**
155
+ * Check if a given request has access to blog items.
156
+ *
157
+ * @since 6.0.0
158
+ *
159
+ * @param WP_REST_Request $request Full data about the request.
160
+ * @return WP_Error|bool
161
+ */
162
+ public function get_items_permissions_check( $request ) {
163
+
164
+ /**
165
+ * Filter the blogs `get_items` permissions check.
166
+ *
167
+ * @since 6.0.0
168
+ *
169
+ * @param bool|WP_Error $retval Returned value.
170
+ * @param WP_REST_Request $request The request sent to the API.
171
+ */
172
+ return apply_filters( 'bp_rest_blogs_get_items_permissions_check', true, $request );
173
+ }
174
+
175
+ /**
176
+ * Retrieve a blog.
177
+ *
178
+ * @since 6.0.0
179
+ *
180
+ * @param WP_REST_Request $request Full details about the request.
181
+ * @return WP_REST_Response
182
+ */
183
+ public function get_item( $request ) {
184
+ $blog = $this->get_blog_object( $request['id'] );
185
+
186
+ if ( empty( $blog->blog_id ) || empty( $blog->admin_user_id ) ) {
187
+ return new WP_Error(
188
+ 'bp_rest_blog_invalid_id',
189
+ __( 'Invalid blog ID.', 'buddypress' ),
190
+ array(
191
+ 'status' => 404,
192
+ )
193
+ );
194
+ }
195
+
196
+ $retval = array(
197
+ $this->prepare_response_for_collection(
198
+ $this->prepare_item_for_response( $blog, $request )
199
+ ),
200
+ );
201
+
202
+ $response = rest_ensure_response( $retval );
203
+
204
+ /**
205
+ * Fires after a blog is fetched via the REST API.
206
+ *
207
+ * @since 6.0.0
208
+ *
209
+ * @param stdClass $blog Fetched blog.
210
+ * @param WP_REST_Response $response The response data.
211
+ * @param WP_REST_Request $request The request sent to the API.
212
+ */
213
+ do_action( 'bp_rest_blogs_get_item', $blog, $response, $request );
214
+
215
+ return $response;
216
+ }
217
+
218
+ /**
219
+ * Check if a given request has access to get information about a specific blog.
220
+ *
221
+ * @since 6.0.0
222
+ *
223
+ * @param WP_REST_Request $request Full details about the request.
224
+ * @return WP_Error|bool
225
+ */
226
+ public function get_item_permissions_check( $request ) {
227
+
228
+ /**
229
+ * Filter the blog `get_item` permissions check.
230
+ *
231
+ * @since 6.0.0
232
+ *
233
+ * @param bool|WP_Error $retval Returned value.
234
+ * @param WP_REST_Request $request The request sent to the API.
235
+ */
236
+ return apply_filters( 'bp_rest_blogs_get_item_permissions_check', true, $request );
237
+ }
238
+
239
+ /**
240
+ * Prepares blogs data for return as an object.
241
+ *
242
+ * @since 6.0.0
243
+ *
244
+ * @param stdClass $blog Blog object.
245
+ * @param WP_REST_Request $request Full details about the request.
246
+ * @return WP_REST_Response
247
+ */
248
+ public function prepare_item_for_response( $blog, $request ) {
249
+ $data = array(
250
+ 'id' => $blog->blog_id,
251
+ 'user_id' => $blog->admin_user_id,
252
+ 'name' => $blog->name,
253
+ 'domain' => $blog->domain,
254
+ 'path' => $blog->path,
255
+ 'permalink' => $this->get_blog_domain( $blog ),
256
+ 'description' => stripslashes( $blog->description ),
257
+ 'last_activity' => bp_rest_prepare_date_response( $blog->last_activity ),
258
+ );
259
+
260
+ // Get item schema.
261
+ $schema = $this->get_item_schema();
262
+
263
+ // Blog Avatars.
264
+ if ( ! empty( $schema['properties']['avatar_urls'] ) ) {
265
+ $data['avatar_urls'] = array(
266
+ 'thumb' => bp_get_blog_avatar(
267
+ array(
268
+ 'type' => 'thumb',
269
+ 'blog_id' => $blog->blog_id,
270
+ 'admin_user_id' => $blog->admin_user_id,
271
+ )
272
+ ),
273
+ 'full' => bp_get_blog_avatar(
274
+ array(
275
+ 'type' => 'full',
276
+ 'blog_id' => $blog->blog_id,
277
+ 'admin_user_id' => $blog->admin_user_id,
278
+ )
279
+ ),
280
+ );
281
+ }
282
+
283
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
284
+ $data = $this->add_additional_fields_to_object( $data, $request );
285
+ $data = $this->filter_response_by_context( $data, $context );
286
+
287
+ $response = rest_ensure_response( $data );
288
+ $response->add_links( $this->prepare_links( $blog ) );
289
+
290
+ /**
291
+ * Filter a blog returned from the API.
292
+ *
293
+ * @since 6.0.0
294
+ *
295
+ * @param WP_REST_Response $response Response generated by the request.
296
+ * @param WP_REST_Request $request Request used to generate the response.
297
+ * @param stdClass $blog The blog object.
298
+ */
299
+ return apply_filters( 'bp_rest_blogs_prepare_value', $response, $request, $blog );
300
+ }
301
+
302
+ /**
303
+ * Prepare links for the request.
304
+ *
305
+ * @since 6.0.0
306
+ *
307
+ * @param stdClass $blog Blog object.
308
+ * @return array
309
+ */
310
+ protected function prepare_links( $blog ) {
311
+ $base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );
312
+ $url = $base . $blog->blog_id;
313
+
314
+ // Entity meta.
315
+ $links = array(
316
+ 'self' => array(
317
+ 'href' => rest_url( $url ),
318
+ ),
319
+ 'collection' => array(
320
+ 'href' => rest_url( $base ),
321
+ ),
322
+ 'user' => array(
323
+ 'href' => rest_url( bp_rest_get_user_url( $blog->admin_user_id ) ),
324
+ 'embeddable' => true,
325
+ ),
326
+ );
327
+
328
+ /**
329
+ * Filter links prepared for the REST response.
330
+ *
331
+ * @since 5.0.0
332
+ *
333
+ * @param array $links The prepared links of the REST response.
334
+ * @param stdClass $blog Blog object.
335
+ */
336
+ return apply_filters( 'bp_rest_blogs_prepare_links', $links, $blog );
337
+ }
338
+
339
+ /**
340
+ * Get blog permalink.
341
+ *
342
+ * @param stdClass $blog Blog object.
343
+ * @return string
344
+ */
345
+ protected function get_blog_domain( $blog ) {
346
+
347
+ // Bail early.
348
+ if ( empty( $blog->domain ) && empty( $blog->path ) ) {
349
+ return '';
350
+ }
351
+
352
+ if ( empty( $blog->domain ) && ! empty( $blog->path ) ) {
353
+ return bp_get_root_domain() . $blog->path;
354
+ }
355
+
356
+ $protocol = is_ssl() ? 'https://' : 'http://';
357
+ $permalink = $protocol . $blog->domain . $blog->path;
358
+
359
+ return apply_filters( 'bp_get_blog_permalink', $permalink );
360
+ }
361
+
362
+ /**
363
+ * Get a blog object from a blog_id.
364
+ *
365
+ * @since 6.0.0
366
+ *
367
+ * @param int $blog_id Blog ID.
368
+ * @return stdClass|int
369
+ */
370
+ public function get_blog_object( $blog_id ) {
371
+ $blogs = current(
372
+ bp_blogs_get_blogs(
373
+ array(
374
+ 'include_blog_ids' => array( $blog_id ),
375
+ )
376
+ )
377
+ );
378
+
379
+ if ( ! empty( $blogs[0] ) ) {
380
+ return $blogs[0];
381
+ }
382
+
383
+ return 0;
384
+ }
385
+
386
+ /**
387
+ * Get the blogs schema, conforming to JSON Schema.
388
+ *
389
+ * @since 6.0.0
390
+ *
391
+ * @return array
392
+ */
393
+ public function get_item_schema() {
394
+ $schema = array(
395
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
396
+ 'title' => 'bp_blogs',
397
+ 'type' => 'object',
398
+ 'properties' => array(
399
+ 'id' => array(
400
+ 'context' => array( 'view', 'edit' ),
401
+ 'description' => __( 'A unique numeric ID for the blog.', 'buddypress' ),
402
+ 'readonly' => true,
403
+ 'type' => 'integer',
404
+ ),
405
+ 'user_id' => array(
406
+ 'context' => array( 'view', 'edit' ),
407
+ 'description' => __( 'A unique numeric ID for the blog admin.', 'buddypress' ),
408
+ 'readonly' => true,
409
+ 'type' => 'integer',
410
+ ),
411
+ 'name' => array(
412
+ 'context' => array( 'view', 'edit' ),
413
+ 'description' => __( 'The name of the blog.', 'buddypress' ),
414
+ 'readonly' => true,
415
+ 'type' => 'string',
416
+ 'arg_options' => array(
417
+ 'sanitize_callback' => 'sanitize_text_field',
418
+ ),
419
+ ),
420
+ 'permalink' => array(
421
+ 'context' => array( 'view', 'edit' ),
422
+ 'description' => __( 'The permalink of the blog.', 'buddypress' ),
423
+ 'readonly' => true,
424
+ 'type' => 'string',
425
+ 'format' => 'uri',
426
+ ),
427
+ 'description' => array(
428
+ 'context' => array( 'view', 'edit' ),
429
+ 'description' => __( 'The description of the blog.', 'buddypress' ),
430
+ 'readonly' => true,
431
+ 'type' => 'string',
432
+ ),
433
+ 'path' => array(
434
+ 'context' => array( 'view', 'edit' ),
435
+ 'description' => __( 'The path of the blog.', 'buddypress' ),
436
+ 'readonly' => true,
437
+ 'type' => 'string',
438
+ ),
439
+ 'domain' => array(
440
+ 'context' => array( 'view', 'edit' ),
441
+ 'description' => __( 'the domain of the blog.', 'buddypress' ),
442
+ 'readonly' => true,
443
+ 'type' => 'string',
444
+ ),
445
+ 'last_activity' => array(
446
+ 'context' => array( 'view', 'edit' ),
447
+ 'description' => __( "The last activity date from the blog, in the site's timezone.", 'buddypress' ),
448
+ 'type' => 'string',
449
+ 'format' => 'date-time',
450
+ ),
451
+ ),
452
+ );
453
+
454
+ // Blog Avatars.
455
+ if ( ! buddypress()->avatar->show_avatars ) {
456
+ $avatar_properties = array();
457
+
458
+ $avatar_properties['full'] = array(
459
+ /* translators: 1: Full avatar width in pixels. 2: Full avatar height in pixels */
460
+ 'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),
461
+ 'type' => 'string',
462
+ 'format' => 'uri',
463
+ 'context' => array( 'view', 'edit' ),
464
+ );
465
+
466
+ $avatar_properties['thumb'] = array(
467
+ /* translators: 1: Thumb avatar width in pixels. 2: Thumb avatar height in pixels */
468
+ 'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),
469
+ 'type' => 'string',
470
+ 'format' => 'uri',
471
+ 'context' => array( 'view', 'edit' ),
472
+ );
473
+
474
+ $schema['properties']['avatar_urls'] = array(
475
+ 'description' => __( 'Avatar URLs for the blog.', 'buddypress' ),
476
+ 'type' => 'object',
477
+ 'context' => array( 'view', 'edit' ),
478
+ 'readonly' => true,
479
+ 'properties' => $avatar_properties,
480
+ );
481
+ }
482
+
483
+ /**
484
+ * Filter the blogs schema.
485
+ *
486
+ * @since 6.0.0
487
+ *
488
+ * @param array $schema The endpoint schema.
489
+ */
490
+ return apply_filters( 'bp_rest_blogs_schema', $this->add_additional_fields_schema( $schema ) );
491
+ }
492
+
493
+ /**
494
+ * Get the query params for blogs collections.
495
+ *
496
+ * @since 6.0.0
497
+ *
498
+ * @return array
499
+ */
500
+ public function get_collection_params() {
501
+ $params = parent::get_collection_params();
502
+ $params['context']['default'] = 'view';
503
+
504
+ $params['user_id'] = array(
505
+ 'description' => __( 'ID of the user whose blogs user can post to.', 'buddypress' ),
506
+ 'default' => 0,
507
+ 'type' => 'integer',
508
+ 'sanitize_callback' => 'absint',
509
+ 'validate_callback' => 'rest_validate_request_arg',
510
+ );
511
+
512
+ $params['include'] = array(
513
+ 'description' => __( 'Ensure result set includes specific IDs.', 'buddypress' ),
514
+ 'default' => array(),
515
+ 'type' => 'array',
516
+ 'items' => array( 'type' => 'integer' ),
517
+ 'sanitize_callback' => 'wp_parse_id_list',
518
+ 'validate_callback' => 'rest_validate_request_arg',
519
+ );
520
+
521
+ $params['type'] = array(
522
+ 'description' => __( 'Limit result set to items with a specific type.', 'buddypress' ),
523
+ 'default' => 'active',
524
+ 'type' => 'string',
525
+ 'enum' => array( 'active', 'alphabetical', 'newest', 'random' ),
526
+ 'sanitize_callback' => 'sanitize_key',
527
+ 'validate_callback' => 'rest_validate_request_arg',
528
+ );
529
+
530
+ /**
531
+ * Filters the collection query params.
532
+ *
533
+ * @param array $params Query params.
534
+ */
535
+ return apply_filters( 'bp_rest_blogs_collection_params', $params );
536
+ }
537
+ }
bp-blogs/screens/create.php CHANGED
@@ -14,11 +14,9 @@
14
  */
15
  function bp_blogs_screen_create_a_blog() {
16
 
17
- if ( !is_multisite() || !bp_is_blogs_component() || !bp_is_current_action( 'create' ) )
18
- return false;
19
-
20
- if ( !is_user_logged_in() || !bp_blog_signup_enabled() )
21
  return false;
 
22
 
23
  /**
24
  * Fires right before the loading of the Create A Blog screen template file.
14
  */
15
  function bp_blogs_screen_create_a_blog() {
16
 
17
+ if ( ! is_multisite() || ! bp_is_blogs_component() || ! bp_is_current_action( 'create' ) || ! is_user_logged_in() || ! bp_blog_signup_enabled() ) {
 
 
 
18
  return false;
19
+ }
20
 
21
  /**
22
  * Fires right before the loading of the Create A Blog screen template file.
bp-core/admin/bp-core-admin-actions.php CHANGED
@@ -46,7 +46,7 @@ add_action( 'customize_controls_enqueue_scripts', 'bp_admin_enqueue_scripts', 8
46
  add_action( 'network_admin_menu', 'bp_admin_menu' );
47
  add_action( 'custom_menu_order', 'bp_admin_custom_menu_order' );
48
  add_action( 'menu_order', 'bp_admin_menu_order' );
49
- add_action( 'wpmu_new_blog', 'bp_new_site', 10, 6 );
50
 
51
  // Hook on to admin_init.
52
  add_action( 'bp_admin_init', 'bp_setup_updater', 1000 );
46
  add_action( 'network_admin_menu', 'bp_admin_menu' );
47
  add_action( 'custom_menu_order', 'bp_admin_custom_menu_order' );
48
  add_action( 'menu_order', 'bp_admin_menu_order' );
49
+ add_action( 'bp_insert_site', 'bp_new_site', 10, 6 );
50
 
51
  // Hook on to admin_init.
52
  add_action( 'bp_admin_init', 'bp_setup_updater', 1000 );
bp-core/admin/bp-core-admin-components.php CHANGED
@@ -142,24 +142,70 @@ function bp_core_admin_components_options() {
142
  case 'retired' :
143
  $current_components = $retired_components;
144
  break;
145
- } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
 
147
  <h3 class="screen-reader-text"><?php
148
  /* translators: accessibility text */
149
- _e( 'Filter components list', 'buddypress' );
150
  ?></h3>
151
 
152
  <ul class="subsubsub">
153
- <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>
154
- <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'active' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'active' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', count( $active_components ), 'buddypress' ), number_format_i18n( count( $active_components ) ) ); ?></a> | </li>
155
- <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'inactive' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'inactive' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Inactive <span class="count">(%s)</span>', 'Inactive <span class="count">(%s)</span>', count( $inactive_components ), 'buddypress' ), number_format_i18n( count( $inactive_components ) ) ); ?></a> | </li>
156
- <li><a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => 'mustuse' ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === 'mustuse' ) : ?>class="current"<?php endif; ?>><?php printf( _n( 'Must-Use <span class="count">(%s)</span>', 'Must-Use <span class="count">(%s)</span>', count( $required_components ), 'buddypress' ), number_format_i18n( count( $required_components ) ) ); ?></a> | </li>
157
- <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>
 
 
158
  </ul>
159
 
160
  <h3 class="screen-reader-text"><?php
161
  /* translators: accessibility text */
162
- _e( 'Components list', 'buddypress' );
163
  ?></h3>
164
 
165
  <table class="wp-list-table widefat plugins">
142
  case 'retired' :
143
  $current_components = $retired_components;
144
  break;
145
+ }
146
+
147
+ $component_views = array(
148
+ array(
149
+ 'action' => 'all',
150
+ 'view' => sprintf(
151
+ /* translators: %s: the number of installed components */
152
+ _nx( 'All <span class="count">(%s)</span>', 'All <span class="count">(%s)</span>', $all_count, 'plugins', 'buddypress' ),
153
+ number_format_i18n( $all_count )
154
+ ),
155
+ ),
156
+ array(
157
+ 'action' => 'active',
158
+ 'view' => sprintf(
159
+ /* translators: %s: the number of active components */
160
+ _n( 'Active <span class="count">(%s)</span>', 'Active <span class="count">(%s)</span>', count( $active_components ), 'buddypress' ),
161
+ number_format_i18n( count( $active_components ) )
162
+ ),
163
+ ),
164
+ array(
165
+ 'action' => 'inactive',
166
+ 'view' => sprintf(
167
+ /* translators: %s: the number of inactive components */
168
+ _n( 'Inactive <span class="count">(%s)</span>', 'Inactive <span class="count">(%s)</span>', count( $inactive_components ), 'buddypress' ),
169
+ number_format_i18n( count( $inactive_components ) )
170
+ ),
171
+ ),
172
+ array(
173
+ 'action' => 'mustuse',
174
+ 'view' => sprintf(
175
+ /* translators: %s: the number of must-Use components */
176
+ _n( 'Must-Use <span class="count">(%s)</span>', 'Must-Use <span class="count">(%s)</span>', count( $required_components ), 'buddypress' ),
177
+ number_format_i18n( count( $required_components ) )
178
+ ),
179
+ ),
180
+ array(
181
+ 'action' => 'retired',
182
+ 'view' => sprintf(
183
+ /* translators: %s: the number of retired components */
184
+ _n( 'Retired <span class="count">(%s)</span>', 'Retired <span class="count">(%s)</span>', count( $retired_components ), 'buddypress' ),
185
+ number_format_i18n( count( $retired_components ) )
186
+ ),
187
+ ),
188
+ );
189
+ ?>
190
 
191
  <h3 class="screen-reader-text"><?php
192
  /* translators: accessibility text */
193
+ esc_html_e( 'Filter components list', 'buddypress' );
194
  ?></h3>
195
 
196
  <ul class="subsubsub">
197
+ <?php foreach ( $component_views as $component_view ) : ?>
198
+ <li>
199
+ <a href="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-components', 'action' => $component_view['action'] ), bp_get_admin_url( $page ) ) ); ?>" <?php if ( $action === $component_view['action'] ) : ?>class="current"<?php endif; ?>>
200
+ <?php echo wp_kses( $component_view['view'], array( 'span' => array( 'class' => true ) ) ); ?>
201
+ </a><?php echo 'retired' !== $component_view['action'] ? ' |' : ''; ?>
202
+ </li>
203
+ <?php endforeach ;?>
204
  </ul>
205
 
206
  <h3 class="screen-reader-text"><?php
207
  /* translators: accessibility text */
208
+ esc_html_e( 'Components list', 'buddypress' );
209
  ?></h3>
210
 
211
  <table class="wp-list-table widefat plugins">
bp-core/admin/bp-core-admin-functions.php CHANGED
@@ -14,7 +14,6 @@ defined( 'ABSPATH' ) || exit;
14
 
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 );
@@ -65,7 +64,7 @@ add_action( bp_core_admin_hook(), 'bp_core_admin_backpat_menu', 999 );
65
  * This tells WP to highlight the Settings > BuddyPress menu item,
66
  * regardless of which actual BuddyPress admin screen we are on.
67
  *
68
- * The conditional prevents the behaviour when the user is viewing the
69
  * backpat "Help" page, the Activity page, or any third-party plugins.
70
  *
71
  * @global string $plugin_page
@@ -77,7 +76,7 @@ function bp_core_modify_admin_menu_highlight() {
77
  global $plugin_page, $submenu_file;
78
 
79
  // This tweaks the Settings subnav menu to show only one BuddyPress menu item.
80
- if ( ! in_array( $plugin_page, array( 'bp-activity', 'bp-general-settings', ) ) ) {
81
  $submenu_file = 'bp-components';
82
  }
83
 
@@ -96,7 +95,7 @@ function bp_core_modify_admin_menu_highlight() {
96
  *
97
  * @since 1.6.0
98
  *
99
- * @todo Add convenience links into the markup once new positions are finalised.
100
  */
101
  function bp_core_admin_backpat_page() {
102
  $url = bp_core_do_network_admin() ? network_admin_url( 'settings.php' ) : admin_url( 'options-general.php' );
@@ -106,7 +105,16 @@ function bp_core_admin_backpat_page() {
106
  <h2><?php _e( 'Why have all my BuddyPress menus disappeared?', 'buddypress' ); ?></h2>
107
 
108
  <p><?php _e( "Don't worry! We've moved the BuddyPress options into more convenient and easier to find locations. You're seeing this page because you are running a legacy BuddyPress plugin which has not been updated.", 'buddypress' ); ?></p>
109
- <p><?php printf( __( 'Components, Pages, Settings, and Forums, have been moved to <a href="%s">Settings &gt; BuddyPress</a>. Profile Fields has been moved into the <a href="%s">Users</a> menu.', 'buddypress' ), esc_url( $settings_url ), bp_get_admin_url( 'users.php?page=bp-profile-setup' ) ); ?></p>
 
 
 
 
 
 
 
 
 
110
  </div>
111
 
112
  <?php
@@ -121,7 +129,6 @@ function bp_core_admin_backpat_page() {
121
  * boxes.
122
  *
123
  * @since 1.5.0
124
- *
125
  */
126
  function bp_core_print_admin_notices() {
127
 
@@ -153,7 +160,7 @@ function bp_core_print_admin_notices() {
153
  printf( '</div>' );
154
  }
155
  }
156
- add_action( 'admin_notices', 'bp_core_print_admin_notices' );
157
  add_action( 'network_admin_notices', 'bp_core_print_admin_notices' );
158
 
159
  /**
@@ -240,7 +247,14 @@ function bp_core_activation_notice() {
240
 
241
  // Add notice if no rewrite rules are enabled.
242
  if ( empty( $wp_rewrite->permalink_structure ) ) {
243
- bp_core_add_admin_notice( sprintf( __( '<strong>BuddyPress is almost ready</strong>. You must <a href="%s">update your permalink structure</a> to something other than the default for it to work.', 'buddypress' ), admin_url( 'options-permalink.php' ) ), 'error' );
 
 
 
 
 
 
 
244
  }
245
 
246
  // Get BuddyPress instance.
@@ -253,11 +267,11 @@ function bp_core_activation_notice() {
253
  $wp_page_components = array();
254
 
255
  // Only components with 'has_directory' require a WP page to function.
256
- foreach( array_keys( $bp->loaded_components ) as $component_id ) {
257
- if ( !empty( $bp->{$component_id}->has_directory ) ) {
258
  $wp_page_components[] = array(
259
  'id' => $component_id,
260
- 'name' => isset( $bp->{$component_id}->name ) ? $bp->{$component_id}->name : ucwords( $bp->{$component_id}->id )
261
  );
262
  }
263
  }
@@ -267,12 +281,12 @@ function bp_core_activation_notice() {
267
  if ( bp_get_signup_allowed() ) {
268
  $wp_page_components[] = array(
269
  'id' => 'activate',
270
- 'name' => __( 'Activate', 'buddypress' )
271
  );
272
 
273
  $wp_page_components[] = array(
274
  'id' => 'register',
275
- 'name' => __( 'Register', 'buddypress' )
276
  );
277
  }
278
 
@@ -282,17 +296,18 @@ function bp_core_activation_notice() {
282
  $bp->pages = bp_core_get_directory_pages();
283
  }
284
 
285
- foreach( $wp_page_components as $component ) {
286
- if ( !isset( $bp->pages->{$component['id']} ) ) {
287
  $orphaned_components[] = $component['name'];
288
  }
289
  }
290
 
291
- if ( !empty( $orphaned_components ) ) {
292
  $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
293
  $notice = sprintf(
294
  '%1$s <a href="%2$s">%3$s</a>',
295
  sprintf(
 
296
  __( 'The following active BuddyPress Components do not have associated WordPress Pages: %s.', 'buddypress' ),
297
  '<strong>' . implode( '</strong>, <strong>', array_map( 'esc_html', $orphaned_components ) ) . '</strong>'
298
  ),
@@ -308,8 +323,8 @@ function bp_core_activation_notice() {
308
  $page_ids = bp_core_get_directory_page_ids();
309
  $dupes = array_diff_assoc( $page_ids, array_unique( $page_ids ) );
310
 
311
- if ( !empty( $dupes ) ) {
312
- foreach( array_keys( $dupes ) as $dupe_component ) {
313
  $dupe_names[] = $bp->pages->{$dupe_component}->title;
314
  }
315
 
@@ -318,11 +333,12 @@ function bp_core_activation_notice() {
318
  }
319
 
320
  // If there are duplicates, post a message about them.
321
- if ( !empty( $dupe_names ) ) {
322
  $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
323
  $notice = sprintf(
324
  '%1$s <a href="%2$s">%3$s</a>',
325
  sprintf(
 
326
  __( 'Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %s.', 'buddypress' ),
327
  '<strong>' . implode( '</strong>, <strong>', array_map( 'esc_html', $dupe_names ) ) . '</strong>'
328
  ),
@@ -340,7 +356,6 @@ function bp_core_activation_notice() {
340
  * @since 1.7.0
341
  *
342
  * @internal Used internally to redirect BuddyPress to the about page on activation.
343
- *
344
  */
345
  function bp_do_activation_redirect() {
346
 
@@ -388,7 +403,7 @@ function bp_core_admin_tabs( $active_tab = '' ) {
388
  *
389
  * @param array $value Array of tabs to output to the admin area.
390
  */
391
- $tabs = apply_filters( 'bp_core_admin_tabs', bp_core_get_admin_tabs( $active_tab ) );
392
 
393
  // Loop through tabs and build navigation.
394
  foreach ( array_values( $tabs ) as $tab_data ) {
@@ -419,19 +434,19 @@ function bp_core_get_admin_tabs( $active_tab = '' ) {
419
  $tabs = array(
420
  '0' => array(
421
  'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), 'admin.php' ) ),
422
- 'name' => __( 'Components', 'buddypress' )
423
  ),
424
  '2' => array(
425
  'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ),
426
- 'name' => __( 'Options', 'buddypress' )
427
  ),
428
  '1' => array(
429
  'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) ),
430
- 'name' => __( 'Pages', 'buddypress' )
431
  ),
432
  '3' => array(
433
  'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-credits' ), 'admin.php' ) ),
434
- 'name' => __( 'Credits', 'buddypress' )
435
  ),
436
  );
437
 
@@ -462,14 +477,15 @@ function bp_core_add_contextual_help( $screen = '' ) {
462
  switch ( $screen->id ) {
463
 
464
  // Component page.
465
- case 'settings_page_bp-components' :
466
-
467
  // Help tabs.
468
- $screen->add_help_tab( array(
469
- 'id' => 'bp-comp-overview',
470
- 'title' => __( 'Overview', 'buddypress' ),
471
- 'content' => bp_core_add_contextual_help_content( 'bp-comp-overview' ),
472
- ) );
 
 
473
 
474
  // Help panel - sidebar links.
475
  $screen->set_help_sidebar(
@@ -480,14 +496,15 @@ function bp_core_add_contextual_help( $screen = '' ) {
480
  break;
481
 
482
  // Pages page.
483
- case 'settings_page_bp-page-settings' :
484
-
485
  // Help tabs.
486
- $screen->add_help_tab( array(
487
- 'id' => 'bp-page-overview',
488
- 'title' => __( 'Overview', 'buddypress' ),
489
- 'content' => bp_core_add_contextual_help_content( 'bp-page-overview' ),
490
- ) );
 
 
491
 
492
  // Help panel - sidebar links.
493
  $screen->set_help_sidebar(
@@ -499,14 +516,15 @@ function bp_core_add_contextual_help( $screen = '' ) {
499
  break;
500
 
501
  // Settings page.
502
- case 'settings_page_bp-settings' :
503
-
504
  // Help tabs.
505
- $screen->add_help_tab( array(
506
- 'id' => 'bp-settings-overview',
507
- 'title' => __( 'Overview', 'buddypress' ),
508
- 'content' => bp_core_add_contextual_help_content( 'bp-settings-overview' ),
509
- ) );
 
 
510
 
511
  // Help panel - sidebar links.
512
  $screen->set_help_sidebar(
@@ -518,14 +536,15 @@ function bp_core_add_contextual_help( $screen = '' ) {
518
  break;
519
 
520
  // Profile fields page.
521
- case 'users_page_bp-profile-setup' :
522
-
523
  // Help tabs.
524
- $screen->add_help_tab( array(
525
- 'id' => 'bp-profile-overview',
526
- 'title' => __( 'Overview', 'buddypress' ),
527
- 'content' => bp_core_add_contextual_help_content( 'bp-profile-overview' ),
528
- ) );
 
 
529
 
530
  // Help panel - sidebar links.
531
  $screen->set_help_sidebar(
@@ -553,19 +572,19 @@ add_action( 'load-users_page_bp-profile-setup', 'bp_core_add_contextual_help' );
553
  function bp_core_add_contextual_help_content( $tab = '' ) {
554
 
555
  switch ( $tab ) {
556
- case 'bp-comp-overview' :
557
  $retval = __( 'By default, all but four of the BuddyPress components are enabled. You can selectively enable or disable any of the components by using the form below. Your BuddyPress installation will continue to function. However, the features of the disabled components will no longer be accessible to anyone using the site.', 'buddypress' );
558
  break;
559
 
560
- case 'bp-page-overview' :
561
  $retval = __( 'BuddyPress Components use WordPress Pages for their root directory/archive pages. You can change the page associations for each active component by using the form below.', 'buddypress' );
562
  break;
563
 
564
- case 'bp-settings-overview' :
565
  $retval = __( 'Extra configuration settings are provided and activated. You can selectively enable or disable any setting by using the form on this screen.', 'buddypress' );
566
  break;
567
 
568
- case 'bp-profile-overview' :
569
  $retval = __( 'Your users will distinguish themselves through their profile page. Create relevant profile fields that will show on each users profile.', 'buddypress' ) . '<br /><br />' . __( 'Note: Any fields in the first group will appear on the signup page.', 'buddypress' );
570
  break;
571
 
@@ -575,7 +594,7 @@ function bp_core_add_contextual_help_content( $tab = '' ) {
575
  }
576
 
577
  // Wrap text in a paragraph tag.
578
- if ( !empty( $retval ) ) {
579
  $retval = '<p>' . $retval . '</p>';
580
  }
581
 
@@ -588,7 +607,6 @@ function bp_core_add_contextual_help_content( $tab = '' ) {
588
  * Add a separator to the WordPress admin menus.
589
  *
590
  * @since 1.7.0
591
- *
592
  */
593
  function bp_admin_separator() {
594
 
@@ -655,7 +673,7 @@ function bp_admin_menu_order( $menu_order = array() ) {
655
  $bp_menu_order = array();
656
 
657
  // Menu values.
658
- $last_sep = is_network_admin() ? 'separator1' : 'separator2';
659
 
660
  /**
661
  * Filters the custom admin menus.
@@ -681,7 +699,7 @@ function bp_admin_menu_order( $menu_order = array() ) {
681
  if ( $last_sep == $item ) {
682
 
683
  // Add our custom menus.
684
- foreach( (array) $custom_menus as $custom_menu ) {
685
  if ( array_search( $custom_menu, $menu_order ) ) {
686
  $bp_menu_order[] = $custom_menu;
687
  }
@@ -690,7 +708,7 @@ function bp_admin_menu_order( $menu_order = array() ) {
690
  // Add the appearance separator.
691
  $bp_menu_order[] = $last_sep;
692
 
693
- // Skip our menu items.
694
  } elseif ( ! in_array( $item, $custom_menus ) ) {
695
  $bp_menu_order[] = $item;
696
  }
@@ -718,7 +736,7 @@ function bp_admin_list_table_current_bulk_action() {
718
  $action = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
719
 
720
  // If the bottom is set, let it override the action.
721
- if ( ! empty( $_REQUEST['action2'] ) && $_REQUEST['action2'] != "-1" ) {
722
  $action = $_REQUEST['action2'];
723
  }
724
 
@@ -759,8 +777,8 @@ function bp_admin_do_wp_nav_menu_meta_box() {
759
 
760
  $tabs = array();
761
 
762
- $tabs['loggedin']['label'] = __( 'Logged-In', 'buddypress' );
763
- $tabs['loggedin']['pages'] = bp_nav_menu_get_loggedin_pages();
764
 
765
  $tabs['loggedout']['label'] = __( 'Logged-Out', 'buddypress' );
766
  $tabs['loggedout']['pages'] = bp_nav_menu_get_loggedout_pages();
@@ -768,21 +786,21 @@ function bp_admin_do_wp_nav_menu_meta_box() {
768
  ?>
769
 
770
  <div id="buddypress-menu" class="posttypediv">
771
- <h4><?php _e( 'Logged-In', 'buddypress' ) ?></h4>
772
- <p><?php _e( '<em>Logged-In</em> links are relative to the current user, and are not visible to visitors who are not logged in.', 'buddypress' ) ?></p>
773
 
774
  <div id="tabs-panel-posttype-<?php echo $post_type_name; ?>-loggedin" class="tabs-panel tabs-panel-active">
775
  <ul id="buddypress-menu-checklist-loggedin" class="categorychecklist form-no-clear">
776
- <?php echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $tabs['loggedin']['pages'] ), 0, (object) $args );?>
777
  </ul>
778
  </div>
779
 
780
- <h4><?php _e( 'Logged-Out', 'buddypress' ) ?></h4>
781
- <p><?php _e( '<em>Logged-Out</em> links are not visible to users who are logged in.', 'buddypress' ) ?></p>
782
 
783
  <div id="tabs-panel-posttype-<?php echo $post_type_name; ?>-loggedout" class="tabs-panel tabs-panel-active">
784
  <ul id="buddypress-menu-checklist-loggedout" class="categorychecklist form-no-clear">
785
- <?php echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $tabs['loggedout']['pages'] ), 0, (object) $args );?>
786
  </ul>
787
  </div>
788
 
@@ -799,18 +817,28 @@ function bp_admin_do_wp_nav_menu_meta_box() {
799
 
800
  <p class="button-controls">
801
  <span class="list-controls">
802
- <a href="<?php
803
- echo esc_url( add_query_arg(
804
- array(
805
- $post_type_name . '-tab' => 'all',
806
- 'selectall' => 1,
807
- ),
808
- remove_query_arg( $removed_args )
809
- ) );
810
- ?>#buddypress-menu" class="select-all"><?php _e( 'Select All', 'buddypress' ); ?></a>
 
 
 
 
811
  </span>
812
  <span class="add-to-menu">
813
- <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" />
 
 
 
 
 
 
814
  <span class="spinner"></span>
815
  </span>
816
  </p>
@@ -845,6 +873,7 @@ function bp_admin_email_maybe_add_translation_notice() {
845
 
846
  bp_core_add_admin_notice(
847
  sprintf(
 
848
  __( 'Are these emails not written in your site\'s language? Go to <a href="%s">BuddyPress Tools and try the "reinstall emails"</a> tool.', 'buddypress' ),
849
  esc_url( add_query_arg( 'page', 'bp-tools', bp_get_admin_url( $admin_page ) ) )
850
  ),
@@ -865,6 +894,7 @@ function bp_admin_email_add_codex_notice() {
865
 
866
  bp_core_add_admin_notice(
867
  sprintf(
 
868
  __( 'Phrases wrapped in braces <code>{{ }}</code> are email tokens. <a href="%s">Learn about tokens on the BuddyPress Codex</a>.', 'buddypress' ),
869
  esc_url( 'https://codex.buddypress.org/emails/email-tokens/' )
870
  ),
@@ -891,7 +921,7 @@ add_action( 'admin_head-post.php', 'bp_admin_email_add_codex_notice' );
891
  */
892
  function bp_email_tax_type_metabox( $post, $box ) {
893
  $r = array(
894
- 'taxonomy' => bp_get_email_tax_type()
895
  );
896
 
897
  $tax_name = esc_attr( $r['taxonomy'] );
@@ -904,7 +934,15 @@ function bp_email_tax_type_metabox( $post, $box ) {
904
  echo "<input type='hidden' name='{$name}[]' value='0' />"; // Allows for an empty term set to be sent. 0 is an invalid Term ID and will be ignored by empty() checks.
905
  ?>
906
  <ul id="<?php echo $tax_name; ?>checklist" data-wp-lists="list:<?php echo $tax_name; ?>" class="categorychecklist form-no-clear">
907
- <?php wp_terms_checklist( $post->ID, array( 'taxonomy' => $tax_name, 'walker' => new BP_Walker_Category_Checklist ) ); ?>
 
 
 
 
 
 
 
 
908
  </ul>
909
  </div>
910
 
@@ -935,16 +973,18 @@ add_action( 'add_meta_boxes_' . bp_get_email_post_type(), 'bp_email_custom_metab
935
  * @param WP_Post $post
936
  */
937
  function bp_email_plaintext_metabox( $post ) {
938
- ?>
939
 
940
- <label class="screen-reader-text" for="excerpt"><?php
 
941
  /* translators: accessibility text */
942
  _e( 'Plain text email content', 'buddypress' );
943
- ?></label><textarea rows="5" cols="40" name="excerpt" id="excerpt"><?php echo $post->post_excerpt; // textarea_escaped ?></textarea>
 
944
 
945
  <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>
946
 
947
- <?php
948
  }
949
 
950
  /**
@@ -964,7 +1004,7 @@ function bp_email_plaintext_metabox( $post ) {
964
  * @since 1.9.0
965
  */
966
  function bp_admin_wp_nav_menu_restrict_items() {
967
- ?>
968
  <script type="text/javascript">
969
  jQuery( '#menu-to-edit').on( 'click', 'a.item-edit', function() {
970
  var settings = jQuery(this).closest( '.menu-item-bar' ).next( '.menu-item-settings' );
@@ -976,7 +1016,7 @@ function bp_admin_wp_nav_menu_restrict_items() {
976
  }
977
  });
978
  </script>
979
- <?php
980
  }
981
 
982
  /**
@@ -992,7 +1032,7 @@ function bp_core_admin_user_row_actions( $actions, $user_object ) {
992
 
993
  // Setup the $user_id variable from the current user object.
994
  $user_id = 0;
995
- if ( !empty( $user_object->ID ) ) {
996
  $user_id = absint( $user_object->ID );
997
  }
998
 
@@ -1004,13 +1044,25 @@ function bp_core_admin_user_row_actions( $actions, $user_object ) {
1004
 
1005
  // If spammed, create unspam link.
1006
  if ( bp_is_user_spammer( $user_id ) ) {
1007
- $url = add_query_arg( array( 'action' => 'ham', 'user' => $user_id ), $url );
1008
- $unspam_link = wp_nonce_url( $url, 'bp-spam-user' );
1009
- $actions['ham'] = sprintf( '<a href="%1$s">%2$s</a>', esc_url( $unspam_link ), esc_html__( 'Not Spam', 'buddypress' ) );
 
 
 
 
 
 
1010
 
1011
- // If not already spammed, create spam link.
1012
  } else {
1013
- $url = add_query_arg( array( 'action' => 'spam', 'user' => $user_id ), $url );
 
 
 
 
 
 
1014
  $spam_link = wp_nonce_url( $url, 'bp-spam-user' );
1015
  $actions['spam'] = sprintf( '<a class="submitdelete" href="%1$s">%2$s</a>', esc_url( $spam_link ), esc_html__( 'Spam', 'buddypress' ) );
1016
  }
@@ -1141,8 +1193,8 @@ add_filter( 'admin_body_class', 'bp_core_admin_body_classes' );
1141
  *
1142
  * @since 5.0.0
1143
  *
1144
- * @param array $categories Array of block categories.
1145
- * @param object $post Post being loaded.
1146
  */
1147
  function bp_block_category( $categories = array(), $post = null ) {
1148
  if ( ! ( $post instanceof WP_Post ) ) {
@@ -1169,12 +1221,15 @@ function bp_block_category( $categories = array(), $post = null ) {
1169
  return $categories;
1170
  }
1171
 
1172
- return array_merge( $categories, array(
 
1173
  array(
1174
- 'slug' => 'buddypress',
1175
- 'title' => __( 'BuddyPress', 'buddypress' ),
1176
- 'icon' => 'buddicons-buddypress-logo',
1177
- ),
1178
- ) );
 
 
1179
  }
1180
  add_filter( 'block_categories', 'bp_block_category', 1, 2 );
14
 
15
  /**
16
  * Initializes the wp-admin area "BuddyPress" menus and sub menus.
 
17
  */
18
  function bp_core_admin_menu_init() {
19
  add_action( bp_core_admin_hook(), 'bp_core_add_admin_menu', 9 );
64
  * This tells WP to highlight the Settings > BuddyPress menu item,
65
  * regardless of which actual BuddyPress admin screen we are on.
66
  *
67
+ * The conditional prevents the behavior when the user is viewing the
68
  * backpat "Help" page, the Activity page, or any third-party plugins.
69
  *
70
  * @global string $plugin_page
76
  global $plugin_page, $submenu_file;
77
 
78
  // This tweaks the Settings subnav menu to show only one BuddyPress menu item.
79
+ if ( ! in_array( $plugin_page, array( 'bp-activity', 'bp-general-settings' ) ) ) {
80
  $submenu_file = 'bp-components';
81
  }
82
 
95
  *
96
  * @since 1.6.0
97
  *
98
+ * @todo Add convenience links into the markup once new positions are finalized.
99
  */
100
  function bp_core_admin_backpat_page() {
101
  $url = bp_core_do_network_admin() ? network_admin_url( 'settings.php' ) : admin_url( 'options-general.php' );
105
  <h2><?php _e( 'Why have all my BuddyPress menus disappeared?', 'buddypress' ); ?></h2>
106
 
107
  <p><?php _e( "Don't worry! We've moved the BuddyPress options into more convenient and easier to find locations. You're seeing this page because you are running a legacy BuddyPress plugin which has not been updated.", 'buddypress' ); ?></p>
108
+ <p>
109
+ <?php
110
+ printf(
111
+ // Translators: 1: is the url to the BP Components settings screen. 2: is the url to the xProfile administration screen.
112
+ __( 'Components, Pages, Settings, and Forums, have been moved to <a href="%1$s">Settings &gt; BuddyPress</a>. Profile Fields has been moved into the <a href="%2$s">Users</a> menu.', 'buddypress' ),
113
+ esc_url( $settings_url ),
114
+ bp_get_admin_url( 'users.php?page=bp-profile-setup' )
115
+ );
116
+ ?>
117
+ </p>
118
  </div>
119
 
120
  <?php
129
  * boxes.
130
  *
131
  * @since 1.5.0
 
132
  */
133
  function bp_core_print_admin_notices() {
134
 
160
  printf( '</div>' );
161
  }
162
  }
163
+ add_action( 'admin_notices', 'bp_core_print_admin_notices' );
164
  add_action( 'network_admin_notices', 'bp_core_print_admin_notices' );
165
 
166
  /**
247
 
248
  // Add notice if no rewrite rules are enabled.
249
  if ( empty( $wp_rewrite->permalink_structure ) ) {
250
+ bp_core_add_admin_notice(
251
+ sprintf(
252
+ // Translators: %s is the url to the permalink settings.
253
+ __( '<strong>BuddyPress is almost ready</strong>. You must <a href="%s">update your permalink structure</a> to something other than the default for it to work.', 'buddypress' ),
254
+ admin_url( 'options-permalink.php' )
255
+ ),
256
+ 'error'
257
+ );
258
  }
259
 
260
  // Get BuddyPress instance.
267
  $wp_page_components = array();
268
 
269
  // Only components with 'has_directory' require a WP page to function.
270
+ foreach ( array_keys( $bp->loaded_components ) as $component_id ) {
271
+ if ( ! empty( $bp->{$component_id}->has_directory ) ) {
272
  $wp_page_components[] = array(
273
  'id' => $component_id,
274
+ 'name' => isset( $bp->{$component_id}->name ) ? $bp->{$component_id}->name : ucwords( $bp->{$component_id}->id ),
275
  );
276
  }
277
  }
281
  if ( bp_get_signup_allowed() ) {
282
  $wp_page_components[] = array(
283
  'id' => 'activate',
284
+ 'name' => __( 'Activate', 'buddypress' ),
285
  );
286
 
287
  $wp_page_components[] = array(
288
  'id' => 'register',
289
+ 'name' => __( 'Register', 'buddypress' ),
290
  );
291
  }
292
 
296
  $bp->pages = bp_core_get_directory_pages();
297
  }
298
 
299
+ foreach ( $wp_page_components as $component ) {
300
+ if ( ! isset( $bp->pages->{$component['id']} ) ) {
301
  $orphaned_components[] = $component['name'];
302
  }
303
  }
304
 
305
+ if ( ! empty( $orphaned_components ) ) {
306
  $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
307
  $notice = sprintf(
308
  '%1$s <a href="%2$s">%3$s</a>',
309
  sprintf(
310
+ // Translators: %s is the comma separated list of components needing a directory page.
311
  __( 'The following active BuddyPress Components do not have associated WordPress Pages: %s.', 'buddypress' ),
312
  '<strong>' . implode( '</strong>, <strong>', array_map( 'esc_html', $orphaned_components ) ) . '</strong>'
313
  ),
323
  $page_ids = bp_core_get_directory_page_ids();
324
  $dupes = array_diff_assoc( $page_ids, array_unique( $page_ids ) );
325
 
326
+ if ( ! empty( $dupes ) ) {
327
+ foreach ( array_keys( $dupes ) as $dupe_component ) {
328
  $dupe_names[] = $bp->pages->{$dupe_component}->title;
329
  }
330
 
333
  }
334
 
335
  // If there are duplicates, post a message about them.
336
+ if ( ! empty( $dupe_names ) ) {
337
  $admin_url = bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) );
338
  $notice = sprintf(
339
  '%1$s <a href="%2$s">%3$s</a>',
340
  sprintf(
341
+ // Translators: %s is the list of directory pages associated to more than one component.
342
  __( 'Each BuddyPress Component needs its own WordPress page. The following WordPress Pages have more than one component associated with them: %s.', 'buddypress' ),
343
  '<strong>' . implode( '</strong>, <strong>', array_map( 'esc_html', $dupe_names ) ) . '</strong>'
344
  ),
356
  * @since 1.7.0
357
  *
358
  * @internal Used internally to redirect BuddyPress to the about page on activation.
 
359
  */
360
  function bp_do_activation_redirect() {
361
 
403
  *
404
  * @param array $value Array of tabs to output to the admin area.
405
  */
406
+ $tabs = apply_filters( 'bp_core_admin_tabs', bp_core_get_admin_tabs( $active_tab ) );
407
 
408
  // Loop through tabs and build navigation.
409
  foreach ( array_values( $tabs ) as $tab_data ) {
434
  $tabs = array(
435
  '0' => array(
436
  'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-components' ), 'admin.php' ) ),
437
+ 'name' => __( 'Components', 'buddypress' ),
438
  ),
439
  '2' => array(
440
  'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ),
441
+ 'name' => __( 'Options', 'buddypress' ),
442
  ),
443
  '1' => array(
444
  'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-page-settings' ), 'admin.php' ) ),
445
+ 'name' => __( 'Pages', 'buddypress' ),
446
  ),
447
  '3' => array(
448
  'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-credits' ), 'admin.php' ) ),
449
+ 'name' => __( 'Credits', 'buddypress' ),
450
  ),
451
  );
452
 
477
  switch ( $screen->id ) {
478
 
479
  // Component page.
480
+ case 'settings_page_bp-components':
 
481
  // Help tabs.
482
+ $screen->add_help_tab(
483
+ array(
484
+ 'id' => 'bp-comp-overview',
485
+ 'title' => __( 'Overview', 'buddypress' ),
486
+ 'content' => bp_core_add_contextual_help_content( 'bp-comp-overview' ),
487
+ )
488
+ );
489
 
490
  // Help panel - sidebar links.
491
  $screen->set_help_sidebar(
496
  break;
497
 
498
  // Pages page.
499
+ case 'settings_page_bp-page-settings':
 
500
  // Help tabs.
501
+ $screen->add_help_tab(
502
+ array(
503
+ 'id' => 'bp-page-overview',
504
+ 'title' => __( 'Overview', 'buddypress' ),
505
+ 'content' => bp_core_add_contextual_help_content( 'bp-page-overview' ),
506
+ )
507
+ );
508
 
509
  // Help panel - sidebar links.
510
  $screen->set_help_sidebar(
516
  break;
517
 
518
  // Settings page.
519
+ case 'settings_page_bp-settings':
 
520
  // Help tabs.
521
+ $screen->add_help_tab(
522
+ array(
523
+ 'id' => 'bp-settings-overview',
524
+ 'title' => __( 'Overview', 'buddypress' ),
525
+ 'content' => bp_core_add_contextual_help_content( 'bp-settings-overview' ),
526
+ )
527
+ );
528
 
529
  // Help panel - sidebar links.
530
  $screen->set_help_sidebar(
536
  break;
537
 
538
  // Profile fields page.
539
+ case 'users_page_bp-profile-setup':
 
540
  // Help tabs.
541
+ $screen->add_help_tab(
542
+ array(
543
+ 'id' => 'bp-profile-overview',
544
+ 'title' => __( 'Overview', 'buddypress' ),
545
+ 'content' => bp_core_add_contextual_help_content( 'bp-profile-overview' ),
546
+ )
547
+ );
548
 
549
  // Help panel - sidebar links.
550
  $screen->set_help_sidebar(
572
  function bp_core_add_contextual_help_content( $tab = '' ) {
573
 
574
  switch ( $tab ) {
575
+ case 'bp-comp-overview':
576
  $retval = __( 'By default, all but four of the BuddyPress components are enabled. You can selectively enable or disable any of the components by using the form below. Your BuddyPress installation will continue to function. However, the features of the disabled components will no longer be accessible to anyone using the site.', 'buddypress' );
577
  break;
578
 
579
+ case 'bp-page-overview':
580
  $retval = __( 'BuddyPress Components use WordPress Pages for their root directory/archive pages. You can change the page associations for each active component by using the form below.', 'buddypress' );
581
  break;
582
 
583
+ case 'bp-settings-overview':
584
  $retval = __( 'Extra configuration settings are provided and activated. You can selectively enable or disable any setting by using the form on this screen.', 'buddypress' );
585
  break;
586
 
587
+ case 'bp-profile-overview':
588
  $retval = __( 'Your users will distinguish themselves through their profile page. Create relevant profile fields that will show on each users profile.', 'buddypress' ) . '<br /><br />' . __( 'Note: Any fields in the first group will appear on the signup page.', 'buddypress' );
589
  break;
590
 
594
  }
595
 
596
  // Wrap text in a paragraph tag.
597
+ if ( ! empty( $retval ) ) {
598
  $retval = '<p>' . $retval . '</p>';
599
  }
600
 
607
  * Add a separator to the WordPress admin menus.
608
  *
609
  * @since 1.7.0
 
610
  */
611
  function bp_admin_separator() {
612
 
673
  $bp_menu_order = array();
674
 
675
  // Menu values.
676
+ $last_sep = is_network_admin() ? 'separator1' : 'separator2';
677
 
678
  /**
679
  * Filters the custom admin menus.
699
  if ( $last_sep == $item ) {
700
 
701
  // Add our custom menus.
702
+ foreach ( (array) $custom_menus as $custom_menu ) {
703
  if ( array_search( $custom_menu, $menu_order ) ) {
704
  $bp_menu_order[] = $custom_menu;
705
  }
708
  // Add the appearance separator.
709
  $bp_menu_order[] = $last_sep;
710
 
711
+ // Skip our menu items.
712
  } elseif ( ! in_array( $item, $custom_menus ) ) {
713
  $bp_menu_order[] = $item;
714
  }
736
  $action = ! empty( $_REQUEST['action'] ) ? $_REQUEST['action'] : '';
737
 
738
  // If the bottom is set, let it override the action.
739
+ if ( ! empty( $_REQUEST['action2'] ) && $_REQUEST['action2'] != '-1' ) {
740
  $action = $_REQUEST['action2'];
741
  }
742
 
777
 
778
  $tabs = array();
779
 
780
+ $tabs['loggedin']['label'] = __( 'Logged-In', 'buddypress' );
781
+ $tabs['loggedin']['pages'] = bp_nav_menu_get_loggedin_pages();
782
 
783
  $tabs['loggedout']['label'] = __( 'Logged-Out', 'buddypress' );
784
  $tabs['loggedout']['pages'] = bp_nav_menu_get_loggedout_pages();
786
  ?>
787
 
788
  <div id="buddypress-menu" class="posttypediv">
789
+ <h4><?php _e( 'Logged-In', 'buddypress' ); ?></h4>
790
+ <p><?php _e( '<em>Logged-In</em> links are relative to the current user, and are not visible to visitors who are not logged in.', 'buddypress' ); ?></p>
791
 
792
  <div id="tabs-panel-posttype-<?php echo $post_type_name; ?>-loggedin" class="tabs-panel tabs-panel-active">
793
  <ul id="buddypress-menu-checklist-loggedin" class="categorychecklist form-no-clear">
794
+ <?php echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $tabs['loggedin']['pages'] ), 0, (object) $args ); ?>
795
  </ul>
796
  </div>
797
 
798
+ <h4><?php _e( 'Logged-Out', 'buddypress' ); ?></h4>
799
+ <p><?php _e( '<em>Logged-Out</em> links are not visible to users who are logged in.', 'buddypress' ); ?></p>
800
 
801
  <div id="tabs-panel-posttype-<?php echo $post_type_name; ?>-loggedout" class="tabs-panel tabs-panel-active">
802
  <ul id="buddypress-menu-checklist-loggedout" class="categorychecklist form-no-clear">
803
+ <?php echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $tabs['loggedout']['pages'] ), 0, (object) $args ); ?>
804
  </ul>
805
  </div>
806
 
817
 
818
  <p class="button-controls">
819
  <span class="list-controls">
820
+ <a href="
821
+ <?php
822
+ echo esc_url(
823
+ add_query_arg(
824
+ array(
825
+ $post_type_name . '-tab' => 'all',
826
+ 'selectall' => 1,
827
+ ),
828
+ remove_query_arg( $removed_args )
829
+ )
830
+ );
831
+ ?>
832
+ #buddypress-menu" class="select-all"><?php _e( 'Select All', 'buddypress' ); ?></a>
833
  </span>
834
  <span class="add-to-menu">
835
+ <input type="submit"
836
+ <?php
837
+ if ( function_exists( 'wp_nav_menu_disabled_check' ) ) :
838
+ wp_nav_menu_disabled_check( $nav_menu_selected_id );
839
+ endif;
840
+ ?>
841
+ 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" />
842
  <span class="spinner"></span>
843
  </span>
844
  </p>
873
 
874
  bp_core_add_admin_notice(
875
  sprintf(
876
+ // Translators: %s is the url to the BuddyPress tools administration screen.
877
  __( 'Are these emails not written in your site\'s language? Go to <a href="%s">BuddyPress Tools and try the "reinstall emails"</a> tool.', 'buddypress' ),
878
  esc_url( add_query_arg( 'page', 'bp-tools', bp_get_admin_url( $admin_page ) ) )
879
  ),
894
 
895
  bp_core_add_admin_notice(
896
  sprintf(
897
+ // Translators: %s is the url to the BuddyPress codex page about BP Email tokens.
898
  __( 'Phrases wrapped in braces <code>{{ }}</code> are email tokens. <a href="%s">Learn about tokens on the BuddyPress Codex</a>.', 'buddypress' ),
899
  esc_url( 'https://codex.buddypress.org/emails/email-tokens/' )
900
  ),
921
  */
922
  function bp_email_tax_type_metabox( $post, $box ) {
923
  $r = array(
924
+ 'taxonomy' => bp_get_email_tax_type(),
925
  );
926
 
927
  $tax_name = esc_attr( $r['taxonomy'] );
934
  echo "<input type='hidden' name='{$name}[]' value='0' />"; // Allows for an empty term set to be sent. 0 is an invalid Term ID and will be ignored by empty() checks.
935
  ?>
936
  <ul id="<?php echo $tax_name; ?>checklist" data-wp-lists="list:<?php echo $tax_name; ?>" class="categorychecklist form-no-clear">
937
+ <?php
938
+ wp_terms_checklist(
939
+ $post->ID,
940
+ array(
941
+ 'taxonomy' => $tax_name,
942
+ 'walker' => new BP_Walker_Category_Checklist(),
943
+ )
944
+ );
945
+ ?>
946
  </ul>
947
  </div>
948
 
973
  * @param WP_Post $post
974
  */
975
  function bp_email_plaintext_metabox( $post ) {
976
+ ?>
977
 
978
+ <label class="screen-reader-text" for="excerpt">
979
+ <?php
980
  /* translators: accessibility text */
981
  _e( 'Plain text email content', 'buddypress' );
982
+ ?>
983
+ </label><textarea rows="5" cols="40" name="excerpt" id="excerpt"><?php echo $post->post_excerpt; // textarea_escaped ?></textarea>
984
 
985
  <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>
986
 
987
+ <?php
988
  }
989
 
990
  /**
1004
  * @since 1.9.0
1005
  */
1006
  function bp_admin_wp_nav_menu_restrict_items() {
1007
+ ?>
1008
  <script type="text/javascript">
1009
  jQuery( '#menu-to-edit').on( 'click', 'a.item-edit', function() {
1010
  var settings = jQuery(this).closest( '.menu-item-bar' ).next( '.menu-item-settings' );
1016
  }
1017
  });
1018
  </script>
1019
+ <?php
1020
  }
1021
 
1022
  /**
1032
 
1033
  // Setup the $user_id variable from the current user object.
1034
  $user_id = 0;
1035
+ if ( ! empty( $user_object->ID ) ) {
1036
  $user_id = absint( $user_object->ID );
1037
  }
1038
 
1044
 
1045
  // If spammed, create unspam link.
1046
  if ( bp_is_user_spammer( $user_id ) ) {
1047
+ $url = add_query_arg(
1048
+ array(
1049
+ 'action' => 'ham',
1050
+ 'user' => $user_id,
1051
+ ),
1052
+ $url
1053
+ );
1054
+ $unspam_link = wp_nonce_url( $url, 'bp-spam-user' );
1055
+ $actions['ham'] = sprintf('<a href="%1$s">%2$s</a>', esc_url( $unspam_link ), esc_html__( 'Not Spam', 'buddypress' ) );
1056
 
1057
+ // If not already spammed, create spam link.
1058
  } else {
1059
+ $url = add_query_arg(
1060
+ array(
1061
+ 'action' => 'spam',
1062
+ 'user' => $user_id,
1063
+ ),
1064
+ $url
1065
+ );
1066
  $spam_link = wp_nonce_url( $url, 'bp-spam-user' );
1067
  $actions['spam'] = sprintf( '<a class="submitdelete" href="%1$s">%2$s</a>', esc_url( $spam_link ), esc_html__( 'Spam', 'buddypress' ) );
1068
  }
1193
  *
1194
  * @since 5.0.0
1195
  *
1196
+ * @param array $categories Array of block categories.
1197
+ * @param object $post Post being loaded.
1198
  */
1199
  function bp_block_category( $categories = array(), $post = null ) {
1200
  if ( ! ( $post instanceof WP_Post ) ) {
1221
  return $categories;
1222
  }
1223
 
1224
+ return array_merge(
1225
+ $categories,
1226
  array(
1227
+ array(
1228
+ 'slug' => 'buddypress',
1229
+ 'title' => __( 'BuddyPress', 'buddypress' ),
1230
+ 'icon' => 'buddicons-buddypress-logo',
1231
+ ),
1232
+ )
1233
+ );
1234
  }
1235
  add_filter( 'block_categories', 'bp_block_category', 1, 2 );
bp-core/admin/bp-core-admin-settings.php CHANGED
@@ -147,42 +147,25 @@ function bp_admin_sanitize_callback_blogforum_comments( $value = false ) {
147
  return $value ? 0 : 1;
148
  }
149
 
150
- /** XProfile ******************************************************************/
151
 
152
  /**
153
  * Profile settings section description for the settings page.
154
  *
155
  * @since 1.6.0
156
  */
157
- function bp_admin_setting_callback_xprofile_section() { }
158
-
159
- /**
160
- * Enable BP->WP profile syncing field.
161
- *
162
- * @since 1.6.0
163
- *
164
- */
165
- function bp_admin_setting_callback_profile_sync() {
166
- ?>
167
-
168
- <input id="bp-disable-profile-sync" name="bp-disable-profile-sync" type="checkbox" value="1" <?php checked( !bp_disable_profile_sync( false ) ); ?> />
169
- <label for="bp-disable-profile-sync"><?php _e( 'Enable BuddyPress to WordPress profile syncing', 'buddypress' ); ?></label>
170
-
171
- <?php
172
- }
173
 
174
  /**
175
  * Allow members to upload avatars field.
176
  *
177
  * @since 1.6.0
178
- *
179
  */
180
  function bp_admin_setting_callback_avatar_uploads() {
181
  ?>
182
-
183
  <input id="bp-disable-avatar-uploads" name="bp-disable-avatar-uploads" type="checkbox" value="1" <?php checked( !bp_disable_avatar_uploads( false ) ); ?> />
184
  <label for="bp-disable-avatar-uploads"><?php _e( 'Allow registered members to upload avatars', 'buddypress' ); ?></label>
185
-
186
  <?php
187
  }
188
 
@@ -190,6 +173,7 @@ function bp_admin_setting_callback_avatar_uploads() {
190
  * Allow members to upload cover images field.
191
  *
192
  * @since 2.4.0
 
193
  */
194
  function bp_admin_setting_callback_cover_image_uploads() {
195
  ?>
@@ -198,6 +182,30 @@ function bp_admin_setting_callback_cover_image_uploads() {
198
  <?php
199
  }
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  /** Groups Section ************************************************************/
202
 
203
  /**
147
  return $value ? 0 : 1;
148
  }
149
 
150
+ /** Members *******************************************************************/
151
 
152
  /**
153
  * Profile settings section description for the settings page.
154
  *
155
  * @since 1.6.0
156
  */
157
+ function bp_admin_setting_callback_members_section() { }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
  /**
160
  * Allow members to upload avatars field.
161
  *
162
  * @since 1.6.0
163
+ * @since 6.0.0 Setting has been moved into the Members section.
164
  */
165
  function bp_admin_setting_callback_avatar_uploads() {
166
  ?>
 
167
  <input id="bp-disable-avatar-uploads" name="bp-disable-avatar-uploads" type="checkbox" value="1" <?php checked( !bp_disable_avatar_uploads( false ) ); ?> />
168
  <label for="bp-disable-avatar-uploads"><?php _e( 'Allow registered members to upload avatars', 'buddypress' ); ?></label>
 
169
  <?php
170
  }
171
 
173
  * Allow members to upload cover images field.
174
  *
175
  * @since 2.4.0
176
+ * @since 6.0.0 Setting has been moved into the Members section.
177
  */
178
  function bp_admin_setting_callback_cover_image_uploads() {
179
  ?>
182
  <?php
183
  }
184
 
185
+ /** XProfile ******************************************************************/
186
+
187
+ /**
188
+ * Profile settings section description for the settings page.
189
+ *
190
+ * @since 1.6.0
191
+ */
192
+ function bp_admin_setting_callback_xprofile_section() { }
193
+
194
+ /**
195
+ * Enable BP->WP profile syncing field.
196
+ *
197
+ * @since 1.6.0
198
+ *
199
+ */
200
+ function bp_admin_setting_callback_profile_sync() {
201
+ ?>
202
+
203
+ <input id="bp-disable-profile-sync" name="bp-disable-profile-sync" type="checkbox" value="1" <?php checked( !bp_disable_profile_sync( false ) ); ?> />
204
+ <label for="bp-disable-profile-sync"><?php _e( 'Enable BuddyPress to WordPress profile syncing', 'buddypress' ); ?></label>
205
+
206
+ <?php
207
+ }
208
+
209
  /** Groups Section ************************************************************/
210
 
211
  /**
bp-core/admin/bp-core-admin-slugs.php CHANGED
@@ -110,7 +110,7 @@ function bp_core_admin_get_static_pages() {
110
  */
111
  function bp_core_admin_slugs_options() {
112
 
113
- // Get the existing WP pages
114
  $existing_pages = bp_core_get_directory_page_ids();
115
 
116
  // Set up an array of components (along with component names) that have directory pages.
@@ -145,7 +145,10 @@ function bp_core_admin_slugs_options() {
145
 
146
  <?php if ( !empty( $existing_pages[$name] ) ) : ?>
147
 
148
- <a href="<?php echo get_permalink( $existing_pages[$name] ); ?>" class="button-secondary" target="_bp"><?php _e( 'View', 'buddypress' ); ?></a>
 
 
 
149
 
150
  <?php endif; ?>
151
 
@@ -187,9 +190,19 @@ function bp_core_admin_slugs_options() {
187
  <p><?php _e( 'Associate WordPress Pages with the following BuddyPress Registration pages.', 'buddypress' ); ?></p>
188
  <?php else : ?>
189
  <?php if ( is_multisite() ) : ?>
190
- <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>
 
 
 
 
 
191
  <?php else : ?>
192
- <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>
 
 
 
 
 
193
  <?php endif; ?>
194
  <?php endif; ?>
195
 
110
  */
111
  function bp_core_admin_slugs_options() {
112
 
113
+ // Get the existing WP pages.
114
  $existing_pages = bp_core_get_directory_page_ids();
115
 
116
  // Set up an array of components (along with component names) that have directory pages.
145
 
146
  <?php if ( !empty( $existing_pages[$name] ) ) : ?>
147
 
148
+ <a href="<?php echo esc_url( get_permalink( $existing_pages[$name] ) ); ?>" class="button-secondary" target="_bp">
149
+ <?php _e( 'View', 'buddypress' ); ?> <span class="dashicons dashicons-external" aria-hidden="true"></span>
150
+ <span class="screen-reader-text"><?php esc_html_e( '(opens in a new tab)', 'buddypress' ); ?></span>
151
+ </a>
152
 
153
  <?php endif; ?>
154
 
190
  <p><?php _e( 'Associate WordPress Pages with the following BuddyPress Registration pages.', 'buddypress' ); ?></p>
191
  <?php else : ?>
192
  <?php if ( is_multisite() ) : ?>
193
+ <p>
194
+ <?php
195
+ /* translators: %s: the link to the Network settings page */
196
+ 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' ) );
197
+ ?>
198
+ </p>
199
  <?php else : ?>
200
+ <p>
201
+ <?php
202
+ /* translators: %s: the link to the Site settings page */
203
+ 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' ) );
204
+ ?>
205
+ </p>
206
  <?php endif; ?>
207
  <?php endif; ?>
208
 
bp-core/admin/bp-core-admin-tools.php CHANGED
@@ -173,6 +173,7 @@ function bp_admin_repair_friend_count() {
173
  return;
174
  }
175
 
 
176
  $statement = __( 'Counting the number of friends for each user&hellip; %s', 'buddypress' );
177
  $result = __( 'Failed!', 'buddypress' );
178
 
@@ -231,6 +232,7 @@ function bp_admin_repair_group_count() {
231
  return;
232
  }
233
 
 
234
  $statement = __( 'Counting the number of groups for each user&hellip; %s', 'buddypress' );
235
  $result = __( 'Failed!', 'buddypress' );
236
 
@@ -273,7 +275,7 @@ function bp_admin_repair_group_count() {
273
  */
274
  function bp_admin_repair_blog_records() {
275
 
276
- // Description of this tool, displayed to the user.
277
  $statement = __( 'Repopulating Blogs records&hellip; %s', 'buddypress' );
278
 
279
  // Default to failure text.
@@ -302,6 +304,7 @@ function bp_admin_repair_blog_records() {
302
  * @since 2.0.0
303
  */
304
  function bp_admin_repair_count_members() {
 
305
  $statement = __( 'Counting the number of active members on the site&hellip; %s', 'buddypress' );
306
  delete_transient( 'bp_active_member_count' );
307
  bp_core_get_active_member_count();
@@ -316,6 +319,7 @@ function bp_admin_repair_count_members() {
316
  * @since 2.0.0
317
  */
318
  function bp_admin_repair_last_activity() {
 
319
  $statement = __( 'Determining last activity dates for each user&hellip; %s', 'buddypress' );
320
  bp_last_activity_migrate();
321
  return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
@@ -407,7 +411,13 @@ function bp_core_admin_available_tools_intro() {
407
  <h2><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h2>
408
  <p>
409
  <?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?>
410
- <?php printf( esc_html_x( 'Use the %s to repair these relationships.', 'buddypress tools intro', 'buddypress' ), '<a href="' . esc_url( $url ) . '">' . esc_html__( 'BuddyPress Tools', 'buddypress' ) . '</a>' ); ?>
 
 
 
 
 
 
411
  </p>
412
  </div>
413
  <?php
173
  return;
174
  }
175
 
176
+ /* translators: %s: the result of the action performed by the repair tool */
177
  $statement = __( 'Counting the number of friends for each user&hellip; %s', 'buddypress' );
178
  $result = __( 'Failed!', 'buddypress' );
179
 
232
  return;
233
  }
234
 
235
+ /* translators: %s: the result of the action performed by the repair tool */
236
  $statement = __( 'Counting the number of groups for each user&hellip; %s', 'buddypress' );
237
  $result = __( 'Failed!', 'buddypress' );
238
 
275
  */
276
  function bp_admin_repair_blog_records() {
277
 
278
+ /* translators: %s: the result of the action performed by the repair tool */
279
  $statement = __( 'Repopulating Blogs records&hellip; %s', 'buddypress' );
280
 
281
  // Default to failure text.
304
  * @since 2.0.0
305
  */
306
  function bp_admin_repair_count_members() {
307
+ /* translators: %s: the result of the action performed by the repair tool */
308
  $statement = __( 'Counting the number of active members on the site&hellip; %s', 'buddypress' );
309
  delete_transient( 'bp_active_member_count' );
310
  bp_core_get_active_member_count();
319
  * @since 2.0.0
320
  */
321
  function bp_admin_repair_last_activity() {
322
+ /* translators: %s: the result of the action performed by the repair tool */
323
  $statement = __( 'Determining last activity dates for each user&hellip; %s', 'buddypress' );
324
  bp_last_activity_migrate();
325
  return array( 0, sprintf( $statement, __( 'Complete!', 'buddypress' ) ) );
411
  <h2><?php esc_html_e( 'BuddyPress Tools', 'buddypress' ) ?></h2>
412
  <p>
413
  <?php esc_html_e( 'BuddyPress keeps track of various relationships between users, groups, and activity items. Occasionally these relationships become out of sync, most often after an import, update, or migration.', 'buddypress' ); ?>
414
+ <?php
415
+ printf(
416
+ /* translators: %s: the link to the BuddyPress repair tools */
417
+ esc_html_x( 'Use the %s to repair these relationships.', 'buddypress tools intro', 'buddypress' ),
418
+ '<a href="' . esc_url( $url ) . '">' . esc_html__( 'BuddyPress Tools', 'buddypress' ) . '</a>'
419
+ );
420
+ ?>
421
  </p>
422
  </div>
423
  <?php
bp-core/admin/css/common-rtl.css CHANGED
@@ -274,6 +274,11 @@ TABLE OF CONTENTS:
274
  content: "\f307";
275
  }
276
 
 
 
 
 
 
277
  #bp-admin-component-form .wp-list-table.plugins .plugin-title {
278
  width: 25%;
279
  }
274
  content: "\f307";
275
  }
276
 
277
+ .settings_page_bp-page-settings .button-secondary .dashicons {
278
+ position: relative;
279
+ top: 3px;
280
+ }
281
+
282
  #bp-admin-component-form .wp-list-table.plugins .plugin-title {
283
  width: 25%;
284
  }
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"}.index_page_bp-about code,.settings_page_bp-credits code{background-color:#e0e0e0;color:#636363;font-size:1em}.bp-about-wrap{position:relative;max-width:1050px;font-size:15px}.bp-about-wrap img{margin:0;max-width:100%;height:auto;vertical-align:middle}.bp-about-wrap p{line-height:1.5;font-size:14px}.bp-about-wrap h2{margin:40px 0 .6em;font-size:2.7em;line-height:1.3;font-weight:300;text-align:center}.bp-about-wrap h3{margin:1.25em 0 .6em;font-size:1.4em;line-height:1.5}.bp-about-wrap code{font-size:14px;font-weight:400}.bp-about-wrap .about-description{margin-top:1.4em;font-weight:400;line-height:1.6;font-size:19px}.bp-about-wrap h3.wp-people-group{margin:2.6em 0 1.33em;padding:0;font-size:16px;line-height:inherit}.bp-about-wrap .wp-people-group{padding:0 5px;margin:0 -5px 0 -15px}.bp-about-wrap .compact{margin-bottom:0}.bp-about-wrap .wp-person{display:inline-block;vertical-align:top;margin-left:10px;padding-bottom:15px;height:70px;width:280px}.bp-about-wrap .compact .wp-person{height:auto;width:180px;padding-bottom:0;margin-bottom:0}.bp-about-wrap .wp-person .gravatar{float:right;margin:0 0 10px 10px;padding:1px;width:60px;height:60px}.bp-about-wrap .compact .wp-person .gravatar{width:30px;height:30px}.bp-about-wrap .wp-person .web{margin:6px 0 2px;font-size:16px;font-weight:400;line-height:2;text-decoration:none}.bp-about-wrap .wp-person .title{display:block}.bp-about-wrap p.wp-credits-list a{white-space:nowrap}@media only screen and (max-width:500px){.bp-about-wrap{margin-left:20px;margin-right:10px}.bp-about-wrap .bp-about-wrap h1{margin-left:0}}#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.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:""}.bp-tooltip{position:relative}.bp-tooltip:after{background:#fff;border:1px solid #aaa;border-collapse:separate;border-radius:1px;box-shadow:-1px 1px 0 1px rgba(132,132,132,.3);color:#000;content:attr(data-bp-tooltip);display:none;font-family:sans-serif;font-size:11px;font-weight:400;letter-spacing:normal;line-height:1.5;margin-top:10px;max-width:240px;opacity:0;padding:3px 6px;position:absolute;left:50%;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;top:100%;transform:translateX(-50%);transition:opacity 2s ease-out;white-space:pre;word-wrap:break-word;z-index:998}.bp-hello-close .bp-tooltip:after{left:0;text-align:left;transform:translateX(0)}.bp-hello-social .bp-tooltip:after{bottom:120%;margin-bottom:20px;margin-top:0;top:auto;transform:translateX(-15%)}.bp-tooltip:active:after,.bp-tooltip:focus:after,.bp-tooltip:hover:after{display:inline-block;opacity:1;overflow:visible;text-decoration:none;z-index:999}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}.bp-signups-list table{margin:1em 0}.bp-signups-list .column-fields{font-weight:700}.bp-new-notice-panel{background:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04);font-size:13px;line-height:2.1;margin:1.5em 0 3em;overflow:auto;padding:10px 25px 25px;position:relative}.bp-new-notice-panel label{clear:both;float:right;margin-left:3%;width:20%}.bp-new-notice-panel input,.bp-new-notice-panel textarea{clear:none;margin-bottom:1em;width:75%}.bp-new-notice-panel input[type=text]:after,.bp-new-notice-panel textarea:after{clear:both;content:" ";display:table}.bp-new-notice-panel .button-primary{margin-right:23%;width:auto}.bp-notice-about{font-size:1em;margin-bottom:1em}.bp-new-notice{margin-bottom:1em;margin-top:0}.bp-notices-list{margin-bottom:0}@media screen and (max-width:782px){.bp-new-notice-panel{margin-bottom:1.5em}.bp-new-notice-panel input,.bp-new-notice-panel textarea{margin-right:0;width:100%}.bp-new-notice-panel .button-primary{margin-right:0;width:auto}.bp-new-notice-panel .button{max-width:45%;word-wrap:break-word}.bp-notice-about{margin-top:0;margin-bottom:1em}.bp-new-notice{margin-bottom:.5em}}body.post-type-bp-email #excerpt{height:auto}body.post-type-bp-email th#situation{width:20%}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:600;margin:1em 0}.tools_page_bp-tools label{clear:right;display:block;line-height:1.5;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"}
1
+ .bp-badge{color:#d84800;display:inline-block;font:400 150px/1 dashicons!important}.bp-badge:before{content:"\f448"}.index_page_bp-about code,.settings_page_bp-credits code{background-color:#e0e0e0;color:#636363;font-size:1em}.bp-about-wrap{position:relative;max-width:1050px;font-size:15px}.bp-about-wrap img{margin:0;max-width:100%;height:auto;vertical-align:middle}.bp-about-wrap p{line-height:1.5;font-size:14px}.bp-about-wrap h2{margin:40px 0 .6em;font-size:2.7em;line-height:1.3;font-weight:300;text-align:center}.bp-about-wrap h3{margin:1.25em 0 .6em;font-size:1.4em;line-height:1.5}.bp-about-wrap code{font-size:14px;font-weight:400}.bp-about-wrap .about-description{margin-top:1.4em;font-weight:400;line-height:1.6;font-size:19px}.bp-about-wrap h3.wp-people-group{margin:2.6em 0 1.33em;padding:0;font-size:16px;line-height:inherit}.bp-about-wrap .wp-people-group{padding:0 5px;margin:0 -5px 0 -15px}.bp-about-wrap .compact{margin-bottom:0}.bp-about-wrap .wp-person{display:inline-block;vertical-align:top;margin-left:10px;padding-bottom:15px;height:70px;width:280px}.bp-about-wrap .compact .wp-person{height:auto;width:180px;padding-bottom:0;margin-bottom:0}.bp-about-wrap .wp-person .gravatar{float:right;margin:0 0 10px 10px;padding:1px;width:60px;height:60px}.bp-about-wrap .compact .wp-person .gravatar{width:30px;height:30px}.bp-about-wrap .wp-person .web{margin:6px 0 2px;font-size:16px;font-weight:400;line-height:2;text-decoration:none}.bp-about-wrap .wp-person .title{display:block}.bp-about-wrap p.wp-credits-list a{white-space:nowrap}@media only screen and (max-width:500px){.bp-about-wrap{margin-left:20px;margin-right:10px}.bp-about-wrap .bp-about-wrap h1{margin-left:0}}#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.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"}.settings_page_bp-page-settings .button-secondary .dashicons{position:relative;top:3px}#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:""}.bp-tooltip{position:relative}.bp-tooltip:after{background:#fff;border:1px solid #aaa;border-collapse:separate;border-radius:1px;box-shadow:-1px 1px 0 1px rgba(132,132,132,.3);color:#000;content:attr(data-bp-tooltip);display:none;font-family:sans-serif;font-size:11px;font-weight:400;letter-spacing:normal;line-height:1.5;margin-top:10px;max-width:240px;opacity:0;padding:3px 6px;position:absolute;left:50%;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;top:100%;transform:translateX(-50%);transition:opacity 2s ease-out;white-space:pre;word-wrap:break-word;z-index:998}.bp-hello-close .bp-tooltip:after{left:0;text-align:left;transform:translateX(0)}.bp-hello-social .bp-tooltip:after{bottom:120%;margin-bottom:20px;margin-top:0;top:auto;transform:translateX(-15%)}.bp-tooltip:active:after,.bp-tooltip:focus:after,.bp-tooltip:hover:after{display:inline-block;opacity:1;overflow:visible;text-decoration:none;z-index:999}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}.bp-signups-list table{margin:1em 0}.bp-signups-list .column-fields{font-weight:700}.bp-new-notice-panel{background:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04);font-size:13px;line-height:2.1;margin:1.5em 0 3em;overflow:auto;padding:10px 25px 25px;position:relative}.bp-new-notice-panel label{clear:both;float:right;margin-left:3%;width:20%}.bp-new-notice-panel input,.bp-new-notice-panel textarea{clear:none;margin-bottom:1em;width:75%}.bp-new-notice-panel input[type=text]:after,.bp-new-notice-panel textarea:after{clear:both;content:" ";display:table}.bp-new-notice-panel .button-primary{margin-right:23%;width:auto}.bp-notice-about{font-size:1em;margin-bottom:1em}.bp-new-notice{margin-bottom:1em;margin-top:0}.bp-notices-list{margin-bottom:0}@media screen and (max-width:782px){.bp-new-notice-panel{margin-bottom:1.5em}.bp-new-notice-panel input,.bp-new-notice-panel textarea{margin-right:0;width:100%}.bp-new-notice-panel .button-primary{margin-right:0;width:auto}.bp-new-notice-panel .button{max-width:45%;word-wrap:break-word}.bp-notice-about{margin-top:0;margin-bottom:1em}.bp-new-notice{margin-bottom:.5em}}body.post-type-bp-email #excerpt{height:auto}body.post-type-bp-email th#situation{width:20%}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:600;margin:1em 0}.tools_page_bp-tools label{clear:right;display:block;line-height:1.5;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
@@ -274,6 +274,11 @@ TABLE OF CONTENTS:
274
  content: "\f307";
275
  }
276
 
 
 
 
 
 
277
  #bp-admin-component-form .wp-list-table.plugins .plugin-title {
278
  width: 25%;
279
  }
274
  content: "\f307";
275
  }
276
 
277
+ .settings_page_bp-page-settings .button-secondary .dashicons {
278
+ position: relative;
279
+ top: 3px;
280
+ }
281
+
282
  #bp-admin-component-form .wp-list-table.plugins .plugin-title {
283
  width: 25%;
284
  }
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"}.index_page_bp-about code,.settings_page_bp-credits code{background-color:#e0e0e0;color:#636363;font-size:1em}.bp-about-wrap{position:relative;max-width:1050px;font-size:15px}.bp-about-wrap img{margin:0;max-width:100%;height:auto;vertical-align:middle}.bp-about-wrap p{line-height:1.5;font-size:14px}.bp-about-wrap h2{margin:40px 0 .6em;font-size:2.7em;line-height:1.3;font-weight:300;text-align:center}.bp-about-wrap h3{margin:1.25em 0 .6em;font-size:1.4em;line-height:1.5}.bp-about-wrap code{font-size:14px;font-weight:400}.bp-about-wrap .about-description{margin-top:1.4em;font-weight:400;line-height:1.6;font-size:19px}.bp-about-wrap h3.wp-people-group{margin:2.6em 0 1.33em;padding:0;font-size:16px;line-height:inherit}.bp-about-wrap .wp-people-group{padding:0 5px;margin:0 -15px 0 -5px}.bp-about-wrap .compact{margin-bottom:0}.bp-about-wrap .wp-person{display:inline-block;vertical-align:top;margin-right:10px;padding-bottom:15px;height:70px;width:280px}.bp-about-wrap .compact .wp-person{height:auto;width:180px;padding-bottom:0;margin-bottom:0}.bp-about-wrap .wp-person .gravatar{float:left;margin:0 10px 10px 0;padding:1px;width:60px;height:60px}.bp-about-wrap .compact .wp-person .gravatar{width:30px;height:30px}.bp-about-wrap .wp-person .web{margin:6px 0 2px;font-size:16px;font-weight:400;line-height:2;text-decoration:none}.bp-about-wrap .wp-person .title{display:block}.bp-about-wrap p.wp-credits-list a{white-space:nowrap}@media only screen and (max-width:500px){.bp-about-wrap{margin-right:20px;margin-left:10px}.bp-about-wrap .bp-about-wrap h1{margin-right:0}}#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.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:""}.bp-tooltip{position:relative}.bp-tooltip:after{background:#fff;border:1px solid #aaa;border-collapse:separate;border-radius:1px;box-shadow:1px 1px 0 1px rgba(132,132,132,.3);color:#000;content:attr(data-bp-tooltip);display:none;font-family:sans-serif;font-size:11px;font-weight:400;letter-spacing:normal;line-height:1.5;margin-top:10px;max-width:240px;opacity:0;padding:3px 6px;position:absolute;right:50%;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;top:100%;transform:translateX(50%);transition:opacity 2s ease-out;white-space:pre;word-wrap:break-word;z-index:998}.bp-hello-close .bp-tooltip:after{right:0;text-align:right;transform:translateX(0)}.bp-hello-social .bp-tooltip:after{bottom:120%;margin-bottom:20px;margin-top:0;top:auto;transform:translateX(15%)}.bp-tooltip:active:after,.bp-tooltip:focus:after,.bp-tooltip:hover:after{display:inline-block;opacity:1;overflow:visible;text-decoration:none;z-index:999}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}.bp-signups-list table{margin:1em 0}.bp-signups-list .column-fields{font-weight:700}.bp-new-notice-panel{background:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04);font-size:13px;line-height:2.1;margin:1.5em 0 3em;overflow:auto;padding:10px 25px 25px;position:relative}.bp-new-notice-panel label{clear:both;float:left;margin-right:3%;width:20%}.bp-new-notice-panel input,.bp-new-notice-panel textarea{clear:none;margin-bottom:1em;width:75%}.bp-new-notice-panel input[type=text]:after,.bp-new-notice-panel textarea:after{clear:both;content:" ";display:table}.bp-new-notice-panel .button-primary{margin-left:23%;width:auto}.bp-notice-about{font-size:1em;margin-bottom:1em}.bp-new-notice{margin-bottom:1em;margin-top:0}.bp-notices-list{margin-bottom:0}@media screen and (max-width:782px){.bp-new-notice-panel{margin-bottom:1.5em}.bp-new-notice-panel input,.bp-new-notice-panel textarea{margin-left:0;width:100%}.bp-new-notice-panel .button-primary{margin-left:0;width:auto}.bp-new-notice-panel .button{max-width:45%;word-wrap:break-word}.bp-notice-about{margin-top:0;margin-bottom:1em}.bp-new-notice{margin-bottom:.5em}}body.post-type-bp-email #excerpt{height:auto}body.post-type-bp-email th#situation{width:20%}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:600;margin:1em 0}.tools_page_bp-tools label{clear:left;display:block;line-height:1.5;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"}
1
+ .bp-badge{color:#d84800;display:inline-block;font:400 150px/1 dashicons!important}.bp-badge:before{content:"\f448"}.index_page_bp-about code,.settings_page_bp-credits code{background-color:#e0e0e0;color:#636363;font-size:1em}.bp-about-wrap{position:relative;max-width:1050px;font-size:15px}.bp-about-wrap img{margin:0;max-width:100%;height:auto;vertical-align:middle}.bp-about-wrap p{line-height:1.5;font-size:14px}.bp-about-wrap h2{margin:40px 0 .6em;font-size:2.7em;line-height:1.3;font-weight:300;text-align:center}.bp-about-wrap h3{margin:1.25em 0 .6em;font-size:1.4em;line-height:1.5}.bp-about-wrap code{font-size:14px;font-weight:400}.bp-about-wrap .about-description{margin-top:1.4em;font-weight:400;line-height:1.6;font-size:19px}.bp-about-wrap h3.wp-people-group{margin:2.6em 0 1.33em;padding:0;font-size:16px;line-height:inherit}.bp-about-wrap .wp-people-group{padding:0 5px;margin:0 -15px 0 -5px}.bp-about-wrap .compact{margin-bottom:0}.bp-about-wrap .wp-person{display:inline-block;vertical-align:top;margin-right:10px;padding-bottom:15px;height:70px;width:280px}.bp-about-wrap .compact .wp-person{height:auto;width:180px;padding-bottom:0;margin-bottom:0}.bp-about-wrap .wp-person .gravatar{float:left;margin:0 10px 10px 0;padding:1px;width:60px;height:60px}.bp-about-wrap .compact .wp-person .gravatar{width:30px;height:30px}.bp-about-wrap .wp-person .web{margin:6px 0 2px;font-size:16px;font-weight:400;line-height:2;text-decoration:none}.bp-about-wrap .wp-person .title{display:block}.bp-about-wrap p.wp-credits-list a{white-space:nowrap}@media only screen and (max-width:500px){.bp-about-wrap{margin-right:20px;margin-left:10px}.bp-about-wrap .bp-about-wrap h1{margin-right:0}}#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.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"}.settings_page_bp-page-settings .button-secondary .dashicons{position:relative;top:3px}#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:""}.bp-tooltip{position:relative}.bp-tooltip:after{background:#fff;border:1px solid #aaa;border-collapse:separate;border-radius:1px;box-shadow:1px 1px 0 1px rgba(132,132,132,.3);color:#000;content:attr(data-bp-tooltip);display:none;font-family:sans-serif;font-size:11px;font-weight:400;letter-spacing:normal;line-height:1.5;margin-top:10px;max-width:240px;opacity:0;padding:3px 6px;position:absolute;right:50%;text-align:center;text-decoration:none;text-shadow:none;text-transform:none;top:100%;transform:translateX(50%);transition:opacity 2s ease-out;white-space:pre;word-wrap:break-word;z-index:998}.bp-hello-close .bp-tooltip:after{right:0;text-align:right;transform:translateX(0)}.bp-hello-social .bp-tooltip:after{bottom:120%;margin-bottom:20px;margin-top:0;top:auto;transform:translateX(15%)}.bp-tooltip:active:after,.bp-tooltip:focus:after,.bp-tooltip:hover:after{display:inline-block;opacity:1;overflow:visible;text-decoration:none;z-index:999}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}.bp-signups-list table{margin:1em 0}.bp-signups-list .column-fields{font-weight:700}.bp-new-notice-panel{background:#fff;border:1px solid #e5e5e5;box-shadow:0 1px 1px rgba(0,0,0,.04);font-size:13px;line-height:2.1;margin:1.5em 0 3em;overflow:auto;padding:10px 25px 25px;position:relative}.bp-new-notice-panel label{clear:both;float:left;margin-right:3%;width:20%}.bp-new-notice-panel input,.bp-new-notice-panel textarea{clear:none;margin-bottom:1em;width:75%}.bp-new-notice-panel input[type=text]:after,.bp-new-notice-panel textarea:after{clear:both;content:" ";display:table}.bp-new-notice-panel .button-primary{margin-left:23%;width:auto}.bp-notice-about{font-size:1em;margin-bottom:1em}.bp-new-notice{margin-bottom:1em;margin-top:0}.bp-notices-list{margin-bottom:0}@media screen and (max-width:782px){.bp-new-notice-panel{margin-bottom:1.5em}.bp-new-notice-panel input,.bp-new-notice-panel textarea{margin-left:0;width:100%}.bp-new-notice-panel .button-primary{margin-left:0;width:auto}.bp-new-notice-panel .button{max-width:45%;word-wrap:break-word}.bp-notice-about{margin-top:0;margin-bottom:1em}.bp-new-notice{margin-bottom:.5em}}body.post-type-bp-email #excerpt{height:auto}body.post-type-bp-email th#situation{width:20%}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:600;margin:1em 0}.tools_page_bp-tools label{clear:left;display:block;line-height:1.5;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/bp-core-actions.php CHANGED
@@ -75,6 +75,7 @@ add_action( 'bp_init', 'bp_setup_globals', 4 );
75
  add_action( 'bp_init', 'bp_setup_canonical_stack', 5 );
76
  add_action( 'bp_init', 'bp_setup_nav', 6 );
77
  add_action( 'bp_init', 'bp_setup_title', 8 );
 
78
  add_action( 'bp_init', 'bp_core_load_admin_bar_css', 12 );
79
  add_action( 'bp_init', 'bp_add_rewrite_tags', 20 );
80
  add_action( 'bp_init', 'bp_add_rewrite_rules', 30 );
75
  add_action( 'bp_init', 'bp_setup_canonical_stack', 5 );
76
  add_action( 'bp_init', 'bp_setup_nav', 6 );
77
  add_action( 'bp_init', 'bp_setup_title', 8 );
78
+ add_action( 'bp_init', 'bp_blocks_init', 10 );
79
  add_action( 'bp_init', 'bp_core_load_admin_bar_css', 12 );
80
  add_action( 'bp_init', 'bp_add_rewrite_tags', 20 );
81
  add_action( 'bp_init', 'bp_add_rewrite_rules', 30 );
bp-core/bp-core-admin.php CHANGED
@@ -54,5 +54,6 @@ function bp_admin() {
54
  'buddypress'
55
  );
56
 
 
57
  __( 'For more information, see <a href="%s">the release notes</a>.', 'buddypress' );
58
  }
54
  'buddypress'
55
  );
56
 
57
+ /* translators: %s: the link to the BuddyPress release notes */
58
  __( 'For more information, see <a href="%s">the release notes</a>.', 'buddypress' );
59
  }
bp-core/bp-core-adminbar.php CHANGED
@@ -30,7 +30,7 @@ function bp_admin_bar_my_account_root() {
30
  if ( is_user_logged_in() ) {
31
 
32
  // Add secondary parent item for all BuddyPress components.
33
- $wp_admin_bar->add_menu( array(
34
  'parent' => 'my-account',
35
  'id' => 'my-account-buddypress',
36
  'title' => __( 'My Account', 'buddypress' ),
30
  if ( is_user_logged_in() ) {
31
 
32
  // Add secondary parent item for all BuddyPress components.
33
+ $wp_admin_bar->add_node( array(
34
  'parent' => 'my-account',
35
  'id' => 'my-account-buddypress',
36
  'title' => __( 'My Account', 'buddypress' ),
bp-core/bp-core-attachments.php CHANGED
@@ -10,22 +10,6 @@
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
- /**
14
- * Check if the current WordPress version is using Plupload 2.1.1
15
- *
16
- * Plupload 2.1.1 was introduced in WordPress 3.9. Our bp-plupload.js
17
- * script requires it. So we need to make sure the current WordPress
18
- * match with our needs.
19
- *
20
- * @since 2.3.0
21
- * @since 3.0.0 This is always true.
22
- *
23
- * @return bool Always true.
24
- */
25
- function bp_attachments_is_wp_version_supported() {
26
- return true;
27
- }
28
-
29
  /**
30
  * Get the Attachments Uploads dir data.
31
  *
@@ -92,7 +76,7 @@ function bp_attachments_uploads_dir_get( $data = '' ) {
92
  * @return array See wp_upload_dir().
93
  */
94
  function bp_attachments_cover_image_upload_dir( $args = array() ) {
95
- // Default values are for profiles.
96
  $object_id = bp_displayed_user_id();
97
 
98
  if ( empty( $object_id ) ) {
@@ -288,7 +272,7 @@ function bp_attachments_check_filetype( $file, $filename, $allowed_mimes ) {
288
  * @param array $args {
289
  * @type int $item_id The ID of the object (Required). Default: 0.
290
  * @type string $object The object type (eg: group, user, blog) (Required). Default: 'user'.
291
- * @type string $component The component for the object (eg: groups, xprofile, blogs). Default: ''.
292
  * @type string $image The absolute path to the image (Required). Default: ''.
293
  * @type int $crop_w Crop width. Default: 0.
294
  * @type int $crop_h Crop height. Default: 0.
@@ -325,7 +309,7 @@ function bp_attachments_create_item_type( $type = 'avatar', $args = array() ) {
325
  // Set the component if not already done.
326
  if ( empty( $r['component'] ) ) {
327
  if ( 'user' === $r['object'] ) {
328
- $r['component'] = 'xprofile';
329
  } else {
330
  $r['component'] = $r['object'] . 's';
331
  }
@@ -357,8 +341,8 @@ function bp_attachments_create_item_type( $type = 'avatar', $args = array() ) {
357
  if ( is_callable( $r['component'] . '_avatar_upload_dir' ) ) {
358
  $dir_args = array( $r['item_id'] );
359
 
360
- // In case of xprofile, we need an extra argument.
361
- if ( 'xprofile' === $r['component'] ) {
362
  $dir_args = array( false, $r['item_id'] );
363
  }
364
 
@@ -375,7 +359,7 @@ function bp_attachments_create_item_type( $type = 'avatar', $args = array() ) {
375
  // Default to members for xProfile.
376
  $object_subdir = 'members';
377
 
378
- if ( 'xprofile' !== $r['component'] ) {
379
  $object_subdir = sanitize_key( $r['component'] );
380
  }
381
 
@@ -645,9 +629,19 @@ function bp_attachments_get_plupload_default_settings() {
645
  * @return array Plupload default localization strings.
646
  */
647
  function bp_attachments_get_plupload_l10n() {
648
- // Localization strings.
649
- return apply_filters( 'bp_attachments_get_plupload_l10n', array(
 
 
 
 
 
 
 
 
650
  'queue_limit_exceeded' => __( 'You have attempted to queue too many files.', 'buddypress' ),
 
 
651
  'file_exceeds_size_limit' => __( '%s exceeds the maximum upload size for this site.', 'buddypress' ),
652
  'zero_byte_file' => __( 'This file is empty. Please try another.', 'buddypress' ),
653
  'invalid_filetype' => __( 'This file type is not allowed. Please try another.', 'buddypress' ),
@@ -659,7 +653,11 @@ function bp_attachments_get_plupload_l10n() {
659
  'upload_limit_exceeded' => __( 'You may only upload 1 file.', 'buddypress' ),
660
  'http_error' => __( 'HTTP error.', 'buddypress' ),
661
  'upload_failed' => __( 'Upload failed.', 'buddypress' ),
 
 
662
  'big_upload_failed' => __( 'Please try uploading this file with the %1$sbrowser uploader%2$s.', 'buddypress' ),
 
 
663
  'big_upload_queued' => __( '%s exceeds the maximum upload size for the multi-file uploader when used in your browser.', 'buddypress' ),
664
  'io_error' => __( 'IO error.', 'buddypress' ),
665
  'security_error' => __( 'Security error.', 'buddypress' ),
@@ -668,9 +666,12 @@ function bp_attachments_get_plupload_l10n() {
668
  'dismiss' => __( 'Dismiss', 'buddypress' ),
669
  'crunching' => __( 'Crunching&hellip;', 'buddypress' ),
670
  'unique_file_warning' => __( 'Make sure to upload a unique file', 'buddypress' ),
 
 
671
  'error_uploading' => __( '&#8220;%s&#8221; has failed to upload.', 'buddypress' ),
672
  'has_avatar_warning' => __( 'If you&#39;d like to delete the existing profile photo but not upload a new one, please use the delete tab.', 'buddypress' )
673
- ) );
 
674
  }
675
 
676
  /**
@@ -819,8 +820,8 @@ function bp_attachments_enqueue_scripts( $class = '' ) {
819
  // Cover images only need 1 file and 1 only!
820
  $defaults['multi_selection'] = false;
821
 
822
- // Default cover component is xprofile.
823
- $cover_component = 'xprofile';
824
 
825
  // Get the object we're editing the cover image of.
826
  $object = $defaults['multipart_params']['bp_params']['object'];
@@ -837,10 +838,11 @@ function bp_attachments_enqueue_scripts( $class = '' ) {
837
  // Set warning messages.
838
  $strings['cover_image_warnings'] = apply_filters( 'bp_attachments_cover_image_ui_warnings', array(
839
  'dimensions' => sprintf(
840
- __( 'For better results, make sure to upload an image that is larger than %1$spx wide, and %2$spx tall.', 'buddypress' ),
841
- (int) $cover_dimensions['width'],
842
- (int) $cover_dimensions['height']
843
- ),
 
844
  ) );
845
  }
846
 
@@ -914,7 +916,7 @@ function bp_attachments_current_user_can( $capability, $args = array() ) {
914
  $can = (bool) groups_is_user_admin( bp_loggedin_user_id(), $args['item_id'] ) || bp_current_user_can( 'bp_moderate' );
915
  }
916
  // User profile photo.
917
- } elseif ( bp_is_active( 'xprofile' ) && 'user' === $args['object'] ) {
918
  $can = bp_loggedin_user_id() === (int) $args['item_id'] || bp_current_user_can( 'bp_moderate' );
919
  }
920
  /**
@@ -1003,10 +1005,10 @@ function bp_attachments_get_template_part( $slug ) {
1003
  *
1004
  * @since 2.4.0
1005
  *
1006
- * @param string $component The component to get the settings for ("xprofile" for user or "groups").
1007
  * @return false|array The cover image settings in array, false on failure.
1008
  */
1009
- function bp_attachments_get_cover_image_settings( $component = 'xprofile' ) {
1010
  // Default parameters.
1011
  $args = array();
1012
 
@@ -1017,24 +1019,42 @@ function bp_attachments_get_cover_image_settings( $component = 'xprofile' ) {
1017
  $args = (array) $cover_image;
1018
  }
1019
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1020
  /**
1021
  * Then let people override/set the feature using this dynamic filter
1022
  *
1023
  * Eg: for the user's profile cover image use:
1024
- * add_filter( 'bp_before_xprofile_cover_image_settings_parse_args', 'your_filter', 10, 1 );
1025
  *
1026
  * @since 2.4.0
1027
  *
1028
  * @param array $settings The cover image settings
1029
  */
1030
- $settings = bp_parse_args( $args, array(
1031
- 'components' => array(),
1032
- 'width' => 1300,
1033
- 'height' => 225,
1034
- 'callback' => '',
1035
- 'theme_handle' => '',
1036
- 'default_cover' => '',
1037
- ), $component . '_cover_image_settings' );
1038
 
1039
  if ( empty( $settings['components'] ) || empty( $settings['callback'] ) || empty( $settings['theme_handle'] ) ) {
1040
  return false;
@@ -1054,10 +1074,10 @@ function bp_attachments_get_cover_image_settings( $component = 'xprofile' ) {
1054
  *
1055
  * @since 2.4.0
1056
  *
1057
- * @param string $component The BuddyPress component concerned ("xprofile" for user or "groups").
1058
  * @return array|bool An associative array containing the advised width and height for the cover image. False if settings are empty.
1059
  */
1060
- function bp_attachments_get_cover_image_dimensions( $component = 'xprofile' ) {
1061
  // Let's prevent notices when setting the warning strings.
1062
  $default = array( 'width' => 0, 'height' => 0 );
1063
 
@@ -1093,8 +1113,8 @@ function bp_attachments_cover_image_is_edit() {
1093
  $retval = false;
1094
 
1095
  $current_component = bp_current_component();
1096
- if ( bp_is_active( 'xprofile' ) && bp_is_current_component( 'xprofile' ) ) {
1097
- $current_component = 'xprofile';
1098
  }
1099
 
1100
  if ( ! bp_is_active( $current_component, 'cover_image' ) ) {
@@ -1137,6 +1157,7 @@ function bp_attachments_get_user_has_cover_image( $user_id = 0 ) {
1137
  * Does the group has a cover image?
1138
  *
1139
  * @since 2.4.0
 
1140
  *
1141
  * @param int $group_id Group ID to check cover image existence for.
1142
  * @return bool True if the group has a cover image, false otherwise.
@@ -1151,7 +1172,7 @@ function bp_attachments_get_group_has_cover_image( $group_id = 0 ) {
1151
  'item_id' => $group_id,
1152
  ) );
1153
 
1154
- return (bool) apply_filters( 'bp_attachments_get_user_has_cover_image', $cover_src, $group_id );
1155
  }
1156
 
1157
  /**
@@ -1161,7 +1182,7 @@ function bp_attachments_get_group_has_cover_image( $group_id = 0 ) {
1161
  *
1162
  * @param array $args {
1163
  * @type string $file The absolute path to the image. Required.
1164
- * @type string $component The component for the object (eg: groups, xprofile). Required.
1165
  * @type string $cover_image_dir The Cover image dir to write the image into. Required.
1166
  * }
1167
  * @param BP_Attachment_Cover_Image|null $cover_image_class The class to use to fit the cover image.
@@ -1282,7 +1303,7 @@ function bp_attachments_cover_image_ajax_upload() {
1282
 
1283
  // Member's cover image.
1284
  if ( 'user' === $bp_params['object'] ) {
1285
- $object_data = array( 'dir' => 'members', 'component' => 'xprofile' );
1286
 
1287
  if ( ! bp_displayed_user_id() && ! empty( $bp_params['item_id'] ) ) {
1288
  $needs_reset = array( 'key' => 'displayed_user', 'value' => $bp->displayed_user );
@@ -1341,7 +1362,11 @@ function bp_attachments_cover_image_ajax_upload() {
1341
  // Upload error response.
1342
  bp_attachments_json_response( false, $is_html4, array(
1343
  'type' => 'upload_error',
1344
- 'message' => sprintf( __( 'Upload Failed! Error was: %s', 'buddypress' ), $uploaded['error'] ),
 
 
 
 
1345
  ) );
1346
  }
1347
 
@@ -1399,16 +1424,20 @@ function bp_attachments_cover_image_ajax_upload() {
1399
  }
1400
 
1401
  // Set the name of the file.
1402
- $name = $_FILES['file']['name'];
1403
  $name_parts = pathinfo( $name );
1404
- $name = trim( substr( $name, 0, - ( 1 + strlen( $name_parts['extension'] ) ) ) );
 
 
 
 
1405
 
1406
  /**
1407
  * Fires if the new cover image was successfully uploaded.
1408
  *
1409
- * The dynamic portion of the hook will be xprofile in case of a user's
1410
  * cover image, groups in case of a group's cover image. For instance:
1411
- * Use add_action( 'xprofile_cover_image_uploaded' ) to run your specific
1412
  * code once the user has set his cover image.
1413
  *
1414
  * @since 2.4.0
@@ -1420,13 +1449,29 @@ function bp_attachments_cover_image_ajax_upload() {
1420
  * @param int $feedback_code If value not 1, an error occured.
1421
  */
1422
  do_action(
1423
- $object_data['component'] . '_cover_image_uploaded',
1424
- (int) $bp_params['item_id'],
1425
  $name,
1426
  $cover_url,
1427
  $feedback_code
1428
  );
1429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1430
  // Finally return the cover image url to the UI.
1431
  bp_attachments_json_response( true, $is_html4, array(
1432
  'name' => $name,
@@ -1466,7 +1511,7 @@ function bp_attachments_cover_image_ajax_delete() {
1466
 
1467
  // Set object for the user's case.
1468
  if ( 'user' === $args['object'] ) {
1469
- $component = 'xprofile';
1470
  $dir = 'members';
1471
 
1472
  // Set it for any other cases.
@@ -1477,19 +1522,27 @@ function bp_attachments_cover_image_ajax_delete() {
1477
 
1478
  // Handle delete.
1479
  if ( bp_attachments_delete_file( array( 'item_id' => $args['item_id'], 'object_dir' => $dir, 'type' => 'cover-image' ) ) ) {
 
 
1480
  /**
1481
  * Fires if the cover image was successfully deleted.
1482
  *
1483
- * The dynamic portion of the hook will be xprofile in case of a user's
1484
  * cover image, groups in case of a group's cover image. For instance:
1485
- * Use add_action( 'xprofile_cover_image_deleted' ) to run your specific
1486
  * code once the user has deleted his cover image.
1487
  *
1488
  * @since 2.8.0
1489
  *
1490
  * @param int $item_id Inform about the item id the cover image was deleted for.
1491
  */
1492
- do_action( "{$component}_cover_image_deleted", (int) $args['item_id'] );
 
 
 
 
 
 
1493
 
1494
  $response = array(
1495
  'reset_url' => '',
10
  // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  /**
14
  * Get the Attachments Uploads dir data.
15
  *
76
  * @return array See wp_upload_dir().
77
  */
78
  function bp_attachments_cover_image_upload_dir( $args = array() ) {
79
+ // Default values are for members.
80
  $object_id = bp_displayed_user_id();
81
 
82
  if ( empty( $object_id ) ) {
272
  * @param array $args {
273
  * @type int $item_id The ID of the object (Required). Default: 0.
274
  * @type string $object The object type (eg: group, user, blog) (Required). Default: 'user'.
275
+ * @type string $component The component for the object (eg: groups, members, blogs). Default: ''.
276
  * @type string $image The absolute path to the image (Required). Default: ''.
277
  * @type int $crop_w Crop width. Default: 0.
278
  * @type int $crop_h Crop height. Default: 0.
309
  // Set the component if not already done.
310
  if ( empty( $r['component'] ) ) {
311
  if ( 'user' === $r['object'] ) {
312
+ $r['component'] = 'members';
313
  } else {
314
  $r['component'] = $r['object'] . 's';
315
  }
341
  if ( is_callable( $r['component'] . '_avatar_upload_dir' ) ) {
342
  $dir_args = array( $r['item_id'] );
343
 
344
+ // In case of members, we need an extra argument.
345
+ if ( 'members' === $r['component'] ) {
346
  $dir_args = array( false, $r['item_id'] );
347
  }
348
 
359
  // Default to members for xProfile.
360
  $object_subdir = 'members';
361
 
362
+ if ( 'members' !== $r['component'] ) {
363
  $object_subdir = sanitize_key( $r['component'] );
364
  }
365
 
629
  * @return array Plupload default localization strings.
630
  */
631
  function bp_attachments_get_plupload_l10n() {
632
+ /**
633
+ * Use this filter to edit localization strings.
634
+ *
635
+ * @since 2.3.0
636
+ *
637
+ * @param array $value An associative array of the localization strings.
638
+ */
639
+ return apply_filters(
640
+ 'bp_attachments_get_plupload_l10n',
641
+ array(
642
  'queue_limit_exceeded' => __( 'You have attempted to queue too many files.', 'buddypress' ),
643
+
644
+ /* translators: %s: File name. */
645
  'file_exceeds_size_limit' => __( '%s exceeds the maximum upload size for this site.', 'buddypress' ),
646
  'zero_byte_file' => __( 'This file is empty. Please try another.', 'buddypress' ),
647
  'invalid_filetype' => __( 'This file type is not allowed. Please try another.', 'buddypress' ),
653
  'upload_limit_exceeded' => __( 'You may only upload 1 file.', 'buddypress' ),
654
  'http_error' => __( 'HTTP error.', 'buddypress' ),
655
  'upload_failed' => __( 'Upload failed.', 'buddypress' ),
656
+
657
+ /* translators: 1: Opening link tag, 2: Closing link tag. */
658
  'big_upload_failed' => __( 'Please try uploading this file with the %1$sbrowser uploader%2$s.', 'buddypress' ),
659
+
660
+ /* translators: %s: File name. */
661
  'big_upload_queued' => __( '%s exceeds the maximum upload size for the multi-file uploader when used in your browser.', 'buddypress' ),
662
  'io_error' => __( 'IO error.', 'buddypress' ),
663
  'security_error' => __( 'Security error.', 'buddypress' ),
666
  'dismiss' => __( 'Dismiss', 'buddypress' ),
667
  'crunching' => __( 'Crunching&hellip;', 'buddypress' ),
668
  'unique_file_warning' => __( 'Make sure to upload a unique file', 'buddypress' ),
669
+
670
+ /* translators: %s: File name. */
671
  'error_uploading' => __( '&#8220;%s&#8221; has failed to upload.', 'buddypress' ),
672
  'has_avatar_warning' => __( 'If you&#39;d like to delete the existing profile photo but not upload a new one, please use the delete tab.', 'buddypress' )
673
+ )
674
+ );
675
  }
676
 
677
  /**
820
  // Cover images only need 1 file and 1 only!
821
  $defaults['multi_selection'] = false;
822
 
823
+ // Default cover component is members.
824
+ $cover_component = 'members';
825
 
826
  // Get the object we're editing the cover image of.
827
  $object = $defaults['multipart_params']['bp_params']['object'];
838
  // Set warning messages.
839
  $strings['cover_image_warnings'] = apply_filters( 'bp_attachments_cover_image_ui_warnings', array(
840
  'dimensions' => sprintf(
841
+ /* translators: 1: the advised width size in pixels. 2: the advised height size in pixels. */
842
+ __( 'For better results, make sure to upload an image that is larger than %1$spx wide, and %2$spx tall.', 'buddypress' ),
843
+ (int) $cover_dimensions['width'],
844
+ (int) $cover_dimensions['height']
845
+ ),
846
  ) );
847
  }
848
 
916
  $can = (bool) groups_is_user_admin( bp_loggedin_user_id(), $args['item_id'] ) || bp_current_user_can( 'bp_moderate' );
917
  }
918
  // User profile photo.
919
+ } elseif ( bp_is_active( 'members' ) && 'user' === $args['object'] ) {
920
  $can = bp_loggedin_user_id() === (int) $args['item_id'] || bp_current_user_can( 'bp_moderate' );
921
  }
922
  /**
1005
  *
1006
  * @since 2.4.0
1007
  *
1008
+ * @param string $component The component to get the settings for ("members" for user or "groups").
1009
  * @return false|array The cover image settings in array, false on failure.
1010
  */
1011
+ function bp_attachments_get_cover_image_settings( $component = 'members' ) {
1012
  // Default parameters.
1013
  $args = array();
1014
 
1019
  $args = (array) $cover_image;
1020
  }
1021
 
1022
+ // Set default args.
1023
+ $default_args = wp_parse_args(
1024
+ $args,
1025
+ array(
1026
+ 'components' => array(),
1027
+ 'width' => 1300,
1028
+ 'height' => 225,
1029
+ 'callback' => '',
1030
+ 'theme_handle' => '',
1031
+ 'default_cover' => '',
1032
+ )
1033
+ );
1034
+
1035
+ // Handle deprecated xProfile fitler.
1036
+ if ( 'members' === $component ) {
1037
+ /** This filter is documented in wp-includes/deprecated.php */
1038
+ $args = apply_filters_deprecated( 'bp_before_xprofile_cover_image_settings_parse_args', array( $default_args ), '6.0.0', 'bp_before_members_cover_image_settings_parse_args' );
1039
+ }
1040
+
1041
  /**
1042
  * Then let people override/set the feature using this dynamic filter
1043
  *
1044
  * Eg: for the user's profile cover image use:
1045
+ * add_filter( 'bp_before_members_cover_image_settings_parse_args', 'your_filter', 10, 1 );
1046
  *
1047
  * @since 2.4.0
1048
  *
1049
  * @param array $settings The cover image settings
1050
  */
1051
+ $settings = bp_parse_args( $args, $default_args, $component . '_cover_image_settings' );
1052
+
1053
+ // Handle deprecated xProfile fitler.
1054
+ if ( 'members' === $component ) {
1055
+ /** This filter is documented in wp-includes/deprecated.php */
1056
+ $settings = apply_filters_deprecated( 'bp_after_xprofile_cover_image_settings_parse_args', array( $settings ), '6.0.0', 'bp_after_members_cover_image_settings_parse_args' );
1057
+ }
 
1058
 
1059
  if ( empty( $settings['components'] ) || empty( $settings['callback'] ) || empty( $settings['theme_handle'] ) ) {
1060
  return false;
1074
  *
1075
  * @since 2.4.0
1076
  *
1077
+ * @param string $component The BuddyPress component concerned ("members" for user or "groups").
1078
  * @return array|bool An associative array containing the advised width and height for the cover image. False if settings are empty.
1079
  */
1080
+ function bp_attachments_get_cover_image_dimensions( $component = 'members' ) {
1081
  // Let's prevent notices when setting the warning strings.
1082
  $default = array( 'width' => 0, 'height' => 0 );
1083
 
1113
  $retval = false;
1114
 
1115
  $current_component = bp_current_component();
1116
+ if ( bp_is_user() ) {
1117
+ $current_component = 'members';
1118
  }
1119
 
1120
  if ( ! bp_is_active( $current_component, 'cover_image' ) ) {
1157
  * Does the group has a cover image?
1158
  *
1159
  * @since 2.4.0
1160
+ * @since 6.0.0 Renamed the filter coherently.
1161
  *
1162
  * @param int $group_id Group ID to check cover image existence for.
1163
  * @return bool True if the group has a cover image, false otherwise.
1172
  'item_id' => $group_id,
1173
  ) );
1174
 
1175
+ return (bool) apply_filters( 'bp_attachments_get_group_has_cover_image', $cover_src, $group_id );
1176
  }
1177
 
1178
  /**
1182
  *
1183
  * @param array $args {
1184
  * @type string $file The absolute path to the image. Required.
1185
+ * @type string $component The component for the object (eg: groups, members). Required.
1186
  * @type string $cover_image_dir The Cover image dir to write the image into. Required.
1187
  * }
1188
  * @param BP_Attachment_Cover_Image|null $cover_image_class The class to use to fit the cover image.
1303
 
1304
  // Member's cover image.
1305
  if ( 'user' === $bp_params['object'] ) {
1306
+ $object_data = array( 'dir' => 'members', 'component' => 'members' );
1307
 
1308
  if ( ! bp_displayed_user_id() && ! empty( $bp_params['item_id'] ) ) {
1309
  $needs_reset = array( 'key' => 'displayed_user', 'value' => $bp->displayed_user );
1362
  // Upload error response.
1363
  bp_attachments_json_response( false, $is_html4, array(
1364
  'type' => 'upload_error',
1365
+ 'message' => sprintf(
1366
+ /* translators: %s: the upload error message */
1367
+ __( 'Upload Failed! Error was: %s', 'buddypress' ),
1368
+ $uploaded['error']
1369
+ ),
1370
  ) );
1371
  }
1372
 
1424
  }
1425
 
1426
  // Set the name of the file.
1427
+ $name = $_FILES['file']['name'];
1428
  $name_parts = pathinfo( $name );
1429
+ $name = trim( substr( $name, 0, - ( 1 + strlen( $name_parts['extension'] ) ) ) );
1430
+
1431
+ // Set some arguments for filters.
1432
+ $item_id = (int) $bp_params['item_id'];
1433
+ $component = $object_data['component'];
1434
 
1435
  /**
1436
  * Fires if the new cover image was successfully uploaded.
1437
  *
1438
+ * The dynamic portion of the hook will be members in case of a user's
1439
  * cover image, groups in case of a group's cover image. For instance:
1440
+ * Use add_action( 'members_cover_image_uploaded' ) to run your specific
1441
  * code once the user has set his cover image.
1442
  *
1443
  * @since 2.4.0
1449
  * @param int $feedback_code If value not 1, an error occured.
1450
  */
1451
  do_action(
1452
+ $component . '_cover_image_uploaded',
1453
+ $item_id,
1454
  $name,
1455
  $cover_url,
1456
  $feedback_code
1457
  );
1458
 
1459
+ // Handle deprecated xProfile action.
1460
+ if ( 'members' === $component ) {
1461
+ /** This filter is documented in wp-includes/deprecated.php */
1462
+ do_action_deprecated(
1463
+ 'xprofile_cover_image_uploaded',
1464
+ array(
1465
+ $item_id,
1466
+ $name,
1467
+ $cover_url,
1468
+ $feedback_code,
1469
+ ),
1470
+ '6.0.0',
1471
+ 'members_cover_image_deleted'
1472
+ );
1473
+ }
1474
+
1475
  // Finally return the cover image url to the UI.
1476
  bp_attachments_json_response( true, $is_html4, array(
1477
  'name' => $name,
1511
 
1512
  // Set object for the user's case.
1513
  if ( 'user' === $args['object'] ) {
1514
+ $component = 'members';
1515
  $dir = 'members';
1516
 
1517
  // Set it for any other cases.
1522
 
1523
  // Handle delete.
1524
  if ( bp_attachments_delete_file( array( 'item_id' => $args['item_id'], 'object_dir' => $dir, 'type' => 'cover-image' ) ) ) {
1525
+ $item_id = (int) $args['item_id'];
1526
+
1527
  /**
1528
  * Fires if the cover image was successfully deleted.
1529
  *
1530
+ * The dynamic portion of the hook will be members in case of a user's
1531
  * cover image, groups in case of a group's cover image. For instance:
1532
+ * Use add_action( 'members_cover_image_deleted' ) to run your specific
1533
  * code once the user has deleted his cover image.
1534
  *
1535
  * @since 2.8.0
1536
  *
1537
  * @param int $item_id Inform about the item id the cover image was deleted for.
1538
  */
1539
+ do_action( "{$component}_cover_image_deleted", $item_id );
1540
+
1541
+ // Handle deprecated xProfile action.
1542
+ if ( 'members' === $component ) {
1543
+ /** This filter is documented in wp-includes/deprecated.php */
1544
+ do_action_deprecated( 'xprofile_cover_image_deleted', array( $item_id ), '6.0.0', 'members_cover_image_deleted' );
1545
+ }
1546
 
1547
  $response = array(
1548
  'reset_url' => '',
bp-core/bp-core-avatars.php CHANGED
@@ -193,12 +193,10 @@ function bp_core_fetch_avatar( $args = '' ) {
193
  $bp = buddypress();
194
 
195
  // If avatars are disabled for the root site, obey that request and bail.
196
- if ( ! $bp->avatar->show_avatars ) {
197
  return;
198
  }
199
 
200
- global $current_blog;
201
-
202
  // Set the default variables array and parse it against incoming $args array.
203
  $params = wp_parse_args( $args, array(
204
  'item_id' => false,
@@ -227,7 +225,7 @@ function bp_core_fetch_avatar( $args = '' ) {
227
  switch ( $params['object'] ) {
228
 
229
  case 'blog' :
230
- $params['item_id'] = $current_blog->id;
231
  break;
232
 
233
  case 'group' :
@@ -750,7 +748,7 @@ function bp_core_delete_existing_avatar( $args = '' ) {
750
  } elseif ( 'group' === $args['object'] ) {
751
  $args['item_id'] = buddypress()->groups->current_group->id;
752
  } elseif ( 'blog' === $args['object'] ) {
753
- $args['item_id'] = $current_blog->id;
754
  }
755
 
756
  /** This filter is documented in bp-core/bp-core-avatars.php */
@@ -913,6 +911,7 @@ function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
913
 
914
  // In case of an error, stop the process and display a feedback to the user.
915
  if ( ! empty( $bp->avatar_admin->original['error'] ) ) {
 
916
  bp_core_add_message( sprintf( __( 'Upload Failed! Error was: %s', 'buddypress' ), $bp->avatar_admin->original['error'] ), 'error' );
917
  return false;
918
  }
@@ -941,13 +940,15 @@ function bp_core_avatar_handle_upload( $file, $upload_dir_filter ) {
941
 
942
  // Check for WP_Error on what should be an image.
943
  if ( is_wp_error( $bp->avatar_admin->image->dir ) ) {
 
944
  bp_core_add_message( sprintf( __( 'Upload failed! Error was: %s', 'buddypress' ), $bp->avatar_admin->image->dir->get_error_message() ), 'error' );
945
  return false;
946
  }
947
 
948
  // If the uploaded image is smaller than the "full" dimensions, throw a warning.
949
  if ( $avatar_attachment->is_too_small( $bp->avatar_admin->image->file ) ) {
950
- bp_core_add_message( sprintf( __( 'You have selected an image that is smaller than recommended. For best results, upload a picture larger than %d x %d pixels.', 'buddypress' ), bp_core_avatar_full_width(), bp_core_avatar_full_height() ), 'error' );
 
951
  }
952
 
953
  // Set the url value for the image.
@@ -1005,8 +1006,8 @@ function bp_avatar_ajax_upload() {
1005
  $bp_params['upload_dir_filter'] = '';
1006
  $needs_reset = array();
1007
 
1008
- if ( 'user' === $bp_params['object'] && bp_is_active( 'xprofile' ) ) {
1009
- $bp_params['upload_dir_filter'] = 'xprofile_avatar_upload_dir';
1010
 
1011
  if ( ! bp_displayed_user_id() && ! empty( $bp_params['item_id'] ) ) {
1012
  $needs_reset = array( 'key' => 'displayed_user', 'value' => $bp->displayed_user );
@@ -1297,20 +1298,19 @@ function bp_avatar_ajax_set() {
1297
  'item_id' => $avatar_data['item_id'],
1298
  );
1299
 
 
 
 
1300
  /**
1301
  * Fires if the new avatar was successfully captured.
1302
  *
1303
- * @since 1.1.0 Used to inform the avatar was successfully cropped
1304
- * @since 2.3.4 Add two new parameters to inform about the user id and
1305
- * about the way the avatar was set (eg: 'crop' or 'camera')
1306
- * Move the action at the right place, once the avatar is set
1307
- * @since 2.8.0 Added the `$avatar_data` parameter.
1308
  *
1309
  * @param string $item_id Inform about the user id the avatar was set for.
1310
  * @param string $type Inform about the way the avatar was set ('camera').
1311
  * @param array $avatar_data Array of parameters passed to the avatar handler.
1312
  */
1313
- do_action( 'xprofile_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $avatar_data );
1314
 
1315
  wp_send_json_success( $return );
1316
  }
@@ -1355,8 +1355,11 @@ function bp_avatar_ajax_set() {
1355
  );
1356
 
1357
  if ( 'user' === $avatar_data['object'] ) {
 
 
 
1358
  /** This action is documented in bp-core/bp-core-avatars.php */
1359
- do_action( 'xprofile_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $r );
1360
  } elseif ( 'group' === $avatar_data['object'] ) {
1361
  /** This action is documented in bp-groups/bp-groups-screens.php */
1362
  do_action( 'groups_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $r );
@@ -1936,11 +1939,6 @@ add_action( 'bp_parse_query', 'bp_core_avatar_reset_query', 10, 1 );
1936
  function bp_avatar_is_front_edit() {
1937
  $retval = false;
1938
 
1939
- // No need to carry on if the current WordPress version is not supported.
1940
- if ( ! bp_attachments_is_wp_version_supported() ) {
1941
- return $retval;
1942
- }
1943
-
1944
  if ( bp_is_user_change_avatar() && 'crop-image' !== bp_get_avatar_admin_step() ) {
1945
  $retval = ! bp_core_get_root_option( 'bp-disable-avatar-uploads' );
1946
  }
193
  $bp = buddypress();
194
 
195
  // If avatars are disabled for the root site, obey that request and bail.
196
+ if ( ! $bp->avatar || ! $bp->avatar->show_avatars ) {
197
  return;
198
  }
199
 
 
 
200
  // Set the default variables array and parse it against incoming $args array.
201
  $params = wp_parse_args( $args, array(
202
  'item_id' => false,
225
  switch ( $params['object'] ) {
226
 
227
  case 'blog' :
228
+ $params['item_id'] = get_current_blog_id();
229
  break;
230
 
231
  case 'group' :
748
  } elseif ( 'group' === $args['object'] ) {
749
  $args['item_id'] = buddypress()->groups->current_group->id;
750
  } elseif ( 'blog' === $args['object'] ) {
751
+ $args['item_id'] = get_current_blog_id();
752
  }
753
 
754
  /** This filter is documented in bp-core/bp-core-avatars.php */
911
 
912
  // In case of an error, stop the process and display a feedback to the user.
913
  if ( ! empty( $bp->avatar_admin->original['error'] ) ) {
914
+ /* translators: %s: the upload error message */
915
  bp_core_add_message( sprintf( __( 'Upload Failed! Error was: %s', 'buddypress' ), $bp->avatar_admin->original['error'] ), 'error' );
916
  return false;
917
  }
940
 
941
  // Check for WP_Error on what should be an image.
942
  if ( is_wp_error( $bp->avatar_admin->image->dir ) ) {
943
+ /* translators: %s: the upload error message */
944
  bp_core_add_message( sprintf( __( 'Upload failed! Error was: %s', 'buddypress' ), $bp->avatar_admin->image->dir->get_error_message() ), 'error' );
945
  return false;
946
  }
947
 
948
  // If the uploaded image is smaller than the "full" dimensions, throw a warning.
949
  if ( $avatar_attachment->is_too_small( $bp->avatar_admin->image->file ) ) {
950
+ /* translators: 1: the advised width size in pixels. 2: the advised height size in pixels. */
951
+ bp_core_add_message( sprintf( __( 'You have selected an image that is smaller than recommended. For best results, upload a picture larger than %1$d x %2$d pixels.', 'buddypress' ), bp_core_avatar_full_width(), bp_core_avatar_full_height() ), 'error' );
952
  }
953
 
954
  // Set the url value for the image.
1006
  $bp_params['upload_dir_filter'] = '';
1007
  $needs_reset = array();
1008
 
1009
+ if ( 'user' === $bp_params['object'] && bp_is_active( 'members' ) ) {
1010
+ $bp_params['upload_dir_filter'] = 'bp_members_avatar_upload_dir';
1011
 
1012
  if ( ! bp_displayed_user_id() && ! empty( $bp_params['item_id'] ) ) {
1013
  $needs_reset = array( 'key' => 'displayed_user', 'value' => $bp->displayed_user );
1298
  'item_id' => $avatar_data['item_id'],
1299
  );
1300
 
1301
+ /** This action is documented in wp-includes/deprecated.php */
1302
+ do_action_deprecated( 'xprofile_avatar_uploaded', array( (int) $avatar_data['item_id'], $avatar_data['type'], $avatar_data ), '6.0.0', 'bp_members_avatar_uploaded' );
1303
+
1304
  /**
1305
  * Fires if the new avatar was successfully captured.
1306
  *
1307
+ * @since 6.0.0
 
 
 
 
1308
  *
1309
  * @param string $item_id Inform about the user id the avatar was set for.
1310
  * @param string $type Inform about the way the avatar was set ('camera').
1311
  * @param array $avatar_data Array of parameters passed to the avatar handler.
1312
  */
1313
+ do_action( 'bp_members_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $avatar_data );
1314
 
1315
  wp_send_json_success( $return );
1316
  }
1355
  );
1356
 
1357
  if ( 'user' === $avatar_data['object'] ) {
1358
+ /** This action is documented in wp-includes/deprecated.php */
1359
+ do_action_deprecated( 'xprofile_avatar_uploaded', array( (int) $avatar_data['item_id'], $avatar_data['type'], $r ), '6.0.0', 'bp_members_avatar_uploaded' );
1360
+
1361
  /** This action is documented in bp-core/bp-core-avatars.php */
1362
+ do_action( 'bp_members_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $r );
1363
  } elseif ( 'group' === $avatar_data['object'] ) {
1364
  /** This action is documented in bp-groups/bp-groups-screens.php */
1365
  do_action( 'groups_avatar_uploaded', (int) $avatar_data['item_id'], $avatar_data['type'], $r );
1939
  function bp_avatar_is_front_edit() {
1940
  $retval = false;
1941
 
 
 
 
 
 
1942
  if ( bp_is_user_change_avatar() && 'crop-image' !== bp_get_avatar_admin_step() ) {
1943
  $retval = ! bp_core_get_root_option( 'bp-disable-avatar-uploads' );
1944
  }
bp-core/bp-core-blocks.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Core BP Blocks functions.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage Core
7
+ * @since 6.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ defined( 'ABSPATH' ) || exit;
12
+
13
+ /**
14
+ * BuddyPress blocks require WordPress >= 5.0.0 & the BP REST API.
15
+ *
16
+ * @since 6.0.0
17
+ *
18
+ * @return bool True if the current installation supports BP Blocks.
19
+ * False otherwise.
20
+ */
21
+ function bp_support_blocks() {
22
+ return function_exists( 'register_block_type' ) && bp_rest_api_is_available();
23
+ }
24
+
25
+ /**
26
+ * Registers the BP Block components.
27
+ *
28
+ * @since 6.0.0
29
+ */
30
+ function bp_register_block_components() {
31
+ wp_register_script(
32
+ 'bp-block-components',
33
+ plugins_url( 'js/block-components.js', __FILE__ ),
34
+ array(
35
+ 'wp-element',
36
+ 'wp-components',
37
+ 'wp-i18n',
38
+ 'wp-api-fetch',
39
+ ),
40
+ bp_get_version()
41
+ );
42
+ }
43
+ add_action( 'bp_blocks_init', 'bp_register_block_components', 1 );
44
+
45
+ /**
46
+ * Filters the Block Editor settings to gather BuddyPress ones into a `bp` key.
47
+ *
48
+ * @since 6.0.0
49
+ *
50
+ * @param array $editor_settings Default editor settings.
51
+ * @return array The editor settings including BP blocks specific ones.
52
+ */
53
+ function bp_blocks_editor_settings( $editor_settings = array() ) {
54
+ /**
55
+ * Filter here to include your BP Blocks specific settings.
56
+ *
57
+ * @since 6.0.0
58
+ *
59
+ * @param array $bp_editor_settings BP blocks specific editor settings.
60
+ */
61
+ $bp_editor_settings = (array) apply_filters( 'bp_blocks_editor_settings', array() );
62
+
63
+ if ( $bp_editor_settings ) {
64
+ $editor_settings['bp'] = $bp_editor_settings;
65
+ }
66
+
67
+ return $editor_settings;
68
+ }
69
+ add_filter( 'block_editor_settings', 'bp_blocks_editor_settings' );
70
+
71
+ /**
72
+ * Register a BuddyPress block type.
73
+ *
74
+ * @since 6.0.0
75
+ *
76
+ * @param array $args The registration arguments for the block type.
77
+ * @return BP_Block The BuddyPress block type object.
78
+ */
79
+ function bp_register_block( $args = array() ) {
80
+ return new BP_Block( $args );
81
+ }
bp-core/bp-core-cache.php CHANGED
@@ -6,7 +6,7 @@
6
  * actions throughout BuddyPress.
7
  *
8
  * @package BuddyPress
9
- * @supackage Cache
10
  * @since 1.5.0
11
  */
12
 
@@ -80,14 +80,14 @@ function bp_core_clear_directory_pages_cache_page_edit( $post_id = 0 ) {
80
  return;
81
  }
82
 
83
- // Bail if not on the root blog
84
  if ( ! bp_is_root_blog() ) {
85
  return;
86
  }
87
 
88
  $page_ids = bp_core_get_directory_page_ids( 'all' );
89
 
90
- // Bail if post ID is not a directory page
91
  if ( ! in_array( $post_id, $page_ids ) ) {
92
  return;
93
  }
6
  * actions throughout BuddyPress.
7
  *
8
  * @package BuddyPress
9
+ * @subpackage Cache
10
  * @since 1.5.0
11
  */
12
 
80
  return;
81
  }
82
 
83
+ // Bail if not on the root blog.
84
  if ( ! bp_is_root_blog() ) {
85
  return;
86
  }
87
 
88
  $page_ids = bp_core_get_directory_page_ids( 'all' );
89
 
90
+ // Bail if post ID is not a directory page.
91
  if ( ! in_array( $post_id, $page_ids ) ) {
92
  return;
93
  }
bp-core/bp-core-catchuri.php CHANGED
@@ -97,7 +97,7 @@ function bp_core_set_uri_globals() {
97
  foreach( $chunks as $key => $chunk ) {
98
  $bkey = array_search( $chunk, $bp_uri );
99
 
100
- // ...and unset offending keys
101
  if ( false !== $bkey ) {
102
  unset( $bp_uri[$bkey] );
103
  }
97
  foreach( $chunks as $key => $chunk ) {
98
  $bkey = array_search( $chunk, $bp_uri );
99
 
100
+ // ...and unset offending keys.
101
  if ( false !== $bkey ) {
102
  unset( $bp_uri[$bkey] );
103
  }
bp-core/bp-core-cssjs.php CHANGED
@@ -442,7 +442,7 @@ function bp_add_cover_image_inline_css( $return = false ) {
442
  }
443
 
444
  $cover_image_object = array(
445
- 'component' => 'xprofile',
446
  'object' => $bp->displayed_user
447
  );
448
  } elseif ( bp_is_group() ) {
@@ -479,7 +479,7 @@ function bp_add_cover_image_inline_css( $return = false ) {
479
 
480
  $object_dir = $cover_image_object['component'];
481
 
482
- if ( 'xprofile' === $object_dir ) {
483
  $object_dir = 'members';
484
  }
485
 
442
  }
443
 
444
  $cover_image_object = array(
445
+ 'component' => 'members',
446
  'object' => $bp->displayed_user
447
  );
448
  } elseif ( bp_is_group() ) {
479
 
480
  $object_dir = $cover_image_object['component'];
481
 
482
+ if ( 'members' === $object_dir ) {
483
  $object_dir = 'members';
484
  }
485
 
bp-core/bp-core-dependency.php CHANGED
@@ -7,7 +7,7 @@
7
  * own in a safe and reliable way.
8
  *
9
  * We do this in BuddyPress by mirroring existing WordPress hooks in many places
10
- * allowing dependant plugins to hook into the BuddyPress specific ones, thus
11
  * guaranteeing proper code execution only when BuddyPress is active.
12
  *
13
  * The following functions are wrappers for hooks, allowing them to be
@@ -267,6 +267,20 @@ function bp_rest_api_init() {
267
  do_action( 'bp_rest_api_init' );
268
  }
269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  /**
271
  * Fire the 'bp_customize_register' action when the Customizer has loaded,
272
  * allowing scripts and styles to be initialized.
7
  * own in a safe and reliable way.
8
  *
9
  * We do this in BuddyPress by mirroring existing WordPress hooks in many places
10
+ * allowing dependent plugins to hook into the BuddyPress specific ones, thus
11
  * guaranteeing proper code execution only when BuddyPress is active.
12
  *
13
  * The following functions are wrappers for hooks, allowing them to be
267
  do_action( 'bp_rest_api_init' );
268
  }
269
 
270
+ /**
271
+ * BP Blocks Init hook.
272
+ *
273
+ * @since 6.0.0
274
+ */
275
+ function bp_blocks_init() {
276
+ /**
277
+ * Hook here to register your BuddyPress blocks.
278
+ *
279
+ * @since 6.0.0
280
+ */
281
+ do_action( 'bp_blocks_init' );
282
+ }
283
+
284
  /**
285
  * Fire the 'bp_customize_register' action when the Customizer has loaded,
286
  * allowing scripts and styles to be initialized.
bp-core/bp-core-filters.php CHANGED
@@ -434,7 +434,7 @@ function bp_core_filter_blog_welcome_email( $welcome_email, $blog_id, $user_id,
434
  if ( ! bp_has_custom_signup_page() )
435
  return $welcome_email;
436
 
437
- // [User Set] Replaces $password in welcome email; Represents value set by user
438
  return str_replace( $password, __( '[User Set]', 'buddypress' ), $welcome_email );
439
  }
440
  add_filter( 'update_welcome_email', 'bp_core_filter_blog_welcome_email', 10, 4 );
@@ -600,6 +600,7 @@ function bp_modify_page_title( $title = '', $sep = '&raquo;', $seplocation = 'ri
600
  $bp_title_parts['site'] = $blogname;
601
 
602
  if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() && ! bp_is_single_activity() ) {
 
603
  $bp_title_parts['page'] = sprintf( __( 'Page %s', 'buddypress' ), max( $paged, $page ) );
604
  }
605
  }
@@ -811,7 +812,7 @@ add_filter( 'customize_nav_menu_available_items', 'bp_customizer_nav_menus_get_i
811
  *
812
  * @since 2.3.3
813
  *
814
- * @param array $item_types An associative array structured for the customizer.
815
  * @return array $item_types An associative array structured for the customizer.
816
  */
817
  function bp_customizer_nav_menus_set_item_types( $item_types = array() ) {
@@ -1168,3 +1169,18 @@ function bp_core_render_email_template( $template ) {
1168
  return '';
1169
  }
1170
  add_action( 'bp_template_include', 'bp_core_render_email_template', 12 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
434
  if ( ! bp_has_custom_signup_page() )
435
  return $welcome_email;
436
 
437
+ // [User Set] Replaces $password in welcome email; Represents value set by user.
438
  return str_replace( $password, __( '[User Set]', 'buddypress' ), $welcome_email );
439
  }
440
  add_filter( 'update_welcome_email', 'bp_core_filter_blog_welcome_email', 10, 4 );
600
  $bp_title_parts['site'] = $blogname;
601
 
602
  if ( ( $paged >= 2 || $page >= 2 ) && ! is_404() && ! bp_is_single_activity() ) {
603
+ /* translators: %s: the page number. */
604
  $bp_title_parts['page'] = sprintf( __( 'Page %s', 'buddypress' ), max( $paged, $page ) );
605
  }
606
  }
812
  *
813
  * @since 2.3.3
814
  *
815
+ * @param array $item_types An associative array structured for the customizer.
816
  * @return array $item_types An associative array structured for the customizer.
817
  */
818
  function bp_customizer_nav_menus_set_item_types( $item_types = array() ) {
1169
  return '';
1170
  }
1171
  add_action( 'bp_template_include', 'bp_core_render_email_template', 12 );
1172
+
1173
+ /**
1174
+ * Adds BuddyPress components' slugs to the WordPress Multisite subdirectory reserved names.
1175
+ *
1176
+ * @since 6.0.0
1177
+ *
1178
+ * @param array $names The WordPress Multisite subdirectory reserved names.
1179
+ * @return array The WordPress & BuddyPress Multisite subdirectory reserved names.
1180
+ */
1181
+ function bp_core_components_subdirectory_reserved_names( $names = array() ) {
1182
+ $bp_pages = (array) buddypress()->pages;
1183
+
1184
+ return array_merge( $names, wp_list_pluck( $bp_pages, 'slug' ) );
1185
+ }
1186
+ add_filter( 'subdirectory_reserved_names', 'bp_core_components_subdirectory_reserved_names' );
bp-core/bp-core-functions.php CHANGED
@@ -16,7 +16,6 @@ defined( 'ABSPATH' ) || exit;
16
  * Output the BuddyPress version.
17
  *
18
  * @since 1.6.0
19
- *
20
  */
21
  function bp_version() {
22
  echo bp_get_version();
@@ -36,7 +35,6 @@ function bp_version() {
36
  * Output the BuddyPress database version.
37
  *
38
  * @since 1.6.0
39
- *
40
  */
41
  function bp_db_version() {
42
  echo bp_get_db_version();
@@ -56,7 +54,6 @@ function bp_db_version() {
56
  * Output the BuddyPress database version.
57
  *
58
  * @since 1.6.0
59
- *
60
  */
61
  function bp_db_version_raw() {
62
  echo bp_get_db_version_raw();
@@ -236,7 +233,7 @@ function bp_core_number_format( $number = 0, $decimals = false ) {
236
  *
237
  * @since 1.6.0
238
  *
239
- * @param array $old_args_keys Old argument indexs, keyed to their positions.
240
  * @param array $func_args The parameters passed to the originating function.
241
  * @return array $new_args The parsed arguments.
242
  */
@@ -321,7 +318,7 @@ function bp_parse_args( $args, $defaults = array(), $filter_key = '' ) {
321
  /**
322
  * Sanitizes a pagination argument based on both the request override and the
323
  * original value submitted via a query argument, likely to a template class
324
- * responsible for limiting the resultset of a template loop.
325
  *
326
  * @since 2.2.0
327
  *
@@ -505,7 +502,7 @@ function bp_core_get_packaged_component_ids() {
505
  function bp_core_get_directory_page_ids( $status = 'active' ) {
506
  $page_ids = bp_get_option( 'bp-pages', array() );
507
 
508
- // Loop through pages
509
  foreach ( $page_ids as $component_name => $page_id ) {
510
 
511
  // Ensure that empty indexes are unset. Should only matter in edge cases.
@@ -908,19 +905,6 @@ function bp_core_create_root_component_page() {
908
  bp_core_update_directory_page_ids( $page_ids );
909
  }
910
 
911
- /**
912
- * Add illegal blog names to WP so that root components will not conflict with blog names on a subdirectory installation.
913
- *
914
- * For example, it would stop someone creating a blog with the slug "groups".
915
- *
916
- * @since 1.0.0
917
- *
918
- * @todo Deprecate?
919
- */
920
- function bp_core_add_illegal_names() {
921
- update_site_option( 'illegal_names', get_site_option( 'illegal_names' ), array() );
922
- }
923
-
924
  /**
925
  * Get the 'search' query argument for a given component.
926
  *
@@ -1201,7 +1185,11 @@ function bp_core_time_since( $older_date, $newer_date = false ) {
1201
  *
1202
  * @param string $value String representing the time since the older date.
1203
  */
1204
- $ago_text = apply_filters( 'bp_core_time_since_ago_text', __( '%s ago', 'buddypress' ) );
 
 
 
 
1205
 
1206
  // Array of time period chunks.
1207
  $chunks = array(
@@ -1262,24 +1250,31 @@ function bp_core_time_since( $older_date, $newer_date = false ) {
1262
  // Set output var.
1263
  switch ( $seconds ) {
1264
  case YEAR_IN_SECONDS :
 
1265
  $output = sprintf( _n( '%s year', '%s years', $count, 'buddypress' ), $count );
1266
  break;
1267
  case 30 * DAY_IN_SECONDS :
 
1268
  $output = sprintf( _n( '%s month', '%s months', $count, 'buddypress' ), $count );
1269
  break;
1270
  case WEEK_IN_SECONDS :
 
1271
  $output = sprintf( _n( '%s week', '%s weeks', $count, 'buddypress' ), $count );
1272
  break;
1273
  case DAY_IN_SECONDS :
 
1274
  $output = sprintf( _n( '%s day', '%s days', $count, 'buddypress' ), $count );
1275
  break;
1276
  case HOUR_IN_SECONDS :
 
1277
  $output = sprintf( _n( '%s hour', '%s hours', $count, 'buddypress' ), $count );
1278
  break;
1279
  case MINUTE_IN_SECONDS :
 
1280
  $output = sprintf( _n( '%s minute', '%s minutes', $count, 'buddypress' ), $count );
1281
  break;
1282
  default:
 
1283
  $output = sprintf( _n( '%s second', '%s seconds', $count, 'buddypress' ), $count );
1284
  }
1285
 
@@ -1299,21 +1294,27 @@ function bp_core_time_since( $older_date, $newer_date = false ) {
1299
 
1300
  switch ( $seconds2 ) {
1301
  case 30 * DAY_IN_SECONDS :
 
1302
  $output .= sprintf( _n( '%s month', '%s months', $count2, 'buddypress' ), $count2 );
1303
  break;
1304
  case WEEK_IN_SECONDS :
 
1305
  $output .= sprintf( _n( '%s week', '%s weeks', $count2, 'buddypress' ), $count2 );
1306
  break;
1307
  case DAY_IN_SECONDS :
 
1308
  $output .= sprintf( _n( '%s day', '%s days', $count2, 'buddypress' ), $count2 );
1309
  break;
1310
  case HOUR_IN_SECONDS :
 
1311
  $output .= sprintf( _n( '%s hour', '%s hours', $count2, 'buddypress' ), $count2 );
1312
  break;
1313
  case MINUTE_IN_SECONDS :
 
1314
  $output .= sprintf( _n( '%s minute', '%s minutes', $count2, 'buddypress' ), $count2 );
1315
  break;
1316
  default:
 
1317
  $output .= sprintf( _n( '%s second', '%s seconds', $count2, 'buddypress' ), $count2 );
1318
  }
1319
  }
@@ -1422,7 +1423,6 @@ function bp_core_add_message( $message, $type = '' ) {
1422
  * so that the message is not shown to the user multiple times.
1423
  *
1424
  * @since 1.1.0
1425
- *
1426
  */
1427
  function bp_core_setup_message() {
1428
 
@@ -1506,8 +1506,6 @@ function bp_core_render_message() {
1506
  *
1507
  * @since 1.0.0
1508
  *
1509
- * usermeta table.
1510
- *
1511
  * @return false|null Returns false if there is nothing to do.
1512
  */
1513
  function bp_core_record_activity() {
@@ -1563,8 +1561,6 @@ add_action( 'wp_head', 'bp_core_record_activity' );
1563
  *
1564
  * @since 1.0.0
1565
  *
1566
- * representation of the time elapsed.
1567
- *
1568
  * @param int|string $last_activity_date The date of last activity.
1569
  * @param string $string A sprintf()-able statement of the form 'active %s'.
1570
  * @return string $last_active A string of the form '3 years ago'.
@@ -1573,7 +1569,7 @@ function bp_core_get_last_activity( $last_activity_date = '', $string = '' ) {
1573
 
1574
  // Setup a default string if none was passed.
1575
  $string = empty( $string )
1576
- ? '%s' // Gettext placeholder.
1577
  : $string;
1578
 
1579
  // Use the string if a last activity date was passed.
@@ -1598,7 +1594,7 @@ function bp_core_get_last_activity( $last_activity_date = '', $string = '' ) {
1598
  /**
1599
  * Get the meta_key for a given piece of user metadata
1600
  *
1601
- * BuddyPress stores a number of pieces of userdata in the WordPress central
1602
  * usermeta table. In order to allow plugins to enable multiple instances of
1603
  * BuddyPress on a single WP installation, BP's usermeta keys are filtered
1604
  * through this function, so that they can be altered on the fly.
@@ -2739,7 +2735,7 @@ function bp_core_get_suggestions( $args ) {
2739
  * @since 2.1.0
2740
  *
2741
  * @param string $value Custom class to use. Default: none.
2742
- * @param array $args Array of arguments for sugggestions.
2743
  */
2744
  $class = apply_filters( 'bp_suggestions_services', '', $args );
2745
  }
@@ -3110,11 +3106,11 @@ function bp_get_email( $email_type ) {
3110
  *
3111
  * @param string $email_type Type of email being sent.
3112
  * @param string|array|int|WP_User $to Either a email address, user ID, WP_User object,
3113
- * or an array containg the address and name.
3114
  * @param array $args {
3115
  * Optional. Array of extra parameters.
3116
  *
3117
- * @type array $tokens Optional. Assocative arrays of string replacements for the email.
3118
  * }
3119
  * @return bool|WP_Error True if the email was sent successfully. Otherwise, a WP_Error object
3120
  * describing why the email failed to send. The contents will vary based
@@ -3155,7 +3151,12 @@ function bp_send_email( $email_type, $to, $args = array() ) {
3155
  }
3156
 
3157
  // From, subject, content are set automatically.
3158
- $email->set_to( $to );
 
 
 
 
 
3159
  $email->set_tokens( $args['tokens'] );
3160
 
3161
  /**
@@ -3166,11 +3167,11 @@ function bp_send_email( $email_type, $to, $args = array() ) {
3166
  * @param BP_Email $email The email (object) about to be sent.
3167
  * @param string $email_type Type of email being sent.
3168
  * @param string|array|int|WP_User $to Either a email address, user ID, WP_User object,
3169
- * or an array containg the address and name.
3170
  * @param array $args {
3171
  * Optional. Array of extra parameters.
3172
  *
3173
- * @type array $tokens Optional. Assocative arrays of string replacements for the email.
3174
  * }
3175
  */
3176
  do_action_ref_array( 'bp_send_email', array( &$email, $email_type, $to, $args ) );
@@ -3220,7 +3221,7 @@ function bp_send_email( $email_type, $to, $args = array() ) {
3220
  * @param array $args {
3221
  * Optional. Array of extra parameters.
3222
  *
3223
- * @type array $tokens Optional. Assocative arrays of string replacements for the email.
3224
  * }
3225
  */
3226
  $delivery_class = apply_filters( 'bp_send_email_delivery_class', 'BP_PHPMailer', $email_type, $to, $args );
@@ -3247,7 +3248,7 @@ function bp_send_email( $email_type, $to, $args = array() ) {
3247
  } else {
3248
 
3249
  /**
3250
- * Fires after BuddyPress has succesfully sent an email.
3251
  *
3252
  * @since 2.5.0
3253
  *
@@ -3270,10 +3271,10 @@ function bp_send_email( $email_type, $to, $args = array() ) {
3270
  * @return array
3271
  */
3272
  function bp_email_get_appearance_settings() {
3273
- /* translators: This is the copyright text for email footers. 1. Copyright year, 2. Site name */
3274
  $footer_text = array(
3275
  sprintf(
3276
- _x( '&copy; %1$s %2$s', 'email', 'buddypress' ),
 
3277
  date_i18n( 'Y' ),
3278
  bp_get_option( 'blogname' )
3279
  )
16
  * Output the BuddyPress version.
17
  *
18
  * @since 1.6.0
 
19
  */
20
  function bp_version() {
21
  echo bp_get_version();
35
  * Output the BuddyPress database version.
36
  *
37
  * @since 1.6.0
 
38
  */
39
  function bp_db_version() {
40
  echo bp_get_db_version();
54
  * Output the BuddyPress database version.
55
  *
56
  * @since 1.6.0
 
57
  */
58
  function bp_db_version_raw() {
59
  echo bp_get_db_version_raw();
233
  *
234
  * @since 1.6.0
235
  *
236
+ * @param array $old_args_keys Old argument indexes, keyed to their positions.
237
  * @param array $func_args The parameters passed to the originating function.
238
  * @return array $new_args The parsed arguments.
239
  */
318
  /**
319
  * Sanitizes a pagination argument based on both the request override and the
320
  * original value submitted via a query argument, likely to a template class
321
+ * responsible for limiting the result set of a template loop.
322
  *
323
  * @since 2.2.0
324
  *
502
  function bp_core_get_directory_page_ids( $status = 'active' ) {
503
  $page_ids = bp_get_option( 'bp-pages', array() );
504
 
505
+ // Loop through pages.
506
  foreach ( $page_ids as $component_name => $page_id ) {
507
 
508
  // Ensure that empty indexes are unset. Should only matter in edge cases.
905
  bp_core_update_directory_page_ids( $page_ids );
906
  }
907
 
 
 
 
 
 
 
 
 
 
 
 
 
 
908
  /**
909
  * Get the 'search' query argument for a given component.
910
  *
1185
  *
1186
  * @param string $value String representing the time since the older date.
1187
  */
1188
+ $ago_text = apply_filters(
1189
+ 'bp_core_time_since_ago_text',
1190
+ /* translators: %s: the human time diff. */
1191
+ __( '%s ago', 'buddypress' )
1192
+ );
1193
 
1194
  // Array of time period chunks.
1195
  $chunks = array(
1250
  // Set output var.
1251
  switch ( $seconds ) {
1252
  case YEAR_IN_SECONDS :
1253
+ /* translators: %s: the number of years. */
1254
  $output = sprintf( _n( '%s year', '%s years', $count, 'buddypress' ), $count );
1255
  break;
1256
  case 30 * DAY_IN_SECONDS :
1257
+ /* translators: %s: the number of months. */
1258
  $output = sprintf( _n( '%s month', '%s months', $count, 'buddypress' ), $count );
1259
  break;
1260
  case WEEK_IN_SECONDS :
1261
+ /* translators: %s: the number of weeks. */
1262
  $output = sprintf( _n( '%s week', '%s weeks', $count, 'buddypress' ), $count );
1263
  break;
1264
  case DAY_IN_SECONDS :
1265
+ /* translators: %s: the number of days. */
1266
  $output = sprintf( _n( '%s day', '%s days', $count, 'buddypress' ), $count );
1267
  break;
1268
  case HOUR_IN_SECONDS :
1269
+ /* translators: %s: the number of hours. */
1270
  $output = sprintf( _n( '%s hour', '%s hours', $count, 'buddypress' ), $count );
1271
  break;
1272
  case MINUTE_IN_SECONDS :
1273
+ /* translators: %s: the number of minutes. */
1274
  $output = sprintf( _n( '%s minute', '%s minutes', $count, 'buddypress' ), $count );
1275
  break;
1276
  default:
1277
+ /* translators: %s: the number of seconds. */
1278
  $output = sprintf( _n( '%s second', '%s seconds', $count, 'buddypress' ), $count );
1279
  }
1280
 
1294
 
1295
  switch ( $seconds2 ) {
1296
  case 30 * DAY_IN_SECONDS :
1297
+ /* translators: %s: the number of months. */
1298
  $output .= sprintf( _n( '%s month', '%s months', $count2, 'buddypress' ), $count2 );
1299
  break;
1300
  case WEEK_IN_SECONDS :
1301
+ /* translators: %s: the number of weeks. */
1302
  $output .= sprintf( _n( '%s week', '%s weeks', $count2, 'buddypress' ), $count2 );
1303
  break;
1304
  case DAY_IN_SECONDS :
1305
+ /* translators: %s: the number of days. */
1306
  $output .= sprintf( _n( '%s day', '%s days', $count2, 'buddypress' ), $count2 );
1307
  break;
1308
  case HOUR_IN_SECONDS :
1309
+ /* translators: %s: the number of hours. */
1310
  $output .= sprintf( _n( '%s hour', '%s hours', $count2, 'buddypress' ), $count2 );
1311
  break;
1312
  case MINUTE_IN_SECONDS :
1313
+ /* translators: %s: the number of minutes. */
1314
  $output .= sprintf( _n( '%s minute', '%s minutes', $count2, 'buddypress' ), $count2 );
1315
  break;
1316
  default:
1317
+ /* translators: %s: the number of seconds. */
1318
  $output .= sprintf( _n( '%s second', '%s seconds', $count2, 'buddypress' ), $count2 );
1319
  }
1320
  }
1423
  * so that the message is not shown to the user multiple times.
1424
  *
1425
  * @since 1.1.0
 
1426
  */
1427
  function bp_core_setup_message() {
1428
 
1506
  *
1507
  * @since 1.0.0
1508
  *
 
 
1509
  * @return false|null Returns false if there is nothing to do.
1510
  */
1511
  function bp_core_record_activity() {
1561
  *
1562
  * @since 1.0.0
1563
  *
 
 
1564
  * @param int|string $last_activity_date The date of last activity.
1565
  * @param string $string A sprintf()-able statement of the form 'active %s'.
1566
  * @return string $last_active A string of the form '3 years ago'.
1569
 
1570
  // Setup a default string if none was passed.
1571
  $string = empty( $string )
1572
+ ? '%s' // Gettext library's placeholder.
1573
  : $string;
1574
 
1575
  // Use the string if a last activity date was passed.
1594
  /**
1595
  * Get the meta_key for a given piece of user metadata
1596
  *
1597
+ * BuddyPress stores a number of pieces of user data in the WordPress central
1598
  * usermeta table. In order to allow plugins to enable multiple instances of
1599
  * BuddyPress on a single WP installation, BP's usermeta keys are filtered
1600
  * through this function, so that they can be altered on the fly.
2735
  * @since 2.1.0
2736
  *
2737
  * @param string $value Custom class to use. Default: none.
2738
+ * @param array $args Array of arguments for suggestions.
2739
  */
2740
  $class = apply_filters( 'bp_suggestions_services', '', $args );
2741
  }
3106
  *
3107
  * @param string $email_type Type of email being sent.
3108
  * @param string|array|int|WP_User $to Either a email address, user ID, WP_User object,
3109
+ * or an array containing the address and name.
3110
  * @param array $args {
3111
  * Optional. Array of extra parameters.
3112
  *
3113
+ * @type array $tokens Optional. Associative arrays of string replacements for the email.
3114
  * }
3115
  * @return bool|WP_Error True if the email was sent successfully. Otherwise, a WP_Error object
3116
  * describing why the email failed to send. The contents will vary based
3151
  }
3152
 
3153
  // From, subject, content are set automatically.
3154
+ if ( 'settings-verify-email-change' === $email_type && isset( $args['tokens']['displayname'] ) ) {
3155
+ $email->set_to( $to, $args['tokens']['displayname'] );
3156
+ } else {
3157
+ $email->set_to( $to );
3158
+ }
3159
+
3160
  $email->set_tokens( $args['tokens'] );
3161
 
3162
  /**
3167
  * @param BP_Email $email The email (object) about to be sent.
3168
  * @param string $email_type Type of email being sent.
3169
  * @param string|array|int|WP_User $to Either a email address, user ID, WP_User object,
3170
+ * or an array containing the address and name.
3171
  * @param array $args {
3172
  * Optional. Array of extra parameters.
3173
  *
3174
+ * @type array $tokens Optional. Associative arrays of string replacements for the email.
3175
  * }
3176
  */
3177
  do_action_ref_array( 'bp_send_email', array( &$email, $email_type, $to, $args ) );
3221
  * @param array $args {
3222
  * Optional. Array of extra parameters.
3223
  *
3224
+ * @type array $tokens Optional. Associative arrays of string replacements for the email.
3225
  * }
3226
  */
3227
  $delivery_class = apply_filters( 'bp_send_email_delivery_class', 'BP_PHPMailer', $email_type, $to, $args );
3248
  } else {
3249
 
3250
  /**
3251
+ * Fires after BuddyPress has successfully sent an email.
3252
  *
3253
  * @since 2.5.0
3254
  *
3271
  * @return array
3272
  */
3273
  function bp_email_get_appearance_settings() {
 
3274
  $footer_text = array(
3275
  sprintf(
3276
+ /* translators: 1. Copyright year, 2. Site name */
3277
+ _x( '&copy; %1$s %2$s', 'copyright text for email footers', 'buddypress' ),
3278
  date_i18n( 'Y' ),
3279
  bp_get_option( 'blogname' )
3280
  )
bp-core/bp-core-template-loader.php CHANGED
@@ -97,7 +97,7 @@ function bp_get_asset_template_part( $slug, $name = null ) {
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
  }
@@ -135,7 +135,7 @@ function bp_locate_template( $template_names, $load = false, $require_once = tru
135
 
136
  /**
137
  * This action exists only to follow the standard BuddyPress coding convention,
138
- * and should not be used to short-circuit any part of the template locator.
139
  *
140
  * If you want to override a specific template part, please either filter
141
  * 'bp_get_template_part' or add a new location to the template stack.
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
  }
135
 
136
  /**
137
  * This action exists only to follow the standard BuddyPress coding convention,
138
+ * and should not be used to short-circuit any part of the template locater.
139
  *
140
  * If you want to override a specific template part, please either filter
141
  * 'bp_get_template_part' or add a new location to the template stack.
bp-core/bp-core-template.php CHANGED
@@ -143,6 +143,7 @@ function bp_get_directory_title( $component = '' ) {
143
 
144
  // If none is found, concatenate.
145
  } elseif ( isset( buddypress()->{$component}->name ) ) {
 
146
  $title = sprintf( __( '%s Directory', 'buddypress' ), buddypress()->{$component}->name );
147
  }
148
 
@@ -152,7 +153,7 @@ function bp_get_directory_title( $component = '' ) {
152
  * @since 2.0.0
153
  *
154
  * @param string $title Text to be used in <title> tag.
155
- * @param string $component Current componet being displayed.
156
  */
157
  return apply_filters( 'bp_get_directory_title', $title, $component );
158
  }
@@ -195,7 +196,11 @@ function bp_comment_author_avatar() {
195
  echo apply_filters( 'bp_comment_author_avatar', bp_core_fetch_avatar( array(
196
  'item_id' => $comment->user_id,
197
  'type' => 'thumb',
198
- 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), bp_core_get_user_displayname( $comment->user_id ) )
 
 
 
 
199
  ) ) );
200
  }
201
 
@@ -210,7 +215,11 @@ function bp_post_author_avatar() {
210
  echo apply_filters( 'bp_post_author_avatar', bp_core_fetch_avatar( array(
211
  'item_id' => $post->post_author,
212
  'type' => 'thumb',
213
- 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), bp_core_get_user_displayname( $post->post_author ) )
 
 
 
 
214
  ) ) );
215
  }
216
 
@@ -352,7 +361,7 @@ function bp_site_name() {
352
  * Format a date based on a UNIX timestamp.
353
  *
354
  * This function can be used to turn a UNIX timestamp into a properly formatted
355
- * (and possibly localized) string, userful for ouputting the date & time an
356
  * action took place.
357
  *
358
  * Not to be confused with `bp_core_time_since()`, this function is best used
@@ -1219,7 +1228,7 @@ function bp_get_email_subject( $args = array() ) {
1219
  *
1220
  * @since 1.7.0
1221
  *
1222
- * @param string $subject Client friendy version of the root blog name.
1223
  * @param array $r Array of arguments for the email subject.
1224
  */
1225
  return apply_filters( 'bp_get_email_subject', $subject, $r );
@@ -1248,7 +1257,7 @@ function bp_ajax_querystring( $object = false ) {
1248
  }
1249
 
1250
  /**
1251
- * Filters the template paramenters to be used in the query string.
1252
  *
1253
  * Allows templates to pass parameters into the template loops via AJAX.
1254
  *
@@ -2073,7 +2082,7 @@ function bp_is_active( $component = '', $feature = '' ) {
2073
  }
2074
 
2075
  // Is component in either the active or required components arrays.
2076
- if ( isset( buddypress()->active_components[ $component ] ) || isset( buddypress()->required_components[ $component ] ) ) {
2077
  $retval = true;
2078
 
2079
  // Is feature active?
@@ -2081,6 +2090,19 @@ function bp_is_active( $component = '', $feature = '' ) {
2081
  // The xProfile component is specific.
2082
  if ( 'xprofile' === $component ) {
2083
  $component = 'profile';
 
 
 
 
 
 
 
 
 
 
 
 
 
2084
  }
2085
 
2086
  $component_features = isset( buddypress()->{$component}->features ) ? buddypress()->{$component}->features : array();
@@ -3016,7 +3038,7 @@ function bp_get_title_parts( $seplocation = 'right' ) {
3016
  return $bp_title_parts;
3017
  }
3018
 
3019
- // Now we can build the BP Title Parts
3020
  // Is there a displayed user, and do they have a name?
3021
  $displayed_user_name = bp_get_displayed_user_fullname();
3022
 
@@ -3619,7 +3641,7 @@ function bp_nav_menu( $args = array() ) {
3619
  $args->walker = new BP_Walker_Nav_Menu;
3620
  }
3621
 
3622
- // Sanitise values for class and ID.
3623
  $args->container_class = sanitize_html_class( $args->container_class );
3624
  $args->container_id = sanitize_html_class( $args->container_id );
3625
 
@@ -3744,5 +3766,14 @@ function bp_email_the_salutation( $settings = array() ) {
3744
  * @param array $settings Email Settings.
3745
  * @param string $token The Recipient token.
3746
  */
3747
- return apply_filters( 'bp_email_get_salutation', sprintf( _x( 'Hi %s,', 'recipient salutation', 'buddypress' ), $token ), $settings, $token );
 
 
 
 
 
 
 
 
 
3748
  }
143
 
144
  // If none is found, concatenate.
145
  } elseif ( isset( buddypress()->{$component}->name ) ) {
146
+ /* translators: %s: Name of the BuddyPress component */
147
  $title = sprintf( __( '%s Directory', 'buddypress' ), buddypress()->{$component}->name );
148
  }
149
 
153
  * @since 2.0.0
154
  *
155
  * @param string $title Text to be used in <title> tag.
156
+ * @param string $component Current component being displayed.
157
  */
158
  return apply_filters( 'bp_get_directory_title', $title, $component );
159
  }
196
  echo apply_filters( 'bp_comment_author_avatar', bp_core_fetch_avatar( array(
197
  'item_id' => $comment->user_id,
198
  'type' => 'thumb',
199
+ 'alt' => sprintf(
200
+ /* translators: %s: member name */
201
+ __( 'Profile photo of %s', 'buddypress' ),
202
+ bp_core_get_user_displayname( $comment->user_id )
203
+ ),
204
  ) ) );
205
  }
206
 
215
  echo apply_filters( 'bp_post_author_avatar', bp_core_fetch_avatar( array(
216
  'item_id' => $post->post_author,
217
  'type' => 'thumb',
218
+ 'alt' => sprintf(
219
+ /* translators: %s: member name */
220
+ __( 'Profile photo of %s', 'buddypress' ),
221
+ bp_core_get_user_displayname( $post->post_author )
222
+ ),
223
  ) ) );
224
  }
225
 
361
  * Format a date based on a UNIX timestamp.
362
  *
363
  * This function can be used to turn a UNIX timestamp into a properly formatted
364
+ * (and possibly localized) string, useful for outputting the date & time an
365
  * action took place.
366
  *
367
  * Not to be confused with `bp_core_time_since()`, this function is best used
1228
  *
1229
  * @since 1.7.0
1230
  *
1231
+ * @param string $subject Client friendly version of the root blog name.
1232
  * @param array $r Array of arguments for the email subject.
1233
  */
1234
  return apply_filters( 'bp_get_email_subject', $subject, $r );
1257
  }
1258
 
1259
  /**
1260
+ * Filters the template parameters to be used in the query string.
1261
  *
1262
  * Allows templates to pass parameters into the template loops via AJAX.
1263
  *
2082
  }
2083
 
2084
  // Is component in either the active or required components arrays.
2085
+ if ( isset( buddypress()->active_components[ $component ] ) || in_array( $component, buddypress()->required_components, true ) ) {
2086
  $retval = true;
2087
 
2088
  // Is feature active?
2090
  // The xProfile component is specific.
2091
  if ( 'xprofile' === $component ) {
2092
  $component = 'profile';
2093
+
2094
+ // The Cover Image feature has been moved to the Members component in 6.0.0.
2095
+ if ( 'cover_image' === $feature && 'profile' === $component ) {
2096
+ _doing_it_wrong( 'bp_is_active( \'profile\', \'cover_image\' )', esc_html__( 'The cover image is a Members component feature, please use bp_is_active( \'members\', \'cover_image\' ) instead.', 'buddypress' ), '6.0.0' );
2097
+ $members_component = buddypress()->members;
2098
+
2099
+ if ( ! isset( $members_component->features ) || false === in_array( $feature, $members_component->features, true ) ) {
2100
+ $retval = false;
2101
+ }
2102
+
2103
+ /** This filter is documented in wp-includes/deprecated.php */
2104
+ return apply_filters_deprecated( 'bp_is_profile_cover_image_active', array( $retval ), '6.0.0', 'bp_is_members_cover_image_active' );
2105
+ }
2106
  }
2107
 
2108
  $component_features = isset( buddypress()->{$component}->features ) ? buddypress()->{$component}->features : array();
3038
  return $bp_title_parts;
3039
  }
3040
 
3041
+ // Now we can build the BP Title Parts.
3042
  // Is there a displayed user, and do they have a name?
3043
  $displayed_user_name = bp_get_displayed_user_fullname();
3044
 
3641
  $args->walker = new BP_Walker_Nav_Menu;
3642
  }
3643
 
3644
+ // Sanitize values for class and ID.
3645
  $args->container_class = sanitize_html_class( $args->container_class );
3646
  $args->container_id = sanitize_html_class( $args->container_id );
3647
 
3766
  * @param array $settings Email Settings.
3767
  * @param string $token The Recipient token.
3768
  */
3769
+ return apply_filters(
3770
+ 'bp_email_get_salutation',
3771
+ sprintf(
3772
+ /* translators: %s: the email token for the recipient name */
3773
+ _x( 'Hi %s,', 'recipient salutation', 'buddypress' ),
3774
+ $token
3775
+ ),
3776
+ $settings,
3777
+ $token
3778
+ );
3779
  }
bp-core/bp-core-theme-compatibility.php CHANGED
@@ -189,7 +189,7 @@ function bp_use_theme_compat_with_current_theme() {
189
  * fallback check for themes that were derived from bp-default, and have
190
  * not been updated for BP 1.7+; we make the assumption that any theme in
191
  * this category will have the members-loop.php template, and so use its
192
- * presence as an indicator that theme compatibility is not required
193
  *
194
  * @since 1.9.0
195
  *
@@ -432,7 +432,7 @@ function bp_register_theme_compat_default_features() {
432
  * than the width used by BuddyPress, so we need to manually set the
433
  * content width for the concerned themes.
434
  *
435
- * Example: array( stylesheet => content width used by BuddyPress )
436
  */
437
  $bp_content_widths = array(
438
  'twentyfifteen' => 1300,
@@ -464,7 +464,7 @@ function bp_register_theme_compat_default_features() {
464
  bp_set_theme_compat_feature( 'legacy', array(
465
  'name' => 'cover_image',
466
  'settings' => array(
467
- 'components' => array( 'xprofile', 'groups' ),
468
  'width' => $bp_content_width,
469
  'height' => $top_offset + round( $avatar_height / 2 ),
470
  'callback' => 'bp_legacy_theme_cover_image',
@@ -945,7 +945,7 @@ function bp_comments_open( $open, $post_id = 0 ) {
945
  *
946
  * @since 1.9.2
947
  *
948
- * @param string $retval The current post content.
949
  * @return string $retval
950
  */
951
  function bp_theme_compat_toggle_is_page( $retval = '' ) {
189
  * fallback check for themes that were derived from bp-default, and have
190
  * not been updated for BP 1.7+; we make the assumption that any theme in
191
  * this category will have the members-loop.php template, and so use its
192
+ * presence as an indicator that theme compatibility is not required.
193
  *
194
  * @since 1.9.0
195
  *
432
  * than the width used by BuddyPress, so we need to manually set the
433
  * content width for the concerned themes.
434
  *
435
+ * Example: array( stylesheet => content width used by BuddyPress ).
436
  */
437
  $bp_content_widths = array(
438
  'twentyfifteen' => 1300,
464
  bp_set_theme_compat_feature( 'legacy', array(
465
  'name' => 'cover_image',
466
  'settings' => array(
467
+ 'components' => array( 'members', 'groups' ),
468
  'width' => $bp_content_width,
469
  'height' => $top_offset + round( $avatar_height / 2 ),
470
  'callback' => 'bp_legacy_theme_cover_image',
945
  *
946
  * @since 1.9.2
947
  *
948
+ * @param string $retval The current post content.
949
  * @return string $retval
950
  */
951
  function bp_theme_compat_toggle_is_page( $retval = '' ) {
bp-core/bp-core-wpabstraction.php CHANGED
@@ -307,3 +307,168 @@ if ( !function_exists( 'mb_strrpos' ) ) {
307
  }
308
  }
309
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  }
308
  }
309
  }
310
+
311
+ /**
312
+ * Returns the name of the hook to use once a WordPress Site is inserted into the Database.
313
+ *
314
+ * WordPress 5.1.0 deprecated the `wpmu_new_blog` action. As BuddyPress is supporting WordPress back
315
+ * to 4.8.0, this function makes sure we are using the new hook `wp_initialize_site` when the current
316
+ * WordPress version is upper or equal to 5.1.0 and that we keep on using `wpmu_new_blog` for earlier
317
+ * versions of WordPress.
318
+ *
319
+ * @since 6.0.0
320
+ *
321
+ * @return string The name of the hook to use.
322
+ */
323
+ function bp_insert_site_hook() {
324
+ $wp_hook = 'wpmu_new_blog';
325
+
326
+ if ( function_exists( 'wp_insert_site' ) ) {
327
+ $wp_hook = 'wp_initialize_site';
328
+ }
329
+
330
+ return $wp_hook;
331
+ }
332
+
333
+ /**
334
+ * Catch the new site data for a later use.
335
+ *
336
+ * @since 6.0.0
337
+ */
338
+ function bp_catch_site_data( $errors = null, $data = array() ) {
339
+ buddypress()->new_site_data = $data;
340
+ }
341
+ add_action( 'wp_validate_site_data', 'bp_catch_site_data', 10, 2 );
342
+
343
+ /**
344
+ * Fires a BuddyPress hook when a new WordPress site is inserted into the database.
345
+ *
346
+ * This hook makes sure BuddyPress is back compatible with WordPress versions < 5.1.0.
347
+ *
348
+ * @since 6.0.0
349
+ *
350
+ * @param int|WP_Site $site The Site ID or the WP Site object.
351
+ * @param int|array $args_or_user_id An array of Site arguments or the User ID.
352
+ * @param string $domain Site domain.
353
+ * @param string $path Site path.
354
+ * @param int $network_id Network ID. Only relevant on multi-network installations.
355
+ * @param array $meta Meta data. Used to set initial site options.
356
+ */
357
+ function bp_insert_site( $site, $args_or_user_id = null, $domain = '', $path = '', $network_id = 0, $meta = array() ) {
358
+ if ( $site instanceof WP_Site ) {
359
+ $bp = buddypress();
360
+ $site_id = $site->id;
361
+ $domain = $site->domain;
362
+ $path = $site->path;
363
+ $network_id = $site->network_id;
364
+ $args = (array) $args_or_user_id;
365
+
366
+ $user_id = 0;
367
+ if ( isset( $args['user_id'] ) && $args['user_id'] ) {
368
+ $user_id = (int) $args['user_id'];
369
+ }
370
+
371
+ $meta = array();
372
+ if ( isset( $args['options'] ) && $args['options'] ) {
373
+ $meta = (array) $args['options'];
374
+
375
+ if ( ! array_key_exists( 'WPLANG', $meta ) ) {
376
+ $meta['WPLANG'] = get_network_option( $site->network_id, 'WPLANG' );
377
+ }
378
+
379
+ if ( isset( $bp->new_site_data ) ) {
380
+ $meta = array_merge( $bp->new_site_data, $meta );
381
+ }
382
+ }
383
+ } else {
384
+ $site_id = $site;
385
+ $user_id = (int) $args_or_user_id;
386
+ }
387
+
388
+ /**
389
+ * Fires when a new WordPress site has been inserted into the database.
390
+ *
391
+ * @since 6.0.0
392
+ *
393
+ * @param int $site_id Site ID.
394
+ * @param int $user_id User ID.
395
+ * @param string $domain Site domain.
396
+ * @param string $path Site path.
397
+ * @param int $network_id Network ID. Only relevant on multi-network installations.
398
+ * @param array $meta Meta data. Used to set initial site options.
399
+ */
400
+ do_action( 'bp_insert_site', $site_id, $user_id, $domain, $path, $network_id, $meta );
401
+ }
402
+ add_action( bp_insert_site_hook(), 'bp_insert_site' );
403
+
404
+ /**
405
+ * Returns the name of the hook to use once a WordPress Site is deleted.
406
+ *
407
+ * WordPress 5.1.0 deprecated the `delete_blog` action. As BuddyPress is supporting WordPress back
408
+ * to 4.8.0, this function makes sure we are using the new hook `wp_validate_site_deletion` when the
409
+ * current WordPress version is upper or equal to 5.1.0 and that we keep on using `delete_blog` for
410
+ * earlier versions of WordPress.
411
+ *
412
+ * @since 6.0.0
413
+ *
414
+ * @return string The name of the hook to use.
415
+ */
416
+ function bp_delete_site_hook() {
417
+ $wp_hook = 'delete_blog';
418
+
419
+ if ( function_exists( 'wp_delete_site' ) ) {
420
+ $wp_hook = 'wp_validate_site_deletion';
421
+ }
422
+
423
+ return $wp_hook;
424
+ }
425
+
426
+ /**
427
+ * Makes sure the `bp_delete_site` hook is fired if site's deletion
428
+ * was performed without dropping tables.
429
+ *
430
+ * @since 6.0.0
431
+ *
432
+ * @param WP_Site $site The site object.
433
+ */
434
+ function bp_delete_site_no_tables_drop( $site ) {
435
+ if ( isset( $site->deleted ) && 1 === (int) $site->deleted ) {
436
+ return bp_delete_site( $site->id, false );
437
+ }
438
+ }
439
+ add_action( 'wp_update_site', 'bp_delete_site_no_tables_drop', 10, 1 );
440
+
441
+ /**
442
+ * Fires a BuddyPress hook when a new WordPress site is deleted.
443
+ *
444
+ * This hook makes sure BuddyPress is back compatible with WordPress versions < 5.1.0.
445
+ *
446
+ * @since 6.0.0
447
+ *
448
+ * @param int|WP_Error $site_id_or_error A WP Error object or the site ID.
449
+ * @param bool|WP_Site $drop_or_site A WP Site object or a boolean to inform whether site's table should be dropped.
450
+ */
451
+ function bp_delete_site( $site_id_or_error, $drop_or_site = false ) {
452
+ if ( $drop_or_site instanceof WP_Site ) {
453
+ if ( ! empty( $site_id_or_error->errors ) ) {
454
+ return;
455
+ }
456
+
457
+ $site_id = (int) $drop_or_site->id;
458
+ $drop = true;
459
+ } else {
460
+ $site_id = (int) $site_id_or_error;
461
+ $drop = (bool) $drop_or_site;
462
+ }
463
+
464
+ /**
465
+ * Fires when a WordPress site is deleted.
466
+ *
467
+ * @since 6.0.0
468
+ *
469
+ * @param int $site_id The site ID.
470
+ * @param bool $drop True if site's table should be dropped. Default is false.
471
+ */
472
+ do_action( 'bp_delete_site', $site_id, $drop );
473
+ }
474
+ add_action( bp_delete_site_hook(), 'bp_delete_site', 10, 2 );
bp-core/classes/class-bp-admin.php CHANGED
@@ -394,6 +394,21 @@ class BP_Admin {
394
  add_settings_field( '_bp_theme_package_id', __( 'Template Pack', 'buddypress' ), 'bp_admin_setting_callback_theme_package_id', 'buddypress', 'bp_main', array( 'label_for' => '_bp_theme_package_id' ) );
395
  register_setting( 'buddypress', '_bp_theme_package_id', 'sanitize_text_field' );
396
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
397
  /* XProfile Section **************************************************/
398
 
399
  if ( bp_is_active( 'xprofile' ) ) {
@@ -401,16 +416,6 @@ class BP_Admin {
401
  // Add the main section.
402
  add_settings_section( 'bp_xprofile', _x( 'Profile Settings', 'BuddyPress setting tab', 'buddypress' ), 'bp_admin_setting_callback_xprofile_section', 'buddypress' );
403
 
404
- // Avatars.
405
- add_settings_field( 'bp-disable-avatar-uploads', __( 'Profile Photo Uploads', 'buddypress' ), 'bp_admin_setting_callback_avatar_uploads', 'buddypress', 'bp_xprofile' );
406
- register_setting( 'buddypress', 'bp-disable-avatar-uploads', 'intval' );
407
-
408
- // Cover images.
409
- if ( bp_is_active( 'xprofile', 'cover_image' ) ) {
410
- add_settings_field( 'bp-disable-cover-image-uploads', __( 'Cover Image Uploads', 'buddypress' ), 'bp_admin_setting_callback_cover_image_uploads', 'buddypress', 'bp_xprofile' );
411
- register_setting( 'buddypress', 'bp-disable-cover-image-uploads', 'intval' );
412
- }
413
-
414
  // Profile sync setting.
415
  add_settings_field( 'bp-disable-profile-sync', __( 'Profile Syncing', 'buddypress' ), 'bp_admin_setting_callback_profile_sync', 'buddypress', 'bp_xprofile' );
416
  register_setting ( 'buddypress', 'bp-disable-profile-sync', 'intval' );
@@ -474,7 +479,7 @@ class BP_Admin {
474
  return;
475
  }
476
 
477
- $wp_admin_bar->add_menu( array(
478
  'parent' => 'wp-logo',
479
  'id' => 'bp-about',
480
  'title' => esc_html_x( 'Hello, BuddyPress!', 'Colloquial alternative to "learn about BuddyPress"', 'buddypress' ),
@@ -633,7 +638,7 @@ class BP_Admin {
633
  <div class='vignette'></div>
634
  <h2>
635
  <?php printf(
636
- /* translators: %s is the placehoder for the BuddyPress version number. */
637
  esc_html__( 'BuddyPress %s', 'buddypress' ),
638
  $version
639
  ); ?>
@@ -658,7 +663,7 @@ class BP_Admin {
658
  <p>
659
  <?php esc_html_e( 'BuddyPress endpoints provide machine-readable external access to your WordPress site with a clear, standards-driven interface, paving the way for new and innovative methods of interacting with your community through plugins, themes, apps, and beyond.', 'buddypress' ); ?>
660
  <?php printf(
661
- /* translators: %s is the placehoder for the link to the BP REST API documentation site. */
662
  esc_html__( 'Ready to get started with development? Check out the %s.', 'buddypress' ),
663
  sprintf(
664
  '<a href="%1$s">%2$s</a>',
@@ -693,7 +698,7 @@ class BP_Admin {
693
  <p>
694
  <?php esc_html_e( 'The BP Invitations API abstracts how these two actions are handled and allows developers to use them for any object on your site (e.g., Sites of a WordPress network).', 'buddypress' ); ?>
695
  <?php printf(
696
- /* translators: %s is the placehoder for the link to the BP Invitations API development note. */
697
  esc_html__( 'Read more about the %s.', 'buddypress' ),
698
  sprintf(
699
  '<a href="%1$s">%2$s</a>',
@@ -737,7 +742,7 @@ class BP_Admin {
737
  <p>
738
  <?php esc_html_e( 'Developers building tools for the Block Editor can now add their blocks to the BuddyPress category. This change provides a foundation for organizing custom BuddyPress blocks.', 'buddypress' ); ?>
739
  <?php printf(
740
- /* translators: %s is the placehoder for the link to the blocks category development note. */
741
  esc_html__( 'Read more about this feature in the %s.', 'buddypress' ),
742
  sprintf(
743
  '<a href="%1$s">%2$s</a>',
@@ -753,7 +758,7 @@ class BP_Admin {
753
  <p>
754
  <?php
755
  printf(
756
- /* translators: %s is the placehoder for the link to BuddyPress support forums. */
757
  esc_html__( ' How are you using BuddyPress? Receiving your feedback and suggestions for future versions of BuddyPress genuinely motivates and encourages our contributors. Please %s about this version of BuddyPress on our website. ', 'buddypress' ),
758
  sprintf(
759
  '<a href="%1$s">%2$s</a>',
@@ -774,6 +779,7 @@ class BP_Admin {
774
  <p>
775
  <?php
776
  printf(
 
777
  _n( 'Built with %1$s by <a href="%2$s">%3$d volunteer</a>.', 'Built with %1$s by <a href="%2$s">%3$d volunteers</a>.', 28, 'buddypress' ),
778
  '<span class="dashicons dashicons-heart"></span>',
779
  esc_url( bp_get_admin_url( 'admin.php?page=bp-credits' ) ),
@@ -950,7 +956,15 @@ class BP_Admin {
950
  </li>
951
  </ul>
952
 
953
- <h3 class="wp-people-group"><?php printf( esc_html__( 'Contributors to BuddyPress %s', 'buddypress' ), self::display_version() ); ?></h3>
 
 
 
 
 
 
 
 
954
  <p class="wp-credits-list">
955
  <a href="https://github.com/baconbro">baconbro</a>,
956
  <a href="https://profiles.wordpress.org/boonebgorges/">Boone B Gorges (boonebgorges)</a>,
394
  add_settings_field( '_bp_theme_package_id', __( 'Template Pack', 'buddypress' ), 'bp_admin_setting_callback_theme_package_id', 'buddypress', 'bp_main', array( 'label_for' => '_bp_theme_package_id' ) );
395
  register_setting( 'buddypress', '_bp_theme_package_id', 'sanitize_text_field' );
396
 
397
+ /* Members Section **************************************************/
398
+
399
+ // Add the main section.
400
+ add_settings_section( 'bp_members', _x( 'Members Settings', 'BuddyPress setting tab', 'buddypress' ), 'bp_admin_setting_callback_members_section', 'buddypress' );
401
+
402
+ // Avatars.
403
+ add_settings_field( 'bp-disable-avatar-uploads', __( 'Profile Photo Uploads', 'buddypress' ), 'bp_admin_setting_callback_avatar_uploads', 'buddypress', 'bp_members' );
404
+ register_setting( 'buddypress', 'bp-disable-avatar-uploads', 'intval' );
405
+
406
+ // Cover images.
407
+ if ( bp_is_active( 'members', 'cover_image' ) ) {
408
+ add_settings_field( 'bp-disable-cover-image-uploads', __( 'Cover Image Uploads', 'buddypress' ), 'bp_admin_setting_callback_cover_image_uploads', 'buddypress', 'bp_members' );
409
+ register_setting( 'buddypress', 'bp-disable-cover-image-uploads', 'intval' );
410
+ }
411
+
412
  /* XProfile Section **************************************************/
413
 
414
  if ( bp_is_active( 'xprofile' ) ) {
416
  // Add the main section.
417
  add_settings_section( 'bp_xprofile', _x( 'Profile Settings', 'BuddyPress setting tab', 'buddypress' ), 'bp_admin_setting_callback_xprofile_section', 'buddypress' );
418
 
 
 
 
 
 
 
 
 
 
 
419
  // Profile sync setting.
420
  add_settings_field( 'bp-disable-profile-sync', __( 'Profile Syncing', 'buddypress' ), 'bp_admin_setting_callback_profile_sync', 'buddypress', 'bp_xprofile' );
421
  register_setting ( 'buddypress', 'bp-disable-profile-sync', 'intval' );
479
  return;
480
  }
481
 
482
+ $wp_admin_bar->add_node( array(
483
  'parent' => 'wp-logo',
484
  'id' => 'bp-about',
485
  'title' => esc_html_x( 'Hello, BuddyPress!', 'Colloquial alternative to "learn about BuddyPress"', 'buddypress' ),
638
  <div class='vignette'></div>
639
  <h2>
640
  <?php printf(
641
+ /* translators: %s is the placeholder for the BuddyPress version number. */
642
  esc_html__( 'BuddyPress %s', 'buddypress' ),
643
  $version
644
  ); ?>
663
  <p>
664
  <?php esc_html_e( 'BuddyPress endpoints provide machine-readable external access to your WordPress site with a clear, standards-driven interface, paving the way for new and innovative methods of interacting with your community through plugins, themes, apps, and beyond.', 'buddypress' ); ?>
665
  <?php printf(
666
+ /* translators: %s is the placeholder for the link to the BP REST API documentation site. */
667
  esc_html__( 'Ready to get started with development? Check out the %s.', 'buddypress' ),
668
  sprintf(
669
  '<a href="%1$s">%2$s</a>',
698
  <p>
699
  <?php esc_html_e( 'The BP Invitations API abstracts how these two actions are handled and allows developers to use them for any object on your site (e.g., Sites of a WordPress network).', 'buddypress' ); ?>
700
  <?php printf(
701
+ /* translators: %s is the placeholder for the link to the BP Invitations API development note. */
702
  esc_html__( 'Read more about the %s.', 'buddypress' ),
703
  sprintf(
704
  '<a href="%1$s">%2$s</a>',
742
  <p>
743
  <?php esc_html_e( 'Developers building tools for the Block Editor can now add their blocks to the BuddyPress category. This change provides a foundation for organizing custom BuddyPress blocks.', 'buddypress' ); ?>
744
  <?php printf(
745
+ /* translators: %s is the placeholder for the link to the blocks category development note. */
746
  esc_html__( 'Read more about this feature in the %s.', 'buddypress' ),
747
  sprintf(
748
  '<a href="%1$s">%2$s</a>',
758
  <p>
759
  <?php
760
  printf(
761
+ /* translators: %s is the placeholder for the link to BuddyPress support forums. */
762
  esc_html__( ' How are you using BuddyPress? Receiving your feedback and suggestions for future versions of BuddyPress genuinely motivates and encourages our contributors. Please %s about this version of BuddyPress on our website. ', 'buddypress' ),
763
  sprintf(
764
  '<a href="%1$s">%2$s</a>',
779
  <p>
780
  <?php
781
  printf(
782
+ /* translators: 1: heart dashicons. 2: BP Credits screen url. 3: number of BuddyPress contributors to this version. */
783
  _n( 'Built with %1$s by <a href="%2$s">%3$d volunteer</a>.', 'Built with %1$s by <a href="%2$s">%3$d volunteers</a>.', 28, 'buddypress' ),
784
  '<span class="dashicons dashicons-heart"></span>',
785
  esc_url( bp_get_admin_url( 'admin.php?page=bp-credits' ) ),
956
  </li>
957
  </ul>
958
 
959
+ <h3 class="wp-people-group">
960
+ <?php
961
+ printf(
962
+ /* translators: %s: BuddyPress version number */
963
+ esc_html__( 'Contributors to BuddyPress %s', 'buddypress' ),
964
+ self::display_version()
965
+ );
966
+ ?>
967
+ </h3>
968
  <p class="wp-credits-list">
969
  <a href="https://github.com/baconbro">baconbro</a>,
970
  <a href="https://profiles.wordpress.org/boonebgorges/">Boone B Gorges (boonebgorges)</a>,
bp-core/classes/class-bp-attachment-avatar.php CHANGED
@@ -37,8 +37,11 @@ class BP_Attachment_Avatar extends BP_Attachment {
37
 
38
  // Specific errors for avatars.
39
  'upload_error_strings' => array(
40
- 9 => sprintf( __( 'That photo is too big. Please upload one smaller than %s', 'buddypress' ), size_format( bp_core_avatar_original_max_filesize() ) ),
41
- 10 => sprintf( _n( 'Please upload only this file type: %s.', 'Please upload only these file types: %s.', count( $allowed_types ), 'buddypress' ), self::get_avatar_types( $allowed_types ) ),
 
 
 
42
  ),
43
  ) );
44
  }
@@ -130,7 +133,7 @@ class BP_Attachment_Avatar extends BP_Attachment {
130
  */
131
  $original_max_width = $ui_available_width;
132
 
133
- // $original_max_width has to be larger than the avatar's full width
134
  if ( $original_max_width < bp_core_avatar_full_width() ) {
135
  $original_max_width = bp_core_avatar_full_width();
136
  }
@@ -337,7 +340,7 @@ class BP_Attachment_Avatar extends BP_Attachment {
337
  }
338
 
339
  /**
340
- * Build script datas for the Uploader UI.
341
  *
342
  * @since 2.3.0
343
  *
37
 
38
  // Specific errors for avatars.
39
  'upload_error_strings' => array(
40
+ /* translators: %s: Max file size for the profile photo */
41
+ 9 => sprintf( _x( 'That photo is too big. Please upload one smaller than %s', 'profile photo upload error', 'buddypress' ), size_format( bp_core_avatar_original_max_filesize() ) ),
42
+
43
+ /* translators: %s: comma separated list of file types allowed for the profile photo */
44
+ 10 => sprintf( _nx( 'Please upload only this file type: %s.', 'Please upload only these file types: %s.', count( $allowed_types ), 'profile photo upload error', 'buddypress' ), self::get_avatar_types( $allowed_types ) ),
45
  ),
46
  ) );
47
  }
133
  */
134
  $original_max_width = $ui_available_width;
135
 
136
+ // $original_max_width has to be larger than the avatar's full width.
137
  if ( $original_max_width < bp_core_avatar_full_width() ) {
138
  $original_max_width = bp_core_avatar_full_width();
139
  }
340
  }
341
 
342
  /**
343
+ * Build script data for the Uploader UI.
344
  *
345
  * @since 2.3.0
346
  *
bp-core/classes/class-bp-attachment-cover-image.php CHANGED
@@ -37,8 +37,11 @@ class BP_Attachment_Cover_Image extends BP_Attachment {
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
  }
@@ -75,11 +78,11 @@ class BP_Attachment_Cover_Image extends BP_Attachment {
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
 
37
 
38
  // Specific errors for cover images.
39
  'upload_error_strings' => array(
40
+ /* translators: %s: Max file size for the cover image */
41
+ 11 => sprintf( _x( 'That image is too big. Please upload one smaller than %s', 'cover image upload error', 'buddypress' ), size_format( $max_upload_file_size ) ),
42
+
43
+ /* translators: %s: comma separated list of file types allowed for the cover image */
44
+ 12 => sprintf( _nx( 'Please upload only this file type: %s.', 'Please upload only these file types: %s.', count( $allowed_types ), 'cover image upload error', 'buddypress' ), self::get_cover_image_types( $allowed_types ) ),
45
  ),
46
  ) );
47
  }
78
  }
79
 
80
  // File size is too big.
81
+ if ( isset( $file['size'] ) && ( $file['size'] > $this->original_max_filesize ) ) {
82
  $file['error'] = 11;
83
 
84
  // File is of invalid type.
85
+ } elseif ( isset( $file['tmp_name'] ) && isset( $file['name'] ) && ! bp_attachments_check_filetype( $file['tmp_name'], $file['name'], bp_attachments_get_allowed_mimes( 'cover_image' ) ) ) {
86
  $file['error'] = 12;
87
  }
88
 
bp-core/classes/class-bp-attachment.php CHANGED
@@ -77,7 +77,7 @@ abstract class BP_Attachment {
77
 
78
  /**
79
  * Max file size defaults to php ini settings or, in the case of
80
- * a multisite config, the root site fileupload_maxk option
81
  */
82
  $this->default_args['original_max_filesize'] = (int) wp_max_upload_size();
83
 
@@ -159,6 +159,8 @@ abstract class BP_Attachment {
159
  $upload_errors = array(
160
  0 => __( 'The file was uploaded successfully', 'buddypress' ),
161
  1 => __( 'The uploaded file exceeds the maximum allowed file size for this site', 'buddypress' ),
 
 
162
  2 => sprintf( __( 'The uploaded file exceeds the maximum allowed file size of: %s', 'buddypress' ), size_format( $this->original_max_filesize ) ),
163
  3 => __( 'The uploaded file was only partially uploaded.', 'buddypress' ),
164
  4 => __( 'No file was uploaded.', 'buddypress' ),
@@ -500,7 +502,15 @@ abstract class BP_Attachment {
500
  $ext = $is_image['ext'];
501
 
502
  if ( empty( $ext ) || empty( $supported_image_types[ $ext ] ) ) {
503
- $wp_error->add( 'crop_error', sprintf( __( 'Cropping the file failed: %s is not a supported image file.', 'buddypress' ), $file['error'] ) );
 
 
 
 
 
 
 
 
504
  return $wp_error;
505
  }
506
  }
77
 
78
  /**
79
  * Max file size defaults to php ini settings or, in the case of
80
+ * a multisite config, the root site fileupload_maxk option.
81
  */
82
  $this->default_args['original_max_filesize'] = (int) wp_max_upload_size();
83
 
159
  $upload_errors = array(
160
  0 => __( 'The file was uploaded successfully', 'buddypress' ),
161
  1 => __( 'The uploaded file exceeds the maximum allowed file size for this site', 'buddypress' ),
162
+
163
+ /* translators: %s: Max file size for the file */
164
  2 => sprintf( __( 'The uploaded file exceeds the maximum allowed file size of: %s', 'buddypress' ), size_format( $this->original_max_filesize ) ),
165
  3 => __( 'The uploaded file was only partially uploaded.', 'buddypress' ),
166
  4 => __( 'No file was uploaded.', 'buddypress' ),
502
  $ext = $is_image['ext'];
503
 
504
  if ( empty( $ext ) || empty( $supported_image_types[ $ext ] ) ) {
505
+ $wp_error->add(
506
+ 'crop_error',
507
+ sprintf(
508
+ /* translators: %s: image file extension */
509
+ __( 'Cropping the file failed: %s is not a supported image file.', 'buddypress' ),
510
+ $file['error']
511
+ )
512
+ );
513
+
514
  return $wp_error;
515
  }
516
  }
bp-core/classes/class-bp-block.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP Block class.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage Core
7
+ * @since 6.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * BP Block Class.
17
+ *
18
+ * @since 6.0.0
19
+ */
20
+ class BP_Block {
21
+ /**
22
+ * WP Block Type object.
23
+ *
24
+ * @since 6.0.0
25
+ * @var WP_Block_Type|WP_Error
26
+ */
27
+ public $block;
28
+
29
+ /**
30
+ * The script types registered.
31
+ *
32
+ * @since 6.0.0
33
+ * @var array
34
+ */
35
+ private $registered_scripts;
36
+
37
+ /**
38
+ * The style types registered.
39
+ *
40
+ * @since 6.0.0
41
+ * @var array
42
+ */
43
+ private $registered_styles;
44
+
45
+ /**
46
+ * Construct the BuddyPress Block.
47
+ *
48
+ * @since 6.0.0
49
+ *
50
+ * @param array $args The registration arguments for the BP Block.
51
+ */
52
+ public function __construct( $args ) {
53
+ if ( ! did_action( 'bp_blocks_init' ) ) {
54
+ _doing_it_wrong( __METHOD__, esc_html__( 'BP Blocks needs to be registered hooking `bp_blocks_init`', 'buddypress' ), '6.0.0' );
55
+ }
56
+
57
+ $min = bp_core_get_minified_asset_suffix();
58
+ $wp_args = array_intersect_key(
59
+ $args,
60
+ array(
61
+ 'name' => '',
62
+ 'render_callback' => '',
63
+ 'attributes' => '',
64
+ 'editor_script' => '',
65
+ 'script' => '',
66
+ 'editor_style' => '',
67
+ 'style' => '',
68
+ )
69
+ );
70
+
71
+ if ( ! isset( $wp_args['name'] ) || ! $wp_args['name'] || ! isset( $wp_args['editor_script'] ) || ! $wp_args['editor_script'] ) {
72
+ $this->block = new WP_Error( 'missing_parameters', __( 'The `name` or `editor_script` required keys are missing.', 'buddypress' ) );
73
+ } else {
74
+ // Get specific BP Blocks arguments.
75
+ $bp_args = array_intersect_key(
76
+ $args,
77
+ array(
78
+ 'editor_script_url' => '',
79
+ 'editor_script_deps' => array(),
80
+ 'script_url' => '',
81
+ 'script_deps' => array(),
82
+ 'editor_style_url' => '',
83
+ 'editor_style_deps' => array(),
84
+ 'style_url' => '',
85
+ 'style_deps' => array(),
86
+ )
87
+ );
88
+
89
+ // Register the scripts.
90
+ $version = bp_get_version();
91
+ $this->registered_scripts = array();
92
+
93
+ foreach ( array( 'editor_script', 'script' ) as $script_handle_key ) {
94
+ if ( ! isset( $wp_args[ $script_handle_key ] ) || ! $wp_args[ $script_handle_key ] ) {
95
+ continue;
96
+ }
97
+
98
+ if ( ! isset( $bp_args[ $script_handle_key . '_url' ] ) || ! $bp_args[ $script_handle_key . '_url' ] ) {
99
+ continue;
100
+ }
101
+
102
+ $deps = array();
103
+ if ( isset( $bp_args[ $script_handle_key . '_deps' ] ) && is_array( $bp_args[ $script_handle_key . '_deps' ] ) ) {
104
+ $deps = $bp_args[ $script_handle_key . '_deps' ];
105
+ }
106
+
107
+ $this->registered_scripts[ $script_handle_key ] = wp_register_script(
108
+ $wp_args[ $script_handle_key ],
109
+ $bp_args[ $script_handle_key . '_url' ],
110
+ $deps,
111
+ $version,
112
+ true
113
+ );
114
+ }
115
+
116
+ if ( ! isset( $this->registered_scripts['editor_script'] ) || ! $this->registered_scripts['editor_script'] ) {
117
+ $this->block = new WP_Error( 'script_registration_error', __( 'The required `editor_script` could not be registered.', 'buddypress' ) );
118
+ } else {
119
+ // Register the styles.
120
+ $registered_styles = array();
121
+
122
+ foreach ( array( 'editor_style', 'style' ) as $style_handle_key ) {
123
+ if ( ! isset( $wp_args[ $style_handle_key ] ) || ! $wp_args[ $style_handle_key ] ) {
124
+ continue;
125
+ }
126
+
127
+ if ( ! isset( $bp_args[ $style_handle_key . '_url' ] ) || ! $bp_args[ $style_handle_key . '_url' ] ) {
128
+ continue;
129
+ }
130
+
131
+ if ( $min ) {
132
+ $minified_css = str_replace( '.css', $min . '.css', $bp_args[ $style_handle_key . '_url' ] );
133
+ $css_file_path = str_replace( content_url(), WP_CONTENT_DIR, $minified_css );
134
+
135
+ if ( file_exists( $css_file_path ) ) {
136
+ $bp_args[ $style_handle_key . '_url' ] = $minified_css;
137
+ }
138
+ }
139
+
140
+ $deps = array();
141
+ if ( isset( $bp_args[ $style_handle_key . '_deps' ] ) && is_array( $bp_args[ $style_handle_key . '_deps' ] ) ) {
142
+ $deps = $bp_args[ $style_handle_key . '_deps' ];
143
+ }
144
+
145
+ $this->registered_styles[ $style_handle_key ] = wp_register_style(
146
+ $wp_args[ $style_handle_key ],
147
+ $bp_args[ $style_handle_key . '_url' ],
148
+ $deps,
149
+ $version
150
+ );
151
+
152
+ wp_style_add_data( $wp_args[ $style_handle_key ], 'rtl', 'replace' );
153
+ if ( $min ) {
154
+ wp_style_add_data( $wp_args[ $style_handle_key ], 'suffix', $min );
155
+ }
156
+ }
157
+
158
+ $name = $wp_args['name'];
159
+ unset( $wp_args['name'] );
160
+
161
+ // Set the Block Type.
162
+ $this->block = new WP_Block_Type( $name, $wp_args );
163
+
164
+ // Register the Block Type.
165
+ register_block_type( $this->block );
166
+
167
+ // Load Block translations if found.
168
+ if ( $this->block->editor_script ) {
169
+ /**
170
+ * Filter here to use a custom directory to look for the JSON translation file into.
171
+ *
172
+ * @since 6.0.0
173
+ *
174
+ * @param string $value Absolute path to the directory to look for the JSON translation file into.
175
+ * @param string $editor_script The editor's script handle.
176
+ * @param string $name The block's name.
177
+ */
178
+ $translation_dir = apply_filters( 'bp_block_translation_dir', null, $this->block->editor_script, $name );
179
+
180
+ /**
181
+ * Filter here to use a custom domain for the JSON translation file.
182
+ *
183
+ * @since 6.0.0
184
+ *
185
+ * @param string $value The custom domain for the JSON translation file.
186
+ * @param string $editor_script The editor's script handle.
187
+ * @param string $name The block's name.
188
+ */
189
+ $domain = apply_filters( 'bp_block_translation_dir', 'buddypress', $this->block->editor_script, $name );
190
+
191
+ // Try to load the translation.
192
+ $translated = wp_set_script_translations( $this->block->editor_script, $domain, $translation_dir );
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
bp-core/classes/class-bp-component.php CHANGED
@@ -461,11 +461,16 @@ class BP_Component {
461
  // Generate rewrite rules.
462
  add_action( 'bp_generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ), 10 );
463
 
464
- // Register BP REST Endpoints
465
  if ( bp_rest_in_buddypress() && bp_rest_api_is_available() ) {
466
  add_action( 'bp_rest_api_init', array( $this, 'rest_api_init' ), 10 );
467
  }
468
 
 
 
 
 
 
469
  /**
470
  * Fires at the end of the setup_actions method inside BP_Component.
471
  *
@@ -578,7 +583,7 @@ class BP_Component {
578
  } else {
579
  $pos = $nav['position'];
580
 
581
- // Reset not set pos to 1
582
  if ( $pos % 10 === 0 ) {
583
  $not_set_pos = 1;
584
  }
@@ -596,7 +601,7 @@ class BP_Component {
596
 
597
  // Add each admin menu.
598
  foreach( $this->admin_menu as $admin_menu ) {
599
- $wp_admin_bar->add_menu( $admin_menu );
600
  }
601
  }
602
 
@@ -906,5 +911,40 @@ class BP_Component {
906
  */
907
  do_action( 'bp_' . $this->id . '_rest_api_init' );
908
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
909
  }
910
  endif; // BP_Component.
461
  // Generate rewrite rules.
462
  add_action( 'bp_generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ), 10 );
463
 
464
+ // Register BP REST Endpoints.
465
  if ( bp_rest_in_buddypress() && bp_rest_api_is_available() ) {
466
  add_action( 'bp_rest_api_init', array( $this, 'rest_api_init' ), 10 );
467
  }
468
 
469
+ // Register BP Blocks.
470
+ if ( bp_support_blocks() ) {
471
+ add_action( 'bp_blocks_init', array( $this, 'blocks_init' ), 10 );
472
+ }
473
+
474
  /**
475
  * Fires at the end of the setup_actions method inside BP_Component.
476
  *
583
  } else {
584
  $pos = $nav['position'];
585
 
586
+ // Reset not set pos to 1.
587
  if ( $pos % 10 === 0 ) {
588
  $not_set_pos = 1;
589
  }
601
 
602
  // Add each admin menu.
603
  foreach( $this->admin_menu as $admin_menu ) {
604
+ $wp_admin_bar->add_node( $admin_menu );
605
  }
606
  }
607
 
911
  */
912
  do_action( 'bp_' . $this->id . '_rest_api_init' );
913
  }
914
+
915
+ /**
916
+ * Register the BP Blocks.
917
+ *
918
+ * @since 6.0.0
919
+ *
920
+ * @param array $blocks The list of BP Blocks to register.
921
+ */
922
+ public function blocks_init( $blocks = array() ) {
923
+ if ( is_array( $blocks ) && $blocks ) {
924
+ /**
925
+ * Filter here to disable all or some BP Blocks for a component.
926
+ *
927
+ * This is a dynamic hook that is based on the component string ID.
928
+ *
929
+ * @since 6.0.0
930
+ *
931
+ * @param array $blocks The list of BP Blocks for the component.
932
+ */
933
+ $blocks = (array) apply_filters( 'bp_' . $this->id . '_register_blocks', $blocks );
934
+
935
+ foreach ( $blocks as $block ) {
936
+ bp_register_block( $block );
937
+ }
938
+ }
939
+
940
+ /**
941
+ * Fires in the blocks_init method inside BP_Component.
942
+ *
943
+ * This is a dynamic hook that is based on the component string ID.
944
+ *
945
+ * @since 6.0.0
946
+ */
947
+ do_action( 'bp_' . $this->id . '_blocks_init' );
948
+ }
949
  }
950
  endif; // BP_Component.
bp-core/classes/class-bp-core-nav.php CHANGED
@@ -216,15 +216,15 @@ class BP_Core_Nav {
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 ) {
@@ -237,15 +237,15 @@ class BP_Core_Nav {
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 ) {
@@ -267,7 +267,7 @@ class BP_Core_Nav {
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
  }
@@ -292,14 +292,14 @@ class BP_Core_Nav {
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
 
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 ) {
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 ) {
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
  }
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
 
bp-core/classes/class-bp-core-user.php CHANGED
@@ -166,10 +166,46 @@ class BP_Core_User {
166
  $this->email = esc_attr( bp_core_get_user_email( $this->id ) );
167
  }
168
 
169
- $this->avatar = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'full', 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->fullname ) ) );
170
- $this->avatar_thumb = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->fullname ) ) );
171
- $this->avatar_mini = bp_core_fetch_avatar( array( 'item_id' => $this->id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->fullname ), 'width' => 30, 'height' => 30 ) );
172
- $this->last_active = bp_core_get_last_activity( bp_get_user_last_activity( $this->id ), __( 'active %s', 'buddypress' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  }
174
 
175
  /**
@@ -183,7 +219,11 @@ class BP_Core_User {
183
 
184
  if ( bp_is_active( 'groups' ) ) {
185
  $this->total_groups = BP_Groups_Member::total_group_count( $this->id );
186
- $this->total_groups = sprintf( _n( '%d group', '%d groups', $this->total_groups, 'buddypress' ), $this->total_groups );
 
 
 
 
187
  }
188
  }
189
 
166
  $this->email = esc_attr( bp_core_get_user_email( $this->id ) );
167
  }
168
 
169
+ $this->avatar = bp_core_fetch_avatar(
170
+ array(
171
+ 'item_id' => $this->id,
172
+ 'type' => 'full',
173
+ 'alt' => sprintf(
174
+ /* translators: %s: member name */
175
+ __( 'Profile photo of %s', 'buddypress' ),
176
+ $this->fullname
177
+ )
178
+ )
179
+ );
180
+
181
+ $this->avatar_thumb = bp_core_fetch_avatar(
182
+ array(
183
+ 'item_id' => $this->id,
184
+ 'type' => 'thumb',
185
+ 'alt' => sprintf(
186
+ /* translators: %s: member name */
187
+ __( 'Profile photo of %s', 'buddypress' ),
188
+ $this->fullname
189
+ )
190
+ )
191
+ );
192
+
193
+ $this->avatar_mini = bp_core_fetch_avatar(
194
+ array(
195
+ 'item_id' => $this->id,
196
+ 'type' => 'thumb',
197
+ 'alt' => sprintf(
198
+ /* translators: %s: member name */
199
+ __( 'Profile photo of %s', 'buddypress' ),
200
+ $this->fullname
201
+ ),
202
+ 'width' => 30,
203
+ 'height' => 30
204
+ )
205
+ );
206
+
207
+ /* translators: %s: human time diff of the last time the user was active on the site. */
208
+ $this->last_active = bp_core_get_last_activity( bp_get_user_last_activity( $this->id ), _x( 'active %s', 'last time the user was active', 'buddypress' ) );
209
  }
210
 
211
  /**
219
 
220
  if ( bp_is_active( 'groups' ) ) {
221
  $this->total_groups = BP_Groups_Member::total_group_count( $this->id );
222
+ $this->total_groups = sprintf(
223
+ /* translators: %s: total groups count */
224
+ _n( '%d group', '%d groups', $this->total_groups, 'buddypress' ),
225
+ $this->total_groups
226
+ );
227
  }
228
  }
229
 
bp-core/classes/class-bp-invitation.php CHANGED
@@ -187,15 +187,15 @@ class BP_Invitation {
187
  */
188
  do_action_ref_array( 'bp_invitation_before_save', array( &$this ) );
189
 
190
- // Update
191
  if ( ! empty( $this->id ) ) {
192
  $result = self::_update( $data, array( 'ID' => $this->id ), $data_format, array( '%d' ) );
193
- // Insert
194
  } else {
195
  $result = self::_insert( $data, $data_format );
196
  }
197
 
198
- // Set the invitation ID if successful
199
  if ( ! empty( $result ) && ! is_wp_error( $result ) ) {
200
  global $wpdb;
201
 
@@ -214,7 +214,7 @@ class BP_Invitation {
214
  */
215
  do_action_ref_array( 'bp_invitation_after_save', array( &$this ) );
216
 
217
- // Return the result
218
  return $retval;
219
  }
220
 
@@ -346,13 +346,13 @@ class BP_Invitation {
346
  $where_conditions = array();
347
  $where = '';
348
 
349
- // id
350
  if ( false !== $args['id'] ) {
351
  $id_in = implode( ',', wp_parse_id_list( $args['id'] ) );
352
  $where_conditions['id'] = "id IN ({$id_in})";
353
  }
354
 
355
- // user_id
356
  if ( ! empty( $args['user_id'] ) ) {
357
  $user_id_in = implode( ',', wp_parse_id_list( $args['user_id'] ) );
358
  $where_conditions['user_id'] = "user_id IN ({$user_id_in})";
@@ -364,7 +364,7 @@ class BP_Invitation {
364
  $where_conditions['inviter_id'] = "inviter_id IN ({$inviter_id_in})";
365
  }
366
 
367
- // invitee_email
368
  if ( ! empty( $args['invitee_email'] ) ) {
369
  if ( ! is_array( $args['invitee_email'] ) ) {
370
  $invitee_emails = explode( ',', $args['invitee_email'] );
@@ -381,7 +381,7 @@ class BP_Invitation {
381
  $where_conditions['invitee_email'] = "invitee_email IN ({$invitee_email_in})";
382
  }
383
 
384
- // class
385
  if ( ! empty( $args['class'] ) ) {
386
  if ( ! is_array( $args['class'] ) ) {
387
  $class_names = explode( ',', $args['class'] );
@@ -398,19 +398,19 @@ class BP_Invitation {
398
  $where_conditions['class'] = "class IN ({$cn_in})";
399
  }
400
 
401
- // item_id
402
  if ( ! empty( $args['item_id'] ) ) {
403
  $item_id_in = implode( ',', wp_parse_id_list( $args['item_id'] ) );
404
  $where_conditions['item_id'] = "item_id IN ({$item_id_in})";
405
  }
406
 
407
- // secondary_item_id
408
  if ( ! empty( $args['secondary_item_id'] ) ) {
409
  $secondary_item_id_in = implode( ',', wp_parse_id_list( $args['secondary_item_id'] ) );
410
  $where_conditions['secondary_item_id'] = "secondary_item_id IN ({$secondary_item_id_in})";
411
  }
412
 
413
- // type
414
  if ( ! empty( $args['type'] ) && 'all' !== $args['type'] ) {
415
  if ( 'invite' == $args['type'] || 'request' == $args['type'] ) {
416
  $type_clean = $wpdb->prepare( '%s', $args['type'] );
@@ -431,7 +431,7 @@ class BP_Invitation {
431
  }
432
  }
433
 
434
- // accepted
435
  if ( ! empty( $args['accepted'] ) && 'all' !== $args['accepted'] ) {
436
  if ( $args['accepted'] == 'pending' ) {
437
  $where_conditions['accepted'] = "accepted = 0";
@@ -440,13 +440,13 @@ class BP_Invitation {
440
  }
441
  }
442
 
443
- // search_terms
444
  if ( ! empty( $args['search_terms'] ) ) {
445
  $search_terms_like = '%' . bp_esc_like( $args['search_terms'] ) . '%';
446
  $where_conditions['search_terms'] = $wpdb->prepare( "( class LIKE %s )", $search_terms_like, $search_terms_like );
447
  }
448
 
449
- // Custom WHERE
450
  if ( ! empty( $where_conditions ) ) {
451
  $where = 'WHERE ' . implode( ' AND ', $where_conditions );
452
  }
@@ -467,23 +467,23 @@ class BP_Invitation {
467
  */
468
  protected static function get_order_by_sql( $args = array() ) {
469
 
470
- // Setup local variable
471
  $conditions = array();
472
  $retval = '';
473
 
474
- // Order by
475
  if ( ! empty( $args['order_by'] ) ) {
476
  $order_by = implode( ', ', (array) $args['order_by'] );
477
  $conditions['order_by'] = "{$order_by}";
478
  }
479
 
480
- // Sort order direction
481
  if ( ! empty( $args['sort_order'] ) ) {
482
  $sort_order = bp_esc_sql_order( $args['sort_order'] );
483
  $conditions['sort_order'] = "{$sort_order}";
484
  }
485
 
486
- // Custom ORDER BY
487
  if ( ! empty( $conditions ) ) {
488
  $retval = 'ORDER BY ' . implode( ' ', $conditions );
489
  }
@@ -504,10 +504,10 @@ class BP_Invitation {
504
  protected static function get_paged_sql( $args = array() ) {
505
  global $wpdb;
506
 
507
- // Setup local variable
508
  $retval = '';
509
 
510
- // Custom LIMIT
511
  if ( ! empty( $args['page'] ) && ! empty( $args['per_page'] ) ) {
512
  $page = absint( $args['page'] );
513
  $per_page = absint( $args['per_page'] );
@@ -564,49 +564,49 @@ class BP_Invitation {
564
  'format' => array(),
565
  );
566
 
567
- // id
568
  if ( ! empty( $args['id'] ) ) {
569
  $where_clauses['data']['id'] = absint( $args['id'] );
570
  $where_clauses['format'][] = '%d';
571
  }
572
 
573
- // user_id
574
  if ( ! empty( $args['user_id'] ) ) {
575
  $where_clauses['data']['user_id'] = absint( $args['user_id'] );
576
  $where_clauses['format'][] = '%d';
577
  }
578
 
579
- // inviter_id
580
  if ( ! empty( $args['inviter_id'] ) ) {
581
  $where_clauses['data']['inviter_id'] = absint( $args['inviter_id'] );
582
  $where_clauses['format'][] = '%d';
583
  }
584
 
585
- // invitee_email
586
  if ( ! empty( $args['invitee_email'] ) ) {
587
  $where_clauses['data']['invitee_email'] = $args['invitee_email'];
588
  $where_clauses['format'][] = '%s';
589
  }
590
 
591
- // class
592
  if ( ! empty( $args['class'] ) ) {
593
  $where_clauses['data']['class'] = $args['class'];
594
  $where_clauses['format'][] = '%s';
595
  }
596
 
597
- // item_id
598
  if ( ! empty( $args['item_id'] ) ) {
599
  $where_clauses['data']['item_id'] = absint( $args['item_id'] );
600
  $where_clauses['format'][] = '%d';
601
  }
602
 
603
- // secondary_item_id
604
  if ( ! empty( $args['secondary_item_id'] ) ) {
605
  $where_clauses['data']['secondary_item_id'] = absint( $args['secondary_item_id'] );
606
  $where_clauses['format'][] = '%d';
607
  }
608
 
609
- // type
610
  if ( ! empty( $args['type'] ) && 'all' !== $args['type'] ) {
611
  if ( 'invite' == $args['type'] || 'request' == $args['type'] ) {
612
  $where_clauses['data']['type'] = $args['type'];
@@ -629,7 +629,7 @@ class BP_Invitation {
629
  }
630
  }
631
 
632
- // accepted
633
  if ( ! empty( $args['accepted'] ) && 'all' !== $args['accepted'] ) {
634
  if ( $args['accepted'] == 'pending' ) {
635
  $where_clauses['data']['accepted'] = 0;
@@ -699,13 +699,13 @@ class BP_Invitation {
699
  * Default: 'all' (return BP_Invitation objects).
700
  * }
701
  *
702
- * @return array BP_Invitation objects | IDs of found invit.
703
  */
704
  public static function get( $args = array() ) {
705
  global $wpdb;
706
  $invites_table_name = BP_Invitation_Manager::get_table_name();
707
 
708
- // Parse the arguments
709
  $r = bp_parse_args( $args, array(
710
  'id' => false,
711
  'user_id' => false,
@@ -744,7 +744,7 @@ class BP_Invitation {
744
  $sql['fields'] = 'DISTINCT i.id';
745
  }
746
 
747
- // WHERE
748
  $sql['where'] = self::get_where_sql( array(
749
  'id' => $r['id'],
750
  'user_id' => $r['user_id'],
@@ -759,13 +759,13 @@ class BP_Invitation {
759
  'search_terms' => $r['search_terms'],
760
  ) );
761
 
762
- // ORDER BY
763
  $sql['orderby'] = self::get_order_by_sql( array(
764
  'order_by' => $r['order_by'],
765
  'sort_order' => $r['sort_order']
766
  ) );
767
 
768
- // LIMIT %d, %d
769
  $sql['pagination'] = self::get_paged_sql( array(
770
  'page' => $r['page'],
771
  'per_page' => $r['per_page'],
@@ -976,12 +976,12 @@ class BP_Invitation {
976
  return false;
977
  }
978
 
979
- // Values to be updated
980
  $update_args = array(
981
  'invite_sent' => 'sent',
982
  );
983
 
984
- // WHERE clauses
985
  $where_args = array(
986
  'id' => $id,
987
  );
@@ -999,7 +999,7 @@ class BP_Invitation {
999
  */
1000
  public static function mark_sent_by_data( $args ) {
1001
 
1002
- // Values to be updated
1003
  $update_args = array(
1004
  'invite_sent' => 'sent',
1005
  );
@@ -1022,12 +1022,12 @@ class BP_Invitation {
1022
  return false;
1023
  }
1024
 
1025
- // Values to be updated
1026
  $update_args = array(
1027
  'accepted' => 'accepted',
1028
  );
1029
 
1030
- // WHERE clauses
1031
  $where_args = array(
1032
  'id' => $id,
1033
  );
@@ -1045,7 +1045,7 @@ class BP_Invitation {
1045
  */
1046
  public static function mark_accepted_by_data( $args ) {
1047
 
1048
- // Values to be updated
1049
  $update_args = array(
1050
  'accepted' => 'accepted',
1051
  );
187
  */
188
  do_action_ref_array( 'bp_invitation_before_save', array( &$this ) );
189
 
190
+ // Update.
191
  if ( ! empty( $this->id ) ) {
192
  $result = self::_update( $data, array( 'ID' => $this->id ), $data_format, array( '%d' ) );
193
+ // Insert.
194
  } else {
195
  $result = self::_insert( $data, $data_format );
196
  }
197
 
198
+ // Set the invitation ID if successful.
199
  if ( ! empty( $result ) && ! is_wp_error( $result ) ) {
200
  global $wpdb;
201
 
214
  */
215
  do_action_ref_array( 'bp_invitation_after_save', array( &$this ) );
216
 
217
+ // Return the result.
218
  return $retval;
219
  }
220
 
346
  $where_conditions = array();
347
  $where = '';
348
 
349
+ // id.
350
  if ( false !== $args['id'] ) {
351
  $id_in = implode( ',', wp_parse_id_list( $args['id'] ) );
352
  $where_conditions['id'] = "id IN ({$id_in})";
353
  }
354
 
355
+ // user_id.
356
  if ( ! empty( $args['user_id'] ) ) {
357
  $user_id_in = implode( ',', wp_parse_id_list( $args['user_id'] ) );
358
  $where_conditions['user_id'] = "user_id IN ({$user_id_in})";
364
  $where_conditions['inviter_id'] = "inviter_id IN ({$inviter_id_in})";
365
  }
366
 
367
+ // invitee_email.
368
  if ( ! empty( $args['invitee_email'] ) ) {
369
  if ( ! is_array( $args['invitee_email'] ) ) {
370
  $invitee_emails = explode( ',', $args['invitee_email'] );
381
  $where_conditions['invitee_email'] = "invitee_email IN ({$invitee_email_in})";
382
  }
383
 
384
+ // class.
385
  if ( ! empty( $args['class'] ) ) {
386
  if ( ! is_array( $args['class'] ) ) {
387
  $class_names = explode( ',', $args['class'] );
398
  $where_conditions['class'] = "class IN ({$cn_in})";
399
  }
400
 
401
+ // item_id.
402
  if ( ! empty( $args['item_id'] ) ) {
403
  $item_id_in = implode( ',', wp_parse_id_list( $args['item_id'] ) );
404
  $where_conditions['item_id'] = "item_id IN ({$item_id_in})";
405
  }
406
 
407
+ // secondary_item_id.
408
  if ( ! empty( $args['secondary_item_id'] ) ) {
409
  $secondary_item_id_in = implode( ',', wp_parse_id_list( $args['secondary_item_id'] ) );
410
  $where_conditions['secondary_item_id'] = "secondary_item_id IN ({$secondary_item_id_in})";
411
  }
412
 
413
+ // Type.
414
  if ( ! empty( $args['type'] ) && 'all' !== $args['type'] ) {
415
  if ( 'invite' == $args['type'] || 'request' == $args['type'] ) {
416
  $type_clean = $wpdb->prepare( '%s', $args['type'] );
431
  }
432
  }
433
 
434
+ // Accepted.
435
  if ( ! empty( $args['accepted'] ) && 'all' !== $args['accepted'] ) {
436
  if ( $args['accepted'] == 'pending' ) {
437
  $where_conditions['accepted'] = "accepted = 0";
440
  }
441
  }
442
 
443
+ // search_terms.
444
  if ( ! empty( $args['search_terms'] ) ) {
445
  $search_terms_like = '%' . bp_esc_like( $args['search_terms'] ) . '%';
446
  $where_conditions['search_terms'] = $wpdb->prepare( "( class LIKE %s )", $search_terms_like, $search_terms_like );
447
  }
448
 
449
+ // Custom WHERE.
450
  if ( ! empty( $where_conditions ) ) {
451
  $where = 'WHERE ' . implode( ' AND ', $where_conditions );
452
  }
467
  */
468
  protected static function get_order_by_sql( $args = array() ) {
469
 
470
+ // Setup local variable.
471
  $conditions = array();
472
  $retval = '';
473
 
474
+ // Order by.
475
  if ( ! empty( $args['order_by'] ) ) {
476
  $order_by = implode( ', ', (array) $args['order_by'] );
477
  $conditions['order_by'] = "{$order_by}";
478
  }
479
 
480
+ // Sort order direction.
481
  if ( ! empty( $args['sort_order'] ) ) {
482
  $sort_order = bp_esc_sql_order( $args['sort_order'] );
483
  $conditions['sort_order'] = "{$sort_order}";
484
  }
485
 
486
+ // Custom ORDER BY.
487
  if ( ! empty( $conditions ) ) {
488
  $retval = 'ORDER BY ' . implode( ' ', $conditions );
489
  }
504
  protected static function get_paged_sql( $args = array() ) {
505
  global $wpdb;
506
 
507
+ // Setup local variable.
508
  $retval = '';
509
 
510
+ // Custom LIMIT.
511
  if ( ! empty( $args['page'] ) && ! empty( $args['per_page'] ) ) {
512
  $page = absint( $args['page'] );
513
  $per_page = absint( $args['per_page'] );
564
  'format' => array(),
565
  );
566
 
567
+ // id.
568
  if ( ! empty( $args['id'] ) ) {
569
  $where_clauses['data']['id'] = absint( $args['id'] );
570
  $where_clauses['format'][] = '%d';
571
  }
572
 
573
+ // user_id.
574
  if ( ! empty( $args['user_id'] ) ) {
575
  $where_clauses['data']['user_id'] = absint( $args['user_id'] );
576
  $where_clauses['format'][] = '%d';
577
  }
578
 
579
+ // inviter_id.
580
  if ( ! empty( $args['inviter_id'] ) ) {
581
  $where_clauses['data']['inviter_id'] = absint( $args['inviter_id'] );
582
  $where_clauses['format'][] = '%d';
583
  }
584
 
585
+ // invitee_email.
586
  if ( ! empty( $args['invitee_email'] ) ) {
587
  $where_clauses['data']['invitee_email'] = $args['invitee_email'];
588
  $where_clauses['format'][] = '%s';
589
  }
590
 
591
+ // class.
592
  if ( ! empty( $args['class'] ) ) {
593
  $where_clauses['data']['class'] = $args['class'];
594
  $where_clauses['format'][] = '%s';
595
  }
596
 
597
+ // item_id.
598
  if ( ! empty( $args['item_id'] ) ) {
599
  $where_clauses['data']['item_id'] = absint( $args['item_id'] );
600
  $where_clauses['format'][] = '%d';
601
  }
602
 
603
+ // secondary_item_id.
604
  if ( ! empty( $args['secondary_item_id'] ) ) {
605
  $where_clauses['data']['secondary_item_id'] = absint( $args['secondary_item_id'] );
606
  $where_clauses['format'][] = '%d';
607
  }
608
 
609
+ // type.
610
  if ( ! empty( $args['type'] ) && 'all' !== $args['type'] ) {
611
  if ( 'invite' == $args['type'] || 'request' == $args['type'] ) {
612
  $where_clauses['data']['type'] = $args['type'];
629
  }
630
  }
631
 
632
+ // accepted.
633
  if ( ! empty( $args['accepted'] ) && 'all' !== $args['accepted'] ) {
634
  if ( $args['accepted'] == 'pending' ) {
635
  $where_clauses['data']['accepted'] = 0;
699
  * Default: 'all' (return BP_Invitation objects).
700
  * }
701
  *
702
+ * @return array BP_Invitation objects | IDs of found invite.
703
  */
704
  public static function get( $args = array() ) {
705
  global $wpdb;
706
  $invites_table_name = BP_Invitation_Manager::get_table_name();
707
 
708
+ // Parse the arguments.
709
  $r = bp_parse_args( $args, array(
710
  'id' => false,
711
  'user_id' => false,
744
  $sql['fields'] = 'DISTINCT i.id';
745
  }
746
 
747
+ // WHERE.
748
  $sql['where'] = self::get_where_sql( array(
749
  'id' => $r['id'],
750
  'user_id' => $r['user_id'],
759
  'search_terms' => $r['search_terms'],
760
  ) );
761
 
762
+ // ORDER BY.
763
  $sql['orderby'] = self::get_order_by_sql( array(
764
  'order_by' => $r['order_by'],
765
  'sort_order' => $r['sort_order']
766
  ) );
767
 
768
+ // LIMIT %d, %d.
769
  $sql['pagination'] = self::get_paged_sql( array(
770
  'page' => $r['page'],
771
  'per_page' => $r['per_page'],
976
  return false;
977
  }
978
 
979
+ // Values to be updated.
980
  $update_args = array(
981
  'invite_sent' => 'sent',
982
  );
983
 
984
+ // WHERE clauses.
985
  $where_args = array(
986
  'id' => $id,
987
  );
999
  */
1000
  public static function mark_sent_by_data( $args ) {
1001
 
1002
+ // Values to be updated.
1003
  $update_args = array(
1004
  'invite_sent' => 'sent',
1005
  );
1022
  return false;
1023
  }
1024
 
1025
+ // Values to be updated.
1026
  $update_args = array(
1027
  'accepted' => 'accepted',
1028
  );
1029
 
1030
+ // WHERE clauses.
1031
  $where_args = array(
1032
  'id' => $id,
1033
  );
1045
  */
1046
  public static function mark_accepted_by_data( $args ) {
1047
 
1048
+ // Values to be updated.
1049
  $update_args = array(
1050
  'accepted' => 'accepted',
1051
  );
bp-core/classes/class-bp-media-extractor.php CHANGED
@@ -825,10 +825,15 @@ class BP_Media_Extractor {
825
  // Extract the data we need from each image in this gallery.
826
  foreach ( $images as $image_id ) {
827
  $image = wp_get_attachment_image_src( $image_id, $image_size );
 
 
 
 
 
828
  $data[] = array(
829
- 'url' => $image[0],
830
- 'width' => $image[1],
831
- 'height' => $image[2],
832
 
833
  'gallery_id' => 1 + $gallery_id,
834
  );
825
  // Extract the data we need from each image in this gallery.
826
  foreach ( $images as $image_id ) {
827
  $image = wp_get_attachment_image_src( $image_id, $image_size );
828
+
829
+ $image_url = isset( $image[0] ) ? $image[0] : '';
830
+ $image_width = isset( $image[1] ) ? $image[1] : '';
831
+ $image_height = isset( $image[2] ) ? $image[2] : '';
832
+
833
  $data[] = array(
834
+ 'url' => $image_url,
835
+ 'width' => $image_width,
836
+ 'height' => $image_height,
837
 
838
  'gallery_id' => 1 + $gallery_id,
839
  );
bp-core/classes/class-bp-phpmailer.php CHANGED
@@ -6,7 +6,7 @@
6
  * @subpackage Core
7
  */
8
 
9
- // Exit if accessed directly
10
  defined( 'ABSPATH' ) || exit;
11
 
12
  /**
6
  * @subpackage Core
7
  */
8
 
9
+ // Exit if accessed directly.
10
  defined( 'ABSPATH' ) || exit;
11
 
12
  /**
bp-core/classes/class-bp-recursive-query.php CHANGED
@@ -84,7 +84,7 @@ abstract class BP_Recursive_Query {
84
  if ( 'relation' === $key ) {
85
  $relation = $query['relation'];
86
  } elseif ( is_array( $clause ) ) {
87
- // This is a first-order clause
88
  if ( $this->is_first_order_clause( $clause ) ) {
89
  $clause_sql = $this->get_sql_for_clause( $clause, $query );
90
 
@@ -98,7 +98,7 @@ abstract class BP_Recursive_Query {
98
  }
99
 
100
  $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] );
101
- // This is a subquery
102
  } else {
103
  $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 );
104
 
@@ -108,7 +108,7 @@ abstract class BP_Recursive_Query {
108
  }
109
  }
110
 
111
- // Filter empties
112
  $sql_chunks['join'] = array_filter( $sql_chunks['join'] );
113
  $sql_chunks['where'] = array_filter( $sql_chunks['where'] );
114
 
84
  if ( 'relation' === $key ) {
85
  $relation = $query['relation'];
86
  } elseif ( is_array( $clause ) ) {
87
+ // This is a first-order clause.
88
  if ( $this->is_first_order_clause( $clause ) ) {
89
  $clause_sql = $this->get_sql_for_clause( $clause, $query );
90
 
98
  }
99
 
100
  $sql_chunks['join'] = array_merge( $sql_chunks['join'], $clause_sql['join'] );
101
+ // This is a subquery.
102
  } else {
103
  $clause_sql = $this->get_sql_for_query( $clause, $depth + 1 );
104
 
108
  }
109
  }
110
 
111
+ // Filter empties.
112
  $sql_chunks['join'] = array_filter( $sql_chunks['join'] );
113
  $sql_chunks['where'] = array_filter( $sql_chunks['where'] );
114
 
bp-core/classes/class-bp-rest-attachments-group-avatar-endpoint.php CHANGED
@@ -3,497 +3,12 @@
3
  * BP REST: BP_REST_Attachments_Group_Avatar_Endpoint class
4
  *
5
  * @package BuddyPress
6
- * @since 5.0.0
7
  */
8
 
9
  defined( 'ABSPATH' ) || exit;
10
 
11
- /**
12
- * Group Avatar endpoints.
13
- *
14
- * @since 5.0.0
15
- */
16
- class BP_REST_Attachments_Group_Avatar_Endpoint extends WP_REST_Controller {
17
-
18
- use BP_REST_Attachments;
19
-
20
- /**
21
- * Reuse some parts of the BP_REST_Groups_Endpoint class.
22
- *
23
- * @since 5.0.0
24
- *
25
- * @var BP_REST_Groups_Endpoint
26
- */
27
- protected $groups_endpoint;
28
-
29
- /**
30
- * BP_Attachment_Avatar Instance.
31
- *
32
- * @since 5.0.0
33
- *
34
- * @var BP_Attachment_Avatar
35
- */
36
- protected $avatar_instance;
37
-
38
- /**
39
- * Hold the group object.
40
- *
41
- * @since 5.0.0
42
- *
43
- * @var BP_Groups_Group
44
- */
45
- protected $group;
46
-
47
- /**
48
- * Group object type.
49
- *
50
- * @since 5.0.0
51
- *
52
- * @var string
53
- */
54
- protected $object = 'group';
55
-
56
- /**
57
- * Constructor.
58
- *
59
- * @since 5.0.0
60
- */
61
- public function __construct() {
62
- $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
63
- $this->rest_base = buddypress()->groups->id;
64
- $this->groups_endpoint = new BP_REST_Groups_Endpoint();
65
- $this->avatar_instance = new BP_Attachment_Avatar();
66
- }
67
-
68
- /**
69
- * Register the component routes.
70
- *
71
- * @since 5.0.0
72
- */
73
- public function register_routes() {
74
- register_rest_route(
75
- $this->namespace,
76
- '/' . $this->rest_base . '/(?P<group_id>[\d]+)/avatar',
77
- array(
78
- 'args' => array(
79
- 'group_id' => array(
80
- 'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),
81
- 'type' => 'integer',
82
- ),
83
- ),
84
- array(
85
- 'methods' => WP_REST_Server::READABLE,
86
- 'callback' => array( $this, 'get_item' ),
87
- 'permission_callback' => array( $this, 'get_item_permissions_check' ),
88
- 'args' => $this->get_item_collection_params(),
89
- ),
90
- array(
91
- 'methods' => WP_REST_Server::CREATABLE,
92
- 'callback' => array( $this, 'create_item' ),
93
- 'permission_callback' => array( $this, 'create_item_permissions_check' ),
94
- ),
95
- array(
96
- 'methods' => WP_REST_Server::DELETABLE,
97
- 'callback' => array( $this, 'delete_item' ),
98
- 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
99
- ),
100
- 'schema' => array( $this, 'get_item_schema' ),
101
- )
102
- );
103
- }
104
-
105
- /**
106
- * Fetch an existing group avatar.
107
- *
108
- * @since 5.0.0
109
- *
110
- * @param WP_REST_Request $request Full details about the request.
111
- * @return WP_REST_Response|WP_Error
112
- */
113
- public function get_item( $request ) {
114
- $args = array();
115
-
116
- foreach ( array( 'full', 'thumb' ) as $type ) {
117
- $args[ $type ] = bp_core_fetch_avatar(
118
- array(
119
- 'object' => $this->object,
120
- 'type' => $type,
121
- 'item_id' => (int) $this->group->id,
122
- 'html' => (bool) $request['html'],
123
- 'alt' => $request['alt'],
124
- )
125
- );
126
- }
127
-
128
- // Get the avatar object.
129
- $avatar = $this->get_avatar_object( $args );
130
-
131
- if ( ! $avatar->full && ! $avatar->thumb ) {
132
- return new WP_Error(
133
- 'bp_rest_attachments_group_avatar_no_image',
134
- __( 'Sorry, there was a problem fetching this group avatar.', 'buddypress' ),
135
- array(
136
- 'status' => 500,
137
- )
138
- );
139
- }
140
-
141
- $retval = array(
142
- $this->prepare_response_for_collection(
143
- $this->prepare_item_for_response( $avatar, $request )
144
- ),
145
- );
146
-
147
- $response = rest_ensure_response( $retval );
148
-
149
- /**
150
- * Fires after a group avatar is fetched via the REST API.
151
- *
152
- * @since 5.0.0
153
- *
154
- * @param string $avatar The group avatar.
155
- * @param WP_REST_Response $response The response data.
156
- * @param WP_REST_Request $request The request sent to the API.
157
- */
158
- do_action( 'bp_rest_attachments_group_avatar_get_item', $avatar, $response, $request );
159
-
160
- return $response;
161
- }
162
-
163
- /**
164
- * Checks if a given request has access to get a group avatar.
165
- *
166
- * @since 5.0.0
167
- *
168
- * @param WP_REST_Request $request Full details about the request.
169
- * @return bool|WP_Error
170
- */
171
- public function get_item_permissions_check( $request ) {
172
- $retval = true;
173
- $this->group = $this->groups_endpoint->get_group_object( $request );
174
-
175
- if ( ! $this->group ) {
176
- $retval = new WP_Error(
177
- 'bp_rest_group_invalid_id',
178
- __( 'Invalid group ID.', 'buddypress' ),
179
- array(
180
- 'status' => 404,
181
- )
182
- );
183
- }
184
-
185
- /**
186
- * Filter the group avatar `get_item` permissions check.
187
- *
188
- * @since 5.0.0
189
- *
190
- * @param bool|WP_Error $retval Returned value.
191
- * @param WP_REST_Request $request The request sent to the API.
192
- */
193
- return apply_filters( 'bp_rest_attachments_group_avatar_get_item_permissions_check', $retval, $request );
194
- }
195
-
196
- /**
197
- * Upload a group avatar.
198
- *
199
- * @since 5.0.0
200
- *
201
- * @param WP_REST_Request $request Full details about the request.
202
- * @return WP_REST_Response|WP_Error
203
- */
204
- public function create_item( $request ) {
205
- $request->set_param( 'context', 'edit' );
206
-
207
- // Get the image file from $_FILES.
208
- $files = $request->get_file_params();
209
-
210
- if ( empty( $files ) ) {
211
- return new WP_Error(
212
- 'bp_rest_attachments_group_avatar_no_image_file',
213
- __( 'Sorry, you need an image file to upload.', 'buddypress' ),
214
- array(
215
- 'status' => 500,
216
- )
217
- );
218
- }
219
-
220
- // Upload the avatar.
221
- $avatar = $this->upload_avatar_from_file( $files );
222
- if ( is_wp_error( $avatar ) ) {
223
- return $avatar;
224
- }
225
-
226
- $retval = array(
227
- $this->prepare_response_for_collection(
228
- $this->prepare_item_for_response( $avatar, $request )
229
- ),
230
- );
231
-
232
- $response = rest_ensure_response( $retval );
233
-
234
- /**
235
- * Fires after a group avatar is uploaded via the REST API.
236
- *
237
- * @since 5.0.0
238
- *
239
- * @param stdClass $avatar The group avatar object.
240
- * @param WP_REST_Response $response The response data.
241
- * @param WP_REST_Request $request The request sent to the API.
242
- */
243
- do_action( 'bp_rest_attachments_group_avatar_create_item', $avatar, $response, $request );
244
-
245
- return $response;
246
- }
247
-
248
- /**
249
- * Checks if a given request has access to upload a group avatar.
250
- *
251
- * @since 5.0.0
252
- *
253
- * @param WP_REST_Request $request Full details about the request.
254
- * @return bool|WP_Error
255
- */
256
- public function create_item_permissions_check( $request ) {
257
- $retval = $this->get_item_permissions_check( $request );
258
-
259
- if ( true === $retval && ( bp_disable_group_avatar_uploads() || ! buddypress()->avatar->show_avatars ) ) {
260
- $retval = new WP_Error(
261
- 'bp_rest_attachments_group_avatar_disabled',
262
- __( 'Sorry, group avatar upload is disabled.', 'buddypress' ),
263
- array(
264
- 'status' => 500,
265
- )
266
- );
267
- }
268
-
269
- if ( true === $retval
270
- && ! groups_is_user_admin( bp_loggedin_user_id(), $this->group->id )
271
- && ! current_user_can( 'bp_moderate' )
272
- ) {
273
- $retval = new WP_Error(
274
- 'bp_rest_authorization_required',
275
- __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
276
- array(
277
- 'status' => rest_authorization_required_code(),
278
- )
279
- );
280
- }
281
-
282
- /**
283
- * Filter the group avatar `create_item` permissions check.
284
- *
285
- * @since 5.0.0
286
- *
287
- * @param bool|WP_Error $retval Returned value.
288
- * @param WP_REST_Request $request The request sent to the API.
289
- */
290
- return apply_filters( 'bp_rest_attachments_group_avatar_create_item_permissions_check', $retval, $request );
291
- }
292
-
293
- /**
294
- * Delete an existing group avatar.
295
- *
296
- * @since 5.0.0
297
- *
298
- * @param WP_REST_Request $request Full details about the request.
299
- * @return WP_REST_Response|WP_Error
300
- */
301
- public function delete_item( $request ) {
302
- $request->set_param( 'context', 'edit' );
303
- $group_id = (int) $this->group->id;
304
-
305
- if ( ! bp_get_group_has_avatar( $group_id ) ) {
306
- return new WP_Error(
307
- 'bp_rest_attachments_group_avatar_no_uploaded_avatar',
308
- __( 'Sorry, there are no uploaded avatars for this group on this site.', 'buddypress' ),
309
- array(
310
- 'status' => 404,
311
- )
312
- );
313
- }
314
-
315
- $args = array();
316
-
317
- foreach ( array( 'full', 'thumb' ) as $type ) {
318
- $args[ $type ] = bp_core_fetch_avatar(
319
- array(
320
- 'object' => $this->object,
321
- 'type' => $type,
322
- 'item_id' => $group_id,
323
- 'html' => false,
324
- )
325
- );
326
- }
327
-
328
- // Get the avatar object before deleting it.
329
- $avatar = $this->get_avatar_object( $args );
330
-
331
- $deleted = bp_core_delete_existing_avatar(
332
- array(
333
- 'object' => $this->object,
334
- 'item_id' => $group_id,
335
- )
336
- );
337
-
338
- if ( ! $deleted ) {
339
- return new WP_Error(
340
- 'bp_rest_attachments_group_avatar_delete_failed',
341
- __( 'Sorry, there was a problem deleting this group avatar.', 'buddypress' ),
342
- array(
343
- 'status' => 500,
344
- )
345
- );
346
- }
347
-
348
- // Build the response.
349
- $response = new WP_REST_Response();
350
- $response->set_data(
351
- array(
352
- 'deleted' => true,
353
- 'previous' => $avatar,
354
- )
355
- );
356
-
357
- /**
358
- * Fires after a group avatar is deleted via the REST API.
359
- *
360
- * @since 5.0.0
361
- *
362
- * @param WP_REST_Response $response The response data.
363
- * @param WP_REST_Request $request The request sent to the API.
364
- */
365
- do_action( 'bp_rest_attachments_group_avatar_delete_item', $response, $request );
366
-
367
- return $response;
368
- }
369
-
370
- /**
371
- * Checks if a given request has access to delete a group avatar.
372
- *
373
- * @since 5.0.0
374
- *
375
- * @param WP_REST_Request $request Full details about the request.
376
- * @return bool|WP_Error
377
- */
378
- public function delete_item_permissions_check( $request ) {
379
- $retval = $this->create_item_permissions_check( $request );
380
-
381
- /**
382
- * Filter the group avatar `delete_item` permissions check.
383
- *
384
- * @since 5.0.0
385
- *
386
- * @param bool|WP_Error $retval Returned value.
387
- * @param WP_REST_Request $request The request sent to the API.
388
- */
389
- return apply_filters( 'bp_rest_attachments_group_avatar_delete_item_permissions_check', $retval, $request );
390
- }
391
-
392
- /**
393
- * Prepares avatar data to return as an object.
394
- *
395
- * @since 5.0.0
396
- *
397
- * @param stdClass|string $avatar Avatar object or string with url or image with html.
398
- * @param WP_REST_Request $request Full details about the request.
399
- * @return WP_REST_Response
400
- */
401
- public function prepare_item_for_response( $avatar, $request ) {
402
- $data = array(
403
- 'full' => $avatar->full,
404
- 'thumb' => $avatar->thumb,
405
- );
406
-
407
- $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
408
- $data = $this->add_additional_fields_to_object( $data, $request );
409
- $data = $this->filter_response_by_context( $data, $context );
410
-
411
- // @todo add prepare_links
412
- $response = rest_ensure_response( $data );
413
-
414
- /**
415
- * Filter a group avatar value returned from the API.
416
- *
417
- * @since 5.0.0
418
- *
419
- * @param WP_REST_Response $response Response.
420
- * @param WP_REST_Request $request Request used to generate the response.
421
- * @param stdClass|string $avatar Avatar object or string with url or image with html.
422
- */
423
- return apply_filters( 'bp_rest_attachments_group_avatar_prepare_value', $response, $request, $avatar );
424
- }
425
-
426
- /**
427
- * Get the plugin schema, conforming to JSON Schema.
428
- *
429
- * @since 5.0.0
430
- *
431
- * @return array
432
- */
433
- public function get_item_schema() {
434
- $schema = array(
435
- '$schema' => 'http://json-schema.org/draft-04/schema#',
436
- 'title' => 'bp_attachments_group_avatar',
437
- 'type' => 'object',
438
- 'properties' => array(
439
- 'full' => array(
440
- 'context' => array( 'view', 'edit' ),
441
- 'description' => __( 'Full size of the image file.', 'buddypress' ),
442
- 'type' => 'string',
443
- 'readonly' => true,
444
- ),
445
- 'thumb' => array(
446
- 'context' => array( 'view', 'edit' ),
447
- 'description' => __( 'Thumb size of the image file.', 'buddypress' ),
448
- 'type' => 'string',
449
- 'readonly' => true,
450
- ),
451
- ),
452
- );
453
-
454
- /**
455
- * Filters the group avatar schema.
456
- *
457
- * @param string $schema The endpoint schema.
458
- */
459
- return apply_filters( 'bp_rest_attachments_group_avatar_schema', $this->add_additional_fields_schema( $schema ) );
460
- }
461
-
462
- /**
463
- * Get the query params for the `get_item`.
464
- *
465
- * @since 5.0.0
466
- *
467
- * @return array
468
- */
469
- public function get_item_collection_params() {
470
- $params = parent::get_collection_params();
471
- $params['context']['default'] = 'view';
472
-
473
- // Removing unused params.
474
- unset( $params['search'], $params['page'], $params['per_page'] );
475
-
476
- $params['html'] = array(
477
- 'description' => __( 'Whether to return an <img> HTML element, vs a raw URL to a group avatar.', 'buddypress' ),
478
- 'default' => false,
479
- 'type' => 'boolean',
480
- 'sanitize_callback' => 'rest_sanitize_boolean',
481
- 'validate_callback' => 'rest_validate_request_arg',
482
- );
483
-
484
- $params['alt'] = array(
485
- 'description' => __( 'The alt attribute for the <img> element.', 'buddypress' ),
486
- 'default' => '',
487
- 'type' => 'string',
488
- 'sanitize_callback' => 'sanitize_text_field',
489
- 'validate_callback' => 'rest_validate_request_arg',
490
- );
491
 
492
- /**
493
- * Filters the item collection query params.
494
- *
495
- * @param array $params Query params.
496
- */
497
- return apply_filters( 'bp_rest_attachments_group_avatar_collection_params', $params );
498
- }
499
- }
3
  * BP REST: BP_REST_Attachments_Group_Avatar_Endpoint class
4
  *
5
  * @package BuddyPress
6
+ * @deprecated 6.0.0
7
  */
8
 
9
  defined( 'ABSPATH' ) || exit;
10
 
11
+ _deprecated_file( basename( __FILE__ ), '6.0.0', 'bp-groups/classes/class-bp-rest-attachments-group-avatar-endpoint.php' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ /** BP_REST_Attachments_Group_Avatar_Endpoint class */
14
+ require_once trailingslashit( constant( 'BP_PLUGIN_DIR' ) . constant( 'BP_SOURCE_SUBDIRECTORY' ) ) . 'bp-groups/classes/class-bp-rest-attachments-group-avatar-endpoint.php';
 
 
 
 
 
 
bp-core/classes/class-bp-rest-attachments-member-avatar-endpoint.php CHANGED
@@ -3,513 +3,12 @@
3
  * BP REST: BP_REST_Attachments_Member_Avatar_Endpoint class
4
  *
5
  * @package BuddyPress
6
- * @since 5.0.0
7
  */
8
 
9
  defined( 'ABSPATH' ) || exit;
10
 
11
- /**
12
- * Member Avatar endpoints.
13
- *
14
- * @since 5.0.0
15
- */
16
- class BP_REST_Attachments_Member_Avatar_Endpoint extends WP_REST_Controller {
17
-
18
- use BP_REST_Attachments;
19
-
20
- /**
21
- * BP_Attachment_Avatar Instance.
22
- *
23
- * @since 5.0.0
24
- *
25
- * @var BP_Attachment_Avatar
26
- */
27
- protected $avatar_instance;
28
-
29
- /**
30
- * Member object type.
31
- *
32
- * @since 5.0.0
33
- *
34
- * @var string
35
- */
36
- protected $object = 'user';
37
-
38
- /**
39
- * Member object.
40
- *
41
- * @since 5.0.0
42
- *
43
- * @var WP_User
44
- */
45
- protected $user;
46
-
47
- /**
48
- * Constructor.
49
- *
50
- * @since 5.0.0
51
- */
52
- public function __construct() {
53
- $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
54
- $this->rest_base = 'members';
55
- $this->avatar_instance = new BP_Attachment_Avatar();
56
- }
57
-
58
- /**
59
- * Register the component routes.
60
- *
61
- * @since 5.0.0
62
- */
63
- public function register_routes() {
64
- register_rest_route(
65
- $this->namespace,
66
- '/' . $this->rest_base . '/(?P<user_id>[\d]+)/avatar',
67
- array(
68
- 'args' => array(
69
- 'user_id' => array(
70
- 'description' => __( 'A unique numeric ID for the Member.', 'buddypress' ),
71
- 'type' => 'integer',
72
- ),
73
- ),
74
- array(
75
- 'methods' => WP_REST_Server::READABLE,
76
- 'callback' => array( $this, 'get_item' ),
77
- 'permission_callback' => array( $this, 'get_item_permissions_check' ),
78
- 'args' => $this->get_item_collection_params(),
79
- ),
80
- array(
81
- 'methods' => WP_REST_Server::CREATABLE,
82
- 'callback' => array( $this, 'create_item' ),
83
- 'permission_callback' => array( $this, 'create_item_permissions_check' ),
84
- ),
85
- array(
86
- 'methods' => WP_REST_Server::DELETABLE,
87
- 'callback' => array( $this, 'delete_item' ),
88
- 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
89
- ),
90
- 'schema' => array( $this, 'get_item_schema' ),
91
- )
92
- );
93
- }
94
-
95
- /**
96
- * Fetch an existing member avatar.
97
- *
98
- * @since 5.0.0
99
- *
100
- * @param WP_REST_Request $request Full details about the request.
101
- * @return WP_REST_Response|WP_Error
102
- */
103
- public function get_item( $request ) {
104
- $args = array();
105
-
106
- foreach ( array( 'full', 'thumb' ) as $type ) {
107
- $args[ $type ] = bp_core_fetch_avatar(
108
- array(
109
- 'object' => $this->object,
110
- 'type' => $type,
111
- 'item_id' => (int) $this->user->ID,
112
- 'html' => (bool) $request['html'],
113
- 'alt' => $request['alt'],
114
- 'no_grav' => (bool) $request['no_gravatar'],
115
- )
116
- );
117
- }
118
-
119
- // Get the avatar object.
120
- $avatar = $this->get_avatar_object( $args );
121
-
122
- if ( ! $avatar->full && ! $avatar->thumb ) {
123
- return new WP_Error(
124
- 'bp_rest_attachments_member_avatar_no_image',
125
- __( 'Sorry, there was a problem fetching the avatar.', 'buddypress' ),
126
- array(
127
- 'status' => 500,
128
- )
129
- );
130
- }
131
-
132
- $retval = array(
133
- $this->prepare_response_for_collection(
134
- $this->prepare_item_for_response( $avatar, $request )
135
- ),
136
- );
137
-
138
- $response = rest_ensure_response( $retval );
139
-
140
- /**
141
- * Fires after a member avatar is fetched via the REST API.
142
- *
143
- * @since 5.0.0
144
- *
145
- * @param string $avatar The avatar.
146
- * @param WP_REST_Response $response The response data.
147
- * @param WP_REST_Request $request The request sent to the API.
148
- */
149
- do_action( 'bp_rest_attachments_member_avatar_get_item', $avatar, $response, $request );
150
-
151
- return $response;
152
- }
153
-
154
- /**
155
- * Checks if a given request has access to get a member avatar.
156
- *
157
- * @since 5.0.0
158
- *
159
- * @param WP_REST_Request $request Full details about the request.
160
- * @return bool|WP_Error
161
- */
162
- public function get_item_permissions_check( $request ) {
163
- $retval = true;
164
- $this->user = bp_rest_get_user( $request['user_id'] );
165
-
166
- if ( true === $retval && ! $this->user instanceof WP_User ) {
167
- $retval = new WP_Error(
168
- 'bp_rest_member_invalid_id',
169
- __( 'Invalid member ID.', 'buddypress' ),
170
- array(
171
- 'status' => 404,
172
- )
173
- );
174
- }
175
-
176
- /**
177
- * Filter the member avatar `get_item` permissions check.
178
- *
179
- * @since 5.0.0
180
- *
181
- * @param bool|WP_Error $retval Returned value.
182
- * @param WP_REST_Request $request The request sent to the API.
183
- */
184
- return apply_filters( 'bp_rest_attachments_member_avatar_get_item_permissions_check', $retval, $request );
185
- }
186
-
187
- /**
188
- * Upload a member avatar.
189
- *
190
- * @since 5.0.0
191
- *
192
- * @param WP_REST_Request $request Full details about the request.
193
- * @return WP_REST_Response|WP_Error
194
- */
195
- public function create_item( $request ) {
196
- $request->set_param( 'context', 'edit' );
197
-
198
- // Get the image file from $_FILES.
199
- $files = $request->get_file_params();
200
-
201
- if ( empty( $files ) ) {
202
- return new WP_Error(
203
- 'bp_rest_attachments_member_avatar_no_image_file',
204
- __( 'Sorry, you need an image file to upload.', 'buddypress' ),
205
- array(
206
- 'status' => 500,
207
- )
208
- );
209
- }
210
-
211
- // Upload the avatar.
212
- $avatar = $this->upload_avatar_from_file( $files );
213
- if ( is_wp_error( $avatar ) ) {
214
- return $avatar;
215
- }
216
-
217
- $retval = array(
218
- $this->prepare_response_for_collection(
219
- $this->prepare_item_for_response( $avatar, $request )
220
- ),
221
- );
222
-
223
- $response = rest_ensure_response( $retval );
224
-
225
- /**
226
- * Fires after a member avatar is uploaded via the REST API.
227
- *
228
- * @since 5.0.0
229
- *
230
- * @param stdClass $avatar Avatar object.
231
- * @param WP_REST_Response $response The response data.
232
- * @param WP_REST_Request $request The request sent to the API.
233
- */
234
- do_action( 'bp_rest_attachments_member_avatar_create_item', $avatar, $response, $request );
235
-
236
- return $response;
237
- }
238
-
239
- /**
240
- * Checks if a given request has access to upload a member avatar.
241
- *
242
- * @since 5.0.0
243
- *
244
- * @param WP_REST_Request $request Full details about the request.
245
- * @return bool|WP_Error
246
- */
247
- public function create_item_permissions_check( $request ) {
248
- $retval = $this->get_item_permissions_check( $request );
249
- $args = array();
250
-
251
- if ( isset( $this->user->ID ) ) {
252
- $args = array(
253
- 'item_id' => (int) $this->user->ID,
254
- 'object' => 'user',
255
- );
256
- }
257
-
258
- if ( true === $retval && ! is_user_logged_in() ) {
259
- $retval = new WP_Error(
260
- 'bp_rest_authorization_required',
261
- __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
262
- array(
263
- 'status' => rest_authorization_required_code(),
264
- )
265
- );
266
- }
267
-
268
- if ( true === $retval && bp_disable_avatar_uploads() ) {
269
- $retval = new WP_Error(
270
- 'bp_rest_attachments_member_avatar_disabled',
271
- __( 'Sorry, member avatar upload is disabled.', 'buddypress' ),
272
- array(
273
- 'status' => 500,
274
- )
275
- );
276
- }
277
-
278
- if ( true === $retval && ! empty( $args ) && ! bp_attachments_current_user_can( 'edit_avatar', $args ) ) {
279
- $retval = new WP_Error(
280
- 'bp_rest_authorization_required',
281
- __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
282
- array(
283
- 'status' => rest_authorization_required_code(),
284
- )
285
- );
286
- }
287
-
288
- /**
289
- * Filter the member avatar `create_item` permissions check.
290
- *
291
- * @since 5.0.0
292
- *
293
- * @param bool|WP_Error $retval Returned value.
294
- * @param WP_REST_Request $request The request sent to the API.
295
- */
296
- return apply_filters( 'bp_rest_attachments_member_avatar_create_item_permissions_check', $retval, $request );
297
- }
298
-
299
- /**
300
- * Delete an existing member avatar.
301
- *
302
- * @since 5.0.0
303
- *
304
- * @param WP_REST_Request $request Full details about the request.
305
- * @return WP_REST_Response|WP_Error
306
- */
307
- public function delete_item( $request ) {
308
- $request->set_param( 'context', 'edit' );
309
- $user_id = (int) $this->user->ID;
310
-
311
- if ( ! bp_get_user_has_avatar( $user_id ) ) {
312
- return new WP_Error(
313
- 'bp_rest_attachments_member_avatar_no_uploaded_avatar',
314
- __( 'Sorry, there are no uploaded avatars for this user on this site.', 'buddypress' ),
315
- array(
316
- 'status' => 404,
317
- )
318
- );
319
- }
320
-
321
- $args = array();
322
-
323
- foreach ( array( 'full', 'thumb' ) as $type ) {
324
- $args[ $type ] = bp_core_fetch_avatar(
325
- array(
326
- 'object' => $this->object,
327
- 'type' => $type,
328
- 'item_id' => $user_id,
329
- 'html' => false,
330
- )
331
- );
332
- }
333
-
334
- // Get the avatar object before deleting it.
335
- $avatar = $this->get_avatar_object( $args );
336
-
337
- $deleted = bp_core_delete_existing_avatar(
338
- array(
339
- 'object' => $this->object,
340
- 'item_id' => $user_id,
341
- )
342
- );
343
-
344
- if ( ! $deleted ) {
345
- return new WP_Error(
346
- 'bp_rest_attachments_member_avatar_delete_failed',
347
- __( 'Sorry, there was a problem deleting the avatar.', 'buddypress' ),
348
- array(
349
- 'status' => 500,
350
- )
351
- );
352
- }
353
-
354
- // Build the response.
355
- $response = new WP_REST_Response();
356
- $response->set_data(
357
- array(
358
- 'deleted' => true,
359
- 'previous' => $avatar,
360
- )
361
- );
362
-
363
- /**
364
- * Fires after a member avatar is deleted via the REST API.
365
- *
366
- * @since 5.0.0
367
- *
368
- * @param WP_REST_Response $response The response data.
369
- * @param WP_REST_Request $request The request sent to the API.
370
- */
371
- do_action( 'bp_rest_attachments_member_avatar_delete_item', $response, $request );
372
-
373
- return $response;
374
- }
375
-
376
- /**
377
- * Checks if a given request has access to delete member avatar.
378
- *
379
- * @since 5.0.0
380
- *
381
- * @param WP_REST_Request $request Full details about the request.
382
- * @return bool|WP_Error
383
- */
384
- public function delete_item_permissions_check( $request ) {
385
- $retval = $this->create_item_permissions_check( $request );
386
-
387
- /**
388
- * Filter the member avatar `delete_item` permissions check.
389
- *
390
- * @since 5.0.0
391
- *
392
- * @param bool|WP_Error $retval Returned value.
393
- * @param WP_REST_Request $request The request sent to the API.
394
- */
395
- return apply_filters( 'bp_rest_attachments_member_avatar_delete_item_permissions_check', $retval, $request );
396
- }
397
-
398
- /**
399
- * Prepares avatar data to return as an object.
400
- *
401
- * @since 5.0.0
402
- *
403
- * @param stdClass|string $avatar Avatar object or string with url or image with html.
404
- * @param WP_REST_Request $request Full details about the request.
405
- * @return WP_REST_Response
406
- */
407
- public function prepare_item_for_response( $avatar, $request ) {
408
- $data = array(
409
- 'full' => $avatar->full,
410
- 'thumb' => $avatar->thumb,
411
- );
412
-
413
- $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
414
- $data = $this->add_additional_fields_to_object( $data, $request );
415
- $data = $this->filter_response_by_context( $data, $context );
416
-
417
- // @todo add prepare_links
418
- $response = rest_ensure_response( $data );
419
-
420
- /**
421
- * Filter a member avatar value returned from the API.
422
- *
423
- * @since 5.0.0
424
- *
425
- * @param WP_REST_Response $response Response.
426
- * @param WP_REST_Request $request Request used to generate the response.
427
- * @param stdClass|string $avatar Avatar object or string with url or image with html.
428
- */
429
- return apply_filters( 'bp_rest_attachments_member_avatar_prepare_value', $response, $request, $avatar );
430
- }
431
-
432
- /**
433
- * Get the member avatar schema, conforming to JSON Schema.
434
- *
435
- * @since 5.0.0
436
- *
437
- * @return array
438
- */
439
- public function get_item_schema() {
440
- $schema = array(
441
- '$schema' => 'http://json-schema.org/draft-04/schema#',
442
- 'title' => 'bp_attachments_member_avatar',
443
- 'type' => 'object',
444
- 'properties' => array(
445
- 'full' => array(
446
- 'context' => array( 'view', 'edit' ),
447
- 'description' => __( 'Full size of the image file.', 'buddypress' ),
448
- 'type' => 'string',
449
- 'format' => 'uri',
450
- 'readonly' => true,
451
- ),
452
- 'thumb' => array(
453
- 'context' => array( 'view', 'edit' ),
454
- 'description' => __( 'Thumb size of the image file.', 'buddypress' ),
455
- 'type' => 'string',
456
- 'format' => 'uri',
457
- 'readonly' => true,
458
- ),
459
- ),
460
- );
461
-
462
- /**
463
- * Filters the member avatar schema.
464
- *
465
- * @param string $schema The endpoint schema.
466
- */
467
- return apply_filters( 'bp_rest_attachments_member_avatar_schema', $this->add_additional_fields_schema( $schema ) );
468
- }
469
-
470
- /**
471
- * Get the query params for the `get_item`.
472
- *
473
- * @since 5.0.0
474
- *
475
- * @return array
476
- */
477
- public function get_item_collection_params() {
478
- $params = parent::get_collection_params();
479
- $params['context']['default'] = 'view';
480
-
481
- // Removing unused params.
482
- unset( $params['search'], $params['page'], $params['per_page'] );
483
-
484
- $params['html'] = array(
485
- 'description' => __( 'Whether to return an <img> HTML element, vs a raw URL to an avatar.', 'buddypress' ),
486
- 'default' => false,
487
- 'type' => 'boolean',
488
- 'sanitize_callback' => 'rest_sanitize_boolean',
489
- 'validate_callback' => 'rest_validate_request_arg',
490
- );
491
-
492
- $params['alt'] = array(
493
- 'description' => __( 'The alt attribute for the <img> element.', 'buddypress' ),
494
- 'default' => '',
495
- 'type' => 'string',
496
- 'sanitize_callback' => 'sanitize_text_field',
497
- 'validate_callback' => 'rest_validate_request_arg',
498
- );
499
-
500
- $params['no_grav'] = array(
501
- 'description' => __( 'Whether to disable the default Gravatar fallback.', 'buddypress' ),
502
- 'default' => false,
503
- 'type' => 'boolean',
504
- 'sanitize_callback' => 'rest_sanitize_boolean',
505
- 'validate_callback' => 'rest_validate_request_arg',
506
- );
507
 
508
- /**
509
- * Filters the item collection query params.
510
- *
511
- * @param array $params Query params.
512
- */
513
- return apply_filters( 'bp_rest_attachments_member_avatar_collection_params', $params );
514
- }
515
- }
3
  * BP REST: BP_REST_Attachments_Member_Avatar_Endpoint class
4
  *
5
  * @package BuddyPress
6
+ * @deprecated 6.0.0
7
  */
8
 
9
  defined( 'ABSPATH' ) || exit;
10
 
11
+ _deprecated_file( basename( __FILE__ ), '6.0.0', 'bp-members/classes/class-class-bp-rest-attachments-member-avatar-endpoint.php' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ /** BP_REST_Attachments_Member_Avatar_Endpoint class */
14
+ require_once trailingslashit( constant( 'BP_PLUGIN_DIR' ) . constant( 'BP_SOURCE_SUBDIRECTORY' ) ) . 'bp-members/classes/class-bp-rest-attachments-member-avatar-endpoint.php';
 
 
 
 
 
 
bp-core/classes/class-bp-user-query.php CHANGED
@@ -183,7 +183,7 @@ class BP_User_Query {
183
  */
184
  do_action_ref_array( 'bp_pre_user_query_construct', array( &$this ) );
185
 
186
- // Get user ids
187
  // If the user_ids param is present, we skip the query.
188
  if ( false !== $this->query_vars['user_ids'] ) {
189
  $this->user_ids = wp_parse_id_list( $this->query_vars['user_ids'] );
@@ -684,7 +684,7 @@ class BP_User_Query {
684
 
685
  // Set a last_activity value for each user, even if it's empty.
686
  foreach ( $this->results as $user_id => $user ) {
687
- $user_last_activity = isset( $last_activities[ $user_id ] ) ? $last_activities[ $user_id ]['date_recorded'] : '';
688
  $this->results[ $user_id ]->last_activity = $user_last_activity;
689
  }
690
 
183
  */
184
  do_action_ref_array( 'bp_pre_user_query_construct', array( &$this ) );
185
 
186
+ // Get user ids.
187
  // If the user_ids param is present, we skip the query.
188
  if ( false !== $this->query_vars['user_ids'] ) {
189
  $this->user_ids = wp_parse_id_list( $this->query_vars['user_ids'] );
684
 
685
  // Set a last_activity value for each user, even if it's empty.
686
  foreach ( $this->results as $user_id => $user ) {
687
+ $user_last_activity = isset( $last_activities[ $user_id ]['date_recorded'] ) ? $last_activities[ $user_id ]['date_recorded'] : '';
688
  $this->results[ $user_id ]->last_activity = $user_last_activity;
689
  }
690
 
bp-core/classes/class-bp-walker-nav-menu.php CHANGED
@@ -11,12 +11,11 @@
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
14
- * Compatibility Class to make BP_Walker_Nav_Menu::walk() compatible
15
- * from PHP 5.3 to 5.6 and up.
16
  *
17
- * @since 5.1.0
18
  */
19
- class BP_Walker_Nav_Menu_Compat extends Walker_Nav_Menu {
20
  /**
21
  * Description of fields indexes for building markup.
22
  *
@@ -131,6 +130,20 @@ class BP_Walker_Nav_Menu_Compat extends Walker_Nav_Menu {
131
  return $output;
132
  }
133
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  /**
135
  * Display the current <li> that we are on.
136
  *
@@ -212,9 +225,3 @@ class BP_Walker_Nav_Menu_Compat extends Walker_Nav_Menu {
212
  $output .= apply_filters( 'bp_walker_nav_menu_start_el', $item_output, $item, $depth, $args );
213
  }
214
  }
215
-
216
- if ( PHP_VERSION_ID >= 50600 ) {
217
- require_once dirname( __DIR__ ) . '/compat/php56/class-bp-compat-walker-nav-menu.php';
218
- } else {
219
- require_once dirname( __DIR__ ) . '/compat/php53/class-bp-compat-walker-nav-menu.php';
220
- }
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
14
+ * Create HTML list of BP nav items.
 
15
  *
16
+ * @since 1.7.0
17
  */
18
+ class BP_Walker_Nav_Menu extends Walker_Nav_Menu {
19
  /**
20
  * Description of fields indexes for building markup.
21
  *
130
  return $output;
131
  }
132
 
133
+ /**
134
+ * Overrides Walker::walk() method.
135
+ *
136
+ * @since 6.0.0 Formalized the existing `...$args` parameter by adding it
137
+ * to the function signature to match WordPress 5.3.
138
+ *
139
+ * @param array $elements See {@link Walker::walk()}.
140
+ * @param int $max_depth See {@link Walker::walk()}.
141
+ * @param mixed ...$args See {@link Walker::walk()}.
142
+ */
143
+ public function walk( $elements, $max_depth, ...$args ) {
144
+ return $this->do_walk( $elements, $max_depth, $args );
145
+ }
146
+
147
  /**
148
  * Display the current <li> that we are on.
149
  *
225
  $output .= apply_filters( 'bp_walker_nav_menu_start_el', $item_output, $item, $depth, $args );
226
  }
227
  }
 
 
 
 
 
 
bp-core/classes/trait-attachments.php CHANGED
@@ -16,28 +16,126 @@ defined( 'ABSPATH' ) || exit;
16
  trait BP_REST_Attachments {
17
 
18
  /**
19
- * Returns the avatar object.
20
- *
21
- * @since 5.0.0
22
  *
23
- * @param array $args {
24
- * An array of arguments to build the Avatar object.
25
  *
26
- * @type string $full The url to the full version of the avatar.
27
- * @type string $thumb The url to the thumb version of the avatar.
28
- * }
29
- * @return object The avatar object.
30
  */
31
- protected function get_avatar_object( $args = array() ) {
32
- $avatar_object = array_intersect_key(
33
- $args,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  array(
35
- 'full' => '',
36
- 'thumb' => '',
37
  )
38
  );
39
 
40
- return (object) $avatar_object;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
42
 
43
  /**
@@ -49,16 +147,20 @@ trait BP_REST_Attachments {
49
  * @return stdClass|WP_Error
50
  */
51
  protected function upload_avatar_from_file( $files ) {
52
- $bp = buddypress();
53
 
54
  // Set global variables.
55
- if ( 'group' === $this->object ) {
56
- $bp->groups->current_group = $this->group;
57
- $upload_main_dir = 'groups_avatar_upload_dir';
58
- } else {
59
- $upload_main_dir = 'xprofile_avatar_upload_dir';
60
- $bp->displayed_user = new stdClass();
61
- $bp->displayed_user->id = (int) $this->user->ID;
 
 
 
 
 
62
  }
63
 
64
  $avatar_attachment = $this->avatar_instance;
@@ -69,7 +171,7 @@ trait BP_REST_Attachments {
69
  return new WP_Error(
70
  "bp_rest_attachments_{$this->object}_avatar_upload_error",
71
  sprintf(
72
- /* translators: %s is replaced with the error */
73
  __( 'Upload failed! Error was: %s.', 'buddypress' ),
74
  $avatar_original['error']
75
  ),
@@ -172,7 +274,7 @@ trait BP_REST_Attachments {
172
  return new WP_Error(
173
  "bp_rest_attachments_{$this->object}_avatar_upload_error",
174
  sprintf(
175
- /* translators: %s is replaced with error message. */
176
  __( 'Upload failed! Error was: %s', 'buddypress' ),
177
  $img_dir->get_error_message()
178
  ),
@@ -289,12 +391,50 @@ trait BP_REST_Attachments {
289
  }
290
  }
291
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
  /**
293
  * Get item id.
294
  *
 
 
295
  * @return int
296
  */
297
  protected function get_item_id() {
298
  return ( 'group' === $this->object ) ? $this->group->id : $this->user->ID;
299
  }
 
 
 
 
 
 
 
 
 
 
 
300
  }
16
  trait BP_REST_Attachments {
17
 
18
  /**
19
+ * Cover upload from file.
 
 
20
  *
21
+ * @since 6.0.0
 
22
  *
23
+ * @param array $file $_FILES superglobal.
24
+ * @return string|WP_Error
 
 
25
  */
26
+ protected function upload_cover_from_file( $file ) {
27
+
28
+ // Set global variables.
29
+ $bp = buddypress();
30
+ switch ( $this->object ) {
31
+ case 'group':
32
+ $bp->groups->current_group = $this->group;
33
+ break;
34
+ case 'user':
35
+ default:
36
+ $bp->displayed_user = new stdClass();
37
+ $bp->displayed_user->id = (int) $this->user->ID;
38
+ break;
39
+ }
40
+
41
+ // Try to upload image.
42
+ $uploaded_image = $this->attachment_instance->upload( $file );
43
+
44
+ // Bail with error.
45
+ if ( ! empty( $uploaded_image['error'] ) ) {
46
+ return new WP_Error(
47
+ "bp_rest_attachments_{$this->object}_cover_upload_error",
48
+ sprintf(
49
+ /* translators: %s: the upload error message */
50
+ __( 'Upload Failed! Error was: %s', 'buddypress' ),
51
+ $uploaded_image['error']
52
+ ),
53
+ array(
54
+ 'status' => 500,
55
+ )
56
+ );
57
+ }
58
+
59
+ $component = $this->get_cover_object_component();
60
+ $item_id = $this->get_item_id();
61
+ $bp_attachments_uploads_dir = bp_attachments_cover_image_upload_dir(
62
  array(
63
+ 'object_directory' => $component,
64
+ 'object_id' => $item_id,
65
  )
66
  );
67
 
68
+ // The BP Attachments Uploads Dir is not set, stop.
69
+ if ( ! $bp_attachments_uploads_dir ) {
70
+ return new WP_Error(
71
+ "bp_rest_attachments_{$this->object}_cover_upload_error",
72
+ __( 'The BuddyPress attachments uploads directory is not set.', 'buddypress' ),
73
+ array(
74
+ 'status' => 500,
75
+ )
76
+ );
77
+ }
78
+
79
+ $cover_subdir = $bp_attachments_uploads_dir['subdir'];
80
+ $cover_dir = $bp_attachments_uploads_dir['basedir'] . $cover_subdir;
81
+
82
+ // If upload path doesn't exist, stop.
83
+ if ( 0 !== validate_file( $cover_dir ) || ! is_dir( $cover_dir ) ) {
84
+ return new WP_Error(
85
+ "bp_rest_attachments_{$this->object}_cover_upload_error",
86
+ __( 'The cover image directory is not valid.', 'buddypress' ),
87
+ array(
88
+ 'status' => 500,
89
+ )
90
+ );
91
+ }
92
+
93
+ // Upload cover.
94
+ $cover = bp_attachments_cover_image_generate_file(
95
+ array(
96
+ 'file' => $uploaded_image['file'],
97
+ 'component' => $component,
98
+ 'cover_image_dir' => $cover_dir,
99
+ )
100
+ );
101
+
102
+ // Bail if any error happened.
103
+ if ( false === $cover ) {
104
+ return new WP_Error(
105
+ "bp_rest_attachments_{$this->object}_cover_upload_error",
106
+ __( 'There was a problem uploading the cover image.', 'buddypress' ),
107
+ array(
108
+ 'status' => 500,
109
+ )
110
+ );
111
+ }
112
+
113
+ // Bail with error if too small.
114
+ if ( true === $cover['is_too_small'] ) {
115
+
116
+ // Get cover image advised dimensions.
117
+ $cover_dimensions = bp_attachments_get_cover_image_dimensions( $component );
118
+
119
+ return new WP_Error(
120
+ "bp_rest_attachments_{$this->object}_cover_upload_error",
121
+ sprintf(
122
+ /* translators: %$1s and %$2s is replaced with the correct sizes. */
123
+ __( 'You have selected an image that is smaller than recommended. For better results, make sure to upload an image that is larger than %1$spx wide, and %2$spx tall.', 'buddypress' ),
124
+ (int) $cover_dimensions['width'],
125
+ (int) $cover_dimensions['height']
126
+ ),
127
+ array(
128
+ 'status' => 500,
129
+ )
130
+ );
131
+ }
132
+
133
+ return sprintf(
134
+ '%1$/%2$/%3$',
135
+ $bp_attachments_uploads_dir['baseurl'],
136
+ $cover_subdir,
137
+ $cover['cover_basename']
138
+ );
139
  }
140
 
141
  /**
147
  * @return stdClass|WP_Error
148
  */
149
  protected function upload_avatar_from_file( $files ) {
 
150
 
151
  // Set global variables.
152
+ $bp = buddypress();
153
+ switch ( $this->object ) {
154
+ case 'group':
155
+ $bp->groups->current_group = $this->group;
156
+ $upload_main_dir = 'groups_avatar_upload_dir';
157
+ break;
158
+ case 'user':
159
+ default:
160
+ $upload_main_dir = 'bp_members_avatar_upload_dir';
161
+ $bp->displayed_user = new stdClass();
162
+ $bp->displayed_user->id = (int) $this->user->ID;
163
+ break;
164
  }
165
 
166
  $avatar_attachment = $this->avatar_instance;
171
  return new WP_Error(
172
  "bp_rest_attachments_{$this->object}_avatar_upload_error",
173
  sprintf(
174
+ /* translators: %s: the upload error message */
175
  __( 'Upload failed! Error was: %s.', 'buddypress' ),
176
  $avatar_original['error']
177
  ),
274
  return new WP_Error(
275
  "bp_rest_attachments_{$this->object}_avatar_upload_error",
276
  sprintf(
277
+ /* translators: %s: the upload error message */
278
  __( 'Upload failed! Error was: %s', 'buddypress' ),
279
  $img_dir->get_error_message()
280
  ),
391
  }
392
  }
393
 
394
+ /**
395
+ * Returns the avatar object.
396
+ *
397
+ * @since 6.0.0
398
+ *
399
+ * @param array $args {
400
+ * An array of arguments to build the Avatar object.
401
+ *
402
+ * @type string $full The url to the full version of the avatar.
403
+ * @type string $thumb The url to the thumb version of the avatar.
404
+ * }
405
+ * @return object The avatar object.
406
+ */
407
+ protected function get_avatar_object( $args = array() ) {
408
+ $avatar_object = array_intersect_key(
409
+ $args,
410
+ array(
411
+ 'full' => '',
412
+ 'thumb' => '',
413
+ )
414
+ );
415
+
416
+ return (object) $avatar_object;
417
+ }
418
+
419
  /**
420
  * Get item id.
421
  *
422
+ * @since 5.0.0
423
+ *
424
  * @return int
425
  */
426
  protected function get_item_id() {
427
  return ( 'group' === $this->object ) ? $this->group->id : $this->user->ID;
428
  }
429
+
430
+ /**
431
+ * Get cover object component.
432
+ *
433
+ * @since 6.0.0
434
+ *
435
+ * @return string
436
+ */
437
+ protected function get_cover_object_component() {
438
+ return ( 'group' === $this->object ) ? 'groups' : 'members';
439
+ }
440
  }
bp-core/compat/php53/class-bp-compat-walker-nav-menu.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
- /**
3
- * Walker_Nav_Menu Compat for PHP 5.3 and UP.
4
- *
5
- * @package BuddyPress
6
- * @subpackage Core
7
- * @since 5.1.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Create HTML list of BP nav items.
15
- *
16
- * @since 1.7.0
17
- */
18
- class BP_Walker_Nav_Menu extends BP_Walker_Nav_Menu_Compat {
19
- /**
20
- * Compat method to extend Walker_Nav_Menu::walk() in PHP < 5.6.
21
- *
22
- * @since 5.1.0
23
- *
24
- * @param array $elements See {@link Walker::walk()}.
25
- * @param int $max_depth See {@link Walker::walk()}.
26
- */
27
- public function walk( $elements, $max_depth ) {
28
- $args = array_slice( func_get_args(), 2 );
29
-
30
- return $this->do_walk( $elements, $max_depth, $args );
31
- }
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core/compat/php56/class-bp-compat-walker-nav-menu.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
- /**
3
- * Walker_Nav_Menu Compat for PHP 5.6 and UP.
4
- *
5
- * @package BuddyPress
6
- * @subpackage Core
7
- * @since 5.1.0
8
- */
9
-
10
- // Exit if accessed directly.
11
- defined( 'ABSPATH' ) || exit;
12
-
13
- /**
14
- * Create HTML list of BP nav items.
15
- *
16
- * @since 1.7.0
17
- */
18
- class BP_Walker_Nav_Menu extends BP_Walker_Nav_Menu_Compat {
19
- /**
20
- * Compat method to extend Walker_Nav_Menu::walk() in PHP > 5.6.
21
- *
22
- * @since 5.1.0
23
- *
24
- * @param array $elements See {@link Walker::walk()}.
25
- * @param int $max_depth See {@link Walker::walk()}.
26
- * @param mixed ...$args See {@link Walker::walk()}.
27
- */
28
- public function walk( $elements, $max_depth, ...$args ) { // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ellipsisFound
29
- return $this->do_walk( $elements, $max_depth, $args );
30
- }
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bp-core/deprecated/1.2.php CHANGED
@@ -22,23 +22,23 @@ function bp_activity_get_sitewide( $args = '' ) {
22
  _deprecated_function( __FUNCTION__, '1.2', 'bp_activity_get()' );
23
 
24
  $defaults = array(
25
- 'max' => false, // Maximum number of results to return
26
- 'page' => 1, // page 1 without a per_page will result in no pagination.
27
- 'per_page' => false, // results per page
28
- 'sort' => 'DESC', // sort ASC or DESC
29
- 'display_comments' => false, // false for no comments. 'stream' for within stream display, 'threaded' for below each activity item
30
 
31
- 'search_terms' => false, // Pass search terms as a string
32
- 'show_hidden' => false, // Show activity items that are hidden site-wide?
33
 
34
  /**
35
  * Pass filters as an array:
36
  * array(
37
- * 'user_id' => false, // user_id to filter on
38
- * 'object' => false, // object to filter on e.g. groups, profile, status, friends
39
- * 'action' => false, // action to filter on e.g. new_wire_post, new_forum_post, profile_updated
40
- * 'primary_id' => false, // object ID to filter on e.g. a group_id or forum_id or blog_id etc.
41
- * 'secondary_id' => false, // secondary object ID to filter on e.g. a post_id
42
  * );
43
  */
44
  'filter' => array()
22
  _deprecated_function( __FUNCTION__, '1.2', 'bp_activity_get()' );
23
 
24
  $defaults = array(
25
+ 'max' => false, // Maximum number of results to return.
26
+ 'page' => 1, // Page 1 without a per_page will result in no pagination.
27
+ 'per_page' => false, // Results per page.
28
+ 'sort' => 'DESC', // Sort ASC or DESC.
29
+ 'display_comments' => false, // False for no comments. 'stream' for within stream display, 'threaded' for below each activity item.
30
 
31
+ 'search_terms' => false, // Pass search terms as a string.
32
+ 'show_hidden' => false, // Show activity items that are hidden site-wide?
33
 
34
  /**
35
  * Pass filters as an array:
36
  * array(
37
+ * 'user_id' => false, // user_id to filter on.
38
+ * 'object' => false, // Object to filter on e.g. groups, profile, status, friends.
39
+ * 'action' => false, // Action to filter on e.g. new_wire_post, new_forum_post, profile_updated.
40
+ * 'primary_id' => false, // Object ID to filter on e.g. a group_id or forum_id or blog_id etc.
41
+ * 'secondary_id' => false, // Secondary object ID to filter on e.g. a post_id.
42
  * );
43
  */
44
  'filter' => array()
bp-core/deprecated/1.5.php CHANGED
@@ -7,7 +7,7 @@
7
  * @deprecated Since 1.5.0
8
  */
9
 
10
- // Exit if accessed directly
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /** Loader ********************************************************************/
@@ -74,7 +74,7 @@ if ( !function_exists( 'is_site_admin' ) ) {
74
 
75
  /**
76
  * In BuddyPress 1.1 - 1.2.x, this function provided a better version of add_menu_page()
77
- * that allowed positioning of menus. Deprecated in 1.5 in favour of a WP core function.
78
  *
79
  * @deprecated 1.5.0
80
  * @deprecated Use add_menu_page().
@@ -341,7 +341,7 @@ function groups_at_message_notification( $content, $poster_user_id, $group_id, $
341
  if ( !groups_is_user_member( $receiver_user_id, $group_id ) )
342
  continue;
343
 
344
- // Now email the user with the contents of the message (if they have enabled email notifications)
345
  if ( 'no' != bp_get_user_meta( $receiver_user_id, 'notification_activity_new_mention', true ) ) {
346
  $poster_name = bp_core_get_user_displayname( $poster_user_id );
347
 
@@ -352,12 +352,22 @@ function groups_at_message_notification( $content, $poster_user_id, $group_id, $
352
  $poster_name = stripslashes( $poster_name );
353
  $content = bp_groups_filter_kses( stripslashes( $content ) );
354
 
355
- // Set up and send the message
356
  $ud = bp_core_get_core_userdata( $receiver_user_id );
357
  $to = $ud->user_email;
358
- $subject = bp_get_email_subject( array( 'text' => sprintf( __( '%1$s mentioned you in the group "%2$s"', 'buddypress' ), $poster_name, $group->name ) ) );
359
-
360
- $message = sprintf( __(
 
 
 
 
 
 
 
 
 
 
361
  '%1$s mentioned you in the group "%2$s":
362
 
363
  "%3$s"
@@ -365,7 +375,7 @@ $message = sprintf( __(
365
  To view and respond to the message, log in and visit: %4$s
366
 
367
  ---------------------
368
- ', 'buddypress' ), $poster_name, $group->name, $content, $message_link );
369
 
370
  /* Send the message */
371
  $to = apply_filters( 'groups_at_message_notification_to', $to );
7
  * @deprecated Since 1.5.0
8
  */
9
 
10
+ // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /** Loader ********************************************************************/
74
 
75
  /**
76
  * In BuddyPress 1.1 - 1.2.x, this function provided a better version of add_menu_page()
77
+ * that allowed positioning of menus. Deprecated in 1.5 in favor of a WP core function.
78
  *
79
  * @deprecated 1.5.0
80
  * @deprecated Use add_menu_page().
341
  if ( !groups_is_user_member( $receiver_user_id, $group_id ) )
342
  continue;
343
 
344
+ // Now email the user with the contents of the message (if they have enabled email notifications).
345
  if ( 'no' != bp_get_user_meta( $receiver_user_id, 'notification_activity_new_mention', true ) ) {
346
  $poster_name = bp_core_get_user_displayname( $poster_user_id );
347
 
352
  $poster_name = stripslashes( $poster_name );
353
  $content = bp_groups_filter_kses( stripslashes( $content ) );
354
 
355
+ // Set up and send the message.
356
  $ud = bp_core_get_core_userdata( $receiver_user_id );
357
  $to = $ud->user_email;
358
+ $subject = bp_get_email_subject(
359
+ array(
360
+ 'text' => sprintf(
361
+ /* translators: 1: the poster name. 2: the group name. */
362
+ _x( '%1$s mentioned you in the group "%2$s"', 'deprecated string', 'buddypress' ),
363
+ $poster_name,
364
+ $group->name
365
+ )
366
+ )
367
+ );
368
+
369
+ /* translators: 1: the poster name. 2: the group name. 3: the content of the activity. 4: the activity permalink. */
370
+ $message = sprintf( _x(
371
  '%1$s mentioned you in the group "%2$s":
372
 
373
  "%3$s"
375
  To view and respond to the message, log in and visit: %4$s
376
 
377
  ---------------------
378
+ ', 'deprecated string', 'buddypress' ), $poster_name, $group->name, $content, $message_link );
379
 
380
  /* Send the message */
381
  $to = apply_filters( 'groups_at_message_notification_to', $to );
bp-core/deprecated/1.6.php CHANGED
@@ -7,7 +7,7 @@
7
  * @deprecated 1.6.0
8
  */
9
 
10
- // Exit if accessed directly
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /** Toolbar functions *********************************************************/
@@ -224,16 +224,16 @@ if ( !function_exists( 'bp_dtheme_register_actions' ) ) :
224
  function bp_die_legacy_ajax_callbacks() {
225
 
226
  // This is a list of the BP wp_ajax_ hook suffixes whose associated functions did
227
- // not die properly before BP 1.6
228
  $actions = array(
229
- // Directory template loaders
230
  'members_filter',
231
  'groups_filter',
232
  'blogs_filter',
233
  'forums_filter',
234
  'messages_filter',
235
 
236
- // Activity
237
  'activity_widget_filter',
238
  'activity_get_older_updates',
239
  'post_update',
@@ -245,16 +245,16 @@ if ( !function_exists( 'bp_dtheme_register_actions' ) ) :
245
  'activity_mark_fav',
246
  'activity_mark_unfav',
247
 
248
- // Groups
249
  'groups_invite_user',
250
  'joinleave_group',
251
 
252
- // Members
253
  'addremove_friend',
254
  'accept_friendship',
255
  'reject_friendship',
256
 
257
- // Messages
258
  'messages_close_notice',
259
  'messages_send_reply',
260
  'messages_markunread',
@@ -263,7 +263,7 @@ if ( !function_exists( 'bp_dtheme_register_actions' ) ) :
263
  'messages_autocomplete_results'
264
  );
265
 
266
- // For each of the problematic hooks, exit at the very end of execution
267
  foreach( $actions as $action ) {
268
  add_action( 'wp_ajax_' . $action, function() {
269
  exit;
7
  * @deprecated 1.6.0
8
  */
9
 
10
+ // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /** Toolbar functions *********************************************************/
224
  function bp_die_legacy_ajax_callbacks() {
225
 
226
  // This is a list of the BP wp_ajax_ hook suffixes whose associated functions did
227
+ // not die properly before BP 1.6.
228
  $actions = array(
229
+ // Directory template loaders.
230
  'members_filter',
231
  'groups_filter',
232
  'blogs_filter',
233
  'forums_filter',
234
  'messages_filter',
235
 
236
+ // Activity.
237
  'activity_widget_filter',
238
  'activity_get_older_updates',
239
  'post_update',
245
  'activity_mark_fav',
246
  'activity_mark_unfav',
247
 
248
+ // Groups.
249
  'groups_invite_user',
250
  'joinleave_group',
251
 
252
+ // Members.
253
  'addremove_friend',
254
  'accept_friendship',
255
  'reject_friendship',
256
 
257
+ // Messages.
258
  'messages_close_notice',
259
  'messages_send_reply',
260
  'messages_markunread',
263
  'messages_autocomplete_results'
264
  );
265
 
266
+ // For each of the problematic hooks, exit at the very end of execution.
267
  foreach( $actions as $action ) {
268
  add_action( 'wp_ajax_' . $action, function() {
269
  exit;
bp-core/deprecated/1.7.php CHANGED
@@ -7,7 +7,7 @@
7
  * @deprecated Since 1.7.0
8
  */
9
 
10
- // Exit if accessed directly
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
@@ -153,7 +153,7 @@ function bp_update_db_stuff() {
153
  bp_core_add_illegal_names();
154
  }
155
 
156
- // Update and remove the message threads table if it exists
157
  if ( $wpdb->get_var( "SHOW TABLES LIKE '%{$bp_prefix}bp_messages_threads%'" ) ) {
158
  if ( BP_Messages_Thread::update_tables() ) {
159
  $wpdb->query( "DROP TABLE {$bp_prefix}bp_messages_threads" );
7
  * @deprecated Since 1.7.0
8
  */
9
 
10
+ // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
153
  bp_core_add_illegal_names();
154
  }
155
 
156
+ // Update and remove the message threads table if it exists.
157
  if ( $wpdb->get_var( "SHOW TABLES LIKE '%{$bp_prefix}bp_messages_threads%'" ) ) {
158
  if ( BP_Messages_Thread::update_tables() ) {
159
  $wpdb->query( "DROP TABLE {$bp_prefix}bp_messages_threads" );
bp-core/deprecated/1.9.php CHANGED
@@ -9,7 +9,7 @@
9
  * @subpackage MembersNotifications
10
  */
11
 
12
- // Exit if accessed directly
13
  defined( 'ABSPATH' ) || exit;
14
 
15
  /**
@@ -30,20 +30,20 @@ defined( 'ABSPATH' ) || exit;
30
  */
31
  function bp_core_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false, $is_new = 1 ) {
32
 
33
- // Bail if notifications is not active
34
  if ( ! bp_is_active( 'notifications' ) ) {
35
  return false;
36
  }
37
 
38
- // Trigger the deprecated function notice
39
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_add_notification()' );
40
 
41
- // Notifications must always have a time
42
  if ( false === $date_notified ) {
43
  $date_notified = bp_core_current_time();
44
  }
45
 
46
- // Add the notification
47
  return bp_notifications_add_notification( array(
48
  'item_id' => $item_id,
49
  'user_id' => $user_id,
@@ -68,12 +68,12 @@ function bp_core_add_notification( $item_id, $user_id, $component_name, $compone
68
  */
69
  function bp_core_delete_notification( $id ) {
70
 
71
- // Bail if notifications is not active
72
  if ( ! bp_is_active( 'notifications' ) ) {
73
  return false;
74
  }
75
 
76
- // Trigger the deprecated function notice
77
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notification()' );
78
 
79
  return BP_Notifications_Notification::delete_by_id( $id );
@@ -91,12 +91,12 @@ function bp_core_delete_notification( $id ) {
91
  */
92
  function bp_core_get_notification( $id ) {
93
 
94
- // Bail if notifications is not active
95
  if ( ! bp_is_active( 'notifications' ) ) {
96
  return false;
97
  }
98
 
99
- // Trigger the deprecated function notice
100
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_get_notification()' );
101
 
102
  return bp_notifications_get_notification( $id );
@@ -115,12 +115,12 @@ function bp_core_get_notification( $id ) {
115
  */
116
  function bp_core_get_notifications_for_user( $user_id, $format = 'string' ) {
117
 
118
- // Bail if notifications is not active
119
  if ( ! bp_is_active( 'notifications' ) ) {
120
  return false;
121
  }
122
 
123
- // Trigger the deprecated function notice
124
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_get_notifications_for_user()' );
125
 
126
  return bp_notifications_get_notifications_for_user( $user_id, $format );
@@ -145,12 +145,12 @@ function bp_core_get_notifications_for_user( $user_id, $format = 'string' ) {
145
  */
146
  function bp_core_delete_notifications_by_type( $user_id, $component_name, $component_action ) {
147
 
148
- // Bail if notifications is not active
149
  if ( ! bp_is_active( 'notifications' ) ) {
150
  return false;
151
  }
152
 
153
- // Trigger the deprecated function notice
154
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_by_type()' );
155
 
156
  return bp_notifications_delete_notifications_by_type( $user_id, $component_name, $component_action );
@@ -174,12 +174,12 @@ function bp_core_delete_notifications_by_type( $user_id, $component_name, $compo
174
  */
175
  function bp_core_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false ) {
176
 
177
- // Bail if notifications is not active
178
  if ( ! bp_is_active( 'notifications' ) ) {
179
  return false;
180
  }
181
 
182
- // Trigger the deprecated function notice
183
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_by_item_id()' );
184
 
185
  return bp_notifications_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id );
@@ -200,12 +200,12 @@ function bp_core_delete_notifications_by_item_id( $user_id, $item_id, $component
200
  */
201
  function bp_core_delete_all_notifications_by_type( $item_id, $component_name, $component_action = false, $secondary_item_id = false ) {
202
 
203
- // Bail if notifications is not active
204
  if ( ! bp_is_active( 'notifications' ) ) {
205
  return false;
206
  }
207
 
208
- // Trigger the deprecated function notice
209
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_all_notifications_by_type()' );
210
 
211
  bp_notifications_delete_all_notifications_by_type( $item_id, $component_name, $component_action, $secondary_item_id );
@@ -214,7 +214,7 @@ function bp_core_delete_all_notifications_by_type( $item_id, $component_name, $c
214
  /**
215
  * Delete all notifications for a user.
216
  *
217
- * Used when clearing out all notifications for a user, when deleted or spammed
218
  *
219
  * @deprecated Deprecated since BuddyPress 1.9.0. Use
220
  * bp_notifications_delete_notifications_from_user() instead.
@@ -227,12 +227,12 @@ function bp_core_delete_all_notifications_by_type( $item_id, $component_name, $c
227
  */
228
  function bp_core_delete_notifications_from_user( $user_id, $component_name, $component_action ) {
229
 
230
- // Bail if notifications is not active
231
  if ( ! bp_is_active( 'notifications' ) ) {
232
  return false;
233
  }
234
 
235
- // Trigger the deprecated function notice
236
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_from_user()' );
237
 
238
  return bp_notifications_delete_notifications_from_user( $user_id, $component_name, $component_action );
@@ -255,12 +255,12 @@ function bp_core_delete_notifications_from_user( $user_id, $component_name, $com
255
  */
256
  function bp_core_check_notification_access( $user_id, $notification_id ) {
257
 
258
- // Bail if notifications is not active
259
  if ( ! bp_is_active( 'notifications' ) ) {
260
  return false;
261
  }
262
 
263
- // Trigger the deprecated function notice
264
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_check_notification_access()' );
265
 
266
  return bp_notifications_check_notification_access( $user_id, $notification_id );
9
  * @subpackage MembersNotifications
10
  */
11
 
12
+ // Exit if accessed directly.
13
  defined( 'ABSPATH' ) || exit;
14
 
15
  /**
30
  */
31
  function bp_core_add_notification( $item_id, $user_id, $component_name, $component_action, $secondary_item_id = 0, $date_notified = false, $is_new = 1 ) {
32
 
33
+ // Bail if notifications is not active.
34
  if ( ! bp_is_active( 'notifications' ) ) {
35
  return false;
36
  }
37
 
38
+ // Trigger the deprecated function notice.
39
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_add_notification()' );
40
 
41
+ // Notifications must always have a time.
42
  if ( false === $date_notified ) {
43
  $date_notified = bp_core_current_time();
44
  }
45
 
46
+ // Add the notification.
47
  return bp_notifications_add_notification( array(
48
  'item_id' => $item_id,
49
  'user_id' => $user_id,
68
  */
69
  function bp_core_delete_notification( $id ) {
70
 
71
+ // Bail if notifications is not active.
72
  if ( ! bp_is_active( 'notifications' ) ) {
73
  return false;
74
  }
75
 
76
+ // Trigger the deprecated function notice.
77
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notification()' );
78
 
79
  return BP_Notifications_Notification::delete_by_id( $id );
91
  */
92
  function bp_core_get_notification( $id ) {
93
 
94
+ // Bail if notifications is not active.
95
  if ( ! bp_is_active( 'notifications' ) ) {
96
  return false;
97
  }
98
 
99
+ // Trigger the deprecated function notice.
100
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_get_notification()' );
101
 
102
  return bp_notifications_get_notification( $id );
115
  */
116
  function bp_core_get_notifications_for_user( $user_id, $format = 'string' ) {
117
 
118
+ // Bail if notifications is not active.
119
  if ( ! bp_is_active( 'notifications' ) ) {
120
  return false;
121
  }
122
 
123
+ // Trigger the deprecated function notice.
124
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_get_notifications_for_user()' );
125
 
126
  return bp_notifications_get_notifications_for_user( $user_id, $format );
145
  */
146
  function bp_core_delete_notifications_by_type( $user_id, $component_name, $component_action ) {
147
 
148
+ // Bail if notifications is not active.
149
  if ( ! bp_is_active( 'notifications' ) ) {
150
  return false;
151
  }
152
 
153
+ // Trigger the deprecated function notice.
154
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_by_type()' );
155
 
156
  return bp_notifications_delete_notifications_by_type( $user_id, $component_name, $component_action );
174
  */
175
  function bp_core_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id = false ) {
176
 
177
+ // Bail if notifications is not active.
178
  if ( ! bp_is_active( 'notifications' ) ) {
179
  return false;
180
  }
181
 
182
+ // Trigger the deprecated function notice.
183
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_by_item_id()' );
184
 
185
  return bp_notifications_delete_notifications_by_item_id( $user_id, $item_id, $component_name, $component_action, $secondary_item_id );
200
  */
201
  function bp_core_delete_all_notifications_by_type( $item_id, $component_name, $component_action = false, $secondary_item_id = false ) {
202
 
203
+ // Bail if notifications is not active.
204
  if ( ! bp_is_active( 'notifications' ) ) {
205
  return false;
206
  }
207
 
208
+ // Trigger the deprecated function notice.
209
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_all_notifications_by_type()' );
210
 
211
  bp_notifications_delete_all_notifications_by_type( $item_id, $component_name, $component_action, $secondary_item_id );
214
  /**
215
  * Delete all notifications for a user.
216
  *
217
+ * Used when clearing out all notifications for a user, when deleted or spammed.
218
  *
219
  * @deprecated Deprecated since BuddyPress 1.9.0. Use
220
  * bp_notifications_delete_notifications_from_user() instead.
227
  */
228
  function bp_core_delete_notifications_from_user( $user_id, $component_name, $component_action ) {
229
 
230
+ // Bail if notifications is not active.
231
  if ( ! bp_is_active( 'notifications' ) ) {
232
  return false;
233
  }
234
 
235
+ // Trigger the deprecated function notice.
236
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_delete_notifications_from_user()' );
237
 
238
  return bp_notifications_delete_notifications_from_user( $user_id, $component_name, $component_action );
255
  */
256
  function bp_core_check_notification_access( $user_id, $notification_id ) {
257
 
258
+ // Bail if notifications is not active.
259
  if ( ! bp_is_active( 'notifications' ) ) {
260
  return false;
261
  }
262
 
263
+ // Trigger the deprecated function notice.
264
  _deprecated_function( __FUNCTION__, '1.9', 'bp_notifications_check_notification_access()' );
265
 
266
  return bp_notifications_check_notification_access( $user_id, $notification_id );
bp-core/deprecated/2.0.php CHANGED
@@ -7,7 +7,7 @@
7
  * @deprecated 2.0.0
8
  */
9
 
10
- // Exit if accessed directly
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
7
  * @deprecated 2.0.0
8
  */
9
 
10
+ // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
bp-core/deprecated/2.1.php CHANGED
@@ -7,7 +7,7 @@
7
  * @deprecated 2.1.0
8
  */
9
 
10
- // Exit if accessed directly
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
@@ -189,7 +189,7 @@ function bp_adminbar_login_menu() {
189
 
190
  echo '<li class="bp-login no-arrow"><a href="' . wp_login_url() . '">' . __( 'Log In', 'buddypress' ) . '</a></li>';
191
 
192
- // Show "Sign Up" link if user registrations are allowed
193
  if ( bp_get_signup_allowed() ) {
194
  echo '<li class="bp-signup no-arrow"><a href="' . bp_get_signup_page() . '">' . __( 'Sign Up', 'buddypress' ) . '</a></li>';
195
  }
@@ -213,7 +213,7 @@ function bp_adminbar_account_menu() {
213
  echo __( 'My Account', 'buddypress' ) . '</a>';
214
  echo '<ul>';
215
 
216
- // Loop through each navigation item
217
  $counter = 0;
218
  foreach( (array) $bp->bp_nav as $nav_item ) {
219
  $alt = ( 0 == $counter % 2 ) ? ' class="alt"' : '';
@@ -326,7 +326,7 @@ function bp_core_load_buddybar_css() {
326
 
327
  $min = bp_core_get_minified_asset_suffix();
328
 
329
- if ( file_exists( get_stylesheet_directory() . '/_inc/css/adminbar.css' ) ) { // Backwards compatibility
330
  $stylesheet = get_stylesheet_directory_uri() . '/_inc/css/adminbar.css';
331
  } else {
332
  $stylesheet = buddypress()->plugin_url . "bp-core/css/buddybar{$min}.css";
@@ -355,7 +355,7 @@ function bp_groups_adminbar_admin_menu() {
355
  return false;
356
  }
357
 
358
- // Only group admins and site admins can see this menu
359
  if ( !current_user_can( 'edit_users' ) && !bp_current_user_can( 'bp_moderate' ) && !bp_is_item_admin() ) {
360
  return false;
361
  } ?>
@@ -406,7 +406,7 @@ add_action( 'bp_adminbar_menus', 'bp_groups_adminbar_admin_menu', 20 );
406
  */
407
  function bp_adminbar_notifications_menu() {
408
 
409
- // Bail if notifications is not active
410
  if ( ! bp_is_active( 'notifications' ) ) {
411
  return false;
412
  }
@@ -423,12 +423,12 @@ add_action( 'bp_adminbar_menus', 'bp_adminbar_notifications_menu', 8 );
423
  function bp_adminbar_authors_menu() {
424
  global $wpdb;
425
 
426
- // Only for multisite
427
  if ( ! is_multisite() ) {
428
  return false;
429
  }
430
 
431
- // Hide on root blog
432
  if ( bp_is_root_blog( $wpdb->blogid ) || ! bp_is_active( 'blogs' ) ) {
433
  return false;
434
  }
@@ -437,7 +437,7 @@ function bp_adminbar_authors_menu() {
437
  $authors = $wpdb->get_results( "SELECT user_id, user_login, user_nicename, display_name, user_email, meta_value as caps FROM $wpdb->users u, $wpdb->usermeta um WHERE u.ID = um.user_id AND meta_key = '{$blog_prefix}capabilities' ORDER BY um.user_id" );
438
 
439
  if ( !empty( $authors ) ) {
440
- // This is a blog, render a menu with links to all authors
441
  echo '<li id="bp-adminbar-authors-menu"><a href="/">';
442
  _e('Blog Authors', 'buddypress');
443
  echo '</a>';
@@ -456,7 +456,11 @@ function bp_adminbar_authors_menu() {
456
  'email' => $author->user_email,
457
  'width' => 15,
458
  'height' => 15,
459
- 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), $author->display_name )
 
 
 
 
460
  ) );
461
  echo ' ' . $author->display_name . '</a>';
462
  echo '<div class="admin-bar-clear"></div>';
@@ -478,12 +482,12 @@ add_action( 'bp_adminbar_menus', 'bp_adminbar_authors_menu', 12 );
478
  */
479
  function bp_members_adminbar_admin_menu() {
480
 
481
- // Only show if viewing a user
482
  if ( ! bp_displayed_user_id() ) {
483
  return false;
484
  }
485
 
486
- // Don't show this menu to non site admins or if you're viewing your own profile
487
  if ( !current_user_can( 'edit_users' ) || bp_is_my_profile() ) {
488
  return false;
489
  } ?>
@@ -495,15 +499,36 @@ function bp_members_adminbar_admin_menu() {
495
  <ul>
496
  <?php if ( bp_is_active( 'xprofile' ) ) : ?>
497
 
498
- <li><a href="<?php bp_members_component_link( 'profile', 'edit' ); ?>"><?php printf( __( "Edit %s's Profile", 'buddypress' ), esc_attr( bp_get_displayed_user_fullname() ) ) ?></a></li>
 
 
 
 
 
 
 
499
 
500
  <?php endif ?>
501
 
502
- <li><a href="<?php bp_members_component_link( 'profile', 'change-avatar' ); ?>"><?php printf( __( "Edit %s's Profile Photo", 'buddypress' ), esc_attr( bp_get_displayed_user_fullname() ) ) ?></a></li>
 
 
 
 
 
 
 
503
 
504
  <li><a href="<?php bp_members_component_link( 'settings', 'capabilities' ); ?>"><?php _e( 'User Capabilities', 'buddypress' ); ?></a></li>
505
 
506
- <li><a href="<?php bp_members_component_link( 'settings', 'delete-account' ); ?>"><?php printf( __( "Delete %s's Account", 'buddypress' ), esc_attr( bp_get_displayed_user_fullname() ) ); ?></a></li>
 
 
 
 
 
 
 
507
 
508
  <?php do_action( 'bp_members_adminbar_admin_menu' ) ?>
509
 
7
  * @deprecated 2.1.0
8
  */
9
 
10
+ // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
189
 
190
  echo '<li class="bp-login no-arrow"><a href="' . wp_login_url() . '">' . __( 'Log In', 'buddypress' ) . '</a></li>';
191
 
192
+ // Show "Sign Up" link if user registrations are allowed.
193
  if ( bp_get_signup_allowed() ) {
194
  echo '<li class="bp-signup no-arrow"><a href="' . bp_get_signup_page() . '">' . __( 'Sign Up', 'buddypress' ) . '</a></li>';
195
  }
213
  echo __( 'My Account', 'buddypress' ) . '</a>';
214
  echo '<ul>';
215
 
216
+ // Loop through each navigation item.
217
  $counter = 0;
218
  foreach( (array) $bp->bp_nav as $nav_item ) {
219
  $alt = ( 0 == $counter % 2 ) ? ' class="alt"' : '';
326
 
327
  $min = bp_core_get_minified_asset_suffix();
328
 
329
+ if ( file_exists( get_stylesheet_directory() . '/_inc/css/adminbar.css' ) ) { // Backwards compatibility.
330
  $stylesheet = get_stylesheet_directory_uri() . '/_inc/css/adminbar.css';
331
  } else {
332
  $stylesheet = buddypress()->plugin_url . "bp-core/css/buddybar{$min}.css";
355
  return false;
356
  }
357
 
358
+ // Only group admins and site admins can see this menu.
359
  if ( !current_user_can( 'edit_users' ) && !bp_current_user_can( 'bp_moderate' ) && !bp_is_item_admin() ) {
360
  return false;
361
  } ?>
406
  */
407
  function bp_adminbar_notifications_menu() {
408
 
409
+ // Bail if notifications is not active.
410
  if ( ! bp_is_active( 'notifications' ) ) {
411
  return false;
412
  }
423
  function bp_adminbar_authors_menu() {
424
  global $wpdb;
425
 
426
+ // Only for multisite.
427
  if ( ! is_multisite() ) {
428
  return false;
429
  }
430
 
431
+ // Hide on root blog.
432
  if ( bp_is_root_blog( $wpdb->blogid ) || ! bp_is_active( 'blogs' ) ) {
433
  return false;
434
  }
437
  $authors = $wpdb->get_results( "SELECT user_id, user_login, user_nicename, display_name, user_email, meta_value as caps FROM $wpdb->users u, $wpdb->usermeta um WHERE u.ID = um.user_id AND meta_key = '{$blog_prefix}capabilities' ORDER BY um.user_id" );
438
 
439
  if ( !empty( $authors ) ) {
440
+ // This is a blog, render a menu with links to all authors.
441
  echo '<li id="bp-adminbar-authors-menu"><a href="/">';
442
  _e('Blog Authors', 'buddypress');
443
  echo '</a>';
456
  'email' => $author->user_email,
457
  'width' => 15,
458
  'height' => 15,
459
+ 'alt' => sprintf(
460
+ /* translators: %s: member name */
461
+ __( 'Profile picture of %s', 'buddypress' ),
462
+ $author->display_name
463
+ ),
464
  ) );
465
  echo ' ' . $author->display_name . '</a>';
466
  echo '<div class="admin-bar-clear"></div>';
482
  */
483
  function bp_members_adminbar_admin_menu() {
484
 
485
+ // Only show if viewing a user.
486
  if ( ! bp_displayed_user_id() ) {
487
  return false;
488
  }
489
 
490
+ // Don't show this menu to non site admins or if you're viewing your own profile.
491
  if ( !current_user_can( 'edit_users' ) || bp_is_my_profile() ) {
492
  return false;
493
  } ?>
499
  <ul>
500
  <?php if ( bp_is_active( 'xprofile' ) ) : ?>
501
 
502
+ <li>
503
+ <a href="<?php bp_members_component_link( 'profile', 'edit' ); ?>">
504
+ <?php
505
+ /* translators: %s: member name */
506
+ printf( __( "Edit %s's Profile", 'buddypress' ), esc_attr( bp_get_displayed_user_fullname() ) );
507
+ ?>
508
+ </a>
509
+ </li>
510
 
511
  <?php endif ?>
512
 
513
+ <li>
514
+ <a href="<?php bp_members_component_link( 'profile', 'change-avatar' ); ?>">
515
+ <?php
516
+ /* translators: %s: member name */
517
+ printf( _x( "Edit %s's Profile Photo", 'deprecated string', 'buddypress' ), esc_attr( bp_get_displayed_user_fullname() ) );
518
+ ?>
519
+ </a>
520
+ </li>
521
 
522
  <li><a href="<?php bp_members_component_link( 'settings', 'capabilities' ); ?>"><?php _e( 'User Capabilities', 'buddypress' ); ?></a></li>
523
 
524
+ <li>
525
+ <a href="<?php bp_members_component_link( 'settings', 'delete-account' ); ?>">
526
+ <?php
527
+ /* translators: %s: member name */
528
+ printf( _x( "Delete %s's Account", 'deprecated string', 'buddypress' ), esc_attr( bp_get_displayed_user_fullname() ) );
529
+ ?>
530
+ </a>
531
+ </li>
532
 
533
  <?php do_action( 'bp_members_adminbar_admin_menu' ) ?>
534
 
bp-core/deprecated/2.2.php CHANGED
@@ -7,7 +7,7 @@
7
  * @deprecated 2.2.0
8
  */
9
 
10
- // Exit if accessed directly
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
@@ -22,7 +22,7 @@ defined( 'ABSPATH' ) || exit;
22
  * @since 2.0.0
23
  * @deprecated 2.2.0
24
  *
25
- * @todo Support untrashing better
26
  *
27
  * @param string $new_status New status for the post.
28
  * @param string $old_status Old status for the post.
@@ -96,7 +96,7 @@ function bp_xprofile_format_activity_action_new_member( $action, $activity ) {
96
  }
97
 
98
  /**
99
- * Add 'bp' to global group of network wide cachable objects.
100
  *
101
  * @since 1.1.0
102
  * @deprecated 2.2.0
7
  * @deprecated 2.2.0
8
  */
9
 
10
+ // Exit if accessed directly.
11
  defined( 'ABSPATH' ) || exit;
12
 
13
  /**
22
  * @since 2.0.0
23
  * @deprecated 2.2.0
24
  *
25
+ * @todo Support untrashing better.
26
  *
27
  * @param string $new_status New status for the post.
28
  * @param string $old_status Old status for the post.
96
  }
97
 
98
  /**
99
+ * Add 'bp' to global group of network wide catchable objects.
100
  *
101
  * @since 1.1.0
102
  * @deprecated 2.2.0
bp-core/deprecated/2.5.php CHANGED
@@ -79,8 +79,8 @@ function bp_core_deprecated_email_filters( $value, $property, $transform, $email
79
  $to_changed = true;
80
 
81
  $value = array_shift( $original_value );
82
- $recipient_name = $value->get_name(); // Value - name
83
- $value = $value->get_address(); // Key - email
84
  }
85
 
86
  if ( $email_type === 'activity-comment' ) {
79
  $to_changed = true;
80
 
81
  $value = array_shift( $original_value );
82
+ $recipient_name = $value->get_name(); // Value - name.
83
+ $value = $value->get_address(); // Key - email.
84
  }
85
 
86
  if ( $email_type === 'activity-comment' ) {
bp-core/deprecated/2.8.php CHANGED
@@ -195,7 +195,17 @@ function bp_core_admin_php53_admin_notice() {
195
 
196
  <div id="message" class="error notice is-dismissible bp-is-dismissible" data-noticeid="<?php echo esc_attr( $notice_id ); ?>">
197
  <p><strong><?php esc_html_e( 'Your site is not ready for BuddyPress 2.8.', 'buddypress' ); ?></strong></p>
198
- <p><?php printf( esc_html__( 'Your site is currently running PHP version %s, while BuddyPress 2.8 will require version 5.3+.', 'buddypress' ), esc_html( phpversion() ) ); ?> <?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>
 
 
 
 
 
 
 
 
 
 
199
  <?php wp_nonce_field( "bp-dismissible-notice-$notice_id", "bp-dismissible-nonce-$notice_id" ); ?>
200
  </div>
201
  <?php
195
 
196
  <div id="message" class="error notice is-dismissible bp-is-dismissible" data-noticeid="<?php echo esc_attr( $notice_id ); ?>">
197
  <p><strong><?php esc_html_e( 'Your site is not ready for BuddyPress 2.8.', 'buddypress' ); ?></strong></p>
198
+ <p>
199
+ <?php
200
+ /* translators: %s: the site's PHP version number */
201
+ printf( esc_html_x( 'Your site is currently running PHP version %s, while BuddyPress 2.8 will require version 5.3+.', 'deprecated string', 'buddypress' ), esc_html( phpversion() ) );
202
+ ?>
203
+ &nbsp;
204
+ <?php
205
+ /* translators: %s: the url to a codex page */
206
+ printf( _x( 'See <a href="%s">the Codex guide</a> for more information.', 'deprecated string', 'buddypress' ), 'https://codex.buddypress.org/getting-started/buddypress-2-8-will-require-php-5-3/' );
207
+ ?>
208
+ </p>
209
  <?php wp_nonce_field( "bp-dismissible-notice-$notice_id", "bp-dismissible-nonce-$notice_id" ); ?>
210
  </div>
211
  <?php
bp-core/deprecated/3.0.php CHANGED
@@ -171,9 +171,17 @@ function bp_core_action_delete_user() {
171
  do_action( 'bp_core_before_action_delete_user', $errors );
172
 
173
  if ( bp_core_delete_account( bp_displayed_user_id() ) ) {
174
- bp_core_add_message( sprintf( __( '%s has been deleted from the system.', 'buddypress' ), bp_get_displayed_user_fullname() ) );
 
 
 
175
  } else {
176
- bp_core_add_message( sprintf( __( 'There was an error deleting %s from the system. Please try again.', 'buddypress' ), bp_get_displayed_user_fullname() ), 'error' );
 
 
 
 
 
177
  $errors = true;
178
  }
179
 
171
  do_action( 'bp_core_before_action_delete_user', $errors );
172
 
173
  if ( bp_core_delete_account( bp_displayed_user_id() ) ) {
174
+ bp_core_add_message(
175
+ /* translators: %s: member name */
176
+ sprintf( _x( '%s has been deleted from the system.', 'deprecated string', 'buddypress' ), bp_get_displayed_user_fullname() )
177
+ );
178
  } else {
179
+ bp_core_add_message(
180
+ /* translators: %s: member name */
181
+ sprintf( _x( 'There was an error deleting %s from the system. Please try again.', 'deprecated string', 'buddypress' ), bp_get_displayed_user_fullname() ),
182
+ 'error'
183
+ );
184
+
185
  $errors = true;
186
  }
187
 
bp-core/deprecated/6.0.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Deprecated functions.
4
+ *
5
+ * @deprecated 6.0.0
6
+ */
7
+
8
+ // Exit if accessed directly.
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Check if the current WordPress version is using Plupload 2.1.1
13
+ *
14
+ * Plupload 2.1.1 was introduced in WordPress 3.9. Our bp-plupload.js
15
+ * script requires it. So we need to make sure the current WordPress
16
+ * match with our needs.
17
+ *
18
+ * @since 2.3.0
19
+ * @since 3.0.0 This is always true.
20
+ * @deprecated 6.0.0
21
+ *
22
+ * @return bool Always true.
23
+ */
24
+ function bp_attachments_is_wp_version_supported() {
25
+ _deprecated_function( __FUNCTION__, '6.0.0' );
26
+ return true;
27
+ }
28
+
29
+ /**
30
+ * Setup the avatar upload directory for a user.
31
+ *
32
+ * @since 1.0.0
33
+ * @deprecated 6.0.0
34
+ *
35
+ * @package BuddyPress Core
36
+ *
37
+ * @param string $directory The root directory name. Optional.
38
+ * @param int $user_id The user ID. Optional.
39
+ * @return array Array containing the path, URL, and other helpful settings.
40
+ */
41
+ function xprofile_avatar_upload_dir( $directory = 'avatars', $user_id = 0 ) {
42
+ _deprecated_function( __FUNCTION__, '6.0.0', 'bp_members_avatar_upload_dir()' );
43
+
44
+ $avatar_dir = bp_members_avatar_upload_dir( $directory, $user_id );
45
+
46
+ /** This filter is documented in wp-includes/deprecated.php */
47
+ return apply_filters_deprecated( 'xprofile_avatar_upload_dir', array( $avatar_dir ), '6.0.0', 'bp_members_avatar_upload_dir' );
48
+ }
49
+
50
+ /**
51
+ * This function runs when an action is set for a screen:
52
+ * example.com/members/andy/profile/change-avatar/ [delete-avatar]
53
+ *
54
+ * The function will delete the active avatar for a user.
55
+ *
56
+ * @since 1.0.0
57
+ * @deprecated 6.0.0
58
+ */
59
+ function xprofile_action_delete_avatar() {
60
+ _deprecated_function( __FUNCTION__, '6.0.0', 'bp_members_action_delete_avatar()' );
61
+
62
+ bp_members_action_delete_avatar();
63
+ }
64
+
65
+ /**
66
+ * Displays the change cover image page.
67
+ *
68
+ * @since 2.4.0
69
+ * @deprecated 6.0.0
70
+ */
71
+ function xprofile_screen_change_cover_image() {
72
+ _deprecated_function( __FUNCTION__, '6.0.0', 'bp_members_screen_change_cover_image()' );
73
+
74
+ bp_members_screen_change_cover_image();
75
+ }
76
+
77
+ /**
78
+ * Handles the uploading and cropping of a user avatar. Displays the change avatar page.
79
+ *
80
+ * @since 1.0.0
81
+ * @deprecated 6.0.0
82
+ */
83
+ function xprofile_screen_change_avatar() {
84
+ _deprecated_function( __FUNCTION__, '6.0.0', 'bp_members_screen_change_avatar()' );
85
+
86
+ bp_members_screen_change_avatar();
87
+ }
88
+
89
+ /**
90
+ * Output the status of the current group in the loop.
91
+ *
92
+ * Either 'Public' or 'Private'.
93
+ *
94
+ * @since 1.0.0
95
+ * @deprecated 6.0.0 Not used anymore.
96
+ *
97
+ * @param object|bool $group Optional. Group object.
98
+ * Default: current group in loop.
99
+ */
100
+ function bp_group_public_status( $group = false ) {
101
+ _deprecated_function( __FUNCTION__, '6.0' );
102
+ }
103
+ /**
104
+ * Return the status of the current group in the loop.
105
+ *
106
+ * Either 'Public' or 'Private'.
107
+ *
108
+ * @since 1.0.0
109
+ * @deprecated 6.0.0 Not used anymore.
110
+ *
111
+ * @param object|bool $group Optional. Group object.
112
+ * Default: current group in loop.
113
+ * @return string
114
+ */
115
+ function bp_get_group_public_status( $group = false ) {
116
+ _deprecated_function( __FUNCTION__, '6.0' );
117
+ }
118
+
119
+ /**
120
+ * Output whether the current group in the loop is public.
121
+ *
122
+ * No longer used in BuddyPress.
123
+ *
124
+ * @deprecated 6.0.0 Not used anymore.
125
+ *
126
+ * @param object|bool $group Optional. Group object.
127
+ * Default: current group in loop.
128
+ */
129
+ function bp_group_is_public( $group = false ) {
130
+ _deprecated_function( __FUNCTION__, '6.0' );
131
+ }
132
+ /**
133
+ * Return whether the current group in the loop is public.
134
+ *
135
+ * No longer used in BuddyPress.
136
+ *
137
+ * @deprecated 6.0.0 Not used anymore.
138
+ *
139
+ * @param object|bool $group Optional. Group object.
140
+ * Default: current group in loop.
141
+ * @return mixed
142
+ */
143
+ function bp_get_group_is_public( $group = false ) {
144
+ _deprecated_function( __FUNCTION__, '6.0' );
145
+ }
146
+
147
+ /**
148
+ * Add illegal blog names to WP so that root components will not conflict with blog names on a subdirectory installation.
149
+ *
150
+ * For example, it would stop someone creating a blog with the slug "groups".
151
+ *
152
+ * @since 1.0.0
153
+ * @deprecated 6.0.0
154
+ */
155
+ function bp_core_add_illegal_names() {
156
+ _deprecated_function( __FUNCTION__, '6.0' );
157
+
158
+ update_site_option( 'illegal_names', get_site_option( 'illegal_names' ), array() );
159
+ }
bp-core/images/Jcrop.gif CHANGED
Binary file
bp-core/images/admin-menu-arrow.gif CHANGED
Binary file
bp-core/images/mystery-man-50.jpg CHANGED
Binary file
bp-core/images/mystery-man.jpg CHANGED
Binary file
bp-core/js/avatar.js CHANGED
@@ -4,7 +4,7 @@ window.bp = window.bp || {};
4
 
5
  ( function( exports, $ ) {
6
 
7
- // Bail if not set
8
  if ( typeof BP_Uploader === 'undefined' ) {
9
  return;
10
  }
@@ -25,21 +25,21 @@ window.bp = window.bp || {};
25
  */
26
  this.removeLegacyUI();
27
 
28
- // Init some vars
29
  this.views = new Backbone.Collection();
30
  this.jcropapi = {};
31
  this.warning = null;
32
 
33
- // Set up nav
34
  this.setupNav();
35
 
36
- // Avatars are uploaded files
37
  this.avatars = bp.Uploader.filesUploaded;
38
 
39
  // The Avatar Attachment object.
40
  this.Attachment = new Backbone.Model();
41
 
42
- // Wait till the queue is reset
43
  bp.Uploader.filesQueue.on( 'reset', this.cropView, this );
44
 
45
  /**
@@ -50,18 +50,18 @@ window.bp = window.bp || {};
50
  self.resetViews();
51
  } );
52
 
53
- $( 'body.wp-admin' ).on( 'click', '.bp-xprofile-avatar-user-edit', function() {
54
  self.resetViews();
55
  } );
56
  },
57
 
58
  removeLegacyUI: function() {
59
- // User
60
  if ( $( '#avatar-upload-form' ).length ) {
61
  $( '#avatar-upload' ).remove();
62
  $( '#avatar-upload-form p' ).remove();
63
 
64
- // Group Manage
65
  } else if ( $( '#group-settings-form' ).length ) {
66
  $( '#group-settings-form p' ).each( function( i ) {
67
  if ( 0 !== i ) {
@@ -73,40 +73,40 @@ window.bp = window.bp || {};
73
  $( '#delete-group-avatar-button' ).remove();
74
  }
75
 
76
- // Group Create
77
  } else if ( $( '#group-create-body' ).length ) {
78
  $( '.main-column p #file' ).remove();
79
  $( '.main-column p #upload' ).remove();
80
 
81
- // Admin Extended Profile
82
- } else if ( $( '#bp_xprofile_user_admin_avatar a.bp-xprofile-avatar-user-admin' ).length ) {
83
- $( '#bp_xprofile_user_admin_avatar a.bp-xprofile-avatar-user-admin' ).remove();
84
  }
85
  },
86
 
87
  setView: function( view ) {
88
- // Clear views
89
  if ( ! _.isUndefined( this.views.models ) ) {
90
  _.each( this.views.models, function( model ) {
91
  model.get( 'view' ).remove();
92
  }, this );
93
  }
94
 
95
- // Reset Views
96
  this.views.reset();
97
 
98
- // Reset Avatars (file uploaded)
99
  if ( ! _.isUndefined( this.avatars ) ) {
100
  this.avatars.reset();
101
  }
102
 
103
- // Reset the Jcrop API
104
  if ( ! _.isEmpty( this.jcropapi ) ) {
105
  this.jcropapi.destroy();
106
  this.jcropapi = {};
107
  }
108
 
109
- // Load the required view
110
  switch ( view ) {
111
  case 'upload':
112
  this.uploaderView();
@@ -119,10 +119,10 @@ window.bp = window.bp || {};
119
  },
120
 
121
  resetViews: function() {
122
- // Reset to the uploader view
123
  this.nav.trigger( 'bp-avatar-view:changed', 'upload' );
124
 
125
- // Reset to the uploader nav
126
  _.each( this.navItems.models, function( model ) {
127
  if ( model.id === 'upload' ) {
128
  model.set( { active: 1 } );
@@ -143,7 +143,7 @@ window.bp = window.bp || {};
143
  return;
144
  }
145
 
146
- // Reset active View
147
  activeView = 0;
148
 
149
  if ( 0 === index ) {
@@ -163,29 +163,29 @@ window.bp = window.bp || {};
163
  this.nav = new bp.Views.Nav( { collection: this.navItems } );
164
  this.nav.inject( '.bp-avatar-nav' );
165
 
166
- // Activate the initial view (uploader)
167
  this.setView( initView );
168
 
169
- // Listen to nav changes (it's like a do_action!)
170
  this.nav.on( 'bp-avatar-view:changed', _.bind( this.setView, this ) );
171
  },
172
 
173
  uploaderView: function() {
174
- // Listen to the Queued uploads
175
  bp.Uploader.filesQueue.on( 'add', this.uploadProgress, this );
176
 
177
- // Create the BuddyPress Uploader
178
  var uploader = new bp.Views.Uploader();
179
 
180
- // Add it to views
181
  this.views.add( { id: 'upload', view: uploader } );
182
 
183
- // Display it
184
  uploader.inject( '.bp-avatar' );
185
  },
186
 
187
  uploadProgress: function() {
188
- // Create the Uploader status view
189
  var avatarStatus = new bp.Views.uploaderStatus( { collection: bp.Uploader.filesQueue } );
190
 
191
  if ( ! _.isUndefined( this.views.get( 'status' ) ) ) {
@@ -194,26 +194,26 @@ window.bp = window.bp || {};
194
  this.views.add( { id: 'status', view: avatarStatus } );
195
  }
196
 
197
- // Display it
198
  avatarStatus.inject( '.bp-avatar-status' );
199
  },
200
 
201
  cropView: function() {
202
  var status;
203
 
204
- // Bail there was an error during the Upload
205
  if ( _.isEmpty( this.avatars.models ) ) {
206
  return;
207
  }
208
 
209
- // Make sure to remove the uploads status
210
  if ( ! _.isUndefined( this.views.get( 'status' ) ) ) {
211
  status = this.views.get( 'status' );
212
  status.get( 'view' ).remove();
213
  this.views.remove( { id: 'status', view: status } );
214
  }
215
 
216
- // Create the Avatars view
217
  var avatar = new bp.Views.Avatars( { collection: this.avatars } );
218
  this.views.add( { id: 'crop', view: avatar } );
219
 
@@ -224,9 +224,9 @@ window.bp = window.bp || {};
224
  var self = this,
225
  crop;
226
 
227
- // Remove the crop view
228
  if ( ! _.isUndefined( this.views.get( 'crop' ) ) ) {
229
- // Remove the JCrop API
230
  if ( ! _.isEmpty( this.jcropapi ) ) {
231
  this.jcropapi.destroy();
232
  this.jcropapi = {};
@@ -261,12 +261,12 @@ window.bp = window.bp || {};
261
 
262
  avatarStatus.inject( '.bp-avatar-status' );
263
 
264
- // Update each avatars of the page
265
  $( '.' + avatar.get( 'object' ) + '-' + response.item_id + '-avatar' ).each( function() {
266
  $(this).prop( 'src', response.avatar );
267
  } );
268
 
269
- // Inject the Delete nav
270
  bp.Avatar.navItems.get( 'delete' ).set( { hide: 0 } );
271
 
272
  /**
@@ -304,20 +304,20 @@ window.bp = window.bp || {};
304
  },
305
 
306
  deleteView:function() {
307
- // Create the delete model
308
  var delete_model = new Backbone.Model( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
309
  'object',
310
  'item_id',
311
  'nonces'
312
  ) );
313
 
314
- // Create the delete view
315
  var deleteView = new bp.Views.DeleteAvatar( { model: delete_model } );
316
 
317
- // Add it to views
318
  this.views.add( { id: 'delete', view: deleteView } );
319
 
320
- // Display it
321
  deleteView.inject( '.bp-avatar' );
322
  },
323
 
@@ -325,7 +325,7 @@ window.bp = window.bp || {};
325
  var self = this,
326
  deleteView;
327
 
328
- // Remove the delete view
329
  if ( ! _.isUndefined( this.views.get( 'delete' ) ) ) {
330
  deleteView = this.views.get( 'delete' );
331
  deleteView.get( 'view' ).remove();
@@ -351,16 +351,16 @@ window.bp = window.bp || {};
351
 
352
  avatarStatus.inject( '.bp-avatar-status' );
353
 
354
- // Update each avatars of the page
355
  $( '.' + model.get( 'object' ) + '-' + response.item_id + '-avatar').each( function() {
356
  $( this ).prop( 'src', response.avatar );
357
  } );
358
 
359
- // Remove the Delete nav
360
  bp.Avatar.navItems.get( 'delete' ).set( { active: 0, hide: 1 } );
361
 
362
  /**
363
- * Reset the Attachment object
364
  *
365
  * You can run extra actions once the avatar is set using:
366
  * bp.Avatar.Attachment.on( 'change:url', function( data ) { your code } );
@@ -410,7 +410,7 @@ window.bp = window.bp || {};
410
  }
411
  };
412
 
413
- // Main Nav view
414
  bp.Views.Nav = bp.View.extend( {
415
  tagName: 'ul',
416
  className: 'avatar-nav-items',
@@ -422,7 +422,7 @@ window.bp = window.bp || {};
422
  initialize: function() {
423
  var hasAvatar = _.findWhere( this.collection.models, { id: 'delete' } );
424
 
425
- // Display a message to inform about the delete tab
426
  if ( 1 !== hasAvatar.get( 'hide' ) ) {
427
  bp.Avatar.displayWarning( BP_Uploader.strings.has_avatar_warning );
428
  }
@@ -434,7 +434,7 @@ window.bp = window.bp || {};
434
  addNavItem: function( item ) {
435
  /**
436
  * The delete nav is not added if no avatar
437
- * is set for the object
438
  */
439
  if ( 1 === item.get( 'hide' ) ) {
440
  return;
@@ -455,13 +455,13 @@ window.bp = window.bp || {};
455
  view.remove();
456
  }
457
 
458
- // Check to see if the nav is not already rendered
459
  if ( item.get( 'id' ) === view.model.get( 'id' ) ) {
460
  isRendered = true;
461
  }
462
  } );
463
 
464
- // Add the Delete nav if not rendered
465
  if ( ! _.isBoolean( isRendered ) ) {
466
  this.addNavItem( item );
467
  }
@@ -470,7 +470,7 @@ window.bp = window.bp || {};
470
  toggleView: function( event ) {
471
  event.preventDefault();
472
 
473
- // First make sure to remove all warnings
474
  bp.Avatar.removeWarning();
475
 
476
  var active = $( event.target ).data( 'nav' );
@@ -486,7 +486,7 @@ window.bp = window.bp || {};
486
  }
487
  } );
488
 
489
- // Nav item view
490
  bp.Views.NavItem = bp.View.extend( {
491
  tagName: 'li',
492
  className: 'avatar-nav-item',
@@ -510,7 +510,7 @@ window.bp = window.bp || {};
510
  }
511
  } );
512
 
513
- // Avatars view
514
  bp.Views.Avatars = bp.View.extend( {
515
  className: 'items',
516
 
@@ -519,28 +519,28 @@ window.bp = window.bp || {};
519
  },
520
 
521
  addItemView: function( item ) {
522
- // Defaults to 150
523
  var full_d = { full_h: 150, full_w: 150 };
524
 
525
- // Make sure to take in account bp_core_avatar_full_height or bp_core_avatar_full_width php filters
526
  if ( ! _.isUndefined( BP_Uploader.settings.crop.full_h ) && ! _.isUndefined( BP_Uploader.settings.crop.full_w ) ) {
527
  full_d.full_h = BP_Uploader.settings.crop.full_h;
528
  full_d.full_w = BP_Uploader.settings.crop.full_w;
529
  }
530
 
531
- // Set the avatar model
532
  item.set( _.extend( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
533
  'object',
534
  'item_id',
535
  'nonces'
536
  ), full_d ) );
537
 
538
- // Add the view
539
  this.views.add( new bp.Views.Avatar( { model: item } ) );
540
  }
541
  } );
542
 
543
- // Avatar view
544
  bp.Views.Avatar = bp.View.extend( {
545
  className: 'item',
546
  template: bp.template( 'bp-avatar-item' ),
@@ -556,7 +556,7 @@ window.bp = window.bp || {};
556
  aspectRatio : 1
557
  } );
558
 
559
- // Display a warning if the image is smaller than minimum advised
560
  if ( false !== this.model.get( 'feedback' ) ) {
561
  bp.Avatar.displayWarning( this.model.get( 'feedback' ) );
562
  }
@@ -600,14 +600,14 @@ window.bp = window.bp || {};
600
  crop_bottom = nh + crop_top;
601
  }
602
 
603
- // Add the cropping interface
604
  tocrop.Jcrop( {
605
  onChange: _.bind( self.showPreview, self ),
606
  onSelect: _.bind( self.showPreview, self ),
607
  aspectRatio: self.options.aspectRatio,
608
  setSelect: [ crop_left, crop_top, crop_right, crop_bottom ]
609
  }, function() {
610
- // Get the Jcrop API
611
  bp.Avatar.jcropapi = this;
612
  } );
613
  },
@@ -629,7 +629,7 @@ window.bp = window.bp || {};
629
  var rx = fw / coords.w;
630
  var ry = fh / coords.h;
631
 
632
- // Update the model
633
  this.model.set( { x: coords.x, y: coords.y, w: coords.w, h: coords.h } );
634
 
635
  $( '#avatar-crop-preview' ).css( {
@@ -643,7 +643,7 @@ window.bp = window.bp || {};
643
  }
644
  } );
645
 
646
- // BuddyPress Avatar Feedback view
647
  bp.Views.AvatarStatus = bp.View.extend( {
648
  tagName: 'p',
649
  className: 'updated',
4
 
5
  ( function( exports, $ ) {
6
 
7
+ // Bail if not set.
8
  if ( typeof BP_Uploader === 'undefined' ) {
9
  return;
10
  }
25
  */
26
  this.removeLegacyUI();
27
 
28
+ // Init some vars.
29
  this.views = new Backbone.Collection();
30
  this.jcropapi = {};
31
  this.warning = null;
32
 
33
+ // Set up nav.
34
  this.setupNav();
35
 
36
+ // Avatars are uploaded files.
37
  this.avatars = bp.Uploader.filesUploaded;
38
 
39
  // The Avatar Attachment object.
40
  this.Attachment = new Backbone.Model();
41
 
42
+ // Wait till the queue is reset.
43
  bp.Uploader.filesQueue.on( 'reset', this.cropView, this );
44
 
45
  /**
50
  self.resetViews();
51
  } );
52
 
53
+ $( 'body.wp-admin' ).on( 'click', '.bp-members-avatar-user-edit', function() {
54
  self.resetViews();
55
  } );
56
  },
57
 
58
  removeLegacyUI: function() {
59
+ // User.
60
  if ( $( '#avatar-upload-form' ).length ) {
61
  $( '#avatar-upload' ).remove();
62
  $( '#avatar-upload-form p' ).remove();
63
 
64
+ // Group Manage.
65
  } else if ( $( '#group-settings-form' ).length ) {
66
  $( '#group-settings-form p' ).each( function( i ) {
67
  if ( 0 !== i ) {
73
  $( '#delete-group-avatar-button' ).remove();
74
  }
75
 
76
+ // Group Create.
77
  } else if ( $( '#group-create-body' ).length ) {
78
  $( '.main-column p #file' ).remove();
79
  $( '.main-column p #upload' ).remove();
80
 
81
+ // Member Admin.
82
+ } else if ( $( '#bp_members_user_admin_avatar a.bp-members-avatar-user-admin' ).length ) {
83
+ $( '#bp_members_user_admin_avatar a.bp-members-avatar-user-admin' ).remove();
84
  }
85
  },
86
 
87
  setView: function( view ) {
88
+ // Clear views.
89
  if ( ! _.isUndefined( this.views.models ) ) {
90
  _.each( this.views.models, function( model ) {
91
  model.get( 'view' ).remove();
92
  }, this );
93
  }
94
 
95
+ // Reset Views.
96
  this.views.reset();
97
 
98
+ // Reset Avatars (file uploaded).
99
  if ( ! _.isUndefined( this.avatars ) ) {
100
  this.avatars.reset();
101
  }
102
 
103
+ // Reset the Jcrop API.
104
  if ( ! _.isEmpty( this.jcropapi ) ) {
105
  this.jcropapi.destroy();
106
  this.jcropapi = {};
107
  }
108
 
109
+ // Load the required view.
110
  switch ( view ) {
111
  case 'upload':
112
  this.uploaderView();
119
  },
120
 
121
  resetViews: function() {
122
+ // Reset to the uploader view.
123
  this.nav.trigger( 'bp-avatar-view:changed', 'upload' );
124
 
125
+ // Reset to the uploader nav.
126
  _.each( this.navItems.models, function( model ) {
127
  if ( model.id === 'upload' ) {
128
  model.set( { active: 1 } );
143
  return;
144
  }
145
 
146
+ // Reset active View.
147
  activeView = 0;
148
 
149
  if ( 0 === index ) {
163
  this.nav = new bp.Views.Nav( { collection: this.navItems } );
164
  this.nav.inject( '.bp-avatar-nav' );
165
 
166
+ // Activate the initial view (uploader).
167
  this.setView( initView );
168
 
169
+ // Listen to nav changes (it's like a do_action!).
170
  this.nav.on( 'bp-avatar-view:changed', _.bind( this.setView, this ) );
171
  },
172
 
173
  uploaderView: function() {
174
+ // Listen to the Queued uploads.
175
  bp.Uploader.filesQueue.on( 'add', this.uploadProgress, this );
176
 
177
+ // Create the BuddyPress Uploader.
178
  var uploader = new bp.Views.Uploader();
179
 
180
+ // Add it to views.
181
  this.views.add( { id: 'upload', view: uploader } );
182
 
183
+ // Display it.
184
  uploader.inject( '.bp-avatar' );
185
  },
186
 
187
  uploadProgress: function() {
188
+ // Create the Uploader status view.
189
  var avatarStatus = new bp.Views.uploaderStatus( { collection: bp.Uploader.filesQueue } );
190
 
191
  if ( ! _.isUndefined( this.views.get( 'status' ) ) ) {
194
  this.views.add( { id: 'status', view: avatarStatus } );
195
  }
196
 
197
+ // Display it.
198
  avatarStatus.inject( '.bp-avatar-status' );
199
  },
200
 
201
  cropView: function() {
202
  var status;
203
 
204
+ // Bail there was an error during the Upload.
205
  if ( _.isEmpty( this.avatars.models ) ) {
206
  return;
207
  }
208
 
209
+ // Make sure to remove the uploads status.
210
  if ( ! _.isUndefined( this.views.get( 'status' ) ) ) {
211
  status = this.views.get( 'status' );
212
  status.get( 'view' ).remove();
213
  this.views.remove( { id: 'status', view: status } );
214
  }
215
 
216
+ // Create the Avatars view.
217
  var avatar = new bp.Views.Avatars( { collection: this.avatars } );
218
  this.views.add( { id: 'crop', view: avatar } );
219
 
224
  var self = this,
225
  crop;
226
 
227
+ // Remove the crop view.
228
  if ( ! _.isUndefined( this.views.get( 'crop' ) ) ) {
229
+ // Remove the JCrop API.
230
  if ( ! _.isEmpty( this.jcropapi ) ) {
231
  this.jcropapi.destroy();
232
  this.jcropapi = {};
261
 
262
  avatarStatus.inject( '.bp-avatar-status' );
263
 
264
+ // Update each avatars of the page.
265
  $( '.' + avatar.get( 'object' ) + '-' + response.item_id + '-avatar' ).each( function() {
266
  $(this).prop( 'src', response.avatar );
267
  } );
268
 
269
+ // Inject the Delete nav.
270
  bp.Avatar.navItems.get( 'delete' ).set( { hide: 0 } );
271
 
272
  /**
304
  },
305
 
306
  deleteView:function() {
307
+ // Create the delete model.
308
  var delete_model = new Backbone.Model( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
309
  'object',
310
  'item_id',
311
  'nonces'
312
  ) );
313
 
314
+ // Create the delete view.
315
  var deleteView = new bp.Views.DeleteAvatar( { model: delete_model } );
316
 
317
+ // Add it to views.
318
  this.views.add( { id: 'delete', view: deleteView } );
319
 
320
+ // Display it.
321
  deleteView.inject( '.bp-avatar' );
322
  },
323
 
325
  var self = this,
326
  deleteView;
327
 
328
+ // Remove the delete view.
329
  if ( ! _.isUndefined( this.views.get( 'delete' ) ) ) {
330
  deleteView = this.views.get( 'delete' );
331
  deleteView.get( 'view' ).remove();
351
 
352
  avatarStatus.inject( '.bp-avatar-status' );
353
 
354
+ // Update each avatars of the page.
355
  $( '.' + model.get( 'object' ) + '-' + response.item_id + '-avatar').each( function() {
356
  $( this ).prop( 'src', response.avatar );
357
  } );
358
 
359
+ // Remove the Delete nav.
360
  bp.Avatar.navItems.get( 'delete' ).set( { active: 0, hide: 1 } );
361
 
362
  /**
363
+ * Reset the Attachment object.
364
  *
365
  * You can run extra actions once the avatar is set using:
366
  * bp.Avatar.Attachment.on( 'change:url', function( data ) { your code } );
410
  }
411
  };
412
 
413
+ // Main Nav view.
414
  bp.Views.Nav = bp.View.extend( {
415
  tagName: 'ul',
416
  className: 'avatar-nav-items',
422
  initialize: function() {
423
  var hasAvatar = _.findWhere( this.collection.models, { id: 'delete' } );
424
 
425
+ // Display a message to inform about the delete tab.
426
  if ( 1 !== hasAvatar.get( 'hide' ) ) {
427
  bp.Avatar.displayWarning( BP_Uploader.strings.has_avatar_warning );
428
  }
434
  addNavItem: function( item ) {
435
  /**
436
  * The delete nav is not added if no avatar
437
+ * is set for the object.
438
  */
439
  if ( 1 === item.get( 'hide' ) ) {
440
  return;
455
  view.remove();
456
  }
457
 
458
+ // Check to see if the nav is not already rendered.
459
  if ( item.get( 'id' ) === view.model.get( 'id' ) ) {
460
  isRendered = true;
461
  }
462
  } );
463
 
464
+ // Add the Delete nav if not rendered.
465
  if ( ! _.isBoolean( isRendered ) ) {
466
  this.addNavItem( item );
467
  }
470
  toggleView: function( event ) {
471
  event.preventDefault();
472
 
473
+ // First make sure to remove all warnings.
474
  bp.Avatar.removeWarning();
475
 
476
  var active = $( event.target ).data( 'nav' );
486
  }
487
  } );
488
 
489
+ // Nav item view.
490
  bp.Views.NavItem = bp.View.extend( {
491
  tagName: 'li',
492
  className: 'avatar-nav-item',
510
  }
511
  } );
512
 
513
+ // Avatars view.
514
  bp.Views.Avatars = bp.View.extend( {
515
  className: 'items',
516
 
519
  },
520
 
521
  addItemView: function( item ) {
522
+ // Defaults to 150.
523
  var full_d = { full_h: 150, full_w: 150 };
524
 
525
+ // Make sure to take in account bp_core_avatar_full_height or bp_core_avatar_full_width php filters.
526
  if ( ! _.isUndefined( BP_Uploader.settings.crop.full_h ) && ! _.isUndefined( BP_Uploader.settings.crop.full_w ) ) {
527
  full_d.full_h = BP_Uploader.settings.crop.full_h;
528
  full_d.full_w = BP_Uploader.settings.crop.full_w;
529
  }
530
 
531
+ // Set the avatar model.
532
  item.set( _.extend( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
533
  'object',
534
  'item_id',
535
  'nonces'
536
  ), full_d ) );
537
 
538
+ // Add the view.
539
  this.views.add( new bp.Views.Avatar( { model: item } ) );
540
  }
541
  } );
542
 
543
+ // Avatar view.
544
  bp.Views.Avatar = bp.View.extend( {
545
  className: 'item',
546
  template: bp.template( 'bp-avatar-item' ),
556
  aspectRatio : 1
557
  } );
558
 
559
+ // Display a warning if the image is smaller than minimum advised.
560
  if ( false !== this.model.get( 'feedback' ) ) {
561
  bp.Avatar.displayWarning( this.model.get( 'feedback' ) );
562
  }
600
  crop_bottom = nh + crop_top;
601
  }
602
 
603
+ // Add the cropping interface.
604
  tocrop.Jcrop( {
605
  onChange: _.bind( self.showPreview, self ),
606
  onSelect: _.bind( self.showPreview, self ),
607
  aspectRatio: self.options.aspectRatio,
608
  setSelect: [ crop_left, crop_top, crop_right, crop_bottom ]
609
  }, function() {
610
+ // Get the Jcrop API.
611
  bp.Avatar.jcropapi = this;
612
  } );
613
  },
629
  var rx = fw / coords.w;
630
  var ry = fh / coords.h;
631
 
632
+ // Update the model.
633
  this.model.set( { x: coords.x, y: coords.y, w: coords.w, h: coords.h } );
634
 
635
  $( '#avatar-crop-preview' ).css( {
643
  }
644
  } );
645
 
646
+ // BuddyPress Avatar Feedback view.
647
  bp.Views.AvatarStatus = bp.View.extend( {
648
  tagName: 'p',
649
  className: 'updated',
bp-core/js/avatar.min.js CHANGED
@@ -1 +1 @@
1
- window.bp=window.bp||{},function(e,t){"undefined"!=typeof BP_Uploader&&(bp.Models=bp.Models||{},bp.Collections=bp.Collections||{},bp.Views=bp.Views||{},bp.Avatar={start:function(){var e=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),t("body.wp-admin").on("tb_unload","#TB_window",function(){e.resetViews()}),t("body.wp-admin").on("click",".bp-xprofile-avatar-user-edit",function(){e.resetViews()})},removeLegacyUI:function(){t("#avatar-upload-form").length?(t("#avatar-upload").remove(),t("#avatar-upload-form p").remove()):t("#group-settings-form").length?(t("#group-settings-form p").each(function(e){0!==e&&t(this).remove()}),t("#delete-group-avatar-button").length&&t("#delete-group-avatar-button").remove()):t("#group-create-body").length?(t(".main-column p #file").remove(),t(".main-column p #upload").remove()):t("#bp_xprofile_user_admin_avatar a.bp-xprofile-avatar-user-admin").length&&t("#bp_xprofile_user_admin_avatar a.bp-xprofile-avatar-user-admin").remove()},setView:function(e){switch(_.isUndefined(this.views.models)||_.each(this.views.models,function(e){e.get("view").remove()},this),this.views.reset(),_.isUndefined(this.avatars)||this.avatars.reset(),_.isEmpty(this.jcropapi)||(this.jcropapi.destroy(),this.jcropapi={}),e){case"upload":this.uploaderView();break;case"delete":this.deleteView()}},resetViews:function(){this.nav.trigger("bp-avatar-view:changed","upload"),_.each(this.navItems.models,function(e){"upload"===e.id?e.set({active:1}):e.set({active:0})})},setupNav:function(){var e,t,a=this;this.navItems=new Backbone.Collection,_.each(BP_Uploader.settings.nav,function(i,s){_.isObject(i)&&(t=0,0===s&&(e=i.id,t=1),a.navItems.add({id:i.id,name:i.caption,href:"#",active:t,hide:_.isUndefined(i.hide)?0:i.hide}))}),this.nav=new bp.Views.Nav({collection:this.navItems}),this.nav.inject(".bp-avatar-nav"),this.setView(e),this.nav.on("bp-avatar-view:changed",_.bind(this.setView,this))},uploaderView:function(){bp.Uploader.filesQueue.on("add",this.uploadProgress,this);var e=new bp.Views.Uploader;this.views.add({id:"upload",view:e}),e.inject(".bp-avatar")},uploadProgress:function(){var e=new bp.Views.uploaderStatus({collection:bp.Uploader.filesQueue});_.isUndefined(this.views.get("status"))?this.views.add({id:"status",view:e}):this.views.set({id:"status",view:e}),e.inject(".bp-avatar-status")},cropView:function(){var e;if(!_.isEmpty(this.avatars.models)){_.isUndefined(this.views.get("status"))||((e=this.views.get("status")).get("view").remove(),this.views.remove({id:"status",view:e}));var t=new bp.Views.Avatars({collection:this.avatars});this.views.add({id:"crop",view:t}),t.inject(".bp-avatar")}},setAvatar:function(e){var a,i=this;_.isUndefined(this.views.get("crop"))||(_.isEmpty(this.jcropapi)||(this.jcropapi.destroy(),this.jcropapi={}),(a=this.views.get("crop")).get("view").remove(),this.views.remove({id:"crop",view:a})),bp.ajax.post("bp_avatar_set",{json:!0,original_file:e.get("url"),crop_w:e.get("w"),crop_h:e.get("h"),crop_x:e.get("x"),crop_y:e.get("y"),item_id:e.get("item_id"),object:e.get("object"),type:_.isUndefined(e.get("type"))?"crop":e.get("type"),nonce:e.get("nonces").set}).done(function(a){var s=new bp.Views.AvatarStatus({value:BP_Uploader.strings.feedback_messages[a.feedback_code],type:"success"});i.views.add({id:"status",view:s}),s.inject(".bp-avatar-status"),t("."+e.get("object")+"-"+a.item_id+"-avatar").each(function(){t(this).prop("src",a.avatar)}),bp.Avatar.navItems.get("delete").set({hide:0}),i.Attachment.set(_.extend(_.pick(e.attributes,["object","item_id"]),{url:a.avatar,action:"uploaded"}))}).fail(function(e){var t=BP_Uploader.strings.default_error;_.isUndefined(e)||(t=BP_Uploader.strings.feedback_messages[e.feedback_code]);var a=new bp.Views.AvatarStatus({value:t,type:"error"});i.views.add({id:"status",view:a}),a.inject(".bp-avatar-status")})},deleteView:function(){var e=new Backbone.Model(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,"object","item_id","nonces")),t=new bp.Views.DeleteAvatar({model:e});this.views.add({id:"delete",view:t}),t.inject(".bp-avatar")},deleteAvatar:function(e){var a,i=this;_.isUndefined(this.views.get("delete"))||((a=this.views.get("delete")).get("view").remove(),this.views.remove({id:"delete",view:a})),bp.ajax.post("bp_avatar_delete",{json:!0,item_id:e.get("item_id"),object:e.get("object"),nonce:e.get("nonces").remove}).done(function(a){var s=new bp.Views.AvatarStatus({value:BP_Uploader.strings.feedback_messages[a.feedback_code],type:"success"});i.views.add({id:"status",view:s}),s.inject(".bp-avatar-status"),t("."+e.get("object")+"-"+a.item_id+"-avatar").each(function(){t(this).prop("src",a.avatar)}),bp.Avatar.navItems.get("delete").set({active:0,hide:1}),i.Attachment.set(_.extend(_.pick(e.attributes,["object","item_id"]),{url:a.avatar,action:"deleted"}))}).fail(function(e){var t=BP_Uploader.strings.default_error;_.isUndefined(e)||(t=BP_Uploader.strings.feedback_messages[e.feedback_code]);var a=new bp.Views.AvatarStatus({value:t,type:"error"});i.views.add({id:"status",view:a}),a.inject(".bp-avatar-status")})},removeWarning:function(){_.isNull(this.warning)||this.warning.remove()},displayWarning:function(e){this.removeWarning(),this.warning=new bp.Views.uploaderWarning({value:e}),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(){1!==_.findWhere(this.collection.models,{id:"delete"}).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(e){1!==e.get("hide")&&this.views.add(new bp.Views.NavItem({model:e}))},showHideNavItem:function(e){var t=null;_.each(this.views._views[""],function(a){1===a.model.get("hide")&&a.remove(),e.get("id")===a.model.get("id")&&(t=!0)}),_.isBoolean(t)||this.addNavItem(e)},toggleView:function(e){e.preventDefault(),bp.Avatar.removeWarning();var a=t(e.target).data("nav");_.each(this.collection.models,function(e){e.id===a?(e.set({active:1}),this.trigger("bp-avatar-view:changed",e.id)):e.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(e){1===e.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(e){var t={full_h:150,full_w:150};_.isUndefined(BP_Uploader.settings.crop.full_h)||_.isUndefined(BP_Uploader.settings.crop.full_w)||(t.full_h=BP_Uploader.settings.crop.full_h,t.full_w=BP_Uploader.settings.crop.full_w),e.set(_.extend(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,"object","item_id","nonces"),t)),this.views.add(new bp.Views.Avatar({model:e}))}}),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 e,a,i,s,n,o,r=this,d=this.$el.find("#avatar-to-crop img"),l=this.$el.width(),p={};_.isUndefined(this.options.full_h)||_.isUndefined(this.options.full_w)||(this.options.aspectRatio=this.options.full_w/this.options.full_h),p.w=this.model.get("width"),p.h=this.model.get("height"),this.options.full_w+p.w+20<l&&(t("#avatar-to-crop").addClass("adjust"),this.$el.find(".avatar-crop-management").addClass("adjust")),p.h<=p.w?(e=Math.round(p.h/4),a=(n=o=Math.round(p.h/2))+e,s=o+(i=(p.w-o)/2)):(i=Math.round(p.w/4),n=o=Math.round(p.w/2),s=o+i,a=n+(e=(p.h-n)/2)),d.Jcrop({onChange:_.bind(r.showPreview,r),onSelect:_.bind(r.showPreview,r),aspectRatio:r.options.aspectRatio,setSelect:[i,e,s,a]},function(){bp.Avatar.jcropapi=this})},cropAvatar:function(e){e.preventDefault(),bp.Avatar.setAvatar(this.model)},showPreview:function(e){if(e.w&&e.h&&parseInt(e.w,10)>0){var a=this.options.full_w,i=this.options.full_h,s=a/e.w,n=i/e.h;this.model.set({x:e.x,y:e.y,w:e.w,h:e.h}),t("#avatar-crop-preview").css({maxWidth:"none",width:Math.round(s*this.model.get("width"))+"px",height:Math.round(n*this.model.get("height"))+"px",marginLeft:"-"+Math.round(s*this.model.get("x"))+"px",marginTop:"-"+Math.round(n*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(e){e.preventDefault(),bp.Avatar.deleteAvatar(this.model)}}),bp.Avatar.start())}(bp,jQuery);
1
+ window.bp=window.bp||{},function(e,t){"undefined"!=typeof BP_Uploader&&(bp.Models=bp.Models||{},bp.Collections=bp.Collections||{},bp.Views=bp.Views||{},bp.Avatar={start:function(){var e=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),t("body.wp-admin").on("tb_unload","#TB_window",function(){e.resetViews()}),t("body.wp-admin").on("click",".bp-members-avatar-user-edit",function(){e.resetViews()})},removeLegacyUI:function(){t("#avatar-upload-form").length?(t("#avatar-upload").remove(),t("#avatar-upload-form p").remove()):t("#group-settings-form").length?(t("#group-settings-form p").each(function(e){0!==e&&t(this).remove()}),t("#delete-group-avatar-button").length&&t("#delete-group-avatar-button").remove()):t("#group-create-body").length?(t(".main-column p #file").remove(),t(".main-column p #upload").remove()):t("#bp_members_user_admin_avatar a.bp-members-avatar-user-admin").length&&t("#bp_members_user_admin_avatar a.bp-members-avatar-user-admin").remove()},setView:function(e){switch(_.isUndefined(this.views.models)||_.each(this.views.models,function(e){e.get("view").remove()},this),this.views.reset(),_.isUndefined(this.avatars)||this.avatars.reset(),_.isEmpty(this.jcropapi)||(this.jcropapi.destroy(),this.jcropapi={}),e){case"upload":this.uploaderView();break;case"delete":this.deleteView()}},resetViews:function(){this.nav.trigger("bp-avatar-view:changed","upload"),_.each(this.navItems.models,function(e){"upload"===e.id?e.set({active:1}):e.set({active:0})})},setupNav:function(){var e,t,a=this;this.navItems=new Backbone.Collection,_.each(BP_Uploader.settings.nav,function(i,s){_.isObject(i)&&(t=0,0===s&&(e=i.id,t=1),a.navItems.add({id:i.id,name:i.caption,href:"#",active:t,hide:_.isUndefined(i.hide)?0:i.hide}))}),this.nav=new bp.Views.Nav({collection:this.navItems}),this.nav.inject(".bp-avatar-nav"),this.setView(e),this.nav.on("bp-avatar-view:changed",_.bind(this.setView,this))},uploaderView:function(){bp.Uploader.filesQueue.on("add",this.uploadProgress,this);var e=new bp.Views.Uploader;this.views.add({id:"upload",view:e}),e.inject(".bp-avatar")},uploadProgress:function(){var e=new bp.Views.uploaderStatus({collection:bp.Uploader.filesQueue});_.isUndefined(this.views.get("status"))?this.views.add({id:"status",view:e}):this.views.set({id:"status",view:e}),e.inject(".bp-avatar-status")},cropView:function(){var e;if(!_.isEmpty(this.avatars.models)){_.isUndefined(this.views.get("status"))||((e=this.views.get("status")).get("view").remove(),this.views.remove({id:"status",view:e}));var t=new bp.Views.Avatars({collection:this.avatars});this.views.add({id:"crop",view:t}),t.inject(".bp-avatar")}},setAvatar:function(e){var a,i=this;_.isUndefined(this.views.get("crop"))||(_.isEmpty(this.jcropapi)||(this.jcropapi.destroy(),this.jcropapi={}),(a=this.views.get("crop")).get("view").remove(),this.views.remove({id:"crop",view:a})),bp.ajax.post("bp_avatar_set",{json:!0,original_file:e.get("url"),crop_w:e.get("w"),crop_h:e.get("h"),crop_x:e.get("x"),crop_y:e.get("y"),item_id:e.get("item_id"),object:e.get("object"),type:_.isUndefined(e.get("type"))?"crop":e.get("type"),nonce:e.get("nonces").set}).done(function(a){var s=new bp.Views.AvatarStatus({value:BP_Uploader.strings.feedback_messages[a.feedback_code],type:"success"});i.views.add({id:"status",view:s}),s.inject(".bp-avatar-status"),t("."+e.get("object")+"-"+a.item_id+"-avatar").each(function(){t(this).prop("src",a.avatar)}),bp.Avatar.navItems.get("delete").set({hide:0}),i.Attachment.set(_.extend(_.pick(e.attributes,["object","item_id"]),{url:a.avatar,action:"uploaded"}))}).fail(function(e){var t=BP_Uploader.strings.default_error;_.isUndefined(e)||(t=BP_Uploader.strings.feedback_messages[e.feedback_code]);var a=new bp.Views.AvatarStatus({value:t,type:"error"});i.views.add({id:"status",view:a}),a.inject(".bp-avatar-status")})},deleteView:function(){var e=new Backbone.Model(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,"object","item_id","nonces")),t=new bp.Views.DeleteAvatar({model:e});this.views.add({id:"delete",view:t}),t.inject(".bp-avatar")},deleteAvatar:function(e){var a,i=this;_.isUndefined(this.views.get("delete"))||((a=this.views.get("delete")).get("view").remove(),this.views.remove({id:"delete",view:a})),bp.ajax.post("bp_avatar_delete",{json:!0,item_id:e.get("item_id"),object:e.get("object"),nonce:e.get("nonces").remove}).done(function(a){var s=new bp.Views.AvatarStatus({value:BP_Uploader.strings.feedback_messages[a.feedback_code],type:"success"});i.views.add({id:"status",view:s}),s.inject(".bp-avatar-status"),t("."+e.get("object")+"-"+a.item_id+"-avatar").each(function(){t(this).prop("src",a.avatar)}),bp.Avatar.navItems.get("delete").set({active:0,hide:1}),i.Attachment.set(_.extend(_.pick(e.attributes,["object","item_id"]),{url:a.avatar,action:"deleted"}))}).fail(function(e){var t=BP_Uploader.strings.default_error;_.isUndefined(e)||(t=BP_Uploader.strings.feedback_messages[e.feedback_code]);var a=new bp.Views.AvatarStatus({value:t,type:"error"});i.views.add({id:"status",view:a}),a.inject(".bp-avatar-status")})},removeWarning:function(){_.isNull(this.warning)||this.warning.remove()},displayWarning:function(e){this.removeWarning(),this.warning=new bp.Views.uploaderWarning({value:e}),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(){1!==_.findWhere(this.collection.models,{id:"delete"}).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(e){1!==e.get("hide")&&this.views.add(new bp.Views.NavItem({model:e}))},showHideNavItem:function(e){var t=null;_.each(this.views._views[""],function(a){1===a.model.get("hide")&&a.remove(),e.get("id")===a.model.get("id")&&(t=!0)}),_.isBoolean(t)||this.addNavItem(e)},toggleView:function(e){e.preventDefault(),bp.Avatar.removeWarning();var a=t(e.target).data("nav");_.each(this.collection.models,function(e){e.id===a?(e.set({active:1}),this.trigger("bp-avatar-view:changed",e.id)):e.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(e){1===e.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(e){var t={full_h:150,full_w:150};_.isUndefined(BP_Uploader.settings.crop.full_h)||_.isUndefined(BP_Uploader.settings.crop.full_w)||(t.full_h=BP_Uploader.settings.crop.full_h,t.full_w=BP_Uploader.settings.crop.full_w),e.set(_.extend(_.pick(BP_Uploader.settings.defaults.multipart_params.bp_params,"object","item_id","nonces"),t)),this.views.add(new bp.Views.Avatar({model:e}))}}),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 e,a,i,s,n,o,r=this,d=this.$el.find("#avatar-to-crop img"),l=this.$el.width(),p={};_.isUndefined(this.options.full_h)||_.isUndefined(this.options.full_w)||(this.options.aspectRatio=this.options.full_w/this.options.full_h),p.w=this.model.get("width"),p.h=this.model.get("height"),this.options.full_w+p.w+20<l&&(t("#avatar-to-crop").addClass("adjust"),this.$el.find(".avatar-crop-management").addClass("adjust")),p.h<=p.w?(e=Math.round(p.h/4),a=(n=o=Math.round(p.h/2))+e,s=o+(i=(p.w-o)/2)):(i=Math.round(p.w/4),n=o=Math.round(p.w/2),s=o+i,a=n+(e=(p.h-n)/2)),d.Jcrop({onChange:_.bind(r.showPreview,r),onSelect:_.bind(r.showPreview,r),aspectRatio:r.options.aspectRatio,setSelect:[i,e,s,a]},function(){bp.Avatar.jcropapi=this})},cropAvatar:function(e){e.preventDefault(),bp.Avatar.setAvatar(this.model)},showPreview:function(e){if(e.w&&e.h&&parseInt(e.w,10)>0){var a=this.options.full_w,i=this.options.full_h,s=a/e.w,n=i/e.h;this.model.set({x:e.x,y:e.y,w:e.w,h:e.h}),t("#avatar-crop-preview").css({maxWidth:"none",width:Math.round(s*this.model.get("width"))+"px",height:Math.round(n*this.model.get("height"))+"px",marginLeft:"-"+Math.round(s*this.model.get("x"))+"px",marginTop:"-"+Math.round(n*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(e){e.preventDefault(),bp.Avatar.deleteAvatar(this.model)}}),bp.Avatar.start())}(bp,jQuery);
bp-core/js/block-components.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;c<t.length;c++)try{f(t[c])}catch(e){i||(i=e)}if(t.length){var l=f(t[t.length-1]);"object"==typeof exports&&"undefined"!=typeof module?module.exports=l:"function"==typeof define&&define.amd?define(function(){return l}):n&&(this[n]=l)}if(parcelRequire=f,i)throw i;return f}({"IC7x":[function(require,module,exports) {
2
+ function n(n,o){if(!(n instanceof o))throw new TypeError("Cannot call a class as a function")}module.exports=n;
3
+ },{}],"WiqS":[function(require,module,exports) {
4
+ function e(e,r){for(var n=0;n<r.length;n++){var t=r[n];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(e,t.key,t)}}function r(r,n,t){return n&&e(r.prototype,n),t&&e(r,t),r}module.exports=r;
5
+ },{}],"NS7G":[function(require,module,exports) {
6
+ function e(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}module.exports=e;
7
+ },{}],"xOn8":[function(require,module,exports) {
8
+ function o(t){return"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?module.exports=o=function(o){return typeof o}:module.exports=o=function(o){return o&&"function"==typeof Symbol&&o.constructor===Symbol&&o!==Symbol.prototype?"symbol":typeof o},o(t)}module.exports=o;
9
+ },{}],"oXYo":[function(require,module,exports) {
10
+ var e=require("../helpers/typeof"),r=require("./assertThisInitialized");function t(t,i){return!i||"object"!==e(i)&&"function"!=typeof i?r(t):i}module.exports=t;
11
+ },{"../helpers/typeof":"xOn8","./assertThisInitialized":"NS7G"}],"goD2":[function(require,module,exports) {
12
+ function t(e){return module.exports=t=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},t(e)}module.exports=t;
13
+ },{}],"zqo5":[function(require,module,exports) {
14
+ function t(o,e){return module.exports=t=Object.setPrototypeOf||function(t,o){return t.__proto__=o,t},t(o,e)}module.exports=t;
15
+ },{}],"RISo":[function(require,module,exports) {
16
+ var e=require("./setPrototypeOf");function r(r,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(t&&t.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),t&&e(r,t)}module.exports=r;
17
+ },{"./setPrototypeOf":"zqo5"}],"W80x":[function(require,module,exports) {
18
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var e=o(require("@babel/runtime/helpers/classCallCheck")),t=o(require("@babel/runtime/helpers/createClass")),r=o(require("@babel/runtime/helpers/assertThisInitialized")),a=o(require("@babel/runtime/helpers/possibleConstructorReturn")),s=o(require("@babel/runtime/helpers/getPrototypeOf")),n=o(require("@babel/runtime/helpers/inherits"));function o(e){return e&&e.__esModule?e:{default:e}}function u(e){return function(){var t,r=(0,s.default)(e);if(l()){var n=(0,s.default)(this).constructor;t=Reflect.construct(r,arguments,n)}else t=r.apply(this,arguments);return(0,a.default)(this,t)}}function l(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(e){return!1}}var i=wp.element,c=i.Component,m=i.Fragment,p=i.createElement,h=wp.components.Popover,f=wp,d=f.apiFetch,b=wp.i18n.__,_=function(a){(0,n.default)(o,a);var s=u(o);function o(){var t;return(0,e.default)(this,o),(t=s.apply(this,arguments)).state={search:"",items:[],error:""},t.searchItemName=t.searchItemName.bind((0,r.default)(t)),t.selectItemName=t.selectItemName.bind((0,r.default)(t)),t}return(0,t.default)(o,[{key:"searchItemName",value:function(e){var t=this,r=this.state.search,a=this.props,s=a.component,n=a.objectStatus;this.setState({search:e}),e.length<r.length&&this.setState({items:[]});var o="/buddypress/v1/"+s;e&&(o+="?search="+encodeURIComponent(e)),n&&(o+="&status="+n),d({path:o}).then(function(e){t.setState({items:e})},function(e){t.setState({error:e.message})})}},{key:"selectItemName",value:function(e,t){var r=this.props.onSelectItem;return e.preventDefault(),this.setState({search:"",items:[],error:""}),r({itemID:t})}},{key:"render",value:function(){var e,t=this,r=this.state,a=r.search,s=r.items,n=this.props,o=n.ariaLabel,u=n.placeholder,l=n.useAvatar;return o||(o=b("Item's name","buddypress")),u||(u=b("Enter Item's name here…","buddypress")),s.length&&(e=s.map(function(e){return p("button",{type:"button",key:"editor-autocompleters__item-item-"+e.id,role:"option","aria-selected":"true",className:"components-button components-autocomplete__result editor-autocompleters__user",onClick:function(r){return t.selectItemName(r,e.id)}},l&&p("img",{key:"avatar",className:"editor-autocompleters__user-avatar",alt:"",src:e.avatar_urls.thumb}),p("span",{key:"name",className:"editor-autocompleters__user-name"},e.name),e.mention_name&&p("span",{key:"slug",className:"editor-autocompleters__user-slug"},e.mention_name))})),p(m,null,p("input",{type:"text",value:a,className:"components-placeholder__input","aria-label":o,placeholder:u,onChange:function(e){return t.searchItemName(e.target.value)}}),0!==s.length&&p(h,{className:"components-autocomplete__popover",focusOnMount:!1,position:"bottom left"},p("div",{className:"components-autocomplete__results"},e)))}}]),o}(c),v=_;exports.default=v;
19
+ },{"@babel/runtime/helpers/classCallCheck":"IC7x","@babel/runtime/helpers/createClass":"WiqS","@babel/runtime/helpers/assertThisInitialized":"NS7G","@babel/runtime/helpers/possibleConstructorReturn":"oXYo","@babel/runtime/helpers/getPrototypeOf":"goD2","@babel/runtime/helpers/inherits":"RISo"}],"iA92":[function(require,module,exports) {
20
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var e=t(require("./autocompleter"));function t(e){return e&&e.__esModule?e:{default:e}}var r={AutoCompleter:e.default};exports.default=r;
21
+ },{"./autocompleter":"W80x"}],"Ee8M":[function(require,module,exports) {
22
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"blockComponents",{enumerable:!0,get:function(){return e.default}});var e=t(require("./components"));function t(e){return e&&e.__esModule?e:{default:e}}
23
+ },{"./components":"iA92"}]},{},["Ee8M"], "bp")
bp-core/js/bp-api-request.js CHANGED
@@ -8,14 +8,14 @@
8
  window.bp = window.bp || {};
9
 
10
  ( function( wp, bp, $ ) {
11
- // Bail if not set
12
  if ( typeof bpApiSettings === 'undefined' ) {
13
  return;
14
  }
15
 
16
  bp.isRestEnabled = true;
17
 
18
- // Polyfill wp.apiRequest if WordPress < 4.9
19
  bp.apiRequest = function( options ) {
20
  var bpRequest;
21
 
8
  window.bp = window.bp || {};
9
 
10
  ( function( wp, bp, $ ) {
11
+ // Bail if not set.
12
  if ( typeof bpApiSettings === 'undefined' ) {
13
  return;
14
  }
15
 
16
  bp.isRestEnabled = true;
17
 
18
+ // Polyfill wp.apiRequest if WordPress < 4.9.
19
  bp.apiRequest = function( options ) {
20
  var bpRequest;
21
 
bp-core/js/bp-plupload.js CHANGED
@@ -5,7 +5,7 @@ window.bp = window.bp || {};
5
 
6
  ( function( exports, $ ) {
7
 
8
- // Bail if not set
9
  if ( typeof BP_Uploader === 'undefined' ) {
10
  return;
11
  }
@@ -17,7 +17,7 @@ window.bp = window.bp || {};
17
  */
18
  _.extend( bp, _.pick( wp, 'Backbone', 'ajax', 'template' ) );
19
 
20
- // Init Models, Collections, Views and the BuddyPress Uploader
21
  bp.Models = bp.Models || {};
22
  bp.Collections = bp.Collections || {};
23
  bp.Views = bp.Views || {};
@@ -26,7 +26,7 @@ window.bp = window.bp || {};
26
  /**
27
  * BuddyPress Uploader.
28
  *
29
- * This is an adapted version of wp.Uploader
30
  */
31
  bp.Uploader.uploader = function() {
32
  var self = this,
@@ -47,7 +47,7 @@ window.bp = window.bp || {};
47
  return;
48
  }
49
 
50
- // Make sure flash sends cookies (seems in IE it does without switching to urlstream mode)
51
  if ( ! isIE && 'flash' === plupload.predictRuntime( this.params.defaults ) &&
52
  ( ! this.params.defaults.required_features || ! this.params.defaults.required_features.hasOwnProperty( 'send_binary_string' ) ) ) {
53
 
@@ -97,19 +97,19 @@ window.bp = window.bp || {};
97
 
98
  } );
99
 
100
- // See https://core.trac.wordpress.org/ticket/37039
101
  this.uploader.bind( 'postinit', function( up ) {
102
  up.refresh();
103
  });
104
 
105
- // Init BuddyPress Uploader
106
  this.uploader.init();
107
 
108
  /**
109
  * Feedback callback.
110
  *
111
  * Add a new message to the errors collection, so it's possible
112
- * to give some feedback to the user
113
  *
114
  * @param {string} message
115
  * @param {object} data
@@ -140,7 +140,7 @@ window.bp = window.bp || {};
140
 
141
  /**
142
  * In case the multiple selection is false (eg: avatar) stop the process and send
143
- * and event containing a warning
144
  */
145
  if ( ! uploader.settings.multi_selection && files.length > 1 ) {
146
  for ( var i in files ) {
@@ -181,7 +181,7 @@ window.bp = window.bp || {};
181
  } );
182
 
183
  /**
184
- * Update each file item on progress
185
  *
186
  * @event UploadProgress
187
  * @param {plupload.Uploader} uploader Uploader instance.
@@ -225,15 +225,15 @@ window.bp = window.bp || {};
225
 
226
  file.item.set( _.extend( response.data, { uploading: false } ) );
227
 
228
- // Add the file to the Uploaded ones
229
  bp.Uploader.filesUploaded.add( file.item );
230
 
231
  } );
232
 
233
  /**
234
- * Trigger an event to inform a new upload is being processed
235
  *
236
- * Mainly used to remove an eventual warning
237
  *
238
  * @event BeforeUpload
239
  * @param {plupload.Uploader} uploader Uploader instance.
@@ -244,7 +244,7 @@ window.bp = window.bp || {};
244
  } );
245
 
246
  /**
247
- * Reset the filesQueue once the upload is complete
248
  *
249
  * @event BeforeUpload
250
  * @param {plupload.Uploader} uploader Uploader instance.
@@ -256,7 +256,7 @@ window.bp = window.bp || {};
256
  } );
257
 
258
  /**
259
- * Map Plupload errors & Create a warning when plupload failed
260
  *
261
  * @event Error
262
  * @param {plupload.Uploader} uploader Uploader instance.
@@ -291,19 +291,19 @@ window.bp = window.bp || {};
291
  } );
292
  };
293
 
294
- // Create a very generic Model for files
295
  bp.Models.File = Backbone.Model.extend( {
296
  file: {}
297
  } );
298
 
299
- // Add Collections to store queue, uploaded files and errors
300
  $.extend( bp.Uploader, {
301
  filesQueue : new Backbone.Collection(),
302
  filesUploaded : new Backbone.Collection(),
303
  filesError : new Backbone.Collection()
304
  } );
305
 
306
- // Extend wp.Backbone.View with .prepare() and .inject()
307
  bp.View = bp.Backbone.View.extend( {
308
  inject: function( selector ) {
309
  this.render();
@@ -320,7 +320,7 @@ window.bp = window.bp || {};
320
  }
321
  } );
322
 
323
- // BuddyPress Uploader main view
324
  bp.Views.Uploader = bp.View.extend( {
325
  className: 'bp-uploader-window',
326
  template: bp.template( 'upload-window' ),
@@ -358,17 +358,17 @@ window.bp = window.bp || {};
358
  return;
359
  }
360
 
361
- // Remove all warning views
362
  _.each( this.warnings, function( view ) {
363
  view.remove();
364
  } );
365
 
366
- // Reset Warnings
367
  this.warnings = [];
368
  }
369
  } );
370
 
371
- // BuddyPress Uploader warning view
372
  bp.Views.uploaderWarning = bp.View.extend( {
373
  tagName: 'p',
374
  className: 'warning',
@@ -383,7 +383,7 @@ window.bp = window.bp || {};
383
  }
384
  } );
385
 
386
- // BuddyPress Uploader Files view
387
  bp.Views.uploaderStatus = bp.View.extend( {
388
  className: 'files',
389
 
@@ -410,7 +410,7 @@ window.bp = window.bp || {};
410
  }
411
  } );
412
 
413
- // BuddyPress Uploader File progress view
414
  bp.Views.uploaderProgress = bp.View.extend( {
415
  className: 'bp-uploader-progress',
416
  template: bp.template( 'progress-window' )
5
 
6
  ( function( exports, $ ) {
7
 
8
+ // Bail if not set.
9
  if ( typeof BP_Uploader === 'undefined' ) {
10
  return;
11
  }
17
  */
18
  _.extend( bp, _.pick( wp, 'Backbone', 'ajax', 'template' ) );
19
 
20
+ // Init Models, Collections, Views and the BuddyPress Uploader.
21
  bp.Models = bp.Models || {};
22
  bp.Collections = bp.Collections || {};
23
  bp.Views = bp.Views || {};
26
  /**
27
  * BuddyPress Uploader.
28
  *
29
+ * This is an adapted version of wp.Uploader.
30
  */
31
  bp.Uploader.uploader = function() {
32
  var self = this,
47
  return;
48
  }
49
 
50
+ // Make sure flash sends cookies (seems in IE it does without switching to urlstream mode).
51
  if ( ! isIE && 'flash' === plupload.predictRuntime( this.params.defaults ) &&
52
  ( ! this.params.defaults.required_features || ! this.params.defaults.required_features.hasOwnProperty( 'send_binary_string' ) ) ) {
53
 
97
 
98
  } );
99
 
100
+ // See https://core.trac.wordpress.org/ticket/37039.
101
  this.uploader.bind( 'postinit', function( up ) {
102
  up.refresh();
103
  });
104
 
105
+ // Init BuddyPress Uploader.
106
  this.uploader.init();
107
 
108
  /**
109
  * Feedback callback.
110
  *
111
  * Add a new message to the errors collection, so it's possible
112
+ * to give some feedback to the user.
113
  *
114
  * @param {string} message
115
  * @param {object} data
140
 
141
  /**
142
  * In case the multiple selection is false (eg: avatar) stop the process and send
143
+ * and event containing a warning.
144
  */
145
  if ( ! uploader.settings.multi_selection && files.length > 1 ) {
146
  for ( var i in files ) {
181
  } );
182
 
183
  /**
184
+ * Update each file item on progress.
185
  *
186
  * @event UploadProgress
187
  * @param {plupload.Uploader} uploader Uploader instance.
225
 
226
  file.item.set( _.extend( response.data, { uploading: false } ) );
227
 
228
+ // Add the file to the Uploaded ones.
229
  bp.Uploader.filesUploaded.add( file.item );
230
 
231
  } );
232
 
233
  /**
234
+ * Trigger an event to inform a new upload is being processed.
235
  *
236
+ * Mainly used to remove an eventual warning.
237
  *
238
  * @event BeforeUpload
239
  * @param {plupload.Uploader} uploader Uploader instance.
244
  } );
245
 
246
  /**
247
+ * Reset the filesQueue once the upload is complete.
248
  *
249
  * @event BeforeUpload
250
  * @param {plupload.Uploader} uploader Uploader instance.
256
  } );
257
 
258
  /**
259
+ * Map Plupload errors & Create a warning when plupload failed.
260
  *
261
  * @event Error
262
  * @param {plupload.Uploader} uploader Uploader instance.
291
  } );
292
  };
293
 
294
+ // Create a very generic Model for files.
295
  bp.Models.File = Backbone.Model.extend( {
296
  file: {}
297
  } );
298
 
299
+ // Add Collections to store queue, uploaded files and errors.
300
  $.extend( bp.Uploader, {
301
  filesQueue : new Backbone.Collection(),
302
  filesUploaded : new Backbone.Collection(),
303
  filesError : new Backbone.Collection()
304
  } );
305
 
306
+ // Extend wp.Backbone.View with .prepare() and .inject().
307
  bp.View = bp.Backbone.View.extend( {
308
  inject: function( selector ) {
309
  this.render();
320
  }
321
  } );
322
 
323
+ // BuddyPress Uploader main view.
324
  bp.Views.Uploader = bp.View.extend( {
325
  className: 'bp-uploader-window',
326
  template: bp.template( 'upload-window' ),
358
  return;
359
  }
360
 
361
+ // Remove all warning views.
362
  _.each( this.warnings, function( view ) {
363
  view.remove();
364
  } );
365
 
366
+ // Reset Warnings.
367
  this.warnings = [];
368
  }
369
  } );
370
 
371
+ // BuddyPress Uploader warning view.
372
  bp.Views.uploaderWarning = bp.View.extend( {
373
  tagName: 'p',
374
  className: 'warning',
383
  }
384
  } );
385
 
386
+ // BuddyPress Uploader Files view.
387
  bp.Views.uploaderStatus = bp.View.extend( {
388
  className: 'files',
389
 
410
  }
411
  } );
412
 
413
+ // BuddyPress Uploader File progress view.
414
  bp.Views.uploaderProgress = bp.View.extend( {
415
  className: 'bp-uploader-progress',
416
  template: bp.template( 'progress-window' )
bp-core/js/cover-image.js CHANGED
@@ -4,7 +4,7 @@ window.bp = window.bp || {};
4
 
5
  ( function( exports, $ ) {
6
 
7
- // Bail if not set
8
  if ( typeof BP_Uploader === 'undefined' ) {
9
  return;
10
  }
@@ -16,41 +16,41 @@ window.bp = window.bp || {};
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' ) ) ) {
@@ -59,12 +59,12 @@ window.bp = window.bp || {};
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
  ) );
@@ -74,13 +74,13 @@ window.bp = window.bp || {};
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
 
@@ -88,7 +88,7 @@ window.bp = window.bp || {};
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();
@@ -114,7 +114,7 @@ window.bp = window.bp || {};
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'
@@ -125,11 +125,11 @@ window.bp = window.bp || {};
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 } );
@@ -182,7 +182,7 @@ window.bp = window.bp || {};
182
  }
183
  };
184
 
185
- // Custom Uploader Files view
186
  bp.Views.coverImageUploadProgress = bp.Views.uploaderStatus.extend( {
187
  className: 'files',
188
 
@@ -197,7 +197,7 @@ window.bp = window.bp || {};
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';
@@ -213,16 +213,16 @@ window.bp = window.bp || {};
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 } );
@@ -238,7 +238,7 @@ window.bp = window.bp || {};
238
  }
239
  } );
240
 
241
- // BuddyPress Cover Image Feedback view
242
  bp.Views.CoverImageStatus = bp.View.extend( {
243
  tagName: 'p',
244
  className: 'updated',
@@ -255,7 +255,7 @@ window.bp = window.bp || {};
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',
4
 
5
  ( function( exports, $ ) {
6
 
7
+ // Bail if not set.
8
  if ( typeof BP_Uploader === 'undefined' ) {
9
  return;
10
  }
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' ) ) ) {
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
  ) );
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
 
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();
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'
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 } );
182
  }
183
  };
184
 
185
+ // Custom Uploader Files view.
186
  bp.Views.coverImageUploadProgress = bp.Views.uploaderStatus.extend( {
187
  className: 'files',
188
 
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';
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 } );
238
  }
239
  } );
240
 
241
+ // BuddyPress Cover Image Feedback view.
242
  bp.Views.CoverImageStatus = bp.View.extend( {
243
  tagName: 'p',
244
  className: 'updated',
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',
bp-core/js/vendor/jquery-cookie.js CHANGED
@@ -8,13 +8,13 @@
8
  * Released under the MIT license
9
  */
10
  (function(factory) {
11
- // AMD
12
  if (typeof define === 'function' && define.amd) {
13
  define(['jquery'], factory);
14
- // CommonJS
15
  } else if (typeof exports === 'object') {
16
  factory(require('jquery'));
17
- // Browser globals
18
  } else {
19
  factory(jQuery);
20
  }
@@ -57,7 +57,7 @@
57
 
58
  var config = $.cookie = function(key, value, options) {
59
 
60
- // Write
61
 
62
  if (value !== undefined && !$.isFunction(value)) {
63
  options = $.extend({}, config.defaults, options);
@@ -76,7 +76,7 @@
76
  ].join(''));
77
  }
78
 
79
- // Read
80
 
81
  var result = key ? undefined : {};
82
 
8
  * Released under the MIT license
9
  */
10
  (function(factory) {
11
+ // AMD.
12
  if (typeof define === 'function' && define.amd) {
13
  define(['jquery'], factory);
14
+ // CommonJS.
15
  } else if (typeof exports === 'object') {
16
  factory(require('jquery'));
17
+ // Browser globals.
18
  } else {
19
  factory(jQuery);
20
  }
57
 
58
  var config = $.cookie = function(key, value, options) {
59
 
60
+ // Write.
61
 
62
  if (value !== undefined && !$.isFunction(value)) {
63
  options = $.extend({}, config.defaults, options);
76
  ].join(''));
77
  }
78
 
79
+ // Read.
80
 
81
  var result = key ? undefined : {};
82
 
bp-core/js/vendor/jquery-scroll-to.js CHANGED
@@ -12,13 +12,13 @@
12
  */
13
 
14
  (function(factory) {
15
- // AMD
16
  if (typeof define === 'function' && define.amd) {
17
  define(['jquery'], factory);
18
- // CommonJS
19
  } else if (typeof exports === 'object') {
20
  factory(require('jquery'));
21
- // Browser globals
22
  } else {
23
  factory(jQuery);
24
  }
@@ -35,13 +35,13 @@
35
  };
36
 
37
  // Returns the element that needs to be animated to scroll the window.
38
- // Kept for backwards compatibility (specially for localScroll & serialScroll)
39
  $scrollTo.window = function() {
40
  return $(window)._scrollable();
41
  };
42
 
43
  // Hack, hack, hack :)
44
- // Returns the real elements to scroll (supports window/iframes, documents and regular nodes)
45
  $.fn._scrollable = function() {
46
  return this.map(function() {
47
  var elem = this,
@@ -73,12 +73,12 @@
73
  }
74
 
75
  settings = $.extend({}, $scrollTo.defaults, settings);
76
- // Speed is still recognized for backwards compatibility
77
  duration = duration || settings.duration;
78
- // Make sure the settings are given right
79
  settings.queue = settings.queue && settings.axis.length > 1;
80
 
81
- // Let's keep the overall duration
82
  if (settings.queue) {
83
  duration /= 2;
84
  }
@@ -88,7 +88,7 @@
88
 
89
  return this._scrollable().each(function() {
90
 
91
- // Null target yields nothing, just like jQuery does
92
  if (target === null) {
93
  return;
94
  }
@@ -99,7 +99,7 @@
99
  win = $elem.is('html,body');
100
 
101
  switch (typeof targ) {
102
- // A number will pass the regex
103
  case 'number':
104
  case 'string':
105
  if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) {
@@ -114,9 +114,9 @@
114
  }
115
  /* falls through */
116
  case 'object':
117
- // DOMElement / jQuery
118
  if (targ.is || targ.style) {
119
- // Get the real position of the target
120
  toff = (targ = $(targ)).offset();
121
  }
122
  }
@@ -130,10 +130,10 @@
130
  old = elem[key],
131
  max = $scrollTo.max(elem, axis);
132
 
133
- if (toff) {// jQuery / DOMElement
134
  attr[key] = toff[pos] + (win ? 0 : old - $elem.offset()[pos]);
135
 
136
- // If it's a dom element, reduce the margin
137
  if (settings.margin) {
138
  attr[key] -= parseInt(targ.css('margin' + Pos)) || 0;
139
  attr[key] -= parseInt(targ.css('border' + Pos + 'Width')) || 0;
@@ -141,29 +141,29 @@
141
 
142
  attr[key] += offset[pos] || 0;
143
 
144
- // Scroll to a fraction of its width/height
145
  if (settings.over[pos]) {
146
  attr[key] += targ[axis === 'x' ? 'width' : 'height']() * settings.over[pos];
147
  }
148
  } else {
149
  var val = targ[pos];
150
- // Handle percentage values
151
  attr[key] = val.slice && val.slice(-1) === '%' ?
152
  parseFloat(val) / 100 * max
153
  : val;
154
  }
155
 
156
- // Number or 'number'
157
  if (settings.limit && /^\d+$/.test(attr[key])) {
158
  // Check the limits
159
  attr[key] = attr[key] <= 0 ? 0 : Math.min(attr[key], max);
160
  }
161
 
162
- // Queueing axes
163
  if (!i && settings.queue) {
164
  // Don't waste time animating, if there's no need.
165
  if (old !== attr[key]) {
166
- // Intermediate animation
167
  animate(settings.onAfterFirst);
168
  }
169
  // Don't animate this axis again in the next iteration.
@@ -203,6 +203,6 @@
203
  return $.isFunction(val) || typeof val === 'object' ? val : {top: val, left: val};
204
  }
205
 
206
- // AMD requirement
207
  return $scrollTo;
208
  }));
12
  */
13
 
14
  (function(factory) {
15
+ // AMD.
16
  if (typeof define === 'function' && define.amd) {
17
  define(['jquery'], factory);
18
+ // CommonJS.
19
  } else if (typeof exports === 'object') {
20
  factory(require('jquery'));
21
+ // Browser globals.
22
  } else {
23
  factory(jQuery);
24
  }
35
  };
36
 
37
  // Returns the element that needs to be animated to scroll the window.
38
+ // Kept for backwards compatibility (specially for localScroll & serialScroll).
39
  $scrollTo.window = function() {
40
  return $(window)._scrollable();
41
  };
42
 
43
  // Hack, hack, hack :)
44
+ // Returns the real elements to scroll (supports window/iframes, documents and regular nodes).
45
  $.fn._scrollable = function() {
46
  return this.map(function() {
47
  var elem = this,
73
  }
74
 
75
  settings = $.extend({}, $scrollTo.defaults, settings);
76
+ // Speed is still recognized for backwards compatibility.
77
  duration = duration || settings.duration;
78
+ // Make sure the settings are given right.
79
  settings.queue = settings.queue && settings.axis.length > 1;
80
 
81
+ // Let's keep the overall duration.
82
  if (settings.queue) {
83
  duration /= 2;
84
  }
88
 
89
  return this._scrollable().each(function() {
90
 
91
+ // Null target yields nothing, just like jQuery does.
92
  if (target === null) {
93
  return;
94
  }
99
  win = $elem.is('html,body');
100
 
101
  switch (typeof targ) {
102
+ // A number will pass the regex.
103
  case 'number':
104
  case 'string':
105
  if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) {
114
  }
115
  /* falls through */
116
  case 'object':
117
+ // DOMElement / jQuery.
118
  if (targ.is || targ.style) {
119
+ // Get the real position of the target.
120
  toff = (targ = $(targ)).offset();
121
  }
122
  }
130
  old = elem[key],
131
  max = $scrollTo.max(elem, axis);
132
 
133
+ if (toff) { // jQuery / DOMElement.
134
  attr[key] = toff[pos] + (win ? 0 : old - $elem.offset()[pos]);
135
 
136
+ // If it's a dom element, reduce the margin.
137
  if (settings.margin) {
138
  attr[key] -= parseInt(targ.css('margin' + Pos)) || 0;
139
  attr[key] -= parseInt(targ.css('border' + Pos + 'Width')) || 0;
141
 
142
  attr[key] += offset[pos] || 0;
143
 
144
+ // Scroll to a fraction of its width/height.
145
  if (settings.over[pos]) {
146
  attr[key] += targ[axis === 'x' ? 'width' : 'height']() * settings.over[pos];
147
  }
148
  } else {
149
  var val = targ[pos];
150
+ // Handle percentage values.
151
  attr[key] = val.slice && val.slice(-1) === '%' ?
152
  parseFloat(val) / 100 * max
153
  : val;
154
  }
155
 
156
+ // Number or 'number'.
157
  if (settings.limit && /^\d+$/.test(attr[key])) {
158
  // Check the limits
159
  attr[key] = attr[key] <= 0 ? 0 : Math.min(attr[key], max);
160
  }
161
 
162
+ // Queueing axes.
163
  if (!i && settings.queue) {
164
  // Don't waste time animating, if there's no need.
165
  if (old !== attr[key]) {
166
+ // Intermediate animation.
167
  animate(settings.onAfterFirst);
168
  }
169
  // Don't animate this axis again in the next iteration.
203
  return $.isFunction(val) || typeof val === 'object' ? val : {top: val, left: val};
204
  }
205
 
206
+ // AMD requirement.
207
  return $scrollTo;
208
  }));
bp-core/js/vendor/jquery.atwho.js CHANGED
@@ -6,7 +6,7 @@
6
  */
7
  (function (root, factory) {
8
  if (typeof define === 'function' && define.amd) {
9
- // AMD. Register as an anonymous module unless amdModuleId is set
10
  define(["jquery"], function (a0) {
11
  return (factory(a0));
12
  });
6
  */
7
  (function (root, factory) {
8
  if (typeof define === 'function' && define.amd) {
9
+ // AMD. Register as an anonymous module unless amdModuleId is set.
10
  define(["jquery"], function (a0) {
11
  return (factory(a0));
12
  });
bp-core/js/vendor/jquery.caret.js CHANGED
@@ -6,7 +6,7 @@
6
  });
7
  } else if (typeof exports === 'object') {
8
  // Node. Does not work with strict CommonJS, but
9
- // only CommonJS-like enviroments that support module.exports,
10
  // like Node.
11
  module.exports = factory(require("jquery"));
12
  } else {
6
  });
7
  } else if (typeof exports === 'object') {
8
  // Node. Does not work with strict CommonJS, but
9
+ // only CommonJS-like environments that support module.exports,
10
  // like Node.
11
  module.exports = factory(require("jquery"));
12
  } else {
bp-core/js/vendor/moment-js/moment.js CHANGED
@@ -28,14 +28,14 @@
28
 
29
  function isObject(input) {
30
  // IE8 will treat undefined and null as object if it wasn't for
31
- // input != null
32
  return input != null && Object.prototype.toString.call(input) === '[object Object]';
33
  }
34
 
35
  function isObjectEmpty(obj) {
36
  var k;
37
  for (k in obj) {
38
- // even if its not own property I'd still call it non-empty
39
  return false;
40
  }
41
  return true;
@@ -224,7 +224,7 @@
224
 
225
  var updateInProgress = false;
226
 
227
- // Moment prototype object
228
  function Moment(config) {
229
  copyConfig(this, config);
230
  this._d = new Date(config._d != null ? config._d.getTime() : NaN);
@@ -261,7 +261,7 @@
261
  return value;
262
  }
263
 
264
- // compare two arrays, return the number of differences
265
  function compareArrays(array1, array2, dontConvert) {
266
  var len = Math.min(array1.length, array2.length),
267
  lengthDiff = Math.abs(array1.length - array2.length),
@@ -300,7 +300,7 @@
300
  for (var key in arguments[0]) {
301
  arg += key + ': ' + arguments[0][key] + ', ';
302
  }
303
- arg = arg.slice(0, -2); // Remove trailing comma and space
304
  } else {
305
  arg = arguments[i];
306
  }
@@ -367,7 +367,7 @@
367
  if (hasOwnProp(parentConfig, prop) &&
368
  !hasOwnProp(childConfig, prop) &&
369
  isObject(parentConfig[prop])) {
370
- // make sure changes to properties don't modify parent config
371
  res[prop] = extend({}, res[prop]);
372
  }
373
  }
@@ -543,7 +543,7 @@
543
  }
544
  }
545
 
546
- // MOMENTS
547
 
548
  function stringGet (units) {
549
  units = normalizeUnits(units);
@@ -639,7 +639,7 @@
639
  };
640
  }
641
 
642
- // format date using native date object
643
  function formatMoment(m, format) {
644
  if (!m.isValid()) {
645
  return m.localeData().invalidDate();
@@ -688,8 +688,8 @@
688
 
689
  var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
690
 
691
- // any word (or two) characters or numbers including two/three word month in arabic.
692
- // includes scottish gaelic two word and hyphenated months
693
  var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
694
 
695
 
@@ -766,7 +766,7 @@
766
  indexOf = Array.prototype.indexOf;
767
  } else {
768
  indexOf = function (o) {
769
- // I know
770
  var i;
771
  for (i = 0; i < this.length; ++i) {
772
  if (this[i] === o) {
@@ -781,7 +781,7 @@
781
  return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
782
  }
783
 
784
- // FORMATTING
785
 
786
  addFormatToken('M', ['MM', 2], 'Mo', function () {
787
  return this.month() + 1;
@@ -795,15 +795,15 @@
795
  return this.localeData().months(this, format);
796
  });
797
 
798
- // ALIASES
799
 
800
  addUnitAlias('month', 'M');
801
 
802
- // PRIORITY
803
 
804
  addUnitPriority('month', 8);
805
 
806
- // PARSING
807
 
808
  addRegexToken('M', match1to2);
809
  addRegexToken('MM', match1to2, match2);
@@ -820,7 +820,7 @@
820
 
821
  addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
822
  var month = config._locale.monthsParse(input, token, config._strict);
823
- // if we didn't find a month name, mark the date as invalid.
824
  if (month != null) {
825
  array[MONTH] = month;
826
  } else {
@@ -828,7 +828,7 @@
828
  }
829
  });
830
 
831
- // LOCALES
832
 
833
  var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/;
834
  var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
@@ -903,11 +903,11 @@
903
  this._shortMonthsParse = [];
904
  }
905
 
906
- // TODO: add sorting
907
  // Sorting makes sure if one month (or abbr) is a prefix of another
908
- // see sorting in computeMonthsParse
909
  for (i = 0; i < 12; i++) {
910
- // make the regex if we don't have it already
911
  mom = create_utc__createUTC([2000, i]);
912
  if (strict && !this._longMonthsParse[i]) {
913
  this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
@@ -917,7 +917,7 @@
917
  regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
918
  this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
919
  }
920
- // test the regex
921
  if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
922
  return i;
923
  } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
@@ -928,13 +928,13 @@
928
  }
929
  }
930
 
931
- // MOMENTS
932
 
933
  function setMonth (mom, value) {
934
  var dayOfMonth;
935
 
936
  if (!mom.isValid()) {
937
- // No op
938
  return mom;
939
  }
940
 
@@ -1017,7 +1017,7 @@
1017
  var shortPieces = [], longPieces = [], mixedPieces = [],
1018
  i, mom;
1019
  for (i = 0; i < 12; i++) {
1020
- // make the regex if we don't have it already
1021
  mom = create_utc__createUTC([2000, i]);
1022
  shortPieces.push(this.monthsShort(mom, ''));
1023
  longPieces.push(this.months(mom, ''));
@@ -1043,7 +1043,7 @@
1043
  this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
1044
  }
1045
 
1046
- // FORMATTING
1047
 
1048
  addFormatToken('Y', 0, 0, function () {
1049
  var y = this.year();
@@ -1058,15 +1058,15 @@
1058
  addFormatToken(0, ['YYYYY', 5], 0, 'year');
1059
  addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
1060
 
1061
- // ALIASES
1062
 
1063
  addUnitAlias('year', 'y');
1064
 
1065
- // PRIORITIES
1066
 
1067
  addUnitPriority('year', 1);
1068
 
1069
- // PARSING
1070
 
1071
  addRegexToken('Y', matchSigned);
1072
  addRegexToken('YY', match1to2, match2);
@@ -1085,7 +1085,7 @@
1085
  array[YEAR] = parseInt(input, 10);
1086
  });
1087
 
1088
- // HELPERS
1089
 
1090
  function daysInYear(year) {
1091
  return isLeapYear(year) ? 366 : 365;
@@ -1095,13 +1095,13 @@
1095
  return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
1096
  }
1097
 
1098
- // HOOKS
1099
 
1100
  utils_hooks__hooks.parseTwoDigitYear = function (input) {
1101
  return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
1102
  };
1103
 
1104
- // MOMENTS
1105
 
1106
  var getSetYear = makeGetSet('FullYear', true);
1107
 
@@ -1110,11 +1110,11 @@
1110
  }
1111
 
1112
  function createDate (y, m, d, h, M, s, ms) {
1113
- //can't just apply() to create a date:
1114
- //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
1115
  var date = new Date(y, m, d, h, M, s, ms);
1116
 
1117
- //the date constructor remaps years 0-99 to 1900-1999
1118
  if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
1119
  date.setFullYear(y);
1120
  }
@@ -1124,24 +1124,24 @@
1124
  function createUTCDate (y) {
1125
  var date = new Date(Date.UTC.apply(null, arguments));
1126
 
1127
- //the Date.UTC function remaps years 0-99 to 1900-1999
1128
  if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
1129
  date.setUTCFullYear(y);
1130
  }
1131
  return date;
1132
  }
1133
 
1134
- // start-of-first-week - start-of-year
1135
  function firstWeekOffset(year, dow, doy) {
1136
- var // first-week day -- which january is always in the first week (4 for iso, 1 for other)
1137
  fwd = 7 + dow - doy,
1138
- // first-week day local weekday -- which local weekday is fwd
1139
  fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
1140
 
1141
  return -fwdlw + fwd - 1;
1142
  }
1143
 
1144
- //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1145
  function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
1146
  var localWeekday = (7 + weekday - dow) % 7,
1147
  weekOffset = firstWeekOffset(year, dow, doy),
@@ -1193,22 +1193,22 @@
1193
  return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
1194
  }
1195
 
1196
- // FORMATTING
1197
 
1198
  addFormatToken('w', ['ww', 2], 'wo', 'week');
1199
  addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
1200
 
1201
- // ALIASES
1202
 
1203
  addUnitAlias('week', 'w');
1204
  addUnitAlias('isoWeek', 'W');
1205
 
1206
- // PRIORITIES
1207
 
1208
  addUnitPriority('week', 5);
1209
  addUnitPriority('isoWeek', 5);
1210
 
1211
- // PARSING
1212
 
1213
  addRegexToken('w', match1to2);
1214
  addRegexToken('ww', match1to2, match2);
@@ -1219,9 +1219,9 @@
1219
  week[token.substr(0, 1)] = toInt(input);
1220
  });
1221
 
1222
- // HELPERS
1223
 
1224
- // LOCALES
1225
 
1226
  function localeWeek (mom) {
1227
  return weekOfYear(mom, this._week.dow, this._week.doy).week;
@@ -1240,7 +1240,7 @@
1240
  return this._week.doy;
1241
  }
1242
 
1243
- // MOMENTS
1244
 
1245
  function getSetWeek (input) {
1246
  var week = this.localeData().week(this);
@@ -1252,7 +1252,7 @@
1252
  return input == null ? week : this.add((input - week) * 7, 'd');
1253
  }
1254
 
1255
- // FORMATTING
1256
 
1257
  addFormatToken('d', 0, 'do', 'day');
1258
 
@@ -1271,18 +1271,18 @@
1271
  addFormatToken('e', 0, 0, 'weekday');
1272
  addFormatToken('E', 0, 0, 'isoWeekday');
1273
 
1274
- // ALIASES
1275
 
1276
  addUnitAlias('day', 'd');
1277
  addUnitAlias('weekday', 'e');
1278
  addUnitAlias('isoWeekday', 'E');
1279
 
1280
- // PRIORITY
1281
  addUnitPriority('day', 11);
1282
  addUnitPriority('weekday', 11);
1283
  addUnitPriority('isoWeekday', 11);
1284
 
1285
- // PARSING
1286
 
1287
  addRegexToken('d', match1to2);
1288
  addRegexToken('e', match1to2);
@@ -1299,7 +1299,7 @@
1299
 
1300
  addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
1301
  var weekday = config._locale.weekdaysParse(input, token, config._strict);
1302
- // if we didn't get a weekday name, mark the date as invalid
1303
  if (weekday != null) {
1304
  week.d = weekday;
1305
  } else {
@@ -1311,7 +1311,7 @@
1311
  week[token] = toInt(input);
1312
  });
1313
 
1314
- // HELPERS
1315
 
1316
  function parseWeekday(input, locale) {
1317
  if (typeof input !== 'string') {
@@ -1337,7 +1337,7 @@
1337
  return isNaN(input) ? null : input;
1338
  }
1339
 
1340
- // LOCALES
1341
 
1342
  var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
1343
  function localeWeekdays (m, format) {
@@ -1437,7 +1437,7 @@
1437
  }
1438
 
1439
  for (i = 0; i < 7; i++) {
1440
- // make the regex if we don't have it already
1441
 
1442
  mom = create_utc__createUTC([2000, 1]).day(i);
1443
  if (strict && !this._fullWeekdaysParse[i]) {
@@ -1449,7 +1449,7 @@
1449
  regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
1450
  this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
1451
  }
1452
- // test the regex
1453
  if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
1454
  return i;
1455
  } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
@@ -1462,7 +1462,7 @@
1462
  }
1463
  }
1464
 
1465
- // MOMENTS
1466
 
1467
  function getSetDayOfWeek (input) {
1468
  if (!this.isValid()) {
@@ -1490,7 +1490,7 @@
1490
  return input != null ? this : NaN;
1491
  }
1492
 
1493
- // behaves the same as moment#day except
1494
  // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
1495
  // as a setter, sunday should belong to the previous week.
1496
 
@@ -1604,7 +1604,7 @@
1604
  this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
1605
  }
1606
 
1607
- // FORMATTING
1608
 
1609
  function hFormat() {
1610
  return this.hours() % 12 || 12;
@@ -1645,14 +1645,14 @@
1645
  meridiem('a', true);
1646
  meridiem('A', false);
1647
 
1648
- // ALIASES
1649
 
1650
  addUnitAlias('hour', 'h');
1651
 
1652
- // PRIORITY
1653
  addUnitPriority('hour', 13);
1654
 
1655
- // PARSING
1656
 
1657
  function matchMeridiem (isStrict, locale) {
1658
  return locale._meridiemParse;
@@ -1706,7 +1706,7 @@
1706
  array[SECOND] = toInt(input.substr(pos2));
1707
  });
1708
 
1709
- // LOCALES
1710
 
1711
  function localeIsPM (input) {
1712
  // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
@@ -1724,7 +1724,7 @@
1724
  }
1725
 
1726
 
1727
- // MOMENTS
1728
 
1729
  // Setting the hour should keep the time, because the user explicitly
1730
  // specified which hour he wants. So trying to maintain the same hour (in
@@ -1752,7 +1752,7 @@
1752
  meridiemParse: defaultLocaleMeridiemParse
1753
  };
1754
 
1755
- // internal storage for locale config files
1756
  var locales = {};
1757
  var globalLocale;
1758
 
@@ -1760,7 +1760,7 @@
1760
  return key ? key.toLowerCase().replace('_', '-') : key;
1761
  }
1762
 
1763
- // pick the locale from the array
1764
  // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
1765
  // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
1766
  function chooseLocale(names) {
@@ -1777,7 +1777,7 @@
1777
  return locale;
1778
  }
1779
  if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
1780
- //the next array item is better than a shallower substring of this one
1781
  break;
1782
  }
1783
  j--;
@@ -1789,14 +1789,14 @@
1789
 
1790
  function loadLocale(name) {
1791
  var oldLocale = null;
1792
- // TODO: Find a better way to register and load all the locales in Node
1793
  if (!locales[name] && (typeof module !== 'undefined') &&
1794
  module && module.exports) {
1795
  try {
1796
  oldLocale = globalLocale._abbr;
1797
  require('./locale/' + name);
1798
- // because defineLocale currently also sets the global locale, we
1799
- // want to undo that for lazy loaded locales
1800
  locale_locales__getSetGlobalLocale(oldLocale);
1801
  } catch (e) { }
1802
  }
@@ -1840,19 +1840,19 @@
1840
  if (locales[config.parentLocale] != null) {
1841
  parentConfig = locales[config.parentLocale]._config;
1842
  } else {
1843
- // treat as if there is no base config
1844
  deprecateSimple('parentLocaleUndefined',
1845
  'specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/');
1846
  }
1847
  }
1848
  locales[name] = new Locale(mergeConfigs(parentConfig, config));
1849
 
1850
- // backwards compat for now: also set the locale
1851
  locale_locales__getSetGlobalLocale(name);
1852
 
1853
  return locales[name];
1854
  } else {
1855
- // useful for testing
1856
  delete locales[name];
1857
  return null;
1858
  }
@@ -1861,7 +1861,7 @@
1861
  function updateLocale(name, config) {
1862
  if (config != null) {
1863
  var locale, parentConfig = baseConfig;
1864
- // MERGE
1865
  if (locales[name] != null) {
1866
  parentConfig = locales[name]._config;
1867
  }
@@ -1870,10 +1870,10 @@
1870
  locale.parentLocale = locales[name];
1871
  locales[name] = locale;
1872
 
1873
- // backwards compat for now: also set the locale
1874
  locale_locales__getSetGlobalLocale(name);
1875
  } else {
1876
- // pass null for config to unupdate, useful for tests
1877
  if (locales[name] != null) {
1878
  if (locales[name].parentLocale != null) {
1879
  locales[name] = locales[name].parentLocale;
@@ -1885,7 +1885,7 @@
1885
  return locales[name];
1886
  }
1887
 
1888
- // returns locale data
1889
  function locale_locales__getLocale (key) {
1890
  var locale;
1891
 
@@ -1898,7 +1898,7 @@
1898
  }
1899
 
1900
  if (!isArray(key)) {
1901
- //short-circuit everything else
1902
  locale = loadLocale(key);
1903
  if (locale) {
1904
  return locale;
@@ -1959,13 +1959,13 @@
1959
  ['YYYY-MM', /\d{4}-\d\d/, false],
1960
  ['YYYYYYMMDD', /[+-]\d{10}/],
1961
  ['YYYYMMDD', /\d{8}/],
1962
- // YYYYMM is NOT allowed by the standard
1963
  ['GGGG[W]WWE', /\d{4}W\d{3}/],
1964
  ['GGGG[W]WW', /\d{4}W\d{2}/, false],
1965
  ['YYYYDDD', /\d{7}/]
1966
  ];
1967
 
1968
- // iso time formats and regexes
1969
  var isoTimes = [
1970
  ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
1971
  ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
@@ -1980,7 +1980,7 @@
1980
 
1981
  var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
1982
 
1983
- // date from iso format
1984
  function configFromISO(config) {
1985
  var i, l,
1986
  string = config._i,
@@ -2033,7 +2033,7 @@
2033
  }
2034
  }
2035
 
2036
- // date from iso format or fallback
2037
  function configFromString(config) {
2038
  var matched = aspNetJsonRegex.exec(config._i);
2039
 
@@ -2079,10 +2079,10 @@
2079
  return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
2080
  }
2081
 
2082
- // convert an array to a date.
2083
  // the array should mirror the parameters below
2084
  // note: all values past the year are optional and will default to the lowest possible value.
2085
- // [year, month, day , hour, minute, second, millisecond]
2086
  function configFromArray (config) {
2087
  var i, date, input = [], currentDate, yearToUse;
2088
 
@@ -2092,12 +2092,12 @@
2092
 
2093
  currentDate = currentDateArray(config);
2094
 
2095
- //compute day of the year from weeks and weekdays
2096
  if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
2097
  dayOfYearFromWeekInfo(config);
2098
  }
2099
 
2100
- //if the day of the year is set, figure out what it is
2101
  if (config._dayOfYear) {
2102
  yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
2103
 
@@ -2119,7 +2119,7 @@
2119
  config._a[i] = input[i] = currentDate[i];
2120
  }
2121
 
2122
- // Zero out whatever was not defaulted, including time
2123
  for (; i < 7; i++) {
2124
  config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
2125
  }
@@ -2171,19 +2171,19 @@
2171
  week = defaults(w.w, 1);
2172
 
2173
  if (w.d != null) {
2174
- // weekday -- low day numbers are considered next week
2175
  weekday = w.d;
2176
  if (weekday < 0 || weekday > 6) {
2177
  weekdayOverflow = true;
2178
  }
2179
  } else if (w.e != null) {
2180
- // local weekday -- counting starts from begining of week
2181
  weekday = w.e + dow;
2182
  if (w.e < 0 || w.e > 6) {
2183
  weekdayOverflow = true;
2184
  }
2185
  } else {
2186
- // default to begining of week
2187
  weekday = dow;
2188
  }
2189
  }
@@ -2198,12 +2198,12 @@
2198
  }
2199
  }
2200
 
2201
- // constant that refers to the ISO standard
2202
  utils_hooks__hooks.ISO_8601 = function () {};
2203
 
2204
- // date from string and format string
2205
  function configFromStringAndFormat(config) {
2206
- // TODO: Move this to another part of the creation flow to prevent circular deps
2207
  if (config._f === utils_hooks__hooks.ISO_8601) {
2208
  configFromISO(config);
2209
  return;
@@ -2212,7 +2212,7 @@
2212
  config._a = [];
2213
  getParsingFlags(config).empty = true;
2214
 
2215
- // This array is used to make a Date, either with `new Date` or `Date.UTC`
2216
  var string = '' + config._i,
2217
  i, parsedInput, tokens, token, skipped,
2218
  stringLength = string.length,
@@ -2223,7 +2223,7 @@
2223
  for (i = 0; i < tokens.length; i++) {
2224
  token = tokens[i];
2225
  parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
2226
- // console.log('token', token, 'parsedInput', parsedInput,
2227
  // 'regex', getParseRegexForToken(token, config));
2228
  if (parsedInput) {
2229
  skipped = string.substr(0, string.indexOf(parsedInput));
@@ -2233,7 +2233,7 @@
2233
  string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
2234
  totalParsedInputLength += parsedInput.length;
2235
  }
2236
- // don't parse if it's not a known token
2237
  if (formatTokenFunctions[token]) {
2238
  if (parsedInput) {
2239
  getParsingFlags(config).empty = false;
@@ -2248,13 +2248,13 @@
2248
  }
2249
  }
2250
 
2251
- // add remaining unparsed input length to the string
2252
  getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
2253
  if (string.length > 0) {
2254
  getParsingFlags(config).unusedInput.push(string);
2255
  }
2256
 
2257
- // clear _12h flag if hour is <= 12
2258
  if (config._a[HOUR] <= 12 &&
2259
  getParsingFlags(config).bigHour === true &&
2260
  config._a[HOUR] > 0) {
@@ -2275,13 +2275,13 @@
2275
  var isPm;
2276
 
2277
  if (meridiem == null) {
2278
- // nothing to do
2279
  return hour;
2280
  }
2281
  if (locale.meridiemHour != null) {
2282
  return locale.meridiemHour(hour, meridiem);
2283
  } else if (locale.isPM != null) {
2284
- // Fallback
2285
  isPm = locale.isPM(meridiem);
2286
  if (isPm && hour < 12) {
2287
  hour += 12;
@@ -2291,12 +2291,12 @@
2291
  }
2292
  return hour;
2293
  } else {
2294
- // this is not supposed to happen
2295
  return hour;
2296
  }
2297
  }
2298
 
2299
- // date from string and array of format strings
2300
  function configFromStringAndArray(config) {
2301
  var tempConfig,
2302
  bestMoment,
@@ -2324,10 +2324,10 @@
2324
  continue;
2325
  }
2326
 
2327
- // if there is any input that was not parsed add a penalty for that format
2328
  currentScore += getParsingFlags(tempConfig).charsLeftOver;
2329
 
2330
- //or tokens
2331
  currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
2332
 
2333
  getParsingFlags(tempConfig).score = currentScore;
@@ -2357,7 +2357,7 @@
2357
  function createFromConfig (config) {
2358
  var res = new Moment(checkOverflow(prepareConfig(config)));
2359
  if (res._nextDay) {
2360
- // Adding is smart enough around DST
2361
  res.add(1, 'd');
2362
  res._nextDay = undefined;
2363
  }
@@ -2433,7 +2433,7 @@
2433
  (isArray(input) && input.length === 0)) {
2434
  input = undefined;
2435
  }
2436
- // object construction must be done this way.
2437
  // https://github.com/moment/moment/issues/1423
2438
  c._isAMomentObject = true;
2439
  c._useUTC = c._isUTC = isUTC;
@@ -2524,13 +2524,13 @@
2524
  seconds = normalizedInput.second || 0,
2525
  milliseconds = normalizedInput.millisecond || 0;
2526
 
2527
- // representation for dateAddRemove
2528
  this._milliseconds = +milliseconds +
2529
  seconds * 1e3 + // 1000
2530
  minutes * 6e4 + // 1000 * 60
2531
- hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
2532
  // Because of dateAddRemove treats 24 hours as different from a
2533
- // day when working around DST, we need to store them separately
2534
  this._days = +days +
2535
  weeks * 7;
2536
  // It is impossible translate months into days without knowing
@@ -2559,7 +2559,7 @@
2559
  }
2560
  }
2561
 
2562
- // FORMATTING
2563
 
2564
  function offset (token, separator) {
2565
  addFormatToken(token, 0, 0, function () {
@@ -2576,7 +2576,7 @@
2576
  offset('Z', ':');
2577
  offset('ZZ', '');
2578
 
2579
- // PARSING
2580
 
2581
  addRegexToken('Z', matchShortOffset);
2582
  addRegexToken('ZZ', matchShortOffset);
@@ -2585,11 +2585,11 @@
2585
  config._tzm = offsetFromString(matchShortOffset, input);
2586
  });
2587
 
2588
- // HELPERS
2589
 
2590
- // timezone chunker
2591
  // '+10:00' > ['10', '00']
2592
- // '-1530' > ['-15', '30']
2593
  var chunkOffset = /([\+\-]|\d\d)/gi;
2594
 
2595
  function offsetFromString(matcher, string) {
@@ -2769,17 +2769,17 @@
2769
  return this.isValid() ? this._isUTC && this._offset === 0 : false;
2770
  }
2771
 
2772
- // ASP.NET json date format regex
2773
  var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
2774
 
2775
  // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
2776
  // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
2777
- // and further modified to allow for strings containing both week and day
2778
  var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
2779
 
2780
  function create__createDuration (input, key) {
2781
  var duration = input,
2782
- // matching against regexp is expensive, do it on demand
2783
  match = null,
2784
  sign,
2785
  ret,
@@ -2806,7 +2806,7 @@
2806
  h : toInt(match[HOUR]) * sign,
2807
  m : toInt(match[MINUTE]) * sign,
2808
  s : toInt(match[SECOND]) * sign,
2809
- ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match
2810
  };
2811
  } else if (!!(match = isoRegex.exec(input))) {
2812
  sign = (match[1] === '-') ? -1 : 1;
@@ -2819,7 +2819,7 @@
2819
  m : parseIso(match[7], sign),
2820
  s : parseIso(match[8], sign)
2821
  };
2822
- } else if (duration == null) {// checks for null or undefined
2823
  duration = {};
2824
  } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
2825
  diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));
@@ -2845,7 +2845,7 @@
2845
  // converts floats to ints.
2846
  // inp may be undefined, so careful calling replace on it.
2847
  var res = inp && parseFloat(inp.replace(',', '.'));
2848
- // apply sign while we're at it
2849
  return (isNaN(res) ? 0 : res) * sign;
2850
  }
2851
 
@@ -2881,11 +2881,11 @@
2881
  return res;
2882
  }
2883
 
2884
- // TODO: remove 'name' arg after deprecation is removed
2885
  function createAdder(direction, name) {
2886
  return function (val, period) {
2887
  var dur, tmp;
2888
- //invert the arguments, but complain about it
2889
  if (period !== null && !isNaN(+period)) {
2890
  deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
2891
  'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
@@ -2905,7 +2905,7 @@
2905
  months = absRound(duration._months);
2906
 
2907
  if (!mom.isValid()) {
2908
- // No op
2909
  return;
2910
  }
2911
 
@@ -3048,23 +3048,23 @@
3048
  }
3049
 
3050
  function monthDiff (a, b) {
3051
- // difference in months
3052
  var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
3053
- // b is in (anchor - 1 month, anchor + 1 month)
3054
  anchor = a.clone().add(wholeMonthDiff, 'months'),
3055
  anchor2, adjust;
3056
 
3057
  if (b - anchor < 0) {
3058
  anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
3059
- // linear across the month
3060
  adjust = (b - anchor) / (anchor - anchor2);
3061
  } else {
3062
  anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
3063
- // linear across the month
3064
  adjust = (b - anchor) / (anchor2 - anchor);
3065
  }
3066
 
3067
- //check for negative zero, return zero if negative zero
3068
  return -(wholeMonthDiff + adjust) || 0;
3069
  }
3070
 
@@ -3079,7 +3079,7 @@
3079
  var m = this.clone().utc();
3080
  if (0 < m.year() && m.year() <= 9999) {
3081
  if (isFunction(Date.prototype.toISOString)) {
3082
- // native implementation is ~50x faster, use it when we can
3083
  return this.toDate().toISOString();
3084
  } else {
3085
  return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
@@ -3159,7 +3159,7 @@
3159
 
3160
  function startOf (units) {
3161
  units = normalizeUnits(units);
3162
- // the following switch intentionally omits break keywords
3163
  // to utilize falling through the cases.
3164
  switch (units) {
3165
  case 'year':
@@ -3185,7 +3185,7 @@
3185
  this.milliseconds(0);
3186
  }
3187
 
3188
- // weeks are a special case
3189
  if (units === 'week') {
3190
  this.weekday(0);
3191
  }
@@ -3193,7 +3193,7 @@
3193
  this.isoWeekday(1);
3194
  }
3195
 
3196
- // quarters are also special
3197
  if (units === 'quarter') {
3198
  this.month(Math.floor(this.month() / 3) * 3);
3199
  }
@@ -3246,7 +3246,7 @@
3246
  }
3247
 
3248
  function toJSON () {
3249
- // new Date(NaN).toJSON() === null
3250
  return this.isValid() ? this.toISOString() : null;
3251
  }
3252
 
@@ -3272,7 +3272,7 @@
3272
  };
3273
  }
3274
 
3275
- // FORMATTING
3276
 
3277
  addFormatToken(0, ['gg', 2], 0, function () {
3278
  return this.weekYear() % 100;
@@ -3291,18 +3291,18 @@
3291
  addWeekYearFormatToken('GGGG', 'isoWeekYear');
3292
  addWeekYearFormatToken('GGGGG', 'isoWeekYear');
3293
 
3294
- // ALIASES
3295
 
3296
  addUnitAlias('weekYear', 'gg');
3297
  addUnitAlias('isoWeekYear', 'GG');
3298
 
3299
- // PRIORITY
3300
 
3301
  addUnitPriority('weekYear', 1);
3302
  addUnitPriority('isoWeekYear', 1);
3303
 
3304
 
3305
- // PARSING
3306
 
3307
  addRegexToken('G', matchSigned);
3308
  addRegexToken('g', matchSigned);
@@ -3321,7 +3321,7 @@
3321
  week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
3322
  });
3323
 
3324
- // MOMENTS
3325
 
3326
  function getSetWeekYear (input) {
3327
  return getSetWeekYearHelper.call(this,
@@ -3369,43 +3369,43 @@
3369
  return this;
3370
  }
3371
 
3372
- // FORMATTING
3373
 
3374
  addFormatToken('Q', 0, 'Qo', 'quarter');
3375
 
3376
- // ALIASES
3377
 
3378
  addUnitAlias('quarter', 'Q');
3379
 
3380
- // PRIORITY
3381
 
3382
  addUnitPriority('quarter', 7);
3383
 
3384
- // PARSING
3385
 
3386
  addRegexToken('Q', match1);
3387
  addParseToken('Q', function (input, array) {
3388
  array[MONTH] = (toInt(input) - 1) * 3;
3389
  });
3390
 
3391
- // MOMENTS
3392
 
3393
  function getSetQuarter (input) {
3394
  return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
3395
  }
3396
 
3397
- // FORMATTING
3398
 
3399
  addFormatToken('D', ['DD', 2], 'Do', 'date');
3400
 
3401
- // ALIASES
3402
 
3403
  addUnitAlias('date', 'D');
3404
 
3405
- // PRIOROITY
3406
  addUnitPriority('date', 9);
3407
 
3408
- // PARSING
3409
 
3410
  addRegexToken('D', match1to2);
3411
  addRegexToken('DD', match1to2, match2);
@@ -3418,22 +3418,22 @@
3418
  array[DATE] = toInt(input.match(match1to2)[0], 10);
3419
  });
3420
 
3421
- // MOMENTS
3422
 
3423
  var getSetDayOfMonth = makeGetSet('Date', true);
3424
 
3425
- // FORMATTING
3426
 
3427
  addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
3428
 
3429
- // ALIASES
3430
 
3431
  addUnitAlias('dayOfYear', 'DDD');
3432
 
3433
- // PRIORITY
3434
  addUnitPriority('dayOfYear', 4);
3435
 
3436
- // PARSING
3437
 
3438
  addRegexToken('DDD', match1to3);
3439
  addRegexToken('DDDD', match3);
@@ -3441,60 +3441,60 @@
3441
  config._dayOfYear = toInt(input);
3442
  });
3443
 
3444
- // HELPERS
3445
 
3446
- // MOMENTS
3447
 
3448
  function getSetDayOfYear (input) {
3449
  var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
3450
  return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
3451
  }
3452
 
3453
- // FORMATTING
3454
 
3455
  addFormatToken('m', ['mm', 2], 0, 'minute');
3456
 
3457
- // ALIASES
3458
 
3459
  addUnitAlias('minute', 'm');
3460
 
3461
- // PRIORITY
3462
 
3463
  addUnitPriority('minute', 14);
3464
 
3465
- // PARSING
3466
 
3467
  addRegexToken('m', match1to2);
3468
  addRegexToken('mm', match1to2, match2);
3469
  addParseToken(['m', 'mm'], MINUTE);
3470
 
3471
- // MOMENTS
3472
 
3473
  var getSetMinute = makeGetSet('Minutes', false);
3474
 
3475
- // FORMATTING
3476
 
3477
  addFormatToken('s', ['ss', 2], 0, 'second');
3478
 
3479
- // ALIASES
3480
 
3481
  addUnitAlias('second', 's');
3482
 
3483
- // PRIORITY
3484
 
3485
  addUnitPriority('second', 15);
3486
 
3487
- // PARSING
3488
 
3489
  addRegexToken('s', match1to2);
3490
  addRegexToken('ss', match1to2, match2);
3491
  addParseToken(['s', 'ss'], SECOND);
3492
 
3493
- // MOMENTS
3494
 
3495
  var getSetSecond = makeGetSet('Seconds', false);
3496
 
3497
- // FORMATTING
3498
 
3499
  addFormatToken('S', 0, 0, function () {
3500
  return ~~(this.millisecond() / 100);
@@ -3525,15 +3525,15 @@
3525
  });
3526
 
3527
 
3528
- // ALIASES
3529
 
3530
  addUnitAlias('millisecond', 'ms');
3531
 
3532
- // PRIORITY
3533
 
3534
  addUnitPriority('millisecond', 16);
3535
 
3536
- // PARSING
3537
 
3538
  addRegexToken('S', match1to3, match1);
3539
  addRegexToken('SS', match1to3, match2);
@@ -3551,16 +3551,16 @@
3551
  for (token = 'S'; token.length <= 9; token += 'S') {
3552
  addParseToken(token, parseMs);
3553
  }
3554
- // MOMENTS
3555
 
3556
  var getSetMillisecond = makeGetSet('Milliseconds', false);
3557
 
3558
- // FORMATTING
3559
 
3560
  addFormatToken('z', 0, 0, 'zoneAbbr');
3561
  addFormatToken('zz', 0, 0, 'zoneName');
3562
 
3563
- // MOMENTS
3564
 
3565
  function getZoneAbbr () {
3566
  return this._isUTC ? 'UTC' : '';
@@ -3610,47 +3610,47 @@
3610
  momentPrototype__proto.valueOf = to_type__valueOf;
3611
  momentPrototype__proto.creationData = creationData;
3612
 
3613
- // Year
3614
  momentPrototype__proto.year = getSetYear;
3615
  momentPrototype__proto.isLeapYear = getIsLeapYear;
3616
 
3617
- // Week Year
3618
  momentPrototype__proto.weekYear = getSetWeekYear;
3619
  momentPrototype__proto.isoWeekYear = getSetISOWeekYear;
3620
 
3621
- // Quarter
3622
  momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;
3623
 
3624
- // Month
3625
  momentPrototype__proto.month = getSetMonth;
3626
  momentPrototype__proto.daysInMonth = getDaysInMonth;
3627
 
3628
- // Week
3629
  momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek;
3630
  momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek;
3631
  momentPrototype__proto.weeksInYear = getWeeksInYear;
3632
  momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;
3633
 
3634
- // Day
3635
  momentPrototype__proto.date = getSetDayOfMonth;
3636
  momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek;
3637
  momentPrototype__proto.weekday = getSetLocaleDayOfWeek;
3638
  momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
3639
  momentPrototype__proto.dayOfYear = getSetDayOfYear;
3640
 
3641
- // Hour
3642
  momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;
3643
 
3644
- // Minute
3645
  momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;
3646
 
3647
- // Second
3648
  momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;
3649
 
3650
- // Millisecond
3651
  momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;
3652
 
3653
- // Offset
3654
  momentPrototype__proto.utcOffset = getSetOffset;
3655
  momentPrototype__proto.utc = setOffsetToUTC;
3656
  momentPrototype__proto.local = setOffsetToLocal;
@@ -3662,11 +3662,11 @@
3662
  momentPrototype__proto.isUtc = isUtc;
3663
  momentPrototype__proto.isUTC = isUtc;
3664
 
3665
- // Timezone
3666
  momentPrototype__proto.zoneAbbr = getZoneAbbr;
3667
  momentPrototype__proto.zoneName = getZoneName;
3668
 
3669
- // Deprecations
3670
  momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
3671
  momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
3672
  momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
@@ -3699,19 +3699,19 @@
3699
  prototype__proto.pastFuture = pastFuture;
3700
  prototype__proto.set = locale_set__set;
3701
 
3702
- // Month
3703
  prototype__proto.months = localeMonths;
3704
  prototype__proto.monthsShort = localeMonthsShort;
3705
  prototype__proto.monthsParse = localeMonthsParse;
3706
  prototype__proto.monthsRegex = monthsRegex;
3707
  prototype__proto.monthsShortRegex = monthsShortRegex;
3708
 
3709
- // Week
3710
  prototype__proto.week = localeWeek;
3711
  prototype__proto.firstDayOfYear = localeFirstDayOfYear;
3712
  prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;
3713
 
3714
- // Day of Week
3715
  prototype__proto.weekdays = localeWeekdays;
3716
  prototype__proto.weekdaysMin = localeWeekdaysMin;
3717
  prototype__proto.weekdaysShort = localeWeekdaysShort;
@@ -3721,7 +3721,7 @@
3721
  prototype__proto.weekdaysShortRegex = weekdaysShortRegex;
3722
  prototype__proto.weekdaysMinRegex = weekdaysMinRegex;
3723
 
3724
- // Hours
3725
  prototype__proto.isPM = localeIsPM;
3726
  prototype__proto.meridiem = localeMeridiem;
3727
 
@@ -3827,7 +3827,7 @@
3827
  }
3828
  });
3829
 
3830
- // Side effect imports
3831
  utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
3832
  utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);
3833
 
@@ -3860,12 +3860,12 @@
3860
  return duration._bubble();
3861
  }
3862
 
3863
- // supports only 2.0-style add(1, 's') or add(duration)
3864
  function duration_add_subtract__add (input, value) {
3865
  return duration_add_subtract__addSubtract(this, input, value, 1);
3866
  }
3867
 
3868
- // supports only 2.0-style subtract(1, 's') or subtract(duration)
3869
  function duration_add_subtract__subtract (input, value) {
3870
  return duration_add_subtract__addSubtract(this, input, value, -1);
3871
  }
@@ -3885,8 +3885,8 @@
3885
  var data = this._data;
3886
  var seconds, minutes, hours, years, monthsFromDays;
3887
 
3888
- // if we have a mix of positive and negative values, bubble down first
3889
- // check: https://github.com/moment/moment/issues/2166
3890
  if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
3891
  (milliseconds <= 0 && days <= 0 && months <= 0))) {
3892
  milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
@@ -3909,12 +3909,12 @@
3909
 
3910
  days += absFloor(hours / 24);
3911
 
3912
- // convert days to months
3913
  monthsFromDays = absFloor(daysToMonths(days));
3914
  months += monthsFromDays;
3915
  days -= absCeil(monthsToDays(monthsFromDays));
3916
 
3917
- // 12 months -> 1 year
3918
  years = absFloor(months / 12);
3919
  months %= 12;
3920
 
@@ -3927,12 +3927,12 @@
3927
 
3928
  function daysToMonths (days) {
3929
  // 400 years have 146097 days (taking into account leap year rules)
3930
- // 400 years have 12 months === 4800
3931
  return days * 4800 / 146097;
3932
  }
3933
 
3934
  function monthsToDays (months) {
3935
- // the reverse of daysToMonths
3936
  return months * 146097 / 4800;
3937
  }
3938
 
@@ -3948,7 +3948,7 @@
3948
  months = this._months + daysToMonths(days);
3949
  return units === 'month' ? months : months / 12;
3950
  } else {
3951
- // handle milliseconds separately because of floating point math errors (issue #1867)
3952
  days = this._days + Math.round(monthsToDays(this._months));
3953
  switch (units) {
3954
  case 'week' : return days / 7 + milliseconds / 6048e5;
@@ -3956,7 +3956,7 @@
3956
  case 'hour' : return days * 24 + milliseconds / 36e5;
3957
  case 'minute' : return days * 1440 + milliseconds / 6e4;
3958
  case 'second' : return days * 86400 + milliseconds / 1000;
3959
- // Math.floor prevents floating point math errors here
3960
  case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
3961
  default: throw new Error('Unknown unit ' + units);
3962
  }
@@ -4013,14 +4013,14 @@
4013
 
4014
  var round = Math.round;
4015
  var thresholds = {
4016
- s: 45, // seconds to minute
4017
- m: 45, // minutes to hour
4018
- h: 22, // hours to day
4019
- d: 26, // days to month
4020
- M: 11 // months to year
4021
  };
4022
 
4023
- // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize
4024
  function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
4025
  return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
4026
  }
@@ -4051,7 +4051,7 @@
4051
  return substituteTimeAgo.apply(null, a);
4052
  }
4053
 
4054
- // This function allows you to set the rounding function for relative time strings
4055
  function duration_humanize__getSetRelativeTimeRounding (roundingFunction) {
4056
  if (roundingFunction === undefined) {
4057
  return round;
@@ -4063,7 +4063,7 @@
4063
  return false;
4064
  }
4065
 
4066
- // This function allows you to set a threshold for relative time strings
4067
  function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {
4068
  if (thresholds[threshold] === undefined) {
4069
  return false;
@@ -4092,27 +4092,27 @@
4092
  // for ISO strings we do not use the normal bubbling rules:
4093
  // * milliseconds bubble up until they become hours
4094
  // * days do not bubble at all
4095
- // * months bubble up until they become years
4096
  // This is because there is no context-free conversion between hours and days
4097
  // (think of clock changes)
4098
- // and also not between days and months (28-31 days per month)
4099
  var seconds = iso_string__abs(this._milliseconds) / 1000;
4100
  var days = iso_string__abs(this._days);
4101
  var months = iso_string__abs(this._months);
4102
  var minutes, hours, years;
4103
 
4104
- // 3600 seconds -> 60 minutes -> 1 hour
4105
  minutes = absFloor(seconds / 60);
4106
  hours = absFloor(minutes / 60);
4107
  seconds %= 60;
4108
  minutes %= 60;
4109
 
4110
- // 12 months -> 1 year
4111
  years = absFloor(months / 12);
4112
  months %= 12;
4113
 
4114
 
4115
- // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
4116
  var Y = years;
4117
  var M = months;
4118
  var D = days;
@@ -4122,8 +4122,8 @@
4122
  var total = this.asSeconds();
4123
 
4124
  if (!total) {
4125
- // this is the same as C#'s (Noda) and python (isodate)...
4126
- // but not other JS (goog.date)
4127
  return 'P0D';
4128
  }
4129
 
@@ -4170,18 +4170,18 @@
4170
  duration_prototype__proto.locale = locale;
4171
  duration_prototype__proto.localeData = localeData;
4172
 
4173
- // Deprecations
4174
  duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
4175
  duration_prototype__proto.lang = lang;
4176
 
4177
- // Side effect imports
4178
 
4179
- // FORMATTING
4180
 
4181
  addFormatToken('X', 0, 0, 'unix');
4182
  addFormatToken('x', 0, 0, 'valueOf');
4183
 
4184
- // PARSING
4185
 
4186
  addRegexToken('x', matchSigned);
4187
  addRegexToken('X', matchTimestamp);
@@ -4192,7 +4192,7 @@
4192
  config._d = new Date(toInt(input));
4193
  });
4194
 
4195
- // Side effect imports
4196
 
4197
 
4198
  utils_hooks__hooks.version = '2.15.1';
28
 
29
  function isObject(input) {
30
  // IE8 will treat undefined and null as object if it wasn't for
31
+ // input != null.
32
  return input != null && Object.prototype.toString.call(input) === '[object Object]';
33
  }
34
 
35
  function isObjectEmpty(obj) {
36
  var k;
37
  for (k in obj) {
38
+ // Even if its not own property I'd still call it non-empty.
39
  return false;
40
  }
41
  return true;
224
 
225
  var updateInProgress = false;
226
 
227
+ // Moment prototype object.
228
  function Moment(config) {
229
  copyConfig(this, config);
230
  this._d = new Date(config._d != null ? config._d.getTime() : NaN);
261
  return value;
262
  }
263
 
264
+ // Compare two arrays, return the number of differences.
265
  function compareArrays(array1, array2, dontConvert) {
266
  var len = Math.min(array1.length, array2.length),
267
  lengthDiff = Math.abs(array1.length - array2.length),
300
  for (var key in arguments[0]) {
301
  arg += key + ': ' + arguments[0][key] + ', ';
302
  }
303
+ arg = arg.slice(0, -2); // Remove trailing comma and space.
304
  } else {
305
  arg = arguments[i];
306
  }
367
  if (hasOwnProp(parentConfig, prop) &&
368
  !hasOwnProp(childConfig, prop) &&
369
  isObject(parentConfig[prop])) {
370
+ // Make sure changes to properties don't modify parent config.
371
  res[prop] = extend({}, res[prop]);
372
  }
373
  }
543
  }
544
  }
545
 
546
+ // MOMENTS.
547
 
548
  function stringGet (units) {
549
  units = normalizeUnits(units);
639
  };
640
  }
641
 
642
+ // format date using native date object.
643
  function formatMoment(m, format) {
644
  if (!m.isValid()) {
645
  return m.localeData().invalidDate();
688
 
689
  var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 123456789 123456789.123
690
 
691
+ // Any word (or two) characters or numbers including two/three word month in arabic.
692
+ // includes scottish gaelic two word and hyphenated months.
693
  var matchWord = /[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i;
694
 
695
 
766
  indexOf = Array.prototype.indexOf;
767
  } else {
768
  indexOf = function (o) {
769
+ // I know.
770
  var i;
771
  for (i = 0; i < this.length; ++i) {
772
  if (this[i] === o) {
781
  return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
782
  }
783
 
784
+ // FORMATTING.
785
 
786
  addFormatToken('M', ['MM', 2], 'Mo', function () {
787
  return this.month() + 1;
795
  return this.localeData().months(this, format);
796
  });
797
 
798
+ // ALIASES.
799
 
800
  addUnitAlias('month', 'M');
801
 
802
+ // PRIORITY.
803
 
804
  addUnitPriority('month', 8);
805
 
806
+ // PARSING.
807
 
808
  addRegexToken('M', match1to2);
809
  addRegexToken('MM', match1to2, match2);
820
 
821
  addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {
822
  var month = config._locale.monthsParse(input, token, config._strict);
823
+ // If we didn't find a month name, mark the date as invalid.
824
  if (month != null) {
825
  array[MONTH] = month;
826
  } else {
828
  }
829
  });
830
 
831
+ // LOCALES.
832
 
833
  var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/;
834
  var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');
903
  this._shortMonthsParse = [];
904
  }
905
 
906
+ // TODO: add sorting.
907
  // Sorting makes sure if one month (or abbr) is a prefix of another
908
+ // see sorting in computeMonthsParse.
909
  for (i = 0; i < 12; i++) {
910
+ // Make the regex if we don't have it already.
911
  mom = create_utc__createUTC([2000, i]);
912
  if (strict && !this._longMonthsParse[i]) {
913
  this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');
917
  regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');
918
  this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');
919
  }
920
+ // Test the regex.
921
  if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {
922
  return i;
923
  } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {
928
  }
929
  }
930
 
931
+ // MOMENTS.
932
 
933
  function setMonth (mom, value) {
934
  var dayOfMonth;
935
 
936
  if (!mom.isValid()) {
937
+ // No op.
938
  return mom;
939
  }
940
 
1017
  var shortPieces = [], longPieces = [], mixedPieces = [],
1018
  i, mom;
1019
  for (i = 0; i < 12; i++) {
1020
+ // Make the regex if we don't have it already.
1021
  mom = create_utc__createUTC([2000, i]);
1022
  shortPieces.push(this.monthsShort(mom, ''));
1023
  longPieces.push(this.months(mom, ''));
1043
  this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i');
1044
  }
1045
 
1046
+ // FORMATTING.
1047
 
1048
  addFormatToken('Y', 0, 0, function () {
1049
  var y = this.year();
1058
  addFormatToken(0, ['YYYYY', 5], 0, 'year');
1059
  addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');
1060
 
1061
+ // ALIASES.
1062
 
1063
  addUnitAlias('year', 'y');
1064
 
1065
+ // PRIORITIES.
1066
 
1067
  addUnitPriority('year', 1);
1068
 
1069
+ // PARSING.
1070
 
1071
  addRegexToken('Y', matchSigned);
1072
  addRegexToken('YY', match1to2, match2);
1085
  array[YEAR] = parseInt(input, 10);
1086
  });
1087
 
1088
+ // HELPERS.
1089
 
1090
  function daysInYear(year) {
1091
  return isLeapYear(year) ? 366 : 365;
1095
  return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
1096
  }
1097
 
1098
+ // HOOKS.
1099
 
1100
  utils_hooks__hooks.parseTwoDigitYear = function (input) {
1101
  return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);
1102
  };
1103
 
1104
+ // MOMENTS.
1105
 
1106
  var getSetYear = makeGetSet('FullYear', true);
1107
 
1110
  }
1111
 
1112
  function createDate (y, m, d, h, M, s, ms) {
1113
+ // can't just apply() to create a date:
1114
+ // http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply
1115
  var date = new Date(y, m, d, h, M, s, ms);
1116
 
1117
+ // The date constructor remaps years 0-99 to 1900-1999.
1118
  if (y < 100 && y >= 0 && isFinite(date.getFullYear())) {
1119
  date.setFullYear(y);
1120
  }
1124
  function createUTCDate (y) {
1125
  var date = new Date(Date.UTC.apply(null, arguments));
1126
 
1127
+ // The Date.UTC function remaps years 0-99 to 1900-1999.
1128
  if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) {
1129
  date.setUTCFullYear(y);
1130
  }
1131
  return date;
1132
  }
1133
 
1134
+ // Start-of-first-week - start-of-year.
1135
  function firstWeekOffset(year, dow, doy) {
1136
+ var // First-week day -- which January is always in the first week (4 for iso, 1 for other).
1137
  fwd = 7 + dow - doy,
1138
+ // First-week day local weekday -- which local weekday is fwd.
1139
  fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7;
1140
 
1141
  return -fwdlw + fwd - 1;
1142
  }
1143
 
1144
+ // http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday
1145
  function dayOfYearFromWeeks(year, week, weekday, dow, doy) {
1146
  var localWeekday = (7 + weekday - dow) % 7,
1147
  weekOffset = firstWeekOffset(year, dow, doy),
1193
  return (daysInYear(year) - weekOffset + weekOffsetNext) / 7;
1194
  }
1195
 
1196
+ // FORMATTING.
1197
 
1198
  addFormatToken('w', ['ww', 2], 'wo', 'week');
1199
  addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');
1200
 
1201
+ // ALIASES.
1202
 
1203
  addUnitAlias('week', 'w');
1204
  addUnitAlias('isoWeek', 'W');
1205
 
1206
+ // PRIORITIES.
1207
 
1208
  addUnitPriority('week', 5);
1209
  addUnitPriority('isoWeek', 5);
1210
 
1211
+ // PARSING.
1212
 
1213
  addRegexToken('w', match1to2);
1214
  addRegexToken('ww', match1to2, match2);
1219
  week[token.substr(0, 1)] = toInt(input);
1220
  });
1221
 
1222
+ // HELPERS.
1223
 
1224
+ // LOCALES.
1225
 
1226
  function localeWeek (mom) {
1227
  return weekOfYear(mom, this._week.dow, this._week.doy).week;
1240
  return this._week.doy;
1241
  }
1242
 
1243
+ // MOMENTS.
1244
 
1245
  function getSetWeek (input) {
1246
  var week = this.localeData().week(this);
1252
  return input == null ? week : this.add((input - week) * 7, 'd');
1253
  }
1254
 
1255
+ // FORMATTING.
1256
 
1257
  addFormatToken('d', 0, 'do', 'day');
1258
 
1271
  addFormatToken('e', 0, 0, 'weekday');
1272
  addFormatToken('E', 0, 0, 'isoWeekday');
1273
 
1274
+ // ALIASES.
1275
 
1276
  addUnitAlias('day', 'd');
1277
  addUnitAlias('weekday', 'e');
1278
  addUnitAlias('isoWeekday', 'E');
1279
 
1280
+ // PRIORITY.
1281
  addUnitPriority('day', 11);
1282
  addUnitPriority('weekday', 11);
1283
  addUnitPriority('isoWeekday', 11);
1284
 
1285
+ // PARSING.
1286
 
1287
  addRegexToken('d', match1to2);
1288
  addRegexToken('e', match1to2);
1299
 
1300
  addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) {
1301
  var weekday = config._locale.weekdaysParse(input, token, config._strict);
1302
+ // If we didn't get a weekday name, mark the date as invalid.
1303
  if (weekday != null) {
1304
  week.d = weekday;
1305
  } else {
1311
  week[token] = toInt(input);
1312
  });
1313
 
1314
+ // HELPERS.
1315
 
1316
  function parseWeekday(input, locale) {
1317
  if (typeof input !== 'string') {
1337
  return isNaN(input) ? null : input;
1338
  }
1339
 
1340
+ // LOCALES.
1341
 
1342
  var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');
1343
  function localeWeekdays (m, format) {
1437
  }
1438
 
1439
  for (i = 0; i < 7; i++) {
1440
+ // Make the regex if we don't have it already.
1441
 
1442
  mom = create_utc__createUTC([2000, 1]).day(i);
1443
  if (strict && !this._fullWeekdaysParse[i]) {
1449
  regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');
1450
  this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');
1451
  }
1452
+ // Test the regex.
1453
  if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) {
1454
  return i;
1455
  } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) {
1462
  }
1463
  }
1464
 
1465
+ // MOMENTS.
1466
 
1467
  function getSetDayOfWeek (input) {
1468
  if (!this.isValid()) {
1490
  return input != null ? this : NaN;
1491
  }
1492
 
1493
+ // Behaves the same as moment#day except
1494
  // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)
1495
  // as a setter, sunday should belong to the previous week.
1496
 
1604
  this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i');
1605
  }
1606
 
1607
+ // FORMATTING.
1608
 
1609
  function hFormat() {
1610
  return this.hours() % 12 || 12;
1645
  meridiem('a', true);
1646
  meridiem('A', false);
1647
 
1648
+ // ALIASES.
1649
 
1650
  addUnitAlias('hour', 'h');
1651
 
1652
+ // PRIORITY.
1653
  addUnitPriority('hour', 13);
1654
 
1655
+ // PARSING.
1656
 
1657
  function matchMeridiem (isStrict, locale) {
1658
  return locale._meridiemParse;
1706
  array[SECOND] = toInt(input.substr(pos2));
1707
  });
1708
 
1709
+ // LOCALES.
1710
 
1711
  function localeIsPM (input) {
1712
  // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays
1724
  }
1725
 
1726
 
1727
+ // MOMENTS.
1728
 
1729
  // Setting the hour should keep the time, because the user explicitly
1730
  // specified which hour he wants. So trying to maintain the same hour (in
1752
  meridiemParse: defaultLocaleMeridiemParse
1753
  };
1754
 
1755
+ // Internal storage for locale config files.
1756
  var locales = {};
1757
  var globalLocale;
1758
 
1760
  return key ? key.toLowerCase().replace('_', '-') : key;
1761
  }
1762
 
1763
+ // Pick the locale from the array
1764
  // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each
1765
  // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root
1766
  function chooseLocale(names) {
1777
  return locale;
1778
  }
1779
  if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {
1780
+ // The next array item is better than a shallower substring of this one.
1781
  break;
1782
  }
1783
  j--;
1789
 
1790
  function loadLocale(name) {
1791
  var oldLocale = null;
1792
+ // TODO: Find a better way to register and load all the locales in Node.
1793
  if (!locales[name] && (typeof module !== 'undefined') &&
1794
  module && module.exports) {
1795
  try {
1796
  oldLocale = globalLocale._abbr;
1797
  require('./locale/' + name);
1798
+ // Because defineLocale currently also sets the global locale, we
1799
+ // want to undo that for lazy loaded locales.
1800
  locale_locales__getSetGlobalLocale(oldLocale);
1801
  } catch (e) { }
1802
  }
1840
  if (locales[config.parentLocale] != null) {
1841
  parentConfig = locales[config.parentLocale]._config;
1842
  } else {
1843
+ // Treat as if there is no base config.
1844
  deprecateSimple('parentLocaleUndefined',
1845
  'specified parentLocale is not defined yet. See http://momentjs.com/guides/#/warnings/parent-locale/');
1846
  }
1847
  }
1848
  locales[name] = new Locale(mergeConfigs(parentConfig, config));
1849
 
1850
+ // backwards compat for now: also set the locale.
1851
  locale_locales__getSetGlobalLocale(name);
1852
 
1853
  return locales[name];
1854
  } else {
1855
+ // Useful for testing.
1856
  delete locales[name];
1857
  return null;
1858
  }
1861
  function updateLocale(name, config) {
1862
  if (config != null) {
1863
  var locale, parentConfig = baseConfig;
1864
+ // MERGE.
1865
  if (locales[name] != null) {
1866
  parentConfig = locales[name]._config;
1867
  }
1870
  locale.parentLocale = locales[name];
1871
  locales[name] = locale;
1872
 
1873
+ // Backwards compat for now: also set the locale.
1874
  locale_locales__getSetGlobalLocale(name);
1875
  } else {
1876
+ // Pass null for config to unupdate, useful for tests.
1877
  if (locales[name] != null) {
1878
  if (locales[name].parentLocale != null) {
1879
  locales[name] = locales[name].parentLocale;
1885
  return locales[name];
1886
  }
1887
 
1888
+ // Returns locale data.
1889
  function locale_locales__getLocale (key) {
1890
  var locale;
1891
 
1898
  }
1899
 
1900
  if (!isArray(key)) {
1901
+ // Short-circuit everything else.
1902
  locale = loadLocale(key);
1903
  if (locale) {
1904
  return locale;
1959
  ['YYYY-MM', /\d{4}-\d\d/, false],
1960
  ['YYYYYYMMDD', /[+-]\d{10}/],
1961
  ['YYYYMMDD', /\d{8}/],
1962
+ // YYYYMM is NOT allowed by the standard.
1963
  ['GGGG[W]WWE', /\d{4}W\d{3}/],
1964
  ['GGGG[W]WW', /\d{4}W\d{2}/, false],
1965
  ['YYYYDDD', /\d{7}/]
1966
  ];
1967
 
1968
+ // Iso time formats and regexes.
1969
  var isoTimes = [
1970
  ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/],
1971
  ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/],
1980
 
1981
  var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i;
1982
 
1983
+ // Date from iso format.
1984
  function configFromISO(config) {
1985
  var i, l,
1986
  string = config._i,
2033
  }
2034
  }
2035
 
2036
+ // Date from iso format or fallback.
2037
  function configFromString(config) {
2038
  var matched = aspNetJsonRegex.exec(config._i);
2039
 
2079
  return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()];
2080
  }
2081
 
2082
+ // Convert an array to a date.
2083
  // the array should mirror the parameters below
2084
  // note: all values past the year are optional and will default to the lowest possible value.
2085
+ // [year, month, day , hour, minute, second, millisecond].
2086
  function configFromArray (config) {
2087
  var i, date, input = [], currentDate, yearToUse;
2088
 
2092
 
2093
  currentDate = currentDateArray(config);
2094
 
2095
+ // Compute day of the year from weeks and weekdays.
2096
  if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {
2097
  dayOfYearFromWeekInfo(config);
2098
  }
2099
 
2100
+ // If the day of the year is set, figure out what it is.
2101
  if (config._dayOfYear) {
2102
  yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);
2103
 
2119
  config._a[i] = input[i] = currentDate[i];
2120
  }
2121
 
2122
+ // Zero out whatever was not defaulted, including time.
2123
  for (; i < 7; i++) {
2124
  config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];
2125
  }
2171
  week = defaults(w.w, 1);
2172
 
2173
  if (w.d != null) {
2174
+ // Weekday -- low day numbers are considered next week.
2175
  weekday = w.d;
2176
  if (weekday < 0 || weekday > 6) {
2177
  weekdayOverflow = true;
2178
  }
2179
  } else if (w.e != null) {
2180
+ // Local weekday -- counting starts from beginning of week.
2181
  weekday = w.e + dow;
2182
  if (w.e < 0 || w.e > 6) {
2183
  weekdayOverflow = true;
2184
  }
2185
  } else {
2186
+ // Default to beginning of week.
2187
  weekday = dow;
2188
  }
2189
  }
2198
  }
2199
  }
2200
 
2201
+ // Constant that refers to the ISO standard.
2202
  utils_hooks__hooks.ISO_8601 = function () {};
2203
 
2204
+ // Date from string and format string.
2205
  function configFromStringAndFormat(config) {
2206
+ // TODO: Move this to another part of the creation flow to prevent circular deps.
2207
  if (config._f === utils_hooks__hooks.ISO_8601) {
2208
  configFromISO(config);
2209
  return;
2212
  config._a = [];
2213
  getParsingFlags(config).empty = true;
2214
 
2215
+ // This array is used to make a Date, either with `new Date` or `Date.UTC`.
2216
  var string = '' + config._i,
2217
  i, parsedInput, tokens, token, skipped,
2218
  stringLength = string.length,
2223
  for (i = 0; i < tokens.length; i++) {
2224
  token = tokens[i];
2225
  parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];
2226
+ // Console.log('token', token, 'parsedInput', parsedInput,
2227
  // 'regex', getParseRegexForToken(token, config));
2228
  if (parsedInput) {
2229
  skipped = string.substr(0, string.indexOf(parsedInput));
2233
  string = string.slice(string.indexOf(parsedInput) + parsedInput.length);
2234
  totalParsedInputLength += parsedInput.length;
2235
  }
2236
+ // Don't parse if it's not a known token.
2237
  if (formatTokenFunctions[token]) {
2238
  if (parsedInput) {
2239
  getParsingFlags(config).empty = false;
2248
  }
2249
  }
2250
 
2251
+ // Add remaining unparsed input length to the string.
2252
  getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength;
2253
  if (string.length > 0) {
2254
  getParsingFlags(config).unusedInput.push(string);
2255
  }
2256
 
2257
+ // Clear _12h flag if hour is <= 12.
2258
  if (config._a[HOUR] <= 12 &&
2259
  getParsingFlags(config).bigHour === true &&
2260
  config._a[HOUR] > 0) {
2275
  var isPm;
2276
 
2277
  if (meridiem == null) {
2278
+ // Nothing to do.
2279
  return hour;
2280
  }
2281
  if (locale.meridiemHour != null) {
2282
  return locale.meridiemHour(hour, meridiem);
2283
  } else if (locale.isPM != null) {
2284
+ // Fallback.
2285
  isPm = locale.isPM(meridiem);
2286
  if (isPm && hour < 12) {
2287
  hour += 12;
2291
  }
2292
  return hour;
2293
  } else {
2294
+ // This is not supposed to happen.
2295
  return hour;
2296
  }
2297
  }
2298
 
2299
+ // Date from string and array of format strings.
2300
  function configFromStringAndArray(config) {
2301
  var tempConfig,
2302
  bestMoment,
2324
  continue;
2325
  }
2326
 
2327
+ // If there is any input that was not parsed add a penalty for that format.
2328
  currentScore += getParsingFlags(tempConfig).charsLeftOver;
2329
 
2330
+ // Or tokens.
2331
  currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10;
2332
 
2333
  getParsingFlags(tempConfig).score = currentScore;
2357
  function createFromConfig (config) {
2358
  var res = new Moment(checkOverflow(prepareConfig(config)));
2359
  if (res._nextDay) {
2360
+ // Adding is smart enough around DST.
2361
  res.add(1, 'd');
2362
  res._nextDay = undefined;
2363
  }
2433
  (isArray(input) && input.length === 0)) {
2434
  input = undefined;
2435
  }
2436
+ // Object construction must be done this way.
2437
  // https://github.com/moment/moment/issues/1423
2438
  c._isAMomentObject = true;
2439
  c._useUTC = c._isUTC = isUTC;
2524
  seconds = normalizedInput.second || 0,
2525
  milliseconds = normalizedInput.millisecond || 0;
2526
 
2527
+ // Representation for dateAddRemove.
2528
  this._milliseconds = +milliseconds +
2529
  seconds * 1e3 + // 1000
2530
  minutes * 6e4 + // 1000 * 60
2531
+ hours * 1000 * 60 * 60; // Using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978
2532
  // Because of dateAddRemove treats 24 hours as different from a
2533
+ // day when working around DST, we need to store them separately.
2534
  this._days = +days +
2535
  weeks * 7;
2536
  // It is impossible translate months into days without knowing
2559
  }
2560
  }
2561
 
2562
+ // FORMATTING.
2563
 
2564
  function offset (token, separator) {
2565
  addFormatToken(token, 0, 0, function () {
2576
  offset('Z', ':');
2577
  offset('ZZ', '');
2578
 
2579
+ // PARSING.
2580
 
2581
  addRegexToken('Z', matchShortOffset);
2582
  addRegexToken('ZZ', matchShortOffset);
2585
  config._tzm = offsetFromString(matchShortOffset, input);
2586
  });
2587
 
2588
+ // HELPERS.
2589
 
2590
+ // Timezone chunker
2591
  // '+10:00' > ['10', '00']
2592
+ // '-1530' > ['-15', '30'].
2593
  var chunkOffset = /([\+\-]|\d\d)/gi;
2594
 
2595
  function offsetFromString(matcher, string) {
2769
  return this.isValid() ? this._isUTC && this._offset === 0 : false;
2770
  }
2771
 
2772
+ // ASP.NET json date format regex.
2773
  var aspNetRegex = /^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/;
2774
 
2775
  // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html
2776
  // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere
2777
+ // and further modified to allow for strings containing both week and day.
2778
  var isoRegex = /^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;
2779
 
2780
  function create__createDuration (input, key) {
2781
  var duration = input,
2782
+ // Matching against regexp is expensive, do it on demand.
2783
  match = null,
2784
  sign,
2785
  ret,
2806
  h : toInt(match[HOUR]) * sign,
2807
  m : toInt(match[MINUTE]) * sign,
2808
  s : toInt(match[SECOND]) * sign,
2809
+ ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // The millisecond decimal point is included in the match.
2810
  };
2811
  } else if (!!(match = isoRegex.exec(input))) {
2812
  sign = (match[1] === '-') ? -1 : 1;
2819
  m : parseIso(match[7], sign),
2820
  s : parseIso(match[8], sign)
2821
  };
2822
+ } else if (duration == null) { // Checks for null or undefined.
2823
  duration = {};
2824
  } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {
2825
  diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));
2845
  // converts floats to ints.
2846
  // inp may be undefined, so careful calling replace on it.
2847
  var res = inp && parseFloat(inp.replace(',', '.'));
2848
+ // Apply sign while we're at it.
2849
  return (isNaN(res) ? 0 : res) * sign;
2850
  }
2851
 
2881
  return res;
2882
  }
2883
 
2884
+ // TODO: remove 'name' arg after deprecation is removed.
2885
  function createAdder(direction, name) {
2886
  return function (val, period) {
2887
  var dur, tmp;
2888
+ // Invert the arguments, but complain about it.
2889
  if (period !== null && !isNaN(+period)) {
2890
  deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' +
2891
  'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.');
2905
  months = absRound(duration._months);
2906
 
2907
  if (!mom.isValid()) {
2908
+ // No op.
2909
  return;
2910
  }
2911
 
3048
  }
3049
 
3050
  function monthDiff (a, b) {
3051
+ // Difference in months.
3052
  var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),
3053
+ // B is in (anchor - 1 month, anchor + 1 month).
3054
  anchor = a.clone().add(wholeMonthDiff, 'months'),
3055
  anchor2, adjust;
3056
 
3057
  if (b - anchor < 0) {
3058
  anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');
3059
+ // linear across the month.
3060
  adjust = (b - anchor) / (anchor - anchor2);
3061
  } else {
3062
  anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');
3063
+ // linear across the month.
3064
  adjust = (b - anchor) / (anchor2 - anchor);
3065
  }
3066
 
3067
+ // Check for negative zero, return zero if negative zero.
3068
  return -(wholeMonthDiff + adjust) || 0;
3069
  }
3070
 
3079
  var m = this.clone().utc();
3080
  if (0 < m.year() && m.year() <= 9999) {
3081
  if (isFunction(Date.prototype.toISOString)) {
3082
+ // Native implementation is ~50x faster, use it when we can.
3083
  return this.toDate().toISOString();
3084
  } else {
3085
  return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');
3159
 
3160
  function startOf (units) {
3161
  units = normalizeUnits(units);
3162
+ // The following switch intentionally omits break keywords
3163
  // to utilize falling through the cases.
3164
  switch (units) {
3165
  case 'year':
3185
  this.milliseconds(0);
3186
  }
3187
 
3188
+ // Weeks are a special case.
3189
  if (units === 'week') {
3190
  this.weekday(0);
3191
  }
3193
  this.isoWeekday(1);
3194
  }
3195
 
3196
+ // Quarters are also special.
3197
  if (units === 'quarter') {
3198
  this.month(Math.floor(this.month() / 3) * 3);
3199
  }
3246
  }
3247
 
3248
  function toJSON () {
3249
+ // New Date(NaN).toJSON() === null.
3250
  return this.isValid() ? this.toISOString() : null;
3251
  }
3252
 
3272
  };
3273
  }
3274
 
3275
+ // FORMATTING.
3276
 
3277
  addFormatToken(0, ['gg', 2], 0, function () {
3278
  return this.weekYear() % 100;
3291
  addWeekYearFormatToken('GGGG', 'isoWeekYear');
3292
  addWeekYearFormatToken('GGGGG', 'isoWeekYear');
3293
 
3294
+ // ALIASES.
3295
 
3296
  addUnitAlias('weekYear', 'gg');
3297
  addUnitAlias('isoWeekYear', 'GG');
3298
 
3299
+ // PRIORITY.
3300
 
3301
  addUnitPriority('weekYear', 1);
3302
  addUnitPriority('isoWeekYear', 1);
3303
 
3304
 
3305
+ // PARSING.
3306
 
3307
  addRegexToken('G', matchSigned);
3308
  addRegexToken('g', matchSigned);
3321
  week[token] = utils_hooks__hooks.parseTwoDigitYear(input);
3322
  });
3323
 
3324
+ // MOMENTS.
3325
 
3326
  function getSetWeekYear (input) {
3327
  return getSetWeekYearHelper.call(this,
3369
  return this;
3370
  }
3371
 
3372
+ // FORMATTING.
3373
 
3374
  addFormatToken('Q', 0, 'Qo', 'quarter');
3375
 
3376
+ // ALIASES.
3377
 
3378
  addUnitAlias('quarter', 'Q');
3379
 
3380
+ // PRIORITY.
3381
 
3382
  addUnitPriority('quarter', 7);
3383
 
3384
+ // PARSING.
3385
 
3386
  addRegexToken('Q', match1);
3387
  addParseToken('Q', function (input, array) {
3388
  array[MONTH] = (toInt(input) - 1) * 3;
3389
  });
3390
 
3391
+ // MOMENTS.
3392
 
3393
  function getSetQuarter (input) {
3394
  return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);
3395
  }
3396
 
3397
+ // FORMATTING.
3398
 
3399
  addFormatToken('D', ['DD', 2], 'Do', 'date');
3400
 
3401
+ // ALIASES.
3402
 
3403
  addUnitAlias('date', 'D');
3404
 
3405
+ // PRIOROITY.
3406
  addUnitPriority('date', 9);
3407
 
3408
+ // PARSING.
3409
 
3410
  addRegexToken('D', match1to2);
3411
  addRegexToken('DD', match1to2, match2);
3418
  array[DATE] = toInt(input.match(match1to2)[0], 10);
3419
  });
3420
 
3421
+ // MOMENTS.
3422
 
3423
  var getSetDayOfMonth = makeGetSet('Date', true);
3424
 
3425
+ // FORMATTING.
3426
 
3427
  addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');
3428
 
3429
+ // ALIASES.
3430
 
3431
  addUnitAlias('dayOfYear', 'DDD');
3432
 
3433
+ // PRIORITY.
3434
  addUnitPriority('dayOfYear', 4);
3435
 
3436
+ // PARSING.
3437
 
3438
  addRegexToken('DDD', match1to3);
3439
  addRegexToken('DDDD', match3);
3441
  config._dayOfYear = toInt(input);
3442
  });
3443
 
3444
+ // HELPERS.
3445
 
3446
+ // MOMENTS.
3447
 
3448
  function getSetDayOfYear (input) {
3449
  var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;
3450
  return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');
3451
  }
3452
 
3453
+ // FORMATTING.
3454
 
3455
  addFormatToken('m', ['mm', 2], 0, 'minute');
3456
 
3457
+ // ALIASES.
3458
 
3459
  addUnitAlias('minute', 'm');
3460
 
3461
+ // PRIORITY.
3462
 
3463
  addUnitPriority('minute', 14);
3464
 
3465
+ // PARSING.
3466
 
3467
  addRegexToken('m', match1to2);
3468
  addRegexToken('mm', match1to2, match2);
3469
  addParseToken(['m', 'mm'], MINUTE);
3470
 
3471
+ // MOMENTS.
3472
 
3473
  var getSetMinute = makeGetSet('Minutes', false);
3474
 
3475
+ // FORMATTING.
3476
 
3477
  addFormatToken('s', ['ss', 2], 0, 'second');
3478
 
3479
+ // ALIASES.
3480
 
3481
  addUnitAlias('second', 's');
3482
 
3483
+ // PRIORITY.
3484
 
3485
  addUnitPriority('second', 15);
3486
 
3487
+ // PARSING.
3488
 
3489
  addRegexToken('s', match1to2);
3490
  addRegexToken('ss', match1to2, match2);
3491
  addParseToken(['s', 'ss'], SECOND);
3492
 
3493
+ // MOMENTS.
3494
 
3495
  var getSetSecond = makeGetSet('Seconds', false);
3496
 
3497
+ // FORMATTING.
3498
 
3499
  addFormatToken('S', 0, 0, function () {
3500
  return ~~(this.millisecond() / 100);
3525
  });
3526
 
3527
 
3528
+ // ALIASES.
3529
 
3530
  addUnitAlias('millisecond', 'ms');
3531
 
3532
+ // PRIORITY.
3533
 
3534
  addUnitPriority('millisecond', 16);
3535
 
3536
+ // PARSING.
3537
 
3538
  addRegexToken('S', match1to3, match1);
3539
  addRegexToken('SS', match1to3, match2);
3551
  for (token = 'S'; token.length <= 9; token += 'S') {
3552
  addParseToken(token, parseMs);
3553
  }
3554
+ // MOMENTS.
3555
 
3556
  var getSetMillisecond = makeGetSet('Milliseconds', false);
3557
 
3558
+ // FORMATTING.
3559
 
3560
  addFormatToken('z', 0, 0, 'zoneAbbr');
3561
  addFormatToken('zz', 0, 0, 'zoneName');
3562
 
3563
+ // MOMENTS.
3564
 
3565
  function getZoneAbbr () {
3566
  return this._isUTC ? 'UTC' : '';
3610
  momentPrototype__proto.valueOf = to_type__valueOf;
3611
  momentPrototype__proto.creationData = creationData;
3612
 
3613
+ // Year.
3614
  momentPrototype__proto.year = getSetYear;
3615
  momentPrototype__proto.isLeapYear = getIsLeapYear;
3616
 
3617
+ // Week Year.
3618
  momentPrototype__proto.weekYear = getSetWeekYear;
3619
  momentPrototype__proto.isoWeekYear = getSetISOWeekYear;
3620
 
3621
+ // Quarter.
3622
  momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;
3623
 
3624
+ // Month.
3625
  momentPrototype__proto.month = getSetMonth;
3626
  momentPrototype__proto.daysInMonth = getDaysInMonth;
3627
 
3628
+ // Week.
3629
  momentPrototype__proto.week = momentPrototype__proto.weeks = getSetWeek;
3630
  momentPrototype__proto.isoWeek = momentPrototype__proto.isoWeeks = getSetISOWeek;
3631
  momentPrototype__proto.weeksInYear = getWeeksInYear;
3632
  momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;
3633
 
3634
+ // Day.
3635
  momentPrototype__proto.date = getSetDayOfMonth;
3636
  momentPrototype__proto.day = momentPrototype__proto.days = getSetDayOfWeek;
3637
  momentPrototype__proto.weekday = getSetLocaleDayOfWeek;
3638
  momentPrototype__proto.isoWeekday = getSetISODayOfWeek;
3639
  momentPrototype__proto.dayOfYear = getSetDayOfYear;
3640
 
3641
+ // Hour.
3642
  momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;
3643
 
3644
+ // Minute.
3645
  momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;
3646
 
3647
+ // Second.
3648
  momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;
3649
 
3650
+ // Millisecond.
3651
  momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;
3652
 
3653
+ // Offset.
3654
  momentPrototype__proto.utcOffset = getSetOffset;
3655
  momentPrototype__proto.utc = setOffsetToUTC;
3656
  momentPrototype__proto.local = setOffsetToLocal;
3662
  momentPrototype__proto.isUtc = isUtc;
3663
  momentPrototype__proto.isUTC = isUtc;
3664
 
3665
+ // Timezone.
3666
  momentPrototype__proto.zoneAbbr = getZoneAbbr;
3667
  momentPrototype__proto.zoneName = getZoneName;
3668
 
3669
+ // Deprecations.
3670
  momentPrototype__proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);
3671
  momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);
3672
  momentPrototype__proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear);
3699
  prototype__proto.pastFuture = pastFuture;
3700
  prototype__proto.set = locale_set__set;
3701
 
3702
+ // Month.
3703
  prototype__proto.months = localeMonths;
3704
  prototype__proto.monthsShort = localeMonthsShort;
3705
  prototype__proto.monthsParse = localeMonthsParse;
3706
  prototype__proto.monthsRegex = monthsRegex;
3707
  prototype__proto.monthsShortRegex = monthsShortRegex;
3708
 
3709
+ // Week.
3710
  prototype__proto.week = localeWeek;
3711
  prototype__proto.firstDayOfYear = localeFirstDayOfYear;
3712
  prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;
3713
 
3714
+ // Day of Week.
3715
  prototype__proto.weekdays = localeWeekdays;
3716
  prototype__proto.weekdaysMin = localeWeekdaysMin;
3717
  prototype__proto.weekdaysShort = localeWeekdaysShort;
3721
  prototype__proto.weekdaysShortRegex = weekdaysShortRegex;
3722
  prototype__proto.weekdaysMinRegex = weekdaysMinRegex;
3723
 
3724
+ // Hours.
3725
  prototype__proto.isPM = localeIsPM;
3726
  prototype__proto.meridiem = localeMeridiem;
3727
 
3827
  }
3828
  });
3829
 
3830
+ // Side effect imports.
3831
  utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);
3832
  utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);
3833
 
3860
  return duration._bubble();
3861
  }
3862
 
3863
+ // Supports only 2.0-style add(1, 's') or add(duration).
3864
  function duration_add_subtract__add (input, value) {
3865
  return duration_add_subtract__addSubtract(this, input, value, 1);
3866
  }
3867
 
3868
+ // Supports only 2.0-style subtract(1, 's') or subtract(duration).
3869
  function duration_add_subtract__subtract (input, value) {
3870
  return duration_add_subtract__addSubtract(this, input, value, -1);
3871
  }
3885
  var data = this._data;
3886
  var seconds, minutes, hours, years, monthsFromDays;
3887
 
3888
+ // If we have a mix of positive and negative values, bubble down first
3889
+ // check: https://github.com/moment/moment/issues/2166.
3890
  if (!((milliseconds >= 0 && days >= 0 && months >= 0) ||
3891
  (milliseconds <= 0 && days <= 0 && months <= 0))) {
3892
  milliseconds += absCeil(monthsToDays(months) + days) * 864e5;
3909
 
3910
  days += absFloor(hours / 24);
3911
 
3912
+ // Convert days to months.
3913
  monthsFromDays = absFloor(daysToMonths(days));
3914
  months += monthsFromDays;
3915
  days -= absCeil(monthsToDays(monthsFromDays));
3916
 
3917
+ // 12 months -> 1 year.
3918
  years = absFloor(months / 12);
3919
  months %= 12;
3920
 
3927
 
3928
  function daysToMonths (days) {
3929
  // 400 years have 146097 days (taking into account leap year rules)
3930
+ // 400 years have 12 months === 4800.
3931
  return days * 4800 / 146097;
3932
  }
3933
 
3934
  function monthsToDays (months) {
3935
+ // The reverse of daysToMonths.
3936
  return months * 146097 / 4800;
3937
  }
3938
 
3948
  months = this._months + daysToMonths(days);
3949
  return units === 'month' ? months : months / 12;
3950
  } else {
3951
+ // Handle milliseconds separately because of floating point math errors (issue #1867).
3952
  days = this._days + Math.round(monthsToDays(this._months));
3953
  switch (units) {
3954
  case 'week' : return days / 7 + milliseconds / 6048e5;
3956
  case 'hour' : return days * 24 + milliseconds / 36e5;
3957
  case 'minute' : return days * 1440 + milliseconds / 6e4;
3958
  case 'second' : return days * 86400 + milliseconds / 1000;
3959
+ // Math.floor prevents floating point math errors here.
3960
  case 'millisecond': return Math.floor(days * 864e5) + milliseconds;
3961
  default: throw new Error('Unknown unit ' + units);
3962
  }
4013
 
4014
  var round = Math.round;
4015
  var thresholds = {
4016
+ s: 45, // Seconds to minute.
4017
+ m: 45, // Minutes to hour.
4018
+ h: 22, // Hours to day.
4019
+ d: 26, // Days to month.
4020
+ M: 11 // Months to year.
4021
  };
4022
 
4023
+ // Helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize.
4024
  function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {
4025
  return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);
4026
  }
4051
  return substituteTimeAgo.apply(null, a);
4052
  }
4053
 
4054
+ // This function allows you to set the rounding function for relative time strings.
4055
  function duration_humanize__getSetRelativeTimeRounding (roundingFunction) {
4056
  if (roundingFunction === undefined) {
4057
  return round;
4063
  return false;
4064
  }
4065
 
4066
+ // This function allows you to set a threshold for relative time strings.
4067
  function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {
4068
  if (thresholds[threshold] === undefined) {
4069
  return false;
4092
  // for ISO strings we do not use the normal bubbling rules:
4093
  // * milliseconds bubble up until they become hours
4094
  // * days do not bubble at all
4095
+ // * months bubble up until they become years.
4096
  // This is because there is no context-free conversion between hours and days
4097
  // (think of clock changes)
4098
+ // and also not between days and months (28-31 days per month).
4099
  var seconds = iso_string__abs(this._milliseconds) / 1000;
4100
  var days = iso_string__abs(this._days);
4101
  var months = iso_string__abs(this._months);
4102
  var minutes, hours, years;
4103
 
4104
+ // 3600 seconds -> 60 minutes -> 1 hour.
4105
  minutes = absFloor(seconds / 60);
4106
  hours = absFloor(minutes / 60);
4107
  seconds %= 60;
4108
  minutes %= 60;
4109
 
4110
+ // 12 months -> 1 year.
4111
  years = absFloor(months / 12);
4112
  months %= 12;
4113
 
4114
 
4115
+ // Inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js
4116
  var Y = years;
4117
  var M = months;
4118
  var D = days;
4122
  var total = this.asSeconds();
4123
 
4124
  if (!total) {
4125
+ // This is the same as C#'s (Noda) and python (isodate)...
4126
+ // but not other JS (goog.date).
4127
  return 'P0D';
4128
  }
4129
 
4170
  duration_prototype__proto.locale = locale;
4171
  duration_prototype__proto.localeData = localeData;
4172
 
4173
+ // Deprecations.
4174
  duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);
4175
  duration_prototype__proto.lang = lang;
4176
 
4177
+ // Side effect imports.
4178
 
4179
+ // FORMATTING.
4180
 
4181
  addFormatToken('X', 0, 0, 'unix');
4182
  addFormatToken('x', 0, 0, 'valueOf');
4183
 
4184
+ // PARSING.
4185
 
4186
  addRegexToken('x', matchSigned);
4187
  addRegexToken('X', matchTimestamp);
4192
  config._d = new Date(toInt(input));
4193
  });
4194
 
4195
+ // Side effect imports.
4196
 
4197
 
4198
  utils_hooks__hooks.version = '2.15.1';
bp-core/js/webcam.js CHANGED
@@ -4,7 +4,7 @@ window.bp = window.bp || {};
4
 
5
  ( function() {
6
 
7
- // Bail if not set
8
  if ( typeof BP_Uploader === 'undefined' ) {
9
  return;
10
  }
@@ -30,28 +30,28 @@ window.bp = window.bp || {};
30
 
31
  setView: function( view ) {
32
  if ( 'camera' !== view ) {
33
- // Stop the camera if needed
34
  if ( ! _.isNull( this.params.video ) ) {
35
  this.stop();
36
 
37
- // Remove all warnings as we're changing the view
38
  this.removeWarning();
39
  }
40
 
41
- // Stop as this is not Camera area
42
  return;
43
  }
44
 
45
- // Create the WebCam view
46
  var cameraView = new bp.Views.WebCamAvatar( { model: new Backbone.Model( { user_media: false } ) } );
47
 
48
- // Make sure the flipped param is reset
49
  this.params.flipped = false;
50
 
51
- // Add it to views
52
  bp.Avatar.views.add( { id: 'camera', view: cameraView } );
53
 
54
- // Display it
55
  cameraView.inject( '.bp-avatar' );
56
  },
57
 
@@ -69,11 +69,11 @@ window.bp = window.bp || {};
69
  var video = bp.WebCam.params.video;
70
  bp.WebCam.params.videoStream = stream;
71
 
72
- // User Feedback
73
  bp.WebCam.displayWarning( 'loaded' );
74
 
75
  video.onerror = function () {
76
- // User Feedback
77
  bp.WebCam.displayWarning( 'videoerror' );
78
 
79
  if ( video ) {
@@ -83,7 +83,7 @@ window.bp = window.bp || {};
83
 
84
  stream.onended = bp.WebCam.noStream();
85
 
86
- // Older browsers may not have srcObject
87
  if ( 'srcObject' in video ) {
88
  video.srcObject = stream;
89
  } else {
@@ -121,7 +121,7 @@ window.bp = window.bp || {};
121
 
122
  noStream: function() {
123
  if ( _.isNull( bp.WebCam.params.videoStream ) ) {
124
- // User Feedback
125
  bp.WebCam.displayWarning( 'noaccess' );
126
 
127
  bp.WebCam.removeView();
@@ -133,7 +133,7 @@ window.bp = window.bp || {};
133
  bp.WebCam.displayWarning( 'nocapture' );
134
  }
135
 
136
- // Remove the view
137
  bp.WebCam.removeView();
138
 
139
  bp.Avatar.setAvatar( avatar );
@@ -156,7 +156,7 @@ window.bp = window.bp || {};
156
  }
157
  };
158
 
159
- // BuddyPress WebCam view
160
  bp.Views.WebCamAvatar = bp.View.extend( {
161
  tagName: 'div',
162
  id: 'bp-webcam-avatar',
@@ -180,7 +180,7 @@ window.bp = window.bp || {};
180
  );
181
 
182
  if ( typeof navigator.getUserMedia !== 'undefined' ) {
183
- // We need to add some cropping stuff to use bp.Avatar.setAvatar()
184
  params = _.extend( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
185
  'object',
186
  'item_id',
@@ -216,7 +216,7 @@ window.bp = window.bp || {};
216
  bp.WebCam.params.video = this.options.video.el;
217
  bp.WebCam.params.canvas = this.options.canvas.el;
218
 
219
- // User Feedback
220
  bp.WebCam.displayWarning( 'requesting' );
221
 
222
  // Use deprecated getUserMedia call for browsers that require it.
@@ -234,7 +234,7 @@ window.bp = window.bp || {};
234
  }).then(bp.WebCam.gotStream, bp.WebCam.noStream)
235
  // ES3 compatibility.
236
  ['catch'](function() {
237
- // User Feedback
238
  bp.WebCam.displayWarning( 'errormsg' );
239
  });
240
  }
@@ -245,7 +245,7 @@ window.bp = window.bp || {};
245
  event.preventDefault();
246
 
247
  if ( ! bp.WebCam.params.capture_enable ) {
248
- // User Feedback
249
  bp.WebCam.displayWarning( 'loading' );
250
  return;
251
  }
@@ -255,7 +255,7 @@ window.bp = window.bp || {};
255
  return;
256
  }
257
 
258
- // Set the offset
259
  sc = this.options.video.el.videoHeight;
260
  sx = ( this.options.video.el.videoWidth - sc ) / 2;
261
 
@@ -270,7 +270,7 @@ window.bp = window.bp || {};
270
  bp.WebCam.params.capture = this.options.canvas.el.toDataURL( 'image/png' );
271
  this.model.set( 'url', bp.WebCam.params.capture );
272
 
273
- // User Feedback
274
  bp.WebCam.displayWarning( 'ready' );
275
  },
276
 
@@ -278,7 +278,7 @@ window.bp = window.bp || {};
278
  event.preventDefault();
279
 
280
  if ( ! bp.WebCam.params.capture ) {
281
- // User Feedback
282
  bp.WebCam.displayWarning( 'nocapture' );
283
  return;
284
  }
@@ -288,7 +288,7 @@ window.bp = window.bp || {};
288
  }
289
  } );
290
 
291
- // BuddyPress Video stream view
292
  bp.Views.WebCamVideo = bp.View.extend( {
293
  tagName: 'video',
294
  id: 'bp-webcam-video',
@@ -297,7 +297,7 @@ window.bp = window.bp || {};
297
  }
298
  } );
299
 
300
- // BuddyPress Canvas (capture) view
301
  bp.Views.WebCamCanvas = bp.View.extend( {
302
  tagName: 'canvas',
303
  id: 'bp-webcam-canvas',
@@ -307,7 +307,7 @@ window.bp = window.bp || {};
307
  },
308
 
309
  initialize: function() {
310
- // Make sure to take in account bp_core_avatar_full_height or bp_core_avatar_full_width php filters
311
  if ( ! _.isUndefined( BP_Uploader.settings.crop.full_h ) && ! _.isUndefined( BP_Uploader.settings.crop.full_w ) ) {
312
  this.el.attributes.width.value = BP_Uploader.settings.crop.full_w;
313
  this.el.attributes.height.value = BP_Uploader.settings.crop.full_h;
4
 
5
  ( function() {
6
 
7
+ // Bail if not set.
8
  if ( typeof BP_Uploader === 'undefined' ) {
9
  return;
10
  }
30
 
31
  setView: function( view ) {
32
  if ( 'camera' !== view ) {
33
+ // Stop the camera if needed.
34
  if ( ! _.isNull( this.params.video ) ) {
35
  this.stop();
36
 
37
+ // Remove all warnings as we're changing the view.
38
  this.removeWarning();
39
  }
40
 
41
+ // Stop as this is not Camera area.
42
  return;
43
  }
44
 
45
+ // Create the WebCam view.
46
  var cameraView = new bp.Views.WebCamAvatar( { model: new Backbone.Model( { user_media: false } ) } );
47
 
48
+ // Make sure the flipped param is reset.
49
  this.params.flipped = false;
50
 
51
+ // Add it to views.
52
  bp.Avatar.views.add( { id: 'camera', view: cameraView } );
53
 
54
+ // Display it.
55
  cameraView.inject( '.bp-avatar' );
56
  },
57
 
69
  var video = bp.WebCam.params.video;
70
  bp.WebCam.params.videoStream = stream;
71
 
72
+ // User Feedback.
73
  bp.WebCam.displayWarning( 'loaded' );
74
 
75
  video.onerror = function () {
76
+ // User Feedback.
77
  bp.WebCam.displayWarning( 'videoerror' );
78
 
79
  if ( video ) {
83
 
84
  stream.onended = bp.WebCam.noStream();
85
 
86
+ // Older browsers may not have srcObject.
87
  if ( 'srcObject' in video ) {
88
  video.srcObject = stream;
89
  } else {
121
 
122
  noStream: function() {
123
  if ( _.isNull( bp.WebCam.params.videoStream ) ) {
124
+ // User Feedback.
125
  bp.WebCam.displayWarning( 'noaccess' );
126
 
127
  bp.WebCam.removeView();
133
  bp.WebCam.displayWarning( 'nocapture' );
134
  }
135
 
136
+ // Remove the view.
137
  bp.WebCam.removeView();
138
 
139
  bp.Avatar.setAvatar( avatar );
156
  }
157
  };
158
 
159
+ // BuddyPress WebCam view.
160
  bp.Views.WebCamAvatar = bp.View.extend( {
161
  tagName: 'div',
162
  id: 'bp-webcam-avatar',
180
  );
181
 
182
  if ( typeof navigator.getUserMedia !== 'undefined' ) {
183
+ // We need to add some cropping stuff to use bp.Avatar.setAvatar().
184
  params = _.extend( _.pick( BP_Uploader.settings.defaults.multipart_params.bp_params,
185
  'object',
186
  'item_id',
216
  bp.WebCam.params.video = this.options.video.el;
217
  bp.WebCam.params.canvas = this.options.canvas.el;
218
 
219
+ // User Feedback.
220
  bp.WebCam.displayWarning( 'requesting' );
221
 
222
  // Use deprecated getUserMedia call for browsers that require it.
234
  }).then(bp.WebCam.gotStream, bp.WebCam.noStream)
235
  // ES3 compatibility.
236
  ['catch'](function() {
237
+ // User Feedback.
238
  bp.WebCam.displayWarning( 'errormsg' );
239
  });
240
  }
245
  event.preventDefault();
246
 
247
  if ( ! bp.WebCam.params.capture_enable ) {
248
+ // User Feedback.
249
  bp.WebCam.displayWarning( 'loading' );
250
  return;
251
  }
255
  return;
256
  }
257
 
258
+ // Set the offset.
259
  sc = this.options.video.el.videoHeight;
260
  sx = ( this.options.video.el.videoWidth - sc ) / 2;
261
 
270
  bp.WebCam.params.capture = this.options.canvas.el.toDataURL( 'image/png' );
271
  this.model.set( 'url', bp.WebCam.params.capture );
272
 
273
+ // User Feedback.
274
  bp.WebCam.displayWarning( 'ready' );
275
  },
276
 
278
  event.preventDefault();
279
 
280
  if ( ! bp.WebCam.params.capture ) {
281
+ // User Feedback.
282
  bp.WebCam.displayWarning( 'nocapture' );
283
  return;
284
  }
288
  }
289
  } );
290
 
291
+ // BuddyPress Video stream view.
292
  bp.Views.WebCamVideo = bp.View.extend( {
293
  tagName: 'video',
294
  id: 'bp-webcam-video',
297
  }
298
  } );
299
 
300
+ // BuddyPress Canvas (capture) view.
301
  bp.Views.WebCamCanvas = bp.View.extend( {
302
  tagName: 'canvas',
303
  id: 'bp-webcam-canvas',
307
  },
308
 
309
  initialize: function() {
310
+ // Make sure to take in account bp_core_avatar_full_height or bp_core_avatar_full_width php filters.
311
  if ( ! _.isUndefined( BP_Uploader.settings.crop.full_h ) && ! _.isUndefined( BP_Uploader.settings.crop.full_w ) ) {
312
  this.el.attributes.width.value = BP_Uploader.settings.crop.full_w;
313
  this.el.attributes.height.value = BP_Uploader.settings.crop.full_h;
bp-friends/bp-friends-activity.php CHANGED
@@ -141,6 +141,7 @@ function bp_friends_format_activity_action_friendship_accepted( $action, $activi
141
  $initiator_link = bp_core_get_userlink( $activity->user_id );
142
  $friend_link = bp_core_get_userlink( $activity->secondary_item_id );
143
 
 
144
  $action = sprintf( esc_html__( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link );
145
 
146
  // Backward compatibility for legacy filter
@@ -175,6 +176,7 @@ function bp_friends_format_activity_action_friendship_created( $action, $activit
175
  $initiator_link = bp_core_get_userlink( $activity->user_id );
176
  $friend_link = bp_core_get_userlink( $activity->secondary_item_id );
177
 
 
178
  $action = sprintf( esc_html__( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link );
179
 
180
  // Backward compatibility for legacy filter
@@ -310,7 +312,7 @@ function bp_friends_filter_activity_just_me_scope( $retval = array(), $filter =
310
  }
311
 
312
  // Get the requested action.
313
- $action = $filter['filter']['action'];
314
 
315
  // Make sure actions are listed in an array.
316
  if ( ! is_array( $action ) ) {
141
  $initiator_link = bp_core_get_userlink( $activity->user_id );
142
  $friend_link = bp_core_get_userlink( $activity->secondary_item_id );
143
 
144
+ /* translators: 1: the initiator user link. 2: the friend user link. */
145
  $action = sprintf( esc_html__( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link );
146
 
147
  // Backward compatibility for legacy filter
176
  $initiator_link = bp_core_get_userlink( $activity->user_id );
177
  $friend_link = bp_core_get_userlink( $activity->secondary_item_id );
178
 
179
+ /* translators: 1: the initiator user link. 2: the friend user link. */
180
  $action = sprintf( esc_html__( '%1$s and %2$s are now friends', 'buddypress' ), $initiator_link, $friend_link );
181
 
182
  // Backward compatibility for legacy filter
312
  }
313
 
314
  // Get the requested action.
315
+ $action = isset( $filter['filter']['action'] ) ? $filter['filter']['action'] : array();
316
 
317
  // Make sure actions are listed in an array.
318
  if ( ! is_array( $action ) ) {
bp-friends/bp-friends-functions.php CHANGED
@@ -757,9 +757,24 @@ function friends_remove_data( $user_id ) {
757
  do_action( 'friends_remove_data', $user_id );
758
  }
759
  add_action( 'wpmu_delete_user', 'friends_remove_data' );
760
- add_action( 'delete_user', 'friends_remove_data' );
761
  add_action( 'bp_make_spam_user', 'friends_remove_data' );
762
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
763
  /**
764
  * Used by the Activity component's @mentions to print a JSON list of the current user's friends.
765
  *
757
  do_action( 'friends_remove_data', $user_id );
758
  }
759
  add_action( 'wpmu_delete_user', 'friends_remove_data' );
 
760
  add_action( 'bp_make_spam_user', 'friends_remove_data' );
761
 
762
+ /**
763
+ * Deletes user Friends data on the 'delete_user' hook.
764
+ *
765
+ * @since 6.0.0
766
+ *
767
+ * @param int $user_id The ID of the deleted user.
768
+ */
769
+ function bp_friends_remove_data_on_delete_user( $user_id ) {
770
+ if ( ! bp_remove_user_data_on_delete_user_hook( 'friends', $user_id ) ) {
771
+ return;
772
+ }
773
+
774
+ friends_remove_data( $user_id );
775
+ }
776
+ add_action( 'delete_user', 'bp_friends_remove_data_on_delete_user' );
777
+
778
  /**
779
  * Used by the Activity component's @mentions to print a JSON list of the current user's friends.
780
  *
bp-friends/bp-friends-notifications.php CHANGED
@@ -38,9 +38,11 @@ function friends_format_notifications( $action, $item_id, $secondary_item_id, $t
38
 
39
  // Set up the string and the filter.
40
  if ( (int) $total_items > 1 ) {
 
41
  $text = sprintf( __( '%d friends accepted your friendship requests', 'buddypress' ), (int) $total_items );
42
  $amount = 'multiple';
43
  } else {
 
44
  $text = sprintf( __( '%s accepted your friendship request', 'buddypress' ), bp_core_get_user_displayname( $item_id ) );
45
  $amount = 'single';
46
  }
@@ -54,9 +56,11 @@ function friends_format_notifications( $action, $item_id, $secondary_item_id, $t
54
 
55
  // Set up the string and the filter.
56
  if ( (int) $total_items > 1 ) {
 
57
  $text = sprintf( __( 'You have %d pending friendship requests', 'buddypress' ), (int) $total_items );
58
  $amount = 'multiple';
59
  } else {
 
60
  $text = sprintf( __( 'You have a friendship request from %s', 'buddypress' ), bp_core_get_user_displayname( $item_id ) );
61
  $amount = 'single';
62
  }
@@ -78,20 +82,20 @@ function friends_format_notifications( $action, $item_id, $secondary_item_id, $t
78
  * - bp_friends_multiple_friendship_request_notification
79
  *
80
  * @since 1.0.0
 
81
  *
82
- * @param string|array $value Depending on format, an HTML link to new requests profile
83
- * tab or array with link and text.
84
- * @param int $total_items The total number of messaging-related notifications
85
- * waiting for the user.
86
- * @param int $item_id The primary item ID.
87
  */
88
- $return = apply_filters( 'bp_friends_' . $amount . '_friendship_' . $action . '_notification', '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>', (int) $total_items, $item_id );
89
  } else {
90
  /** This filter is documented in bp-friends/bp-friends-notifications.php */
91
  $return = apply_filters( 'bp_friends_' . $amount . '_friendship_' . $action . '_notification', array(
92
  'link' => $link,
93
  'text' => $text
94
- ), (int) $total_items, $item_id );
95
  }
96
 
97
  /**
38
 
39
  // Set up the string and the filter.
40
  if ( (int) $total_items > 1 ) {
41
+ /* translators: %d: the number of friends */
42
  $text = sprintf( __( '%d friends accepted your friendship requests', 'buddypress' ), (int) $total_items );
43
  $amount = 'multiple';
44
  } else {
45
+ /* translators: %s: friend name */
46
  $text = sprintf( __( '%s accepted your friendship request', 'buddypress' ), bp_core_get_user_displayname( $item_id ) );
47
  $amount = 'single';
48
  }
56
 
57
  // Set up the string and the filter.
58
  if ( (int) $total_items > 1 ) {
59
+ /* translators: %d: the number of pending requests */
60
  $text = sprintf( __( 'You have %d pending friendship requests', 'buddypress' ), (int) $total_items );
61
  $amount = 'multiple';
62
  } else {
63
+ /* translators: %s: friend name */
64
  $text = sprintf( __( 'You have a friendship request from %s', 'buddypress' ), bp_core_get_user_displayname( $item_id ) );
65
  $amount = 'single';
66
  }
82
  * - bp_friends_multiple_friendship_request_notification
83
  *
84
  * @since 1.0.0
85
+ * @since 6.0.0 Adds the $secondary_item_id parameter.
86
  *
87
+ * @param string|array $value Depending on format, an HTML link to new requests profile tab or array with link and text.
88
+ * @param int $total_items The total number of messaging-related notifications waiting for the user.
89
+ * @param int $item_id The primary item ID.
90
+ * @param int $secondary_item_id The secondary item ID.
 
91
  */
92
+ $return = apply_filters( 'bp_friends_' . $amount . '_friendship_' . $action . '_notification', '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>', (int) $total_items, $item_id, $secondary_item_id );
93
  } else {
94
  /** This filter is documented in bp-friends/bp-friends-notifications.php */
95
  $return = apply_filters( 'bp_friends_' . $amount . '_friendship_' . $action . '_notification', array(
96
  'link' => $link,
97
  'text' => $text
98
+ ), (int) $total_items, $item_id, $secondary_item_id );
99
  }
100
 
101
  /**
bp-friends/bp-friends-template.php CHANGED
@@ -81,7 +81,20 @@ function bp_friends_random_friends() {
81
  } ?>
82
 
83
  <div class="info-group">
84
- <h4><?php bp_word_or_name( __( "My Friends", 'buddypress' ), __( "%s's Friends", 'buddypress' ) ) ?> (<?php echo BP_Friends_Friendship::total_friend_count( bp_displayed_user_id() ) ?>) <span><a href="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_friends_slug() ) ?>"><?php _e('See All', 'buddypress') ?></a></span></h4>
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
86
  <?php if ( $friend_ids ) { ?>
87
 
@@ -101,7 +114,12 @@ function bp_friends_random_friends() {
101
  <?php } else { ?>
102
 
103
  <div id="message" class="info">
104
- <p><?php bp_word_or_name( __( "You haven't added any friend connections yet.", 'buddypress' ), __( "%s hasn't created any friend connections yet.", 'buddypress' ) ) ?></p>
 
 
 
 
 
105
  </div>
106
 
107
  <?php } ?>
@@ -234,22 +252,21 @@ function bp_member_total_friend_count() {
234
  function bp_get_member_total_friend_count() {
235
  global $members_template;
236
 
237
- if ( 1 == (int) $members_template->member->total_friend_count ) {
238
-
239
- /**
240
- * Filters text used to denote total friend count.
241
- *
242
- * @since 1.2.0
243
- *
244
- * @param string $value String of the form "x friends".
245
- * @param int $value Total friend count for current member in the loop.
246
- */
247
- return apply_filters( 'bp_get_member_total_friend_count', sprintf( __( '%d friend', 'buddypress' ), (int) $members_template->member->total_friend_count ) );
248
- } else {
249
-
250
- /** This filter is documented in bp-friends/bp-friends-template.php */
251
- return apply_filters( 'bp_get_member_total_friend_count', sprintf( __( '%d friends', 'buddypress' ), (int) $members_template->member->total_friend_count ) );
252
- }
253
  }
254
 
255
  /**
@@ -716,7 +733,11 @@ function bp_friends_get_profile_stats( $args = '' ) {
716
  }
717
 
718
  // If friends exist, show some formatted output.
719
- $r['output'] = $r['before'] . sprintf( _n( '%s friend', '%s friends', $r['friends'], 'buddypress' ), '<strong>' . $r['friends'] . '</strong>' ) . $r['after'];
 
 
 
 
720
  }
721
  }
722
 
81
  } ?>
82
 
83
  <div class="info-group">
84
+ <h4>
85
+ <?php
86
+ /* translators: %s: member name */
87
+ bp_word_or_name( __( "My Friends", 'buddypress' ), __( "%s's Friends", 'buddypress' ) );
88
+ ?>
89
+ &nbsp;
90
+ (<?php echo BP_Friends_Friendship::total_friend_count( bp_displayed_user_id() ); ?>)
91
+ &nbsp;
92
+ <span>
93
+ <a href="<?php echo trailingslashit( bp_displayed_user_domain() . bp_get_friends_slug() ) ?>">
94
+ <?php esc_html_e( 'See All', 'buddypress' ) ?>
95
+ </a>
96
+ </span>
97
+ </h4>
98
 
99
  <?php if ( $friend_ids ) { ?>
100
 
114
  <?php } else { ?>
115
 
116
  <div id="message" class="info">
117
+ <p>
118
+ <?php
119
+ /* translators: %s: member name */
120
+ bp_word_or_name( __( "You haven't added any friend connections yet.", 'buddypress' ), __( "%s hasn't created any friend connections yet.", 'buddypress' ) );
121
+ ?>
122
+ </p>
123
  </div>
124
 
125
  <?php } ?>
252
  function bp_get_member_total_friend_count() {
253
  global $members_template;
254
 
255
+ $total_friend_count = (int) $members_template->member->total_friend_count;
256
+
257
+ /**
258
+ * Filters text used to denote total friend count.
259
+ *
260
+ * @since 1.2.0
261
+ *
262
+ * @param string $value String of the form "x friends".
263
+ * @param int $value Total friend count for current member in the loop.
264
+ */
265
+ return apply_filters(
266
+ 'bp_get_member_total_friend_count',
267
+ /* translators: %d: total friend count */
268
+ sprintf( _n( '%d friend', '%d friends', $total_friend_count, 'buddypress' ), number_format_i18n( $total_friend_count ) )
269
+ );
 
270
  }
271
 
272
  /**
733
  }
734
 
735
  // If friends exist, show some formatted output.
736
+ $r['output'] = $r['before'];
737
+
738
+ /* translators: %d: total friend count */
739
+ $r['output'] .= sprintf( _n( '%d friend', '%d friends', $r['friends'], 'buddypress' ), '<strong>' . number_format_i18n( $r['friends'] ) . '</strong>' );
740
+ $r['output'] .= $r['after'];
741
  }
742
  }
743
 
bp-friends/classes/class-bp-friends-component.php CHANGED
@@ -296,7 +296,11 @@ class BP_Friends_Component extends BP_Component {
296
  $bp->bp_options_avatar = bp_core_fetch_avatar( array(
297
  'item_id' => bp_displayed_user_id(),
298
  'type' => 'thumb',
299
- 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() )
 
 
 
 
300
  ) );
301
  $bp->bp_options_title = bp_get_displayed_user_fullname();
302
  }
@@ -321,4 +325,16 @@ class BP_Friends_Component extends BP_Component {
321
 
322
  parent::setup_cache_groups();
323
  }
 
 
 
 
 
 
 
 
 
 
 
 
324
  }
296
  $bp->bp_options_avatar = bp_core_fetch_avatar( array(
297
  'item_id' => bp_displayed_user_id(),
298
  'type' => 'thumb',
299
+ 'alt' => sprintf(
300
+ /* translators: %s: member name */
301
+ __( 'Profile picture of %s', 'buddypress' ),
302
+ bp_get_displayed_user_fullname()
303
+ ),
304
  ) );
305
  $bp->bp_options_title = bp_get_displayed_user_fullname();
306
  }
325
 
326
  parent::setup_cache_groups();
327
  }
328
+
329
+ /**
330
+ * Init the BP REST API.
331
+ *
332
+ * @since 6.0.0
333
+ *
334
+ * @param array $controllers Optional. See BP_Component::rest_api_init() for
335
+ * description.
336
+ */
337
+ public function rest_api_init( $controllers = array() ) {
338
+ parent::rest_api_init( array( 'BP_REST_Friends_Endpoint' ) );
339
+ }
340
  }
bp-friends/classes/class-bp-rest-friends-endpoint.php ADDED
@@ -0,0 +1,924 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Friends_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 6.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Friendship endpoints.
13
+ *
14
+ * /friends/
15
+ * /friends/{id}
16
+ *
17
+ * @since 6.0.0
18
+ */
19
+ class BP_REST_Friends_Endpoint extends WP_REST_Controller {
20
+
21
+ /**
22
+ * Constructor.
23
+ *
24
+ * @since 6.0.0
25
+ */
26
+ public function __construct() {
27
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
28
+ $this->rest_base = buddypress()->friends->id;
29
+ }
30
+
31
+ /**
32
+ * Register the component routes.
33
+ *
34
+ * @since 6.0.0
35
+ */
36
+ public function register_routes() {
37
+ register_rest_route(
38
+ $this->namespace,
39
+ '/' . $this->rest_base,
40
+ array(
41
+ array(
42
+ 'methods' => WP_REST_Server::READABLE,
43
+ 'callback' => array( $this, 'get_items' ),
44
+ 'permission_callback' => array( $this, 'get_items_permissions_check' ),
45
+ 'args' => $this->get_collection_params(),
46
+ ),
47
+ array(
48
+ 'methods' => WP_REST_Server::CREATABLE,
49
+ 'callback' => array( $this, 'create_item' ),
50
+ 'permission_callback' => array( $this, 'create_item_permissions_check' ),
51
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
52
+ ),
53
+ 'schema' => array( $this, 'get_item_schema' ),
54
+ )
55
+ );
56
+
57
+ register_rest_route(
58
+ $this->namespace,
59
+ '/' . $this->rest_base . '/(?P<id>[\w-]+)',
60
+ array(
61
+ 'args' => array(
62
+ 'id' => array(
63
+ 'description' => __( 'Identifier for a user ID.', 'buddypress' ),
64
+ 'type' => 'integer',
65
+ ),
66
+ ),
67
+ array(
68
+ 'methods' => WP_REST_Server::READABLE,
69
+ 'callback' => array( $this, 'get_item' ),
70
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
71
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::READABLE ),
72
+ ),
73
+ array(
74
+ 'methods' => WP_REST_Server::EDITABLE,
75
+ 'callback' => array( $this, 'update_item' ),
76
+ 'permission_callback' => array( $this, 'update_item_permissions_check' ),
77
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
78
+ ),
79
+ array(
80
+ 'methods' => WP_REST_Server::DELETABLE,
81
+ 'callback' => array( $this, 'delete_item' ),
82
+ 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
83
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::DELETABLE ),
84
+ ),
85
+ 'schema' => array( $this, 'get_item_schema' ),
86
+ )
87
+ );
88
+ }
89
+
90
+ /**
91
+ * Retrieve friendships.
92
+ *
93
+ * @since 6.0.0
94
+ *
95
+ * @param WP_REST_Request $request Full details about the request.
96
+ * @return WP_REST_Response
97
+ */
98
+ public function get_items( $request ) {
99
+ $args = array(
100
+ 'id' => $request->get_param( 'id' ),
101
+ 'initiator_user_id' => $request->get_param( 'initiator_id' ),
102
+ 'friend_user_id' => $request->get_param( 'friend_id' ),
103
+ 'is_confirmed' => $request->get_param( 'is_confirmed' ),
104
+ 'order_by' => $request->get_param( 'order_by' ),
105
+ 'sort_order' => strtoupper( $request->get_param( 'order' ) ),
106
+ 'page' => $request->get_param( 'page' ),
107
+ 'per_page' => $request->get_param( 'per_page' ),
108
+ );
109
+
110
+ /**
111
+ * Filter the query arguments for the request.
112
+ *
113
+ * @since 6.0.0
114
+ *
115
+ * @param array $args Key value array of query var to query value.
116
+ * @param WP_REST_Request $request The request sent to the API.
117
+ */
118
+ $args = apply_filters( 'bp_rest_friends_get_items_query_args', $args, $request );
119
+
120
+ // null is the default values.
121
+ foreach ( $args as $key => $value ) {
122
+ if ( empty( $value ) ) {
123
+ $args[ $key ] = null;
124
+ }
125
+ }
126
+
127
+ // Check if user is valid.
128
+ $user = get_user_by( 'id', $request->get_param( 'user_id' ) );
129
+ if ( ! $user instanceof WP_User ) {
130
+ return new WP_Error(
131
+ 'bp_rest_friends_get_items_user_failed',
132
+ __( 'There was a problem confirming if user is a valid one.', 'buddypress' ),
133
+ array(
134
+ 'status' => 500,
135
+ )
136
+ );
137
+ }
138
+
139
+ // Actually, query it.
140
+ $friendships = BP_Friends_Friendship::get_friendships( $user->ID, $args );
141
+
142
+ $retval = array();
143
+ foreach ( (array) $friendships as $friendship ) {
144
+ $retval[] = $this->prepare_response_for_collection(
145
+ $this->prepare_item_for_response( $friendship, $request )
146
+ );
147
+ }
148
+
149
+ $response = rest_ensure_response( $retval );
150
+ $response = bp_rest_response_add_total_headers( $response, count( $friendships ), $args['per_page'] );
151
+
152
+ /**
153
+ * Fires after friendships are fetched via the REST API.
154
+ *
155
+ * @since 6.0.0
156
+ *
157
+ * @param array $friendships Fetched friendships.
158
+ * @param WP_REST_Response $response The response data.
159
+ * @param WP_REST_Request $request The request sent to the API.
160
+ */
161
+ do_action( 'bp_rest_friends_get_items', $friendships, $response, $request );
162
+
163
+ return $response;
164
+ }
165
+
166
+ /**
167
+ * Check if a given request has access to friendship items.
168
+ *
169
+ * @since 6.0.0
170
+ *
171
+ * @param WP_REST_Request $request Full data about the request.
172
+ * @return WP_Error|bool
173
+ */
174
+ public function get_items_permissions_check( $request ) {
175
+ $retval = true;
176
+
177
+ if ( ! is_user_logged_in() ) {
178
+ $retval = new WP_Error(
179
+ 'bp_rest_authorization_required',
180
+ __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
181
+ array(
182
+ 'status' => rest_authorization_required_code(),
183
+ )
184
+ );
185
+ }
186
+
187
+ /**
188
+ * Filter the friends `get_items` permissions check.
189
+ *
190
+ * @since 6.0.0
191
+ *
192
+ * @param bool|WP_Error $retval Returned value.
193
+ * @param WP_REST_Request $request The request sent to the API.
194
+ */
195
+ return apply_filters( 'bp_rest_friends_get_items_permissions_check', $retval, $request );
196
+ }
197
+
198
+ /**
199
+ * Retrieve single friendship.
200
+ *
201
+ * @since 6.0.0
202
+ *
203
+ * @param WP_REST_Request $request Full data about the request.
204
+ * @return WP_REST_Response|WP_Error
205
+ */
206
+ public function get_item( $request ) {
207
+ $user = get_user_by( 'id', $request->get_param( 'id' ) );
208
+
209
+ // Check if user is valid.
210
+ if ( false === $user ) {
211
+ return new WP_Error(
212
+ 'bp_rest_friends_get_item_failed',
213
+ __( 'There was a problem confirming if user is valid.', 'buddypress' ),
214
+ array(
215
+ 'status' => 404,
216
+ )
217
+ );
218
+ }
219
+
220
+ // Get friendship.
221
+ $friendship = $this->get_friendship_object(
222
+ BP_Friends_Friendship::get_friendship_id( bp_loggedin_user_id(), $user->ID )
223
+ );
224
+
225
+ if ( ! $friendship || empty( $friendship->id ) ) {
226
+ return new WP_Error(
227
+ 'bp_rest_invalid_id',
228
+ __( 'Friendship does not exist.', 'buddypress' ),
229
+ array(
230
+ 'status' => 404,
231
+ )
232
+ );
233
+ }
234
+
235
+ $retval = array(
236
+ $this->prepare_response_for_collection(
237
+ $this->prepare_item_for_response( $friendship, $request )
238
+ ),
239
+ );
240
+
241
+ $response = rest_ensure_response( $retval );
242
+
243
+ /**
244
+ * Fires before a friendship is retrieved via the REST API.
245
+ *
246
+ * @since 6.0.0
247
+ *
248
+ * @param BP_Friends_Friendship $friendship The friendship object.
249
+ * @param WP_REST_Response $response The response data.
250
+ * @param WP_REST_Request $request The request sent to the API.
251
+ */
252
+ do_action( 'bp_rest_friends_get_item', $friendship, $response, $request );
253
+
254
+ return $response;
255
+ }
256
+
257
+ /**
258
+ * Check if a given request has access to get a friendship.
259
+ *
260
+ * @since 6.0.0
261
+ *
262
+ * @param WP_REST_Request $request Full data about the request.
263
+ * @return WP_Error|bool
264
+ */
265
+ public function get_item_permissions_check( $request ) {
266
+ $retval = true;
267
+
268
+ if ( ! is_user_logged_in() ) {
269
+ $retval = new WP_Error(
270
+ 'bp_rest_authorization_required',
271
+ __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
272
+ array(
273
+ 'status' => rest_authorization_required_code(),
274
+ )
275
+ );
276
+ }
277
+
278
+ /**
279
+ * Filter the friendship `get_item` permissions check.
280
+ *
281
+ * @since 6.0.0
282
+ *
283
+ * @param bool|WP_Error $retval Returned value.
284
+ * @param WP_REST_Request $request The request sent to the API.
285
+ */
286
+ return apply_filters( 'bp_rest_friends_get_item_permissions_check', $retval, $request );
287
+ }
288
+
289
+ /**
290
+ * Create a new friendship.
291
+ *
292
+ * @since 6.0.0
293
+ *
294
+ * @param WP_REST_Request $request Full details about the request.
295
+ * @return WP_REST_Response|WP_Error
296
+ */
297
+ public function create_item( $request ) {
298
+ $initiator_id = get_user_by( 'id', $request->get_param( 'initiator_id' ) );
299
+ $friend_id = get_user_by( 'id', $request->get_param( 'friend_id' ) );
300
+
301
+ // Check if users are valid.
302
+ if ( ! $initiator_id || ! $friend_id ) {
303
+ return new WP_Error(
304
+ 'bp_rest_friends_create_item_failed',
305
+ __( 'There was a problem confirming if user is valid.', 'buddypress' ),
306
+ array(
307
+ 'status' => 500,
308
+ )
309
+ );
310
+ }
311
+
312
+ $is_moderator = bp_current_user_can( 'bp_moderate' );
313
+
314
+ // Only admins can create friendship requests for other people.
315
+ if ( ! in_array( bp_loggedin_user_id(), [ $initiator_id->ID, $friend_id->ID ], true ) && ! $is_moderator ) {
316
+ return new WP_Error(
317
+ 'bp_rest_friends_create_item_failed',
318
+ __( 'You are not allowed to perform this action.', 'buddypress' ),
319
+ array(
320
+ 'status' => 500,
321
+ )
322
+ );
323
+ }
324
+
325
+ // Only admins can force a friendship request.
326
+ $force = false;
327
+ if ( true === $request->get_param( 'force' ) && $is_moderator ) {
328
+ $force = true;
329
+ }
330
+
331
+ // Adding friendship.
332
+ if ( ! friends_add_friend( $initiator_id->ID, $friend_id->ID, $force ) ) {
333
+ return new WP_Error(
334
+ 'bp_rest_friends_create_item_failed',
335
+ __( 'There was an error trying to create the friendship.', 'buddypress' ),
336
+ array(
337
+ 'status' => 500,
338
+ )
339
+ );
340
+ }
341
+
342
+ // Get friendship.
343
+ $friendship = $this->get_friendship_object(
344
+ BP_Friends_Friendship::get_friendship_id( $initiator_id->ID, $friend_id->ID )
345
+ );
346
+
347
+ if ( ! $friendship || empty( $friendship->id ) ) {
348
+ return new WP_Error(
349
+ 'bp_rest_invalid_id',
350
+ __( 'Friendship does not exist.', 'buddypress' ),
351
+ array(
352
+ 'status' => 404,
353
+ )
354
+ );
355
+ }
356
+
357
+ $retval = array(
358
+ $this->prepare_response_for_collection(
359
+ $this->prepare_item_for_response( $friendship, $request )
360
+ ),
361
+ );
362
+
363
+ $response = rest_ensure_response( $retval );
364
+
365
+ /**
366
+ * Fires after a friendship is created via the REST API.
367
+ *
368
+ * @since 6.0.0
369
+ *
370
+ * @param BP_Friends_Friendship $friendship The friendship object.
371
+ * @param WP_REST_Response $retval The response data.
372
+ * @param WP_REST_Request $request The request sent to the API.
373
+ */
374
+ do_action( 'bp_rest_friends_create_item', $friendship, $response, $request );
375
+
376
+ return $response;
377
+ }
378
+
379
+ /**
380
+ * Check if a given request has access to create a friendship.
381
+ *
382
+ * @since 6.0.0
383
+ *
384
+ * @param WP_REST_Request $request Full details about the request.
385
+ * @return WP_Error|bool
386
+ */
387
+ public function create_item_permissions_check( $request ) {
388
+ $retval = $this->get_item_permissions_check( $request );
389
+
390
+ /**
391
+ * Filter the friends `create_item` permissions check.
392
+ *
393
+ * @since 6.0.0
394
+ *
395
+ * @param bool|WP_Error $retval Returned value.
396
+ * @param WP_REST_Request $request The request sent to the API.
397
+ */
398
+ return apply_filters( 'bp_rest_friends_create_item_permissions_check', $retval, $request );
399
+ }
400
+
401
+ /**
402
+ * Update, accept, friendship.
403
+ *
404
+ * @since 6.0.0
405
+ *
406
+ * @param WP_REST_Request $request Full details about the request.
407
+ * @return WP_REST_Response|WP_Error
408
+ */
409
+ public function update_item( $request ) {
410
+ $user = get_user_by( 'id', $request->get_param( 'id' ) );
411
+
412
+ // Check if user is valid.
413
+ if ( false === $user ) {
414
+ return new WP_Error(
415
+ 'bp_rest_friends_update_item_failed',
416
+ __( 'There was a problem confirming if user is valid.', 'buddypress' ),
417
+ array(
418
+ 'status' => 500,
419
+ )
420
+ );
421
+ }
422
+
423
+ // Get friendship.
424
+ $friendship = $this->get_friendship_object(
425
+ BP_Friends_Friendship::get_friendship_id( bp_loggedin_user_id(), $user->ID )
426
+ );
427
+
428
+ if ( ! $friendship || empty( $friendship->id ) ) {
429
+ return new WP_Error(
430
+ 'bp_rest_invalid_id',
431
+ __( 'Invalid friendship ID.', 'buddypress' ),
432
+ array(
433
+ 'status' => 404,
434
+ )
435
+ );
436
+ }
437
+
438
+ // Accept friendship.
439
+ if ( false === friends_accept_friendship( $friendship->id ) ) {
440
+ return new WP_Error(
441
+ 'bp_rest_friends_cannot_update_item',
442
+ __( 'Could not accept friendship.', 'buddypress' ),
443
+ array(
444
+ 'status' => 500,
445
+ )
446
+ );
447
+ }
448
+
449
+ // Getting new, updated, friendship object.
450
+ $friendship = $this->get_friendship_object( $friendship->id );
451
+
452
+ $retval = array(
453
+ $this->prepare_response_for_collection(
454
+ $this->prepare_item_for_response( $friendship, $request )
455
+ ),
456
+ );
457
+
458
+ $response = rest_ensure_response( $retval );
459
+
460
+ /**
461
+ * Fires after a friendship is updated via the REST API.
462
+ *
463
+ * @since 6.0.0
464
+ *
465
+ * @param BP_Friends_Friendship $friendship Friendship object.
466
+ * @param WP_REST_Response $response The response data.
467
+ * @param WP_REST_Request $request The request sent to the API.
468
+ */
469
+ do_action( 'bp_rest_friends_update_item', $friendship, $response, $request );
470
+
471
+ return $response;
472
+ }
473
+
474
+ /**
475
+ * Check if a given request has access to update a friendship.
476
+ *
477
+ * @since 6.0.0
478
+ *
479
+ * @param WP_REST_Request $request Full details about the request.
480
+ * @return WP_Error|bool
481
+ */
482
+ public function update_item_permissions_check( $request ) {
483
+ $retval = $this->get_item_permissions_check( $request );
484
+
485
+ /**
486
+ * Filter the friendship `update_item` permissions check.
487
+ *
488
+ * @since 6.0.0
489
+ *
490
+ * @param bool|WP_Error $retval Returned value.
491
+ * @param WP_REST_Request $request The request sent to the API.
492
+ */
493
+ return apply_filters( 'bp_rest_friends_update_item_permissions_check', $retval, $request );
494
+ }
495
+
496
+ /**
497
+ * Reject/withdraw/remove friendship.
498
+ *
499
+ * @since 6.0.0
500
+ *
501
+ * @param WP_REST_Request $request Full details about the request.
502
+ * @return WP_REST_Response|WP_Error
503
+ */
504
+ public function delete_item( $request ) {
505
+ $user = get_user_by( 'id', $request->get_param( 'id' ) );
506
+
507
+ // Check if user is valid.
508
+ if ( false === $user ) {
509
+ return new WP_Error(
510
+ 'bp_rest_friends_delete_item_failed',
511
+ __( 'There was a problem confirming if user is valid.', 'buddypress' ),
512
+ array(
513
+ 'status' => 500,
514
+ )
515
+ );
516
+ }
517
+
518
+ // Get friendship.
519
+ $friendship = $this->get_friendship_object(
520
+ BP_Friends_Friendship::get_friendship_id( bp_loggedin_user_id(), $user->ID )
521
+ );
522
+
523
+ if ( ! $friendship || empty( $friendship->id ) ) {
524
+ return new WP_Error(
525
+ 'bp_rest_invalid_id',
526
+ __( 'Invalid friendship ID.', 'buddypress' ),
527
+ array(
528
+ 'status' => 404,
529
+ )
530
+ );
531
+ }
532
+
533
+ $previous = $this->prepare_item_for_response( $friendship, $request );
534
+
535
+ // Remove a friendship.
536
+ if ( true === $request->get_param( 'force' ) ) {
537
+ $deleted = friends_remove_friend( $friendship->initiator_user_id, $friendship->friend_user_id );
538
+ } else {
539
+
540
+ /**
541
+ * If this change is being initiated by the initiator,
542
+ * use the `reject` function.
543
+ *
544
+ * This is the user who requested the friendship, and is doing the withdrawing.
545
+ */
546
+ if ( bp_loggedin_user_id() === $friendship->initiator_user_id ) {
547
+ $deleted = friends_withdraw_friendship( $friendship->initiator_user_id, $friendship->friend_user_id );
548
+ } else {
549
+ /**
550
+ * Otherwise, this change is being initiated by the user, friend,
551
+ * who received the friendship reject.
552
+ */
553
+ $deleted = friends_reject_friendship( $friendship->id );
554
+ }
555
+ }
556
+
557
+ if ( false === $deleted ) {
558
+ return new WP_Error(
559
+ 'bp_rest_friends_cannot_delete_item',
560
+ __( 'Could not delete friendship.', 'buddypress' ),
561
+ array(
562
+ 'status' => 500,
563
+ )
564
+ );
565
+ }
566
+
567
+ // Build the response.
568
+ $response = new WP_REST_Response();
569
+ $response->set_data(
570
+ array(
571
+ 'deleted' => true,
572
+ 'previous' => $previous->get_data(),
573
+ )
574
+ );
575
+
576
+ /**
577
+ * Fires after a friendship is deleted via the REST API.
578
+ *
579
+ * @since 6.0.0
580
+ *
581
+ * @param BP_Friends_Friendship $friendship Friendship object.
582
+ * @param WP_REST_Response $response The response data.
583
+ * @param WP_REST_Request $request The request sent to the API.
584
+ */
585
+ do_action( 'bp_rest_friends_delete_item', $friendship, $response, $request );
586
+
587
+ return $response;
588
+ }
589
+
590
+ /**
591
+ * Check if a given request has access to delete a friendship.
592
+ *
593
+ * @since 6.0.0
594
+ *
595
+ * @param WP_REST_Request $request Full details about the request.
596
+ * @return WP_Error|bool
597
+ */
598
+ public function delete_item_permissions_check( $request ) {
599
+ $retval = $this->get_item_permissions_check( $request );
600
+
601
+ /**
602
+ * Filter the friendship `delete_item` permissions check.
603
+ *
604
+ * @since 6.0.0
605
+ *
606
+ * @param bool|WP_Error $retval Returned value.
607
+ * @param WP_REST_Request $request The request sent to the API.
608
+ */
609
+ return apply_filters( 'bp_rest_friends_delete_item_permissions_check', $retval, $request );
610
+ }
611
+
612
+ /**
613
+ * Prepares friendship data to return as an object.
614
+ *
615
+ * @since 6.0.0
616
+ *
617
+ * @param BP_Friends_Friendship $friendship Friendship object.
618
+ * @param WP_REST_Request $request Full details about the request.
619
+ * @return WP_REST_Response
620
+ */
621
+ public function prepare_item_for_response( $friendship, $request ) {
622
+ $data = array(
623
+ 'id' => $friendship->id,
624
+ 'initiator_id' => $friendship->initiator_user_id,
625
+ 'friend_id' => $friendship->friend_user_id,
626
+ 'is_confirmed' => (bool) $friendship->is_confirmed,
627
+ 'date_created' => bp_rest_prepare_date_response( $friendship->date_created ),
628
+ );
629
+
630
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
631
+ $data = $this->add_additional_fields_to_object( $data, $request );
632
+ $data = $this->filter_response_by_context( $data, $context );
633
+ $response = rest_ensure_response( $data );
634
+
635
+ // Add prepare links.
636
+ $response->add_links( $this->prepare_links( $friendship ) );
637
+
638
+ /**
639
+ * Filter a friendship value returned from the API.
640
+ *
641
+ * @since 6.0.0
642
+ *
643
+ * @param WP_REST_Response $response Response generated by the request.
644
+ * @param WP_REST_Request $request Request used to generate the response.
645
+ * @param BP_Friends_Friendship $friendship The friendship object.
646
+ */
647
+ return apply_filters( 'bp_rest_friends_prepare_value', $response, $request, $friendship );
648
+ }
649
+
650
+ /**
651
+ * Prepare links for the request.
652
+ *
653
+ * @since 6.0.0
654
+ *
655
+ * @param BP_Friends_Friendship $friendship Friendship item.
656
+ * @return array Links for the given plugin.
657
+ */
658
+ protected function prepare_links( $friendship ) {
659
+ $base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );
660
+
661
+ // Entity meta.
662
+ $links = array(
663
+ 'self' => array(
664
+ 'href' => rest_url( $base . $friendship->id ),
665
+ ),
666
+ 'collection' => array(
667
+ 'href' => rest_url( $base ),
668
+ ),
669
+ 'initiator' => array(
670
+ 'href' => rest_url( bp_rest_get_user_url( $friendship->initiator_user_id ) ),
671
+ 'embeddable' => true,
672
+ ),
673
+ 'friend' => array(
674
+ 'href' => rest_url( bp_rest_get_user_url( $friendship->friend_user_id ) ),
675
+ 'embeddable' => true,
676
+ ),
677
+ );
678
+
679
+ /**
680
+ * Filter links prepared for the REST response.
681
+ *
682
+ * @since 5.0.0
683
+ *
684
+ * @param array $links The prepared links of the REST response.
685
+ * @param BP_Friends_Friendship $friendship Friendship object.
686
+ */
687
+ return apply_filters( 'bp_rest_friends_prepare_links', $links, $friendship );
688
+ }
689
+
690
+ /**
691
+ * Get friendship object.
692
+ *
693
+ * @since 6.0.0
694
+ *
695
+ * @param int $friendship_id Friendship ID.
696
+ * @return BP_Friends_Friendship
697
+ */
698
+ public function get_friendship_object( $friendship_id ) {
699
+ return new BP_Friends_Friendship( $friendship_id );
700
+ }
701
+
702
+ /**
703
+ * Edit some arguments for the endpoint's methods.
704
+ *
705
+ * @since 6.0.0
706
+ *
707
+ * @param string $method Optional. HTTP method of the request.
708
+ * @return array Endpoint arguments.
709
+ */
710
+ public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {
711
+ $args = WP_REST_Controller::get_endpoint_args_for_item_schema( $method );
712
+ $context = 'view';
713
+
714
+ $args['id']['required'] = true;
715
+ $args['id']['description'] = __( 'A unique numeric ID of a user.', 'buddypress' );
716
+
717
+ if ( WP_REST_Server::EDITABLE === $method ) {
718
+ $key = 'update_item';
719
+
720
+ unset( $args['initiator_id'] );
721
+ unset( $args['friend_id'] );
722
+ } elseif ( WP_REST_Server::CREATABLE === $method ) {
723
+ $key = 'create_item';
724
+
725
+ // Remove the ID for POST requests since it is not available.
726
+ unset( $args['id'] );
727
+
728
+ // Those fields are required.
729
+ $args['initiator_id']['required'] = true;
730
+ $args['friend_id']['required'] = true;
731
+
732
+ // This one is optional.
733
+ $args['force'] = array(
734
+ 'description' => __( 'Whether to force friendship acceptance.', 'buddypress' ),
735
+ 'default' => false,
736
+ 'type' => 'boolean',
737
+ 'sanitize_callback' => 'rest_sanitize_boolean',
738
+ 'validate_callback' => 'rest_validate_request_arg',
739
+ );
740
+
741
+ } elseif ( WP_REST_Server::DELETABLE === $method ) {
742
+ $key = 'delete_item';
743
+
744
+ // This one is optional.
745
+ $args['force'] = array(
746
+ 'description' => __( 'Whether to force friendship removal.', 'buddypress' ),
747
+ 'default' => false,
748
+ 'type' => 'boolean',
749
+ 'sanitize_callback' => 'rest_sanitize_boolean',
750
+ 'validate_callback' => 'rest_validate_request_arg',
751
+ );
752
+
753
+ unset( $args['initiator_id'] );
754
+ unset( $args['friend_id'] );
755
+ } elseif ( WP_REST_Server::READABLE === $method ) {
756
+ $key = 'get_item';
757
+
758
+ $args['id']['required'] = true;
759
+
760
+ // Removing those args from the GET request.
761
+ unset( $args['initiator_id'] );
762
+ unset( $args['friend_id'] );
763
+ }
764
+
765
+ if ( 'get_item' !== $key ) {
766
+ $context = 'edit';
767
+ }
768
+
769
+ $args = array_merge(
770
+ array(
771
+ 'context' => $this->get_context_param(
772
+ array(
773
+ 'default' => $context,
774
+ )
775
+ ),
776
+ ),
777
+ $args
778
+ );
779
+
780
+ /**
781
+ * Filters the method query arguments.
782
+ *
783
+ * @since 6.0.0
784
+ *
785
+ * @param array $args Query arguments.
786
+ * @param string $method HTTP method of the request.
787
+ */
788
+ return apply_filters( "bp_rest_friends_{$key}_query_arguments", $args, $method );
789
+ }
790
+
791
+ /**
792
+ * Get the friends schema, conforming to JSON Schema.
793
+ *
794
+ * @since 6.0.0
795
+ *
796
+ * @return array
797
+ */
798
+ public function get_item_schema() {
799
+ $schema = array(
800
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
801
+ 'title' => 'bp_friends',
802
+ 'type' => 'object',
803
+ 'properties' => array(
804
+ 'id' => array(
805
+ 'context' => array( 'view', 'edit' ),
806
+ 'description' => __( 'A unique numeric ID for the friendship.', 'buddypress' ),
807
+ 'type' => 'integer',
808
+ ),
809
+ 'initiator_id' => array(
810
+ 'context' => array( 'view', 'edit' ),
811
+ 'description' => __( 'User ID of the friendship initiator.', 'buddypress' ),
812
+ 'type' => 'integer',
813
+ ),
814
+ 'friend_id' => array(
815
+ 'context' => array( 'view', 'edit' ),
816
+ 'description' => __( 'User ID of the `friend` - the one invited to the friendship.', 'buddypress' ),
817
+ 'type' => 'integer',
818
+ ),
819
+ 'is_confirmed' => array(
820
+ 'context' => array( 'view', 'edit' ),
821
+ 'description' => __( 'Whether the friendship been confirmed/accepted.', 'buddypress' ),
822
+ 'readonly' => true,
823
+ 'type' => 'boolean',
824
+ ),
825
+ 'date_created' => array(
826
+ 'context' => array( 'view', 'edit' ),
827
+ 'description' => __( "The date the friendship was created, in the site's timezone.", 'buddypress' ),
828
+ 'readonly' => true,
829
+ 'type' => 'string',
830
+ 'format' => 'date-time',
831
+ ),
832
+ ),
833
+ );
834
+
835
+ /**
836
+ * Filters the friends schema.
837
+ *
838
+ * @since 6.0.0
839
+ *
840
+ * @param array $schema The endpoint schema.
841
+ */
842
+ return apply_filters( 'bp_rest_friends_schema', $this->add_additional_fields_schema( $schema ) );
843
+ }
844
+
845
+ /**
846
+ * Get the query params for friends collections.
847
+ *
848
+ * @since 6.0.0
849
+ *
850
+ * @return array
851
+ */
852
+ public function get_collection_params() {
853
+ $params = parent::get_collection_params();
854
+ $params['context']['default'] = 'view';
855
+
856
+ unset( $params['search'] );
857
+
858
+ $params['user_id'] = array(
859
+ 'description' => __( 'ID of the user whose friends are being retrieved.', 'buddypress' ),
860
+ 'default' => bp_loggedin_user_id(),
861
+ 'type' => 'integer',
862
+ 'required' => true,
863
+ 'sanitize_callback' => 'absint',
864
+ 'validate_callback' => 'rest_validate_request_arg',
865
+ );
866
+
867
+ $params['is_confirmed'] = array(
868
+ 'description' => __( 'Wether the friendship has been accepted.', 'buddypress' ),
869
+ 'default' => 0,
870
+ 'type' => 'integer',
871
+ 'sanitize_callback' => 'absint',
872
+ 'validate_callback' => 'rest_validate_request_arg',
873
+ );
874
+
875
+ $params['id'] = array(
876
+ 'description' => __( 'ID of a specific friendship to retrieve.', 'buddypress' ),
877
+ 'default' => 0,
878
+ 'type' => 'integer',
879
+ 'sanitize_callback' => 'absint',
880
+ 'validate_callback' => 'rest_validate_request_arg',
881
+ );
882
+
883
+ $params['initiator_id'] = array(
884
+ 'description' => __( 'ID of the friendship initiator.', 'buddypress' ),
885
+ 'default' => 0,
886
+ 'type' => 'integer',
887
+ 'sanitize_callback' => 'absint',
888
+ 'validate_callback' => 'rest_validate_request_arg',
889
+ );
890
+
891
+ $params['friend_id'] = array(
892
+ 'description' => __( 'ID of a specific friendship to retrieve.', 'buddypress' ),
893
+ 'default' => 0,
894
+ 'type' => 'integer',
895
+ 'sanitize_callback' => 'absint',
896
+ 'validate_callback' => 'rest_validate_request_arg',
897
+ );
898
+
899
+ $params['order_by'] = array(
900
+ 'description' => __( 'Column name to order the results by.', 'buddypress' ),
901
+ 'default' => 'date_created',
902
+ 'type' => 'string',
903
+ 'enum' => array( 'date_created', 'initiator_user_id', 'friend_user_id', 'id' ),
904
+ 'sanitize_callback' => 'sanitize_key',
905
+ 'validate_callback' => 'rest_validate_request_arg',
906
+ );
907
+
908
+ $params['order'] = array(
909
+ 'description' => __( 'Order results ascending or descending.', 'buddypress' ),
910
+ 'default' => 'desc',
911
+ 'type' => 'string',
912
+ 'enum' => array( 'asc', 'desc' ),
913
+ 'sanitize_callback' => 'sanitize_key',
914
+ 'validate_callback' => 'rest_validate_request_arg',
915
+ );
916
+
917
+ /**
918
+ * Filters the collection query params.
919
+ *
920
+ * @param array $params Query params.
921
+ */
922
+ return apply_filters( 'bp_rest_friends_collection_params', $params );
923
+ }
924
+ }
bp-groups/actions/feed.php CHANGED
@@ -32,11 +32,14 @@ function groups_action_group_feed() {
32
  buddypress()->activity->feed = new BP_Activity_Feed( array(
33
  'id' => 'group',
34
 
35
- /* translators: Group activity RSS title - "[Site Name] | [Group Name] | Activity" */
36
- 'title' => sprintf( __( '%1$s | %2$s | Activity', 'buddypress' ), bp_get_site_name(), bp_get_current_group_name() ),
37
 
38
  'link' => bp_get_group_permalink( $group ),
 
 
39
  'description' => sprintf( __( "Activity feed for the group, %s.", 'buddypress' ), bp_get_current_group_name() ),
 
40
  'activity_args' => array(
41
  'object' => buddypress()->groups->id,
42
  'primary_id' => bp_get_current_group_id(),
@@ -44,4 +47,4 @@ function groups_action_group_feed() {
44
  )
45
  ) );
46
  }
47
- add_action( 'bp_actions', 'groups_action_group_feed' );
32
  buddypress()->activity->feed = new BP_Activity_Feed( array(
33
  'id' => 'group',
34
 
35
+ /* translators: 1: Site Name. 2:Group Name. */
36
+ 'title' => sprintf( _x( '%1$s | %2$s | Activity', 'Group activity RSS title', 'buddypress' ), bp_get_site_name(), bp_get_current_group_name() ),
37
 
38
  'link' => bp_get_group_permalink( $group ),
39
+
40
+ /* translators: %s: Group Name. */
41
  'description' => sprintf( __( "Activity feed for the group, %s.", 'buddypress' ), bp_get_current_group_name() ),
42
+
43
  'activity_args' => array(
44
  'object' => buddypress()->groups->id,
45
  'primary_id' => bp_get_current_group_id(),
47
  )
48
  ) );
49
  }
50
+ add_action( 'bp_actions', 'groups_action_group_feed' );
bp-groups/bp-groups-activity.php CHANGED
@@ -108,6 +108,7 @@ function bp_groups_format_activity_action_created_group( $action, $activity ) {
108
  $group = bp_groups_get_activity_group( $activity->item_id );
109
  $group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
110
 
 
111
  $action = sprintf( esc_html__( '%1$s created the group %2$s', 'buddypress'), $user_link, $group_link );
112
 
113
  /**
@@ -136,6 +137,7 @@ function bp_groups_format_activity_action_joined_group( $action, $activity ) {
136
  $group = bp_groups_get_activity_group( $activity->item_id );
137
  $group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
138
 
 
139
  $action = sprintf( esc_html__( '%1$s joined the group %2$s', 'buddypress' ), $user_link, $group_link );
140
 
141
  // Legacy filters (do not follow parameter patterns of other activity
@@ -183,23 +185,27 @@ function bp_groups_format_activity_action_group_details_updated( $action, $activ
183
 
184
  // No changed details were found, so use a generic message.
185
  if ( empty( $changed ) ) {
 
186
  $action = sprintf( esc_html__( '%1$s updated details for the group %2$s', 'buddypress' ), $user_link, $group_link );
187
 
188
  // Name and description changed - to keep things short, don't describe changes in detail.
189
  } elseif ( isset( $changed['name'] ) && isset( $changed['description'] ) ) {
 
190
  $action = sprintf( esc_html__( '%1$s changed the name and description of the group %2$s', 'buddypress' ), $user_link, $group_link );
191
 
192
  // Name only.
193
  } elseif ( ! empty( $changed['name']['old'] ) && ! empty( $changed['name']['new'] ) ) {
 
194
  $action = sprintf( esc_html__( '%1$s changed the name of the group %2$s from "%3$s" to "%4$s"', 'buddypress' ), $user_link, $group_link, esc_html( $changed['name']['old'] ), esc_html( $changed['name']['new'] ) );
195
 
196
  // Description only.
197
  } elseif ( ! empty( $changed['description']['old'] ) && ! empty( $changed['description']['new'] ) ) {
 
198
  $action = sprintf( esc_html__( '%1$s changed the description of the group %2$s from "%3$s" to "%4$s"', 'buddypress' ), $user_link, $group_link, esc_html( $changed['description']['old'] ), esc_html( $changed['description']['new'] ) );
199
 
200
  } elseif ( ! empty( $changed['slug']['old'] ) && ! empty( $changed['slug']['new'] ) ) {
 
201
  $action = sprintf( esc_html__( '%1$s changed the permalink of the group %2$s.', 'buddypress' ), $user_link, $group_link );
202
-
203
  }
204
 
205
  /**
@@ -229,7 +235,12 @@ function bp_groups_format_activity_action_group_activity_update( $action, $activ
229
  $group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
230
 
231
  // Set the Activity update posted in a Group action.
232
- $action = sprintf( esc_html__( '%1$s posted an update in the group %2$s', 'buddypress' ), $user_link, $group_link );
 
 
 
 
 
233
 
234
  /** This filter is documented in wp-includes/deprecated.php */
235
  $action = apply_filters_deprecated( 'groups_activity_new_update_action', array( $action ), '5.0.0', 'bp_groups_format_activity_action_group_activity_update' );
108
  $group = bp_groups_get_activity_group( $activity->item_id );
109
  $group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
110
 
111
+ /* translators: 1: the user link. 2: the group link. */
112
  $action = sprintf( esc_html__( '%1$s created the group %2$s', 'buddypress'), $user_link, $group_link );
113
 
114
  /**
137
  $group = bp_groups_get_activity_group( $activity->item_id );
138
  $group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
139
 
140
+ /* translators: 1: the user link. 2: the group link. */
141
  $action = sprintf( esc_html__( '%1$s joined the group %2$s', 'buddypress' ), $user_link, $group_link );
142
 
143
  // Legacy filters (do not follow parameter patterns of other activity
185
 
186
  // No changed details were found, so use a generic message.
187
  if ( empty( $changed ) ) {
188
+ /* translators: 1: the user link. 2: the group link. */
189
  $action = sprintf( esc_html__( '%1$s updated details for the group %2$s', 'buddypress' ), $user_link, $group_link );
190
 
191
  // Name and description changed - to keep things short, don't describe changes in detail.
192
  } elseif ( isset( $changed['name'] ) && isset( $changed['description'] ) ) {
193
+ /* translators: 1: the user link. 2: the group link. */
194
  $action = sprintf( esc_html__( '%1$s changed the name and description of the group %2$s', 'buddypress' ), $user_link, $group_link );
195
 
196
  // Name only.
197
  } elseif ( ! empty( $changed['name']['old'] ) && ! empty( $changed['name']['new'] ) ) {
198
+ /* translators: 1: the user link. 2: the group link. 3: the old group name. 4: the new group name. */
199
  $action = sprintf( esc_html__( '%1$s changed the name of the group %2$s from "%3$s" to "%4$s"', 'buddypress' ), $user_link, $group_link, esc_html( $changed['name']['old'] ), esc_html( $changed['name']['new'] ) );
200
 
201
  // Description only.
202
  } elseif ( ! empty( $changed['description']['old'] ) && ! empty( $changed['description']['new'] ) ) {
203
+ /* translators: 1: the user link. 2: the group link. 3: the old group description. 4: the new group description. */
204
  $action = sprintf( esc_html__( '%1$s changed the description of the group %2$s from "%3$s" to "%4$s"', 'buddypress' ), $user_link, $group_link, esc_html( $changed['description']['old'] ), esc_html( $changed['description']['new'] ) );
205
 
206
  } elseif ( ! empty( $changed['slug']['old'] ) && ! empty( $changed['slug']['new'] ) ) {
207
+ /* translators: 1: the user link. 2: the group link. */
208
  $action = sprintf( esc_html__( '%1$s changed the permalink of the group %2$s.', 'buddypress' ), $user_link, $group_link );
 
209
  }
210
 
211
  /**
235
  $group_link = '<a href="' . esc_url( bp_get_group_permalink( $group ) ) . '">' . esc_html( $group->name ) . '</a>';
236
 
237
  // Set the Activity update posted in a Group action.
238
+ $action = sprintf(
239
+ /* translators: 1: the user link. 2: the group link. */
240
+ esc_html__( '%1$s posted an update in the group %2$s', 'buddypress' ),
241
+ $user_link,
242
+ $group_link
243
+ );
244
 
245
  /** This filter is documented in wp-includes/deprecated.php */
246
  $action = apply_filters_deprecated( 'groups_activity_new_update_action', array( $action ), '5.0.0', 'bp_groups_format_activity_action_group_activity_update' );
bp-groups/bp-groups-admin.php CHANGED
@@ -537,20 +537,24 @@ function bp_groups_admin_edit() {
537
  }
538
 
539
  if ( ! empty( $error_new ) ) {
 
540
  $messages[] = sprintf( __( 'The following users could not be added to the group: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $error_new ) ) . '</em>' );
541
  }
542
 
543
  if ( ! empty( $success_new ) ) {
 
544
  $messages[] = sprintf( __( 'The following users were successfully added to the group: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $success_new ) ) . '</em>' );
545
  }
546
 
547
  if ( ! empty( $error_modified ) ) {
548
  $error_modified = bp_groups_admin_get_usernames_from_ids( $error_modified );
 
549
  $messages[] = sprintf( __( 'An error occurred when trying to modify the following members: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $error_modified ) ) . '</em>' );
550
  }
551
 
552
  if ( ! empty( $success_modified ) ) {
553
  $success_modified = bp_groups_admin_get_usernames_from_ids( $success_modified );
 
554
  $messages[] = sprintf( __( 'The following members were successfully modified: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $success_modified ) ) . '</em>' );
555
  }
556
  }
@@ -558,7 +562,7 @@ function bp_groups_admin_edit() {
558
  $is_error = ! empty( $no_admins ) || ! empty( $errors ) || ! empty( $error_new ) || ! empty( $error_modified );
559
 
560
  // Get the group from the database.
561
- $group = groups_get_group( (int) $_GET['gid'] );
562
 
563
  $group_name = isset( $group->name ) ? bp_get_group_name( $group ) : '';
564
 
@@ -745,6 +749,7 @@ function bp_groups_admin_index() {
745
  $deleted = ! empty( $_REQUEST['deleted'] ) ? (int) $_REQUEST['deleted'] : 0;
746
 
747
  if ( $deleted > 0 ) {
 
748
  $messages[] = sprintf( _n( '%s group has been permanently deleted.', '%s groups have been permanently deleted.', $deleted, 'buddypress' ), number_format_i18n( $deleted ) );
749
  }
750
  }
@@ -1229,6 +1234,7 @@ function bp_groups_admin_create_pagination_links( BP_Group_Member_Query $query,
1229
  $viewing_text = __( 'Viewing 1 member', 'buddypress' );
1230
  } else {
1231
  $viewing_text = sprintf(
 
1232
  _nx( 'Viewing %1$s - %2$s of %3$s member', 'Viewing %1$s - %2$s of %3$s members', $query->total_users, 'Group members pagination in group admin', 'buddypress' ),
1233
  bp_core_number_format( $current_page_start ),
1234
  bp_core_number_format( $current_page_end ),
537
  }
538
 
539
  if ( ! empty( $error_new ) ) {
540
+ /* translators: %s: comma separated list of usernames */
541
  $messages[] = sprintf( __( 'The following users could not be added to the group: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $error_new ) ) . '</em>' );
542
  }
543
 
544
  if ( ! empty( $success_new ) ) {
545
+ /* translators: %s: comma separated list of usernames */
546
  $messages[] = sprintf( __( 'The following users were successfully added to the group: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $success_new ) ) . '</em>' );
547
  }
548
 
549
  if ( ! empty( $error_modified ) ) {
550
  $error_modified = bp_groups_admin_get_usernames_from_ids( $error_modified );
551
+ /* translators: %s: comma separated list of usernames */
552
  $messages[] = sprintf( __( 'An error occurred when trying to modify the following members: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $error_modified ) ) . '</em>' );
553
  }
554
 
555
  if ( ! empty( $success_modified ) ) {
556
  $success_modified = bp_groups_admin_get_usernames_from_ids( $success_modified );
557
+ /* translators: %s: comma separated list of usernames */
558
  $messages[] = sprintf( __( 'The following members were successfully modified: %s', 'buddypress' ), '<em>' . esc_html( implode( ', ', $success_modified ) ) . '</em>' );
559
  }
560
  }
562
  $is_error = ! empty( $no_admins ) || ! empty( $errors ) || ! empty( $error_new ) || ! empty( $error_modified );
563
 
564
  // Get the group from the database.
565
+ $group = groups_get_group( (int) $_GET['gid'] );
566
 
567
  $group_name = isset( $group->name ) ? bp_get_group_name( $group ) : '';
568
 
749
  $deleted = ! empty( $_REQUEST['deleted'] ) ? (int) $_REQUEST['deleted'] : 0;
750
 
751
  if ( $deleted > 0 ) {
752
+ /* translators: %s: number of deleted groups */
753
  $messages[] = sprintf( _n( '%s group has been permanently deleted.', '%s groups have been permanently deleted.', $deleted, 'buddypress' ), number_format_i18n( $deleted ) );
754
  }
755
  }
1234
  $viewing_text = __( 'Viewing 1 member', 'buddypress' );
1235
  } else {
1236
  $viewing_text = sprintf(
1237
+ /* translators: 1: group member from number. 2: group member to number. 3: total group members. */
1238
  _nx( 'Viewing %1$s - %2$s of %3$s member', 'Viewing %1$s - %2$s of %3$s members', $query->total_users, 'Group members pagination in group admin', 'buddypress' ),
1239
  bp_core_number_format( $current_page_start ),
1240
  bp_core_number_format( $current_page_end ),
bp-groups/bp-groups-adminbar.php CHANGED
@@ -40,7 +40,7 @@ function bp_groups_group_admin_menu() {
40
  $bp->group_admin_menu_id = 'group-admin';
41
 
42
  // Add the top-level Group Admin button.
43
- $wp_admin_bar->add_menu( array(
44
  'id' => $bp->group_admin_menu_id,
45
  'title' => __( 'Edit Group', 'buddypress' ),
46
  'href' => bp_get_group_permalink( $bp->groups->current_group )
@@ -64,14 +64,16 @@ function bp_groups_group_admin_menu() {
64
  * the 'show_in_admin_bar' argument of your edit screen to true
65
  */
66
  if ( $menu->show_in_admin_bar ) {
 
67
  $title = sprintf( _x( 'Edit Group %s', 'Group WP Admin Bar manage links', 'buddypress' ), $menu->name );
68
 
69
  // Title is specific for delete.
70
  if ( 'delete-group' == $menu->slug ) {
 
71
  $title = sprintf( _x( '%s Group', 'Group WP Admin Bar delete link', 'buddypress' ), $menu->name );
72
  }
73
 
74
- $wp_admin_bar->add_menu( array(
75
  'parent' => $bp->group_admin_menu_id,
76
  'id' => $menu->slug,
77
  'title' => $title,
40
  $bp->group_admin_menu_id = 'group-admin';
41
 
42
  // Add the top-level Group Admin button.
43
+ $wp_admin_bar->add_node( array(
44
  'id' => $bp->group_admin_menu_id,
45
  'title' => __( 'Edit Group', 'buddypress' ),
46
  'href' => bp_get_group_permalink( $bp->groups->current_group )
64
  * the 'show_in_admin_bar' argument of your edit screen to true
65
  */
66
  if ( $menu->show_in_admin_bar ) {
67
+ /* translators: %s the group menu name */
68
  $title = sprintf( _x( 'Edit Group %s', 'Group WP Admin Bar manage links', 'buddypress' ), $menu->name );
69
 
70
  // Title is specific for delete.
71
  if ( 'delete-group' == $menu->slug ) {
72
+ /* translators: %s the group menu name */
73
  $title = sprintf( _x( '%s Group', 'Group WP Admin Bar delete link', 'buddypress' ), $menu->name );
74
  }
75
 
76
+ $wp_admin_bar->add_node( array(
77
  'parent' => $bp->group_admin_menu_id,
78
  'id' => $menu->slug,
79
  'title' => $title,
bp-groups/bp-groups-blocks.php ADDED
@@ -0,0 +1,203 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP Groups Blocks Functions.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage GroupsBlocks
7
+ * @since 6.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Add BP Groups blocks specific settings to the BP Blocks Editor ones.
17
+ *
18
+ * @since 6.0.0
19
+ *
20
+ * @param array $bp_editor_settings BP blocks editor settings.
21
+ * @return array BP Groups blocks editor settings.
22
+ */
23
+ function bp_groups_editor_settings( $bp_editor_settings = array() ) {
24
+ $bp = buddypress();
25
+
26
+ return array_merge(
27
+ $bp_editor_settings,
28
+ array(
29
+ 'groups' => array(
30
+ 'isAvatarEnabled' => $bp->avatar && $bp->avatar->show_avatars && ! bp_disable_group_avatar_uploads(),
31
+ 'isCoverImageEnabled' => bp_is_active( 'groups', 'cover_image' ),
32
+ ),
33
+ )
34
+ );
35
+ }
36
+ add_filter( 'bp_blocks_editor_settings', 'bp_groups_editor_settings' );
37
+
38
+ /**
39
+ * Callback function to render the BP Group Block.
40
+ *
41
+ * @since 6.0.0
42
+ *
43
+ * @param array $attributes The block attributes.
44
+ * @return string HTML output.
45
+ */
46
+ function bp_groups_render_group_block( $attributes = array() ) {
47
+ $bp = buddypress();
48
+
49
+ $block_args = wp_parse_args(
50
+ $attributes,
51
+ array(
52
+ 'itemID' => 0,
53
+ 'avatarSize' => 'full',
54
+ 'displayDescription' => true,
55
+ 'displayActionButton' => true,
56
+ 'displayCoverImage' => true,
57
+ )
58
+ );
59
+
60
+ if ( ! $block_args['itemID'] ) {
61
+ return;
62
+ }
63
+
64
+ // Set the group ID and container classes.
65
+ $group_id = (int) $block_args['itemID'];
66
+ $container_classes = array( 'bp-block-group' );
67
+
68
+ // Group object.
69
+ $group = groups_get_group( $group_id );
70
+
71
+ if ( ! $group->id ) {
72
+ return;
73
+ }
74
+
75
+ // Avatar variables.
76
+ $avatar = '';
77
+ $avatar_container = '';
78
+
79
+ // Cover image variable.
80
+ $cover_image = '';
81
+ $cover_style = '';
82
+ $cover_container = '';
83
+
84
+ // Group name/link/description variables.
85
+ $group_name = bp_get_group_name( $group );
86
+ $group_link = bp_get_group_permalink( $group );
87
+ $group_description = '';
88
+ $group_content = '';
89
+
90
+ // Group action button.
91
+ $action_button = '';
92
+ $display_action_button = (bool) $block_args['displayActionButton'];
93
+
94
+ if ( $bp->avatar && $bp->avatar->show_avatars && ! bp_disable_group_avatar_uploads() && in_array( $block_args['avatarSize'], array( 'thumb', 'full' ), true ) ) {
95
+ $avatar = bp_core_fetch_avatar(
96
+ array(
97
+ 'item_id' => $group->id,
98
+ 'object' => 'group',
99
+ 'type' => $block_args['avatarSize'],
100
+ 'html' => false,
101
+ )
102
+ );
103
+
104
+ $container_classes[] = 'avatar-' . $block_args['avatarSize'];
105
+ } else {
106
+ $container_classes[] = 'avatar-none';
107
+ }
108
+
109
+ if ( $avatar ) {
110
+ $avatar_container = sprintf(
111
+ '<div class="item-header-avatar">
112
+ <a href="%1$s">
113
+ <img src="%2$s" alt="%3$s" class="avatar">
114
+ </a>
115
+ </div>',
116
+ esc_url( $group_link ),
117
+ esc_url( $avatar ),
118
+ // Translators: %s is the group's name.
119
+ sprintf( esc_html__( 'Group Profile photo of %s', 'buddypress' ), $group_name )
120
+ );
121
+ }
122
+
123
+ $display_cover_image = (bool) $block_args['displayCoverImage'];
124
+ if ( bp_is_active( 'groups', 'cover_image' ) && $display_cover_image ) {
125
+ $cover_image = bp_attachments_get_attachment(
126
+ 'url',
127
+ array(
128
+ 'item_id' => $group->id,
129
+ 'object_dir' => 'groups',
130
+ )
131
+ );
132
+
133
+ if ( $cover_image ) {
134
+ $cover_style = sprintf(
135
+ ' style="background-image: url( %s );"',
136
+ esc_url( $cover_image )
137
+ );
138
+ }
139
+
140
+ $cover_container = sprintf(
141
+ '<div class="bp-group-cover-image"%s></div>',
142
+ $cover_style
143
+ );
144
+
145
+ $container_classes[] = 'has-cover';
146
+ }
147
+
148
+ $display_description = (bool) $block_args['displayDescription'];
149
+ if ( $display_description ) {
150
+ $group_description = bp_get_group_description( $group );
151
+ $group_content = sprintf(
152
+ '<div class="group-description-content">%s</div>',
153
+ $group_description
154
+ );
155
+
156
+ $container_classes[] = 'has-description';
157
+ }
158
+
159
+ if ( $display_action_button ) {
160
+ $action_button = sprintf(
161
+ '<div class="bp-profile-button">
162
+ <a href="%1$s" class="button large primary button-primary" role="button">%2$s</a>
163
+ </div>',
164
+ esc_url( $group_link ),
165
+ esc_html__( 'Visit Group', 'buddypress' )
166
+ );
167
+ }
168
+
169
+ $output = sprintf(
170
+ '<div class="%1$s">
171
+ %2$s
172
+ <div class="group-content">
173
+ %3$s
174
+ <div class="group-description">
175
+ <strong><a href="%4$s">%5$s</a></strong>
176
+ %6$s
177
+ %7$s
178
+ </div>
179
+ </div>
180
+ </div>',
181
+ implode( ' ', array_map( 'sanitize_html_class', $container_classes ) ),
182
+ $cover_container,
183
+ $avatar_container,
184
+ esc_url( $group_link ),
185
+ esc_html( $group_name ),
186
+ $group_content,
187
+ $action_button
188
+ );
189
+
190
+ // Compact all interesting parameters.
191
+ $params = array_merge( $block_args, compact( 'group_name', 'group_link', 'group_description', 'avatar', 'cover_image' ) );
192
+
193
+ /**
194
+ * Filter here to edit the output of the single group block.
195
+ *
196
+ * @since 6.0.0
197
+ *
198
+ * @param string $output The HTML output of the block.
199
+ * @param BP_Groups_Group $group The group object.
200
+ * @param array $params The block extended parameters.
201
+ */
202
+ return apply_filters( 'bp_groups_render_group_block_output', $output, $group, $params );
203
+ }
bp-groups/bp-groups-cssjs.php CHANGED
@@ -58,5 +58,8 @@ function bp_groups_get_group_manage_members_script_data( $group_id = 0 ) {
58
  'path' => remove_query_arg( 'exclude_admins', $path ),
59
  'preloaded' => reset( $preloaded_members ),
60
  'roles' => bp_groups_get_group_roles(),
 
 
 
61
  );
62
  }
58
  'path' => remove_query_arg( 'exclude_admins', $path ),
59
  'preloaded' => reset( $preloaded_members ),
60
  'roles' => bp_groups_get_group_roles(),
61
+ 'strings' => array(
62
+ 'allMembers' => _x( 'All members', 'Group Manage Members dropdown default option', 'buddypress' ),
63
+ ),
64
  );
65
  }
bp-groups/bp-groups-functions.php CHANGED
@@ -694,6 +694,7 @@ function groups_get_group_members( $args = array() ) {
694
 
695
  // Backward compatibility with old method of passing arguments.
696
  if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
 
697
  _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
698
 
699
  $old_args_keys = array(
@@ -1689,6 +1690,14 @@ function groups_send_invites( $args = array() ) {
1689
  'force_resend' => false,
1690
  ), 'groups_send_invitation' );
1691
 
 
 
 
 
 
 
 
 
1692
  /*
1693
  * We will generally only want to fetch unsent invitations.
1694
  * If force_resend is true, then we need to fetch both sent and draft invites.
@@ -1699,12 +1708,6 @@ function groups_send_invites( $args = array() ) {
1699
  $args['invite_sent'] = 'draft';
1700
  }
1701
 
1702
- $args = array(
1703
- 'user_id' => $r['user_id'],
1704
- 'invitee_email' => $r['invitee_email'],
1705
- 'item_id' => $r['group_id'],
1706
- 'inviter_id' => $r['inviter_id'],
1707
- );
1708
  $invites = groups_get_invites( $args );
1709
 
1710
  $invited_users = array();
@@ -2076,7 +2079,8 @@ function groups_send_membership_request( $args = array() ) {
2076
  function groups_accept_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
2077
 
2078
  if ( ! empty( $membership_id ) ) {
2079
- _deprecated_argument( __METHOD__, '5.0.0', sprintf( __( 'Argument `membership_id` passed to %1$s is deprecated. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
 
2080
  }
2081
 
2082
  if ( ! $user_id || ! $group_id ) {
@@ -2146,6 +2150,7 @@ function groups_reject_membership_request( $membership_id, $user_id = 0, $group_
2146
  */
2147
  function groups_delete_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
2148
  if ( ! empty( $membership_id ) ){
 
2149
  _deprecated_argument( __METHOD__, '5.0.0', sprintf( __( 'Argument `membership_id` passed to %1$s is deprecated. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
2150
  }
2151
 
@@ -2412,9 +2417,24 @@ function groups_remove_data_for_user( $user_id ) {
2412
  do_action( 'groups_remove_data_for_user', $user_id );
2413
  }
2414
  add_action( 'wpmu_delete_user', 'groups_remove_data_for_user' );
2415
- add_action( 'delete_user', 'groups_remove_data_for_user' );
2416
  add_action( 'bp_make_spam_user', 'groups_remove_data_for_user' );
2417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2418
  /**
2419
  * Update orphaned child groups when the parent is deleted.
2420
  *
@@ -2752,6 +2772,12 @@ function bp_groups_remove_group_type( $group_id, $group_type ) {
2752
  return false;
2753
  }
2754
 
 
 
 
 
 
 
2755
  $deleted = bp_remove_object_terms( $group_id, $group_type, 'bp_group_type' );
2756
 
2757
  // Bust the case, if the type has been removed.
694
 
695
  // Backward compatibility with old method of passing arguments.
696
  if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
697
+ /* translators: 1: the name of the method. 2: the name of the file. */
698
  _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
699
 
700
  $old_args_keys = array(
1690
  'force_resend' => false,
1691
  ), 'groups_send_invitation' );
1692
 
1693
+
1694
+ $args = array(
1695
+ 'user_id' => $r['user_id'],
1696
+ 'invitee_email' => $r['invitee_email'],
1697
+ 'item_id' => $r['group_id'],
1698
+ 'inviter_id' => $r['inviter_id'],
1699
+ );
1700
+
1701
  /*
1702
  * We will generally only want to fetch unsent invitations.
1703
  * If force_resend is true, then we need to fetch both sent and draft invites.
1708
  $args['invite_sent'] = 'draft';
1709
  }
1710
 
 
 
 
 
 
 
1711
  $invites = groups_get_invites( $args );
1712
 
1713
  $invited_users = array();
2079
  function groups_accept_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
2080
 
2081
  if ( ! empty( $membership_id ) ) {
2082
+ /* translators: 1: the name of the method. 2: the name of the file. */
2083
+ _deprecated_argument( __METHOD__, '5.0.0', sprintf( __( 'Argument `membership_id` passed to %1$s is deprecated. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
2084
  }
2085
 
2086
  if ( ! $user_id || ! $group_id ) {
2150
  */
2151
  function groups_delete_membership_request( $membership_id, $user_id = 0, $group_id = 0 ) {
2152
  if ( ! empty( $membership_id ) ){
2153
+ /* translators: 1: method name. 2: file name. */
2154
  _deprecated_argument( __METHOD__, '5.0.0', sprintf( __( 'Argument `membership_id` passed to %1$s is deprecated. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
2155
  }
2156
 
2417
  do_action( 'groups_remove_data_for_user', $user_id );
2418
  }
2419
  add_action( 'wpmu_delete_user', 'groups_remove_data_for_user' );
 
2420
  add_action( 'bp_make_spam_user', 'groups_remove_data_for_user' );
2421
 
2422
+ /**
2423
+ * Deletes user group data on the 'delete_user' hook.
2424
+ *
2425
+ * @since 6.0.0
2426
+ *
2427
+ * @param int $user_id The ID of the deleted user.
2428
+ */
2429
+ function bp_groups_remove_data_for_user_on_delete_user( $user_id ) {
2430
+ if ( ! bp_remove_user_data_on_delete_user_hook( 'groups', $user_id ) ) {
2431
+ return;
2432
+ }
2433
+
2434
+ groups_remove_data_for_user( $user_id );
2435
+ }
2436
+ add_action( 'delete_user', 'bp_groups_remove_data_for_user_on_delete_user' );
2437
+
2438
  /**
2439
  * Update orphaned child groups when the parent is deleted.
2440
  *
2772
  return false;
2773
  }
2774
 
2775
+ // No need to continue if the group doesn't have the type.
2776
+ $existing_types = bp_groups_get_group_type( $group_id, false );
2777
+ if ( ! in_array( $group_type, $existing_types, true ) ) {
2778
+ return false;
2779
+ }
2780
+
2781
  $deleted = bp_remove_object_terms( $group_id, $group_type, 'bp_group_type' );
2782
 
2783
  // Bust the case, if the type has been removed.
bp-groups/bp-groups-notifications.php CHANGED
@@ -31,7 +31,8 @@ function groups_notification_group_updated( $group_id = 0, $old_group = null ) {
31
 
32
  if ( $group->name !== $old_group->name ) {
33
  $changed[] = sprintf(
34
- _x( '* Name changed from "%s" to "%s".', 'Group update email text', 'buddypress' ),
 
35
  esc_html( $old_group->name ),
36
  esc_html( $group->name )
37
  );
@@ -39,7 +40,8 @@ function groups_notification_group_updated( $group_id = 0, $old_group = null ) {
39
 
40
  if ( $group->description !== $old_group->description ) {
41
  $changed[] = sprintf(
42
- _x( '* Description changed from "%s" to "%s".', 'Group update email text', 'buddypress' ),
 
43
  esc_html( $old_group->description ),
44
  esc_html( $group->description )
45
  );
@@ -47,7 +49,8 @@ function groups_notification_group_updated( $group_id = 0, $old_group = null ) {
47
 
48
  if ( $group->slug !== $old_group->slug ) {
49
  $changed[] = sprintf(
50
- _x( '* Permalink changed from "%s" to "%s".', 'Group update email text', 'buddypress' ),
 
51
  esc_url( bp_get_group_permalink( $old_group ) ),
52
  esc_url( bp_get_group_permalink( $group ) )
53
  );
@@ -393,6 +396,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
393
  // because different values are passed to the filters,
394
  // we'll return values inline.
395
  if ( (int) $total_items > 1 ) {
 
396
  $text = sprintf( __( '%1$d new membership requests for the group "%2$s"', 'buddypress' ), (int) $total_items, $group->name );
397
  $amount = 'multiple';
398
  $notification_link = $group_link . 'admin/membership-requests/?n=1';
@@ -439,6 +443,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
439
  }
440
  } else {
441
  $user_fullname = bp_core_get_user_displayname( $requesting_user_id );
 
442
  $text = sprintf( __( '%s requests group membership', 'buddypress' ), $user_fullname );
443
  $notification_link = $group_link . 'admin/membership-requests/?n=1';
444
 
@@ -494,7 +499,8 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
494
  $amount = 'single';
495
 
496
  if ( (int) $total_items > 1 ) {
497
- $text = sprintf( __( '%d accepted group membership requests', 'buddypress' ), (int) $total_items, $group->name );
 
498
  $amount = 'multiple';
499
  $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
500
 
@@ -533,6 +539,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
533
  ), $total_items, $group->name, $text, $notification_link );
534
  }
535
  } else {
 
536
  $text = sprintf( __( 'Membership for group "%s" accepted', 'buddypress' ), $group->name );
537
  $filter = 'bp_groups_single_membership_request_accepted_notification';
538
  $notification_link = $group_link . '?n=1';
@@ -583,7 +590,8 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
583
  $amount = 'single';
584
 
585
  if ( (int) $total_items > 1 ) {
586
- $text = sprintf( __( '%d rejected group membership requests', 'buddypress' ), (int) $total_items, $group->name );
 
587
  $amount = 'multiple';
588
  $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
589
 
@@ -622,6 +630,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
622
  ), $total_items, $group->name, $text, $notification_link );
623
  }
624
  } else {
 
625
  $text = sprintf( __( 'Membership for group "%s" rejected', 'buddypress' ), $group->name );
626
  $notification_link = $group_link . '?n=1';
627
 
@@ -671,6 +680,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
671
  $amount = 'single';
672
 
673
  if ( (int) $total_items > 1 ) {
 
674
  $text = sprintf( __( 'You were promoted to an admin in %d groups', 'buddypress' ), (int) $total_items );
675
  $amount = 'multiple';
676
  $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
@@ -706,6 +716,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
706
  ), $total_items, $text, $notification_link );
707
  }
708
  } else {
 
709
  $text = sprintf( __( 'You were promoted to an admin in the group "%s"', 'buddypress' ), $group->name );
710
  $notification_link = $group_link . '?n=1';
711
 
@@ -753,6 +764,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
753
  $amount = 'single';
754
 
755
  if ( (int) $total_items > 1 ) {
 
756
  $text = sprintf( __( 'You were promoted to a mod in %d groups', 'buddypress' ), (int) $total_items );
757
  $amount = 'multiple';
758
  $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
@@ -788,6 +800,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
788
  ), $total_items, $text, $notification_link );
789
  }
790
  } else {
 
791
  $text = sprintf( __( 'You were promoted to a mod in the group "%s"', 'buddypress' ), $group->name );
792
  $notification_link = $group_link . '?n=1';
793
 
@@ -836,6 +849,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
836
  $notification_link = bp_loggedin_user_domain() . bp_get_groups_slug() . '/invites/?n=1';
837
 
838
  if ( (int) $total_items > 1 ) {
 
839
  $text = sprintf( __( 'You have %d new group invitations', 'buddypress' ), (int) $total_items );
840
  $amount = 'multiple';
841
 
@@ -870,6 +884,7 @@ function groups_format_notifications( $action, $item_id, $secondary_item_id, $to
870
  ), $total_items, $text, $notification_link );
871
  }
872
  } else {
 
873
  $text = sprintf( __( 'You have an invitation to the group: %s', 'buddypress' ), $group->name );
874
  $filter = 'bp_groups_single_group_invite_notification';
875
 
31
 
32
  if ( $group->name !== $old_group->name ) {
33
  $changed[] = sprintf(
34
+ /* translators: 1: the old group name. 2: the new group name. */
35
+ _x( '* Name changed from "%1$s" to "%2$s".', 'Group update email text', 'buddypress' ),
36
  esc_html( $old_group->name ),
37
  esc_html( $group->name )
38
  );
40
 
41
  if ( $group->description !== $old_group->description ) {
42
  $changed[] = sprintf(
43
+ /* translators: 1: the old group description. 2: the new group description. */
44
+ _x( '* Description changed from "%1$s" to "%2$s".', 'Group update email text', 'buddypress' ),
45
  esc_html( $old_group->description ),
46
  esc_html( $group->description )
47
  );
49
 
50
  if ( $group->slug !== $old_group->slug ) {
51
  $changed[] = sprintf(
52
+ /* translators: 1: the old group permalink. 2: the new group permalink. */
53
+ _x( '* Permalink changed from "%1$s" to "%2$s".', 'Group update email text', 'buddypress' ),
54
  esc_url( bp_get_group_permalink( $old_group ) ),
55
  esc_url( bp_get_group_permalink( $group ) )
56
  );
396
  // because different values are passed to the filters,
397
  // we'll return values inline.
398
  if ( (int) $total_items > 1 ) {
399
+ /* translators: 1: number of group membership requests. 2: group name. */
400
  $text = sprintf( __( '%1$d new membership requests for the group "%2$s"', 'buddypress' ), (int) $total_items, $group->name );
401
  $amount = 'multiple';
402
  $notification_link = $group_link . 'admin/membership-requests/?n=1';
443
  }
444
  } else {
445
  $user_fullname = bp_core_get_user_displayname( $requesting_user_id );
446
+ /* translators: %s: member name */
447
  $text = sprintf( __( '%s requests group membership', 'buddypress' ), $user_fullname );
448
  $notification_link = $group_link . 'admin/membership-requests/?n=1';
449
 
499
  $amount = 'single';
500
 
501
  if ( (int) $total_items > 1 ) {
502
+ /* translators: 1: number of accepted group membership requests. 2: group name. */
503
+ $text = sprintf( __( '%1$d accepted group membership requests for the group "%2$s"', 'buddypress' ), (int) $total_items, $group->name );
504
  $amount = 'multiple';
505
  $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
506
 
539
  ), $total_items, $group->name, $text, $notification_link );
540
  }
541
  } else {
542
+ /* translators: %s: group name. */
543
  $text = sprintf( __( 'Membership for group "%s" accepted', 'buddypress' ), $group->name );
544
  $filter = 'bp_groups_single_membership_request_accepted_notification';
545
  $notification_link = $group_link . '?n=1';
590
  $amount = 'single';
591
 
592
  if ( (int) $total_items > 1 ) {
593
+ /* translators: 1: number of accepted group membership requests. 2: group name. */
594
+ $text = sprintf( __( '%1$d rejected group membership requests for the group "%2$s"', 'buddypress' ), (int) $total_items, $group->name );
595
  $amount = 'multiple';
596
  $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
597
 
630
  ), $total_items, $group->name, $text, $notification_link );
631
  }
632
  } else {
633
+ /* translators: %s: group name. */
634
  $text = sprintf( __( 'Membership for group "%s" rejected', 'buddypress' ), $group->name );
635
  $notification_link = $group_link . '?n=1';
636
 
680
  $amount = 'single';
681
 
682
  if ( (int) $total_items > 1 ) {
683
+ /* translators: %d: number of groups the user has been promoted admin for */
684
  $text = sprintf( __( 'You were promoted to an admin in %d groups', 'buddypress' ), (int) $total_items );
685
  $amount = 'multiple';
686
  $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
716
  ), $total_items, $text, $notification_link );
717
  }
718
  } else {
719
+ /* translators: %s: group name. */
720
  $text = sprintf( __( 'You were promoted to an admin in the group "%s"', 'buddypress' ), $group->name );
721
  $notification_link = $group_link . '?n=1';
722
 
764
  $amount = 'single';
765
 
766
  if ( (int) $total_items > 1 ) {
767
+ /* translators: %d: number of groups the user has been promoted mod for */
768
  $text = sprintf( __( 'You were promoted to a mod in %d groups', 'buddypress' ), (int) $total_items );
769
  $amount = 'multiple';
770
  $notification_link = trailingslashit( bp_loggedin_user_domain() . bp_get_groups_slug() ) . '?n=1';
800
  ), $total_items, $text, $notification_link );
801
  }
802
  } else {
803
+ /* translators: %s: group name. */
804
  $text = sprintf( __( 'You were promoted to a mod in the group "%s"', 'buddypress' ), $group->name );
805
  $notification_link = $group_link . '?n=1';
806
 
849
  $notification_link = bp_loggedin_user_domain() . bp_get_groups_slug() . '/invites/?n=1';
850
 
851
  if ( (int) $total_items > 1 ) {
852
+ /* translators: %d: number of group invites */
853
  $text = sprintf( __( 'You have %d new group invitations', 'buddypress' ), (int) $total_items );
854
  $amount = 'multiple';
855
 
884
  ), $total_items, $text, $notification_link );
885
  }
886
  } else {
887
+ /* translators: %s: group name. */
888
  $text = sprintf( __( 'You have an invitation to the group: %s', 'buddypress' ), $group->name );
889
  $filter = 'bp_groups_single_group_invite_notification';
890
 
bp-groups/bp-groups-template.php CHANGED
@@ -912,7 +912,7 @@ function bp_get_group_avatar_url( $group = false, $type = 'full' ) {
912
  * False otherwise
913
  */
914
  function bp_group_use_cover_image_header() {
915
- return (bool) bp_is_active( 'groups', 'cover_image' ) && ! bp_disable_group_cover_image_uploads() && bp_attachments_is_wp_version_supported();
916
  }
917
 
918
  /**
@@ -1301,82 +1301,6 @@ function bp_group_description_excerpt( $group = false, $length = 225 ) {
1301
  return apply_filters( 'bp_get_group_description_excerpt', bp_create_excerpt( $group->description, $length ), $group );
1302
  }
1303
 
1304
- /**
1305
- * Output the status of the current group in the loop.
1306
- *
1307
- * Either 'Public' or 'Private'.
1308
- *
1309
- * @since 1.0.0
1310
- *
1311
- * @param object|bool $group Optional. Group object.
1312
- * Default: current group in loop.
1313
- */
1314
- function bp_group_public_status( $group = false ) {
1315
- echo bp_get_group_public_status( $group );
1316
- }
1317
- /**
1318
- * Return the status of the current group in the loop.
1319
- *
1320
- * Either 'Public' or 'Private'.
1321
- *
1322
- * @since 1.0.0
1323
- *
1324
- * @param object|bool $group Optional. Group object.
1325
- * Default: current group in loop.
1326
- * @return string
1327
- */
1328
- function bp_get_group_public_status( $group = false ) {
1329
- global $groups_template;
1330
-
1331
- if ( empty( $group ) ) {
1332
- $group =& $groups_template->group;
1333
- }
1334
-
1335
- if ( $group->is_public ) {
1336
- return __( 'Public', 'buddypress' );
1337
- } else {
1338
- return __( 'Private', 'buddypress' );
1339
- }
1340
- }
1341
-
1342
- /**
1343
- * Output whether the current group in the loop is public.
1344
- *
1345
- * No longer used in BuddyPress.
1346
- *
1347
- * @param object|bool $group Optional. Group object.
1348
- * Default: current group in loop.
1349
- */
1350
- function bp_group_is_public( $group = false ) {
1351
- echo bp_get_group_is_public( $group );
1352
- }
1353
- /**
1354
- * Return whether the current group in the loop is public.
1355
- *
1356
- * No longer used in BuddyPress.
1357
- *
1358
- * @param object|bool $group Optional. Group object.
1359
- * Default: current group in loop.
1360
- * @return mixed
1361
- */
1362
- function bp_get_group_is_public( $group = false ) {
1363
- global $groups_template;
1364
-
1365
- if ( empty( $group ) ) {
1366
- $group =& $groups_template->group;
1367
- }
1368
-
1369
- /**
1370
- * Filters whether the current group in the loop is public.
1371
- *
1372
- * @since 2.5.0 Added the `$group` parameter.
1373
- *
1374
- * @param bool $public True if the group is public.
1375
- * @param object $group Group object.
1376
- */
1377
- return apply_filters( 'bp_get_group_is_public', $group->is_public, $group );
1378
- }
1379
-
1380
  /**
1381
  * Output the created date of the current group in the loop.
1382
  *
@@ -1621,7 +1545,11 @@ function bp_group_creator_avatar( $group = false, $args = array() ) {
1621
  'height' => false,
1622
  'class' => 'avatar',
1623
  'id' => false,
1624
- 'alt' => sprintf( __( 'Group creator profile photo of %s', 'buddypress' ), bp_core_get_user_displayname( $group->creator_id ) )
 
 
 
 
1625
  ), 'group_creator_avatar' );
1626
  extract( $r, EXTR_SKIP );
1627
 
@@ -1684,7 +1612,21 @@ function bp_group_list_admins( $group = false ) {
1684
  <ul id="group-admins">
1685
  <?php foreach( (array) $group->admins as $admin ) { ?>
1686
  <li>
1687
- <a href="<?php echo bp_core_get_user_domain( $admin->user_id, $admin->user_nicename, $admin->user_login ) ?>" class="bp-tooltip" data-bp-tooltip="<?php printf( ('%s'), bp_core_get_user_displayname( $admin->user_id ) ); ?>"><?php echo bp_core_fetch_avatar( array( 'item_id' => $admin->user_id, 'email' => $admin->user_email, 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $admin->user_id ) ) ) ) ?></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1688
  </li>
1689
  <?php } ?>
1690
  </ul>
@@ -1716,7 +1658,20 @@ function bp_group_list_mods( $group = false ) {
1716
  <?php foreach( (array) $group->mods as $mod ) { ?>
1717
 
1718
  <li>
1719
- <a href="<?php echo bp_core_get_user_domain( $mod->user_id, $mod->user_nicename, $mod->user_login ) ?>" class="bp-tooltip" data-bp-tooltip="<?php printf( ('%s'), bp_core_get_user_displayname( $mod->user_id ) ); ?>"><?php echo bp_core_fetch_avatar( array( 'item_id' => $mod->user_id, 'email' => $mod->user_email, 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $mod->user_id ) ) ) ) ?></a>
 
 
 
 
 
 
 
 
 
 
 
 
 
1720
  </li>
1721
 
1722
  <?php } ?>
@@ -1967,6 +1922,7 @@ function bp_groups_pagination_count() {
1967
  if ( 1 == $groups_template->total_group_count ) {
1968
  $message = __( 'Viewing 1 group', 'buddypress' );
1969
  } else {
 
1970
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s group', 'Viewing %1$s - %2$s of %3$s groups', $groups_template->total_group_count, 'buddypress' ), $from_num, $to_num, $total );
1971
  }
1972
 
@@ -2326,7 +2282,21 @@ function bp_group_admin_memberlist( $admin_list = false, $group = false ) {
2326
 
2327
  <li>
2328
 
2329
- <?php echo bp_core_fetch_avatar( array( 'item_id' => $admin->user_id, 'type' => 'thumb', 'width' => 30, 'height' => 30, 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $admin->user_id ) ) ) ) ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2330
 
2331
  <h5>
2332
 
@@ -2342,11 +2312,26 @@ function bp_group_admin_memberlist( $admin_list = false, $group = false ) {
2342
 
2343
  <li>
2344
 
2345
- <?php echo bp_core_fetch_avatar( array( 'item_id' => $admin->user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $admin->user_id ) ) ) ) ?>
 
 
 
 
 
 
 
 
 
 
 
 
2346
 
2347
  <h5><?php echo bp_core_get_userlink( $admin->user_id ) ?></h5>
2348
  <span class="activity">
2349
- <?php echo bp_core_get_last_activity( strtotime( $admin->date_modified ), __( 'joined %s', 'buddypress') ); ?>
 
 
 
2350
  </span>
2351
 
2352
  <?php if ( bp_is_active( 'friends' ) ) : ?>
@@ -2402,7 +2387,22 @@ function bp_group_mod_memberlist( $admin_list = false, $group = false ) {
2402
 
2403
  <li>
2404
 
2405
- <?php echo bp_core_fetch_avatar( array( 'item_id' => $mod->user_id, 'type' => 'thumb', 'width' => 30, 'height' => 30, 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $mod->user_id ) ) ) ) ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2406
 
2407
  <h5>
2408
  <?php echo bp_core_get_userlink( $mod->user_id ); ?>
@@ -2418,11 +2418,28 @@ function bp_group_mod_memberlist( $admin_list = false, $group = false ) {
2418
 
2419
  <li>
2420
 
2421
- <?php echo bp_core_fetch_avatar( array( 'item_id' => $mod->user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_core_get_user_displayname( $mod->user_id ) ) ) ) ?>
 
 
 
 
 
 
 
 
 
 
 
 
2422
 
2423
  <h5><?php echo bp_core_get_userlink( $mod->user_id ) ?></h5>
2424
 
2425
- <span class="activity"><?php echo bp_core_get_last_activity( strtotime( $mod->date_modified ), __( 'joined %s', 'buddypress') ); ?></span>
 
 
 
 
 
2426
 
2427
  <?php if ( bp_is_active( 'friends' ) ) : ?>
2428
 
@@ -4126,7 +4143,14 @@ function bp_group_member_joined_since( $args = array() ) {
4126
  *
4127
  * @param string $value Joined since time.
4128
  */
4129
- return apply_filters( 'bp_get_group_member_joined_since', bp_core_get_last_activity( $members_template->member->date_modified, __( 'joined %s', 'buddypress') ) );
 
 
 
 
 
 
 
4130
  }
4131
 
4132
  /**
@@ -4242,7 +4266,8 @@ function bp_group_member_pagination_count() {
4242
  if ( 1 == $members_template->total_member_count ) {
4243
  $message = __( 'Viewing 1 member', 'buddypress' );
4244
  } else {
4245
- $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s member', 'Viewing %1$s - %2$s of %3$s members', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
 
4246
  }
4247
 
4248
  /**
@@ -5213,6 +5238,7 @@ function bp_current_group_directory_type_message() {
5213
  function bp_get_current_group_directory_type_message() {
5214
  $type_object = bp_groups_get_group_type_object( bp_get_current_group_directory_type() );
5215
 
 
5216
  $message = sprintf( __( 'Viewing groups of the type: %s', 'buddypress' ), '<strong>' . $type_object->labels['singular_name'] . '</strong>' );
5217
 
5218
  /**
@@ -5570,7 +5596,11 @@ function bp_group_request_time_since_requested() {
5570
  *
5571
  * @param string $value Formatted time since membership was requested.
5572
  */
5573
- echo apply_filters( 'bp_group_request_time_since_requested', sprintf( __( 'requested %s', 'buddypress' ), bp_core_time_since( $requests_template->request->date_modified ) ) );
 
 
 
 
5574
  }
5575
 
5576
  /**
@@ -5643,6 +5673,7 @@ function bp_group_requests_pagination_count() {
5643
  if ( 1 == $requests_template->total_request_count ) {
5644
  $message = __( 'Viewing 1 request', 'buddypress' );
5645
  } else {
 
5646
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s request', 'Viewing %1$s - %2$s of %3$s requests', $requests_template->total_request_count, 'buddypress' ), $from_num, $to_num, $total );
5647
  }
5648
 
@@ -5912,6 +5943,7 @@ function bp_group_invite_pagination_count() {
5912
  if ( 1 == $invites_template->total_invite_count ) {
5913
  $message = __( 'Viewing 1 invitation', 'buddypress' );
5914
  } else {
 
5915
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s invitation', 'Viewing %1$s - %2$s of %3$s invitations', $invites_template->total_invite_count, 'buddypress' ), $from_num, $to_num, $total );
5916
  }
5917
 
@@ -6090,7 +6122,7 @@ function bp_current_group_description() {
6090
  *
6091
  * @param string $current_group_desc Description of the current group.
6092
  */
6093
- $desc = apply_filters( 'bp_get_group_description', $current_group_desc );
6094
 
6095
  /**
6096
  * Filters the description of the current group.
@@ -6215,7 +6247,11 @@ function bp_groups_get_profile_stats( $args = '' ) {
6215
  }
6216
 
6217
  // If groups exist, show some formatted output
6218
- $r['output'] = $r['before'] . sprintf( _n( '%s group', '%s groups', $r['groups'], 'buddypress' ), '<strong>' . $r['groups'] . '</strong>' ) . $r['after'];
 
 
 
 
6219
  }
6220
  }
6221
 
912
  * False otherwise
913
  */
914
  function bp_group_use_cover_image_header() {
915
+ return (bool) bp_is_active( 'groups', 'cover_image' ) && ! bp_disable_group_cover_image_uploads();
916
  }
917
 
918
  /**
1301
  return apply_filters( 'bp_get_group_description_excerpt', bp_create_excerpt( $group->description, $length ), $group );
1302
  }
1303
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1304
  /**
1305
  * Output the created date of the current group in the loop.
1306
  *
1545
  'height' => false,
1546
  'class' => 'avatar',
1547
  'id' => false,
1548
+ 'alt' => sprintf(
1549
+ /* translators: %s: group creator name */
1550
+ __( 'Group creator profile photo of %s', 'buddypress' ),
1551
+ bp_core_get_user_displayname( $group->creator_id )
1552
+ ),
1553
  ), 'group_creator_avatar' );
1554
  extract( $r, EXTR_SKIP );
1555
 
1612
  <ul id="group-admins">
1613
  <?php foreach( (array) $group->admins as $admin ) { ?>
1614
  <li>
1615
+ <a href="<?php echo bp_core_get_user_domain( $admin->user_id, $admin->user_nicename, $admin->user_login ) ?>" class="bp-tooltip" data-bp-tooltip="<?php printf( ('%s'), bp_core_get_user_displayname( $admin->user_id ) ); ?>">
1616
+ <?php
1617
+ echo bp_core_fetch_avatar(
1618
+ array(
1619
+ 'item_id' => $admin->user_id,
1620
+ 'email' => $admin->user_email,
1621
+ 'alt' => sprintf(
1622
+ /* translators: %s: member name */
1623
+ __( 'Profile picture of %s', 'buddypress' ),
1624
+ bp_core_get_user_displayname( $admin->user_id )
1625
+ ),
1626
+ )
1627
+ );
1628
+ ?>
1629
+ </a>
1630
  </li>
1631
  <?php } ?>
1632
  </ul>
1658
  <?php foreach( (array) $group->mods as $mod ) { ?>
1659
 
1660
  <li>
1661
+ <a href="<?php echo bp_core_get_user_domain( $mod->user_id, $mod->user_nicename, $mod->user_login ) ?>" class="bp-tooltip" data-bp-tooltip="<?php printf( ('%s'), bp_core_get_user_displayname( $mod->user_id ) ); ?>">
1662
+ <?php
1663
+ echo bp_core_fetch_avatar(
1664
+ array(
1665
+ 'item_id' => $mod->user_id,
1666
+ 'email' => $mod->user_email,
1667
+ 'alt' => sprintf(
1668
+ /* translators: %s: member name */
1669
+ __( 'Profile picture of %s', 'buddypress' ),
1670
+ bp_core_get_user_displayname( $mod->user_id )
1671
+ ),
1672
+ )
1673
+ ); ?>
1674
+ </a>
1675
  </li>
1676
 
1677
  <?php } ?>
1922
  if ( 1 == $groups_template->total_group_count ) {
1923
  $message = __( 'Viewing 1 group', 'buddypress' );
1924
  } else {
1925
+ /* translators: 1: group from number. 2: group to number. 3: total groups. */
1926
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s group', 'Viewing %1$s - %2$s of %3$s groups', $groups_template->total_group_count, 'buddypress' ), $from_num, $to_num, $total );
1927
  }
1928
 
2282
 
2283
  <li>
2284
 
2285
+ <?php
2286
+ echo bp_core_fetch_avatar(
2287
+ array(
2288
+ 'item_id' => $admin->user_id,
2289
+ 'type' => 'thumb',
2290
+ 'width' => 30,
2291
+ 'height' => 30,
2292
+ 'alt' => sprintf(
2293
+ /* translators: %s: member name */
2294
+ __( 'Profile picture of %s', 'buddypress' ),
2295
+ bp_core_get_user_displayname( $admin->user_id )
2296
+ ),
2297
+ )
2298
+ );
2299
+ ?>
2300
 
2301
  <h5>
2302
 
2312
 
2313
  <li>
2314
 
2315
+ <?php
2316
+ echo bp_core_fetch_avatar(
2317
+ array(
2318
+ 'item_id' => $admin->user_id,
2319
+ 'type' => 'thumb',
2320
+ 'alt' => sprintf(
2321
+ /* translators: %s: member name */
2322
+ __( 'Profile picture of %s', 'buddypress' ),
2323
+ bp_core_get_user_displayname( $admin->user_id )
2324
+ ),
2325
+ )
2326
+ );
2327
+ ?>
2328
 
2329
  <h5><?php echo bp_core_get_userlink( $admin->user_id ) ?></h5>
2330
  <span class="activity">
2331
+ <?php
2332
+ /* translators: %s: human time diff */
2333
+ echo bp_core_get_last_activity( strtotime( $admin->date_modified ), __( 'joined %s', 'buddypress') );
2334
+ ?>
2335
  </span>
2336
 
2337
  <?php if ( bp_is_active( 'friends' ) ) : ?>
2387
 
2388
  <li>
2389
 
2390
+ <?php
2391
+ /* translators: %s: member name */
2392
+ echo bp_core_fetch_avatar(
2393
+ array(
2394
+ 'item_id' => $mod->user_id,
2395
+ 'type' => 'thumb',
2396
+ 'width' => 30,
2397
+ 'height' => 30,
2398
+ 'alt' => sprintf(
2399
+ /* translators: %s: member name */
2400
+ __( 'Profile picture of %s', 'buddypress' ),
2401
+ bp_core_get_user_displayname( $mod->user_id )
2402
+ ),
2403
+ )
2404
+ );
2405
+ ?>
2406
 
2407
  <h5>
2408
  <?php echo bp_core_get_userlink( $mod->user_id ); ?>
2418
 
2419
  <li>
2420
 
2421
+ <?php
2422
+ echo bp_core_fetch_avatar(
2423
+ array(
2424
+ 'item_id' => $mod->user_id,
2425
+ 'type' => 'thumb',
2426
+ 'alt' => sprintf(
2427
+ /* translators: %s: member name */
2428
+ __( 'Profile picture of %s', 'buddypress' ),
2429
+ bp_core_get_user_displayname( $mod->user_id )
2430
+ ),
2431
+ )
2432
+ );
2433
+ ?>
2434
 
2435
  <h5><?php echo bp_core_get_userlink( $mod->user_id ) ?></h5>
2436
 
2437
+ <span class="activity">
2438
+ <?php
2439
+ /* translators: %s: human time diff */
2440
+ echo bp_core_get_last_activity( strtotime( $mod->date_modified ), __( 'joined %s', 'buddypress') );
2441
+ ?>
2442
+ </span>
2443
 
2444
  <?php if ( bp_is_active( 'friends' ) ) : ?>
2445
 
4143
  *
4144
  * @param string $value Joined since time.
4145
  */
4146
+ return apply_filters(
4147
+ 'bp_get_group_member_joined_since',
4148
+ bp_core_get_last_activity(
4149
+ $members_template->member->date_modified,
4150
+ /* translators: %s: human time diff */
4151
+ __( 'joined %s', 'buddypress')
4152
+ )
4153
+ );
4154
  }
4155
 
4156
  /**
4266
  if ( 1 == $members_template->total_member_count ) {
4267
  $message = __( 'Viewing 1 member', 'buddypress' );
4268
  } else {
4269
+ /* translators: 1: group member from number. 2: group member to number. 3: total group members. */
4270
+ $message = sprintf( _nx( 'Viewing %1$s - %2$s of %3$s member', 'Viewing %1$s - %2$s of %3$s members', $members_template->total_member_count, 'group members pagination', 'buddypress' ), $from_num, $to_num, $total );
4271
  }
4272
 
4273
  /**
5238
  function bp_get_current_group_directory_type_message() {
5239
  $type_object = bp_groups_get_group_type_object( bp_get_current_group_directory_type() );
5240
 
5241
+ /* translators: %s: group type singular name */
5242
  $message = sprintf( __( 'Viewing groups of the type: %s', 'buddypress' ), '<strong>' . $type_object->labels['singular_name'] . '</strong>' );
5243
 
5244
  /**
5596
  *
5597
  * @param string $value Formatted time since membership was requested.
5598
  */
5599
+ echo apply_filters(
5600
+ 'bp_group_request_time_since_requested',
5601
+ /* translators: %s: human time diff */
5602
+ sprintf( __( 'requested %s', 'buddypress' ), bp_core_time_since( $requests_template->request->date_modified ) )
5603
+ );
5604
  }
5605
 
5606
  /**
5673
  if ( 1 == $requests_template->total_request_count ) {
5674
  $message = __( 'Viewing 1 request', 'buddypress' );
5675
  } else {
5676
+ /* translators: 1: group request from number. 2: group request to number. 3: total group requests. */
5677
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s request', 'Viewing %1$s - %2$s of %3$s requests', $requests_template->total_request_count, 'buddypress' ), $from_num, $to_num, $total );
5678
  }
5679
 
5943
  if ( 1 == $invites_template->total_invite_count ) {
5944
  $message = __( 'Viewing 1 invitation', 'buddypress' );
5945
  } else {
5946
+ /* translators: 1: group invite from number. 2: group invite to number. 3: total group invites. */
5947
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s invitation', 'Viewing %1$s - %2$s of %3$s invitations', $invites_template->total_invite_count, 'buddypress' ), $from_num, $to_num, $total );
5948
  }
5949
 
6122
  *
6123
  * @param string $current_group_desc Description of the current group.
6124
  */
6125
+ $desc = apply_filters( 'bp_get_group_description', $current_group_desc );
6126
 
6127
  /**
6128
  * Filters the description of the current group.
6247
  }
6248
 
6249
  // If groups exist, show some formatted output
6250
+ $r['output'] = $r['before'];
6251
+
6252
+ /* translators: %s: number of groups */
6253
+ $r['output'] .= sprintf( _n( '%s group', '%s groups', $r['groups'], 'buddypress' ), '<strong>' . $r['groups'] . '</strong>' );
6254
+ $r['output'] .= $r['after'];
6255
  }
6256
  }
6257
 
bp-groups/bp-groups-widgets.php CHANGED
@@ -65,11 +65,21 @@ function groups_ajax_widget_groups_list() {
65
  <div class="item-title"><?php bp_group_link(); ?></div>
66
  <div class="item-meta">
67
  <?php if ( 'newest-groups' === $_POST['filter'] ) : ?>
68
- <span class="activity" data-livestamp="<?php bp_core_iso8601_date( bp_get_group_date_created( 0, array( 'relative' => false ) ) ); ?>"><?php printf( __( 'created %s', 'buddypress' ), bp_get_group_date_created() ); ?></span>
 
 
 
 
 
69
  <?php elseif ( 'popular-groups' === $_POST['filter'] ) : ?>
70
  <span class="activity"><?php bp_group_member_count(); ?></span>
71
  <?php else : ?>
72
- <span class="activity" data-livestamp="<?php bp_core_iso8601_date( bp_get_group_last_active( 0, array( 'relative' => false ) ) ); ?>"><?php printf( __( 'active %s', 'buddypress' ), bp_get_group_last_active() ); ?></span>
 
 
 
 
 
73
  <?php endif; ?>
74
  </div>
75
  </div>
65
  <div class="item-title"><?php bp_group_link(); ?></div>
66
  <div class="item-meta">
67
  <?php if ( 'newest-groups' === $_POST['filter'] ) : ?>
68
+ <span class="activity" data-livestamp="<?php bp_core_iso8601_date( bp_get_group_date_created( 0, array( 'relative' => false ) ) ); ?>">
69
+ <?php
70
+ /* translators: %s: date */
71
+ printf( __( 'created %s', 'buddypress' ), bp_get_group_date_created() );
72
+ ?>
73
+ </span>
74
  <?php elseif ( 'popular-groups' === $_POST['filter'] ) : ?>
75
  <span class="activity"><?php bp_group_member_count(); ?></span>
76
  <?php else : ?>
77
+ <span class="activity" data-livestamp="<?php bp_core_iso8601_date( bp_get_group_last_active( 0, array( 'relative' => false ) ) ); ?>">
78
+ <?php
79
+ /* translators: %s: last activity timestamp (e.g. "active 1 hour ago") */
80
+ printf( _x( 'active %s', 'last time the group was active', 'buddypress' ), bp_get_group_last_active() );
81
+ ?>
82
+ </span>
83
  <?php endif; ?>
84
  </div>
85
  </div>
bp-groups/classes/class-bp-groups-component.php CHANGED
@@ -130,6 +130,7 @@ class BP_Groups_Component extends BP_Component {
130
  'functions',
131
  'notifications',
132
  'cssjs',
 
133
  );
134
 
135
  // Conditional includes.
@@ -649,7 +650,11 @@ class BP_Groups_Component extends BP_Component {
649
  * Only add the members subnav if it's not the home's nav.
650
  */
651
  $sub_nav[] = array(
652
- 'name' => sprintf( _x( 'Members %s', 'My Group screen nav', 'buddypress' ), '<span>' . number_format( $this->current_group->total_member_count ) . '</span>' ),
 
 
 
 
653
  'slug' => 'members',
654
  'parent_url' => $group_link,
655
  'parent_slug' => $this->current_group->slug,
@@ -866,7 +871,11 @@ class BP_Groups_Component extends BP_Component {
866
  $bp->bp_options_avatar = bp_core_fetch_avatar( array(
867
  'item_id' => bp_displayed_user_id(),
868
  'type' => 'thumb',
869
- 'alt' => sprintf( __( 'Profile picture of %s', 'buddypress' ), bp_get_displayed_user_fullname() )
 
 
 
 
870
  ) );
871
  $bp->bp_options_title = bp_get_displayed_user_fullname();
872
 
@@ -927,17 +936,81 @@ class BP_Groups_Component extends BP_Component {
927
  * Init the BP REST API.
928
  *
929
  * @since 5.0.0
 
930
  *
931
  * @param array $controllers Optional. See BP_Component::rest_api_init() for
932
  * description.
933
  */
934
  public function rest_api_init( $controllers = array() ) {
935
- parent::rest_api_init( array(
936
  'BP_REST_Groups_Endpoint',
937
  'BP_REST_Group_Membership_Endpoint',
938
  'BP_REST_Group_Invites_Endpoint',
939
  'BP_REST_Group_Membership_Request_Endpoint',
940
  'BP_REST_Attachments_Group_Avatar_Endpoint',
941
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
942
  }
943
  }
130
  'functions',
131
  'notifications',
132
  'cssjs',
133
+ 'blocks',
134
  );
135
 
136
  // Conditional includes.
650
  * Only add the members subnav if it's not the home's nav.
651
  */
652
  $sub_nav[] = array(
653
+ 'name' => sprintf(
654
+ /* translators: %s: total member count */
655
+ _x( 'Members %s', 'My Group screen nav', 'buddypress' ),
656
+ '<span>' . number_format( $this->current_group->total_member_count ) . '</span>'
657
+ ),
658
  'slug' => 'members',
659
  'parent_url' => $group_link,
660
  'parent_slug' => $this->current_group->slug,
871
  $bp->bp_options_avatar = bp_core_fetch_avatar( array(
872
  'item_id' => bp_displayed_user_id(),
873
  'type' => 'thumb',
874
+ 'alt' => sprintf(
875
+ /* translators: %s: member name */
876
+ __( 'Profile picture of %s', 'buddypress' ),
877
+ bp_get_displayed_user_fullname()
878
+ ),
879
  ) );
880
  $bp->bp_options_title = bp_get_displayed_user_fullname();
881
 
936
  * Init the BP REST API.
937
  *
938
  * @since 5.0.0
939
+ * @since 6.0.0 Adds the Group Cover REST endpoint.
940
  *
941
  * @param array $controllers Optional. See BP_Component::rest_api_init() for
942
  * description.
943
  */
944
  public function rest_api_init( $controllers = array() ) {
945
+ $controllers = array(
946
  'BP_REST_Groups_Endpoint',
947
  'BP_REST_Group_Membership_Endpoint',
948
  'BP_REST_Group_Invites_Endpoint',
949
  'BP_REST_Group_Membership_Request_Endpoint',
950
  'BP_REST_Attachments_Group_Avatar_Endpoint',
951
+ );
952
+
953
+ // Support to Group Cover.
954
+ if ( bp_is_active( 'groups', 'cover_image' ) ) {
955
+ $controllers[] = 'BP_REST_Attachments_Group_Cover_Endpoint';
956
+ }
957
+
958
+ parent::rest_api_init( $controllers );
959
+ }
960
+
961
+ /**
962
+ * Register the BP Groups Blocks.
963
+ *
964
+ * @since 6.0.0
965
+ *
966
+ * @param array $blocks Optional. See BP_Component::blocks_init() for
967
+ * description.
968
+ */
969
+ public function blocks_init( $blocks = array() ) {
970
+ parent::blocks_init(
971
+ array(
972
+ 'bp/group' => array(
973
+ 'name' => 'bp/group',
974
+ 'editor_script' => 'bp-group-block',
975
+ 'editor_script_url' => plugins_url( 'js/blocks/group.js', dirname( __FILE__ ) ),
976
+ 'editor_script_deps' => array(
977
+ 'wp-blocks',
978
+ 'wp-element',
979
+ 'wp-components',
980
+ 'wp-i18n',
981
+ 'wp-editor',
982
+ 'wp-compose',
983
+ 'wp-data',
984
+ 'wp-block-editor',
985
+ 'bp-block-components',
986
+ ),
987
+ 'style' => 'bp-group-block',
988
+ 'style_url' => plugins_url( 'css/blocks/group.css', dirname( __FILE__ ) ),
989
+ 'render_callback' => 'bp_groups_render_group_block',
990
+ 'attributes' => array(
991
+ 'itemID' => array(
992
+ 'type' => 'integer',
993
+ 'default' => 0,
994
+ ),
995
+ 'avatarSize' => array(
996
+ 'type' => 'string',
997
+ 'default' => 'full',
998
+ ),
999
+ 'displayDescription' => array(
1000
+ 'type' => 'boolean',
1001
+ 'default' => true,
1002
+ ),
1003
+ 'displayActionButton' => array(
1004
+ 'type' => 'boolean',
1005
+ 'default' => true,
1006
+ ),
1007
+ 'displayCoverImage' => array(
1008
+ 'type' => 'boolean',
1009
+ 'default' => true,
1010
+ ),
1011
+ ),
1012
+ ),
1013
+ )
1014
+ );
1015
  }
1016
  }
bp-groups/classes/class-bp-groups-group-members-template.php CHANGED
@@ -97,6 +97,7 @@ class BP_Groups_Group_Members_Template {
97
 
98
  // Backward compatibility with old method of passing arguments.
99
  if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
 
100
  _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
101
 
102
  $old_args_keys = array(
97
 
98
  // Backward compatibility with old method of passing arguments.
99
  if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
100
+ /* translators: 1: the name of the method. 2: the name of the file. */
101
  _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
102
 
103
  $old_args_keys = array(
bp-groups/classes/class-bp-groups-invite-template.php CHANGED
@@ -82,6 +82,7 @@ class BP_Groups_Invite_Template {
82
 
83
  // Backward compatibility with old method of passing arguments.
84
  if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
 
85
  _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
86
 
87
  $old_args_keys = array(
@@ -232,13 +233,50 @@ class BP_Groups_Invite_Template {
232
  $this->invite->user->profile_data = BP_XProfile_ProfileData::get_all_for_user( $user_id );
233
  }
234
 
235
- $this->invite->user->avatar = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'full', 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->invite->user->fullname ) ) );
236
- $this->invite->user->avatar_thumb = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->invite->user->fullname ) ) );
237
- $this->invite->user->avatar_mini = bp_core_fetch_avatar( array( 'item_id' => $user_id, 'type' => 'thumb', 'alt' => sprintf( __( 'Profile photo of %s', 'buddypress' ), $this->invite->user->fullname ), 'width' => 30, 'height' => 30 ) );
238
- $this->invite->user->email = $this->invite->user->user_email;
239
- $this->invite->user->user_url = bp_core_get_user_domain( $user_id, $this->invite->user->user_nicename, $this->invite->user->user_login );
240
- $this->invite->user->user_link = "<a href='{$this->invite->user->user_url}'>{$this->invite->user->fullname}</a>";
241
- $this->invite->user->last_active = bp_core_get_last_activity( $this->invite->user->last_activity, __( 'active %s', 'buddypress' ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
  if ( bp_is_active( 'groups' ) ) {
244
  $total_groups = BP_Groups_Member::total_group_count( $user_id );
82
 
83
  // Backward compatibility with old method of passing arguments.
84
  if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
85
+ /* translators: 1: the name of the method. 2: the name of the file. */
86
  _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
87
 
88
  $old_args_keys = array(
233
  $this->invite->user->profile_data = BP_XProfile_ProfileData::get_all_for_user( $user_id );
234
  }
235
 
236
+ $this->invite->user->avatar = bp_core_fetch_avatar(
237
+ array(
238
+ 'item_id' => $user_id,
239
+ 'type' => 'full',
240
+ 'alt' => sprintf(
241
+ /* translators: %s: member name */
242
+ __( 'Profile photo of %s', 'buddypress' ),
243
+ $this->invite->user->fullname
244
+ )
245
+ )
246
+ );
247
+
248
+ $this->invite->user->avatar_thumb = bp_core_fetch_avatar(
249
+ array(
250
+ 'item_id' => $user_id,
251
+ 'type' => 'thumb',
252
+ 'alt' => sprintf(
253
+ /* translators: %s: member name */
254
+ __( 'Profile photo of %s', 'buddypress' ),
255
+ $this->invite->user->fullname
256
+ )
257
+ )
258
+ );
259
+
260
+ $this->invite->user->avatar_mini = bp_core_fetch_avatar(
261
+ array(
262
+ 'item_id' => $user_id,
263
+ 'type' => 'thumb',
264
+ 'alt' => sprintf(
265
+ /* translators: %s: member name */
266
+ __( 'Profile photo of %s', 'buddypress' ),
267
+ $this->invite->user->fullname
268
+ ),
269
+ 'width' => 30,
270
+ 'height' => 30
271
+ )
272
+ );
273
+
274
+ $this->invite->user->email = $this->invite->user->user_email;
275
+ $this->invite->user->user_url = bp_core_get_user_domain( $user_id, $this->invite->user->user_nicename, $this->invite->user->user_login );
276
+ $this->invite->user->user_link = "<a href='{$this->invite->user->user_url}'>{$this->invite->user->fullname}</a>";
277
+
278
+ /* translators: %s: last activity timestamp (e.g. "active 1 hour ago") */
279
+ $this->invite->user->last_active = bp_core_get_last_activity( $this->invite->user->last_activity, __( 'active %s', 'buddypress' ) );
280
 
281
  if ( bp_is_active( 'groups' ) ) {
282
  $total_groups = BP_Groups_Member::total_group_count( $user_id );
bp-groups/classes/class-bp-groups-list-table.php CHANGED
@@ -95,7 +95,7 @@ class BP_Groups_List_Table extends WP_List_Table {
95
 
96
  // Sort order.
97
  $order = 'DESC';
98
- if ( !empty( $_REQUEST['order'] ) ) {
99
  $order = ( 'desc' == strtolower( $_REQUEST['order'] ) ) ? 'DESC' : 'ASC';
100
  }
101
 
@@ -119,14 +119,22 @@ class BP_Groups_List_Table extends WP_List_Table {
119
  }
120
 
121
  // Are we doing a search?
122
- if ( !empty( $_REQUEST['s'] ) )
123
  $search_terms = $_REQUEST['s'];
124
 
 
 
 
 
125
  // Check if user has clicked on a specific group (if so, fetch only that group).
126
- if ( !empty( $_REQUEST['gid'] ) )
127
  $include_id = (int) $_REQUEST['gid'];
128
 
129
- // Set the current view.
 
 
 
 
130
  if ( isset( $_GET['group_status'] ) && in_array( $_GET['group_status'], array( 'public', 'private', 'hidden' ) ) ) {
131
  $this->view = $_GET['group_status'];
132
  }
@@ -186,6 +194,24 @@ class BP_Groups_List_Table extends WP_List_Table {
186
  'total_items' => $groups_template->total_group_count,
187
  'total_pages' => ceil( $groups_template->total_group_count / $per_page )
188
  ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  }
190
 
191
  /**
@@ -331,10 +357,54 @@ class BP_Groups_List_Table extends WP_List_Table {
331
  ?></h2>
332
 
333
  <ul class="subsubsub">
334
- <li class="all"><a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( 'all' == $this->view ) echo 'current'; ?>"><?php _e( 'All', 'buddypress' ); ?></a> |</li>
335
- <li class="public"><a href="<?php echo esc_url( add_query_arg( 'group_status', 'public', $url_base ) ); ?>" class="<?php if ( 'public' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Public <span class="count">(%s)</span>', 'Public <span class="count">(%s)</span>', $this->group_counts['public'], 'buddypress' ), number_format_i18n( $this->group_counts['public'] ) ); ?></a> |</li>
336
- <li class="private"><a href="<?php echo esc_url( add_query_arg( 'group_status', 'private', $url_base ) ); ?>" class="<?php if ( 'private' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Private <span class="count">(%s)</span>', 'Private <span class="count">(%s)</span>', $this->group_counts['private'], 'buddypress' ), number_format_i18n( $this->group_counts['private'] ) ); ?></a> |</li>
337
- <li class="hidden"><a href="<?php echo esc_url( add_query_arg( 'group_status', 'hidden', $url_base ) ); ?>" class="<?php if ( 'hidden' == $this->view ) echo 'current'; ?>"><?php printf( _n( 'Hidden <span class="count">(%s)</span>', 'Hidden <span class="count">(%s)</span>', $this->group_counts['hidden'], 'buddypress' ), number_format_i18n( $this->group_counts['hidden'] ) ); ?></a></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
  <?php
340
 
95
 
96
  // Sort order.
97
  $order = 'DESC';
98
+ if ( ! empty( $_REQUEST['order'] ) ) {
99
  $order = ( 'desc' == strtolower( $_REQUEST['order'] ) ) ? 'DESC' : 'ASC';
100
  }
101
 
119
  }
120
 
121
  // Are we doing a search?
122
+ if ( ! empty( $_REQUEST['s'] ) ) {
123
  $search_terms = $_REQUEST['s'];
124
 
125
+ // Set the view as a search request.
126
+ $this->view = 'search';
127
+ }
128
+
129
  // Check if user has clicked on a specific group (if so, fetch only that group).
130
+ if ( ! empty( $_REQUEST['gid'] ) ) {
131
  $include_id = (int) $_REQUEST['gid'];
132
 
133
+ // Set the view as a single activity.
134
+ $this->view = 'single';
135
+ }
136
+
137
+ // Use the status request to set the current view.
138
  if ( isset( $_GET['group_status'] ) && in_array( $_GET['group_status'], array( 'public', 'private', 'hidden' ) ) ) {
139
  $this->view = $_GET['group_status'];
140
  }
194
  'total_items' => $groups_template->total_group_count,
195
  'total_pages' => ceil( $groups_template->total_group_count / $per_page )
196
  ) );
197
+
198
+ // Set the Total number of groups.
199
+ if ( 'all' === $this->view ) {
200
+ $this->group_counts['all'] = (int) $groups_template->total_group_count;
201
+
202
+ // Only perform a query if not on the main list view.
203
+ } elseif ( 'single' !== $this->view ) {
204
+ $count_groups = groups_get_groups(
205
+ array(
206
+ 'fields' => 'ids',
207
+ 'show_hidden' => true,
208
+ )
209
+ );
210
+
211
+ if ( $count_groups['total'] ) {
212
+ $this->group_counts['all'] = (int) $count_groups['total'];
213
+ }
214
+ }
215
  }
216
 
217
  /**
357
  ?></h2>
358
 
359
  <ul class="subsubsub">
360
+ <li class="all">
361
+ <a href="<?php echo esc_url( $url_base ); ?>" class="<?php if ( 'all' === $this->view ) echo 'current'; ?>">
362
+ <?php printf(
363
+ /* translators: %s is the placeholder for the count html tag `<span class="count"/>` */
364
+ esc_html__( 'All %s', 'buddypress' ),
365
+ sprintf(
366
+ '<span class="count">(%s)</span>',
367
+ number_format_i18n( $this->group_counts['all'] )
368
+ )
369
+ ); ?>
370
+ </a> |
371
+ </li>
372
+ <li class="public">
373
+ <a href="<?php echo esc_url( add_query_arg( 'group_status', 'public', $url_base ) ); ?>" class="<?php if ( 'public' === $this->view ) echo 'current'; ?>">
374
+ <?php printf(
375
+ /* translators: %s is the placeholder for the count html `<span class="count"/>` */
376
+ _n( 'Public %s', 'Public %s', $this->group_counts['public'], 'buddypress' ),
377
+ sprintf(
378
+ '<span class="count">(%s)</span>',
379
+ number_format_i18n( $this->group_counts['public'] )
380
+ )
381
+ ); ?>
382
+ </a> |
383
+ </li>
384
+ <li class="private">
385
+ <a href="<?php echo esc_url( add_query_arg( 'group_status', 'private', $url_base ) ); ?>" class="<?php if ( 'private' === $this->view ) echo 'current'; ?>">
386
+ <?php printf(
387
+ /* translators: %s is the placeholder for the count html `<span class="count"/>` */
388
+ _n( 'Private %s', 'Private %s', $this->group_counts['private'], 'buddypress' ),
389
+ sprintf(
390
+ '<span class="count">(%s)</span>',
391
+ number_format_i18n( $this->group_counts['private'] )
392
+ )
393
+ ); ?>
394
+ </a> |
395
+ </li>
396
+ <li class="hidden">
397
+ <a href="<?php echo esc_url( add_query_arg( 'group_status', 'hidden', $url_base ) ); ?>" class="<?php if ( 'hidden' === $this->view ) echo 'current'; ?>">
398
+ <?php printf(
399
+ /* translators: %s is the placeholder for the count html tag */
400
+ _n( 'Hidden %s', 'Hidden %s', $this->group_counts['hidden'], 'buddypress' ),
401
+ sprintf(
402
+ '<span class="count">(%s)</span>',
403
+ number_format_i18n( $this->group_counts['hidden'] )
404
+ )
405
+ ); ?>
406
+ </a>
407
+ </li>
408
 
409
  <?php
410
 
bp-groups/classes/class-bp-groups-membership-requests-template.php CHANGED
@@ -89,6 +89,7 @@ class BP_Groups_Membership_Requests_Template {
89
 
90
  // Backward compatibility with old method of passing arguments.
91
  if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
 
92
  _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
93
 
94
  $old_args_keys = array(
89
 
90
  // Backward compatibility with old method of passing arguments.
91
  if ( ! is_array( $args ) || count( $function_args ) > 1 ) {
92
+ /* translators: 1: the name of the method. 2: the name of the file. */
93
  _deprecated_argument( __METHOD__, '2.0.0', sprintf( __( 'Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress' ), __METHOD__, __FILE__ ) );
94
 
95
  $old_args_keys = array(
bp-groups/classes/class-bp-groups-widget.php CHANGED
@@ -149,6 +149,7 @@ class BP_Groups_Widget extends WP_Widget {
149
  } elseif ( 'popular' == $instance['group_default'] ) {
150
  bp_group_member_count();
151
  } else {
 
152
  printf( __( 'active %s', 'buddypress' ), bp_get_group_last_active() );
153
  }
154
  ?>
149
  } elseif ( 'popular' == $instance['group_default'] ) {
150
  bp_group_member_count();
151
  } else {
152
+ /* translators: %s: last activity timestamp (e.g. "active 1 hour ago") */
153
  printf( __( 'active %s', 'buddypress' ), bp_get_group_last_active() );
154
  }
155
  ?>
bp-groups/classes/class-bp-rest-attachments-group-avatar-endpoint.php ADDED
@@ -0,0 +1,499 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Attachments_Group_Avatar_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 5.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Group Avatar endpoints.
13
+ *
14
+ * @since 5.0.0
15
+ */
16
+ class BP_REST_Attachments_Group_Avatar_Endpoint extends WP_REST_Controller {
17
+
18
+ use BP_REST_Attachments;
19
+
20
+ /**
21
+ * Reuse some parts of the BP_REST_Groups_Endpoint class.
22
+ *
23
+ * @since 5.0.0
24
+ *
25
+ * @var BP_REST_Groups_Endpoint
26
+ */
27
+ protected $groups_endpoint;
28
+
29
+ /**
30
+ * BP_Attachment_Avatar Instance.
31
+ *
32
+ * @since 5.0.0
33
+ *
34
+ * @var BP_Attachment_Avatar
35
+ */
36
+ protected $avatar_instance;
37
+
38
+ /**
39
+ * Hold the group object.
40
+ *
41
+ * @since 5.0.0
42
+ *
43
+ * @var BP_Groups_Group
44
+ */
45
+ protected $group;
46
+
47
+ /**
48
+ * Group object type.
49
+ *
50
+ * @since 5.0.0
51
+ *
52
+ * @var string
53
+ */
54
+ protected $object = 'group';
55
+
56
+ /**
57
+ * Constructor.
58
+ *
59
+ * @since 5.0.0
60
+ */
61
+ public function __construct() {
62
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
63
+ $this->rest_base = buddypress()->groups->id;
64
+ $this->groups_endpoint = new BP_REST_Groups_Endpoint();
65
+ $this->avatar_instance = new BP_Attachment_Avatar();
66
+ }
67
+
68
+ /**
69
+ * Register the component routes.
70
+ *
71
+ * @since 5.0.0
72
+ */
73
+ public function register_routes() {
74
+ register_rest_route(
75
+ $this->namespace,
76
+ '/' . $this->rest_base . '/(?P<group_id>[\d]+)/avatar',
77
+ array(
78
+ 'args' => array(
79
+ 'group_id' => array(
80
+ 'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),
81
+ 'type' => 'integer',
82
+ ),
83
+ ),
84
+ array(
85
+ 'methods' => WP_REST_Server::READABLE,
86
+ 'callback' => array( $this, 'get_item' ),
87
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
88
+ 'args' => $this->get_item_collection_params(),
89
+ ),
90
+ array(
91
+ 'methods' => WP_REST_Server::CREATABLE,
92
+ 'callback' => array( $this, 'create_item' ),
93
+ 'permission_callback' => array( $this, 'create_item_permissions_check' ),
94
+ ),
95
+ array(
96
+ 'methods' => WP_REST_Server::DELETABLE,
97
+ 'callback' => array( $this, 'delete_item' ),
98
+ 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
99
+ ),
100
+ 'schema' => array( $this, 'get_item_schema' ),
101
+ )
102
+ );
103
+ }
104
+
105
+ /**
106
+ * Fetch an existing group avatar.
107
+ *
108
+ * @since 5.0.0
109
+ *
110
+ * @param WP_REST_Request $request Full details about the request.
111
+ * @return WP_REST_Response|WP_Error
112
+ */
113
+ public function get_item( $request ) {
114
+ $args = array();
115
+
116
+ foreach ( array( 'full', 'thumb' ) as $type ) {
117
+ $args[ $type ] = bp_core_fetch_avatar(
118
+ array(
119
+ 'object' => $this->object,
120
+ 'type' => $type,
121
+ 'item_id' => (int) $this->group->id,
122
+ 'html' => (bool) $request['html'],
123
+ 'alt' => $request['alt'],
124
+ )
125
+ );
126
+ }
127
+
128
+ // Get the avatar object.
129
+ $avatar = $this->get_avatar_object( $args );
130
+
131
+ if ( ! $avatar->full && ! $avatar->thumb ) {
132
+ return new WP_Error(
133
+ 'bp_rest_attachments_group_avatar_no_image',
134
+ __( 'Sorry, there was a problem fetching this group avatar.', 'buddypress' ),
135
+ array(
136
+ 'status' => 500,
137
+ )
138
+ );
139
+ }
140
+
141
+ $retval = array(
142
+ $this->prepare_response_for_collection(
143
+ $this->prepare_item_for_response( $avatar, $request )
144
+ ),
145
+ );
146
+
147
+ $response = rest_ensure_response( $retval );
148
+
149
+ /**
150
+ * Fires after a group avatar is fetched via the REST API.
151
+ *
152
+ * @since 5.0.0
153
+ *
154
+ * @param string $avatar The group avatar.
155
+ * @param WP_REST_Response $response The response data.
156
+ * @param WP_REST_Request $request The request sent to the API.
157
+ */
158
+ do_action( 'bp_rest_attachments_group_avatar_get_item', $avatar, $response, $request );
159
+
160
+ return $response;
161
+ }
162
+
163
+ /**
164
+ * Checks if a given request has access to get a group avatar.
165
+ *
166
+ * @since 5.0.0
167
+ *
168
+ * @param WP_REST_Request $request Full details about the request.
169
+ * @return bool|WP_Error
170
+ */
171
+ public function get_item_permissions_check( $request ) {
172
+ $retval = true;
173
+ $this->group = $this->groups_endpoint->get_group_object( $request );
174
+
175
+ if ( ! $this->group ) {
176
+ $retval = new WP_Error(
177
+ 'bp_rest_group_invalid_id',
178
+ __( 'Invalid group ID.', 'buddypress' ),
179
+ array(
180
+ 'status' => 404,
181
+ )
182
+ );
183
+ }
184
+
185
+ /**
186
+ * Filter the group avatar `get_item` permissions check.
187
+ *
188
+ * @since 5.0.0
189
+ *
190
+ * @param bool|WP_Error $retval Returned value.
191
+ * @param WP_REST_Request $request The request sent to the API.
192
+ */
193
+ return apply_filters( 'bp_rest_attachments_group_avatar_get_item_permissions_check', $retval, $request );
194
+ }
195
+
196
+ /**
197
+ * Upload a group avatar.
198
+ *
199
+ * @since 5.0.0
200
+ *
201
+ * @param WP_REST_Request $request Full details about the request.
202
+ * @return WP_REST_Response|WP_Error
203
+ */
204
+ public function create_item( $request ) {
205
+ $request->set_param( 'context', 'edit' );
206
+
207
+ // Get the image file from $_FILES.
208
+ $files = $request->get_file_params();
209
+
210
+ if ( empty( $files ) ) {
211
+ return new WP_Error(
212
+ 'bp_rest_attachments_group_avatar_no_image_file',
213
+ __( 'Sorry, you need an image file to upload.', 'buddypress' ),
214
+ array(
215
+ 'status' => 500,
216
+ )
217
+ );
218
+ }
219
+
220
+ // Upload the avatar.
221
+ $avatar = $this->upload_avatar_from_file( $files );
222
+ if ( is_wp_error( $avatar ) ) {
223
+ return $avatar;
224
+ }
225
+
226
+ $retval = array(
227
+ $this->prepare_response_for_collection(
228
+ $this->prepare_item_for_response( $avatar, $request )
229
+ ),
230
+ );
231
+
232
+ $response = rest_ensure_response( $retval );
233
+
234
+ /**
235
+ * Fires after a group avatar is uploaded via the REST API.
236
+ *
237
+ * @since 5.0.0
238
+ *
239
+ * @param stdClass $avatar The group avatar object.
240
+ * @param WP_REST_Response $response The response data.
241
+ * @param WP_REST_Request $request The request sent to the API.
242
+ */
243
+ do_action( 'bp_rest_attachments_group_avatar_create_item', $avatar, $response, $request );
244
+
245
+ return $response;
246
+ }
247
+
248
+ /**
249
+ * Checks if a given request has access to upload a group avatar.
250
+ *
251
+ * @since 5.0.0
252
+ *
253
+ * @param WP_REST_Request $request Full details about the request.
254
+ * @return bool|WP_Error
255
+ */
256
+ public function create_item_permissions_check( $request ) {
257
+ $retval = $this->get_item_permissions_check( $request );
258
+
259
+ if ( true === $retval && ( bp_disable_group_avatar_uploads() || false === buddypress()->avatar->show_avatars ) ) {
260
+ $retval = new WP_Error(
261
+ 'bp_rest_attachments_group_avatar_disabled',
262
+ __( 'Sorry, group avatar upload is disabled.', 'buddypress' ),
263
+ array(
264
+ 'status' => 500,
265
+ )
266
+ );
267
+ }
268
+
269
+ if ( true === $retval
270
+ && ! groups_is_user_admin( bp_loggedin_user_id(), $this->group->id )
271
+ && ! current_user_can( 'bp_moderate' )
272
+ ) {
273
+ $retval = new WP_Error(
274
+ 'bp_rest_authorization_required',
275
+ __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
276
+ array(
277
+ 'status' => rest_authorization_required_code(),
278
+ )
279
+ );
280
+ }
281
+
282
+ /**
283
+ * Filter the group avatar `create_item` permissions check.
284
+ *
285
+ * @since 5.0.0
286
+ *
287
+ * @param bool|WP_Error $retval Returned value.
288
+ * @param WP_REST_Request $request The request sent to the API.
289
+ */
290
+ return apply_filters( 'bp_rest_attachments_group_avatar_create_item_permissions_check', $retval, $request );
291
+ }
292
+
293
+ /**
294
+ * Delete an existing group avatar.
295
+ *
296
+ * @since 5.0.0
297
+ *
298
+ * @param WP_REST_Request $request Full details about the request.
299
+ * @return WP_REST_Response|WP_Error
300
+ */
301
+ public function delete_item( $request ) {
302
+ $request->set_param( 'context', 'edit' );
303
+ $group_id = (int) $this->group->id;
304
+
305
+ if ( ! bp_get_group_has_avatar( $group_id ) ) {
306
+ return new WP_Error(
307
+ 'bp_rest_attachments_group_avatar_no_uploaded_avatar',
308
+ __( 'Sorry, there are no uploaded avatars for this group on this site.', 'buddypress' ),
309
+ array(
310
+ 'status' => 404,
311
+ )
312
+ );
313
+ }
314
+
315
+ $args = array();
316
+
317
+ foreach ( array( 'full', 'thumb' ) as $type ) {
318
+ $args[ $type ] = bp_core_fetch_avatar(
319
+ array(
320
+ 'object' => $this->object,
321
+ 'type' => $type,
322
+ 'item_id' => $group_id,
323
+ 'html' => false,
324
+ )
325
+ );
326
+ }
327
+
328
+ // Get the avatar object before deleting it.
329
+ $avatar = $this->get_avatar_object( $args );
330
+
331
+ $deleted = bp_core_delete_existing_avatar(
332
+ array(
333
+ 'object' => $this->object,
334
+ 'item_id' => $group_id,
335
+ )
336
+ );
337
+
338
+ if ( ! $deleted ) {
339
+ return new WP_Error(
340
+ 'bp_rest_attachments_group_avatar_delete_failed',
341
+ __( 'Sorry, there was a problem deleting this group avatar.', 'buddypress' ),
342
+ array(
343
+ 'status' => 500,
344
+ )
345
+ );
346
+ }
347
+
348
+ // Build the response.
349
+ $response = new WP_REST_Response();
350
+ $response->set_data(
351
+ array(
352
+ 'deleted' => true,
353
+ 'previous' => $avatar,
354
+ )
355
+ );
356
+
357
+ /**
358
+ * Fires after a group avatar is deleted via the REST API.
359
+ *
360
+ * @since 5.0.0
361
+ *
362
+ * @param WP_REST_Response $response The response data.
363
+ * @param WP_REST_Request $request The request sent to the API.
364
+ */
365
+ do_action( 'bp_rest_attachments_group_avatar_delete_item', $response, $request );
366
+
367
+ return $response;
368
+ }
369
+
370
+ /**
371
+ * Checks if a given request has access to delete a group avatar.
372
+ *
373
+ * @since 5.0.0
374
+ *
375
+ * @param WP_REST_Request $request Full details about the request.
376
+ * @return bool|WP_Error
377
+ */
378
+ public function delete_item_permissions_check( $request ) {
379
+ $retval = $this->create_item_permissions_check( $request );
380
+
381
+ /**
382
+ * Filter the group avatar `delete_item` permissions check.
383
+ *
384
+ * @since 5.0.0
385
+ *
386
+ * @param bool|WP_Error $retval Returned value.
387
+ * @param WP_REST_Request $request The request sent to the API.
388
+ */
389
+ return apply_filters( 'bp_rest_attachments_group_avatar_delete_item_permissions_check', $retval, $request );
390
+ }
391
+
392
+ /**
393
+ * Prepares avatar data to return as an object.
394
+ *
395
+ * @since 5.0.0
396
+ *
397
+ * @param stdClass|string $avatar Avatar object or string with url or image with html.
398
+ * @param WP_REST_Request $request Full details about the request.
399
+ * @return WP_REST_Response
400
+ */
401
+ public function prepare_item_for_response( $avatar, $request ) {
402
+ $data = array(
403
+ 'full' => $avatar->full,
404
+ 'thumb' => $avatar->thumb,
405
+ );
406
+
407
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
408
+ $data = $this->add_additional_fields_to_object( $data, $request );
409
+ $data = $this->filter_response_by_context( $data, $context );
410
+
411
+ // @todo add prepare_links
412
+ $response = rest_ensure_response( $data );
413
+
414
+ /**
415
+ * Filter a group avatar value returned from the API.
416
+ *
417
+ * @since 5.0.0
418
+ *
419
+ * @param WP_REST_Response $response Response.
420
+ * @param WP_REST_Request $request Request used to generate the response.
421
+ * @param stdClass|string $avatar Avatar object or string with url or image with html.
422
+ */
423
+ return apply_filters( 'bp_rest_attachments_group_avatar_prepare_value', $response, $request, $avatar );
424
+ }
425
+
426
+ /**
427
+ * Get the plugin schema, conforming to JSON Schema.
428
+ *
429
+ * @since 5.0.0
430
+ *
431
+ * @return array
432
+ */
433
+ public function get_item_schema() {
434
+ $schema = array(
435
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
436
+ 'title' => 'bp_attachments_group_avatar',
437
+ 'type' => 'object',
438
+ 'properties' => array(
439
+ 'full' => array(
440
+ 'context' => array( 'view', 'edit' ),
441
+ 'description' => __( 'Full size of the image file.', 'buddypress' ),
442
+ 'type' => 'string',
443
+ 'readonly' => true,
444
+ ),
445
+ 'thumb' => array(
446
+ 'context' => array( 'view', 'edit' ),
447
+ 'description' => __( 'Thumb size of the image file.', 'buddypress' ),
448
+ 'type' => 'string',
449
+ 'readonly' => true,
450
+ ),
451
+ ),
452
+ );
453
+
454
+ /**
455
+ * Filters the group avatar schema.
456
+ *
457
+ * @param string $schema The endpoint schema.
458
+ */
459
+ return apply_filters( 'bp_rest_attachments_group_avatar_schema', $this->add_additional_fields_schema( $schema ) );
460
+ }
461
+
462
+ /**
463
+ * Get the query params for the `get_item`.
464
+ *
465
+ * @since 5.0.0
466
+ *
467
+ * @return array
468
+ */
469
+ public function get_item_collection_params() {
470
+ $params = parent::get_collection_params();
471
+ $params['context']['default'] = 'view';
472
+
473
+ // Removing unused params.
474
+ unset( $params['search'], $params['page'], $params['per_page'] );
475
+
476
+ $params['html'] = array(
477
+ 'description' => __( 'Whether to return an <img> HTML element, vs a raw URL to a group avatar.', 'buddypress' ),
478
+ 'default' => false,
479
+ 'type' => 'boolean',
480
+ 'sanitize_callback' => 'rest_sanitize_boolean',
481
+ 'validate_callback' => 'rest_validate_request_arg',
482
+ );
483
+
484
+ $params['alt'] = array(
485
+ 'description' => __( 'The alt attribute for the <img> element.', 'buddypress' ),
486
+ 'default' => '',
487
+ 'type' => 'string',
488
+ 'sanitize_callback' => 'sanitize_text_field',
489
+ 'validate_callback' => 'rest_validate_request_arg',
490
+ );
491
+
492
+ /**
493
+ * Filters the item collection query params.
494
+ *
495
+ * @param array $params Query params.
496
+ */
497
+ return apply_filters( 'bp_rest_attachments_group_avatar_collection_params', $params );
498
+ }
499
+ }
bp-groups/classes/class-bp-rest-attachments-group-cover-endpoint.php ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Attachments_Group_Cover_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 6.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Group Cover endpoints.
13
+ *
14
+ * /groups/<group_id>/cover
15
+ *
16
+ * @since 6.0.0
17
+ */
18
+ class BP_REST_Attachments_Group_Cover_Endpoint extends WP_REST_Controller {
19
+
20
+ use BP_REST_Attachments;
21
+
22
+ /**
23
+ * BP_Attachment_Cover_Image Instance.
24
+ *
25
+ * @since 6.0.0
26
+ *
27
+ * @var BP_Attachment_Cover_Image
28
+ */
29
+ protected $attachment_instance;
30
+
31
+ /**
32
+ * Reuse some parts of the BP_REST_Groups_Endpoint class.
33
+ *
34
+ * @since 6.0.0
35
+ *
36
+ * @var BP_REST_Groups_Endpoint
37
+ */
38
+ protected $groups_endpoint;
39
+
40
+ /**
41
+ * Hold the group object.
42
+ *
43
+ * @since 6.0.0
44
+ *
45
+ * @var BP_Groups_Group
46
+ */
47
+ protected $group;
48
+
49
+ /**
50
+ * Group object type.
51
+ *
52
+ * @since 6.0.0
53
+ *
54
+ * @var string
55
+ */
56
+ protected $object = 'group';
57
+
58
+ /**
59
+ * Constructor.
60
+ *
61
+ * @since 6.0.0
62
+ */
63
+ public function __construct() {
64
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
65
+ $this->rest_base = buddypress()->groups->id;
66
+ $this->groups_endpoint = new BP_REST_Groups_Endpoint();
67
+ $this->attachment_instance = new BP_Attachment_Cover_Image();
68
+ }
69
+
70
+ /**
71
+ * Register the component routes.
72
+ *
73
+ * @since 6.0.0
74
+ */
75
+ public function register_routes() {
76
+ register_rest_route(
77
+ $this->namespace,
78
+ '/' . $this->rest_base . '/(?P<group_id>[\d]+)/cover',
79
+ array(
80
+ 'args' => array(
81
+ 'group_id' => array(
82
+ 'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ),
83
+ 'type' => 'integer',
84
+ ),
85
+ ),
86
+ array(
87
+ 'methods' => WP_REST_Server::READABLE,
88
+ 'callback' => array( $this, 'get_item' ),
89
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
90
+ ),
91
+ array(
92
+ 'methods' => WP_REST_Server::CREATABLE,
93
+ 'callback' => array( $this, 'create_item' ),
94
+ 'permission_callback' => array( $this, 'create_item_permissions_check' ),
95
+ ),
96
+ array(
97
+ 'methods' => WP_REST_Server::DELETABLE,
98
+ 'callback' => array( $this, 'delete_item' ),
99
+ 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
100
+ ),
101
+ 'schema' => array( $this, 'get_item_schema' ),
102
+ )
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Fetch an existing group cover.
108
+ *
109
+ * @since 6.0.0
110
+ *
111
+ * @param WP_REST_Request $request Full details about the request.
112
+ * @return WP_REST_Response|WP_Error
113
+ */
114
+ public function get_item( $request ) {
115
+ $cover_url = bp_get_group_cover_url( $this->group );
116
+
117
+ if ( empty( $cover_url ) ) {
118
+ return new WP_Error(
119
+ 'bp_rest_attachments_group_cover_no_image',
120
+ __( 'Sorry, there was a problem fetching this group cover.', 'buddypress' ),
121
+ array(
122
+ 'status' => 500,
123
+ )
124
+ );
125
+ }
126
+
127
+ $retval = array(
128
+ $this->prepare_response_for_collection(
129
+ $this->prepare_item_for_response( $cover_url, $request )
130
+ ),
131
+ );
132
+
133
+ $response = rest_ensure_response( $retval );
134
+
135
+ /**
136
+ * Fires after a group cover is fetched via the REST API.
137
+ *
138
+ * @since 6.0.0
139
+ *
140
+ * @param string $cover_url The group cover url.
141
+ * @param WP_REST_Response $response The response data.
142
+ * @param WP_REST_Request $request The request sent to the API.
143
+ */
144
+ do_action( 'bp_rest_attachments_group_cover_get_item', $cover_url, $response, $request );
145
+
146
+ return $response;
147
+ }
148
+
149
+ /**
150
+ * Checks if a given request has access to get a group cover.
151
+ *
152
+ * @since 6.0.0
153
+ *
154
+ * @param WP_REST_Request $request Full details about the request.
155
+ * @return bool|WP_Error
156
+ */
157
+ public function get_item_permissions_check( $request ) {
158
+ $retval = true;
159
+ $this->group = $this->groups_endpoint->get_group_object( $request );
160
+
161
+ if ( ! $this->group ) {
162
+ $retval = new WP_Error(
163
+ 'bp_rest_group_invalid_id',
164
+ __( 'Invalid group id.', 'buddypress' ),
165
+ array(
166
+ 'status' => 404,
167
+ )
168
+ );
169
+ }
170
+
171
+ /**
172
+ * Filter the group cover `get_item` permissions check.
173
+ *
174
+ * @since 6.0.0
175
+ *
176
+ * @param bool|WP_Error $retval Returned value.
177
+ * @param WP_REST_Request $request The request sent to the API.
178
+ */
179
+ return apply_filters( 'bp_rest_attachments_group_cover_get_item_permissions_check', $retval, $request );
180
+ }
181
+
182
+ /**
183
+ * Upload a group cover.
184
+ *
185
+ * @since 6.0.0
186
+ *
187
+ * @param WP_REST_Request $request Full details about the request.
188
+ * @return WP_REST_Response|WP_Error
189
+ */
190
+ public function create_item( $request ) {
191
+ $request->set_param( 'context', 'edit' );
192
+
193
+ // Get the image file from $_FILES.
194
+ $files = $request->get_file_params();
195
+
196
+ if ( empty( $files ) ) {
197
+ return new WP_Error(
198
+ 'bp_rest_attachments_group_cover_no_image_file',
199
+ __( 'Sorry, you need an image file to upload.', 'buddypress' ),
200
+ array(
201
+ 'status' => 500,
202
+ )
203
+ );
204
+ }
205
+
206
+ // Upload the group cover.
207
+ $cover_url = $this->upload_cover_from_file( $files );
208
+ if ( is_wp_error( $cover_url ) ) {
209
+ return $cover_url;
210
+ }
211
+
212
+ $retval = array(
213
+ $this->prepare_response_for_collection(
214
+ $this->prepare_item_for_response( $cover_url, $request )
215
+ ),
216
+ );
217
+
218
+ $response = rest_ensure_response( $retval );
219
+
220
+ /**
221
+ * Fires after a group cover is uploaded via the REST API.
222
+ *
223
+ * @since 6.0.0
224
+ *
225
+ * @param string $cover_url The group cover url.
226
+ * @param WP_REST_Response $response The response data.
227
+ * @param WP_REST_Request $request The request sent to the API.
228
+ */
229
+ do_action( 'bp_rest_attachments_group_cover_create_item', $cover_url, $response, $request );
230
+
231
+ return $response;
232
+ }
233
+
234
+ /**
235
+ * Checks if a given request has access to upload a group cover.
236
+ *
237
+ * @since 6.0.0
238
+ *
239
+ * @param WP_REST_Request $request Full details about the request.
240
+ * @return bool|WP_Error
241
+ */
242
+ public function create_item_permissions_check( $request ) {
243
+ $retval = $this->delete_item_permissions_check( $request );
244
+
245
+ if ( true === $retval && bp_disable_group_cover_image_uploads() ) {
246
+ $retval = new WP_Error(
247
+ 'bp_rest_attachments_group_cover_disabled',
248
+ __( 'Sorry, group cover upload is disabled.', 'buddypress' ),
249
+ array(
250
+ 'status' => 500,
251
+ )
252
+ );
253
+ }
254
+
255
+ /**
256
+ * Filter the group cover `create_item` permissions check.
257
+ *
258
+ * @since 6.0.0
259
+ *
260
+ * @param bool|WP_Error $retval Returned value.
261
+ * @param WP_REST_Request $request The request sent to the API.
262
+ */
263
+ return apply_filters( 'bp_rest_attachments_group_cover_create_item_permissions_check', $retval, $request );
264
+ }
265
+
266
+ /**
267
+ * Delete an existing group cover.
268
+ *
269
+ * @since 6.0.0
270
+ *
271
+ * @param WP_REST_Request $request Full details about the request.
272
+ * @return WP_REST_Response|WP_Error
273
+ */
274
+ public function delete_item( $request ) {
275
+ $request->set_param( 'context', 'edit' );
276
+
277
+ $cover_url = bp_get_group_cover_url( $this->group );
278
+ $deleted = bp_attachments_delete_file(
279
+ array(
280
+ 'item_id' => (int) $this->group->id,
281
+ 'object_dir' => $this->get_cover_object_component(),
282
+ 'type' => 'cover-image',
283
+ )
284
+ );
285
+
286
+ if ( ! $deleted ) {
287
+ return new WP_Error(
288
+ 'bp_rest_attachments_group_cover_delete_failed',
289
+ __( 'Sorry, there was a problem deleting this group cover.', 'buddypress' ),
290
+ array(
291
+ 'status' => 500,
292
+ )
293
+ );
294
+ }
295
+
296
+ // Build the response.
297
+ $response = new WP_REST_Response();
298
+ $response->set_data(
299
+ array(
300
+ 'deleted' => true,
301
+ 'previous' => $cover_url,
302
+ )
303
+ );
304
+
305
+ /**
306
+ * Fires after a group cover is deleted via the REST API.
307
+ *
308
+ * @since 6.0.0
309
+ *
310
+ * @param BP_Groups_Group $group The group object.
311
+ * @param WP_REST_Response $response The response data.
312
+ * @param WP_REST_Request $request The request sent to the API.
313
+ */
314
+ do_action( 'bp_rest_attachments_group_cover_delete_item', $this->group, $response, $request );
315
+
316
+ return $response;
317
+ }
318
+
319
+ /**
320
+ * Checks if a given request has access to delete a group cover.
321
+ *
322
+ * @since 6.0.0
323
+ *
324
+ * @param WP_REST_Request $request Full details about the request.
325
+ * @return bool|WP_Error
326
+ */
327
+ public function delete_item_permissions_check( $request ) {
328
+ $retval = $this->get_item_permissions_check( $request );
329
+ $args = array();
330
+
331
+ if ( isset( $this->group->id ) ) {
332
+ $args = array(
333
+ 'item_id' => (int) $this->group->id,
334
+ 'object' => $this->object,
335
+ );
336
+ }
337
+
338
+ if ( true === $retval && ! is_user_logged_in() ) {
339
+ $retval = new WP_Error(
340
+ 'bp_rest_authorization_required',
341
+ __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
342
+ array(
343
+ 'status' => rest_authorization_required_code(),
344
+ )
345
+ );
346
+ }
347
+
348
+ if ( true === $retval && ! empty( $args ) && ! bp_attachments_current_user_can( 'edit_cover_image', $args ) ) {
349
+ $retval = new WP_Error(
350
+ 'bp_rest_authorization_required',
351
+ __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
352
+ array(
353
+ 'status' => rest_authorization_required_code(),
354
+ )
355
+ );
356
+ }
357
+
358
+ /**
359
+ * Filter the group cover `delete_item` permissions check.
360
+ *
361
+ * @since 6.0.0
362
+ *
363
+ * @param bool|WP_Error $retval Returned value.
364
+ * @param WP_REST_Request $request The request sent to the API.
365
+ */
366
+ return apply_filters( 'bp_rest_attachments_group_cover_delete_item_permissions_check', $retval, $request );
367
+ }
368
+
369
+ /**
370
+ * Prepares group cover to return as an object.
371
+ *
372
+ * @since 6.0.0
373
+ *
374
+ * @param string $cover_url Group cover url.
375
+ * @param WP_REST_Request $request Full details about the request.
376
+ * @return WP_REST_Response
377
+ */
378
+ public function prepare_item_for_response( $cover_url, $request ) {
379
+ $data = array(
380
+ 'image' => $cover_url,
381
+ );
382
+
383
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
384
+ $data = $this->add_additional_fields_to_object( $data, $request );
385
+ $data = $this->filter_response_by_context( $data, $context );
386
+
387
+ // @todo add prepare_links
388
+ $response = rest_ensure_response( $data );
389
+
390
+ /**
391
+ * Filter a group cover value returned from the API.
392
+ *
393
+ * @since 6.0.0
394
+ *
395
+ * @param WP_REST_Response $response Response.
396
+ * @param WP_REST_Request $request Request used to generate the response.
397
+ * @param string $cover_url Group cover url.
398
+ */
399
+ return apply_filters( 'bp_rest_attachments_group_cover_prepare_value', $response, $request, $cover_url );
400
+ }
401
+
402
+ /**
403
+ * Get the plugin schema, conforming to JSON Schema.
404
+ *
405
+ * @since 6.0.0
406
+ *
407
+ * @return array
408
+ */
409
+ public function get_item_schema() {
410
+ $schema = array(
411
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
412
+ 'title' => 'bp_attachments_group_cover',
413
+ 'type' => 'object',
414
+ 'properties' => array(
415
+ 'image' => array(
416
+ 'context' => array( 'view', 'edit' ),
417
+ 'description' => __( 'Full size of the image file.', 'buddypress' ),
418
+ 'type' => 'string',
419
+ 'format' => 'uri',
420
+ 'readonly' => true,
421
+ ),
422
+ ),
423
+ );
424
+
425
+ /**
426
+ * Filters the group cover schema.
427
+ *
428
+ * @param string $schema The endpoint schema.
429
+ */
430
+ return apply_filters( 'bp_rest_attachments_group_cover_schema', $this->add_additional_fields_schema( $schema ) );
431
+ }
432
+ }
bp-groups/classes/class-bp-rest-group-invites-endpoint.php CHANGED
@@ -506,6 +506,8 @@ class BP_REST_Group_Invites_Endpoint extends WP_REST_Controller {
506
  * @return WP_REST_Response|WP_Error
507
  */
508
  public function update_item( $request ) {
 
 
509
  $invite = $this->fetch_single_invite( $request['invite_id'] );
510
  $accept = groups_accept_invite( $invite->user_id, $invite->item_id );
511
  if ( ! $accept ) {
@@ -518,9 +520,6 @@ class BP_REST_Group_Invites_Endpoint extends WP_REST_Controller {
518
  );
519
  }
520
 
521
- // Setting context.
522
- $request->set_param( 'context', 'edit' );
523
-
524
  $accepted_member = new BP_Groups_Member( $invite->user_id, $invite->item_id );
525
 
526
  $retval = array(
@@ -613,7 +612,6 @@ class BP_REST_Group_Invites_Endpoint extends WP_REST_Controller {
613
  * @return WP_REST_Response|WP_Error
614
  */
615
  public function delete_item( $request ) {
616
- // Setting context.
617
  $request->set_param( 'context', 'edit' );
618
 
619
  $user_id = bp_loggedin_user_id();
506
  * @return WP_REST_Response|WP_Error
507
  */
508
  public function update_item( $request ) {
509
+ $request->set_param( 'context', 'edit' );
510
+
511
  $invite = $this->fetch_single_invite( $request['invite_id'] );
512
  $accept = groups_accept_invite( $invite->user_id, $invite->item_id );
513
  if ( ! $accept ) {
520
  );
521
  }
522
 
 
 
 
523
  $accepted_member = new BP_Groups_Member( $invite->user_id, $invite->item_id );
524
 
525
  $retval = array(
612
  * @return WP_REST_Response|WP_Error
613
  */
614
  public function delete_item( $request ) {
 
615
  $request->set_param( 'context', 'edit' );
616
 
617
  $user_id = bp_loggedin_user_id();
bp-groups/classes/class-bp-rest-group-membership-endpoint.php CHANGED
@@ -223,7 +223,7 @@ class BP_REST_Group_Membership_Endpoint extends WP_REST_Controller {
223
  );
224
  }
225
 
226
- // Set the group member.
227
  $group_member = new BP_Groups_Member( $user->ID, $group->id );
228
  } else {
229
  $role = $request['role'];
@@ -334,28 +334,21 @@ class BP_REST_Group_Membership_Endpoint extends WP_REST_Controller {
334
  } else {
335
 
336
  $loggedin_user_id = bp_loggedin_user_id();
337
- if ( $loggedin_user_id === $user->ID && 'view' === $request['context'] ) {
338
-
339
- // Users may only freely join public groups.
340
- if ( true === $retval && (
341
- ! bp_current_user_can( 'groups_join_group', array( 'group_id' => $group->id ) )
342
- || groups_is_user_member( $loggedin_user_id, $group->id ) // As soon as they are not already members.
343
- || groups_is_user_banned( $loggedin_user_id, $group->id ) // And as soon as they are not banned from it.
344
- ) ) {
345
- $retval = new WP_Error(
346
- 'bp_rest_group_member_failed_to_join',
347
- __( 'Could not join the group.', 'buddypress' ),
348
- array(
349
- 'status' => 500,
350
- )
351
- );
352
- }
353
 
354
- if ( true === $retval ) {
355
- $retval = true;
356
- }
357
- } else {
358
- $retval = false;
 
 
 
 
 
 
 
 
 
359
  }
360
  }
361
 
@@ -794,6 +787,7 @@ class BP_REST_Group_Membership_Endpoint extends WP_REST_Controller {
794
  array(
795
  'description' => __( 'A unique numeric ID for the Member to add to the Group.', 'buddypress' ),
796
  'default' => bp_loggedin_user_id(),
 
797
  'readonly' => false,
798
  )
799
  );
@@ -842,30 +836,26 @@ class BP_REST_Group_Membership_Endpoint extends WP_REST_Controller {
842
 
843
  $schema['properties']['is_mod'] = array(
844
  'context' => array( 'view', 'edit' ),
845
- 'description' => __( '`1` if this member is a Group moderator, `0` otherwise.', 'buddypress' ),
846
- 'type' => 'integer',
847
- 'enum' => array( 0, 1 ),
848
  );
849
 
850
  $schema['properties']['is_banned'] = array(
851
  'context' => array( 'view', 'edit' ),
852
- 'description' => __( '`1` if this member has been banned from the Group, `0` otherwise.', 'buddypress' ),
853
- 'type' => 'integer',
854
- 'enum' => array( 0, 1 ),
855
  );
856
 
857
  $schema['properties']['is_admin'] = array(
858
  'context' => array( 'view', 'edit' ),
859
- 'description' => __( '`1` if this member is a Group administrator, `0` otherwise.', 'buddypress' ),
860
- 'type' => 'integer',
861
- 'enum' => array( 0, 1 ),
862
  );
863
 
864
  $schema['properties']['is_confirmed'] = array(
865
  'context' => array( 'view', 'edit' ),
866
- 'description' => __( '`1` if the membership of this user has been confirmed, `0` otherwise.', 'buddypress' ),
867
- 'type' => 'integer',
868
- 'enum' => array( 0, 1 ),
869
  );
870
 
871
  $schema['properties']['date_modified'] = array(
@@ -909,7 +899,7 @@ class BP_REST_Group_Membership_Endpoint extends WP_REST_Controller {
909
  );
910
 
911
  $params['roles'] = array(
912
- 'description' => __( 'Ensure result set includes specific Group roles.', 'buddypress' ),
913
  'default' => array(),
914
  'type' => 'array',
915
  'items' => array(
223
  );
224
  }
225
 
226
+ // Get the group member.
227
  $group_member = new BP_Groups_Member( $user->ID, $group->id );
228
  } else {
229
  $role = $request['role'];
334
  } else {
335
 
336
  $loggedin_user_id = bp_loggedin_user_id();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
337
 
338
+ // Users may only freely join public groups.
339
+ if ( true === $retval && (
340
+ ! bp_current_user_can( 'groups_join_group', array( 'group_id' => $group->id ) )
341
+ || groups_is_user_member( $loggedin_user_id, $group->id ) // As soon as they are not already members.
342
+ || groups_is_user_banned( $loggedin_user_id, $group->id ) // And as soon as they are not banned from it.
343
+ || $loggedin_user_id !== $user->ID // You can only add yourself to a group.
344
+ ) ) {
345
+ $retval = new WP_Error(
346
+ 'bp_rest_group_member_failed_to_join',
347
+ __( 'Could not join the group.', 'buddypress' ),
348
+ array(
349
+ 'status' => 500,
350
+ )
351
+ );
352
  }
353
  }
354
 
787
  array(
788
  'description' => __( 'A unique numeric ID for the Member to add to the Group.', 'buddypress' ),
789
  'default' => bp_loggedin_user_id(),
790
+ 'required' => true,
791
  'readonly' => false,
792
  )
793
  );
836
 
837
  $schema['properties']['is_mod'] = array(
838
  'context' => array( 'view', 'edit' ),
839
+ 'description' => __( 'Whether the member is a group moderator.', 'buddypress' ),
840
+ 'type' => 'boolean',
 
841
  );
842
 
843
  $schema['properties']['is_banned'] = array(
844
  'context' => array( 'view', 'edit' ),
845
+ 'description' => __( 'Whether the member has been banned from the group.', 'buddypress' ),
846
+ 'type' => 'boolean',
 
847
  );
848
 
849
  $schema['properties']['is_admin'] = array(
850
  'context' => array( 'view', 'edit' ),
851
+ 'description' => __( 'Whether the member is a group administrator.', 'buddypress' ),
852
+ 'type' => 'boolean',
 
853
  );
854
 
855
  $schema['properties']['is_confirmed'] = array(
856
  'context' => array( 'view', 'edit' ),
857
+ 'description' => __( 'Whether the membership of this user has been confirmed.', 'buddypress' ),
858
+ 'type' => 'boolean',
 
859
  );
860
 
861
  $schema['properties']['date_modified'] = array(
899
  );
900
 
901
  $params['roles'] = array(
902
+ 'description' => __( 'Ensure result set includes specific group roles.', 'buddypress' ),
903
  'default' => array(),
904
  'type' => 'array',
905
  'items' => array(
bp-groups/classes/class-bp-rest-groups-endpoint.php CHANGED
@@ -313,6 +313,11 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
313
  return $fields_update;
314
  }
315
 
 
 
 
 
 
316
  $retval = array(
317
  $this->prepare_response_for_collection(
318
  $this->prepare_item_for_response( $group, $request )
@@ -602,6 +607,7 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
602
  'name' => bp_get_group_name( $item ),
603
  'slug' => bp_get_group_slug( $item ),
604
  'status' => bp_get_group_status( $item ),
 
605
  'admins' => array(),
606
  'mods' => array(),
607
  'total_member_count' => null,
@@ -614,25 +620,30 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
614
  // Avatars.
615
  if ( ! empty( $schema['properties']['avatar_urls'] ) ) {
616
  $data['avatar_urls'] = array(
617
- 'thumb' => bp_core_fetch_avatar(
618
  array(
619
  'html' => false,
620
  'object' => 'group',
621
  'item_id' => $item->id,
622
- 'type' => 'thumb',
623
  )
624
  ),
625
- 'full' => bp_core_fetch_avatar(
626
  array(
627
  'html' => false,
628
  'object' => 'group',
629
  'item_id' => $item->id,
630
- 'type' => 'full',
631
  )
632
  ),
633
  );
634
  }
635
 
 
 
 
 
 
636
  $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
637
 
638
  // If this is the 'edit' context, fill in more details--similar to "populate_extras".
@@ -698,7 +709,7 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
698
  * @since 5.0.0
699
  *
700
  * @param WP_REST_Request $request Request object.
701
- * @return stdClass|WP_Error Object or WP_Error.
702
  */
703
  protected function prepare_item_for_database( $request ) {
704
  $prepared_group = new stdClass();
@@ -768,6 +779,16 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
768
  $prepared_group->parent_id = $request['parent_id'];
769
  }
770
 
 
 
 
 
 
 
 
 
 
 
771
  /**
772
  * Filters a group before it is inserted or updated via the REST API.
773
  *
@@ -922,6 +943,18 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
922
  $key = 'create_item';
923
  $args['description']['type'] = 'string';
924
 
 
 
 
 
 
 
 
 
 
 
 
 
925
  if ( WP_REST_Server::EDITABLE === $method ) {
926
  $key = 'update_item';
927
  unset( $args['slug'] );
@@ -1040,6 +1073,16 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
1040
  'type' => 'string',
1041
  'format' => 'date-time',
1042
  ),
 
 
 
 
 
 
 
 
 
 
1043
  'admins' => array(
1044
  'context' => array( 'edit' ),
1045
  'description' => __( 'Group administrators.', 'buddypress' ),
@@ -1079,7 +1122,7 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
1079
  $avatar_properties = array();
1080
 
1081
  $avatar_properties['full'] = array(
1082
- /* translators: Full image size for the group Avatar */
1083
  'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),
1084
  'type' => 'string',
1085
  'format' => 'uri',
@@ -1087,7 +1130,7 @@ class BP_REST_Groups_Endpoint extends WP_REST_Controller {
1087
  );
1088
 
1089
  $avatar_properties['thumb'] = array(
1090
- /* translators: Thumb imaze size for the group Avatar */
1091
  'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),
1092
  'type' => 'string',
1093
  'format' => 'uri',
313
  return $fields_update;
314
  }
315
 
316
+ // Set group type(s).
317
+ if ( ! empty( $request['types'] ) ) {
318
+ bp_groups_set_group_type( $group_id, $request['types'] );
319
+ }
320
+
321
  $retval = array(
322
  $this->prepare_response_for_collection(
323
  $this->prepare_item_for_response( $group, $request )
607
  'name' => bp_get_group_name( $item ),
608
  'slug' => bp_get_group_slug( $item ),
609
  'status' => bp_get_group_status( $item ),
610
+ 'types' => bp_groups_get_group_type( $item->id, false ),
611
  'admins' => array(),
612
  'mods' => array(),
613
  'total_member_count' => null,
620
  // Avatars.
621
  if ( ! empty( $schema['properties']['avatar_urls'] ) ) {
622
  $data['avatar_urls'] = array(
623
+ 'full' => bp_core_fetch_avatar(
624
  array(
625
  'html' => false,
626
  'object' => 'group',
627
  'item_id' => $item->id,
628
+ 'type' => 'full',
629
  )
630
  ),
631
+ 'thumb' => bp_core_fetch_avatar(
632
  array(
633
  'html' => false,
634
  'object' => 'group',
635
  'item_id' => $item->id,
636
+ 'type' => 'thumb',
637
  )
638
  ),
639
  );
640
  }
641
 
642
+ // Get group type(s).
643
+ if ( false === $data['types'] ) {
644
+ $data['types'] = array();
645
+ }
646
+
647
  $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
648
 
649
  // If this is the 'edit' context, fill in more details--similar to "populate_extras".
709
  * @since 5.0.0
710
  *
711
  * @param WP_REST_Request $request Request object.
712
+ * @return stdClass|WP_Error
713
  */
714
  protected function prepare_item_for_database( $request ) {
715
  $prepared_group = new stdClass();
779
  $prepared_group->parent_id = $request['parent_id'];
780
  }
781
 
782
+ // Update group type(s).
783
+ if ( isset( $prepared_group->group_id ) && isset( $request['types'] ) ) {
784
+
785
+ // Append on update. Add on creation.
786
+ $append = WP_REST_Server::EDITABLE === $request->get_method();
787
+
788
+ // Add/Append group type(s).
789
+ bp_groups_set_group_type( $prepared_group->group_id, $request['types'], $append );
790
+ }
791
+
792
  /**
793
  * Filters a group before it is inserted or updated via the REST API.
794
  *
943
  $key = 'create_item';
944
  $args['description']['type'] = 'string';
945
 
946
+ // Add group types.
947
+ $args['types'] = array(
948
+ 'description' => __( 'Set type(s) for a group.', 'buddypress' ),
949
+ 'type' => 'array',
950
+ 'enum' => bp_groups_get_group_types(),
951
+ 'sanitize_callback' => 'bp_rest_sanitize_group_types',
952
+ 'validate_callback' => 'bp_rest_validate_group_types',
953
+ 'items' => array(
954
+ 'type' => 'string',
955
+ ),
956
+ );
957
+
958
  if ( WP_REST_Server::EDITABLE === $method ) {
959
  $key = 'update_item';
960
  unset( $args['slug'] );
1073
  'type' => 'string',
1074
  'format' => 'date-time',
1075
  ),
1076
+ 'types' => array(
1077
+ 'context' => array( 'view', 'edit' ),
1078
+ 'description' => __( 'The type(s) of the Group.', 'buddypress' ),
1079
+ 'readonly' => true,
1080
+ 'enum' => bp_groups_get_group_types(),
1081
+ 'type' => 'array',
1082
+ 'items' => array(
1083
+ 'type' => 'string',
1084
+ ),
1085
+ ),
1086
  'admins' => array(
1087
  'context' => array( 'edit' ),
1088
  'description' => __( 'Group administrators.', 'buddypress' ),
1122
  $avatar_properties = array();
1123
 
1124
  $avatar_properties['full'] = array(
1125
+ /* translators: 1: Full avatar width in pixels. 2: Full avatar height in pixels */
1126
  'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),
1127
  'type' => 'string',
1128
  'format' => 'uri',
1130
  );
1131
 
1132
  $avatar_properties['thumb'] = array(
1133
+ /* translators: 1: Thumb avatar width in pixels. 2: Thumb avatar height in pixels */
1134
  'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),
1135
  'type' => 'string',
1136
  'format' => 'uri',
bp-groups/css/blocks/group-rtl.css ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* CSS for the bp/group block */
2
+ .bp-block-group {
3
+ position: relative;
4
+ }
5
+
6
+ .bp-block-group .group-content {
7
+ display: flex;
8
+ }
9
+
10
+ .bp-block-group.has-cover .group-content,
11
+ .bp-block-group.has-cover .item-header-avatar,
12
+ .bp-block-group.has-cover .group-description {
13
+ z-index: 2;
14
+ }
15
+
16
+ .bp-block-group .group-description {
17
+ width: 100%;
18
+ }
19
+
20
+ .bp-block-group.has-cover .group-description {
21
+ padding-top: 75px;
22
+ }
23
+
24
+ .bp-block-group.avatar-full .group-description {
25
+ padding-right: 35px;
26
+ }
27
+
28
+ .bp-block-group.has-cover .bp-group-cover-image {
29
+ background-color: #c5c5c5;
30
+ background-position: center top;
31
+ background-repeat: no-repeat;
32
+ background-size: cover;
33
+ border: 0;
34
+ display: block;
35
+ right: 0;
36
+ margin: 0;
37
+ padding: 0;
38
+ position: absolute;
39
+ top: 0;
40
+ width: 100%;
41
+ z-index: 1;
42
+ height: 150px;
43
+ }
44
+
45
+ .bp-block-group img.avatar {
46
+ width: auto;
47
+ height: auto;
48
+ }
49
+
50
+ .bp-block-group.avatar-none .item-header-avatar {
51
+ display: none;
52
+ }
53
+
54
+ .bp-block-group.avatar-none.has-cover {
55
+ min-height: 200px;
56
+ }
57
+
58
+ .bp-block-group.avatar-full {
59
+ min-height: 150px;
60
+ }
61
+
62
+ .bp-block-group.avatar-full.has-cover {
63
+ min-height: 300px;
64
+ }
65
+
66
+ .bp-block-group.avatar-full .item-header-avatar {
67
+ width: 180px;
68
+ }
69
+
70
+ .bp-block-group.has-cover.avatar-full .item-header-avatar {
71
+ width: 200px;
72
+ }
73
+
74
+ .bp-block-group.has-cover.avatar-full img.avatar {
75
+ border: solid 2px #fff;
76
+ background: rgba(255, 255, 255, 0.8);
77
+ margin-right: 20px;
78
+ }
79
+
80
+ .bp-block-group.has-cover .group-content {
81
+ padding-top: 75px;
82
+ }
83
+
84
+ .bp-block-group.avatar-thumb .item-header-avatar img.avatar {
85
+ margin-top: 15px;
86
+ }
87
+
88
+ .bp-block-group.avatar-thumb:not(.has-description) .group-content {
89
+ min-height: 50px;
90
+ align-items: center;
91
+ }
92
+
93
+ .bp-block-group .group-description-content {
94
+ width: 100%;
95
+ margin-bottom: 18px;
96
+ }
97
+
98
+ .bp-block-group.avatar-thumb .item-header-avatar {
99
+ width: 70px;
100
+ }
101
+
102
+ .bp-block-group.avatar-thumb.has-cover .item-header-avatar {
103
+ padding-top: 75px;
104
+ }
105
+
106
+ .bp-block-group .bp-profile-button {
107
+ width: 100%;
108
+ overflow: hidden;
109
+ }
110
+
111
+ .bp-block-group .bp-profile-button a.button {
112
+ margin: 18px 0 0;
113
+ }
114
+
115
+ .bp-block-group.has-description .bp-profile-button a.button {
116
+ display: block;
117
+ float: left;
118
+ }
bp-groups/css/blocks/group-rtl.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .bp-block-group{position:relative}.bp-block-group .group-content{display:flex}.bp-block-group.has-cover .group-content,.bp-block-group.has-cover .group-description,.bp-block-group.has-cover .item-header-avatar{z-index:2}.bp-block-group .group-description{width:100%}.bp-block-group.has-cover .group-description{padding-top:75px}.bp-block-group.avatar-full .group-description{padding-right:35px}.bp-block-group.has-cover .bp-group-cover-image{background-color:#c5c5c5;background-position:center top;background-repeat:no-repeat;background-size:cover;border:0;display:block;right:0;margin:0;padding:0;position:absolute;top:0;width:100%;z-index:1;height:150px}.bp-block-group img.avatar{width:auto;height:auto}.bp-block-group.avatar-none .item-header-avatar{display:none}.bp-block-group.avatar-none.has-cover{min-height:200px}.bp-block-group.avatar-full{min-height:150px}.bp-block-group.avatar-full.has-cover{min-height:300px}.bp-block-group.avatar-full .item-header-avatar{width:180px}.bp-block-group.has-cover.avatar-full .item-header-avatar{width:200px}.bp-block-group.has-cover.avatar-full img.avatar{border:solid 2px #fff;background:rgba(255,255,255,.8);margin-right:20px}.bp-block-group.has-cover .group-content{padding-top:75px}.bp-block-group.avatar-thumb .item-header-avatar img.avatar{margin-top:15px}.bp-block-group.avatar-thumb:not(.has-description) .group-content{min-height:50px;align-items:center}.bp-block-group .group-description-content{width:100%;margin-bottom:18px}.bp-block-group.avatar-thumb .item-header-avatar{width:70px}.bp-block-group.avatar-thumb.has-cover .item-header-avatar{padding-top:75px}.bp-block-group .bp-profile-button{width:100%;overflow:hidden}.bp-block-group .bp-profile-button a.button{margin:18px 0 0}.bp-block-group.has-description .bp-profile-button a.button{display:block;float:left}
bp-groups/css/blocks/group.css ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* CSS for the bp/group block */
2
+ .bp-block-group {
3
+ position: relative;
4
+ }
5
+
6
+ .bp-block-group .group-content {
7
+ display: flex;
8
+ }
9
+
10
+ .bp-block-group.has-cover .group-content,
11
+ .bp-block-group.has-cover .item-header-avatar,
12
+ .bp-block-group.has-cover .group-description {
13
+ z-index: 2;
14
+ }
15
+
16
+ .bp-block-group .group-description {
17
+ width: 100%;
18
+ }
19
+
20
+ .bp-block-group.has-cover .group-description {
21
+ padding-top: 75px;
22
+ }
23
+
24
+ .bp-block-group.avatar-full .group-description {
25
+ padding-left: 35px;
26
+ }
27
+
28
+ .bp-block-group.has-cover .bp-group-cover-image {
29
+ background-color: #c5c5c5;
30
+ background-position: center top;
31
+ background-repeat: no-repeat;
32
+ background-size: cover;
33
+ border: 0;
34
+ display: block;
35
+ left: 0;
36
+ margin: 0;
37
+ padding: 0;
38
+ position: absolute;
39
+ top: 0;
40
+ width: 100%;
41
+ z-index: 1;
42
+ height: 150px;
43
+ }
44
+
45
+ .bp-block-group img.avatar {
46
+ width: auto;
47
+ height: auto;
48
+ }
49
+
50
+ .bp-block-group.avatar-none .item-header-avatar {
51
+ display: none;
52
+ }
53
+
54
+ .bp-block-group.avatar-none.has-cover {
55
+ min-height: 200px;
56
+ }
57
+
58
+ .bp-block-group.avatar-full {
59
+ min-height: 150px;
60
+ }
61
+
62
+ .bp-block-group.avatar-full.has-cover {
63
+ min-height: 300px;
64
+ }
65
+
66
+ .bp-block-group.avatar-full .item-header-avatar {
67
+ width: 180px;
68
+ }
69
+
70
+ .bp-block-group.has-cover.avatar-full .item-header-avatar {
71
+ width: 200px;
72
+ }
73
+
74
+ .bp-block-group.has-cover.avatar-full img.avatar {
75
+ border: solid 2px #fff;
76
+ background: rgba(255, 255, 255, 0.8);
77
+ margin-left: 20px;
78
+ }
79
+
80
+ .bp-block-group.has-cover .group-content {
81
+ padding-top: 75px;
82
+ }
83
+
84
+ .bp-block-group.avatar-thumb .item-header-avatar img.avatar {
85
+ margin-top: 15px;
86
+ }
87
+
88
+ .bp-block-group.avatar-thumb:not(.has-description) .group-content {
89
+ min-height: 50px;
90
+ align-items: center;
91
+ }
92
+
93
+ .bp-block-group .group-description-content {
94
+ width: 100%;
95
+ margin-bottom: 18px;
96
+ }
97
+
98
+ .bp-block-group.avatar-thumb .item-header-avatar {
99
+ width: 70px;
100
+ }
101
+
102
+ .bp-block-group.avatar-thumb.has-cover .item-header-avatar {
103
+ padding-top: 75px;
104
+ }
105
+
106
+ .bp-block-group .bp-profile-button {
107
+ width: 100%;
108
+ overflow: hidden;
109
+ }
110
+
111
+ .bp-block-group .bp-profile-button a.button {
112
+ margin: 18px 0 0;
113
+ }
114
+
115
+ .bp-block-group.has-description .bp-profile-button a.button {
116
+ display: block;
117
+ float: right;
118
+ }
bp-groups/css/blocks/group.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .bp-block-group{position:relative}.bp-block-group .group-content{display:flex}.bp-block-group.has-cover .group-content,.bp-block-group.has-cover .group-description,.bp-block-group.has-cover .item-header-avatar{z-index:2}.bp-block-group .group-description{width:100%}.bp-block-group.has-cover .group-description{padding-top:75px}.bp-block-group.avatar-full .group-description{padding-left:35px}.bp-block-group.has-cover .bp-group-cover-image{background-color:#c5c5c5;background-position:center top;background-repeat:no-repeat;background-size:cover;border:0;display:block;left:0;margin:0;padding:0;position:absolute;top:0;width:100%;z-index:1;height:150px}.bp-block-group img.avatar{width:auto;height:auto}.bp-block-group.avatar-none .item-header-avatar{display:none}.bp-block-group.avatar-none.has-cover{min-height:200px}.bp-block-group.avatar-full{min-height:150px}.bp-block-group.avatar-full.has-cover{min-height:300px}.bp-block-group.avatar-full .item-header-avatar{width:180px}.bp-block-group.has-cover.avatar-full .item-header-avatar{width:200px}.bp-block-group.has-cover.avatar-full img.avatar{border:solid 2px #fff;background:rgba(255,255,255,.8);margin-left:20px}.bp-block-group.has-cover .group-content{padding-top:75px}.bp-block-group.avatar-thumb .item-header-avatar img.avatar{margin-top:15px}.bp-block-group.avatar-thumb:not(.has-description) .group-content{min-height:50px;align-items:center}.bp-block-group .group-description-content{width:100%;margin-bottom:18px}.bp-block-group.avatar-thumb .item-header-avatar{width:70px}.bp-block-group.avatar-thumb.has-cover .item-header-avatar{padding-top:75px}.bp-block-group .bp-profile-button{width:100%;overflow:hidden}.bp-block-group .bp-profile-button a.button{margin:18px 0 0}.bp-block-group.has-description .bp-profile-button a.button{display:block;float:right}
bp-groups/js/blocks/group.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;c<t.length;c++)try{f(t[c])}catch(e){i||(i=e)}if(t.length){var l=f(t[t.length-1]);"object"==typeof exports&&"undefined"!=typeof module?module.exports=l:"function"==typeof define&&define.amd?define(function(){return l}):n&&(this[n]=l)}if(parcelRequire=f,i)throw i;return f}({"pvse":[function(require,module,exports) {
2
+ var e=wp.blocks.registerBlockType,t=wp.element,o=t.createElement,s=t.Fragment,r=wp.components,n=r.Placeholder,i=r.Disabled,l=r.PanelBody,p=r.SelectControl,a=r.ToggleControl,u=r.Toolbar,d=r.ToolbarButton,b=wp.blockEditor,c=b.InspectorControls,g=b.BlockControls,y=wp.data.withSelect,h=wp.compose.compose,m=wp.editor.ServerSideRender,v=wp.i18n.__,C=bp.blockComponents.AutoCompleter,f=[{label:v("None","buddypress"),value:"none"},{label:v("Thumb","buddypress"),value:"thumb"},{label:v("Full","buddypress"),value:"full"}],S=function(e){var t=e.attributes,r=e.setAttributes,b=e.bpSettings,y=b.isAvatarEnabled,h=b.isCoverImageEnabled,S=t.avatarSize,I=t.displayDescription,k=t.displayActionButton,D=t.displayCoverImage;return t.itemID?o(s,null,o(g,null,o(u,null,o(d,{icon:"edit",title:v("Select another group","buddypress"),onClick:function(){r({itemID:0})}}))),o(c,null,o(l,{title:v("Group's home button settings","buddypress"),initialOpen:!0},o(a,{label:v("Display Group's home button","buddypress"),checked:!!k,onChange:function(){r({displayActionButton:!k})},help:v(k?"Include a link to the group's home page under their name.":"Toggle to display a link to the group's home page under their name.","buddypress")})),o(l,{title:v("Description settings","buddypress"),initialOpen:!1},o(a,{label:v("Display group's description","buddypress"),checked:!!I,onChange:function(){r({displayDescription:!I})},help:v(I?"Include the group's description under their name.":"Toggle to display the group's description under their name.","buddypress")})),y&&o(l,{title:v("Avatar settings","buddypress"),initialOpen:!1},o(p,{label:v("Size","buddypress"),value:S,options:f,onChange:function(e){r({avatarSize:e})}})),h&&o(l,{title:v("Cover image settings","buddypress"),initialOpen:!1},o(a,{label:v("Display Cover Image","buddypress"),checked:!!D,onChange:function(){r({displayCoverImage:!D})},help:v(D?"Include the group's cover image over their name.":"Toggle to display the group's cover image over their name.","buddypress")}))),o(i,null,o(m,{block:"bp/group",attributes:t}))):o(n,{icon:"buddicons-groups",label:v("BuddyPress Group","buddypress"),instructions:v("Start typing the name of the group you want to feature into this post.","buddypress")},o(C,{component:"groups",objectStatus:"public",ariaLabel:v("Group's name","buddypress"),placeholder:v("Enter Group's name here…","buddypress"),onSelectItem:r,useAvatar:y}))},I=h([y(function(e){return{bpSettings:e("core/editor").getEditorSettings().bp.groups||{}}})])(S);e("bp/group",{title:v("Group","buddypress"),description:v("BuddyPress Group.","buddypress"),icon:"buddicons-groups",category:"buddypress",attributes:{itemID:{type:"integer",default:0},avatarSize:{type:"string",default:"full"},displayDescription:{type:"boolean",default:!0},displayActionButton:{type:"boolean",default:!0},displayCoverImage:{type:"boolean",default:!0}},edit:I});
3
+ },{}]},{},["pvse"], null)
bp-groups/js/manage-members.js CHANGED
@@ -162,7 +162,7 @@
162
 
163
  bp.Views.GroupRolesDropDown = bp.View.extend( {
164
  tagName: 'select',
165
- filters: _.extend( { all: { name: 'All members' } }, bpGroupManageMembersSettings.roles ),
166
 
167
  events: {
168
  change: 'change'
162
 
163
  bp.Views.GroupRolesDropDown = bp.View.extend( {
164
  tagName: 'select',
165
+ filters: _.extend( { all: { name: bpGroupManageMembersSettings.strings.allMembers } }, bpGroupManageMembersSettings.roles ),
166
 
167
  events: {
168
  change: 'change'
bp-groups/js/manage-members.min.js CHANGED
@@ -1 +1 @@
1
- !function(e,t,i){"undefined"!=typeof bpGroupManageMembersSettings&&t.isRestEnabled&&(_.extend(t,_.pick(e,"Backbone","template")),t.Models=t.Models||{},t.Collections=t.Collections||{},t.Views=t.Views||{},t.Models.groupMember=Backbone.Model.extend({defaults:{id:0,name:"",avatar_urls:{},is_admin:!1,is_banned:!1,is_confirmed:!1,is_mod:!1,link:""},options:{path:bpGroupManageMembersSettings.path,type:"POST",data:{},dataType:"json"},initialize:function(){this.on("sync",this.resetRequestOptions,this)},resetRequestOptions:function(){this.options.data={},this.options.path=bpGroupManageMembersSettings.path},sync:function(e,i,s){(s=s||{}).context=this;var r=s.data||{};if(this.options.path=this.options.path.concat("/"+i.get("id")),_.extend(s,this.options),_.extend(s.data,r),"delete"===e||"update"===e)return s.headers="delete"===e?{"X-HTTP-Method-Override":"DELETE"}:{"X-HTTP-Method-Override":"PUT"},t.apiRequest(s)},parse:function(e){return _.isArray(e)&&(e=_.first(e)),e}}),t.Collections.groupMembers=Backbone.Collection.extend({model:t.Models.groupMember,options:{path:bpGroupManageMembersSettings.path,type:"GET",data:{},dataType:"json"},initialize:function(){this.on("reset",function(){this.options.data={}},this)},sync:function(e,i,s){(s=s||{}).context=this;var r=s.data||{};if(_.extend(s,this.options),_.extend(s.data,r),"read"===e){var o=this,n=s.success;return s.success=function(e,t,i){if(_.isUndefined(i)||(o.totalPages=parseInt(i.getResponseHeader("X-WP-TotalPages"),10),o.totalGroupMembers=parseInt(i.getResponseHeader("X-WP-Total"),10)),o.currentPage=s.data.page||1,n)return n.apply(this,arguments)},t.apiRequest(s)}}}),t.View=t.View||t.Backbone.View.extend({prepare:function(){return!_.isUndefined(this.model)&&_.isFunction(this.model.toJSON)?this.model.toJSON():{}}}),t.Views.GroupMemberUpdatingInfo=t.View.extend({tagName:"p",template:t.template("bp-manage-members-updating"),initialize:function(){this.model=new Backbone.Model({type:this.options.value})}}),t.Views.GroupMemberErrorInfo=t.View.extend({tagName:"p",template:t.template("bp-manage-members-error"),initialize:function(){this.model=new Backbone.Model({message:this.options.value})}}),t.Views.GroupsMembersLabel=t.Views.GroupMemberUpdatingInfo.extend({tagName:"label",template:t.template("bp-manage-members-label")}),t.Views.GroupRolesDropDown=t.View.extend({tagName:"select",filters:_.extend({all:{name:"All members"}},bpGroupManageMembersSettings.roles),events:{change:"change"},initialize:function(){this.options.omits&&(this.filters=_.omit(this.filters,this.options.omits)),this.$el.html(_.chain(this.filters).map(function(e,t){var s=i("<option></option>").val(t).html(e.name)[0];return this.options.currentRole&&t===this.options.currentRole?{el:i(s).prop("selected",!0)}:{el:s}},this).pluck("el").value())},change:function(e){var t=i(e.target).val(),s={roles:[t]};this.collection&&("all"===t?(this.collection.currentRole="",s={exclude_admins:!1}):this.collection.currentRole=t,this.collection.currentPage=1,s.page=1,i("#manage-members-search").val(""),this.collection.fetch({data:s,reset:!0}))}}),t.Views.GroupMembersSearch=t.View.extend({className:"bp-dir-search-form",tagName:"form",template:t.template("bp-manage-members-search"),events:{"click #manage-members-search-submit":"searchMember"},searchMember:function(e){e.preventDefault();var t=i("#manage-members-search").val(),s=_.extend(this.collection.options.data,{search:t,page:1});this.collection.currentPage=1,this.collection.currentRole?s.roles=[this.collection.currentRole]:s.exclude_admins=!1,this.collection.fetch({data:s,reset:!0})}}),t.Views.GroupsMembersPagination=t.View.extend({className:"bp-pagination",template:t.template("bp-manage-members-paginate"),events:{"click .group-members-paginate-button":"queryPage"},initialize:function(){this.collection.on("reset",this.setPagination,this)},setPagination:function(e){var t=_.pick(e,["currentPage","totalGroupMembers","totalPages"]);t.totalPages>1&&(t.nextPage=t.currentPage+1,t.prevPage=t.currentPage-1),this.model=new Backbone.Model(t),this.render()},queryPage:function(e){e.preventDefault();var t=i(e.currentTarget).data("page"),s=i("#manage-members-search").val(),r=_.extend(this.collection.options.data,{search:s,page:t});this.collection.currentRole?r.roles=[this.collection.currentRole]:r.exclude_admins=!1,this.collection.fetch({data:r,reset:!0})}}),t.Views.GroupMembersNoMatches=t.View.extend({tagName:"tr",template:t.template("bp-manage-members-empty-row")}),t.Views.GroupMembersListRow=t.View.extend({tagName:"tr",template:t.template("bp-manage-members-row"),events:{"click .group-member-actions a":"doMemberAction","change .group-member-edit select":"editMemberRole"},initialize:function(){var e=["is_admin","is_banned","is_confirmed","is_mod"],t=this;_.each(bpGroupManageMembersSettings.roles,function(i){_.isMatch(t.model.attributes,_.pick(i,e))&&t.model.set("role",_.pick(i,["id","name"]),{silent:!0})}),this.model.collection.on("reset",this.clearRow,this)},clearRow:function(){this.views.view.remove()},renderEditForm:function(){var e=this.model.get("id");this.render(),this.views.set("#edit-group-member-"+e,[new t.Views.GroupsMembersLabel({value:e,attributes:{for:"group-member"+e+"-role"}}),new t.Views.GroupRolesDropDown({id:"group-member"+e+"-role",omits:["all","banned"],currentRole:this.model.get("role").id}).render()])},resetRow:function(){return this.model.set("editing",!1),this.render()},getRoleObject:function(e){var t=bpGroupManageMembersSettings.roles;return _.isUndefined(t[e])?{}:_.extend({role:_.pick(t[e],["id","name"])},_.pick(t[e],["is_admin","is_banned","is_confirmed","is_mod"]))},doMemberAction:function(e){e.preventDefault();var s=i(e.target).data("action"),r=this;if("edit"===s)return this.model.set("editing",!0),this.renderEditForm();if("abort"===s)return this.resetRow();if("ban"===s||"unban"===s){var o="ban"===s?"banned":"member",n=this.getRoleObject(o);if(!n)return this.resetRow();this.model.set("managingBan",!0),this.render(),this.views.set("#edit-group-member-"+this.model.get("id"),new t.Views.GroupMemberUpdatingInfo({value:s}).render()),this.model.save(n,{wait:!0,data:{action:s},success:function(e){return r.model.collection.remove(e),r.clearRow()},error:function(e,i){r.views.set("#edit-group-member-"+e.get("id"),new t.Views.GroupMemberErrorInfo({value:i.responseJSON.message}).render()),e.resetRequestOptions(),e.set("managingBan",!1)}})}else"remove"===s&&(this.model.set("removing",!0),this.render(),this.views.set("#edit-group-member-"+this.model.get("id"),new t.Views.GroupMemberUpdatingInfo({value:s}).render()),this.model.destroy({wait:!0,data:{},success:function(){return r.clearRow()},error:function(e,i){r.views.set("#edit-group-member-"+e.get("id"),new t.Views.GroupMemberErrorInfo({value:i.responseJSON.message}).render()),e.resetRequestOptions(),e.set("removing",!1)}}))},editMemberRole:function(e){var s=i(e.target).val(),r=this.getRoleObject(s),o=this.model.get("role").id,n="promote",a=this;if(s===this.model.get("role").id||!r)return this.resetRow();this.views.set("#edit-group-member-"+this.model.get("id"),(new t.Views.GroupMemberUpdatingInfo).render()),("admin"===o||"mod"===o&&"member"===s)&&(n="demote"),this.model.save(r,{wait:!0,data:{action:n,role:s},success:function(e){return a.model.collection.currentRole&&s!==a.model.collection.currentRole?(a.model.collection.remove(e),a.clearRow()):a.resetRow()},error:function(e,i){a.views.set("#edit-group-member-"+e.get("id"),new t.Views.GroupMemberErrorInfo({value:i.responseJSON.message}).render()),e.resetRequestOptions(),e.set("editing",!1)}})}}),t.Views.GroupMembersListHeader=t.View.extend({tagName:"thead",template:t.template("bp-manage-members-header")}),t.Views.GroupMembersListTable=t.View.extend({tagName:"tbody",initialize:function(){var e=bpGroupManageMembersSettings.preloaded||{},i=[];this.collection.on("reset",this.addListTableRows,this),e.body&&e.body.length>0?(_.each(e.body,function(e){i.push(new t.Models.groupMember(e))}),this.collection.currentPage=1,e.headers&&e.headers["X-WP-TotalPages"]&&(this.collection.totalPages=parseInt(e.headers["X-WP-TotalPages"],10)),e.headers&&e.headers["X-WP-Total"]&&(this.collection.totalGroupMembers=parseInt(e.headers["X-WP-Total"],10)),this.collection.reset(i)):this.collection.fetch({data:{exclude_admins:!1},reset:!0})},addListTableRows:function(e){if(this.views._views){var i=_.findWhere(this.views._views[""],{id:"bp-no-group-members"});i&&i.remove()}e.length?_.each(e.models,function(e){this.views.add(new t.Views.GroupMembersListRow({model:e}))},this):this.views.add(new t.Views.GroupMembersNoMatches({id:"bp-no-group-members"}))}}),t.Views.GroupMembersUI=t.View.extend({className:"group-members",initialize:function(){var e=new t.Collections.groupMembers;this.views.set("#group-roles-filter",[new t.Views.GroupsMembersLabel({attributes:{for:"group-members-role-filter"}}),new t.Views.GroupRolesDropDown({id:"group-members-role-filter",collection:e})]),this.views.set("#group-members-search-form",new t.Views.GroupMembersSearch({id:"group-members-search",collection:e})),this.views.set("#group-members-pagination",new t.Views.GroupsMembersPagination({collection:e})),this.views.set("#group-members-list-table",[new t.Views.GroupMembersListHeader,new t.Views.GroupMembersListTable({collection:e})])}}),t.manageGroupMembersUI=new t.Views.GroupMembersUI({el:"#group-manage-members-ui"}).render())}(window.wp||{},window.bp||{},jQuery);
1
+ !function(e,t,i){"undefined"!=typeof bpGroupManageMembersSettings&&t.isRestEnabled&&(_.extend(t,_.pick(e,"Backbone","template")),t.Models=t.Models||{},t.Collections=t.Collections||{},t.Views=t.Views||{},t.Models.groupMember=Backbone.Model.extend({defaults:{id:0,name:"",avatar_urls:{},is_admin:!1,is_banned:!1,is_confirmed:!1,is_mod:!1,link:""},options:{path:bpGroupManageMembersSettings.path,type:"POST",data:{},dataType:"json"},initialize:function(){this.on("sync",this.resetRequestOptions,this)},resetRequestOptions:function(){this.options.data={},this.options.path=bpGroupManageMembersSettings.path},sync:function(e,i,s){(s=s||{}).context=this;var r=s.data||{};if(this.options.path=this.options.path.concat("/"+i.get("id")),_.extend(s,this.options),_.extend(s.data,r),"delete"===e||"update"===e)return s.headers="delete"===e?{"X-HTTP-Method-Override":"DELETE"}:{"X-HTTP-Method-Override":"PUT"},t.apiRequest(s)},parse:function(e){return _.isArray(e)&&(e=_.first(e)),e}}),t.Collections.groupMembers=Backbone.Collection.extend({model:t.Models.groupMember,options:{path:bpGroupManageMembersSettings.path,type:"GET",data:{},dataType:"json"},initialize:function(){this.on("reset",function(){this.options.data={}},this)},sync:function(e,i,s){(s=s||{}).context=this;var r=s.data||{};if(_.extend(s,this.options),_.extend(s.data,r),"read"===e){var o=this,n=s.success;return s.success=function(e,t,i){if(_.isUndefined(i)||(o.totalPages=parseInt(i.getResponseHeader("X-WP-TotalPages"),10),o.totalGroupMembers=parseInt(i.getResponseHeader("X-WP-Total"),10)),o.currentPage=s.data.page||1,n)return n.apply(this,arguments)},t.apiRequest(s)}}}),t.View=t.View||t.Backbone.View.extend({prepare:function(){return!_.isUndefined(this.model)&&_.isFunction(this.model.toJSON)?this.model.toJSON():{}}}),t.Views.GroupMemberUpdatingInfo=t.View.extend({tagName:"p",template:t.template("bp-manage-members-updating"),initialize:function(){this.model=new Backbone.Model({type:this.options.value})}}),t.Views.GroupMemberErrorInfo=t.View.extend({tagName:"p",template:t.template("bp-manage-members-error"),initialize:function(){this.model=new Backbone.Model({message:this.options.value})}}),t.Views.GroupsMembersLabel=t.Views.GroupMemberUpdatingInfo.extend({tagName:"label",template:t.template("bp-manage-members-label")}),t.Views.GroupRolesDropDown=t.View.extend({tagName:"select",filters:_.extend({all:{name:bpGroupManageMembersSettings.strings.allMembers}},bpGroupManageMembersSettings.roles),events:{change:"change"},initialize:function(){this.options.omits&&(this.filters=_.omit(this.filters,this.options.omits)),this.$el.html(_.chain(this.filters).map(function(e,t){var s=i("<option></option>").val(t).html(e.name)[0];return this.options.currentRole&&t===this.options.currentRole?{el:i(s).prop("selected",!0)}:{el:s}},this).pluck("el").value())},change:function(e){var t=i(e.target).val(),s={roles:[t]};this.collection&&("all"===t?(this.collection.currentRole="",s={exclude_admins:!1}):this.collection.currentRole=t,this.collection.currentPage=1,s.page=1,i("#manage-members-search").val(""),this.collection.fetch({data:s,reset:!0}))}}),t.Views.GroupMembersSearch=t.View.extend({className:"bp-dir-search-form",tagName:"form",template:t.template("bp-manage-members-search"),events:{"click #manage-members-search-submit":"searchMember"},searchMember:function(e){e.preventDefault();var t=i("#manage-members-search").val(),s=_.extend(this.collection.options.data,{search:t,page:1});this.collection.currentPage=1,this.collection.currentRole?s.roles=[this.collection.currentRole]:s.exclude_admins=!1,this.collection.fetch({data:s,reset:!0})}}),t.Views.GroupsMembersPagination=t.View.extend({className:"bp-pagination",template:t.template("bp-manage-members-paginate"),events:{"click .group-members-paginate-button":"queryPage"},initialize:function(){this.collection.on("reset",this.setPagination,this)},setPagination:function(e){var t=_.pick(e,["currentPage","totalGroupMembers","totalPages"]);t.totalPages>1&&(t.nextPage=t.currentPage+1,t.prevPage=t.currentPage-1),this.model=new Backbone.Model(t),this.render()},queryPage:function(e){e.preventDefault();var t=i(e.currentTarget).data("page"),s=i("#manage-members-search").val(),r=_.extend(this.collection.options.data,{search:s,page:t});this.collection.currentRole?r.roles=[this.collection.currentRole]:r.exclude_admins=!1,this.collection.fetch({data:r,reset:!0})}}),t.Views.GroupMembersNoMatches=t.View.extend({tagName:"tr",template:t.template("bp-manage-members-empty-row")}),t.Views.GroupMembersListRow=t.View.extend({tagName:"tr",template:t.template("bp-manage-members-row"),events:{"click .group-member-actions a":"doMemberAction","change .group-member-edit select":"editMemberRole"},initialize:function(){var e=["is_admin","is_banned","is_confirmed","is_mod"],t=this;_.each(bpGroupManageMembersSettings.roles,function(i){_.isMatch(t.model.attributes,_.pick(i,e))&&t.model.set("role",_.pick(i,["id","name"]),{silent:!0})}),this.model.collection.on("reset",this.clearRow,this)},clearRow:function(){this.views.view.remove()},renderEditForm:function(){var e=this.model.get("id");this.render(),this.views.set("#edit-group-member-"+e,[new t.Views.GroupsMembersLabel({value:e,attributes:{for:"group-member"+e+"-role"}}),new t.Views.GroupRolesDropDown({id:"group-member"+e+"-role",omits:["all","banned"],currentRole:this.model.get("role").id}).render()])},resetRow:function(){return this.model.set("editing",!1),this.render()},getRoleObject:function(e){var t=bpGroupManageMembersSettings.roles;return _.isUndefined(t[e])?{}:_.extend({role:_.pick(t[e],["id","name"])},_.pick(t[e],["is_admin","is_banned","is_confirmed","is_mod"]))},doMemberAction:function(e){e.preventDefault();var s=i(e.target).data("action"),r=this;if("edit"===s)return this.model.set("editing",!0),this.renderEditForm();if("abort"===s)return this.resetRow();if("ban"===s||"unban"===s){var o="ban"===s?"banned":"member",n=this.getRoleObject(o);if(!n)return this.resetRow();this.model.set("managingBan",!0),this.render(),this.views.set("#edit-group-member-"+this.model.get("id"),new t.Views.GroupMemberUpdatingInfo({value:s}).render()),this.model.save(n,{wait:!0,data:{action:s},success:function(e){return r.model.collection.remove(e),r.clearRow()},error:function(e,i){r.views.set("#edit-group-member-"+e.get("id"),new t.Views.GroupMemberErrorInfo({value:i.responseJSON.message}).render()),e.resetRequestOptions(),e.set("managingBan",!1)}})}else"remove"===s&&(this.model.set("removing",!0),this.render(),this.views.set("#edit-group-member-"+this.model.get("id"),new t.Views.GroupMemberUpdatingInfo({value:s}).render()),this.model.destroy({wait:!0,data:{},success:function(){return r.clearRow()},error:function(e,i){r.views.set("#edit-group-member-"+e.get("id"),new t.Views.GroupMemberErrorInfo({value:i.responseJSON.message}).render()),e.resetRequestOptions(),e.set("removing",!1)}}))},editMemberRole:function(e){var s=i(e.target).val(),r=this.getRoleObject(s),o=this.model.get("role").id,n="promote",a=this;if(s===this.model.get("role").id||!r)return this.resetRow();this.views.set("#edit-group-member-"+this.model.get("id"),(new t.Views.GroupMemberUpdatingInfo).render()),("admin"===o||"mod"===o&&"member"===s)&&(n="demote"),this.model.save(r,{wait:!0,data:{action:n,role:s},success:function(e){return a.model.collection.currentRole&&s!==a.model.collection.currentRole?(a.model.collection.remove(e),a.clearRow()):a.resetRow()},error:function(e,i){a.views.set("#edit-group-member-"+e.get("id"),new t.Views.GroupMemberErrorInfo({value:i.responseJSON.message}).render()),e.resetRequestOptions(),e.set("editing",!1)}})}}),t.Views.GroupMembersListHeader=t.View.extend({tagName:"thead",template:t.template("bp-manage-members-header")}),t.Views.GroupMembersListTable=t.View.extend({tagName:"tbody",initialize:function(){var e=bpGroupManageMembersSettings.preloaded||{},i=[];this.collection.on("reset",this.addListTableRows,this),e.body&&e.body.length>0?(_.each(e.body,function(e){i.push(new t.Models.groupMember(e))}),this.collection.currentPage=1,e.headers&&e.headers["X-WP-TotalPages"]&&(this.collection.totalPages=parseInt(e.headers["X-WP-TotalPages"],10)),e.headers&&e.headers["X-WP-Total"]&&(this.collection.totalGroupMembers=parseInt(e.headers["X-WP-Total"],10)),this.collection.reset(i)):this.collection.fetch({data:{exclude_admins:!1},reset:!0})},addListTableRows:function(e){if(this.views._views){var i=_.findWhere(this.views._views[""],{id:"bp-no-group-members"});i&&i.remove()}e.length?_.each(e.models,function(e){this.views.add(new t.Views.GroupMembersListRow({model:e}))},this):this.views.add(new t.Views.GroupMembersNoMatches({id:"bp-no-group-members"}))}}),t.Views.GroupMembersUI=t.View.extend({className:"group-members",initialize:function(){var e=new t.Collections.groupMembers;this.views.set("#group-roles-filter",[new t.Views.GroupsMembersLabel({attributes:{for:"group-members-role-filter"}}),new t.Views.GroupRolesDropDown({id:"group-members-role-filter",collection:e})]),this.views.set("#group-members-search-form",new t.Views.GroupMembersSearch({id:"group-members-search",collection:e})),this.views.set("#group-members-pagination",new t.Views.GroupsMembersPagination({collection:e})),this.views.set("#group-members-list-table",[new t.Views.GroupMembersListHeader,new t.Views.GroupMembersListTable({collection:e})])}}),t.manageGroupMembersUI=new t.Views.GroupMembersUI({el:"#group-manage-members-ui"}).render())}(window.wp||{},window.bp||{},jQuery);
bp-groups/screens/user/invites.php CHANGED
@@ -17,8 +17,9 @@ function groups_screen_group_invites() {
17
 
18
  if ( bp_is_action_variable( 'accept' ) && is_numeric( $group_id ) ) {
19
  // Check the nonce.
20
- if ( !check_admin_referer( 'groups_accept_invite' ) )
21
  return false;
 
22
 
23
  if ( !groups_accept_invite( bp_loggedin_user_id(), $group_id ) ) {
24
  bp_core_add_message( __('Group invite could not be accepted', 'buddypress'), 'error' );
@@ -26,6 +27,7 @@ function groups_screen_group_invites() {
26
  // Record this in activity streams.
27
  $group = groups_get_group( $group_id );
28
 
 
29
  bp_core_add_message( sprintf( __( 'Group invite accepted. Visit %s.', 'buddypress' ), bp_get_group_link( $group ) ) );
30
 
31
  if ( bp_is_active( 'activity' ) ) {
@@ -81,4 +83,4 @@ function groups_screen_group_invites() {
81
  * @param string $value Path to a users Groups > Invites page template.
82
  */
83
  bp_core_load_template( apply_filters( 'groups_template_group_invites', 'members/single/home' ) );
84
- }
17
 
18
  if ( bp_is_action_variable( 'accept' ) && is_numeric( $group_id ) ) {
19
  // Check the nonce.
20
+ if ( ! check_admin_referer( 'groups_accept_invite' ) ) {
21
  return false;
22
+ }
23
 
24
  if ( !groups_accept_invite( bp_loggedin_user_id(), $group_id ) ) {
25
  bp_core_add_message( __('Group invite could not be accepted', 'buddypress'), 'error' );
27
  // Record this in activity streams.
28
  $group = groups_get_group( $group_id );
29
 
30
+ /* translators: %s: group link */
31
  bp_core_add_message( sprintf( __( 'Group invite accepted. Visit %s.', 'buddypress' ), bp_get_group_link( $group ) ) );
32
 
33
  if ( bp_is_active( 'activity' ) ) {
83
  * @param string $value Path to a users Groups > Invites page template.
84
  */
85
  bp_core_load_template( apply_filters( 'groups_template_group_invites', 'members/single/home' ) );
86
+ }
bp-loader.php CHANGED
@@ -15,7 +15,7 @@
15
  * Description: BuddyPress adds community features to WordPress. Member Profiles, Activity Streams, Direct Messaging, Notifications, and more!
16
  * Author: The BuddyPress Community
17
  * Author URI: https://buddypress.org/
18
- * Version: 5.1.2
19
  * Text Domain: buddypress
20
  * Domain Path: /bp-languages/
21
  * License: GPLv2 or later (license.txt)
@@ -26,7 +26,7 @@
26
  * PHP supported by WordPress.
27
  */
28
 
29
- // Exit if accessed directly
30
  defined( 'ABSPATH' ) || exit;
31
 
32
  // Required PHP version.
@@ -85,7 +85,7 @@ if ( version_compare( phpversion(), BP_REQUIRED_PHP_VERSION, '<' ) ) {
85
  if ( defined( 'BUDDYPRESS_LATE_LOAD' ) ) {
86
  add_action( 'plugins_loaded', 'buddypress', (int) BUDDYPRESS_LATE_LOAD );
87
 
88
- // "And now here's something we hope you'll really like!"
89
  } else {
90
  $GLOBALS['bp'] = buddypress();
91
  }
15
  * Description: BuddyPress adds community features to WordPress. Member Profiles, Activity Streams, Direct Messaging, Notifications, and more!
16
  * Author: The BuddyPress Community
17
  * Author URI: https://buddypress.org/
18
+ * Version: 6.0.0-beta1
19
  * Text Domain: buddypress
20
  * Domain Path: /bp-languages/
21
  * License: GPLv2 or later (license.txt)
26
  * PHP supported by WordPress.
27
  */
28
 
29
+ // Exit if accessed directly.
30
  defined( 'ABSPATH' ) || exit;
31
 
32
  // Required PHP version.
85
  if ( defined( 'BUDDYPRESS_LATE_LOAD' ) ) {
86
  add_action( 'plugins_loaded', 'buddypress', (int) BUDDYPRESS_LATE_LOAD );
87
 
88
+ // "And now here's something we hope you'll really like!".
89
  } else {
90
  $GLOBALS['bp'] = buddypress();
91
  }
{bp-xprofile → bp-members}/actions/delete-avatar.php RENAMED
@@ -1,10 +1,10 @@
1
  <?php
2
  /**
3
- * XProfile: Avatar deletion action handler
4
  *
5
  * @package BuddyPress
6
- * @subpackage XProfileActions
7
- * @since 3.0.0
8
  */
9
 
10
  /**
@@ -13,10 +13,9 @@
13
  *
14
  * The function will delete the active avatar for a user.
15
  *
16
- * @since 1.0.0
17
- *
18
  */
19
- function xprofile_action_delete_avatar() {
20
 
21
  if ( ! bp_is_user_change_avatar() || ! bp_is_action_variable( 'delete-avatar', 0 ) ) {
22
  return false;
@@ -37,4 +36,4 @@ function xprofile_action_delete_avatar() {
37
 
38
  bp_core_redirect( wp_get_referer() );
39
  }
40
- add_action( 'bp_actions', 'xprofile_action_delete_avatar' );
1
  <?php
2
  /**
3
+ * Members: Avatar deletion action handler
4
  *
5
  * @package BuddyPress
6
+ * @subpackage MembersActions
7
+ * @since 6.0.0
8
  */
9
 
10
  /**
13
  *
14
  * The function will delete the active avatar for a user.
15
  *
16
+ * @since 6.0.0
 
17
  */
18
+ function bp_members_action_delete_avatar() {
19
 
20
  if ( ! bp_is_user_change_avatar() || ! bp_is_action_variable( 'delete-avatar', 0 ) ) {
21
  return false;
36
 
37
  bp_core_redirect( wp_get_referer() );
38
  }
39
+ add_action( 'bp_actions', 'bp_members_action_delete_avatar' );
bp-members/admin/css/admin-rtl.css CHANGED
@@ -29,8 +29,8 @@ div#community-profile-page li.bp-members-profile-stats:before,
29
  div#community-profile-page li.bp-friends-profile-stats:before,
30
  div#community-profile-page li.bp-groups-profile-stats:before,
31
  div#community-profile-page li.bp-blogs-profile-stats:before,
32
- div#community-profile-page a.bp-xprofile-avatar-user-admin:before,
33
- div#community-profile-page a.bp-xprofile-avatar-user-edit:before {
34
  font: 400 20px/1 dashicons;
35
  speak: none;
36
  display: inline-block;
@@ -61,25 +61,25 @@ div#community-profile-page li.bp-blogs-profile-stats:before {
61
  content: "\f120";
62
  }
63
 
64
- div#community-profile-page a.bp-xprofile-avatar-user-admin:before {
65
  content: "\f182";
66
  }
67
 
68
- div#community-profile-page a.bp-xprofile-avatar-user-edit:before {
69
  content: "\f107";
70
  }
71
 
72
- div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar {
73
  width: 150px;
74
  margin: 0 auto;
75
  }
76
 
77
- div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar img {
78
  max-width: 100%;
79
  height: auto;
80
  }
81
 
82
- div#community-profile-page div#bp_xprofile_user_admin_avatar a {
83
  display: block;
84
  margin: 1em 0;
85
  }
@@ -117,14 +117,17 @@ div#community-profile-page p.not-activated {
117
  font-size: 14px;
118
  }
119
 
 
 
120
  .field_type_textarea legend,
121
  .field_type_multiselectbox legend,
122
  .field_type_radio .radio legend,
123
- .field_type_checkbox .checkbox legend { /* these fields are usually pretty tall, so align the label for better consistency */
124
  vertical-align: top;
125
  }
126
 
127
- .bp-profile-field .description { /* description also sits in the right side column */
 
128
  margin: 10px 200px 12px 0;
129
  text-align: right;
130
  }
@@ -139,7 +142,8 @@ div#community-profile-page p.not-activated {
139
  margin-top: 0;
140
  }
141
 
142
- .clear-value { /* 'clear value' option also sits in the right side column */
 
143
  display: block;
144
  font-size: 12px;
145
  margin-right: 200px;
@@ -183,19 +187,22 @@ div#community-profile-page p.not-activated {
183
  display: inline-block;
184
  }
185
 
 
186
  .field-visibility-settings-notoggle,
187
- .field-visibility-settings-toggle { /* visibility settings go in the left column */
188
  margin: 10px 200px 10px 0;
189
  text-align: right;
190
  }
191
 
192
- .field-visibility-settings { /* visibility settings go in the left column */
 
193
  display: none;
194
  margin-right: 200px;
195
  margin-top: 1.5em;
196
  }
197
 
198
- .field-visibility-settings .button { /* visibility setting close button */
 
199
  margin-bottom: 15px;
200
  }
201
 
@@ -205,7 +212,8 @@ div#community-profile-page p.not-activated {
205
  margin-bottom: 1em;
206
  }
207
 
208
- #normal-sortables .field-visibility-settings legend { /* id required for css selector weight */
 
209
  font-size: 14px;
210
  font-weight: 600;
211
  }
29
  div#community-profile-page li.bp-friends-profile-stats:before,
30
  div#community-profile-page li.bp-groups-profile-stats:before,
31
  div#community-profile-page li.bp-blogs-profile-stats:before,
32
+ div#community-profile-page a.bp-members-avatar-user-admin:before,
33
+ div#community-profile-page a.bp-members-avatar-user-edit:before {
34
  font: 400 20px/1 dashicons;
35
  speak: none;
36
  display: inline-block;
61
  content: "\f120";
62
  }
63
 
64
+ div#community-profile-page a.bp-members-avatar-user-admin:before {
65
  content: "\f182";
66
  }
67
 
68
+ div#community-profile-page a.bp-members-avatar-user-edit:before {
69
  content: "\f107";
70
  }
71
 
72
+ div#community-profile-page div#bp_members_user_admin_avatar div.avatar {
73
  width: 150px;
74
  margin: 0 auto;
75
  }
76
 
77
+ div#community-profile-page div#bp_members_user_admin_avatar div.avatar img {
78
  max-width: 100%;
79
  height: auto;
80
  }
81
 
82
+ div#community-profile-page div#bp_members_user_admin_avatar a {
83
  display: block;
84
  margin: 1em 0;
85
  }
117
  font-size: 14px;
118
  }
119
 
120
+ /* these fields are usually pretty tall, so align the label
121
+ for better consistency */
122
  .field_type_textarea legend,
123
  .field_type_multiselectbox legend,
124
  .field_type_radio .radio legend,
125
+ .field_type_checkbox .checkbox legend {
126
  vertical-align: top;
127
  }
128
 
129
+ /* description also sits in the right side column */
130
+ .bp-profile-field .description {
131
  margin: 10px 200px 12px 0;
132
  text-align: right;
133
  }
142
  margin-top: 0;
143
  }
144
 
145
+ /* 'clear value' option also sits in the right side column */
146
+ .clear-value {
147
  display: block;
148
  font-size: 12px;
149
  margin-right: 200px;
187
  display: inline-block;
188
  }
189
 
190
+ /* visibility settings go in the left column */
191
  .field-visibility-settings-notoggle,
192
+ .field-visibility-settings-toggle {
193
  margin: 10px 200px 10px 0;
194
  text-align: right;
195
  }
196
 
197
+ /* visibility settings go in the left column */
198
+ .field-visibility-settings {
199
  display: none;
200
  margin-right: 200px;
201
  margin-top: 1.5em;
202
  }
203
 
204
+ /* visibility setting close button */
205
+ .field-visibility-settings .button {
206
  margin-bottom: 15px;
207
  }
208
 
212
  margin-bottom: 1em;
213
  }
214
 
215
+ /* id required for css selector weight */
216
+ #normal-sortables .field-visibility-settings legend {
217
  font-size: 14px;
218
  font-weight: 600;
219
  }
bp-members/admin/css/admin-rtl.min.css CHANGED
@@ -1 +1 @@
1
- div#profile-page.wrap form#your-profile{position:relative;padding-top:50px}div#profile-page.wrap form#your-profile h3:first-of-type{margin-top:5em}div#profile-page.wrap form#your-profile #profile-nav{position:absolute;top:0;width:97%}div#community-profile-page #profile-nav{margin-bottom:1em}#bp_members_admin_user_stats ul{margin-bottom:0}div#community-profile-page a.bp-xprofile-avatar-user-admin:before,div#community-profile-page a.bp-xprofile-avatar-user-edit:before,div#community-profile-page li.bp-blogs-profile-stats:before,div#community-profile-page li.bp-friends-profile-stats:before,div#community-profile-page li.bp-groups-profile-stats:before,div#community-profile-page li.bp-members-profile-stats:before{font:400 20px/1 dashicons;speak:none;display:inline-block;padding:0 0 0 2px;top:0;right:-1px;position:relative;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important;color:#888}div#community-profile-page li.bp-members-profile-stats:before{content:"\f130"}div#community-profile-page li.bp-friends-profile-stats:before{content:"\f454"}div#community-profile-page li.bp-groups-profile-stats:before{content:"\f456"}div#community-profile-page li.bp-blogs-profile-stats:before{content:"\f120"}div#community-profile-page a.bp-xprofile-avatar-user-admin:before{content:"\f182"}div#community-profile-page a.bp-xprofile-avatar-user-edit:before{content:"\f107"}div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar{width:150px;margin:0 auto}div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar img{max-width:100%;height:auto}div#community-profile-page div#bp_xprofile_user_admin_avatar a{display:block;margin:1em 0}div#community-profile-page p.not-activated{margin:1em 1em 0;color:red}#community-profile-page #submitdiv #publishing-action{float:none;width:100%}.bp-view-profile{float:right}.alt{background:0 0}.bp-profile-field{border-bottom:dotted 1px #ccc;font-size:14px;margin:15px 0;padding:10px}.bp-profile-field:last-child{border-bottom:0}.bp-profile-field p{font-size:14px}.field_type_checkbox .checkbox legend,.field_type_multiselectbox legend,.field_type_radio .radio legend,.field_type_textarea legend{vertical-align:top}.bp-profile-field .description{margin:10px 200px 12px 0;text-align:right}.bp-profile-field .wp-editor-wrap{margin-right:200px}.field_type_checkbox .description,.field_type_datebox .description,.field_type_radio .description{margin-top:0}.clear-value{display:block;font-size:12px;margin-right:200px}.field_type_checkbox label,.field_type_radio label{display:block;margin-bottom:1em;margin-right:200px;width:auto}.field_type_checkbox .radio label,.field_type_radio .radio label{margin-right:0}.field_type_datebox .datebox-selects{margin-right:200px}.field_type_datebox select:nth-of-type(1){margin-right:0}.field_type_checkbox .checkbox .input-options label,.field_type_radio .radio .input-options label{display:block}.field_type_checkbox .checkbox .input-options,.field_type_datebox .datebox .input-options,.field_type_radio .radio .input-options{display:inline-block}.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin:10px 200px 10px 0;text-align:right}.field-visibility-settings{display:none;margin-right:200px;margin-top:1.5em}.field-visibility-settings .button{margin-bottom:15px}.field-visibility-settings label{clear:right;display:block;margin-bottom:1em}#normal-sortables .field-visibility-settings legend{font-size:14px;font-weight:600}#your-profile .bp-profile-field legend{float:right;font-size:14px;font-weight:600;line-height:1.4;margin-bottom:1em;text-align:right;vertical-align:middle;width:192px}.bp-profile-field .radio .clear-value{margin-top:10px}@media screen and (max-width:782px){#your-profile .bp-profile-field legend{float:none;clear:right;display:block;margin-bottom:12px}#your-profile .field_type_multiselectbox select{height:auto}.field_type_checkbox label,.field_type_radio label{margin-right:0}.bp-profile-field .checkbox input[type=checkbox],.bp-profile-field .radio input[type=radio]{vertical-align:top}.bp-profile-field .clear-value,.bp-profile-field .description,.bp-profile-field .wp-editor-wrap,.bp-profile-field input[type=checkbox],.bp-profile-field input[type=email],.bp-profile-field input[type=number],.bp-profile-field input[type=radio],.bp-profile-field input[type=text],.bp-profile-field input[type=url],.bp-profile-field select:nth-of-type(1),.field-visibility-settings-notoggle,.field-visibility-settings-toggle{clear:right;margin-right:50px}.field_type_datebox .datebox-selects{margin-right:0}.field-visibility-settings{margin-right:50px}.field-visibility-settings input[type=radio]{margin-right:0}#your-profile .field_multiselectbox select{height:auto}}@media screen and (max-width:480px){.bp-profile-field .clear-value,.bp-profile-field .description,.bp-profile-field .wp-editor-wrap,.bp-profile-field input[type=checkbox],.bp-profile-field input[type=email],.bp-profile-field input[type=number],.bp-profile-field input[type=radio],.bp-profile-field input[type=text],.bp-profile-field input[type=url],.bp-profile-field select:nth-of-type(1),.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin-right:0}.field-visibility-settings{margin-right:0}}
1
+ div#profile-page.wrap form#your-profile{position:relative;padding-top:50px}div#profile-page.wrap form#your-profile h3:first-of-type{margin-top:5em}div#profile-page.wrap form#your-profile #profile-nav{position:absolute;top:0;width:97%}div#community-profile-page #profile-nav{margin-bottom:1em}#bp_members_admin_user_stats ul{margin-bottom:0}div#community-profile-page a.bp-members-avatar-user-admin:before,div#community-profile-page a.bp-members-avatar-user-edit:before,div#community-profile-page li.bp-blogs-profile-stats:before,div#community-profile-page li.bp-friends-profile-stats:before,div#community-profile-page li.bp-groups-profile-stats:before,div#community-profile-page li.bp-members-profile-stats:before{font:400 20px/1 dashicons;speak:none;display:inline-block;padding:0 0 0 2px;top:0;right:-1px;position:relative;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important;color:#888}div#community-profile-page li.bp-members-profile-stats:before{content:"\f130"}div#community-profile-page li.bp-friends-profile-stats:before{content:"\f454"}div#community-profile-page li.bp-groups-profile-stats:before{content:"\f456"}div#community-profile-page li.bp-blogs-profile-stats:before{content:"\f120"}div#community-profile-page a.bp-members-avatar-user-admin:before{content:"\f182"}div#community-profile-page a.bp-members-avatar-user-edit:before{content:"\f107"}div#community-profile-page div#bp_members_user_admin_avatar div.avatar{width:150px;margin:0 auto}div#community-profile-page div#bp_members_user_admin_avatar div.avatar img{max-width:100%;height:auto}div#community-profile-page div#bp_members_user_admin_avatar a{display:block;margin:1em 0}div#community-profile-page p.not-activated{margin:1em 1em 0;color:red}#community-profile-page #submitdiv #publishing-action{float:none;width:100%}.bp-view-profile{float:right}.alt{background:0 0}.bp-profile-field{border-bottom:dotted 1px #ccc;font-size:14px;margin:15px 0;padding:10px}.bp-profile-field:last-child{border-bottom:0}.bp-profile-field p{font-size:14px}.field_type_checkbox .checkbox legend,.field_type_multiselectbox legend,.field_type_radio .radio legend,.field_type_textarea legend{vertical-align:top}.bp-profile-field .description{margin:10px 200px 12px 0;text-align:right}.bp-profile-field .wp-editor-wrap{margin-right:200px}.field_type_checkbox .description,.field_type_datebox .description,.field_type_radio .description{margin-top:0}.clear-value{display:block;font-size:12px;margin-right:200px}.field_type_checkbox label,.field_type_radio label{display:block;margin-bottom:1em;margin-right:200px;width:auto}.field_type_checkbox .radio label,.field_type_radio .radio label{margin-right:0}.field_type_datebox .datebox-selects{margin-right:200px}.field_type_datebox select:nth-of-type(1){margin-right:0}.field_type_checkbox .checkbox .input-options label,.field_type_radio .radio .input-options label{display:block}.field_type_checkbox .checkbox .input-options,.field_type_datebox .datebox .input-options,.field_type_radio .radio .input-options{display:inline-block}.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin:10px 200px 10px 0;text-align:right}.field-visibility-settings{display:none;margin-right:200px;margin-top:1.5em}.field-visibility-settings .button{margin-bottom:15px}.field-visibility-settings label{clear:right;display:block;margin-bottom:1em}#normal-sortables .field-visibility-settings legend{font-size:14px;font-weight:600}#your-profile .bp-profile-field legend{float:right;font-size:14px;font-weight:600;line-height:1.4;margin-bottom:1em;text-align:right;vertical-align:middle;width:192px}.bp-profile-field .radio .clear-value{margin-top:10px}@media screen and (max-width:782px){#your-profile .bp-profile-field legend{float:none;clear:right;display:block;margin-bottom:12px}#your-profile .field_type_multiselectbox select{height:auto}.field_type_checkbox label,.field_type_radio label{margin-right:0}.bp-profile-field .checkbox input[type=checkbox],.bp-profile-field .radio input[type=radio]{vertical-align:top}.bp-profile-field .clear-value,.bp-profile-field .description,.bp-profile-field .wp-editor-wrap,.bp-profile-field input[type=checkbox],.bp-profile-field input[type=email],.bp-profile-field input[type=number],.bp-profile-field input[type=radio],.bp-profile-field input[type=text],.bp-profile-field input[type=url],.bp-profile-field select:nth-of-type(1),.field-visibility-settings-notoggle,.field-visibility-settings-toggle{clear:right;margin-right:50px}.field_type_datebox .datebox-selects{margin-right:0}.field-visibility-settings{margin-right:50px}.field-visibility-settings input[type=radio]{margin-right:0}#your-profile .field_multiselectbox select{height:auto}}@media screen and (max-width:480px){.bp-profile-field .clear-value,.bp-profile-field .description,.bp-profile-field .wp-editor-wrap,.bp-profile-field input[type=checkbox],.bp-profile-field input[type=email],.bp-profile-field input[type=number],.bp-profile-field input[type=radio],.bp-profile-field input[type=text],.bp-profile-field input[type=url],.bp-profile-field select:nth-of-type(1),.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin-right:0}.field-visibility-settings{margin-right:0}}
bp-members/admin/css/admin.css CHANGED
@@ -29,8 +29,8 @@ div#community-profile-page li.bp-members-profile-stats:before,
29
  div#community-profile-page li.bp-friends-profile-stats:before,
30
  div#community-profile-page li.bp-groups-profile-stats:before,
31
  div#community-profile-page li.bp-blogs-profile-stats:before,
32
- div#community-profile-page a.bp-xprofile-avatar-user-admin:before,
33
- div#community-profile-page a.bp-xprofile-avatar-user-edit:before {
34
  font: 400 20px/1 dashicons;
35
  speak: none;
36
  display: inline-block;
@@ -61,25 +61,25 @@ div#community-profile-page li.bp-blogs-profile-stats:before {
61
  content: "\f120";
62
  }
63
 
64
- div#community-profile-page a.bp-xprofile-avatar-user-admin:before {
65
  content: "\f182";
66
  }
67
 
68
- div#community-profile-page a.bp-xprofile-avatar-user-edit:before {
69
  content: "\f107";
70
  }
71
 
72
- div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar {
73
  width: 150px;
74
  margin: 0 auto;
75
  }
76
 
77
- div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar img {
78
  max-width: 100%;
79
  height: auto;
80
  }
81
 
82
- div#community-profile-page div#bp_xprofile_user_admin_avatar a {
83
  display: block;
84
  margin: 1em 0;
85
  }
@@ -117,14 +117,17 @@ div#community-profile-page p.not-activated {
117
  font-size: 14px;
118
  }
119
 
 
 
120
  .field_type_textarea legend,
121
  .field_type_multiselectbox legend,
122
  .field_type_radio .radio legend,
123
- .field_type_checkbox .checkbox legend { /* these fields are usually pretty tall, so align the label for better consistency */
124
  vertical-align: top;
125
  }
126
 
127
- .bp-profile-field .description { /* description also sits in the right side column */
 
128
  margin: 10px 0 12px 200px;
129
  text-align: left;
130
  }
@@ -139,7 +142,8 @@ div#community-profile-page p.not-activated {
139
  margin-top: 0;
140
  }
141
 
142
- .clear-value { /* 'clear value' option also sits in the right side column */
 
143
  display: block;
144
  font-size: 12px;
145
  margin-left: 200px;
@@ -183,19 +187,22 @@ div#community-profile-page p.not-activated {
183
  display: inline-block;
184
  }
185
 
 
186
  .field-visibility-settings-notoggle,
187
- .field-visibility-settings-toggle { /* visibility settings go in the left column */
188
  margin: 10px 0 10px 200px;
189
  text-align: left;
190
  }
191
 
192
- .field-visibility-settings { /* visibility settings go in the left column */
 
193
  display: none;
194
  margin-left: 200px;
195
  margin-top: 1.5em;
196
  }
197
 
198
- .field-visibility-settings .button { /* visibility setting close button */
 
199
  margin-bottom: 15px;
200
  }
201
 
@@ -205,7 +212,8 @@ div#community-profile-page p.not-activated {
205
  margin-bottom: 1em;
206
  }
207
 
208
- #normal-sortables .field-visibility-settings legend { /* id required for css selector weight */
 
209
  font-size: 14px;
210
  font-weight: 600;
211
  }
29
  div#community-profile-page li.bp-friends-profile-stats:before,
30
  div#community-profile-page li.bp-groups-profile-stats:before,
31
  div#community-profile-page li.bp-blogs-profile-stats:before,
32
+ div#community-profile-page a.bp-members-avatar-user-admin:before,
33
+ div#community-profile-page a.bp-members-avatar-user-edit:before {
34
  font: 400 20px/1 dashicons;
35
  speak: none;
36
  display: inline-block;
61
  content: "\f120";
62
  }
63
 
64
+ div#community-profile-page a.bp-members-avatar-user-admin:before {
65
  content: "\f182";
66
  }
67
 
68
+ div#community-profile-page a.bp-members-avatar-user-edit:before {
69
  content: "\f107";
70
  }
71
 
72
+ div#community-profile-page div#bp_members_user_admin_avatar div.avatar {
73
  width: 150px;
74
  margin: 0 auto;
75
  }
76
 
77
+ div#community-profile-page div#bp_members_user_admin_avatar div.avatar img {
78
  max-width: 100%;
79
  height: auto;
80
  }
81
 
82
+ div#community-profile-page div#bp_members_user_admin_avatar a {
83
  display: block;
84
  margin: 1em 0;
85
  }
117
  font-size: 14px;
118
  }
119
 
120
+ /* these fields are usually pretty tall, so align the label
121
+ for better consistency */
122
  .field_type_textarea legend,
123
  .field_type_multiselectbox legend,
124
  .field_type_radio .radio legend,
125
+ .field_type_checkbox .checkbox legend {
126
  vertical-align: top;
127
  }
128
 
129
+ /* description also sits in the right side column */
130
+ .bp-profile-field .description {
131
  margin: 10px 0 12px 200px;
132
  text-align: left;
133
  }
142
  margin-top: 0;
143
  }
144
 
145
+ /* 'clear value' option also sits in the right side column */
146
+ .clear-value {
147
  display: block;
148
  font-size: 12px;
149
  margin-left: 200px;
187
  display: inline-block;
188
  }
189
 
190
+ /* visibility settings go in the left column */
191
  .field-visibility-settings-notoggle,
192
+ .field-visibility-settings-toggle {
193
  margin: 10px 0 10px 200px;
194
  text-align: left;
195
  }
196
 
197
+ /* visibility settings go in the left column */
198
+ .field-visibility-settings {
199
  display: none;
200
  margin-left: 200px;
201
  margin-top: 1.5em;
202
  }
203
 
204
+ /* visibility setting close button */
205
+ .field-visibility-settings .button {
206
  margin-bottom: 15px;
207
  }
208
 
212
  margin-bottom: 1em;
213
  }
214
 
215
+ /* id required for css selector weight */
216
+ #normal-sortables .field-visibility-settings legend {
217
  font-size: 14px;
218
  font-weight: 600;
219
  }
bp-members/admin/css/admin.min.css CHANGED
@@ -1 +1 @@
1
- div#profile-page.wrap form#your-profile{position:relative;padding-top:50px}div#profile-page.wrap form#your-profile h3:first-of-type{margin-top:5em}div#profile-page.wrap form#your-profile #profile-nav{position:absolute;top:0;width:97%}div#community-profile-page #profile-nav{margin-bottom:1em}#bp_members_admin_user_stats ul{margin-bottom:0}div#community-profile-page a.bp-xprofile-avatar-user-admin:before,div#community-profile-page a.bp-xprofile-avatar-user-edit:before,div#community-profile-page li.bp-blogs-profile-stats:before,div#community-profile-page li.bp-friends-profile-stats:before,div#community-profile-page li.bp-groups-profile-stats:before,div#community-profile-page li.bp-members-profile-stats:before{font:400 20px/1 dashicons;speak:none;display:inline-block;padding:0 2px 0 0;top:0;left:-1px;position:relative;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important;color:#888}div#community-profile-page li.bp-members-profile-stats:before{content:"\f130"}div#community-profile-page li.bp-friends-profile-stats:before{content:"\f454"}div#community-profile-page li.bp-groups-profile-stats:before{content:"\f456"}div#community-profile-page li.bp-blogs-profile-stats:before{content:"\f120"}div#community-profile-page a.bp-xprofile-avatar-user-admin:before{content:"\f182"}div#community-profile-page a.bp-xprofile-avatar-user-edit:before{content:"\f107"}div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar{width:150px;margin:0 auto}div#community-profile-page div#bp_xprofile_user_admin_avatar div.avatar img{max-width:100%;height:auto}div#community-profile-page div#bp_xprofile_user_admin_avatar a{display:block;margin:1em 0}div#community-profile-page p.not-activated{margin:1em 1em 0;color:red}#community-profile-page #submitdiv #publishing-action{float:none;width:100%}.bp-view-profile{float:left}.alt{background:0 0}.bp-profile-field{border-bottom:dotted 1px #ccc;font-size:14px;margin:15px 0;padding:10px}.bp-profile-field:last-child{border-bottom:0}.bp-profile-field p{font-size:14px}.field_type_checkbox .checkbox legend,.field_type_multiselectbox legend,.field_type_radio .radio legend,.field_type_textarea legend{vertical-align:top}.bp-profile-field .description{margin:10px 0 12px 200px;text-align:left}.bp-profile-field .wp-editor-wrap{margin-left:200px}.field_type_checkbox .description,.field_type_datebox .description,.field_type_radio .description{margin-top:0}.clear-value{display:block;font-size:12px;margin-left:200px}.field_type_checkbox label,.field_type_radio label{display:block;margin-bottom:1em;margin-left:200px;width:auto}.field_type_checkbox .radio label,.field_type_radio .radio label{margin-left:0}.field_type_datebox .datebox-selects{margin-left:200px}.field_type_datebox select:nth-of-type(1){margin-left:0}.field_type_checkbox .checkbox .input-options label,.field_type_radio .radio .input-options label{display:block}.field_type_checkbox .checkbox .input-options,.field_type_datebox .datebox .input-options,.field_type_radio .radio .input-options{display:inline-block}.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin:10px 0 10px 200px;text-align:left}.field-visibility-settings{display:none;margin-left:200px;margin-top:1.5em}.field-visibility-settings .button{margin-bottom:15px}.field-visibility-settings label{clear:left;display:block;margin-bottom:1em}#normal-sortables .field-visibility-settings legend{font-size:14px;font-weight:600}#your-profile .bp-profile-field legend{float:left;font-size:14px;font-weight:600;line-height:1.4;margin-bottom:1em;text-align:left;vertical-align:middle;width:192px}.bp-profile-field .radio .clear-value{margin-top:10px}@media screen and (max-width:782px){#your-profile .bp-profile-field legend{float:none;clear:left;display:block;margin-bottom:12px}#your-profile .field_type_multiselectbox select{height:auto}.field_type_checkbox label,.field_type_radio label{margin-left:0}.bp-profile-field .checkbox input[type=checkbox],.bp-profile-field .radio input[type=radio]{vertical-align:top}.bp-profile-field .clear-value,.bp-profile-field .description,.bp-profile-field .wp-editor-wrap,.bp-profile-field input[type=checkbox],.bp-profile-field input[type=email],.bp-profile-field input[type=number],.bp-profile-field input[type=radio],.bp-profile-field input[type=text],.bp-profile-field input[type=url],.bp-profile-field select:nth-of-type(1),.field-visibility-settings-notoggle,.field-visibility-settings-toggle{clear:left;margin-left:50px}.field_type_datebox .datebox-selects{margin-left:0}.field-visibility-settings{margin-left:50px}.field-visibility-settings input[type=radio]{margin-left:0}#your-profile .field_multiselectbox select{height:auto}}@media screen and (max-width:480px){.bp-profile-field .clear-value,.bp-profile-field .description,.bp-profile-field .wp-editor-wrap,.bp-profile-field input[type=checkbox],.bp-profile-field input[type=email],.bp-profile-field input[type=number],.bp-profile-field input[type=radio],.bp-profile-field input[type=text],.bp-profile-field input[type=url],.bp-profile-field select:nth-of-type(1),.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin-left:0}.field-visibility-settings{margin-left:0}}
1
+ div#profile-page.wrap form#your-profile{position:relative;padding-top:50px}div#profile-page.wrap form#your-profile h3:first-of-type{margin-top:5em}div#profile-page.wrap form#your-profile #profile-nav{position:absolute;top:0;width:97%}div#community-profile-page #profile-nav{margin-bottom:1em}#bp_members_admin_user_stats ul{margin-bottom:0}div#community-profile-page a.bp-members-avatar-user-admin:before,div#community-profile-page a.bp-members-avatar-user-edit:before,div#community-profile-page li.bp-blogs-profile-stats:before,div#community-profile-page li.bp-friends-profile-stats:before,div#community-profile-page li.bp-groups-profile-stats:before,div#community-profile-page li.bp-members-profile-stats:before{font:400 20px/1 dashicons;speak:none;display:inline-block;padding:0 2px 0 0;top:0;left:-1px;position:relative;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important;color:#888}div#community-profile-page li.bp-members-profile-stats:before{content:"\f130"}div#community-profile-page li.bp-friends-profile-stats:before{content:"\f454"}div#community-profile-page li.bp-groups-profile-stats:before{content:"\f456"}div#community-profile-page li.bp-blogs-profile-stats:before{content:"\f120"}div#community-profile-page a.bp-members-avatar-user-admin:before{content:"\f182"}div#community-profile-page a.bp-members-avatar-user-edit:before{content:"\f107"}div#community-profile-page div#bp_members_user_admin_avatar div.avatar{width:150px;margin:0 auto}div#community-profile-page div#bp_members_user_admin_avatar div.avatar img{max-width:100%;height:auto}div#community-profile-page div#bp_members_user_admin_avatar a{display:block;margin:1em 0}div#community-profile-page p.not-activated{margin:1em 1em 0;color:red}#community-profile-page #submitdiv #publishing-action{float:none;width:100%}.bp-view-profile{float:left}.alt{background:0 0}.bp-profile-field{border-bottom:dotted 1px #ccc;font-size:14px;margin:15px 0;padding:10px}.bp-profile-field:last-child{border-bottom:0}.bp-profile-field p{font-size:14px}.field_type_checkbox .checkbox legend,.field_type_multiselectbox legend,.field_type_radio .radio legend,.field_type_textarea legend{vertical-align:top}.bp-profile-field .description{margin:10px 0 12px 200px;text-align:left}.bp-profile-field .wp-editor-wrap{margin-left:200px}.field_type_checkbox .description,.field_type_datebox .description,.field_type_radio .description{margin-top:0}.clear-value{display:block;font-size:12px;margin-left:200px}.field_type_checkbox label,.field_type_radio label{display:block;margin-bottom:1em;margin-left:200px;width:auto}.field_type_checkbox .radio label,.field_type_radio .radio label{margin-left:0}.field_type_datebox .datebox-selects{margin-left:200px}.field_type_datebox select:nth-of-type(1){margin-left:0}.field_type_checkbox .checkbox .input-options label,.field_type_radio .radio .input-options label{display:block}.field_type_checkbox .checkbox .input-options,.field_type_datebox .datebox .input-options,.field_type_radio .radio .input-options{display:inline-block}.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin:10px 0 10px 200px;text-align:left}.field-visibility-settings{display:none;margin-left:200px;margin-top:1.5em}.field-visibility-settings .button{margin-bottom:15px}.field-visibility-settings label{clear:left;display:block;margin-bottom:1em}#normal-sortables .field-visibility-settings legend{font-size:14px;font-weight:600}#your-profile .bp-profile-field legend{float:left;font-size:14px;font-weight:600;line-height:1.4;margin-bottom:1em;text-align:left;vertical-align:middle;width:192px}.bp-profile-field .radio .clear-value{margin-top:10px}@media screen and (max-width:782px){#your-profile .bp-profile-field legend{float:none;clear:left;display:block;margin-bottom:12px}#your-profile .field_type_multiselectbox select{height:auto}.field_type_checkbox label,.field_type_radio label{margin-left:0}.bp-profile-field .checkbox input[type=checkbox],.bp-profile-field .radio input[type=radio]{vertical-align:top}.bp-profile-field .clear-value,.bp-profile-field .description,.bp-profile-field .wp-editor-wrap,.bp-profile-field input[type=checkbox],.bp-profile-field input[type=email],.bp-profile-field input[type=number],.bp-profile-field input[type=radio],.bp-profile-field input[type=text],.bp-profile-field input[type=url],.bp-profile-field select:nth-of-type(1),.field-visibility-settings-notoggle,.field-visibility-settings-toggle{clear:left;margin-left:50px}.field_type_datebox .datebox-selects{margin-left:0}.field-visibility-settings{margin-left:50px}.field-visibility-settings input[type=radio]{margin-left:0}#your-profile .field_multiselectbox select{height:auto}}@media screen and (max-width:480px){.bp-profile-field .clear-value,.bp-profile-field .description,.bp-profile-field .wp-editor-wrap,.bp-profile-field input[type=checkbox],.bp-profile-field input[type=email],.bp-profile-field input[type=number],.bp-profile-field input[type=radio],.bp-profile-field input[type=text],.bp-profile-field input[type=url],.bp-profile-field select:nth-of-type(1),.field-visibility-settings-notoggle,.field-visibility-settings-toggle{margin-left:0}.field-visibility-settings{margin-left:0}}
bp-members/bp-members-activity.php CHANGED
@@ -47,7 +47,9 @@ add_action( 'bp_register_activity_actions', 'bp_members_register_activity_action
47
  */
48
  function bp_members_format_activity_action_new_member( $action, $activity ) {
49
  $userlink = bp_core_get_userlink( $activity->user_id );
50
- $action = sprintf( esc_html__( '%s became a registered member', 'buddypress' ), $userlink );
 
 
51
 
52
  // Legacy filter - pass $user_id instead of $activity.
53
  if ( has_filter( 'bp_core_activity_registered_member_action' ) ) {
47
  */
48
  function bp_members_format_activity_action_new_member( $action, $activity ) {
49
  $userlink = bp_core_get_userlink( $activity->user_id );
50
+
51
+ /* translators: %s: user link */
52
+ $action = sprintf( esc_html__( '%s became a registered member', 'buddypress' ), $userlink );
53
 
54
  // Legacy filter - pass $user_id instead of $activity.
55
  if ( has_filter( 'bp_core_activity_registered_member_action' ) ) {
bp-members/bp-members-adminbar.php CHANGED
@@ -35,7 +35,7 @@ function bp_members_admin_bar_my_account_menu() {
35
  $bp->my_account_menu_id = 'my-account-buddypress';
36
 
37
  // Create the main 'My Account' menu.
38
- $wp_admin_bar->add_menu( array(
39
  'id' => $bp->my_account_menu_id,
40
  'group' => true,
41
  'title' => __( 'Edit My Profile', 'buddypress' ),
@@ -50,7 +50,7 @@ function bp_members_admin_bar_my_account_menu() {
50
  add_filter( 'show_admin_bar', '__return_true' );
51
 
52
  // Create the main 'My Account' menu.
53
- $wp_admin_bar->add_menu( array(
54
  'id' => 'bp-login',
55
  'title' => __( 'Log In', 'buddypress' ),
56
  'href' => wp_login_url( bp_get_requested_url() )
@@ -58,7 +58,7 @@ function bp_members_admin_bar_my_account_menu() {
58
 
59
  // Sign up.
60
  if ( bp_get_signup_allowed() ) {
61
- $wp_admin_bar->add_menu( array(
62
  'id' => 'bp-register',
63
  'title' => __( 'Register', 'buddypress' ),
64
  'href' => bp_get_signup_page()
@@ -90,7 +90,7 @@ function bp_members_admin_bar_user_admin_menu() {
90
  $bp->user_admin_menu_id = 'user-admin';
91
 
92
  // Add the top-level User Admin button.
93
- $wp_admin_bar->add_menu( array(
94
  'id' => $bp->user_admin_menu_id,
95
  'title' => __( 'Edit Member', 'buddypress' ),
96
  'href' => bp_displayed_user_domain()
@@ -98,7 +98,7 @@ function bp_members_admin_bar_user_admin_menu() {
98
 
99
  if ( bp_is_active( 'xprofile' ) ) {
100
  // User Admin > Edit this user's profile.
101
- $wp_admin_bar->add_menu( array(
102
  'parent' => $bp->user_admin_menu_id,
103
  'id' => $bp->user_admin_menu_id . '-edit-profile',
104
  'title' => __( "Edit Profile", 'buddypress' ),
@@ -107,7 +107,7 @@ function bp_members_admin_bar_user_admin_menu() {
107
 
108
  // User Admin > Edit this user's avatar.
109
  if ( buddypress()->avatar->show_avatars ) {
110
- $wp_admin_bar->add_menu( array(
111
  'parent' => $bp->user_admin_menu_id,
112
  'id' => $bp->user_admin_menu_id . '-change-avatar',
113
  'title' => __( "Edit Profile Photo", 'buddypress' ),
@@ -117,7 +117,7 @@ function bp_members_admin_bar_user_admin_menu() {
117
 
118
  // User Admin > Edit this user's cover image.
119
  if ( bp_displayed_user_use_cover_image_header() ) {
120
- $wp_admin_bar->add_menu( array(
121
  'parent' => $bp->user_admin_menu_id,
122
  'id' => $bp->user_admin_menu_id . '-change-cover-image',
123
  'title' => __( 'Edit Cover Image', 'buddypress' ),
@@ -129,7 +129,7 @@ function bp_members_admin_bar_user_admin_menu() {
129
 
130
  if ( bp_is_active( 'settings' ) ) {
131
  // User Admin > Spam/unspam.
132
- $wp_admin_bar->add_menu( array(
133
  'parent' => $bp->user_admin_menu_id,
134
  'id' => $bp->user_admin_menu_id . '-user-capabilities',
135
  'title' => __( 'User Capabilities', 'buddypress' ),
@@ -137,7 +137,7 @@ function bp_members_admin_bar_user_admin_menu() {
137
  ) );
138
 
139
  // User Admin > Delete Account.
140
- $wp_admin_bar->add_menu( array(
141
  'parent' => $bp->user_admin_menu_id,
142
  'id' => $bp->user_admin_menu_id . '-delete-user',
143
  'title' => __( 'Delete Account', 'buddypress' ),
35
  $bp->my_account_menu_id = 'my-account-buddypress';
36
 
37
  // Create the main 'My Account' menu.
38
+ $wp_admin_bar->add_node( array(
39
  'id' => $bp->my_account_menu_id,
40
  'group' => true,
41
  'title' => __( 'Edit My Profile', 'buddypress' ),
50
  add_filter( 'show_admin_bar', '__return_true' );
51
 
52
  // Create the main 'My Account' menu.
53
+ $wp_admin_bar->add_node( array(
54
  'id' => 'bp-login',
55
  'title' => __( 'Log In', 'buddypress' ),
56
  'href' => wp_login_url( bp_get_requested_url() )
58
 
59
  // Sign up.
60
  if ( bp_get_signup_allowed() ) {
61
+ $wp_admin_bar->add_node( array(
62
  'id' => 'bp-register',
63
  'title' => __( 'Register', 'buddypress' ),
64
  'href' => bp_get_signup_page()
90
  $bp->user_admin_menu_id = 'user-admin';
91
 
92
  // Add the top-level User Admin button.
93
+ $wp_admin_bar->add_node( array(
94
  'id' => $bp->user_admin_menu_id,
95
  'title' => __( 'Edit Member', 'buddypress' ),
96
  'href' => bp_displayed_user_domain()
98
 
99
  if ( bp_is_active( 'xprofile' ) ) {
100
  // User Admin > Edit this user's profile.
101
+ $wp_admin_bar->add_node( array(
102
  'parent' => $bp->user_admin_menu_id,
103
  'id' => $bp->user_admin_menu_id . '-edit-profile',
104
  'title' => __( "Edit Profile", 'buddypress' ),
107
 
108
  // User Admin > Edit this user's avatar.
109
  if ( buddypress()->avatar->show_avatars ) {
110
+ $wp_admin_bar->add_node( array(
111
  'parent' => $bp->user_admin_menu_id,
112
  'id' => $bp->user_admin_menu_id . '-change-avatar',
113
  'title' => __( "Edit Profile Photo", 'buddypress' ),
117
 
118
  // User Admin > Edit this user's cover image.
119
  if ( bp_displayed_user_use_cover_image_header() ) {
120
+ $wp_admin_bar->add_node( array(
121
  'parent' => $bp->user_admin_menu_id,
122
  'id' => $bp->user_admin_menu_id . '-change-cover-image',
123
  'title' => __( 'Edit Cover Image', 'buddypress' ),
129
 
130
  if ( bp_is_active( 'settings' ) ) {
131
  // User Admin > Spam/unspam.
132
+ $wp_admin_bar->add_node( array(
133
  'parent' => $bp->user_admin_menu_id,
134
  'id' => $bp->user_admin_menu_id . '-user-capabilities',
135
  'title' => __( 'User Capabilities', 'buddypress' ),
137
  ) );
138
 
139
  // User Admin > Delete Account.
140
+ $wp_admin_bar->add_node( array(
141
  'parent' => $bp->user_admin_menu_id,
142
  'id' => $bp->user_admin_menu_id . '-delete-user',
143
  'title' => __( 'Delete Account', 'buddypress' ),
bp-members/bp-members-blocks.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP Members Blocks Functions.
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage MembersBlocks
7
+ * @since 6.0.0
8
+ */
9
+
10
+ // Exit if accessed directly.
11
+ if ( ! defined( 'ABSPATH' ) ) {
12
+ exit;
13
+ }
14
+
15
+ /**
16
+ * Add BP Members blocks specific settings to the BP Blocks Editor ones.
17
+ *
18
+ * @since 6.0.0
19
+ *
20
+ * @param array $bp_editor_settings BP blocks editor settings.
21
+ * @return array BP Members blocks editor settings.
22
+ */
23
+ function bp_members_editor_settings( $bp_editor_settings = array() ) {
24
+ $bp = buddypress();
25
+
26
+ return array_merge(
27
+ $bp_editor_settings,
28
+ array(
29
+ 'members' => array(
30
+ 'isMentionEnabled' => bp_is_active( 'activity' ) && bp_activity_do_mentions(),
31
+ 'isAvatarEnabled' => $bp->avatar && $bp->avatar->show_avatars,
32
+ 'isCoverImageEnabled' => bp_is_active( 'members', 'cover_image' ),
33
+ ),
34
+ )
35
+ );
36
+ }
37
+ add_filter( 'bp_blocks_editor_settings', 'bp_members_editor_settings' );
38
+
39
+ /**
40
+ * Callback function to render the BP Member Block.
41
+ *
42
+ * @since 6.0.0
43
+ *
44
+ * @param array $attributes The block attributes.
45
+ * @return string HTML output.
46
+ */
47
+ function bp_members_render_member_block( $attributes = array() ) {
48
+ $bp = buddypress();
49
+
50
+ $block_args = wp_parse_args(
51
+ $attributes,
52
+ array(
53
+ 'itemID' => 0,
54
+ 'avatarSize' => 'full',
55
+ 'displayMentionSlug' => true,
56
+ 'displayActionButton' => true,
57
+ 'displayCoverImage' => true,
58
+ )
59
+ );
60
+
61
+ if ( ! $block_args['itemID'] ) {
62
+ return;
63
+ }
64
+
65
+ // Set the member ID and container classes.
66
+ $member_id = (int) $block_args['itemID'];
67
+ $container_classes = array( 'bp-block-member' );
68
+
69
+ // Mention variables.
70
+ $username = bp_core_get_username( $member_id );
71
+ $at_mention = '';
72
+
73
+ // Avatar variables.
74
+ $avatar = '';
75
+ $avatar_container = '';
76
+
77
+ // Cover image variable.
78
+ $cover_image = '';
79
+ $cover_style = '';
80
+ $cover_container = '';
81
+
82
+ // Member name variables.
83
+ $display_name = bp_core_get_user_displayname( $member_id );
84
+ $member_link = bp_core_get_user_domain( $member_id );
85
+
86
+ // Member action button.
87
+ $action_button = '';
88
+ $display_action_button = (bool) $block_args['displayActionButton'];
89
+
90
+ if ( $bp->avatar && $bp->avatar->show_avatars && in_array( $block_args['avatarSize'], array( 'thumb', 'full' ), true ) ) {
91
+ $avatar = bp_core_fetch_avatar(
92
+ array(
93
+ 'item_id' => $member_id,
94
+ 'object' => 'user',
95
+ 'type' => $block_args['avatarSize'],
96
+ 'html' => false,
97
+ )
98
+ );
99
+
100
+ $container_classes[] = 'avatar-' . $block_args['avatarSize'];
101
+ } else {
102
+ $container_classes[] = 'avatar-none';
103
+ }
104
+
105
+ if ( $avatar ) {
106
+ $avatar_container = sprintf(
107
+ '<div class="item-header-avatar">
108
+ <a href="%1$s">
109
+ <img src="%2$s" alt="%3$s" class="avatar">
110
+ </a>
111
+ </div>',
112
+ esc_url( $member_link ),
113
+ esc_url( $avatar ),
114
+ /* translators: %s: member name */
115
+ sprintf( esc_html__( 'Profile photo of %s', 'buddypress' ), $display_name )
116
+ );
117
+ }
118
+
119
+ $display_cover_image = (bool) $block_args['displayCoverImage'];
120
+ if ( bp_is_active( 'members', 'cover_image' ) && $display_cover_image ) {
121
+ $cover_image = bp_attachments_get_attachment(
122
+ 'url',
123
+ array(
124
+ 'item_id' => $member_id,
125
+ )
126
+ );
127
+
128
+ if ( $cover_image ) {
129
+ $cover_style = sprintf(
130
+ ' style="background-image: url( %s );"',
131
+ esc_url( $cover_image )
132
+ );
133
+ }
134
+
135
+ $cover_container = sprintf(
136
+ '<div class="bp-member-cover-image"%s></div>',
137
+ $cover_style
138
+ );
139
+
140
+ $container_classes[] = 'has-cover';
141
+ }
142
+
143
+ $display_mention_slug = (bool) $block_args['displayMentionSlug'];
144
+ if ( bp_is_active( 'activity' ) && bp_activity_do_mentions() && $display_mention_slug ) {
145
+ $at_mention = sprintf(
146
+ '<span class="user-nicename">@%s</span>',
147
+ esc_html( $username )
148
+ );
149
+ }
150
+
151
+ if ( $display_action_button ) {
152
+ $action_button = sprintf(
153
+ '<div class="bp-profile-button">
154
+ <a href="%1$s" class="button large primary button-primary" role="button">%2$s</a>
155
+ </div>',
156
+ esc_url( $member_link ),
157
+ esc_html__( 'View Profile', 'buddypress' )
158
+ );
159
+ }
160
+
161
+ $output = sprintf(
162
+ '<div class="%1$s">
163
+ %2$s
164
+ <div class="member-content">
165
+ %3$s
166
+ <div class="member-description">
167
+ <strong><a href="%4$s">%5$s</a></strong>
168
+ %6$s
169
+ %7$s
170
+ </div>
171
+ </div>
172
+ </div>',
173
+ implode( ' ', array_map( 'sanitize_html_class', $container_classes ) ),
174
+ $cover_container,
175
+ $avatar_container,
176
+ esc_url( $member_link ),
177
+ esc_html( $display_name ),
178
+ $at_mention,
179
+ $action_button
180
+ );
181
+
182
+ // Compact all interesting parameters.
183
+ $params = array_merge( $block_args, compact( 'username', 'display_name', 'member_link', 'avatar', 'cover_image' ) );
184
+
185
+ /**
186
+ * Filter here to edit the output of the single member block.
187
+ *
188
+ * @since 6.0.0
189
+ *
190
+ * @param string $output The HTML output of the block.
191
+ * @param array $params The block extended parameters.
192
+ */
193
+ return apply_filters( 'bp_members_render_member_block_output', $output, $params );
194
+ }
bp-members/bp-members-functions.php CHANGED
@@ -1261,6 +1261,35 @@ function bp_core_delete_account( $user_id = 0 ) {
1261
  return $retval;
1262
  }
1263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1264
  /**
1265
  * Delete a user's avatar when the user is deleted.
1266
  *
@@ -1276,7 +1305,22 @@ function bp_core_delete_avatar_on_user_delete( $user_id ) {
1276
  ) );
1277
  }
1278
  add_action( 'wpmu_delete_user', 'bp_core_delete_avatar_on_user_delete' );
1279
- add_action( 'delete_user', 'bp_core_delete_avatar_on_user_delete' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1280
 
1281
  /**
1282
  * Multibyte-safe ucfirst() support.
@@ -1344,9 +1388,24 @@ function bp_core_remove_data( $user_id ) {
1344
  wp_cache_flush();
1345
  }
1346
  add_action( 'wpmu_delete_user', 'bp_core_remove_data' );
1347
- add_action( 'delete_user', 'bp_core_remove_data' );
1348
  add_action( 'bp_make_spam_user', 'bp_core_remove_data' );
1349
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1350
  /**
1351
  * Check whether the logged-in user can edit settings for the displayed user.
1352
  *
@@ -1923,7 +1982,7 @@ function bp_core_activate_signup( $key ) {
1923
  // Set up data to pass to the legacy filter.
1924
  $user = array(
1925
  'user_id' => $user_id,
1926
- 'password' => $signup->meta['password'],
1927
  'meta' => $signup->meta,
1928
  );
1929
 
@@ -2273,7 +2332,10 @@ function bp_core_signup_disable_inactive( $user = null, $username = '', $passwor
2273
  'bp-resend-activation'
2274
  );
2275
 
2276
- $resend_string = '<br /><br />' . sprintf( __( 'If you have not received an email yet, <a href="%s">click here to resend it</a>.', 'buddypress' ), esc_url( $resend_url ) );
 
 
 
2277
 
2278
  return new WP_Error( 'bp_account_not_activated', __( '<strong>ERROR</strong>: Your account has not been activated. Check your email for the activation link.', 'buddypress' ) . $resend_string );
2279
  }
@@ -2719,6 +2781,12 @@ function bp_remove_member_type( $user_id, $member_type ) {
2719
  return false;
2720
  }
2721
 
 
 
 
 
 
 
2722
  $deleted = bp_remove_object_terms( $user_id, $member_type, bp_get_member_type_tax_name() );
2723
 
2724
  // Bust the cache if the type has been removed.
@@ -2828,7 +2896,22 @@ function bp_remove_member_type_on_user_delete( $user_id ) {
2828
  return bp_set_member_type( $user_id, '' );
2829
  }
2830
  add_action( 'wpmu_delete_user', 'bp_remove_member_type_on_user_delete' );
2831
- add_action( 'delete_user', 'bp_remove_member_type_on_user_delete' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2832
 
2833
  /**
2834
  * Get the "current" member type, if one is provided, in member directories.
@@ -2848,3 +2931,47 @@ function bp_get_current_member_type() {
2848
  */
2849
  return apply_filters( 'bp_get_current_member_type', buddypress()->current_member_type );
2850
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1261
  return $retval;
1262
  }
1263
 
1264
+ /**
1265
+ * Determines whether user data should be removed on the 'delete_user' hook.
1266
+ *
1267
+ * WordPress's 'delete_user' hook is ambiguous: on a standard installation, it means that a user
1268
+ * account is being removed from the system, while on Multisite it simply means the user is
1269
+ * being removed from a specific site (ie its roles are being revoked). As a rule, this means
1270
+ * that BuddyPress should remove user data on the delete_user hook only on non-Multisite
1271
+ * installations - only when the user account is being removed altogether. However, this behavior
1272
+ * can be filtered in a global, per-user, or per-component fashion.
1273
+ *
1274
+ * @since 6.0.0
1275
+ *
1276
+ * @param string $data_type Type of data to be removed.
1277
+ * @param int $user_id ID of the user, as passed to 'delete_user'.
1278
+ * @return bool
1279
+ */
1280
+ function bp_remove_user_data_on_delete_user_hook( $component, $user_id ) {
1281
+ $remove = ! is_multisite();
1282
+
1283
+ /**
1284
+ * Filters whether to remove user data on the 'delete_user' hook.
1285
+ *
1286
+ * @param bool $remove Whether data should be removed.
1287
+ * @param string $data_type Type of data to be removed.
1288
+ * @param int $user_id ID of the user, as passed to 'delete_user'.
1289
+ */
1290
+ return apply_filters( 'bp_remove_user_data_on_delete_user_hook', $remove, $component, $user_id );
1291
+ }
1292
+
1293
  /**
1294
  * Delete a user's avatar when the user is deleted.
1295
  *
1305
  ) );
1306
  }
1307
  add_action( 'wpmu_delete_user', 'bp_core_delete_avatar_on_user_delete' );
1308
+
1309
+ /**
1310
+ * Deletes last_activity data on the 'delete_user' hook.
1311
+ *
1312
+ * @since 6.0.0
1313
+ *
1314
+ * @param int $user_id The ID of the deleted user.
1315
+ */
1316
+ function bp_core_delete_avatar_on_delete_user( $user_id ) {
1317
+ if ( ! bp_remove_user_data_on_delete_user_hook( 'avatar', $user_id ) ) {
1318
+ return;
1319
+ }
1320
+
1321
+ bp_core_delete_avatar_on_user_delete( $user_id );
1322
+ }
1323
+ add_action( 'delete_user', 'bp_core_delete_avatar_on_delete_user' );
1324
 
1325
  /**
1326
  * Multibyte-safe ucfirst() support.
1388
  wp_cache_flush();
1389
  }
1390
  add_action( 'wpmu_delete_user', 'bp_core_remove_data' );
 
1391
  add_action( 'bp_make_spam_user', 'bp_core_remove_data' );
1392
 
1393
+ /**
1394
+ * Deletes last_activity data on the 'delete_user' hook.
1395
+ *
1396
+ * @since 6.0.0
1397
+ *
1398
+ * @param int $user_id The ID of the deleted user.
1399
+ */
1400
+ function bp_core_remove_data_on_delete_user( $user_id ) {
1401
+ if ( ! bp_remove_user_data_on_delete_user_hook( 'last_activity', $user_id ) ) {
1402
+ return;
1403
+ }
1404
+
1405
+ bp_core_remove_data( $user_id );
1406
+ }
1407
+ add_action( 'delete_user', 'bp_core_remove_data_on_delete_user' );
1408
+
1409
  /**
1410
  * Check whether the logged-in user can edit settings for the displayed user.
1411
  *
1982
  // Set up data to pass to the legacy filter.
1983
  $user = array(
1984
  'user_id' => $user_id,
1985
+ 'password' => isset( $signup->meta['password'] ) ? $signup->meta['password'] : '',
1986
  'meta' => $signup->meta,
1987
  );
1988
 
2332
  'bp-resend-activation'
2333
  );
2334
 
2335
+ $resend_string = '<br /><br />';
2336
+
2337
+ /* translators: %s: the activation url */
2338
+ $resend_string .= sprintf( __( 'If you have not received an email yet, <a href="%s">click here to resend it</a>.', 'buddypress' ), esc_url( $resend_url ) );
2339
 
2340
  return new WP_Error( 'bp_account_not_activated', __( '<strong>ERROR</strong>: Your account has not been activated. Check your email for the activation link.', 'buddypress' ) . $resend_string );
2341
  }
2781
  return false;
2782
  }
2783
 
2784
+ // No need to continue if the member doesn't have the type.
2785
+ $existing_types = bp_get_member_type( $user_id, false );
2786
+ if ( ! in_array( $member_type, $existing_types, true ) ) {
2787
+ return false;
2788
+ }
2789
+
2790
  $deleted = bp_remove_object_terms( $user_id, $member_type, bp_get_member_type_tax_name() );
2791
 
2792
  // Bust the cache if the type has been removed.
2896
  return bp_set_member_type( $user_id, '' );
2897
  }
2898
  add_action( 'wpmu_delete_user', 'bp_remove_member_type_on_user_delete' );
2899
+
2900
+ /**
2901
+ * Deletes user member type on the 'delete_user' hook.
2902
+ *
2903
+ * @since 6.0.0
2904
+ *
2905
+ * @param int $user_id The ID of the deleted user.
2906
+ */
2907
+ function bp_remove_member_type_on_delete_user( $user_id ) {
2908
+ if ( ! bp_remove_user_data_on_delete_user_hook( 'member_type', $user_id ) ) {
2909
+ return;
2910
+ }
2911
+
2912
+ bp_remove_member_type_on_user_delete( $user_id );
2913
+ }
2914
+ add_action( 'delete_user', 'bp_remove_member_type_on_delete_user' );
2915
 
2916
  /**
2917
  * Get the "current" member type, if one is provided, in member directories.
2931
  */
2932
  return apply_filters( 'bp_get_current_member_type', buddypress()->current_member_type );
2933
  }
2934
+
2935
+ /**
2936
+ * Setup the avatar upload directory for a user.
2937
+ *
2938
+ * @since 6.0.0
2939
+ *
2940
+ * @param string $directory The root directory name. Optional.
2941
+ * @param int $user_id The user ID. Optional.
2942
+ * @return array Array containing the path, URL, and other helpful settings.
2943
+ */
2944
+ function bp_members_avatar_upload_dir( $directory = 'avatars', $user_id = 0 ) {
2945
+
2946
+ // Use displayed user if no user ID was passed.
2947
+ if ( empty( $user_id ) ) {
2948
+ $user_id = bp_displayed_user_id();
2949
+ }
2950
+
2951
+ // Failsafe against accidentally nooped $directory parameter.
2952
+ if ( empty( $directory ) ) {
2953
+ $directory = 'avatars';
2954
+ }
2955
+
2956
+ $path = bp_core_avatar_upload_path() . '/' . $directory. '/' . $user_id;
2957
+ $newbdir = $path;
2958
+ $newurl = bp_core_avatar_url() . '/' . $directory. '/' . $user_id;
2959
+ $newburl = $newurl;
2960
+ $newsubdir = '/' . $directory. '/' . $user_id;
2961
+
2962
+ /**
2963
+ * Filters the avatar upload directory for a user.
2964
+ *
2965
+ * @since 6.0.0
2966
+ *
2967
+ * @param array $value Array containing the path, URL, and other helpful settings.
2968
+ */
2969
+ return apply_filters( 'bp_members_avatar_upload_dir', array(
2970
+ 'path' => $path,
2971
+ 'url' => $newurl,
2972
+ 'subdir' => $newsubdir,
2973
+ 'basedir' => $newbdir,
2974
+ 'baseurl' => $newburl,
2975
+ 'error' => false
2976
+ ) );
2977
+ }
bp-members/bp-members-template.php CHANGED
@@ -481,24 +481,28 @@ function bp_members_pagination_count() {
481
  if ( 1 == $members_template->total_member_count ) {
482
  $pag = __( 'Viewing 1 active member', 'buddypress' );
483
  } else {
 
484
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s active member', 'Viewing %1$s - %2$s of %3$s active members', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
485
  }
486
  } elseif ( 'popular' == $members_template->type ) {
487
  if ( 1 == $members_template->total_member_count ) {
488
  $pag = __( 'Viewing 1 member with friends', 'buddypress' );
489
  } else {
 
490
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s member with friends', 'Viewing %1$s - %2$s of %3$s members with friends', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
491
  }
492
  } elseif ( 'online' == $members_template->type ) {
493
  if ( 1 == $members_template->total_member_count ) {
494
  $pag = __( 'Viewing 1 online member', 'buddypress' );
495
  } else {
 
496
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s online member', 'Viewing %1$s - %2$s of %3$s online members', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
497
  }
498
  } else {
499
  if ( 1 == $members_template->total_member_count ) {
500
  $pag = __( 'Viewing 1 member', 'buddypress' );
501
  } else {
 
502
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s member', 'Viewing %1$s - %2$s of %3$s members', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
503
  }
504
  }
@@ -1040,6 +1044,7 @@ function bp_member_latest_update( $args = '' ) {
1040
  */
1041
  $update_content = apply_filters( 'bp_get_activity_latest_update_excerpt', trim( strip_tags( bp_create_excerpt( $update['content'], $length ) ) ), $r );
1042
 
 
1043
  $update_content = sprintf( _x( '- &quot;%s&quot;', 'member latest update in member directory', 'buddypress' ), $update_content );
1044
 
1045
  // If $view_link is true and the text returned by bp_create_excerpt() is different from the original text (ie it's
@@ -1205,6 +1210,7 @@ function bp_member_registered( $args = array() ) {
1205
  return esc_attr( $members_template->member->user_registered );
1206
  }
1207
 
 
1208
  $registered = esc_attr( bp_core_get_last_activity( $members_template->member->user_registered, _x( 'registered %s', 'Records the timestamp that the user registered into the activity stream', 'buddypress' ) ) );
1209
 
1210
  /**
@@ -1510,7 +1516,7 @@ function bp_get_displayed_user_nav() {
1510
  * False otherwise
1511
  */
1512
  function bp_displayed_user_use_cover_image_header() {
1513
- return (bool) bp_is_active( 'xprofile', 'cover_image' ) && ! bp_disable_cover_image_uploads() && bp_attachments_is_wp_version_supported();
1514
  }
1515
 
1516
  /** Avatars *******************************************************************/
@@ -2007,6 +2013,7 @@ function bp_current_member_type_message() {
2007
  function bp_get_current_member_type_message() {
2008
  $type_object = bp_get_member_type_object( bp_get_current_member_type() );
2009
 
 
2010
  $message = sprintf( __( 'Viewing members of the type: %s', 'buddypress' ), '<strong>' . $type_object->labels['singular_name'] . '</strong>' );
2011
 
2012
  /**
@@ -2645,3 +2652,34 @@ function bp_members_component_link( $component, $action = '', $query_args = '',
2645
  if ( !empty( $url ) )
2646
  return $url;
2647
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
481
  if ( 1 == $members_template->total_member_count ) {
482
  $pag = __( 'Viewing 1 active member', 'buddypress' );
483
  } else {
484
+ /* translators: 1: active member from number. 2: active member to number. 3: total active members. */
485
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s active member', 'Viewing %1$s - %2$s of %3$s active members', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
486
  }
487
  } elseif ( 'popular' == $members_template->type ) {
488
  if ( 1 == $members_template->total_member_count ) {
489
  $pag = __( 'Viewing 1 member with friends', 'buddypress' );
490
  } else {
491
+ /* translators: 1: member with friends from number. 2: member with friends to number. 3: total members with friends. */
492
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s member with friends', 'Viewing %1$s - %2$s of %3$s members with friends', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
493
  }
494
  } elseif ( 'online' == $members_template->type ) {
495
  if ( 1 == $members_template->total_member_count ) {
496
  $pag = __( 'Viewing 1 online member', 'buddypress' );
497
  } else {
498
+ /* translators: 1: online member from number. 2: online member to number. 3: total online members. */
499
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s online member', 'Viewing %1$s - %2$s of %3$s online members', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
500
  }
501
  } else {
502
  if ( 1 == $members_template->total_member_count ) {
503
  $pag = __( 'Viewing 1 member', 'buddypress' );
504
  } else {
505
+ /* translators: 1: member from number. 2: member to number. 3: total members. */
506
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s member', 'Viewing %1$s - %2$s of %3$s members', $members_template->total_member_count, 'buddypress' ), $from_num, $to_num, $total );
507
  }
508
  }
1044
  */
1045
  $update_content = apply_filters( 'bp_get_activity_latest_update_excerpt', trim( strip_tags( bp_create_excerpt( $update['content'], $length ) ) ), $r );
1046
 
1047
+ /* translators: %s: the member latest activity update */
1048
  $update_content = sprintf( _x( '- &quot;%s&quot;', 'member latest update in member directory', 'buddypress' ), $update_content );
1049
 
1050
  // If $view_link is true and the text returned by bp_create_excerpt() is different from the original text (ie it's
1210
  return esc_attr( $members_template->member->user_registered );
1211
  }
1212
 
1213
+ /* translators: %s: last activity timestamp (e.g. "active 1 hour ago") */
1214
  $registered = esc_attr( bp_core_get_last_activity( $members_template->member->user_registered, _x( 'registered %s', 'Records the timestamp that the user registered into the activity stream', 'buddypress' ) ) );
1215
 
1216
  /**
1516
  * False otherwise
1517
  */
1518
  function bp_displayed_user_use_cover_image_header() {
1519
+ return (bool) bp_is_active( 'members', 'cover_image' ) && ! bp_disable_cover_image_uploads();
1520
  }
1521
 
1522
  /** Avatars *******************************************************************/
2013
  function bp_get_current_member_type_message() {
2014
  $type_object = bp_get_member_type_object( bp_get_current_member_type() );
2015
 
2016
+ /* translators: %s: member type singular name */
2017
  $message = sprintf( __( 'Viewing members of the type: %s', 'buddypress' ), '<strong>' . $type_object->labels['singular_name'] . '</strong>' );
2018
 
2019
  /**
2652
  if ( !empty( $url ) )
2653
  return $url;
2654
  }
2655
+
2656
+
2657
+ /**
2658
+ * Render an avatar delete link.
2659
+ *
2660
+ * @since 1.1.0
2661
+ * @since 6.0.0 Moved from /bp-xprofile/bp-xprofile-template.php to this file.
2662
+ */
2663
+ function bp_avatar_delete_link() {
2664
+ echo bp_get_avatar_delete_link();
2665
+ }
2666
+
2667
+ /**
2668
+ * Return an avatar delete link.
2669
+ *
2670
+ * @since 1.1.0
2671
+ * @since 6.0.0 Moved from /bp-xprofile/bp-xprofile-template.php to this file.
2672
+ *
2673
+ * @return string
2674
+ */
2675
+ function bp_get_avatar_delete_link() {
2676
+
2677
+ /**
2678
+ * Filters the link used for deleting an avatar.
2679
+ *
2680
+ * @since 1.1.0
2681
+ *
2682
+ * @param string $value Nonced URL used for deleting an avatar.
2683
+ */
2684
+ return apply_filters( 'bp_get_avatar_delete_link', wp_nonce_url( bp_displayed_user_domain() . bp_get_profile_slug() . '/change-avatar/delete-avatar/', 'bp_delete_avatar_link' ) );
2685
+ }
bp-members/classes/class-bp-members-admin.php CHANGED
@@ -642,6 +642,22 @@ class BP_Members_Admin {
642
  */
643
  $js = apply_filters( 'bp_members_admin_js', $js );
644
  wp_enqueue_script( 'bp-members-js', $js, array( 'jquery' ), bp_get_version(), true );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
645
  }
646
 
647
  /**
@@ -723,6 +739,7 @@ class BP_Members_Admin {
723
  * help, and setting up screen options.
724
  *
725
  * @since 2.0.0
 
726
  */
727
  public function user_admin_load() {
728
 
@@ -819,16 +836,35 @@ class BP_Members_Admin {
819
  $display_name = __( 'Member', 'buddypress' );
820
  }
821
 
 
 
 
822
  // User Stat metabox.
823
  add_meta_box(
824
  'bp_members_admin_user_stats',
825
- sprintf( _x( "%s's Stats", 'members user-admin edit screen', 'buddypress' ), $display_name ),
 
 
 
 
826
  array( $this, 'user_admin_stats_metabox' ),
827
- get_current_screen()->id,
828
  sanitize_key( $this->stats_metabox->context ),
829
  sanitize_key( $this->stats_metabox->priority )
830
  );
831
 
 
 
 
 
 
 
 
 
 
 
 
 
832
  // Member Type metabox. Only added if member types have been registered.
833
  $member_types = bp_get_member_types();
834
  if ( ! empty( $member_types ) ) {
@@ -836,7 +872,7 @@ class BP_Members_Admin {
836
  'bp_members_admin_member_type',
837
  _x( 'Member Type', 'members user-admin edit screen', 'buddypress' ),
838
  array( $this, 'user_admin_member_type_metabox' ),
839
- get_current_screen()->id,
840
  'side',
841
  'core'
842
  );
@@ -874,6 +910,22 @@ class BP_Members_Admin {
874
 
875
  bp_core_redirect( $redirect_to );
876
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
877
  // Update other stuff once above ones are done.
878
  } else {
879
  $this->redirect = $redirect_to;
@@ -1090,7 +1142,12 @@ class BP_Members_Admin {
1090
  $datef = __( 'M j, Y @ G:i', 'buddypress' );
1091
  $date = date_i18n( $datef, strtotime( $user->user_registered ) );
1092
  ?>
1093
- <span id="timestamp"><?php printf( __( 'Registered on: %s', 'buddypress' ), '<strong>' . $date . '</strong>' ); ?></span>
 
 
 
 
 
1094
  </div>
1095
  </div> <!-- #misc-publishing-actions -->
1096
 
@@ -1120,7 +1177,12 @@ class BP_Members_Admin {
1120
  */
1121
  public function user_admin_spammer_metabox( $user = null ) {
1122
  ?>
1123
- <p><?php printf( __( '%s has been marked as a spammer. All BuddyPress data associated with the user has been removed', 'buddypress' ), esc_html( bp_core_get_user_displayname( $user->ID ) ) ) ;?></p>
 
 
 
 
 
1124
  <?php
1125
  }
1126
 
@@ -1151,7 +1213,12 @@ class BP_Members_Admin {
1151
  $date = date_i18n( $datef, strtotime( $last_active ) ); ?>
1152
 
1153
  <ul>
1154
- <li class="bp-members-profile-stats"><?php printf( __( 'Last active: %1$s', 'buddypress' ), '<strong>' . $date . '</strong>' ); ?></li>
 
 
 
 
 
1155
 
1156
  <?php
1157
  // Loading other stats only if user has activated their account.
@@ -1173,6 +1240,61 @@ class BP_Members_Admin {
1173
  <?php
1174
  }
1175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1176
  /**
1177
  * Render the Member Type metabox.
1178
  *
@@ -1438,8 +1560,10 @@ class BP_Members_Admin {
1438
  $base_url = bp_get_admin_url( 'users.php' );
1439
  }
1440
 
1441
- $url = add_query_arg( 'page', 'bp-signups', $base_url );
1442
- $text = sprintf( _x( 'Pending %s', 'signup users', 'buddypress' ), '<span class="count">(' . number_format_i18n( $signups ) . ')</span>' );
 
 
1443
 
1444
  $views['registered'] = sprintf( '<a href="%1$s" class="%2$s">%3$s</a>', esc_url( $url ), $class, $text );
1445
 
@@ -1708,6 +1832,7 @@ class BP_Members_Admin {
1708
 
1709
  if ( ! empty( $_REQUEST['resent'] ) ) {
1710
  $notice['message'] .= sprintf(
 
1711
  _nx( '%s activation email successfully sent! ', '%s activation emails successfully sent! ',
1712
  absint( $_REQUEST['resent'] ),
1713
  'signup resent',
@@ -1719,6 +1844,7 @@ class BP_Members_Admin {
1719
 
1720
  if ( ! empty( $_REQUEST['notsent'] ) ) {
1721
  $notice['message'] .= sprintf(
 
1722
  _nx( '%s activation email was not sent.', '%s activation emails were not sent.',
1723
  absint( $_REQUEST['notsent'] ),
1724
  'signup notsent',
@@ -1742,6 +1868,7 @@ class BP_Members_Admin {
1742
 
1743
  if ( ! empty( $_REQUEST['activated'] ) ) {
1744
  $notice['message'] .= sprintf(
 
1745
  _nx( '%s account successfully activated! ', '%s accounts successfully activated! ',
1746
  absint( $_REQUEST['activated'] ),
1747
  'signup resent',
@@ -1753,6 +1880,7 @@ class BP_Members_Admin {
1753
 
1754
  if ( ! empty( $_REQUEST['notactivated'] ) ) {
1755
  $notice['message'] .= sprintf(
 
1756
  _nx( '%s account was not activated.', '%s accounts were not activated.',
1757
  absint( $_REQUEST['notactivated'] ),
1758
  'signup notsent',
@@ -1776,6 +1904,7 @@ class BP_Members_Admin {
1776
 
1777
  if ( ! empty( $_REQUEST['deleted'] ) ) {
1778
  $notice['message'] .= sprintf(
 
1779
  _nx( '%s sign-up successfully deleted!', '%s sign-ups successfully deleted!',
1780
  absint( $_REQUEST['deleted'] ),
1781
  'signup deleted',
@@ -1787,6 +1916,7 @@ class BP_Members_Admin {
1787
 
1788
  if ( ! empty( $_REQUEST['notdeleted'] ) ) {
1789
  $notice['message'] .= sprintf(
 
1790
  _nx( '%s sign-up was not deleted.', '%s sign-ups were not deleted.',
1791
  absint( $_REQUEST['notdeleted'] ),
1792
  'signup notdeleted',
@@ -2155,14 +2285,40 @@ class BP_Members_Admin {
2155
 
2156
  <?php endif; ?>
2157
 
 
 
 
 
 
 
 
 
 
 
 
2158
  </tbody>
2159
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
2160
  <?php endif; ?>
2161
 
2162
  <?php if ( 'resend' == $action ) : ?>
2163
 
2164
  <p class="description">
2165
- <?php printf( esc_html__( 'Last notified: %s', 'buddypress'), $last_notified ) ;?>
 
 
 
2166
 
2167
  <?php if ( ! empty( $signup->recently_sent ) ) : ?>
2168
 
642
  */
643
  $js = apply_filters( 'bp_members_admin_js', $js );
644
  wp_enqueue_script( 'bp-members-js', $js, array( 'jquery' ), bp_get_version(), true );
645
+
646
+ if ( ! bp_core_get_root_option( 'bp-disable-avatar-uploads' ) && buddypress()->avatar->show_avatars ) {
647
+ /**
648
+ * Get Thickbox.
649
+ *
650
+ * We cannot simply use add_thickbox() here as WordPress is not playing
651
+ * nice with Thickbox width/height see https://core.trac.wordpress.org/ticket/17249
652
+ * Using media-upload might be interesting in the future for the send to editor stuff
653
+ * and we make sure the tb_window is wide enough
654
+ */
655
+ wp_enqueue_style ( 'thickbox' );
656
+ wp_enqueue_script( 'media-upload' );
657
+
658
+ // Get Avatar Uploader.
659
+ bp_attachments_enqueue_scripts( 'BP_Attachment_Avatar' );
660
+ }
661
  }
662
 
663
  /**
739
  * help, and setting up screen options.
740
  *
741
  * @since 2.0.0
742
+ * @since 6.0.0 The `delete_avatar` action is now managed into this method.
743
  */
744
  public function user_admin_load() {
745
 
836
  $display_name = __( 'Member', 'buddypress' );
837
  }
838
 
839
+ // Set the screen id.
840
+ $screen_id = get_current_screen()->id;
841
+
842
  // User Stat metabox.
843
  add_meta_box(
844
  'bp_members_admin_user_stats',
845
+ sprintf(
846
+ /* translators: %s: member name */
847
+ _x( "%s's Stats", 'members user-admin edit screen', 'buddypress' ),
848
+ $display_name
849
+ ),
850
  array( $this, 'user_admin_stats_metabox' ),
851
+ $screen_id,
852
  sanitize_key( $this->stats_metabox->context ),
853
  sanitize_key( $this->stats_metabox->priority )
854
  );
855
 
856
+ if ( buddypress()->avatar->show_avatars ) {
857
+ // Avatar Metabox.
858
+ add_meta_box(
859
+ 'bp_members_user_admin_avatar',
860
+ _x( 'Profile Photo', 'members user-admin edit screen', 'buddypress' ),
861
+ array( $this, 'user_admin_avatar_metabox' ),
862
+ $screen_id,
863
+ 'side',
864
+ 'low'
865
+ );
866
+ }
867
+
868
  // Member Type metabox. Only added if member types have been registered.
869
  $member_types = bp_get_member_types();
870
  if ( ! empty( $member_types ) ) {
872
  'bp_members_admin_member_type',
873
  _x( 'Member Type', 'members user-admin edit screen', 'buddypress' ),
874
  array( $this, 'user_admin_member_type_metabox' ),
875
+ $screen_id,
876
  'side',
877
  'core'
878
  );
910
 
911
  bp_core_redirect( $redirect_to );
912
 
913
+ // Eventually delete avatar.
914
+ } elseif ( 'delete_avatar' === $doaction ) {
915
+
916
+ // Check the nonce.
917
+ check_admin_referer( 'delete_avatar' );
918
+
919
+ $redirect_to = remove_query_arg( '_wpnonce', $redirect_to );
920
+
921
+ if ( bp_core_delete_existing_avatar( array( 'item_id' => $user_id ) ) ) {
922
+ $redirect_to = add_query_arg( 'updated', 'avatar', $redirect_to );
923
+ } else {
924
+ $redirect_to = add_query_arg( 'error', 'avatar', $redirect_to );
925
+ }
926
+
927
+ bp_core_redirect( $redirect_to );
928
+
929
  // Update other stuff once above ones are done.
930
  } else {
931
  $this->redirect = $redirect_to;
1142
  $datef = __( 'M j, Y @ G:i', 'buddypress' );
1143
  $date = date_i18n( $datef, strtotime( $user->user_registered ) );
1144
  ?>
1145
+ <span id="timestamp">
1146
+ <?php
1147
+ /* translators: %s: registration date */
1148
+ printf( __( 'Registered on: %s', 'buddypress' ), '<strong>' . $date . '</strong>' );
1149
+ ?>
1150
+ </span>
1151
  </div>
1152
  </div> <!-- #misc-publishing-actions -->
1153
 
1177
  */
1178
  public function user_admin_spammer_metabox( $user = null ) {
1179
  ?>
1180
+ <p>
1181
+ <?php
1182
+ /* translators: %s: member name */
1183
+ printf( __( '%s has been marked as a spammer. All BuddyPress data associated with the user has been removed', 'buddypress' ), esc_html( bp_core_get_user_displayname( $user->ID ) ) );
1184
+ ?>
1185
+ </p>
1186
  <?php
1187
  }
1188
 
1213
  $date = date_i18n( $datef, strtotime( $last_active ) ); ?>
1214
 
1215
  <ul>
1216
+ <li class="bp-members-profile-stats">
1217
+ <?php
1218
+ /* translators: %s: date */
1219
+ printf( __( 'Last active: %1$s', 'buddypress' ), '<strong>' . $date . '</strong>' );
1220
+ ?>
1221
+ </li>
1222
 
1223
  <?php
1224
  // Loading other stats only if user has activated their account.
1240
  <?php
1241
  }
1242
 
1243
+ /**
1244
+ * Render the Avatar metabox to moderate inappropriate images.
1245
+ *
1246
+ * @since 6.0.0
1247
+ *
1248
+ * @param WP_User|null $user The WP_User object for the user being edited.
1249
+ */
1250
+ public function user_admin_avatar_metabox( $user = null ) {
1251
+
1252
+ if ( empty( $user->ID ) ) {
1253
+ return;
1254
+ } ?>
1255
+
1256
+ <div class="avatar">
1257
+
1258
+ <?php echo bp_core_fetch_avatar( array(
1259
+ 'item_id' => $user->ID,
1260
+ 'object' => 'user',
1261
+ 'type' => 'full',
1262
+ 'title' => $user->display_name
1263
+ ) ); ?>
1264
+
1265
+ <?php if ( bp_get_user_has_avatar( $user->ID ) ) :
1266
+
1267
+ $query_args = array(
1268
+ 'user_id' => $user->ID,
1269
+ 'action' => 'delete_avatar'
1270
+ );
1271
+
1272
+ if ( ! empty( $_REQUEST['wp_http_referer'] ) ) {
1273
+ $wp_http_referer = wp_unslash( $_REQUEST['wp_http_referer'] );
1274
+ $wp_http_referer = remove_query_arg( array( 'action', 'updated' ), $wp_http_referer );
1275
+ $wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) );
1276
+ $query_args['wp_http_referer'] = urlencode( $wp_http_referer );
1277
+ }
1278
+
1279
+ $community_url = add_query_arg( $query_args, $this->edit_profile_url );
1280
+ $delete_link = wp_nonce_url( $community_url, 'delete_avatar' ); ?>
1281
+
1282
+ <a href="<?php echo esc_url( $delete_link ); ?>" class="bp-members-avatar-user-admin"><?php esc_html_e( 'Delete Profile Photo', 'buddypress' ); ?></a>
1283
+
1284
+ <?php endif;
1285
+
1286
+ // Load the Avatar UI templates if user avatar uploads are enabled.
1287
+ if ( ! bp_core_get_root_option( 'bp-disable-avatar-uploads' ) ) : ?>
1288
+ <a href="#TB_inline?width=800px&height=400px&inlineId=bp-members-avatar-editor" class="thickbox bp-members-avatar-user-edit"><?php esc_html_e( 'Edit Profile Photo', 'buddypress' ); ?></a>
1289
+ <div id="bp-members-avatar-editor" style="display:none;">
1290
+ <?php bp_attachments_get_template_part( 'avatars/index' ); ?>
1291
+ </div>
1292
+ <?php endif; ?>
1293
+
1294
+ </div>
1295
+ <?php
1296
+ }
1297
+
1298
  /**
1299
  * Render the Member Type metabox.
1300
  *
1560
  $base_url = bp_get_admin_url( 'users.php' );
1561
  }
1562
 
1563
+ $url = add_query_arg( 'page', 'bp-signups', $base_url );
1564
+
1565
+ /* translators: %s: number of pending accounts */
1566
+ $text = sprintf( _x( 'Pending %s', 'signup users', 'buddypress' ), '<span class="count">(' . number_format_i18n( $signups ) . ')</span>' );
1567
 
1568
  $views['registered'] = sprintf( '<a href="%1$s" class="%2$s">%3$s</a>', esc_url( $url ), $class, $text );
1569
 
1832
 
1833
  if ( ! empty( $_REQUEST['resent'] ) ) {
1834
  $notice['message'] .= sprintf(
1835
+ /* translators: %s: number of activation emails sent */
1836
  _nx( '%s activation email successfully sent! ', '%s activation emails successfully sent! ',
1837
  absint( $_REQUEST['resent'] ),
1838
  'signup resent',
1844
 
1845
  if ( ! empty( $_REQUEST['notsent'] ) ) {
1846
  $notice['message'] .= sprintf(
1847
+ /* translators: %s: number of unsent activation emails */
1848
  _nx( '%s activation email was not sent.', '%s activation emails were not sent.',
1849
  absint( $_REQUEST['notsent'] ),
1850
  'signup notsent',
1868
 
1869
  if ( ! empty( $_REQUEST['activated'] ) ) {
1870
  $notice['message'] .= sprintf(
1871
+ /* translators: %s: number of activated accounts */
1872
  _nx( '%s account successfully activated! ', '%s accounts successfully activated! ',
1873
  absint( $_REQUEST['activated'] ),
1874
  'signup resent',
1880
 
1881
  if ( ! empty( $_REQUEST['notactivated'] ) ) {
1882
  $notice['message'] .= sprintf(
1883
+ /* translators: %s: number of accounts not activated */
1884
  _nx( '%s account was not activated.', '%s accounts were not activated.',
1885
  absint( $_REQUEST['notactivated'] ),
1886
  'signup notsent',
1904
 
1905
  if ( ! empty( $_REQUEST['deleted'] ) ) {
1906
  $notice['message'] .= sprintf(
1907
+ /* translators: %s: number of deleted signups */
1908
  _nx( '%s sign-up successfully deleted!', '%s sign-ups successfully deleted!',
1909
  absint( $_REQUEST['deleted'] ),
1910
  'signup deleted',
1916
 
1917
  if ( ! empty( $_REQUEST['notdeleted'] ) ) {
1918
  $notice['message'] .= sprintf(
1919
+ /* translators: %s: number of deleted signups not deleted */
1920
  _nx( '%s sign-up was not deleted.', '%s sign-ups were not deleted.',
1921
  absint( $_REQUEST['notdeleted'] ),
1922
  'signup notdeleted',
2285
 
2286
  <?php endif; ?>
2287
 
2288
+ <?php
2289
+ /**
2290
+ * Fires inside the table listing the activate action confirmation details.
2291
+ *
2292
+ * @since 6.0.0
2293
+ *
2294
+ * @param object $signup The Sign-up Object.
2295
+ */
2296
+ do_action( 'bp_activate_signup_confirmation_details', $signup );
2297
+ ?>
2298
+
2299
  </tbody>
2300
  </table>
2301
+
2302
+ <?php
2303
+ /**
2304
+ * Fires outside the table listing the activate action confirmation details.
2305
+ *
2306
+ * @since 6.0.0
2307
+ *
2308
+ * @param object $signup The Sign-up Object.
2309
+ */
2310
+ do_action( 'bp_activate_signup_confirmation_after_details', $signup );
2311
+ ?>
2312
+
2313
  <?php endif; ?>
2314
 
2315
  <?php if ( 'resend' == $action ) : ?>
2316
 
2317
  <p class="description">
2318
+ <?php
2319
+ /* translators: %s: notification date */
2320
+ printf( esc_html__( 'Last notified: %s', 'buddypress'), $last_notified );
2321
+ ?>
2322
 
2323
  <?php if ( ! empty( $signup->recently_sent ) ) : ?>
2324
 
bp-members/classes/class-bp-members-component.php CHANGED
@@ -61,6 +61,7 @@ class BP_Members_Component extends BP_Component {
61
  'template',
62
  'adminbar',
63
  'functions',
 
64
  'widgets',
65
  'cache',
66
  );
@@ -106,6 +107,18 @@ class BP_Members_Component extends BP_Component {
106
  // Members - User main nav screen.
107
  if ( bp_is_user() ) {
108
  require $this->path . 'bp-members/screens/profile.php';
 
 
 
 
 
 
 
 
 
 
 
 
109
  }
110
 
111
  // Members - Theme compatibility.
@@ -288,6 +301,49 @@ class BP_Members_Component extends BP_Component {
288
  }
289
  }
290
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  /**
292
  * Set up fall-back component navigation if XProfile is inactive.
293
  *
@@ -311,6 +367,7 @@ class BP_Members_Component extends BP_Component {
311
 
312
  // Bail if XProfile component is active and there's no custom front page for the user.
313
  if ( ! bp_displayed_user_has_front_template() && $is_xprofile_active ) {
 
314
  return;
315
  }
316
 
@@ -339,6 +396,15 @@ class BP_Members_Component extends BP_Component {
339
  'default_subnav_slug' => 'public',
340
  'item_css_id' => buddypress()->profile->id
341
  );
 
 
 
 
 
 
 
 
 
342
  }
343
 
344
  /**
@@ -393,7 +459,11 @@ class BP_Members_Component extends BP_Component {
393
  */
394
  } else {
395
  $main_nav = $this->main_nav;
396
- $sub_nav[] = $this->sub_nav;
 
 
 
 
397
  }
398
 
399
 
@@ -417,6 +487,129 @@ class BP_Members_Component extends BP_Component {
417
 
418
  // Add the sub nav item.
419
  bp_core_new_subnav_item( $this->sub_nav, 'members' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  }
421
 
422
  /**
@@ -461,18 +654,86 @@ class BP_Members_Component extends BP_Component {
461
  * Init the BP REST API.
462
  *
463
  * @since 5.0.0
 
464
  *
465
  * @param array $controllers Optional. See BP_Component::rest_api_init() for
466
  * description.
467
  */
468
  public function rest_api_init( $controllers = array() ) {
469
- parent::rest_api_init( array(
470
  /**
471
  * As the Members component is always loaded,
472
  * let's register the Components endpoint here.
473
  */
474
  'BP_REST_Components_Endpoint',
475
  'BP_REST_Members_Endpoint',
476
- ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  }
478
  }
61
  'template',
62
  'adminbar',
63
  'functions',
64
+ 'blocks',
65
  'widgets',
66
  'cache',
67
  );
107
  // Members - User main nav screen.
108
  if ( bp_is_user() ) {
109
  require $this->path . 'bp-members/screens/profile.php';
110
+
111
+ // Action - Delete avatar.
112
+ if ( is_user_logged_in()&& bp_is_user_change_avatar() && bp_is_action_variable( 'delete-avatar', 0 ) ) {
113
+ require $this->path . 'bp-members/actions/delete-avatar.php';
114
+ }
115
+
116
+ // Sub-nav items.
117
+ if ( is_user_logged_in() &&
118
+ in_array( bp_current_action(), array( 'change-avatar', 'change-cover-image' ), true )
119
+ ) {
120
+ require $this->path . 'bp-members/screens/' . bp_current_action() . '.php';
121
+ }
122
  }
123
 
124
  // Members - Theme compatibility.
301
  }
302
  }
303
 
304
+ /**
305
+ * Get the Avatar and Cover image subnavs.
306
+ *
307
+ * @since 6.0.0
308
+ *
309
+ * @return array The Avatar and Cover image subnavs.
310
+ */
311
+ public function get_avatar_cover_image_subnavs() {
312
+ $subnavs = array();
313
+
314
+ $access = bp_core_can_edit_settings();
315
+ $slug = bp_get_profile_slug();
316
+ $profile_link = bp_get_members_component_link( $slug );
317
+
318
+ // Change Avatar.
319
+ if ( buddypress()->avatar->show_avatars ) {
320
+ $subnavs[] = array(
321
+ 'name' => _x( 'Change Profile Photo', 'Profile header sub menu', 'buddypress' ),
322
+ 'slug' => 'change-avatar',
323
+ 'parent_url' => $profile_link,
324
+ 'parent_slug' => $slug,
325
+ 'screen_function' => 'bp_members_screen_change_avatar',
326
+ 'position' => 30,
327
+ 'user_has_access' => $access
328
+ );
329
+ }
330
+
331
+ // Change Cover image.
332
+ if ( bp_displayed_user_use_cover_image_header() ) {
333
+ $subnavs[] = array(
334
+ 'name' => _x( 'Change Cover Image', 'Profile header sub menu', 'buddypress' ),
335
+ 'slug' => 'change-cover-image',
336
+ 'parent_url' => $profile_link,
337
+ 'parent_slug' => $slug,
338
+ 'screen_function' => 'bp_members_screen_change_cover_image',
339
+ 'position' => 40,
340
+ 'user_has_access' => $access
341
+ );
342
+ }
343
+
344
+ return $subnavs;
345
+ }
346
+
347
  /**
348
  * Set up fall-back component navigation if XProfile is inactive.
349
  *
367
 
368
  // Bail if XProfile component is active and there's no custom front page for the user.
369
  if ( ! bp_displayed_user_has_front_template() && $is_xprofile_active ) {
370
+ add_action( 'bp_xprofile_setup_nav', array( $this, 'setup_xprofile_nav' ) );
371
  return;
372
  }
373
 
396
  'default_subnav_slug' => 'public',
397
  'item_css_id' => buddypress()->profile->id
398
  );
399
+
400
+ /**
401
+ * The xProfile component is active.
402
+ *
403
+ * We need to make sure the Change Avatar and Change Cover Image subnavs are
404
+ * added just like it was the case before.
405
+ */
406
+ } else {
407
+ add_action( 'bp_xprofile_setup_nav', array( $this, 'setup_xprofile_nav' ) );
408
  }
409
 
410
  /**
459
  */
460
  } else {
461
  $main_nav = $this->main_nav;
462
+ $sub_nav = array( $this->sub_nav );
463
+
464
+ if ( ! $is_xprofile_active ) {
465
+ $sub_nav = array_merge( $sub_nav, $this->get_avatar_cover_image_subnavs() );
466
+ }
467
  }
468
 
469
 
487
 
488
  // Add the sub nav item.
489
  bp_core_new_subnav_item( $this->sub_nav, 'members' );
490
+
491
+ // Get the Avatar and cover image subnavs.
492
+ $this->setup_xprofile_nav();
493
+ }
494
+
495
+ /**
496
+ * Set up the xProfile nav.
497
+ *
498
+ * @since 6.0.0
499
+ */
500
+ public function setup_xprofile_nav() {
501
+ // Get the Avatar and cover image subnavs.
502
+ $items = $this->get_avatar_cover_image_subnavs();
503
+
504
+ foreach ( $items as $item ) {
505
+ bp_core_new_subnav_item( $item, 'members' );
506
+ }
507
+ }
508
+
509
+ /**
510
+ * Get the Avatar and Cover image admin navs.
511
+ *
512
+ * @since 6.0.0
513
+ *
514
+ * @param string $admin_bar_menu_id The Admin bar menu ID to attach sub items to.
515
+ * @return array The Avatar and Cover image admin navs.
516
+ */
517
+ public function get_avatar_cover_image_admin_navs( $admin_bar_menu_id = '' ) {
518
+ $wp_admin_nav = array();
519
+ $profile_link = trailingslashit( bp_loggedin_user_domain() . bp_get_profile_slug() );
520
+
521
+ if ( ! $admin_bar_menu_id ) {
522
+ $admin_bar_menu_id = $this->id;
523
+ }
524
+
525
+ // Edit Avatar.
526
+ if ( buddypress()->avatar->show_avatars ) {
527
+ $wp_admin_nav[] = array(
528
+ 'parent' => 'my-account-' . $admin_bar_menu_id,
529
+ 'id' => 'my-account-' . $admin_bar_menu_id . '-change-avatar',
530
+ 'title' => _x( 'Change Profile Photo', 'My Account Profile sub nav', 'buddypress' ),
531
+ 'href' => trailingslashit( $profile_link . 'change-avatar' ),
532
+ 'position' => 30
533
+ );
534
+ }
535
+
536
+ // Edit Cover Image
537
+ if ( bp_displayed_user_use_cover_image_header() ) {
538
+ $wp_admin_nav[] = array(
539
+ 'parent' => 'my-account-' . $admin_bar_menu_id,
540
+ 'id' => 'my-account-' . $admin_bar_menu_id . '-change-cover-image',
541
+ 'title' => _x( 'Change Cover Image', 'My Account Profile sub nav', 'buddypress' ),
542
+ 'href' => trailingslashit( $profile_link . 'change-cover-image' ),
543
+ 'position' => 40
544
+ );
545
+ }
546
+
547
+ return $wp_admin_nav;
548
+ }
549
+
550
+ /**
551
+ * Set up the Admin Bar.
552
+ *
553
+ * @since 6.0.0
554
+ *
555
+ * @param array $wp_admin_nav Admin Bar items.
556
+ */
557
+ public function setup_admin_bar( $wp_admin_nav = array() ) {
558
+ // Menus for logged in user.
559
+ if ( is_user_logged_in() ) {
560
+ $profile_link = trailingslashit( bp_loggedin_user_domain() . bp_get_profile_slug() );
561
+
562
+ if ( ! bp_is_active( 'xprofile' ) ) {
563
+ // Add the "Profile" sub menu.
564
+ $wp_admin_nav[] = array(
565
+ 'parent' => buddypress()->my_account_menu_id,
566
+ 'id' => 'my-account-' . $this->id,
567
+ 'title' => _x( 'Profile', 'My Account Profile', 'buddypress' ),
568
+ 'href' => $profile_link
569
+ );
570
+
571
+ // View Profile.
572
+ $wp_admin_nav[] = array(
573
+ 'parent' => 'my-account-' . $this->id,
574
+ 'id' => 'my-account-' . $this->id . '-public',
575
+ 'title' => _x( 'View', 'My Account Profile sub nav', 'buddypress' ),
576
+ 'href' => $profile_link,
577
+ 'position' => 10
578
+ );
579
+
580
+ $wp_admin_nav = array_merge( $wp_admin_nav, $this->get_avatar_cover_image_admin_navs() );
581
+
582
+ /**
583
+ * The xProfile is active.
584
+ *
585
+ * Add the Change Avatar and Change Cover Image Admin Bar items
586
+ * to the xProfile Admin Bar Menu.
587
+ */
588
+ } else {
589
+ add_filter( 'bp_xprofile_admin_nav', array( $this, 'setup_xprofile_admin_nav' ), 2 );
590
+ }
591
+ }
592
+
593
+ parent::setup_admin_bar( $wp_admin_nav );
594
+ }
595
+
596
+ /**
597
+ * Adds "Profile > Change Avatar" & "Profile > Change Cover Image" subnav item
598
+ * under the "Profile" adminbar menu.
599
+ *
600
+ * @since 6.0.0
601
+ *
602
+ * @param array $wp_admin_nav The Profile adminbar nav array.
603
+ * @return array
604
+ */
605
+ public function setup_xprofile_admin_nav( $wp_admin_nav ) {
606
+ $items = $this->get_avatar_cover_image_admin_navs( buddypress()->profile->id );
607
+
608
+ if ( $items ) {
609
+ $wp_admin_nav = array_merge( $wp_admin_nav, $items );
610
+ }
611
+
612
+ return $wp_admin_nav;
613
  }
614
 
615
  /**
654
  * Init the BP REST API.
655
  *
656
  * @since 5.0.0
657
+ * @since 6.0.0 Adds the Member Cover and Signup REST endpoints.
658
  *
659
  * @param array $controllers Optional. See BP_Component::rest_api_init() for
660
  * description.
661
  */
662
  public function rest_api_init( $controllers = array() ) {
663
+ $controllers = array(
664
  /**
665
  * As the Members component is always loaded,
666
  * let's register the Components endpoint here.
667
  */
668
  'BP_REST_Components_Endpoint',
669
  'BP_REST_Members_Endpoint',
670
+ 'BP_REST_Attachments_Member_Avatar_Endpoint',
671
+ );
672
+
673
+ if ( bp_is_active( 'members', 'cover_image' ) ) {
674
+ $controllers[] = 'BP_REST_Attachments_Member_Cover_Endpoint';
675
+ }
676
+
677
+ if ( bp_get_signup_allowed() ) {
678
+ $controllers[] = 'BP_REST_Signup_Endpoint';
679
+ }
680
+
681
+ parent::rest_api_init( $controllers );
682
+ }
683
+
684
+ /**
685
+ * Register the BP Members Blocks.
686
+ *
687
+ * @since 6.0.0
688
+ *
689
+ * @param array $blocks Optional. See BP_Component::blocks_init() for
690
+ * description.
691
+ */
692
+ public function blocks_init( $blocks = array() ) {
693
+ parent::blocks_init(
694
+ array(
695
+ 'bp/member' => array(
696
+ 'name' => 'bp/member',
697
+ 'editor_script' => 'bp-member-block',
698
+ 'editor_script_url' => plugins_url( 'js/blocks/member.js', dirname( __FILE__ ) ),
699
+ 'editor_script_deps' => array(
700
+ 'wp-blocks',
701
+ 'wp-element',
702
+ 'wp-components',
703
+ 'wp-i18n',
704
+ 'wp-editor',
705
+ 'wp-compose',
706
+ 'wp-data',
707
+ 'wp-block-editor',
708
+ 'bp-block-components',
709
+ ),
710
+ 'style' => 'bp-member-block',
711
+ 'style_url' => plugins_url( 'css/blocks/member.css', dirname( __FILE__ ) ),
712
+ 'render_callback' => 'bp_members_render_member_block',
713
+ 'attributes' => array(
714
+ 'itemID' => array(
715
+ 'type' => 'integer',
716
+ 'default' => 0,
717
+ ),
718
+ 'avatarSize' => array(
719
+ 'type' => 'string',
720
+ 'default' => 'full',
721
+ ),
722
+ 'displayMentionSlug' => array(
723
+ 'type' => 'boolean',
724
+ 'default' => true,
725
+ ),
726
+ 'displayActionButton' => array(
727
+ 'type' => 'boolean',
728
+ 'default' => true,
729
+ ),
730
+ 'displayCoverImage' => array(
731
+ 'type' => 'boolean',
732
+ 'default' => true,
733
+ ),
734
+ ),
735
+ ),
736
+ )
737
+ );
738
  }
739
  }
bp-members/classes/class-bp-members-list-table.php CHANGED
@@ -195,6 +195,7 @@ class BP_Members_List_Table extends WP_Users_List_Table {
195
  $link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( bp_get_admin_url( 'options-general.php' ) ), esc_html__( 'Edit settings', 'buddypress' ) );
196
  }
197
 
 
198
  printf( __( 'Registration is disabled. %s', 'buddypress' ), $link );
199
  }
200
 
195
  $link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( bp_get_admin_url( 'options-general.php' ) ), esc_html__( 'Edit settings', 'buddypress' ) );
196
  }
197
 
198
+ /* translators: %s: url to site settings */
199
  printf( __( 'Registration is disabled. %s', 'buddypress' ), $link );
200
  }
201
 
bp-members/classes/class-bp-members-ms-list-table.php CHANGED
@@ -178,6 +178,7 @@ class BP_Members_MS_List_Table extends WP_MS_Users_List_Table {
178
  $link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( network_admin_url( 'settings.php' ) ), esc_html__( 'Edit settings', 'buddypress' ) );
179
  }
180
 
 
181
  printf( __( 'Registration is disabled. %s', 'buddypress' ), $link );
182
  }
183
  }
178
  $link = sprintf( '<a href="%1$s">%2$s</a>', esc_url( network_admin_url( 'settings.php' ) ), esc_html__( 'Edit settings', 'buddypress' ) );
179
  }
180
 
181
+ /* translators: %s: url to site settings */
182
  printf( __( 'Registration is disabled. %s', 'buddypress' ), $link );
183
  }
184
  }
bp-members/classes/class-bp-rest-attachments-member-avatar-endpoint.php ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Attachments_Member_Avatar_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 5.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Member Avatar endpoints.
13
+ *
14
+ * @since 5.0.0
15
+ */
16
+ class BP_REST_Attachments_Member_Avatar_Endpoint extends WP_REST_Controller {
17
+
18
+ use BP_REST_Attachments;
19
+
20
+ /**
21
+ * BP_Attachment_Avatar Instance.
22
+ *
23
+ * @since 5.0.0
24
+ *
25
+ * @var BP_Attachment_Avatar
26
+ */
27
+ protected $avatar_instance;
28
+
29
+ /**
30
+ * Member object.
31
+ *
32
+ * @since 5.0.0
33
+ *
34
+ * @var WP_User
35
+ */
36
+ protected $user;
37
+
38
+ /**
39
+ * Member object type.
40
+ *
41
+ * @since 5.0.0
42
+ *
43
+ * @var string
44
+ */
45
+ protected $object = 'user';
46
+
47
+ /**
48
+ * Constructor.
49
+ *
50
+ * @since 5.0.0
51
+ */
52
+ public function __construct() {
53
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
54
+ $this->rest_base = 'members';
55
+ $this->avatar_instance = new BP_Attachment_Avatar();
56
+ }
57
+
58
+ /**
59
+ * Register the component routes.
60
+ *
61
+ * @since 5.0.0
62
+ */
63
+ public function register_routes() {
64
+ register_rest_route(
65
+ $this->namespace,
66
+ '/' . $this->rest_base . '/(?P<user_id>[\d]+)/avatar',
67
+ array(
68
+ 'args' => array(
69
+ 'user_id' => array(
70
+ 'description' => __( 'A unique numeric ID for the Member.', 'buddypress' ),
71
+ 'type' => 'integer',
72
+ ),
73
+ ),
74
+ array(
75
+ 'methods' => WP_REST_Server::READABLE,
76
+ 'callback' => array( $this, 'get_item' ),
77
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
78
+ 'args' => $this->get_item_collection_params(),
79
+ ),
80
+ array(
81
+ 'methods' => WP_REST_Server::CREATABLE,
82
+ 'callback' => array( $this, 'create_item' ),
83
+ 'permission_callback' => array( $this, 'create_item_permissions_check' ),
84
+ ),
85
+ array(
86
+ 'methods' => WP_REST_Server::DELETABLE,
87
+ 'callback' => array( $this, 'delete_item' ),
88
+ 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
89
+ ),
90
+ 'schema' => array( $this, 'get_item_schema' ),
91
+ )
92
+ );
93
+ }
94
+
95
+ /**
96
+ * Fetch an existing member avatar.
97
+ *
98
+ * @since 5.0.0
99
+ *
100
+ * @param WP_REST_Request $request Full details about the request.
101
+ * @return WP_REST_Response|WP_Error
102
+ */
103
+ public function get_item( $request ) {
104
+ $args = array();
105
+
106
+ foreach ( array( 'full', 'thumb' ) as $type ) {
107
+ $args[ $type ] = bp_core_fetch_avatar(
108
+ array(
109
+ 'object' => $this->object,
110
+ 'type' => $type,
111
+ 'item_id' => (int) $this->user->ID,
112
+ 'html' => (bool) $request['html'],
113
+ 'alt' => $request['alt'],
114
+ 'no_grav' => (bool) $request['no_gravatar'],
115
+ )
116
+ );
117
+ }
118
+
119
+ // Get the avatar object.
120
+ $avatar = $this->get_avatar_object( $args );
121
+
122
+ if ( ! $avatar->full && ! $avatar->thumb ) {
123
+ return new WP_Error(
124
+ 'bp_rest_attachments_member_avatar_no_image',
125
+ __( 'Sorry, there was a problem fetching the avatar.', 'buddypress' ),
126
+ array(
127
+ 'status' => 500,
128
+ )
129
+ );
130
+ }
131
+
132
+ $retval = array(
133
+ $this->prepare_response_for_collection(
134
+ $this->prepare_item_for_response( $avatar, $request )
135
+ ),
136
+ );
137
+
138
+ $response = rest_ensure_response( $retval );
139
+
140
+ /**
141
+ * Fires after a member avatar is fetched via the REST API.
142
+ *
143
+ * @since 5.0.0
144
+ *
145
+ * @param string $avatar The avatar.
146
+ * @param WP_REST_Response $response The response data.
147
+ * @param WP_REST_Request $request The request sent to the API.
148
+ */
149
+ do_action( 'bp_rest_attachments_member_avatar_get_item', $avatar, $response, $request );
150
+
151
+ return $response;
152
+ }
153
+
154
+ /**
155
+ * Checks if a given request has access to get a member avatar.
156
+ *
157
+ * @since 5.0.0
158
+ *
159
+ * @param WP_REST_Request $request Full details about the request.
160
+ * @return bool|WP_Error
161
+ */
162
+ public function get_item_permissions_check( $request ) {
163
+ $retval = true;
164
+ $this->user = bp_rest_get_user( $request['user_id'] );
165
+
166
+ if ( true === $retval && ! $this->user instanceof WP_User ) {
167
+ $retval = new WP_Error(
168
+ 'bp_rest_member_invalid_id',
169
+ __( 'Invalid member ID.', 'buddypress' ),
170
+ array(
171
+ 'status' => 404,
172
+ )
173
+ );
174
+ }
175
+
176
+ /**
177
+ * Filter the member avatar `get_item` permissions check.
178
+ *
179
+ * @since 5.0.0
180
+ *
181
+ * @param bool|WP_Error $retval Returned value.
182
+ * @param WP_REST_Request $request The request sent to the API.
183
+ */
184
+ return apply_filters( 'bp_rest_attachments_member_avatar_get_item_permissions_check', $retval, $request );
185
+ }
186
+
187
+ /**
188
+ * Upload a member avatar.
189
+ *
190
+ * @since 5.0.0
191
+ *
192
+ * @param WP_REST_Request $request Full details about the request.
193
+ * @return WP_REST_Response|WP_Error
194
+ */
195
+ public function create_item( $request ) {
196
+ $request->set_param( 'context', 'edit' );
197
+
198
+ // Get the image file from $_FILES.
199
+ $files = $request->get_file_params();
200
+
201
+ if ( empty( $files ) ) {
202
+ return new WP_Error(
203
+ 'bp_rest_attachments_member_avatar_no_image_file',
204
+ __( 'Sorry, you need an image file to upload.', 'buddypress' ),
205
+ array(
206
+ 'status' => 500,
207
+ )
208
+ );
209
+ }
210
+
211
+ // Upload the avatar.
212
+ $avatar = $this->upload_avatar_from_file( $files );
213
+ if ( is_wp_error( $avatar ) ) {
214
+ return $avatar;
215
+ }
216
+
217
+ $retval = array(
218
+ $this->prepare_response_for_collection(
219
+ $this->prepare_item_for_response( $avatar, $request )
220
+ ),
221
+ );
222
+
223
+ $response = rest_ensure_response( $retval );
224
+
225
+ /**
226
+ * Fires after a member avatar is uploaded via the REST API.
227
+ *
228
+ * @since 5.0.0
229
+ *
230
+ * @param stdClass $avatar Avatar object.
231
+ * @param WP_REST_Response $response The response data.
232
+ * @param WP_REST_Request $request The request sent to the API.
233
+ */
234
+ do_action( 'bp_rest_attachments_member_avatar_create_item', $avatar, $response, $request );
235
+
236
+ return $response;
237
+ }
238
+
239
+ /**
240
+ * Checks if a given request has access to upload a member avatar.
241
+ *
242
+ * @since 5.0.0
243
+ *
244
+ * @param WP_REST_Request $request Full details about the request.
245
+ * @return bool|WP_Error
246
+ */
247
+ public function create_item_permissions_check( $request ) {
248
+ $retval = $this->get_item_permissions_check( $request );
249
+ $args = array();
250
+
251
+ if ( isset( $this->user->ID ) ) {
252
+ $args = array(
253
+ 'item_id' => (int) $this->user->ID,
254
+ 'object' => 'user',
255
+ );
256
+ }
257
+
258
+ if ( true === $retval && ! is_user_logged_in() ) {
259
+ $retval = new WP_Error(
260
+ 'bp_rest_authorization_required',
261
+ __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
262
+ array(
263
+ 'status' => rest_authorization_required_code(),
264
+ )
265
+ );
266
+ }
267
+
268
+ if ( true === $retval && 'POST' === $request->get_method() && bp_disable_avatar_uploads() ) {
269
+ $retval = new WP_Error(
270
+ 'bp_rest_attachments_member_avatar_disabled',
271
+ __( 'Sorry, member avatar upload is disabled.', 'buddypress' ),
272
+ array(
273
+ 'status' => 500,
274
+ )
275
+ );
276
+ }
277
+
278
+ if ( true === $retval && ! empty( $args ) && ! bp_attachments_current_user_can( 'edit_avatar', $args ) ) {
279
+ $retval = new WP_Error(
280
+ 'bp_rest_authorization_required',
281
+ __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
282
+ array(
283
+ 'status' => rest_authorization_required_code(),
284
+ )
285
+ );
286
+ }
287
+
288
+ /**
289
+ * Filter the member avatar `create_item` permissions check.
290
+ *
291
+ * @since 5.0.0
292
+ *
293
+ * @param bool|WP_Error $retval Returned value.
294
+ * @param WP_REST_Request $request The request sent to the API.
295
+ */
296
+ return apply_filters( 'bp_rest_attachments_member_avatar_create_item_permissions_check', $retval, $request );
297
+ }
298
+
299
+ /**
300
+ * Delete an existing member avatar.
301
+ *
302
+ * @since 5.0.0
303
+ *
304
+ * @param WP_REST_Request $request Full details about the request.
305
+ * @return WP_REST_Response|WP_Error
306
+ */
307
+ public function delete_item( $request ) {
308
+ $request->set_param( 'context', 'edit' );
309
+ $user_id = (int) $this->user->ID;
310
+
311
+ if ( ! bp_get_user_has_avatar( $user_id ) ) {
312
+ return new WP_Error(
313
+ 'bp_rest_attachments_member_avatar_no_uploaded_avatar',
314
+ __( 'Sorry, there are no uploaded avatars for this user on this site.', 'buddypress' ),
315
+ array(
316
+ 'status' => 404,
317
+ )
318
+ );
319
+ }
320
+
321
+ $args = array();
322
+
323
+ foreach ( array( 'full', 'thumb' ) as $type ) {
324
+ $args[ $type ] = bp_core_fetch_avatar(
325
+ array(
326
+ 'object' => $this->object,
327
+ 'type' => $type,
328
+ 'item_id' => $user_id,
329
+ 'html' => false,
330
+ )
331
+ );
332
+ }
333
+
334
+ // Get the avatar object before deleting it.
335
+ $avatar = $this->get_avatar_object( $args );
336
+
337
+ $deleted = bp_core_delete_existing_avatar(
338
+ array(
339
+ 'object' => $this->object,
340
+ 'item_id' => $user_id,
341
+ )
342
+ );
343
+
344
+ if ( ! $deleted ) {
345
+ return new WP_Error(
346
+ 'bp_rest_attachments_member_avatar_delete_failed',
347
+ __( 'Sorry, there was a problem deleting the avatar.', 'buddypress' ),
348
+ array(
349
+ 'status' => 500,
350
+ )
351
+ );
352
+ }
353
+
354
+ // Build the response.
355
+ $response = new WP_REST_Response();
356
+ $response->set_data(
357
+ array(
358
+ 'deleted' => true,
359
+ 'previous' => $avatar,
360
+ )
361
+ );
362
+
363
+ /**
364
+ * Fires after a member avatar is deleted via the REST API.
365
+ *
366
+ * @since 5.0.0
367
+ *
368
+ * @param WP_REST_Response $response The response data.
369
+ * @param WP_REST_Request $request The request sent to the API.
370
+ */
371
+ do_action( 'bp_rest_attachments_member_avatar_delete_item', $response, $request );
372
+
373
+ return $response;
374
+ }
375
+
376
+ /**
377
+ * Checks if a given request has access to delete member avatar.
378
+ *
379
+ * @since 5.0.0
380
+ *
381
+ * @param WP_REST_Request $request Full details about the request.
382
+ * @return bool|WP_Error
383
+ */
384
+ public function delete_item_permissions_check( $request ) {
385
+ $retval = $this->create_item_permissions_check( $request );
386
+
387
+ /**
388
+ * Filter the member avatar `delete_item` permissions check.
389
+ *
390
+ * @since 5.0.0
391
+ *
392
+ * @param bool|WP_Error $retval Returned value.
393
+ * @param WP_REST_Request $request The request sent to the API.
394
+ */
395
+ return apply_filters( 'bp_rest_attachments_member_avatar_delete_item_permissions_check', $retval, $request );
396
+ }
397
+
398
+ /**
399
+ * Prepares avatar data to return as an object.
400
+ *
401
+ * @since 5.0.0
402
+ *
403
+ * @param object $avatar Avatar object.
404
+ * @param WP_REST_Request $request Full details about the request.
405
+ * @return WP_REST_Response
406
+ */
407
+ public function prepare_item_for_response( $avatar, $request ) {
408
+ $data = array(
409
+ 'full' => $avatar->full,
410
+ 'thumb' => $avatar->thumb,
411
+ );
412
+
413
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
414
+ $data = $this->add_additional_fields_to_object( $data, $request );
415
+ $data = $this->filter_response_by_context( $data, $context );
416
+
417
+ // @todo add prepare_links
418
+ $response = rest_ensure_response( $data );
419
+
420
+ /**
421
+ * Filter a member avatar value returned from the API.
422
+ *
423
+ * @since 5.0.0
424
+ *
425
+ * @param WP_REST_Response $response Response.
426
+ * @param WP_REST_Request $request Request used to generate the response.
427
+ * @param object $avatar Avatar object.
428
+ */
429
+ return apply_filters( 'bp_rest_attachments_member_avatar_prepare_value', $response, $request, $avatar );
430
+ }
431
+
432
+ /**
433
+ * Get the member avatar schema, conforming to JSON Schema.
434
+ *
435
+ * @since 5.0.0
436
+ *
437
+ * @return array
438
+ */
439
+ public function get_item_schema() {
440
+ $schema = array(
441
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
442
+ 'title' => 'bp_attachments_member_avatar',
443
+ 'type' => 'object',
444
+ 'properties' => array(
445
+ 'full' => array(
446
+ 'context' => array( 'view', 'edit' ),
447
+ 'description' => __( 'Full size of the image file.', 'buddypress' ),
448
+ 'type' => 'string',
449
+ 'format' => 'uri',
450
+ 'readonly' => true,
451
+ ),
452
+ 'thumb' => array(
453
+ 'context' => array( 'view', 'edit' ),
454
+ 'description' => __( 'Thumb size of the image file.', 'buddypress' ),
455
+ 'type' => 'string',
456
+ 'format' => 'uri',
457
+ 'readonly' => true,
458
+ ),
459
+ ),
460
+ );
461
+
462
+ /**
463
+ * Filters the member avatar schema.
464
+ *
465
+ * @param string $schema The endpoint schema.
466
+ */
467
+ return apply_filters( 'bp_rest_attachments_member_avatar_schema', $this->add_additional_fields_schema( $schema ) );
468
+ }
469
+
470
+ /**
471
+ * Get the query params for the `get_item`.
472
+ *
473
+ * @since 5.0.0
474
+ *
475
+ * @return array
476
+ */
477
+ public function get_item_collection_params() {
478
+ $params = parent::get_collection_params();
479
+ $params['context']['default'] = 'view';
480
+
481
+ // Removing unused params.
482
+ unset( $params['search'], $params['page'], $params['per_page'] );
483
+
484
+ $params['html'] = array(
485
+ 'description' => __( 'Whether to return an <img> HTML element, vs a raw URL to an avatar.', 'buddypress' ),
486
+ 'default' => false,
487
+ 'type' => 'boolean',
488
+ 'sanitize_callback' => 'rest_sanitize_boolean',
489
+ 'validate_callback' => 'rest_validate_request_arg',
490
+ );
491
+
492
+ $params['alt'] = array(
493
+ 'description' => __( 'The alt attribute for the <img> element.', 'buddypress' ),
494
+ 'default' => '',
495
+ 'type' => 'string',
496
+ 'sanitize_callback' => 'sanitize_text_field',
497
+ 'validate_callback' => 'rest_validate_request_arg',
498
+ );
499
+
500
+ $params['no_grav'] = array(
501
+ 'description' => __( 'Whether to disable the default Gravatar fallback.', 'buddypress' ),
502
+ 'default' => false,
503
+ 'type' => 'boolean',
504
+ 'sanitize_callback' => 'rest_sanitize_boolean',
505
+ 'validate_callback' => 'rest_validate_request_arg',
506
+ );
507
+
508
+ /**
509
+ * Filters the item collection query params.
510
+ *
511
+ * @param array $params Query params.
512
+ */
513
+ return apply_filters( 'bp_rest_attachments_member_avatar_collection_params', $params );
514
+ }
515
+ }
bp-members/classes/class-bp-rest-attachments-member-cover-endpoint.php ADDED
@@ -0,0 +1,430 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Attachments_Member_Cover_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 6.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Member Cover endpoints.
13
+ *
14
+ * /members/<user_id>/cover
15
+ *
16
+ * @since 6.0.0
17
+ */
18
+ class BP_REST_Attachments_Member_Cover_Endpoint extends WP_REST_Controller {
19
+
20
+ use BP_REST_Attachments;
21
+
22
+ /**
23
+ * BP_Attachment_Cover_Image Instance.
24
+ *
25
+ * @since 6.0.0
26
+ *
27
+ * @var BP_Attachment_Cover_Image
28
+ */
29
+ protected $attachment_instance;
30
+
31
+ /**
32
+ * Member object.
33
+ *
34
+ * @since 6.0.0
35
+ *
36
+ * @var WP_User
37
+ */
38
+ protected $user;
39
+
40
+ /**
41
+ * Member object type.
42
+ *
43
+ * @since 6.0.0
44
+ *
45
+ * @var string
46
+ */
47
+ protected $object = 'user';
48
+
49
+ /**
50
+ * Constructor.
51
+ *
52
+ * @since 6.0.0
53
+ */
54
+ public function __construct() {
55
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
56
+ $this->rest_base = 'members';
57
+ $this->attachment_instance = new BP_Attachment_Cover_Image();
58
+ }
59
+
60
+ /**
61
+ * Register the component routes.
62
+ *
63
+ * @since 6.0.0
64
+ */
65
+ public function register_routes() {
66
+ register_rest_route(
67
+ $this->namespace,
68
+ '/' . $this->rest_base . '/(?P<user_id>[\d]+)/cover',
69
+ array(
70
+ 'args' => array(
71
+ 'user_id' => array(
72
+ 'description' => __( 'A unique numeric ID for the User.', 'buddypress' ),
73
+ 'type' => 'integer',
74
+ ),
75
+ ),
76
+ array(
77
+ 'methods' => WP_REST_Server::READABLE,
78
+ 'callback' => array( $this, 'get_item' ),
79
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
80
+ ),
81
+ array(
82
+ 'methods' => WP_REST_Server::CREATABLE,
83
+ 'callback' => array( $this, 'create_item' ),
84
+ 'permission_callback' => array( $this, 'create_item_permissions_check' ),
85
+ ),
86
+ array(
87
+ 'methods' => WP_REST_Server::DELETABLE,
88
+ 'callback' => array( $this, 'delete_item' ),
89
+ 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
90
+ ),
91
+ 'schema' => array( $this, 'get_item_schema' ),
92
+ )
93
+ );
94
+ }
95
+
96
+ /**
97
+ * Fetch an existing user cover.
98
+ *
99
+ * @since 6.0.0
100
+ *
101
+ * @param WP_REST_Request $request Full details about the request.
102
+ * @return WP_REST_Response|WP_Error
103
+ */
104
+ public function get_item( $request ) {
105
+ $cover_url = bp_attachments_get_attachment(
106
+ 'url',
107
+ array(
108
+ 'item_id' => $this->user->ID,
109
+ )
110
+ );
111
+
112
+ if ( empty( $cover_url ) ) {
113
+ return new WP_Error(
114
+ 'bp_rest_attachments_member_cover_no_image',
115
+ __( 'Sorry, there was a problem fetching this user cover.', 'buddypress' ),
116
+ array(
117
+ 'status' => 500,
118
+ )
119
+ );
120
+ }
121
+
122
+ $retval = array(
123
+ $this->prepare_response_for_collection(
124
+ $this->prepare_item_for_response( $cover_url, $request )
125
+ ),
126
+ );
127
+
128
+ $response = rest_ensure_response( $retval );
129
+
130
+ /**
131
+ * Fires after a user cover is fetched via the REST API.
132
+ *
133
+ * @since 6.0.0
134
+ *
135
+ * @param string $cover_url The user cover url.
136
+ * @param WP_REST_Response $response The response data.
137
+ * @param WP_REST_Request $request The request sent to the API.
138
+ */
139
+ do_action( 'bp_rest_attachments_member_cover_get_item', $cover_url, $response, $request );
140
+
141
+ return $response;
142
+ }
143
+
144
+ /**
145
+ * Checks if a given request has access to get a user cover.
146
+ *
147
+ * @since 6.0.0
148
+ *
149
+ * @param WP_REST_Request $request Full details about the request.
150
+ * @return bool|WP_Error
151
+ */
152
+ public function get_item_permissions_check( $request ) {
153
+ $retval = true;
154
+ $this->user = bp_rest_get_user( $request['user_id'] );
155
+
156
+ if ( ! $this->user instanceof WP_User ) {
157
+ $retval = new WP_Error(
158
+ 'bp_rest_member_invalid_id',
159
+ __( 'Invalid member ID.', 'buddypress' ),
160
+ array(
161
+ 'status' => 404,
162
+ )
163
+ );
164
+ }
165
+
166
+ /**
167
+ * Filter the user cover `get_item` permissions check.
168
+ *
169
+ * @since 6.0.0
170
+ *
171
+ * @param bool|WP_Error $retval Returned value.
172
+ * @param WP_REST_Request $request The request sent to the API.
173
+ */
174
+ return apply_filters( 'bp_rest_attachments_member_cover_get_item_permissions_check', $retval, $request );
175
+ }
176
+
177
+ /**
178
+ * Upload a user cover.
179
+ *
180
+ * @since 6.0.0
181
+ *
182
+ * @param WP_REST_Request $request Full details about the request.
183
+ * @return WP_REST_Response|WP_Error
184
+ */
185
+ public function create_item( $request ) {
186
+ $request->set_param( 'context', 'edit' );
187
+
188
+ // Get the image file from $_FILES.
189
+ $files = $request->get_file_params();
190
+
191
+ if ( empty( $files ) ) {
192
+ return new WP_Error(
193
+ 'bp_rest_attachments_member_cover_no_image_file',
194
+ __( 'Sorry, you need an image file to upload.', 'buddypress' ),
195
+ array(
196
+ 'status' => 500,
197
+ )
198
+ );
199
+ }
200
+
201
+ // Upload the user cover.
202
+ $cover_url = $this->upload_cover_from_file( $files );
203
+ if ( is_wp_error( $cover_url ) ) {
204
+ return $cover_url;
205
+ }
206
+
207
+ $retval = array(
208
+ $this->prepare_response_for_collection(
209
+ $this->prepare_item_for_response( $cover_url, $request )
210
+ ),
211
+ );
212
+
213
+ $response = rest_ensure_response( $retval );
214
+
215
+ /**
216
+ * Fires after a user cover is uploaded via the REST API.
217
+ *
218
+ * @since 6.0.0
219
+ *
220
+ * @param string $cover_url The user cover url.
221
+ * @param WP_REST_Response $response The response data.
222
+ * @param WP_REST_Request $request The request sent to the API.
223
+ */
224
+ do_action( 'bp_rest_attachments_member_cover_create_item', $cover_url, $response, $request );
225
+
226
+ return $response;
227
+ }
228
+
229
+ /**
230
+ * Checks if a given request has access to upload a user cover.
231
+ *
232
+ * @since 6.0.0
233
+ *
234
+ * @param WP_REST_Request $request Full details about the request.
235
+ * @return bool|WP_Error
236
+ */
237
+ public function create_item_permissions_check( $request ) {
238
+ $retval = $this->delete_item_permissions_check( $request );
239
+
240
+ if ( true === $retval && bp_disable_cover_image_uploads() ) {
241
+ $retval = new WP_Error(
242
+ 'bp_rest_attachments_member_cover_disabled',
243
+ __( 'Sorry, user cover upload is disabled.', 'buddypress' ),
244
+ array(
245
+ 'status' => 500,
246
+ )
247
+ );
248
+ }
249
+
250
+ /**
251
+ * Filter the user cover `create_item` permissions check.
252
+ *
253
+ * @since 6.0.0
254
+ *
255
+ * @param bool|WP_Error $retval Returned value.
256
+ * @param WP_REST_Request $request The request sent to the API.
257
+ */
258
+ return apply_filters( 'bp_rest_attachments_member_cover_create_item_permissions_check', $retval, $request );
259
+ }
260
+
261
+ /**
262
+ * Delete an existing user cover.
263
+ *
264
+ * @since 6.0.0
265
+ *
266
+ * @param WP_REST_Request $request Full details about the request.
267
+ * @return WP_REST_Response|WP_Error
268
+ */
269
+ public function delete_item( $request ) {
270
+ $request->set_param( 'context', 'edit' );
271
+
272
+ $cover_url = bp_attachments_get_attachment(
273
+ 'url',
274
+ array(
275
+ 'item_id' => $this->user->ID,
276
+ )
277
+ );
278
+
279
+ $deleted = bp_attachments_delete_file(
280
+ array(
281
+ 'item_id' => (int) $this->user->ID,
282
+ )
283
+ );
284
+
285
+ if ( ! $deleted ) {
286
+ return new WP_Error(
287
+ 'bp_rest_attachments_member_cover_delete_failed',
288
+ __( 'Sorry, there was a problem deleting this user cover.', 'buddypress' ),
289
+ array(
290
+ 'status' => 500,
291
+ )
292
+ );
293
+ }
294
+
295
+ // Build the response.
296
+ $response = new WP_REST_Response();
297
+ $response->set_data(
298
+ array(
299
+ 'deleted' => true,
300
+ 'previous' => $cover_url,
301
+ )
302
+ );
303
+
304
+ /**
305
+ * Fires after a user cover is deleted via the REST API.
306
+ *
307
+ * @since 6.0.0
308
+ *
309
+ * @param WP_User $user The user object.
310
+ * @param WP_REST_Response $response The response data.
311
+ * @param WP_REST_Request $request The request sent to the API.
312
+ */
313
+ do_action( 'bp_rest_attachments_member_cover_delete_item', $this->user, $response, $request );
314
+
315
+ return $response;
316
+ }
317
+
318
+ /**
319
+ * Checks if a given request has access to delete a user cover.
320
+ *
321
+ * @since 6.0.0
322
+ *
323
+ * @param WP_REST_Request $request Full details about the request.
324
+ * @return bool|WP_Error
325
+ */
326
+ public function delete_item_permissions_check( $request ) {
327
+ $retval = $this->get_item_permissions_check( $request );
328
+ $args = array();
329
+
330
+ if ( isset( $this->user->ID ) ) {
331
+ $args = array(
332
+ 'item_id' => $this->user->ID,
333
+ 'object' => $this->object,
334
+ );
335
+ }
336
+
337
+ if ( true === $retval && ! is_user_logged_in() ) {
338
+ $retval = new WP_Error(
339
+ 'bp_rest_authorization_required',
340
+ __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
341
+ array(
342
+ 'status' => rest_authorization_required_code(),
343
+ )
344
+ );
345
+ }
346
+
347
+ if ( true === $retval && ! empty( $args ) && ! bp_attachments_current_user_can( 'edit_cover_image', $args ) ) {
348
+ $retval = new WP_Error(
349
+ 'bp_rest_authorization_required',
350
+ __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
351
+ array(
352
+ 'status' => rest_authorization_required_code(),
353
+ )
354
+ );
355
+ }
356
+
357
+ /**
358
+ * Filter the user cover `delete_item` permissions check.
359
+ *
360
+ * @since 6.0.0
361
+ *
362
+ * @param bool|WP_Error $retval Returned value.
363
+ * @param WP_REST_Request $request The request sent to the API.
364
+ */
365
+ return apply_filters( 'bp_rest_attachments_member_cover_delete_item_permissions_check', $retval, $request );
366
+ }
367
+
368
+ /**
369
+ * Prepares user cover to return as an object.
370
+ *
371
+ * @since 6.0.0
372
+ *
373
+ * @param string $cover_url User cover url.
374
+ * @param WP_REST_Request $request Full details about the request.
375
+ * @return WP_REST_Response
376
+ */
377
+ public function prepare_item_for_response( $cover_url, $request ) {
378
+ $data = array(
379
+ 'image' => $cover_url,
380
+ );
381
+
382
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
383
+ $data = $this->add_additional_fields_to_object( $data, $request );
384
+ $data = $this->filter_response_by_context( $data, $context );
385
+
386
+ $response = rest_ensure_response( $data );
387
+
388
+ /**
389
+ * Filter a user cover value returned from the API.
390
+ *
391
+ * @since 6.0.0
392
+ *
393
+ * @param WP_REST_Response $response Response.
394
+ * @param WP_REST_Request $request Request used to generate the response.
395
+ * @param string $cover_url Group cover url.
396
+ */
397
+ return apply_filters( 'bp_rest_attachments_member_cover_prepare_value', $response, $request, $cover_url );
398
+ }
399
+
400
+ /**
401
+ * Get the plugin schema, conforming to JSON Schema.
402
+ *
403
+ * @since 6.0.0
404
+ *
405
+ * @return array
406
+ */
407
+ public function get_item_schema() {
408
+ $schema = array(
409
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
410
+ 'title' => 'bp_attachments_user_cover',
411
+ 'type' => 'object',
412
+ 'properties' => array(
413
+ 'image' => array(
414
+ 'context' => array( 'view', 'edit' ),
415
+ 'description' => __( 'Full size of the image file.', 'buddypress' ),
416
+ 'type' => 'string',
417
+ 'format' => 'uri',
418
+ 'readonly' => true,
419
+ ),
420
+ ),
421
+ );
422
+
423
+ /**
424
+ * Filters the user cover schema.
425
+ *
426
+ * @param string $schema The endpoint schema.
427
+ */
428
+ return apply_filters( 'bp_rest_attachments_member_cover_schema', $this->add_additional_fields_schema( $schema ) );
429
+ }
430
+ }
bp-members/classes/class-bp-rest-members-endpoint.php CHANGED
@@ -379,8 +379,14 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
379
  'extra_capabilities' => array(),
380
  'registered_date' => '',
381
  'xprofile' => $this->xprofile_data( $user->ID ),
 
382
  );
383
 
 
 
 
 
 
384
  if ( 'edit' === $context ) {
385
  $data['registered_date'] = bp_rest_prepare_date_response( $user->data->user_registered );
386
  $data['roles'] = (array) array_values( $user->roles );
@@ -393,22 +399,28 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
393
  $data['mention_name'] = bp_activity_get_user_mentionname( $user->ID );
394
  }
395
 
 
 
 
396
  // Avatars.
397
- $data['avatar_urls'] = array(
398
- 'full' => bp_core_fetch_avatar(
399
- array(
400
- 'item_id' => $user->ID,
401
- 'html' => false,
402
- 'type' => 'full',
403
- )
404
- ),
405
- 'thumb' => bp_core_fetch_avatar(
406
- array(
407
- 'item_id' => $user->ID,
408
- 'html' => false,
409
- )
410
- ),
411
- );
 
 
 
412
 
413
  // Fallback.
414
  if ( false === $data['member_types'] ) {
@@ -436,6 +448,15 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
436
  $prepared_user->user_login = $request['user_login'];
437
  }
438
 
 
 
 
 
 
 
 
 
 
439
  /**
440
  * Filters an user object before it is inserted or updated via the REST API.
441
  *
@@ -504,6 +525,7 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
504
  */
505
  protected function can_manage_member( $user, $action = 'delete' ) {
506
  $capability = 'delete_user';
 
507
  if ( 'update' === $action ) {
508
  $capability = 'edit_user';
509
  }
@@ -525,7 +547,10 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
525
  */
526
  protected function update_additional_fields_for_object( $object, $request ) {
527
  if ( ! isset( $object->data ) ) {
528
- return new WP_Error( 'invalid_user', __( 'The data for the user was not found.', 'buddypress' ) );
 
 
 
529
  }
530
 
531
  $member = $object->data;
@@ -546,12 +571,25 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
546
  $args = WP_REST_Controller::get_endpoint_args_for_item_schema( $method );
547
  $key = 'get_item';
548
 
 
 
 
 
 
 
 
 
 
 
549
  if ( WP_REST_Server::CREATABLE === $method ) {
550
  $key = 'create_item';
551
 
552
  // We don't need the mention name to create a user.
553
  unset( $args['mention_name'] );
554
 
 
 
 
555
  // But we absolutely need the email.
556
  $args['email'] = array(
557
  'description' => __( 'The email address for the member.', 'buddypress' ),
@@ -568,6 +606,9 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
568
  * 2. The password belongs to the Settings endpoint parameter.
569
  */
570
  unset( $args['mention_name'], $args['user_login'], $args['password'] );
 
 
 
571
  } elseif ( WP_REST_Server::DELETABLE === $method ) {
572
  $key = 'delete_item';
573
  }
@@ -682,6 +723,12 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
682
  'context' => array( 'view', 'edit' ),
683
  'readonly' => true,
684
  ),
 
 
 
 
 
 
685
  ),
686
  );
687
 
@@ -690,7 +737,7 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
690
  $avatar_properties = array();
691
 
692
  $avatar_properties['full'] = array(
693
- /* translators: Full image size for the member Avatar */
694
  'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),
695
  'type' => 'string',
696
  'format' => 'uri',
@@ -698,7 +745,7 @@ class BP_REST_Members_Endpoint extends WP_REST_Users_Controller {
698
  );
699
 
700
  $avatar_properties['thumb'] = array(
701
- /* translators: Thumb imaze size for the member Avatar */
702
  'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),
703
  'type' => 'string',
704
  'format' => 'uri',
379
  'extra_capabilities' => array(),
380
  'registered_date' => '',
381
  'xprofile' => $this->xprofile_data( $user->ID ),
382
+ 'friendship_status' => false,
383
  );
384
 
385
+ // Check if user is friends with current logged in user.
386
+ if ( bp_is_active( 'friends' ) && get_current_user_id() !== $user->ID ) {
387
+ $data['friendship_status'] = ( 'is_friend' === friends_check_friendship_status( get_current_user_id(), $user->ID ) );
388
+ }
389
+
390
  if ( 'edit' === $context ) {
391
  $data['registered_date'] = bp_rest_prepare_date_response( $user->data->user_registered );
392
  $data['roles'] = (array) array_values( $user->roles );
399
  $data['mention_name'] = bp_activity_get_user_mentionname( $user->ID );
400
  }
401
 
402
+ // Get item schema.
403
+ $schema = $this->get_item_schema();
404
+
405
  // Avatars.
406
+ if ( ! empty( $schema['properties']['avatar_urls'] ) ) {
407
+ $data['avatar_urls'] = array(
408
+ 'full' => bp_core_fetch_avatar(
409
+ array(
410
+ 'item_id' => $user->ID,
411
+ 'html' => false,
412
+ 'type' => 'full',
413
+ )
414
+ ),
415
+ 'thumb' => bp_core_fetch_avatar(
416
+ array(
417
+ 'item_id' => $user->ID,
418
+ 'html' => false,
419
+ 'type' => 'thumb',
420
+ )
421
+ ),
422
+ );
423
+ }
424
 
425
  // Fallback.
426
  if ( false === $data['member_types'] ) {
448
  $prepared_user->user_login = $request['user_login'];
449
  }
450
 
451
+ // Set member type.
452
+ if ( isset( $prepared_user->ID ) && isset( $request['member_type'] ) ) {
453
+
454
+ // Append on update. Add on creation.
455
+ $append = WP_REST_Server::EDITABLE === $request->get_method();
456
+
457
+ bp_set_member_type( $prepared_user->ID, $request['member_type'], $append );
458
+ }
459
+
460
  /**
461
  * Filters an user object before it is inserted or updated via the REST API.
462
  *
525
  */
526
  protected function can_manage_member( $user, $action = 'delete' ) {
527
  $capability = 'delete_user';
528
+
529
  if ( 'update' === $action ) {
530
  $capability = 'edit_user';
531
  }
547
  */
548
  protected function update_additional_fields_for_object( $object, $request ) {
549
  if ( ! isset( $object->data ) ) {
550
+ return new WP_Error(
551
+ 'invalid_user',
552
+ __( 'The data for the user was not found.', 'buddypress' )
553
+ );
554
  }
555
 
556
  $member = $object->data;
571
  $args = WP_REST_Controller::get_endpoint_args_for_item_schema( $method );
572
  $key = 'get_item';
573
 
574
+ // Add member type args.
575
+ $member_type_args = array(
576
+ 'description' => __( 'Set type(s) for a member.', 'buddypress' ),
577
+ 'type' => 'string',
578
+ 'enum' => bp_get_member_types(),
579
+ 'context' => array( 'edit' ),
580
+ 'sanitize_callback' => 'bp_rest_sanitize_member_types',
581
+ 'validate_callback' => 'bp_rest_sanitize_member_types',
582
+ );
583
+
584
  if ( WP_REST_Server::CREATABLE === $method ) {
585
  $key = 'create_item';
586
 
587
  // We don't need the mention name to create a user.
588
  unset( $args['mention_name'] );
589
 
590
+ // Add member type args.
591
+ $args['types'] = $member_type_args;
592
+
593
  // But we absolutely need the email.
594
  $args['email'] = array(
595
  'description' => __( 'The email address for the member.', 'buddypress' ),
606
  * 2. The password belongs to the Settings endpoint parameter.
607
  */
608
  unset( $args['mention_name'], $args['user_login'], $args['password'] );
609
+
610
+ // Add member type args.
611
+ $args['types'] = $member_type_args;
612
  } elseif ( WP_REST_Server::DELETABLE === $method ) {
613
  $key = 'delete_item';
614
  }
723
  'context' => array( 'view', 'edit' ),
724
  'readonly' => true,
725
  ),
726
+ 'friendship_status' => array(
727
+ 'description' => __( 'Friendship relation with, current, logged in user.', 'buddypress' ),
728
+ 'type' => 'bool',
729
+ 'context' => array( 'view', 'edit' ),
730
+ 'readonly' => true,
731
+ ),
732
  ),
733
  );
734
 
737
  $avatar_properties = array();
738
 
739
  $avatar_properties['full'] = array(
740
+ /* translators: 1: Full avatar width in pixels. 2: Full avatar height in pixels */
741
  'description' => sprintf( __( 'Avatar URL with full image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_full_width() ), number_format_i18n( bp_core_avatar_full_height() ) ),
742
  'type' => 'string',
743
  'format' => 'uri',
745
  );
746
 
747
  $avatar_properties['thumb'] = array(
748
+ /* translators: 1: Thumb avatar width in pixels. 2: Thumb avatar height in pixels */
749
  'description' => sprintf( __( 'Avatar URL with thumb image size (%1$d x %2$d pixels).', 'buddypress' ), number_format_i18n( bp_core_avatar_thumb_width() ), number_format_i18n( bp_core_avatar_thumb_height() ) ),
750
  'type' => 'string',
751
  'format' => 'uri',
bp-members/classes/class-bp-rest-signup-endpoint.php ADDED
@@ -0,0 +1,818 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Signup_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 6.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Signup endpoints.
13
+ *
14
+ * Use /signup
15
+ * Use /signup/{id}
16
+ * Use /signup/activate/{id}
17
+ *
18
+ * @since 6.0.0
19
+ */
20
+ class BP_REST_Signup_Endpoint extends WP_REST_Controller {
21
+
22
+ /**
23
+ * Constructor.
24
+ *
25
+ * @since 6.0.0
26
+ */
27
+ public function __construct() {
28
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
29
+ $this->rest_base = 'signup';
30
+ }
31
+
32
+ /**
33
+ * Register the component routes.
34
+ *
35
+ * @since 6.0.0
36
+ */
37
+ public function register_routes() {
38
+ register_rest_route(
39
+ $this->namespace,
40
+ '/' . $this->rest_base,
41
+ array(
42
+ array(
43
+ 'methods' => WP_REST_Server::READABLE,
44
+ 'callback' => array( $this, 'get_items' ),
45
+ 'permission_callback' => array( $this, 'get_items_permissions_check' ),
46
+ 'args' => $this->get_collection_params(),
47
+ ),
48
+ array(
49
+ 'methods' => WP_REST_Server::CREATABLE,
50
+ 'callback' => array( $this, 'create_item' ),
51
+ 'permission_callback' => array( $this, 'create_item_permissions_check' ),
52
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
53
+ ),
54
+ 'schema' => array( $this, 'get_item_schema' ),
55
+ )
56
+ );
57
+
58
+ register_rest_route(
59
+ $this->namespace,
60
+ '/' . $this->rest_base . '/(?P<id>[\w-]+)',
61
+ array(
62
+ 'args' => array(
63
+ 'id' => array(
64
+ 'description' => __( 'Identifier for the signup. Can be a signup ID, an email address, or a user_login.', 'buddypress' ),
65
+ 'type' => 'string',
66
+ ),
67
+ ),
68
+ array(
69
+ 'methods' => WP_REST_Server::READABLE,
70
+ 'callback' => array( $this, 'get_item' ),
71
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
72
+ 'args' => array(
73
+ 'context' => $this->get_context_param(
74
+ array(
75
+ 'default' => 'view',
76
+ )
77
+ ),
78
+ ),
79
+ ),
80
+ array(
81
+ 'methods' => WP_REST_Server::DELETABLE,
82
+ 'callback' => array( $this, 'delete_item' ),
83
+ 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
84
+ 'args' => array(
85
+ 'context' => $this->get_context_param( array( 'default' => 'edit' ) ),
86
+ ),
87
+ ),
88
+ 'schema' => array( $this, 'get_item_schema' ),
89
+ )
90
+ );
91
+
92
+ // Register the activate route.
93
+ register_rest_route(
94
+ $this->namespace,
95
+ '/' . $this->rest_base . '/activate/(?P<id>[\w-]+)',
96
+ array(
97
+ 'args' => array(
98
+ 'id' => array(
99
+ 'description' => __( 'Identifier for the signup. Can be a signup ID, an email address, or a user_login.', 'buddypress' ),
100
+ 'type' => 'string',
101
+ ),
102
+ ),
103
+ array(
104
+ 'methods' => WP_REST_Server::EDITABLE,
105
+ 'callback' => array( $this, 'activate_item' ),
106
+ 'permission_callback' => array( $this, 'activate_item_permissions_check' ),
107
+ 'args' => array(
108
+ 'context' => $this->get_context_param( array( 'default' => 'edit' ) ),
109
+ ),
110
+ ),
111
+ 'schema' => array( $this, 'get_item_schema' ),
112
+ )
113
+ );
114
+ }
115
+
116
+ /**
117
+ * Retrieve signups.
118
+ *
119
+ * @since 6.0.0
120
+ *
121
+ * @param WP_REST_Request $request Full details about the request.
122
+ * @return WP_REST_Response
123
+ */
124
+ public function get_items( $request ) {
125
+ $args = array(
126
+ 'include' => $request['include'],
127
+ 'order' => $request['order'],
128
+ 'orderby' => $request['orderby'],
129
+ 'user_login' => $request['user_login'],
130
+ 'page' => $request['number'],
131
+ 'offset' => $request['per_page'],
132
+ );
133
+
134
+ if ( empty( $request['include'] ) ) {
135
+ $args['include'] = false;
136
+ }
137
+
138
+ /**
139
+ * Filter the query arguments for the request.
140
+ *
141
+ * @since 6.0.0
142
+ *
143
+ * @param array $args Key value array of query var to query value.
144
+ * @param WP_REST_Request $request The request sent to the API.
145
+ */
146
+ $args = apply_filters( 'bp_rest_signup_get_items_query_args', $args, $request );
147
+
148
+ // Actually, query it.
149
+ $signups = BP_Signup::get( $args );
150
+
151
+ $retval = array();
152
+ foreach ( $signups['signups'] as $signup ) {
153
+ $retval[] = $this->prepare_response_for_collection(
154
+ $this->prepare_item_for_response( $signup, $request )
155
+ );
156
+ }
157
+
158
+ $response = rest_ensure_response( $retval );
159
+ $response = bp_rest_response_add_total_headers( $response, $signups['total'], $args['offset'] );
160
+
161
+ /**
162
+ * Fires after a list of signups is fetched via the REST API.
163
+ *
164
+ * @since 6.0.0
165
+ *
166
+ * @param array $signups Fetched signups.
167
+ * @param WP_REST_Response $response The response data.
168
+ * @param WP_REST_Request $request The request sent to the API.
169
+ */
170
+ do_action( 'bp_rest_signup_get_items', $signups, $response, $request );
171
+
172
+ return $response;
173
+ }
174
+
175
+ /**
176
+ * Check if a given request has access to signup items.
177
+ *
178
+ * @since 6.0.0
179
+ *
180
+ * @param WP_REST_Request $request Full data about the request.
181
+ * @return bool|WP_Error
182
+ */
183
+ public function get_items_permissions_check( $request ) {
184
+ $retval = true;
185
+
186
+ if ( ! is_user_logged_in() ) {
187
+ $retval = new WP_Error(
188
+ 'bp_rest_authorization_required',
189
+ __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
190
+ array(
191
+ 'status' => rest_authorization_required_code(),
192
+ )
193
+ );
194
+ }
195
+
196
+ if ( true === $retval && ! bp_current_user_can( 'bp_moderate' ) ) {
197
+ $retval = new WP_Error(
198
+ 'bp_rest_authorization_required',
199
+ __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
200
+ array(
201
+ 'status' => rest_authorization_required_code(),
202
+ )
203
+ );
204
+ }
205
+
206
+ /**
207
+ * Filter the signup `get_items` permissions check.
208
+ *
209
+ * @since 6.0.0
210
+ *
211
+ * @param bool|WP_Error $retval Returned value.
212
+ * @param WP_REST_Request $request The request sent to the API.
213
+ */
214
+ return apply_filters( 'bp_rest_signup_get_items_permissions_check', $retval, $request );
215
+ }
216
+
217
+ /**
218
+ * Retrieve single signup.
219
+ *
220
+ * @since 6.0.0
221
+ *
222
+ * @param WP_REST_Request $request Full data about the request.
223
+ * @return WP_REST_Response|WP_Error
224
+ */
225
+ public function get_item( $request ) {
226
+ // Get signup.
227
+ $signup = $this->get_signup_object( $request['id'] );
228
+
229
+ $retval = array(
230
+ $this->prepare_response_for_collection(
231
+ $this->prepare_item_for_response( $signup, $request )
232
+ ),
233
+ );
234
+
235
+ $response = rest_ensure_response( $retval );
236
+
237
+ /**
238
+ * Fires before a signup is retrieved via the REST API.
239
+ *
240
+ * @since 6.0.0
241
+ *
242
+ * @param BP_Signup $signup The signup object.
243
+ * @param WP_REST_Response $response The response data.
244
+ * @param WP_REST_Request $request The request sent to the API.
245
+ */
246
+ do_action( 'bp_rest_signup_get_item', $signup, $response, $request );
247
+
248
+ return $response;
249
+ }
250
+
251
+ /**
252
+ * Check if a given request has access to get a signup.
253
+ *
254
+ * @since 6.0.0
255
+ *
256
+ * @param WP_REST_Request $request Full data about the request.
257
+ * @return WP_Error|bool
258
+ */
259
+ public function get_item_permissions_check( $request ) {
260
+ $retval = true;
261
+ $signup = $this->get_signup_object( $request['id'] );
262
+
263
+ if ( ! is_user_logged_in() ) {
264
+ $retval = new WP_Error(
265
+ 'bp_rest_authorization_required',
266
+ __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
267
+ array(
268
+ 'status' => rest_authorization_required_code(),
269
+ )
270
+ );
271
+ }
272
+
273
+ if ( true === $retval && empty( $signup ) ) {
274
+ $retval = new WP_Error(
275
+ 'bp_rest_invalid_id',
276
+ __( 'Invalid signup id.', 'buddypress' ),
277
+ array(
278
+ 'status' => 404,
279
+ )
280
+ );
281
+ }
282
+
283
+ if ( true === $retval && ! bp_current_user_can( 'bp_moderate' ) ) {
284
+ $retval = new WP_Error(
285
+ 'bp_rest_authorization_required',
286
+ __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
287
+ array(
288
+ 'status' => rest_authorization_required_code(),
289
+ )
290
+ );
291
+ }
292
+
293
+ /**
294
+ * Filter the signup `get_item` permissions check.
295
+ *
296
+ * @since 6.0.0
297
+ *
298
+ * @param bool|WP_Error $retval Returned value.
299
+ * @param WP_REST_Request $request The request sent to the API.
300
+ */
301
+ return apply_filters( 'bp_rest_signup_get_item_permissions_check', $retval, $request );
302
+ }
303
+
304
+ /**
305
+ * Create signup.
306
+ *
307
+ * @since 6.0.0
308
+ *
309
+ * @param WP_REST_Request $request Full data about the request.
310
+ * @return WP_REST_Response|WP_Error
311
+ */
312
+ public function create_item( $request ) {
313
+ $request->set_param( 'context', 'edit' );
314
+
315
+ $user_login = $request['user_login'];
316
+ if ( ! empty( $user_login ) ) {
317
+ $user_login = preg_replace( '/\s+/', '', sanitize_user( $user_login, true ) );
318
+ }
319
+
320
+ $user_email = $request['user_email'];
321
+ if ( ! empty( $user_email ) ) {
322
+ $user_email = sanitize_email( $user_email );
323
+ }
324
+
325
+ $signup_args = array(
326
+ 'user_login' => $user_login,
327
+ 'user_email' => $user_email,
328
+ 'activation_key' => $request['activation_key'],
329
+ 'domain' => $request['domain'],
330
+ 'path' => $request['path'],
331
+ 'title' => $request['title'],
332
+ );
333
+
334
+ // Add signup.
335
+ $id = \BP_Signup::add( $signup_args );
336
+
337
+ if ( ! is_numeric( $id ) ) {
338
+ return new WP_Error(
339
+ 'bp_rest_signup_cannot_create',
340
+ __( 'Cannot create new signup.', 'buddypress' ),
341
+ array(
342
+ 'status' => 500,
343
+ )
344
+ );
345
+ }
346
+
347
+ $signup = $this->get_signup_object( $id );
348
+ $signup_update = $this->update_additional_fields_for_object( $signup, $request );
349
+
350
+ if ( is_wp_error( $signup_update ) ) {
351
+ return $signup_update;
352
+ }
353
+
354
+ $retval = array(
355
+ $this->prepare_response_for_collection(
356
+ $this->prepare_item_for_response( $signup, $request )
357
+ ),
358
+ );
359
+
360
+ $response = rest_ensure_response( $retval );
361
+
362
+ /**
363
+ * Fires after a signup item is created via the REST API.
364
+ *
365
+ * @since 6.0.0
366
+ *
367
+ * @param BP_Signup $signup The created signup.
368
+ * @param WP_REST_Response $response The response data.
369
+ * @param WP_REST_Request $request The request sent to the API.
370
+ */
371
+ do_action( 'bp_rest_signup_create_item', $signup, $response, $request );
372
+
373
+ return $response;
374
+ }
375
+
376
+ /**
377
+ * Checks if a given request has access to create a signup.
378
+ *
379
+ * @since 6.0.0
380
+ *
381
+ * @param WP_REST_Request $request Full details about the request.
382
+ * @return bool|WP_Error
383
+ */
384
+ public function create_item_permissions_check( $request ) {
385
+ $retval = true;
386
+
387
+ if ( ! is_user_logged_in() ) {
388
+ $retval = new WP_Error(
389
+ 'bp_rest_authorization_required',
390
+ __( 'Sorry, you need to be logged in to perform this action.', 'buddypress' ),
391
+ array(
392
+ 'status' => rest_authorization_required_code(),
393
+ )
394
+ );
395
+ }
396
+
397
+ if ( true === $retval && ! bp_current_user_can( 'bp_moderate' ) ) {
398
+ $retval = new WP_Error(
399
+ 'bp_rest_authorization_required',
400
+ __( 'Sorry, you are not authorized to perform this action.', 'buddypress' ),
401
+ array(
402
+ 'status' => rest_authorization_required_code(),
403
+ )
404
+ );
405
+ }
406
+
407
+ /**
408
+ * Filter the signup `create_item` permissions check.
409
+ *
410
+ * @since 6.0.0
411
+ *
412
+ * @param bool|WP_Error $retval Returned value.
413
+ * @param WP_REST_Request $request The request sent to the API.
414
+ */
415
+ return apply_filters( 'bp_rest_signup_create_item_permissions_check', $retval, $request );
416
+ }
417
+
418
+ /**
419
+ * Delete a signup.
420
+ *
421
+ * @since 6.0.0
422
+ *
423
+ * @param WP_REST_Request $request Full details about the request.
424
+ * @return WP_REST_Response|WP_Error
425
+ */
426
+ public function delete_item( $request ) {
427
+ $request->set_param( 'context', 'edit' );
428
+
429
+ // Get the signup before it's deleted.
430
+ $signup = $this->get_signup_object( $request['id'] );
431
+ $previous = $this->prepare_item_for_response( $signup, $request );
432
+ $deleted = BP_Signup::delete( array( $signup->id ) );
433
+
434
+ if ( ! $deleted ) {
435
+ return new WP_Error(
436
+ 'bp_rest_signup_cannot_delete',
437
+ __( 'Could not delete signup.', 'buddypress' ),
438
+ array(
439
+ 'status' => 500,
440
+ )
441
+ );
442
+ }
443
+
444
+ // Build the response.
445
+ $response = new WP_REST_Response();
446
+ $response->set_data(
447
+ array(
448
+ 'deleted' => true,
449
+ 'previous' => $previous->get_data(),
450
+ )
451
+ );
452
+
453
+ /**
454
+ * Fires after a signup is deleted via the REST API.
455
+ *
456
+ * @since 6.0.0
457
+ *
458
+ * @param BP_Signup $signup The deleted signup.
459
+ * @param WP_REST_Response $response The response data.
460
+ * @param WP_REST_Request $request The request sent to the API.
461
+ */
462
+ do_action( 'bp_rest_signup_delete_item', $signup, $response, $request );
463
+
464
+ return $response;
465
+ }
466
+
467
+ /**
468
+ * Check if a given request has access to delete a signup.
469
+ *
470
+ * @since 6.0.0
471
+ *
472
+ * @param WP_REST_Request $request Full details about the request.
473
+ * @return bool|WP_Error
474
+ */
475
+ public function delete_item_permissions_check( $request ) {
476
+ $retval = $this->get_item_permissions_check( $request );
477
+
478
+ /**
479
+ * Filter the signup `delete_item` permissions check.
480
+ *
481
+ * @since 6.0.0
482
+ *
483
+ * @param bool|WP_Error $retval Returned value.
484
+ * @param WP_REST_Request $request The request sent to the API.
485
+ */
486
+ return apply_filters( 'bp_rest_signup_delete_item_permissions_check', $retval, $request );
487
+ }
488
+
489
+ /**
490
+ * Activate a signup.
491
+ *
492
+ * @since 6.0.0
493
+ *
494
+ * @param WP_REST_Request $request Full details about the request.
495
+ * @return WP_REST_Response|WP_Error
496
+ */
497
+ public function activate_item( $request ) {
498
+ $request->set_param( 'context', 'edit' );
499
+
500
+ // Get the signup.
501
+ $signup = $this->get_signup_object( $request['id'] );
502
+ $activated = bp_core_activate_signup( $signup->activation_key );
503
+
504
+ if ( ! $activated ) {
505
+ return new WP_Error(
506
+ 'bp_rest_signup_activate_fail',
507
+ __( 'Fail to activate the signup.', 'buddypress' ),
508
+ array(
509
+ 'status' => 500,
510
+ )
511
+ );
512
+ }
513
+
514
+ $retval = array(
515
+ $this->prepare_response_for_collection(
516
+ $this->prepare_item_for_response( $signup, $request )
517
+ ),
518
+ );
519
+
520
+ $response = rest_ensure_response( $retval );
521
+
522
+ /**
523
+ * Fires after a signup is activated via the REST API.
524
+ *
525
+ * @since 6.0.0
526
+ *
527
+ * @param BP_Signup $signup The activated signup.
528
+ * @param WP_REST_Response $response The response data.
529
+ * @param WP_REST_Request $request The request sent to the API.
530
+ */
531
+ do_action( 'bp_rest_signup_activate_item', $signup, $response, $request );
532
+
533
+ return $response;
534
+ }
535
+
536
+ /**
537
+ * Check if a given request has access to activate a signup.
538
+ *
539
+ * @since 6.0.0
540
+ *
541
+ * @param WP_REST_Request $request Full details about the request.
542
+ * @return bool|WP_Error
543
+ */
544
+ public function activate_item_permissions_check( $request ) {
545
+ $retval = true;
546
+ $signup = $this->get_signup_object( $request['id'] );
547
+
548
+ if ( empty( $signup ) ) {
549
+ $retval = new WP_Error(
550
+ 'bp_rest_invalid_id',
551
+ __( 'Invalid signup id.', 'buddypress' ),
552
+ array(
553
+ 'status' => 404,
554
+ )
555
+ );
556
+ }
557
+
558
+ /**
559
+ * Filter the signup `activate_item` permissions check.
560
+ *
561
+ * @since 6.0.0
562
+ *
563
+ * @param bool|WP_Error $retval Returned value.
564
+ * @param WP_REST_Request $request The request sent to the API.
565
+ */
566
+ return apply_filters( 'bp_rest_signup_activate_item_permissions_check', $retval, $request );
567
+ }
568
+
569
+ /**
570
+ * Prepares signup to return as an object.
571
+ *
572
+ * @since 6.0.0
573
+ *
574
+ * @param BP_Signup $signup Signup object.
575
+ * @param WP_REST_Request $request Full data about the request.
576
+ * @return WP_REST_Response
577
+ */
578
+ public function prepare_item_for_response( $signup, $request ) {
579
+ $data = array(
580
+ 'id' => $signup->id,
581
+ 'user_login' => $signup->user_login,
582
+ 'user_name' => $signup->user_name,
583
+ 'registered' => bp_rest_prepare_date_response( $signup->registered ),
584
+ );
585
+
586
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
587
+
588
+ if ( 'edit' === $context ) {
589
+ $data['activation_key'] = $signup->activation_key;
590
+ $data['user_email'] = $signup->user_email;
591
+ }
592
+
593
+ $data = $this->add_additional_fields_to_object( $data, $request );
594
+ $data = $this->filter_response_by_context( $data, $context );
595
+
596
+ // @todo add prepare_links
597
+ $response = rest_ensure_response( $data );
598
+
599
+ /**
600
+ * Filter the signup response returned from the API.
601
+ *
602
+ * @since 6.0.0
603
+ *
604
+ * @param WP_REST_Response $response The response data.
605
+ * @param WP_REST_Request $request Request used to generate the response.
606
+ * @param BP_Signup $signup Signup object.
607
+ */
608
+ return apply_filters( 'bp_rest_signup_prepare_value', $response, $request, $signup );
609
+ }
610
+
611
+ /**
612
+ * Get signup object.
613
+ *
614
+ * @since 6.0.0
615
+ *
616
+ * @param int $identifier Signup identifier.
617
+ * @return BP_Signup|bool
618
+ */
619
+ public function get_signup_object( $identifier ) {
620
+ if ( is_numeric( $identifier ) ) {
621
+ $signup_args['include'] = array( intval( $identifier ) );
622
+ } elseif ( is_email( $identifier ) ) {
623
+ $signup_args['usersearch'] = $identifier;
624
+ } else {
625
+ $signup_args['user_login'] = $identifier;
626
+ }
627
+
628
+ // Get signups.
629
+ $signups = \BP_Signup::get( $signup_args );
630
+
631
+ if ( ! empty( $signups['signups'] ) ) {
632
+ return reset( $signups['signups'] );
633
+ }
634
+
635
+ return false;
636
+ }
637
+
638
+ /**
639
+ * Edit the type of the some properties for the CREATABLE & EDITABLE methods.
640
+ *
641
+ * @since 6.0.0
642
+ *
643
+ * @param string $method Optional. HTTP method of the request.
644
+ * @return array Endpoint arguments.
645
+ */
646
+ public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {
647
+ $args = WP_REST_Controller::get_endpoint_args_for_item_schema( $method );
648
+ $key = 'get_item';
649
+
650
+ if ( WP_REST_Server::CREATABLE === $method ) {
651
+ $key = 'create_item';
652
+ $args['activation_key']['default'] = wp_generate_password( 32, false );
653
+ $args['domain'] = array(
654
+ 'context' => array( 'edit' ),
655
+ 'description' => __( 'New user domain.', 'buddypress' ),
656
+ 'type' => 'string',
657
+ 'default' => '',
658
+ 'readonly' => true,
659
+ );
660
+ $args['path'] = array(
661
+ 'context' => array( 'edit' ),
662
+ 'description' => __( 'New user title.', 'buddypress' ),
663
+ 'type' => 'string',
664
+ 'default' => '',
665
+ 'readonly' => true,
666
+ );
667
+ $args['title'] = array(
668
+ 'context' => array( 'edit' ),
669
+ 'description' => __( 'New user path.', 'buddypress' ),
670
+ 'type' => 'string',
671
+ 'default' => '',
672
+ 'readonly' => true,
673
+ );
674
+ } elseif ( WP_REST_Server::EDITABLE === $method ) {
675
+ $key = 'update_item';
676
+ } elseif ( WP_REST_Server::DELETABLE === $method ) {
677
+ $key = 'delete_item';
678
+ }
679
+
680
+ /**
681
+ * Filters the method query arguments.
682
+ *
683
+ * @since 6.0.0
684
+ *
685
+ * @param array $args Query arguments.
686
+ * @param string $method HTTP method of the request.
687
+ */
688
+ return apply_filters( "bp_rest_signup_{$key}_query_arguments", $args, $method );
689
+ }
690
+
691
+ /**
692
+ * Get the signup schema, conforming to JSON Schema.
693
+ *
694
+ * @since 6.0.0
695
+ *
696
+ * @return array
697
+ */
698
+ public function get_item_schema() {
699
+ $schema = array(
700
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
701
+ 'title' => 'bp_signup',
702
+ 'type' => 'object',
703
+ 'properties' => array(
704
+ 'id' => array(
705
+ 'context' => array( 'view', 'edit' ),
706
+ 'description' => __( 'A unique numeric ID for the signup.', 'buddypress' ),
707
+ 'readonly' => true,
708
+ 'type' => 'integer',
709
+ ),
710
+ 'user_login' => array(
711
+ 'context' => array( 'view', 'edit' ),
712
+ 'description' => __( 'The username of the user the signup is for.', 'buddypress' ),
713
+ 'required' => true,
714
+ 'type' => 'string',
715
+ 'readonly' => true,
716
+ ),
717
+ 'user_name' => array(
718
+ 'context' => array( 'view', 'edit' ),
719
+ 'description' => __( 'The full name of the user the signup is for.', 'buddypress' ),
720
+ 'type' => 'string',
721
+ 'readonly' => true,
722
+ 'arg_options' => array(
723
+ 'sanitize_callback' => 'sanitize_text_field',
724
+ ),
725
+ ),
726
+ 'user_email' => array(
727
+ 'context' => array( 'edit' ),
728
+ 'description' => __( 'The email for the user the signup is for.', 'buddypress' ),
729
+ 'type' => 'string',
730
+ 'readonly' => true,
731
+ ),
732
+ 'activation_key' => array(
733
+ 'context' => array( 'edit' ),
734
+ 'description' => __( 'Activation key of the signup.', 'buddypress' ),
735
+ 'type' => 'string',
736
+ 'readonly' => true,
737
+ ),
738
+ 'registered' => array(
739
+ 'context' => array( 'view', 'edit' ),
740
+ 'description' => __( 'The registered date for the user, in the site\'s timezone.', 'buddypress' ),
741
+ 'type' => 'string',
742
+ 'readonly' => true,
743
+ 'format' => 'date-time',
744
+ ),
745
+ ),
746
+ );
747
+
748
+ /**
749
+ * Filters the signup schema.
750
+ *
751
+ * @param array $schema The endpoint schema.
752
+ */
753
+ return apply_filters( 'bp_rest_signup_schema', $this->add_additional_fields_schema( $schema ) );
754
+ }
755
+
756
+ /**
757
+ * Get the query params for collections.
758
+ *
759
+ * @since 6.0.0
760
+ *
761
+ * @return array
762
+ */
763
+ public function get_collection_params() {
764
+ $params = parent::get_collection_params();
765
+ $params['context']['default'] = 'view';
766
+
767
+ unset( $params['page'], $params['search'] );
768
+
769
+ $params['include'] = array(
770
+ 'description' => __( 'Ensure result set includes specific IDs.', 'buddypress' ),
771
+ 'default' => array(),
772
+ 'type' => 'array',
773
+ 'items' => array( 'type' => 'integer' ),
774
+ 'sanitize_callback' => 'wp_parse_id_list',
775
+ 'validate_callback' => 'rest_validate_request_arg',
776
+ );
777
+
778
+ $params['order'] = array(
779
+ 'description' => __( 'Order sort attribute ascending or descending.', 'buddypress' ),
780
+ 'default' => 'desc',
781
+ 'type' => 'string',
782
+ 'enum' => array( 'asc', 'desc' ),
783
+ 'sanitize_callback' => 'sanitize_key',
784
+ 'validate_callback' => 'rest_validate_request_arg',
785
+ );
786
+
787
+ $params['number'] = array(
788
+ 'description' => __( 'Total number of signups to return.', 'buddypress' ),
789
+ 'default' => 1,
790
+ 'type' => 'integer',
791
+ 'sanitize_callback' => 'absint',
792
+ 'validate_callback' => 'rest_validate_request_arg',
793
+ );
794
+
795
+ $params['orderby'] = array(
796
+ 'description' => __( 'Order by a specific parameter (default: signup_id).', 'buddypress' ),
797
+ 'default' => 'signup_id',
798
+ 'type' => 'string',
799
+ 'sanitize_callback' => 'sanitize_key',
800
+ 'validate_callback' => 'rest_validate_request_arg',
801
+ );
802
+
803
+ $params['user_login'] = array(
804
+ 'description' => __( 'Specific user login to return.', 'buddypress' ),
805
+ 'default' => '',
806
+ 'type' => 'string',
807
+ 'sanitize_callback' => 'sanitize_key',
808
+ 'validate_callback' => 'rest_validate_request_arg',
809
+ );
810
+
811
+ /**
812
+ * Filters the collection query params.
813
+ *
814
+ * @param array $params Query params.
815
+ */
816
+ return apply_filters( 'bp_rest_signup_collection_params', $params );
817
+ }
818
+ }
bp-members/css/blocks/member-rtl.css ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* CSS for the bp/member block */
2
+ .bp-block-member {
3
+ position: relative;
4
+ }
5
+
6
+ .bp-block-member .member-content {
7
+ display: flex;
8
+ }
9
+
10
+ .bp-block-member.has-cover .member-content,
11
+ .bp-block-member.has-cover .item-header-avatar,
12
+ .bp-block-member.has-cover .member-description {
13
+ z-index: 2;
14
+ }
15
+
16
+ .bp-block-member.has-cover .member-description {
17
+ padding-top: 75px;
18
+ }
19
+
20
+ .bp-block-member.has-cover .bp-member-cover-image {
21
+ background-color: #c5c5c5;
22
+ background-position: center top;
23
+ background-repeat: no-repeat;
24
+ background-size: cover;
25
+ border: 0;
26
+ display: block;
27
+ right: 0;
28
+ margin: 0;
29
+ padding: 0;
30
+ position: absolute;
31
+ top: 0;
32
+ width: 100%;
33
+ z-index: 1;
34
+ height: 150px;
35
+ }
36
+
37
+ .bp-block-member img.avatar {
38
+ width: auto;
39
+ height: auto;
40
+ }
41
+
42
+ .bp-block-member.avatar-none .item-header-avatar {
43
+ display: none;
44
+ }
45
+
46
+ .bp-block-member.avatar-none.has-cover {
47
+ min-height: 200px;
48
+ }
49
+
50
+ .bp-block-member.avatar-full {
51
+ min-height: 150px;
52
+ }
53
+
54
+ .bp-block-member.avatar-full.has-cover {
55
+ min-height: 300px;
56
+ }
57
+
58
+ .bp-block-member.avatar-full .item-header-avatar {
59
+ width: 180px;
60
+ }
61
+
62
+ .bp-block-member.has-cover.avatar-full .item-header-avatar {
63
+ width: 200px;
64
+ }
65
+
66
+ .bp-block-member.has-cover.avatar-full img.avatar {
67
+ border: solid 2px #fff;
68
+ background: rgba(255, 255, 255, 0.8);
69
+ margin-right: 20px;
70
+ }
71
+
72
+ .bp-block-member.has-cover .member-content {
73
+ padding-top: 75px;
74
+ }
75
+
76
+ .bp-block-member.avatar-thumb .member-content {
77
+ min-height: 50px;
78
+ align-items: center;
79
+ }
80
+
81
+ .bp-block-member.avatar-thumb .item-header-avatar {
82
+ width: 70px;
83
+ }
84
+
85
+ .bp-block-member.avatar-thumb.has-cover .item-header-avatar {
86
+ padding-top: 75px;
87
+ }
88
+
89
+ .bp-block-member .user-nicename {
90
+ display: block;
91
+ }
92
+
93
+ .bp-block-member .user-nicename a,
94
+ .entry .entry-content .bp-block-member .user-nicename a {
95
+ color: currentColor;
96
+ text-decoration: none;
97
+ border: none;
98
+ }
99
+
100
+ .bp-block-member .bp-profile-button {
101
+ width: 100%;
102
+ }
103
+
104
+ .bp-block-member .bp-profile-button a.button {
105
+ position: absolute;
106
+ bottom: 10px;
107
+ left: 0;
108
+ display: inline-block;
109
+ margin: 18px 0 0;
110
+ }
bp-members/css/blocks/member-rtl.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .bp-block-member{position:relative}.bp-block-member .member-content{display:flex}.bp-block-member.has-cover .item-header-avatar,.bp-block-member.has-cover .member-content,.bp-block-member.has-cover .member-description{z-index:2}.bp-block-member.has-cover .member-description{padding-top:75px}.bp-block-member.has-cover .bp-member-cover-image{background-color:#c5c5c5;background-position:center top;background-repeat:no-repeat;background-size:cover;border:0;display:block;right:0;margin:0;padding:0;position:absolute;top:0;width:100%;z-index:1;height:150px}.bp-block-member img.avatar{width:auto;height:auto}.bp-block-member.avatar-none .item-header-avatar{display:none}.bp-block-member.avatar-none.has-cover{min-height:200px}.bp-block-member.avatar-full{min-height:150px}.bp-block-member.avatar-full.has-cover{min-height:300px}.bp-block-member.avatar-full .item-header-avatar{width:180px}.bp-block-member.has-cover.avatar-full .item-header-avatar{width:200px}.bp-block-member.has-cover.avatar-full img.avatar{border:solid 2px #fff;background:rgba(255,255,255,.8);margin-right:20px}.bp-block-member.has-cover .member-content{padding-top:75px}.bp-block-member.avatar-thumb .member-content{min-height:50px;align-items:center}.bp-block-member.avatar-thumb .item-header-avatar{width:70px}.bp-block-member.avatar-thumb.has-cover .item-header-avatar{padding-top:75px}.bp-block-member .user-nicename{display:block}.bp-block-member .user-nicename a,.entry .entry-content .bp-block-member .user-nicename a{color:currentColor;text-decoration:none;border:none}.bp-block-member .bp-profile-button{width:100%}.bp-block-member .bp-profile-button a.button{position:absolute;bottom:10px;left:0;display:inline-block;margin:18px 0 0}
bp-members/css/blocks/member.css ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* CSS for the bp/member block */
2
+ .bp-block-member {
3
+ position: relative;
4
+ }
5
+
6
+ .bp-block-member .member-content {
7
+ display: flex;
8
+ }
9
+
10
+ .bp-block-member.has-cover .member-content,
11
+ .bp-block-member.has-cover .item-header-avatar,
12
+ .bp-block-member.has-cover .member-description {
13
+ z-index: 2;
14
+ }
15
+
16
+ .bp-block-member.has-cover .member-description {
17
+ padding-top: 75px;
18
+ }
19
+
20
+ .bp-block-member.has-cover .bp-member-cover-image {
21
+ background-color: #c5c5c5;
22
+ background-position: center top;
23
+ background-repeat: no-repeat;
24
+ background-size: cover;
25
+ border: 0;
26
+ display: block;
27
+ left: 0;
28
+ margin: 0;
29
+ padding: 0;
30
+ position: absolute;
31
+ top: 0;
32
+ width: 100%;
33
+ z-index: 1;
34
+ height: 150px;
35
+ }
36
+
37
+ .bp-block-member img.avatar {
38
+ width: auto;
39
+ height: auto;
40
+ }
41
+
42
+ .bp-block-member.avatar-none .item-header-avatar {
43
+ display: none;
44
+ }
45
+
46
+ .bp-block-member.avatar-none.has-cover {
47
+ min-height: 200px;
48
+ }
49
+
50
+ .bp-block-member.avatar-full {
51
+ min-height: 150px;
52
+ }
53
+
54
+ .bp-block-member.avatar-full.has-cover {
55
+ min-height: 300px;
56
+ }
57
+
58
+ .bp-block-member.avatar-full .item-header-avatar {
59
+ width: 180px;
60
+ }
61
+
62
+ .bp-block-member.has-cover.avatar-full .item-header-avatar {
63
+ width: 200px;
64
+ }
65
+
66
+ .bp-block-member.has-cover.avatar-full img.avatar {
67
+ border: solid 2px #fff;
68
+ background: rgba(255, 255, 255, 0.8);
69
+ margin-left: 20px;
70
+ }
71
+
72
+ .bp-block-member.has-cover .member-content {
73
+ padding-top: 75px;
74
+ }
75
+
76
+ .bp-block-member.avatar-thumb .member-content {
77
+ min-height: 50px;
78
+ align-items: center;
79
+ }
80
+
81
+ .bp-block-member.avatar-thumb .item-header-avatar {
82
+ width: 70px;
83
+ }
84
+
85
+ .bp-block-member.avatar-thumb.has-cover .item-header-avatar {
86
+ padding-top: 75px;
87
+ }
88
+
89
+ .bp-block-member .user-nicename {
90
+ display: block;
91
+ }
92
+
93
+ .bp-block-member .user-nicename a,
94
+ .entry .entry-content .bp-block-member .user-nicename a {
95
+ color: currentColor;
96
+ text-decoration: none;
97
+ border: none;
98
+ }
99
+
100
+ .bp-block-member .bp-profile-button {
101
+ width: 100%;
102
+ }
103
+
104
+ .bp-block-member .bp-profile-button a.button {
105
+ position: absolute;
106
+ bottom: 10px;
107
+ right: 0;
108
+ display: inline-block;
109
+ margin: 18px 0 0;
110
+ }
bp-members/css/blocks/member.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .bp-block-member{position:relative}.bp-block-member .member-content{display:flex}.bp-block-member.has-cover .item-header-avatar,.bp-block-member.has-cover .member-content,.bp-block-member.has-cover .member-description{z-index:2}.bp-block-member.has-cover .member-description{padding-top:75px}.bp-block-member.has-cover .bp-member-cover-image{background-color:#c5c5c5;background-position:center top;background-repeat:no-repeat;background-size:cover;border:0;display:block;left:0;margin:0;padding:0;position:absolute;top:0;width:100%;z-index:1;height:150px}.bp-block-member img.avatar{width:auto;height:auto}.bp-block-member.avatar-none .item-header-avatar{display:none}.bp-block-member.avatar-none.has-cover{min-height:200px}.bp-block-member.avatar-full{min-height:150px}.bp-block-member.avatar-full.has-cover{min-height:300px}.bp-block-member.avatar-full .item-header-avatar{width:180px}.bp-block-member.has-cover.avatar-full .item-header-avatar{width:200px}.bp-block-member.has-cover.avatar-full img.avatar{border:solid 2px #fff;background:rgba(255,255,255,.8);margin-left:20px}.bp-block-member.has-cover .member-content{padding-top:75px}.bp-block-member.avatar-thumb .member-content{min-height:50px;align-items:center}.bp-block-member.avatar-thumb .item-header-avatar{width:70px}.bp-block-member.avatar-thumb.has-cover .item-header-avatar{padding-top:75px}.bp-block-member .user-nicename{display:block}.bp-block-member .user-nicename a,.entry .entry-content .bp-block-member .user-nicename a{color:currentColor;text-decoration:none;border:none}.bp-block-member .bp-profile-button{width:100%}.bp-block-member .bp-profile-button a.button{position:absolute;bottom:10px;right:0;display:inline-block;margin:18px 0 0}
bp-members/js/blocks/member.js ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;c<t.length;c++)try{f(t[c])}catch(e){i||(i=e)}if(t.length){var l=f(t[t.length-1]);"object"==typeof exports&&"undefined"!=typeof module?module.exports=l:"function"==typeof define&&define.amd?define(function(){return l}):n&&(this[n]=l)}if(parcelRequire=f,i)throw i;return f}({"TmUL":[function(require,module,exports) {
2
+ var e=wp.blocks.registerBlockType,t=wp.element,n=t.createElement,s=t.Fragment,l=wp.components,i=l.Placeholder,r=l.Disabled,a=l.PanelBody,o=l.SelectControl,d=l.ToggleControl,u=l.Toolbar,p=l.ToolbarButton,b=wp.blockEditor,m=b.InspectorControls,y=b.BlockControls,c=wp.data.withSelect,g=wp.compose.compose,h=wp.editor.ServerSideRender,v=wp.i18n.__,f=bp.blockComponents.AutoCompleter,C=[{label:v("None","buddypress"),value:"none"},{label:v("Thumb","buddypress"),value:"thumb"},{label:v("Full","buddypress"),value:"full"}],S=function(e){var t=e.attributes,l=e.setAttributes,b=e.bpSettings,c=b.isAvatarEnabled,g=b.isMentionEnabled,S=b.isCoverImageEnabled,I=t.avatarSize,k=t.displayMentionSlug,M=t.displayActionButton,w=t.displayCoverImage;return t.itemID?n(s,null,n(y,null,n(u,null,n(p,{icon:"edit",title:v("Select another member","buddypress"),onClick:function(){l({itemID:0})}}))),n(m,null,n(a,{title:v("Profile button settings","buddypress"),initialOpen:!0},n(d,{label:v("Display Profile button","buddypress"),checked:!!M,onChange:function(){l({displayActionButton:!M})},help:v(M?"Include a link to the user's profile page under their display name.":"Toggle to display a link to the user's profile page under their display name.","buddypress")})),c&&n(a,{title:v("Avatar settings","buddypress"),initialOpen:!1},n(o,{label:v("Size","buddypress"),value:I,options:C,onChange:function(e){l({avatarSize:e})}})),S&&n(a,{title:v("Cover image settings","buddypress"),initialOpen:!1},n(d,{label:v("Display Cover Image","buddypress"),checked:!!w,onChange:function(){l({displayCoverImage:!w})},help:v(w?"Include the user's cover image over their display name.":"Toggle to display the user's cover image over their display name.","buddypress")})),g&&n(a,{title:v("Mention settings","buddypress"),initialOpen:!1},n(d,{label:v("Display Mention slug","buddypress"),checked:!!k,onChange:function(){l({displayMentionSlug:!k})},help:v(k?"Include the user's mention name under their display name.":"Toggle to display the user's mention name under their display name.","buddypress")}))),n(r,null,n(h,{block:"bp/member",attributes:t}))):n(i,{icon:"admin-users",label:v("BuddyPress Member","buddypress"),instructions:v("Start typing the name of the member you want to feature into this post.","buddypress")},n(f,{component:"members",ariaLabel:v("Member's username","buddypress"),placeholder:v("Enter Member's username here…","buddypress"),onSelectItem:l,useAvatar:c}))},I=g([c(function(e){return{bpSettings:e("core/editor").getEditorSettings().bp.members||{}}})])(S);e("bp/member",{title:v("Member","buddypress"),description:v("BuddyPress Member.","buddypress"),icon:"admin-users",category:"buddypress",attributes:{itemID:{type:"integer",default:0},avatarSize:{type:"string",default:"full"},displayMentionSlug:{type:"boolean",default:!0},displayActionButton:{type:"boolean",default:!0},displayCoverImage:{type:"boolean",default:!0}},edit:I});
3
+ },{}]},{},["TmUL"], null)
{bp-xprofile → bp-members}/screens/change-avatar.php RENAMED
@@ -1,20 +1,18 @@
1
  <?php
2
  /**
3
- * XProfile: User's "Profile > Change Avatar" screen handler
4
  *
5
  * @package BuddyPress
6
- * @subpackage XProfileScreens
7
- * @since 3.0.0
8
  */
9
 
10
  /**
11
- * Handles the uploading and cropping of a user avatar. Displays the change avatar page.
12
- *
13
- * @since 1.0.0
14
  *
 
15
  */
16
- function xprofile_screen_change_avatar() {
17
-
18
  // Bail if not the correct screen.
19
  if ( ! bp_is_my_profile() && ! bp_current_user_can( 'bp_moderate' ) ) {
20
  return false;
@@ -40,7 +38,7 @@ function xprofile_screen_change_avatar() {
40
  check_admin_referer( 'bp_avatar_upload' );
41
 
42
  // Pass the file to the avatar upload handler.
43
- if ( bp_core_avatar_handle_upload( $_FILES, 'xprofile_avatar_upload_dir' ) ) {
44
  $bp->avatar_admin->step = 'crop-image';
45
 
46
  // Make sure we include the jQuery jCrop file for image cropping.
@@ -67,35 +65,43 @@ function xprofile_screen_change_avatar() {
67
  bp_core_add_message( __( 'There was a problem cropping your profile photo.', 'buddypress' ), 'error' );
68
  } else {
69
 
 
 
 
70
  /**
71
  * Fires right before the redirect, after processing a new avatar.
72
  *
73
- * @since 1.1.0
74
- * @since 2.3.4 Add two new parameters to inform about the user id and
75
- * about the way the avatar was set (eg: 'crop' or 'camera').
76
  *
77
  * @param string $item_id Inform about the user id the avatar was set for.
78
  * @param string $value Inform about the way the avatar was set ('crop').
79
  */
80
- do_action( 'xprofile_avatar_uploaded', (int) $args['item_id'], 'crop' );
 
81
  bp_core_add_message( __( 'Your new profile photo was uploaded successfully.', 'buddypress' ) );
82
  bp_core_redirect( bp_displayed_user_domain() );
83
  }
84
  }
85
 
 
 
 
86
  /**
87
- * Fires right before the loading of the XProfile change avatar screen template file.
88
  *
89
- * @since 1.0.0
90
  */
91
- do_action( 'xprofile_screen_change_avatar' );
 
 
 
92
 
93
  /**
94
- * Filters the template to load for the XProfile change avatar screen.
95
  *
96
- * @since 1.0.0
97
  *
98
- * @param string $template Path to the XProfile change avatar template to load.
99
  */
100
- bp_core_load_template( apply_filters( 'xprofile_template_change_avatar', 'members/single/home' ) );
101
- }
1
  <?php
2
  /**
3
+ * Members: Change Avatar screen handler
4
  *
5
  * @package BuddyPress
6
+ * @subpackage MembersScreens
7
+ * @since 6.0.0
8
  */
9
 
10
  /**
11
+ * Handle the display of the profile Change Avatar page by loading the correct template file.
 
 
12
  *
13
+ * @since 6.0.0
14
  */
15
+ function bp_members_screen_change_avatar() {
 
16
  // Bail if not the correct screen.
17
  if ( ! bp_is_my_profile() && ! bp_current_user_can( 'bp_moderate' ) ) {
18
  return false;
38
  check_admin_referer( 'bp_avatar_upload' );
39
 
40
  // Pass the file to the avatar upload handler.
41
+ if ( bp_core_avatar_handle_upload( $_FILES, 'bp_members_avatar_upload_dir' ) ) {
42
  $bp->avatar_admin->step = 'crop-image';
43
 
44
  // Make sure we include the jQuery jCrop file for image cropping.
65
  bp_core_add_message( __( 'There was a problem cropping your profile photo.', 'buddypress' ), 'error' );
66
  } else {
67
 
68
+ /** This action is documented in wp-includes/deprecated.php */
69
+ do_action_deprecated( 'xprofile_avatar_uploaded', array( (int) $args['item_id'], 'crop' ), '6.0.0', 'bp_members_avatar_uploaded' );
70
+
71
  /**
72
  * Fires right before the redirect, after processing a new avatar.
73
  *
74
+ * @since 6.0.0
 
 
75
  *
76
  * @param string $item_id Inform about the user id the avatar was set for.
77
  * @param string $value Inform about the way the avatar was set ('crop').
78
  */
79
+ do_action( 'bp_members_avatar_uploaded', (int) $args['item_id'], 'crop' );
80
+
81
  bp_core_add_message( __( 'Your new profile photo was uploaded successfully.', 'buddypress' ) );
82
  bp_core_redirect( bp_displayed_user_domain() );
83
  }
84
  }
85
 
86
+ /** This action is documented in wp-includes/deprecated.php */
87
+ do_action_deprecated( 'xprofile_screen_change_avatar', array(), '6.0.0', 'bp_members_screen_change_avatar' );
88
+
89
  /**
90
+ * Fires right before the loading of the Member Change Avatar screen template file.
91
  *
92
+ * @since 6.0.0
93
  */
94
+ do_action( 'bp_members_screen_change_avatar' );
95
+
96
+ /** This filter is documented in wp-includes/deprecated.php */
97
+ $template = apply_filters_deprecated( 'xprofile_template_change_avatar', array( 'members/single/home' ), '6.0.0', 'bp_members_template_change_avatar' );
98
 
99
  /**
100
+ * Filters the template to load for the Member Change Avatar page screen.
101
  *
102
+ * @since 6.0.0
103
  *
104
+ * @param string $template Path to the Member template to load.
105
  */
106
+ bp_core_load_template( apply_filters( 'bp_members_template_change_avatar', $template ) );
107
+ }
bp-members/screens/change-cover-image.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Members: Change Cover Image screen handler
4
+ *
5
+ * @package BuddyPress
6
+ * @subpackage MembersScreens
7
+ * @since 6.0.0
8
+ */
9
+
10
+ /**
11
+ * Handle the display of the profile Change Cover Image page by loading the correct template file.
12
+ *
13
+ * @since 6.0.0
14
+ */
15
+ function bp_members_screen_change_cover_image() {
16
+ // Bail if not the correct screen.
17
+ if ( ! bp_is_my_profile() && ! bp_current_user_can( 'bp_moderate' ) ) {
18
+ return false;
19
+ }
20
+
21
+ /** This action is documented in wp-includes/deprecated.php */
22
+ do_action_deprecated( 'xprofile_screen_change_cover_image', array(), '6.0.0', 'bp_members_screen_change_cover_image' );
23
+
24
+ /**
25
+ * Fires right before the loading of the Member Change Cover Image screen template file.
26
+ *
27
+ * @since 6.0.0
28
+ */
29
+ do_action( 'bp_members_screen_change_cover_image' );
30
+
31
+ /** This filter is documented in wp-includes/deprecated.php */
32
+ $template = apply_filters_deprecated( 'xprofile_template_cover_image', array( 'members/single/home' ), '6.0.0', 'bp_members_template_change_cover_image' );
33
+
34
+ /**
35
+ * Filters the template to load for the Member Change Cover Image page screen.
36
+ *
37
+ * @since 6.0.0
38
+ *
39
+ * @param string $template Path to the Member template to load.
40
+ */
41
+ bp_core_load_template( apply_filters( 'bp_members_template_change_cover_image', $template ) );
42
+ }
bp-members/screens/profile.php CHANGED
@@ -29,4 +29,4 @@ function bp_members_screen_display_profile() {
29
  * @param string $template Path to the Member template to load.
30
  */
31
  bp_core_load_template( apply_filters( 'bp_members_screen_display_profile', 'members/single/home' ) );
32
- }
29
  * @param string $template Path to the Member template to load.
30
  */
31
  bp_core_load_template( apply_filters( 'bp_members_screen_display_profile', 'members/single/home' ) );
32
+ }
bp-messages/actions/bulk-manage-star.php CHANGED
@@ -52,6 +52,7 @@ function bp_messages_star_bulk_manage_handler() {
52
  ) );
53
  }
54
 
 
55
  bp_core_add_message( sprintf( _n( '%s message was successfully starred', '%s messages were successfully starred', $count, 'buddypress' ), $count ) );
56
  break;
57
 
@@ -66,6 +67,7 @@ function bp_messages_star_bulk_manage_handler() {
66
  ) );
67
  }
68
 
 
69
  bp_core_add_message( sprintf( _n( '%s message was successfully unstarred', '%s messages were successfully unstarred', $count, 'buddypress' ), $count ) );
70
  break;
71
  }
@@ -74,4 +76,4 @@ function bp_messages_star_bulk_manage_handler() {
74
  bp_core_redirect( bp_displayed_user_domain() . bp_get_messages_slug() . '/' . bp_current_action() . '/' );
75
  die();
76
  }
77
- add_action( 'bp_actions', 'bp_messages_star_bulk_manage_handler', 5 );
52
  ) );
53
  }
54
 
55
+ /* translators: %s: number of starred messages */
56
  bp_core_add_message( sprintf( _n( '%s message was successfully starred', '%s messages were successfully starred', $count, 'buddypress' ), $count ) );
57
  break;
58
 
67
  ) );
68
  }
69
 
70
+ /* translators: %s: number of unstarred messages */
71
  bp_core_add_message( sprintf( _n( '%s message was successfully unstarred', '%s messages were successfully unstarred', $count, 'buddypress' ), $count ) );
72
  break;
73
  }
76
  bp_core_redirect( bp_displayed_user_domain() . bp_get_messages_slug() . '/' . bp_current_action() . '/' );
77
  die();
78
  }
79
+ add_action( 'bp_actions', 'bp_messages_star_bulk_manage_handler', 5 );
bp-messages/bp-messages-functions.php CHANGED
@@ -93,6 +93,7 @@ function messages_new_message( $args = '' ) {
93
 
94
  // Set a default reply subject if none was sent.
95
  if ( empty( $message->subject ) ) {
 
96
  $message->subject = sprintf( __( 'Re: %s', 'buddypress' ), $thread->messages[0]->subject );
97
  }
98
 
93
 
94
  // Set a default reply subject if none was sent.
95
  if ( empty( $message->subject ) ) {
96
+ /* translators: %s: message subject */
97
  $message->subject = sprintf( __( 'Re: %s', 'buddypress' ), $thread->messages[0]->subject );
98
  }
99
 
bp-messages/bp-messages-notifications.php CHANGED
@@ -34,7 +34,9 @@ function messages_format_notifications( $action, $item_id, $secondary_item_id, $
34
  if ( 'new_message' === $action ) {
35
  if ( $total_items > 1 ) {
36
  $amount = 'multiple';
37
- $text = sprintf( __( 'You have %d new messages', 'buddypress' ), $total_items );
 
 
38
 
39
  } else {
40
  // Get message thread ID.
@@ -45,8 +47,10 @@ function messages_format_notifications( $action, $item_id, $secondary_item_id, $
45
  : false;
46
 
47
  if ( ! empty( $secondary_item_id ) ) {
 
48
  $text = sprintf( __( '%s sent you a new private message', 'buddypress' ), bp_core_get_user_displayname( $secondary_item_id ) );
49
  } else {
 
50
  $text = sprintf( _n( 'You have %s new private message', 'You have %s new private messages', $total_items, 'buddypress' ), bp_core_number_format( $total_items ) );
51
  }
52
  }
34
  if ( 'new_message' === $action ) {
35
  if ( $total_items > 1 ) {
36
  $amount = 'multiple';
37
+
38
+ /* translators: %s: number of new messages */
39
+ $text = sprintf( __( 'You have %d new messages', 'buddypress' ), $total_items );
40
 
41
  } else {
42
  // Get message thread ID.
47
  : false;
48
 
49
  if ( ! empty( $secondary_item_id ) ) {
50
+ /* translators: %s: member name */
51
  $text = sprintf( __( '%s sent you a new private message', 'buddypress' ), bp_core_get_user_displayname( $secondary_item_id ) );
52
  } else {
53
+ /* translators: %s: number of private messages */
54
  $text = sprintf( _n( 'You have %s new private message', 'You have %s new private messages', $total_items, 'buddypress' ), bp_core_number_format( $total_items ) );
55
  }
56
  }
bp-messages/bp-messages-template.php CHANGED
@@ -639,6 +639,7 @@ function bp_message_thread_total_and_unread_count( $thread_id = false ) {
639
  /* translators: 1: total number, 2: accessibility text: number of unread messages */
640
  '<span class="thread-count">(%1$s)</span> <span class="bp-screen-reader-text">%2$s</span>',
641
  number_format_i18n( $total ),
 
642
  sprintf( _n( '%d unread', '%d unread', $unread, 'buddypress' ), number_format_i18n( $unread ) )
643
  );
644
  }
@@ -825,6 +826,7 @@ function bp_messages_pagination_count() {
825
  if ( 1 == $messages_template->total_thread_count ) {
826
  $message = __( 'Viewing 1 message', 'buddypress' );
827
  } else {
 
828
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s message', 'Viewing %1$s - %2$s of %3$s messages', $messages_template->total_thread_count, 'buddypress' ), $from_num, $to_num, $total );
829
  }
830
 
@@ -1675,6 +1677,7 @@ function bp_the_thread_subject() {
1675
  */
1676
  function bp_get_the_thread_recipients() {
1677
  if ( 5 <= bp_get_thread_recipients_count() ) {
 
1678
  $recipients = sprintf( __( '%s recipients', 'buddypress' ), number_format_i18n( bp_get_thread_recipients_count() ) );
1679
  } else {
1680
  $recipients = bp_get_thread_recipients_list();
@@ -2066,7 +2069,14 @@ function bp_the_thread_message_time_since() {
2066
  *
2067
  * @param string $value Default text of 'Sent x hours ago'.
2068
  */
2069
- return apply_filters( 'bp_get_the_thread_message_time_since', sprintf( __( 'Sent %s', 'buddypress' ), bp_core_time_since( bp_get_the_thread_message_date_sent() ) ) );
 
 
 
 
 
 
 
2070
  }
2071
 
2072
  /**
639
  /* translators: 1: total number, 2: accessibility text: number of unread messages */
640
  '<span class="thread-count">(%1$s)</span> <span class="bp-screen-reader-text">%2$s</span>',
641
  number_format_i18n( $total ),
642
+ /* translators: %d: number of unread messages */
643
  sprintf( _n( '%d unread', '%d unread', $unread, 'buddypress' ), number_format_i18n( $unread ) )
644
  );
645
  }
826
  if ( 1 == $messages_template->total_thread_count ) {
827
  $message = __( 'Viewing 1 message', 'buddypress' );
828
  } else {
829
+ /* translators: 1: message from number. 2: message to number. 3: total messages. */
830
  $message = sprintf( _n( 'Viewing %1$s - %2$s of %3$s message', 'Viewing %1$s - %2$s of %3$s messages', $messages_template->total_thread_count, 'buddypress' ), $from_num, $to_num, $total );
831
  }
832
 
1677
  */
1678
  function bp_get_the_thread_recipients() {
1679
  if ( 5 <= bp_get_thread_recipients_count() ) {
1680
+ /* translators: %s: number of message recipients */
1681
  $recipients = sprintf( __( '%s recipients', 'buddypress' ), number_format_i18n( bp_get_thread_recipients_count() ) );
1682
  } else {
1683
  $recipients = bp_get_thread_recipients_list();
2069
  *
2070
  * @param string $value Default text of 'Sent x hours ago'.
2071
  */
2072
+ return apply_filters(
2073
+ 'bp_get_the_thread_message_time_since',
2074
+ sprintf(
2075
+ /* translators: %s: last activity timestamp (e.g. "active 1 hour ago") */
2076
+ __( 'Sent %s', 'buddypress' ),
2077
+ bp_core_time_since( bp_get_the_thread_message_date_sent() )
2078
+ )
2079
+ );
2080
  }
2081
 
2082
  /**
bp-messages/classes/class-bp-messages-box-template.php CHANGED
@@ -162,8 +162,8 @@ class BP_Messages_Box_Template {
162
  'meta_query' => $r['meta_query'],
163
  ) );
164
 
165
- $this->threads = $threads['threads'];
166
- $this->total_thread_count = $threads['total'];
167
  }
168
 
169
  if ( !$this->threads ) {
162
  'meta_query' => $r['meta_query'],
163
  ) );
164
 
165
+ $this->threads = isset( $threads['threads'] ) ? $threads['threads'] : array();
166
+ $this->total_thread_count = isset( $threads['total'] ) ? $threads['total'] : 0;
167
  }
168
 
169
  if ( !$this->threads ) {
bp-messages/classes/class-bp-messages-notices-list-table.php CHANGED
@@ -16,7 +16,7 @@ if ( ! class_exists( 'WP_List_Table' ) ) {
16
  }
17
 
18
  class BP_Messages_Notices_List_Table extends WP_List_Table {
19
-
20
  /**
21
  * Constructor
22
  *
@@ -109,7 +109,7 @@ class BP_Messages_Notices_List_Table extends WP_List_Table {
109
  */
110
  public function column_subject( $item ) {
111
  $actions = array(
112
- 'activate_deactivate' => sprintf( '<a href="%s" data-bp-notice-id="%d" data-bp-action="activate">%s</a>',
113
  esc_url( wp_nonce_url( add_query_arg( array(
114
  'page' => 'bp-notices',
115
  'notice_action' => 'activate',
@@ -117,7 +117,7 @@ class BP_Messages_Notices_List_Table extends WP_List_Table {
117
  ), bp_get_admin_url( 'users.php' ) ), 'messages-activate-notice-' . $item->id ) ),
118
  (int) $item->id,
119
  esc_html__( 'Activate Notice', 'buddypress' ) ),
120
- 'delete' => sprintf( '<a href="%s" data-bp-notice-id="%d" data-bp-action="delete">%s</a>',
121
  esc_url( wp_nonce_url( add_query_arg( array(
122
  'page' => 'bp-notices',
123
  'notice_action' => 'delete',
@@ -128,8 +128,9 @@ class BP_Messages_Notices_List_Table extends WP_List_Table {
128
  );
129
 
130
  if ( ! empty( $item->is_active ) ) {
 
131
  $item->subject = sprintf( _x( 'Active: %s', 'Tag prepended to active site-wide notice titles on WP Admin notices list table', 'buddypress' ), $item->subject );
132
- $actions['activate_deactivate'] = sprintf( '<a href="%s" data-bp-notice-id="%d" data-bp-action="deactivate">%s</a>',
133
  esc_url( wp_nonce_url( add_query_arg( array(
134
  'page' => 'bp-notices',
135
  'notice_action' => 'deactivate',
16
  }
17
 
18
  class BP_Messages_Notices_List_Table extends WP_List_Table {
19
+
20
  /**
21
  * Constructor
22
  *
109
  */
110
  public function column_subject( $item ) {
111
  $actions = array(
112
+ 'activate_deactivate' => sprintf( '<a href="%s" data-bp-notice-id="%d" data-bp-action="activate">%s</a>',
113
  esc_url( wp_nonce_url( add_query_arg( array(
114
  'page' => 'bp-notices',
115
  'notice_action' => 'activate',
117
  ), bp_get_admin_url( 'users.php' ) ), 'messages-activate-notice-' . $item->id ) ),
118
  (int) $item->id,
119
  esc_html__( 'Activate Notice', 'buddypress' ) ),
120
+ 'delete' => sprintf( '<a href="%s" data-bp-notice-id="%d" data-bp-action="delete">%s</a>',
121
  esc_url( wp_nonce_url( add_query_arg( array(
122
  'page' => 'bp-notices',
123
  'notice_action' => 'delete',
128
  );
129
 
130
  if ( ! empty( $item->is_active ) ) {
131
+ /* translators: %s: notice subject */
132
  $item->subject = sprintf( _x( 'Active: %s', 'Tag prepended to active site-wide notice titles on WP Admin notices list table', 'buddypress' ), $item->subject );
133
+ $actions['activate_deactivate'] = sprintf( '<a href="%s" data-bp-notice-id="%d" data-bp-action="deactivate">%s</a>',
134
  esc_url( wp_nonce_url( add_query_arg( array(
135
  'page' => 'bp-notices',
136
  'notice_action' => 'deactivate',
bp-messages/classes/class-bp-messages-thread.php CHANGED
@@ -851,6 +851,7 @@ class BP_Messages_Thread {
851
  public static function get_recipient_links( $recipients ) {
852
 
853
  if ( count( $recipients ) >= 5 ) {
 
854
  return sprintf( __( '%s Recipients', 'buddypress' ), number_format_i18n( count( $recipients ) ) );
855
  }
856
 
851
  public static function get_recipient_links( $recipients ) {
852
 
853
  if ( count( $recipients ) >= 5 ) {
854
+ /* translators: %s: number of message recipients */
855
  return sprintf( __( '%s Recipients', 'buddypress' ), number_format_i18n( count( $recipients ) ) );
856
  }
857
 
bp-messages/classes/class-bp-rest-messages-endpoint.php CHANGED
@@ -185,7 +185,7 @@ class BP_REST_Messages_Endpoint extends WP_REST_Controller {
185
  if ( ! is_user_logged_in() ) {
186
  $retval = new WP_Error(
187
  'bp_rest_authorization_required',
188
- __( 'Sorry, you are not allowed to see the messages.', 'buddypress' ),
189
  array(
190
  'status' => rest_authorization_required_code(),
191
  )
@@ -333,55 +333,20 @@ class BP_REST_Messages_Endpoint extends WP_REST_Controller {
333
  // Setting context.
334
  $request->set_param( 'context', 'edit' );
335
 
336
- // Prepare the message or the reply arguments.
337
- $args = array(
338
- 'sender_id' => $request['sender_id'],
339
- 'thread_id' => 0,
340
- 'subject' => $request['subject'],
341
- 'content' => $request['message'],
342
- 'recipients' => $request['recipients'],
343
- );
344
-
345
- $error = new WP_Error(
346
- 'bp_rest_messages_create_failed',
347
- __( 'There was an error trying to create the message.', 'buddypress' ),
348
- array(
349
- 'status' => 500,
350
- )
351
- );
352
-
353
- // Replying to an existing Thread ?
354
- if ( $request['id'] ) {
355
- // Try to get the thread.
356
- $thread = $this->get_thread_object( $request['id'] );
357
-
358
- // Validate the Thread exists.
359
- if ( ! $thread->thread_id ) {
360
- return $error;
361
- }
362
-
363
- $args['thread_id'] = (int) $thread->thread_id;
364
- $args['recipients'] = wp_parse_id_list( wp_list_pluck( $thread->recipients, 'user_id' ) );
365
- }
366
 
367
- if ( ! $args['recipients'] ) {
 
368
  return new WP_Error(
369
- 'bp_rest_messages_missing_recipients',
370
- __( 'Please provide some recipients for your message or reply.', 'buddypress' ),
371
  array(
372
- 'status' => 400,
373
  )
374
  );
375
  }
376
 
377
- // Create the message or the reply.
378
- $thread_id = messages_new_message( $args );
379
-
380
- // Validate it created a Thread or was added to it.
381
- if ( ! $thread_id ) {
382
- return $error;
383
- }
384
-
385
  // Make sure to get the newest message to update REST Additional fields.
386
  $thread = $this->get_thread_object( $thread_id );
387
  $last_message = wp_list_filter( $thread->messages, array( 'id' => $thread->last_message_id ) );
@@ -634,7 +599,7 @@ class BP_REST_Messages_Endpoint extends WP_REST_Controller {
634
  *
635
  * @since 5.0.0
636
  *
637
- * @param WP_REST_Request $request Full details about the request.
638
  * @return bool|WP_Error
639
  */
640
  public function update_starred_permissions_check( $request ) {
@@ -690,7 +655,7 @@ class BP_REST_Messages_Endpoint extends WP_REST_Controller {
690
  if ( ! in_array( $user_id, $recipient_ids, true ) || ! messages_delete_thread( $thread->thread_id, $user_id ) ) {
691
  return new WP_Error(
692
  'bp_rest_messages_delete_thread_failed',
693
- __( 'There was an error trying to delete a thread.', 'buddypress' ),
694
  array(
695
  'status' => 500,
696
  )
@@ -742,6 +707,62 @@ class BP_REST_Messages_Endpoint extends WP_REST_Controller {
742
  return apply_filters( 'bp_rest_messages_delete_item_permissions_check', $retval, $request );
743
  }
744
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
745
  /**
746
  * Prepares message data for the REST response.
747
  *
@@ -843,49 +864,6 @@ class BP_REST_Messages_Endpoint extends WP_REST_Controller {
843
  return apply_filters( 'bp_rest_messages_prepare_recipient_value', $data, $recipient, $request );
844
  }
845
 
846
- /**
847
- * Prepare links for the request.
848
- *
849
- * @since 5.0.0
850
- *
851
- * @param BP_Messages_Thread $thread Thread object.
852
- * @return array Links for the given thread.
853
- */
854
- protected function prepare_links( $thread ) {
855
- $base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );
856
-
857
- // Entity meta.
858
- $links = array(
859
- 'self' => array(
860
- 'href' => rest_url( $base . $thread->thread_id ),
861
- ),
862
- 'collection' => array(
863
- 'href' => rest_url( $base ),
864
- ),
865
- );
866
-
867
- // Add star links for each message of the thread.
868
- if ( bp_is_active( 'messages', 'star' ) ) {
869
- $starred_base = $base . bp_get_messages_starred_slug() . '/';
870
-
871
- foreach ( $thread->messages as $message ) {
872
- $links[ $message->id ] = array(
873
- 'href' => rest_url( $starred_base . $message->id ),
874
- );
875
- }
876
- }
877
-
878
- /**
879
- * Filter links prepared for the REST response.
880
- *
881
- * @since 5.0.0
882
- *
883
- * @param array $links The prepared links of the REST response.
884
- * @param BP_Messages_Thread $thread Thread object.
885
- */
886
- return apply_filters( 'bp_rest_messages_prepare_links', $links, $thread );
887
- }
888
-
889
  /**
890
  * Prepares thread data for return as an object.
891
  *
@@ -956,6 +934,49 @@ class BP_REST_Messages_Endpoint extends WP_REST_Controller {
956
  return apply_filters( 'bp_rest_messages_prepare_value', $response, $request, $thread );
957
  }
958
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
959
  /**
960
  * Get thread object.
961
  *
@@ -1020,6 +1041,7 @@ class BP_REST_Messages_Endpoint extends WP_REST_Controller {
1020
  $args['message']['description'] = __( 'Content of the Message to add to the Thread.', 'buddypress' );
1021
 
1022
  // Edit recipients properties.
 
1023
  $args['recipients']['items'] = array( 'type' => 'integer' );
1024
  $args['recipients']['sanitize_callback'] = 'wp_parse_id_list';
1025
  $args['recipients']['validate_callback'] = 'rest_validate_request_arg';
185
  if ( ! is_user_logged_in() ) {
186
  $retval = new WP_Error(
187
  'bp_rest_authorization_required',
188
+ __( 'Sorry, you are not allowed to perform this action.', 'buddypress' ),
189
  array(
190
  'status' => rest_authorization_required_code(),
191
  )
333
  // Setting context.
334
  $request->set_param( 'context', 'edit' );
335
 
336
+ // Create the message or the reply.
337
+ $thread_id = messages_new_message( $this->prepare_item_for_database( $request ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
+ // Validate it created a Thread or was added to it.
340
+ if ( false === $thread_id ) {
341
  return new WP_Error(
342
+ 'bp_rest_messages_create_failed',
343
+ __( 'There was an error trying to create the message.', 'buddypress' ),
344
  array(
345
+ 'status' => 500,
346
  )
347
  );
348
  }
349
 
 
 
 
 
 
 
 
 
350
  // Make sure to get the newest message to update REST Additional fields.
351
  $thread = $this->get_thread_object( $thread_id );
352
  $last_message = wp_list_filter( $thread->messages, array( 'id' => $thread->last_message_id ) );
599
  *
600
  * @since 5.0.0
601
  *
602
+ * @param WP_REST_Request $request Full details about the request.
603
  * @return bool|WP_Error
604
  */
605
  public function update_starred_permissions_check( $request ) {
655
  if ( ! in_array( $user_id, $recipient_ids, true ) || ! messages_delete_thread( $thread->thread_id, $user_id ) ) {
656
  return new WP_Error(
657
  'bp_rest_messages_delete_thread_failed',
658
+ __( 'There was an error trying to delete the thread.', 'buddypress' ),
659
  array(
660
  'status' => 500,
661
  )
707
  return apply_filters( 'bp_rest_messages_delete_item_permissions_check', $retval, $request );
708
  }
709
 
710
+ /**
711
+ * Prepare a message for create.
712
+ *
713
+ * @since 6.0.0
714
+ *
715
+ * @param WP_REST_Request $request The request sent to the API.
716
+ * @return stdClass
717
+ */
718
+ protected function prepare_item_for_database( $request ) {
719
+ $prepared_thread = new stdClass();
720
+ $schema = $this->get_item_schema();
721
+ $thread = $this->get_thread_object( $request['id'] );
722
+
723
+ if ( ! empty( $schema['properties']['id'] ) && ! empty( $request['id'] ) ) {
724
+ $prepared_thread->thread_id = $request['id'];
725
+ } elseif ( ! empty( $thread->thread_id ) ) {
726
+ $prepared_thread->thread_id = $thread->thread_id;
727
+ }
728
+
729
+ if ( ! empty( $schema['properties']['sender_id'] ) && ! empty( $request['sender_id'] ) ) {
730
+ $prepared_thread->sender_id = $thread->sender_id;
731
+ } elseif ( ! empty( $thread->sender_id ) ) {
732
+ $prepared_thread->sender_id = $thread->sender_id;
733
+ } else {
734
+ $prepared_thread->sender_id = bp_loggedin_user_id();
735
+ }
736
+
737
+ if ( ! empty( $schema['properties']['message'] ) && ! empty( $request['message'] ) ) {
738
+ $prepared_thread->content = $request['message'];
739
+ } elseif ( ! empty( $thread->message ) ) {
740
+ $prepared_thread->message = $thread->message;
741
+ }
742
+
743
+ if ( ! empty( $schema['properties']['subject'] ) && ! empty( $request['subject'] ) ) {
744
+ $prepared_thread->subject = $request['subject'];
745
+ } elseif ( ! empty( $thread->subject ) ) {
746
+ $prepared_thread->subject = $thread->subject;
747
+ }
748
+
749
+ if ( ! empty( $schema['properties']['recipients'] ) && ! empty( $request['recipients'] ) ) {
750
+ $prepared_thread->recipients = $request['recipients'];
751
+ } elseif ( ! empty( $thread->recipients ) ) {
752
+ $prepared_thread->recipients = wp_parse_id_list( wp_list_pluck( $thread->recipients, 'user_id' ) );
753
+ }
754
+
755
+ /**
756
+ * Filters a message before it is inserted via the REST API.
757
+ *
758
+ * @since 6.0.0
759
+ *
760
+ * @param stdClass $prepared_thread An object prepared for inserting into the database.
761
+ * @param WP_REST_Request $request Request object.
762
+ */
763
+ return apply_filters( 'bp_rest_message_pre_insert_value', $prepared_thread, $request );
764
+ }
765
+
766
  /**
767
  * Prepares message data for the REST response.
768
  *
864
  return apply_filters( 'bp_rest_messages_prepare_recipient_value', $data, $recipient, $request );
865
  }
866
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
867
  /**
868
  * Prepares thread data for return as an object.
869
  *
934
  return apply_filters( 'bp_rest_messages_prepare_value', $response, $request, $thread );
935
  }
936
 
937
+ /**
938
+ * Prepare links for the request.
939
+ *
940
+ * @since 5.0.0
941
+ *
942
+ * @param BP_Messages_Thread $thread Thread object.
943
+ * @return array Links for the given thread.
944
+ */
945
+ protected function prepare_links( $thread ) {
946
+ $base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );
947
+
948
+ // Entity meta.
949
+ $links = array(
950
+ 'self' => array(
951
+ 'href' => rest_url( $base . $thread->thread_id ),
952
+ ),
953
+ 'collection' => array(
954
+ 'href' => rest_url( $base ),
955
+ ),
956
+ );
957
+
958
+ // Add star links for each message of the thread.
959
+ if ( bp_is_active( 'messages', 'star' ) ) {
960
+ $starred_base = $base . bp_get_messages_starred_slug() . '/';
961
+
962
+ foreach ( $thread->messages as $message ) {
963
+ $links[ $message->id ] = array(
964
+ 'href' => rest_url( $starred_base . $message->id ),
965
+ );
966
+ }
967
+ }
968
+
969
+ /**
970
+ * Filter links prepared for the REST response.
971
+ *
972
+ * @since 5.0.0
973
+ *
974
+ * @param array $links The prepared links of the REST response.
975
+ * @param BP_Messages_Thread $thread Thread object.
976
+ */
977
+ return apply_filters( 'bp_rest_messages_prepare_links', $links, $thread );
978
+ }
979
+
980
  /**
981
  * Get thread object.
982
  *
1041
  $args['message']['description'] = __( 'Content of the Message to add to the Thread.', 'buddypress' );
1042
 
1043
  // Edit recipients properties.
1044
+ $args['recipients']['required'] = true;
1045
  $args['recipients']['items'] = array( 'type' => 'integer' );
1046
  $args['recipients']['sanitize_callback'] = 'wp_parse_id_list';
1047
  $args['recipients']['validate_callback'] = 'rest_validate_request_arg';
bp-messages/screens/view.php CHANGED
@@ -51,7 +51,9 @@ function messages_screen_conversation() {
51
  // Decrease the unread count in the nav before it's rendered.
52
  $count = bp_get_total_unread_messages_count();
53
  $class = ( 0 === $count ) ? 'no-count' : 'count';
54
- $nav_name = sprintf( __( 'Messages <span class="%s">%s</span>', 'buddypress' ), esc_attr( $class ), bp_core_number_format( $count ) );
 
 
55
 
56
  // Edit the Navigation name.
57
  $bp->members->nav->edit_nav( array(
@@ -74,4 +76,4 @@ function messages_screen_conversation() {
74
  */
75
  bp_core_load_template( apply_filters( 'messages_template_view_message', 'members/single/home' ) );
76
  }
77
- add_action( 'bp_screens', 'messages_screen_conversation' );
51
  // Decrease the unread count in the nav before it's rendered.
52
  $count = bp_get_total_unread_messages_count();
53
  $class = ( 0 === $count ) ? 'no-count' : 'count';
54
+
55
+ /* translators: 1: class name. 2: number of messages */
56
+ $nav_name = sprintf( __( 'Messages <span class="%1$s">%2$s</span>', 'buddypress' ), esc_attr( $class ), bp_core_number_format( $count ) );
57
 
58
  // Edit the Navigation name.
59
  $bp->members->nav->edit_nav( array(
76
  */
77
  bp_core_load_template( apply_filters( 'messages_template_view_message', 'members/single/home' ) );
78
  }
79
+ add_action( 'bp_screens', 'messages_screen_conversation' );
bp-notifications/bp-notifications-adminbar.php CHANGED
@@ -33,7 +33,7 @@ function bp_notifications_toolbar_menu() {
33
  $menu_link = trailingslashit( bp_loggedin_user_domain() . bp_get_notifications_slug() );
34
 
35
  // Add the top-level Notifications button.
36
- $wp_admin_bar->add_menu( array(
37
  'parent' => 'top-secondary',
38
  'id' => 'bp-notifications',
39
  'title' => $menu_title,
@@ -42,7 +42,7 @@ function bp_notifications_toolbar_menu() {
42
 
43
  if ( ! empty( $notifications ) ) {
44
  foreach ( (array) $notifications as $notification ) {
45
- $wp_admin_bar->add_menu( array(
46
  'parent' => 'bp-notifications',
47
  'id' => 'notification-' . $notification->id,
48
  'title' => $notification->content,
@@ -50,7 +50,7 @@ function bp_notifications_toolbar_menu() {
50
  ) );
51
  }
52
  } else {
53
- $wp_admin_bar->add_menu( array(
54
  'parent' => 'bp-notifications',
55
  'id' => 'no-notifications',
56
  'title' => __( 'No new notifications', 'buddypress' ),
33
  $menu_link = trailingslashit( bp_loggedin_user_domain() . bp_get_notifications_slug() );
34
 
35
  // Add the top-level Notifications button.
36
+ $wp_admin_bar->add_node( array(
37
  'parent' => 'top-secondary',
38
  'id' => 'bp-notifications',
39
  'title' => $menu_title,
42
 
43
  if ( ! empty( $notifications ) ) {
44
  foreach ( (array) $notifications as $notification ) {
45
+ $wp_admin_bar->add_node( array(
46
  'parent' => 'bp-notifications',
47
  'id' => 'notification-' . $notification->id,
48
  'title' => $notification->content,
50
  ) );
51
  }
52
  } else {
53
+ $wp_admin_bar->add_node( array(
54
  'parent' => 'bp-notifications',
55
  'id' => 'no-notifications',
56
  'title' => __( 'No new notifications', 'buddypress' ),
bp-notifications/bp-notifications-cache.php CHANGED
@@ -93,7 +93,7 @@ add_action( 'bp_notification_before_delete', 'bp_notifications_clear_all_for_use
93
  */
94
  function bp_notifications_clear_all_for_user_cache_before_update( $update_args, $where_args ) {
95
 
96
- // User ID is passed in where arugments.
97
  if ( ! empty( $where_args['user_id'] ) ) {
98
  bp_notifications_clear_all_for_user_cache( $where_args['user_id'] );
99
 
93
  */
94
  function bp_notifications_clear_all_for_user_cache_before_update( $update_args, $where_args ) {
95
 
96
+ // User ID is passed in where arguments.
97
  if ( ! empty( $where_args['user_id'] ) ) {
98
  bp_notifications_clear_all_for_user_cache( $where_args['user_id'] );
99
 
bp-notifications/bp-notifications-functions.php CHANGED
@@ -233,8 +233,8 @@ function bp_notifications_get_notifications_for_user( $user_id, $format = 'strin
233
  $notification_object->content = $content;
234
  $notification_object->href = bp_loggedin_user_domain();
235
  } else {
236
- $notification_object->content = $content['text'];
237
- $notification_object->href = $content['link'];
238
  }
239
 
240
  $renderable[] = $notification_object;
@@ -445,7 +445,23 @@ function bp_notifications_delete_notifications_on_user_delete( $user_id ) {
445
  ) );
446
  }
447
  add_action( 'wpmu_delete_user', 'bp_notifications_delete_notifications_on_user_delete' );
448
- add_action( 'delete_user', 'bp_notifications_delete_notifications_on_user_delete' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
 
450
  /** Mark **********************************************************************/
451
 
233
  $notification_object->content = $content;
234
  $notification_object->href = bp_loggedin_user_domain();
235
  } else {
236
+ $notification_object->content = isset( $content['text'] ) ? $content['text'] : '';
237
+ $notification_object->href = isset( $content['link'] ) ? $content['link'] : '';
238
  }
239
 
240
  $renderable[] = $notification_object;
445
  ) );
446
  }
447
  add_action( 'wpmu_delete_user', 'bp_notifications_delete_notifications_on_user_delete' );
448
+
449
+ /**
450
+ * Deletes user notifications data on the 'delete_user' hook.
451
+ *
452
+ * @since 6.0.0
453
+ *
454
+ * @param int $user_id The ID of the deleted user.
455
+ */
456
+ function bp_notifications_delete_notifications_on_delete_user( $user_id ) {
457
+ if ( ! bp_remove_user_data_on_delete_user_hook( 'notifications', $user_id ) ) {
458
+ return;
459
+ }
460
+
461
+ bp_notifications_delete_notifications_on_user_delete( $user_id );
462
+ }
463
+
464
+ add_action( 'delete_user', 'bp_notifications_delete_notifications_on_delete_user' );
465
 
466
  /** Mark **********************************************************************/
467
 
bp-notifications/bp-notifications-template.php CHANGED
@@ -936,6 +936,7 @@ function bp_notifications_pagination_count() {
936
  if ( 1 == $query_loop->total_notification_count ) {
937
  $pag = __( 'Viewing 1 notification', 'buddypress' );
938
  } else {
 
939
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s notification', 'Viewing %1$s - %2$s of %3$s notifications', $query_loop->total_notification_count, 'buddypress' ), $from_num, $to_num, $total );
940
  }
941
 
936
  if ( 1 == $query_loop->total_notification_count ) {
937
  $pag = __( 'Viewing 1 notification', 'buddypress' );
938
  } else {
939
+ /* translators: 1: notification from number. 2: notification to number. 3: total notifications. */
940
  $pag = sprintf( _n( 'Viewing %1$s - %2$s of %3$s notification', 'Viewing %1$s - %2$s of %3$s notifications', $query_loop->total_notification_count, 'buddypress' ), $from_num, $to_num, $total );
941
  }
942
 
bp-settings/actions/delete-account.php CHANGED
@@ -48,10 +48,17 @@ function bp_settings_action_delete_account() {
48
  if ( bp_core_delete_account( bp_displayed_user_id() ) ) {
49
 
50
  // Add feedback after deleting a user.
51
- bp_core_add_message( sprintf( __( '%s was successfully deleted.', 'buddypress' ), $username ), 'success' );
 
 
 
 
 
 
 
52
 
53
  // Redirect to the root domain.
54
  bp_core_redirect( bp_get_root_domain() );
55
  }
56
  }
57
- add_action( 'bp_actions', 'bp_settings_action_delete_account' );
48
  if ( bp_core_delete_account( bp_displayed_user_id() ) ) {
49
 
50
  // Add feedback after deleting a user.
51
+ bp_core_add_message(
52
+ sprintf(
53
+ /* translators: %s: user username */
54
+ __( '%s was successfully deleted.', 'buddypress' ),
55
+ $username
56
+ ),
57
+ 'success'
58
+ );
59
 
60
  // Redirect to the root domain.
61
  bp_core_redirect( bp_get_root_domain() );
62
  }
63
  }
64
+ add_action( 'bp_actions', 'bp_settings_action_delete_account' );
bp-settings/actions/general.php CHANGED
@@ -110,7 +110,7 @@ function bp_settings_action_general() {
110
  'verify.url' => esc_url( $verify_link ),
111
  ),
112
  );
113
- bp_send_email( 'settings-verify-email-change', bp_displayed_user_id(), $args );
114
 
115
  // We mark that the change has taken place so as to ensure a
116
  // success message, even though verification is still required.
110
  'verify.url' => esc_url( $verify_link ),
111
  ),
112
  );
113
+ bp_send_email( 'settings-verify-email-change', $user_email, $args );
114
 
115
  // We mark that the change has taken place so as to ensure a
116
  // success message, even though verification is still required.
bp-settings/bp-settings-template.php CHANGED
@@ -85,16 +85,24 @@ function bp_settings_pending_email_notice() {
85
  ?>
86
 
87
  <div id="message" class="bp-template-notice error">
88
- <p><?php printf(
89
- __( 'There is a pending change of your email address to %s.', 'buddypress' ),
90
- '<code>' . esc_html( $pending_email['newemail'] ) . '</code>'
91
- ); ?>
92
- <br />
93
- <?php printf(
94
- __( 'Check your email (%1$s) for the verification link, or <a href="%2$s">cancel the pending change</a>.', 'buddypress' ),
95
- '<code>' . esc_html( bp_get_displayed_user_email() ) . '</code>',
96
- esc_url( wp_nonce_url( bp_displayed_user_domain() . bp_get_settings_slug() . '/?dismiss_email_change=1', 'bp_dismiss_email_change' ) )
97
- ); ?></p>
 
 
 
 
 
 
 
 
98
  </div>
99
 
100
  <?php
85
  ?>
86
 
87
  <div id="message" class="bp-template-notice error">
88
+ <p>
89
+ <?php
90
+ printf(
91
+ /* translators: %s: new email address */
92
+ __( 'There is a pending change of your email address to %s.', 'buddypress' ),
93
+ '<code>' . esc_html( $pending_email['newemail'] ) . '</code>'
94
+ );
95
+ ?>
96
+ <br />
97
+ <?php
98
+ printf(
99
+ /* translators: 1: email address. 2: cancel email change url. */
100
+ __( 'Check your email (%1$s) for the verification link, or <a href="%2$s">cancel the pending change</a>.', 'buddypress' ),
101
+ '<code>' . esc_html( $pending_email['newemail'] ) . '</code>',
102
+ esc_url( wp_nonce_url( bp_displayed_user_domain() . bp_get_settings_slug() . '/?dismiss_email_change=1', 'bp_dismiss_email_change' ) )
103
+ );
104
+ ?>
105
+ </p>
106
  </div>
107
 
108
  <?php
bp-templates/bp-legacy/buddypress-functions.php CHANGED
@@ -310,6 +310,8 @@ class BP_Legacy extends BP_Theme_Compat {
310
  'remove_fav' => __( 'Remove Favorite', 'buddypress' ),
311
  'show_all' => __( 'Show all', 'buddypress' ),
312
  'show_all_comments' => __( 'Show all comments for this thread', 'buddypress' ),
 
 
313
  'show_x_comments' => __( 'Show all comments (%d)', 'buddypress' ),
314
  'unsaved_changes' => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
315
  'view' => __( 'View', 'buddypress' ),
@@ -1392,6 +1394,7 @@ function bp_legacy_theme_ajax_invite_user() {
1392
  </div>';
1393
 
1394
  if ( 'is_pending' == $user_status ) {
 
1395
  echo '<p class="description">' . sprintf( __( '%s has previously requested to join this group. Sending an invitation will automatically add the member to the group.', 'buddypress' ), $user->user_link ) . '</p>';
1396
  }
1397
 
310
  'remove_fav' => __( 'Remove Favorite', 'buddypress' ),
311
  'show_all' => __( 'Show all', 'buddypress' ),
312
  'show_all_comments' => __( 'Show all comments for this thread', 'buddypress' ),
313
+
314
+ /* translators: %s: number of activity comments */
315
  'show_x_comments' => __( 'Show all comments (%d)', 'buddypress' ),
316
  'unsaved_changes' => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
317
  'view' => __( 'View', 'buddypress' ),
1394
  </div>';
1395
 
1396
  if ( 'is_pending' == $user_status ) {
1397
+ /* translators: %s: user link */
1398
  echo '<p class="description">' . sprintf( __( '%s has previously requested to join this group. Sending an invitation will automatically add the member to the group.', 'buddypress' ), $user->user_link ) . '</p>';
1399
  }
1400
 
bp-templates/bp-legacy/buddypress/activity/comment.php CHANGED
@@ -50,7 +50,7 @@ do_action( 'bp_before_activity_comment' ); ?>
50
  <?php
51
 
52
  /**
53
- * Fires after the defualt comment action options display.
54
  *
55
  * @since 1.6.0
56
  */
50
  <?php
51
 
52
  /**
53
+ * Fires after the default comment action options display.
54
  *
55
  * @since 1.6.0
56
  */
bp-templates/bp-legacy/buddypress/activity/entry.php CHANGED
@@ -65,7 +65,12 @@ do_action( 'bp_before_activity_entry' ); ?>
65
 
66
  <?php if ( bp_activity_can_comment() ) : ?>
67
 
68
- <a href="<?php bp_activity_comment_link(); ?>" class="button acomment-reply bp-primary-action" id="acomment-comment-<?php bp_activity_id(); ?>"><?php printf( __( 'Comment %s', 'buddypress' ), '<span>' . bp_activity_get_comment_count() . '</span>' ); ?></a>
 
 
 
 
 
69
 
70
  <?php endif; ?>
71
 
65
 
66
  <?php if ( bp_activity_can_comment() ) : ?>
67
 
68
+ <a href="<?php bp_activity_comment_link(); ?>" class="button acomment-reply bp-primary-action" id="acomment-comment-<?php bp_activity_id(); ?>">
69
+ <?php
70
+ /* translators: %s: number of activity comments */
71
+ printf( __( 'Comment %s', 'buddypress' ), '<span>' . bp_activity_get_comment_count() . '</span>' );
72
+ ?>
73
+ </a>
74
 
75
  <?php endif; ?>
76
 
bp-templates/bp-legacy/buddypress/activity/index.php CHANGED
@@ -56,7 +56,14 @@ do_action( 'bp_before_directory_activity' ); ?>
56
  */
57
  do_action( 'bp_before_activity_type_tab_all' ); ?>
58
 
59
- <li class="selected" id="activity-all"><a href="<?php bp_activity_directory_permalink(); ?>"><?php printf( __( 'All Members %s', 'buddypress' ), '<span>' . bp_get_total_member_count() . '</span>' ); ?></a></li>
 
 
 
 
 
 
 
60
 
61
  <?php if ( is_user_logged_in() ) : ?>
62
 
@@ -73,7 +80,14 @@ do_action( 'bp_before_directory_activity' ); ?>
73
 
74
  <?php if ( bp_get_total_friend_count( bp_loggedin_user_id() ) ) : ?>
75
 
76
- <li id="activity-friends"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() . '/'; ?>"><?php printf( __( 'My Friends %s', 'buddypress' ), '<span>' . bp_get_total_friend_count( bp_loggedin_user_id() ) . '</span>' ); ?></a></li>
 
 
 
 
 
 
 
77
 
78
  <?php endif; ?>
79
 
@@ -97,7 +111,7 @@ do_action( 'bp_before_directory_activity' ); ?>
97
  '<li id="activity-groups"><a href="%1$s">%2$s</a></li>',
98
  esc_url( bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() . '/' ),
99
  sprintf(
100
- /* translators: %s: total joined groups count for the current user */
101
  __( 'My Groups %s', 'buddypress' ),
102
  '<span>' . bp_get_total_group_count_for_user( bp_loggedin_user_id() ) . '</span>'
103
  )
@@ -119,7 +133,14 @@ do_action( 'bp_before_directory_activity' ); ?>
119
 
120
  <?php if ( bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ) : ?>
121
 
122
- <li id="activity-favorites"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/'; ?>"><?php printf( __( 'My Favorites %s', 'buddypress' ), '<span>' . bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) . '</span>' ); ?></a></li>
 
 
 
 
 
 
 
123
 
124
  <?php endif; ?>
125
 
@@ -134,7 +155,22 @@ do_action( 'bp_before_directory_activity' ); ?>
134
  */
135
  do_action( 'bp_before_activity_type_tab_mentions' ); ?>
136
 
137
- <li id="activity-mentions"><a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/'; ?>"><?php _e( 'Mentions', 'buddypress' ); ?><?php if ( bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ) : ?> <strong><span><?php printf( _nx( '%s new', '%s new', bp_get_total_mention_count_for_user( bp_loggedin_user_id() ), 'Number of new activity mentions', 'buddypress' ), bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ); ?></span></strong><?php endif; ?></a></li>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
  <?php endif; ?>
140
 
56
  */
57
  do_action( 'bp_before_activity_type_tab_all' ); ?>
58
 
59
+ <li class="selected" id="activity-all">
60
+ <a href="<?php bp_activity_directory_permalink(); ?>">
61
+ <?php
62
+ /* translators: %s: number of members */
63
+ printf( __( 'All Members %s', 'buddypress' ), '<span>' . bp_get_total_member_count() . '</span>' );
64
+ ?>
65
+ </a>
66
+ </li>
67
 
68
  <?php if ( is_user_logged_in() ) : ?>
69
 
80
 
81
  <?php if ( bp_get_total_friend_count( bp_loggedin_user_id() ) ) : ?>
82
 
83
+ <li id="activity-friends">
84
+ <a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_friends_slug() . '/'; ?>">
85
+ <?php
86
+ /* translators: %s: number of friends */
87
+ printf( __( 'My Friends %s', 'buddypress' ), '<span>' . bp_get_total_friend_count( bp_loggedin_user_id() ) . '</span>' );
88
+ ?>
89
+ </a>
90
+ </li>
91
 
92
  <?php endif; ?>
93
 
111
  '<li id="activity-groups"><a href="%1$s">%2$s</a></li>',
112
  esc_url( bp_loggedin_user_domain() . bp_get_activity_slug() . '/' . bp_get_groups_slug() . '/' ),
113
  sprintf(
114
+ /* translators: %s: current user groups count */
115
  __( 'My Groups %s', 'buddypress' ),
116
  '<span>' . bp_get_total_group_count_for_user( bp_loggedin_user_id() ) . '</span>'
117
  )
133
 
134
  <?php if ( bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) ) : ?>
135
 
136
+ <li id="activity-favorites">
137
+ <a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/favorites/'; ?>">
138
+ <?php
139
+ /* translators: %s: number of favorites */
140
+ printf( __( 'My Favorites %s', 'buddypress' ), '<span>' . bp_get_total_favorite_count_for_user( bp_loggedin_user_id() ) . '</span>' );
141
+ ?>
142
+ </a>
143
+ </li>
144
 
145
  <?php endif; ?>
146
 
155
  */
156
  do_action( 'bp_before_activity_type_tab_mentions' ); ?>
157
 
158
+ <li id="activity-mentions">
159
+ <a href="<?php echo bp_loggedin_user_domain() . bp_get_activity_slug() . '/mentions/'; ?>">
160
+ <?php _e( 'Mentions', 'buddypress' ); ?>
161
+ <?php if ( bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) ) : ?>
162
+ &nbsp;
163
+ <strong>
164
+ <span>
165
+ <?php
166
+ /* translators: %s: new mentions count */
167
+ printf( _nx( '%s new', '%s new', bp_get_total_mention_count_for_user( bp_loggedin_user_id() ), 'Number of new activity mentions', 'buddypress' ), bp_get_total_mention_count_for_user( bp_loggedin_user_id() ) );
168
+ ?>
169
+ </span>
170
+ </strong>
171
+ <?php endif; ?>
172
+ </a>
173
+ </li>
174
 
175
  <?php endif; ?>
176
 
bp-templates/bp-legacy/buddypress/activity/post-form.php CHANGED
@@ -26,11 +26,17 @@
26
  </a>
27
  </div>
28
 
29
- <p class="activity-greeting"><?php if ( bp_is_group() )
30
- printf( __( "What's new in %s, %s?", 'buddypress' ), bp_get_group_name(), bp_get_user_firstname( bp_get_loggedin_user_fullname() ) );
31
- else
32
- printf( __( "What's new, %s?", 'buddypress' ), bp_get_user_firstname( bp_get_loggedin_user_fullname() ) );
33
- ?></p>
 
 
 
 
 
 
34
 
35
  <div id="whats-new-content">
36
  <div id="whats-new-textarea">
26
  </a>
27
  </div>
28
 
29
+ <p class="activity-greeting">
30
+ <?php
31
+ if ( bp_is_group() ) {
32
+ /* translators: 1: group name. 2: member name. */
33
+ printf( __( 'What\'s new in %1$s, %2$s?', 'buddypress' ), bp_get_group_name(), bp_get_user_firstname( bp_get_loggedin_user_fullname() ) );
34
+ } else {
35
+ /* translators: %s: member name */
36
+ printf( __( "What's new, %s?", 'buddypress' ), bp_get_user_firstname( bp_get_loggedin_user_fullname() ) );
37
+ }
38
+ ?>
39
+ </p>
40
 
41
  <div id="whats-new-content">
42
  <div id="whats-new-textarea">
bp-templates/bp-legacy/buddypress/assets/emails/single-bp-email.php CHANGED
@@ -60,7 +60,7 @@ $settings = bp_email_get_appearance_settings();
60
  /* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
61
  html,
62
  body {
63
- Margin: 0 !important;
64
  padding: 0 !important;
65
  height: 100% !important;
66
  width: 100% !important;
@@ -89,7 +89,7 @@ $settings = bp_email_get_appearance_settings();
89
  border-spacing: 0 !important;
90
  border-collapse: collapse !important;
91
  table-layout: fixed !important;
92
- Margin: 0 auto !important;
93
  }
94
  table table table {
95
  table-layout: auto;
@@ -205,7 +205,7 @@ $settings = bp_email_get_appearance_settings();
205
  <br>
206
  <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="<?php echo esc_attr( $settings['direction'] ); ?>" width="100%" style="max-width: 600px; border-radius: 5px;" bgcolor="<?php echo esc_attr( $settings['footer_bg'] ); ?>" class="footer_bg">
207
  <tr>
208
- <td style="padding: 20px; width: 100%; font-size: <?php echo esc_attr( $settings['footer_text_size'] . 'px' ); ?>; font-family: sans-serif; mso-height-rule: exactly; line-height: <?php echo esc_attr( floor( $settings['footer_text_size'] * 1.618 ) . 'px' ) ?>; text-align: <?php echo esc_attr( $settings['direction'] ); ?>; color: <?php echo esc_attr( $settings['footer_text_color'] ); ?>;" class="footer_text_color footer_text_size">
209
  <?php
210
  /**
211
  * Fires before the display of the email template footer.
60
  /* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
61
  html,
62
  body {
63
+ margin: 0 !important;
64
  padding: 0 !important;
65
  height: 100% !important;
66
  width: 100% !important;
89
  border-spacing: 0 !important;
90
  border-collapse: collapse !important;
91
  table-layout: fixed !important;
92
+ margin: 0 auto !important;
93
  }
94
  table table table {
95
  table-layout: auto;
205
  <br>
206
  <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="<?php echo esc_attr( $settings['direction'] ); ?>" width="100%" style="max-width: 600px; border-radius: 5px;" bgcolor="<?php echo esc_attr( $settings['footer_bg'] ); ?>" class="footer_bg">
207
  <tr>
208
+ <td style="padding: 20px; width: 100%; font-size: <?php echo esc_attr( $settings['footer_text_size'] . 'px' ); ?>; font-family: sans-serif; mso-height-rule: exactly; line-height: <?php echo esc_attr( floor( $settings['footer_text_size'] * 1.618 ) . 'px' ) ?>; text-align: <?php echo esc_attr( $settings['direction'] ); ?>; color: <?php echo esc_attr( $settings['footer_text_color'] ); ?>; word-break: break-all;" class="footer_text_color footer_text_size">
209
  <?php
210
  /**
211
  * Fires before the display of the email template footer.
bp-templates/bp-legacy/buddypress/blogs/index.php CHANGED
@@ -60,11 +60,23 @@ do_action( 'bp_before_directory_blogs_page' ); ?>
60
 
61
  <div class="item-list-tabs" aria-label="<?php esc_attr_e( 'Sites directory main navigation', 'buddypress' ); ?>" role="navigation">
62
  <ul>
63
- <li class="selected" id="blogs-all"><a href="<?php bp_root_domain(); ?>/<?php bp_blogs_root_slug(); ?>"><?php printf( __( 'All Sites %s', 'buddypress' ), '<span>' . bp_get_total_blog_count() . '</span>' ); ?></a></li>
 
 
 
 
 
 
64
 
65
  <?php if ( is_user_logged_in() && bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) ) : ?>
66
 
67
- <li id="blogs-personal"><a href="<?php echo bp_loggedin_user_domain() . bp_get_blogs_slug(); ?>"><?php printf( __( 'My Sites %s', 'buddypress' ), '<span>' . bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) . '</span>' ); ?></a></li>
 
 
 
 
 
 
68
 
69
  <?php endif; ?>
70
 
60
 
61
  <div class="item-list-tabs" aria-label="<?php esc_attr_e( 'Sites directory main navigation', 'buddypress' ); ?>" role="navigation">
62
  <ul>
63
+ <li class="selected" id="blogs-all">
64
+ <a href="<?php bp_root_domain(); ?>/<?php bp_blogs_root_slug(); ?>">
65
+ <?php
66
+ /* translators: %s: all blogs count */
67
+ printf( __( 'All Sites %s', 'buddypress' ), '<span>' . bp_get_total_blog_count() . '</span>' ); ?>
68
+ </a>
69
+ </li>
70
 
71
  <?php if ( is_user_logged_in() && bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) ) : ?>
72
 
73
+ <li id="blogs-personal">
74
+ <a href="<?php echo bp_loggedin_user_domain() . bp_get_blogs_slug(); ?>">
75
+ <?php
76
+ /* translators: %s: current user blogs count */
77
+ printf( __( 'My Sites %s', 'buddypress' ), '<span>' . bp_get_total_blog_count_for_user( bp_loggedin_user_id() ) . '</span>' ); ?>
78
+ </a>
79
+ </li>
80
 
81
  <?php endif; ?>
82
 
bp-templates/bp-legacy/buddypress/groups/index.php CHANGED
@@ -59,10 +59,24 @@ do_action( 'bp_before_directory_groups_page' ); ?>
59
 
60
  <div class="item-list-tabs" aria-label="<?php esc_attr_e( 'Groups directory main navigation', 'buddypress' ); ?>">
61
  <ul>
62
- <li class="selected" id="groups-all"><a href="<?php bp_groups_directory_permalink(); ?>"><?php printf( __( 'All Groups %s', 'buddypress' ), '<span>' . bp_get_total_group_count() . '</span>' ); ?></a></li>
 
 
 
 
 
 
 
63
 
64
  <?php if ( is_user_logged_in() && bp_get_total_group_count_for_user( bp_loggedin_user_id() ) ) : ?>
65
- <li id="groups-personal"><a href="<?php echo bp_loggedin_user_domain() . bp_get_groups_slug() . '/my-groups/'; ?>"><?php printf( __( 'My Groups %s', 'buddypress' ), '<span>' . bp_get_total_group_count_for_user( bp_loggedin_user_id() ) . '</span>' ); ?></a></li>
 
 
 
 
 
 
 
66
  <?php endif; ?>
67
 
68
  <?php
59
 
60
  <div class="item-list-tabs" aria-label="<?php esc_attr_e( 'Groups directory main navigation', 'buddypress' ); ?>">
61
  <ul>
62
+ <li class="selected" id="groups-all">
63
+ <a href="<?php bp_groups_directory_permalink(); ?>">
64
+ <?php
65
+ /* translators: %s: all groups count */
66
+ printf( __( 'All Groups %s', 'buddypress' ), '<span>' . bp_get_total_group_count() . '</span>' );
67
+ ?>
68
+ </a>
69
+ </li>
70
 
71
  <?php if ( is_user_logged_in() && bp_get_total_group_count_for_user( bp_loggedin_user_id() ) ) : ?>
72
+ <li id="groups-personal">
73
+ <a href="<?php echo bp_loggedin_user_domain() . bp_get_groups_slug() . '/my-groups/'; ?>">
74
+ <?php
75
+ /* translators: %s: current user groups count */
76
+ printf( __( 'My Groups %s', 'buddypress' ), '<span>' . bp_get_total_group_count_for_user( bp_loggedin_user_id() ) . '</span>' );
77
+ ?>
78
+ </a>
79
+ </li>
80
  <?php endif; ?>
81
 
82
  <?php
bp-templates/bp-legacy/buddypress/groups/single/request-membership.php CHANGED
@@ -21,7 +21,7 @@ do_action( 'bp_before_group_request_membership_content' ); ?>
21
  <?php
22
  echo esc_html(
23
  sprintf(
24
- /* translators: %s =group name */
25
  __( 'You are requesting to become a member of the group "%s".', 'buddypress' ),
26
  bp_get_group_name()
27
  )
21
  <?php
22
  echo esc_html(
23
  sprintf(
24
+ /* translators: %s: group name */
25
  __( 'You are requesting to become a member of the group "%s".', 'buddypress' ),
26
  bp_get_group_name()
27
  )
bp-templates/bp-legacy/buddypress/members/activate.php CHANGED
@@ -44,7 +44,12 @@
44
  <?php if ( isset( $_GET['e'] ) ) : ?>
45
  <p><?php _e( 'Your account was activated successfully! Your account details have been sent to you in a separate email.', 'buddypress' ); ?></p>
46
  <?php else : ?>
47
- <p><?php printf( __( 'Your account was activated successfully! You can now <a href="%s">log in</a> with the username and password you provided when you signed up.', 'buddypress' ), wp_login_url( bp_get_root_domain() ) ); ?></p>
 
 
 
 
 
48
  <?php endif; ?>
49
 
50
  <?php else : ?>
44
  <?php if ( isset( $_GET['e'] ) ) : ?>
45
  <p><?php _e( 'Your account was activated successfully! Your account details have been sent to you in a separate email.', 'buddypress' ); ?></p>
46
  <?php else : ?>
47
+ <p>
48
+ <?php
49
+ /* translators: %s: login url */
50
+ printf( __( 'Your account was activated successfully! You can now <a href="%s">log in</a> with the username and password you provided when you signed up.', 'buddypress' ), wp_login_url( bp_get_root_domain() ) );
51
+ ?>
52
+ </p>
53
  <?php endif; ?>
54
 
55
  <?php else : ?>
bp-templates/bp-legacy/buddypress/members/register.php CHANGED
@@ -187,6 +187,7 @@
187
  <p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"><span id="<?php bp_the_profile_field_input_name(); ?>-2">
188
  <?php
189
  printf(
 
190
  __( 'This field can be seen by: %s', 'buddypress' ),
191
  '<span class="current-visibility-level">' . bp_get_the_profile_field_visibility_level_label() . '</span>'
192
  );
187
  <p class="field-visibility-settings-toggle" id="field-visibility-settings-toggle-<?php bp_the_profile_field_id() ?>"><span id="<?php bp_the_profile_field_input_name(); ?>-2">
188
  <?php
189
  printf(
190
+ /* translators: %s: level of visibility */
191
  __( 'This field can be seen by: %s', 'buddypress' ),
192
  '<span class="current-visibility-level">' . bp_get_the_profile_field_visibility_level_label() . '</span>'
193
  );
bp-templates/bp-legacy/buddypress/members/single/groups/invites.php CHANGED
@@ -32,7 +32,16 @@ do_action( 'bp_before_group_invites_content' ); ?>
32
  </div>
33
  <?php endif; ?>
34
 
35
- <h4><?php bp_group_link(); ?><span class="small"> - <?php printf( _nx( '%d member', '%d members', bp_get_group_total_members( false ),'Group member count', 'buddypress' ), bp_get_group_total_members( false ) ); ?></span></h4>
 
 
 
 
 
 
 
 
 
36
 
37
  <p class="desc">
38
  <?php bp_group_description_excerpt(); ?>
32
  </div>
33
  <?php endif; ?>
34
 
35
+ <h4>
36
+ <?php bp_group_link(); ?>
37
+ <span class="small">
38
+ &nbsp;-&nbsp;
39
+ <?php
40
+ /* translators: %s: group members count */
41
+ printf( _nx( '%d member', '%d members', bp_get_group_total_members( false ),'Group member count', 'buddypress' ), bp_get_group_total_members( false ) );
42
+ ?>
43
+ </span>
44
+ </h4>
45
 
46
  <p class="desc">
47
  <?php bp_group_description_excerpt(); ?>
bp-templates/bp-legacy/buddypress/members/single/messages/single.php CHANGED
@@ -32,11 +32,17 @@
32
 
33
  <?php elseif ( bp_get_max_thread_recipients_to_list() <= bp_get_thread_recipients_count() ) : ?>
34
 
35
- <?php printf( __( 'Conversation between %s recipients.', 'buddypress' ), number_format_i18n( bp_get_thread_recipients_count() ) ); ?>
 
 
 
36
 
37
  <?php else : ?>
38
 
39
- <?php printf( __( 'Conversation between %s.', 'buddypress' ), bp_get_thread_recipients_list() ); ?>
 
 
 
40
 
41
  <?php endif; ?>
42
 
32
 
33
  <?php elseif ( bp_get_max_thread_recipients_to_list() <= bp_get_thread_recipients_count() ) : ?>
34
 
35
+ <?php
36
+ /* translators: %s: message recipients count */
37
+ printf( __( 'Conversation between %s recipients.', 'buddypress' ), number_format_i18n( bp_get_thread_recipients_count() ) );
38
+ ?>
39
 
40
  <?php else : ?>
41
 
42
+ <?php
43
+ /* translators: %s: message recipients list */
44
+ printf( __( 'Conversation between %s.', 'buddypress' ), bp_get_thread_recipients_list() );
45
+ ?>
46
 
47
  <?php endif; ?>
48
 
bp-templates/bp-legacy/buddypress/members/single/profile/edit.php CHANGED
@@ -24,7 +24,12 @@ if ( bp_has_profile( 'profile_group_id=' . bp_get_current_profile_group_id() ) )
24
  /** This action is documented in bp-templates/bp-legacy/buddypress/members/single/profile/profile-wp.php */
25
  do_action( 'bp_before_profile_field_content' ); ?>
26
 
27
- <h2><?php printf( __( "Editing '%s' Profile Group", 'buddypress' ), bp_get_the_profile_group_name() ); ?></h2>
 
 
 
 
 
28
 
29
  <?php if ( bp_profile_has_multiple_groups() ) : ?>
30
  <ul class="button-nav" aria-label="<?php esc_attr_e( 'Profile field groups', 'buddypress' ); ?>" role="navigation">
24
  /** This action is documented in bp-templates/bp-legacy/buddypress/members/single/profile/profile-wp.php */
25
  do_action( 'bp_before_profile_field_content' ); ?>
26
 
27
+ <h2>
28
+ <?php
29
+ /* translators: %s: profile group name */
30
+ printf( __( "Editing '%s' Profile Group", 'buddypress' ), bp_get_the_profile_group_name() );
31
+ ?>
32
+ </h2>
33
 
34
  <?php if ( bp_profile_has_multiple_groups() ) : ?>
35
  <ul class="button-nav" aria-label="<?php esc_attr_e( 'Profile field groups', 'buddypress' ); ?>" role="navigation">
bp-templates/bp-legacy/buddypress/members/single/settings/data.php CHANGED
@@ -21,7 +21,12 @@ do_action( 'bp_before_member_settings_template' ); ?>
21
  <?php if ( bp_settings_personal_data_export_exists( $request ) ) : ?>
22
 
23
  <p><?php esc_html_e( 'Your request for an export of personal data has been completed.', 'buddypress' ); ?></p>
24
- <p><?php printf( esc_html__( 'You may download your personal data by clicking on the link below. For privacy and security, we will automatically delete the file on %s, so please download it before then.', 'buddypress' ), bp_settings_get_personal_data_expiration_date( $request ) ); ?></p>
 
 
 
 
 
25
 
26
  <p><strong><?php printf( '<a href="%1$s">%2$s</a>', bp_settings_get_personal_data_export_url( $request ), esc_html__( 'Download personal data', 'buddypress' ) ); ?></strong></p>
27
 
@@ -39,7 +44,12 @@ do_action( 'bp_before_member_settings_template' ); ?>
39
 
40
  <?php elseif ( 'request-confirmed' === $request->status ) : ?>
41
 
42
- <p><?php printf( esc_html__( 'You previously requested an export of your personal data on %s.', 'buddypress' ), bp_settings_get_personal_data_confirmation_date( $request ) ); ?></p>
 
 
 
 
 
43
  <p><?php esc_html_e( 'You will receive a link to download your export via email once we are able to fulfill your request.', 'buddypress' ); ?></p>
44
 
45
  <?php endif; ?>
21
  <?php if ( bp_settings_personal_data_export_exists( $request ) ) : ?>
22
 
23
  <p><?php esc_html_e( 'Your request for an export of personal data has been completed.', 'buddypress' ); ?></p>
24
+ <p>
25
+ <?php
26
+ /* translators: %s: expiration date */
27
+ printf( esc_html__( 'You may download your personal data by clicking on the link below. For privacy and security, we will automatically delete the file on %s, so please download it before then.', 'buddypress' ), bp_settings_get_personal_data_expiration_date( $request ) );
28
+ ?>
29
+ </p>
30
 
31
  <p><strong><?php printf( '<a href="%1$s">%2$s</a>', bp_settings_get_personal_data_export_url( $request ), esc_html__( 'Download personal data', 'buddypress' ) ); ?></strong></p>
32
 
44
 
45
  <?php elseif ( 'request-confirmed' === $request->status ) : ?>
46
 
47
+ <p>
48
+ <?php
49
+ /* translators: %s: confirmation date */
50
+ printf( esc_html__( 'You previously requested an export of your personal data on %s.', 'buddypress' ), bp_settings_get_personal_data_confirmation_date( $request ) );
51
+ ?>
52
+ </p>
53
  <p><?php esc_html_e( 'You will receive a link to download your export via email once we are able to fulfill your request.', 'buddypress' ); ?></p>
54
 
55
  <?php endif; ?>
bp-templates/bp-legacy/css/twentyfifteen.scss CHANGED
@@ -222,12 +222,6 @@ http://codex.buddypress.org/themes/buddypress-companion-stylesheets/
222
  display: none;
223
  }
224
 
225
- .site-content {
226
-
227
- @media screen and (min-width: 77.5em) {
228
- }
229
- }
230
-
231
  main {
232
  padding-top: 4%;
233
 
222
  display: none;
223
  }
224
 
 
 
 
 
 
 
225
  main {
226
  padding-top: 4%;
227
 
bp-templates/bp-legacy/css/twentyseventeen-rtl.css CHANGED
@@ -1976,7 +1976,7 @@ body.colors-light #buddypress div#invite-list {
1976
  #buddypress div.dir-search form input[type="submit"],
1977
  #buddypress div.message-search form input[type="submit"],
1978
  #buddypress li.groups-members-search form input[type="submit"] {
1979
- border-radius: none;
1980
  float: left;
1981
  font-weight: 400;
1982
  padding: 0.2em 1em;
1976
  #buddypress div.dir-search form input[type="submit"],
1977
  #buddypress div.message-search form input[type="submit"],
1978
  #buddypress li.groups-members-search form input[type="submit"] {
1979
+ border-radius: 0;
1980
  float: left;
1981
  font-weight: 400;
1982
  padding: 0.2em 1em;
bp-templates/bp-legacy/css/twentyseventeen-rtl.min.css CHANGED
@@ -1 +1 @@
1
- .buddypress div.clear{display:none}.buddypress ul.item-list h1,.buddypress ul.item-list h2,.buddypress ul.item-list h3,.buddypress ul.item-list h4,.buddypress ul.item-list h5,.buddypress ul.item-list h6{clear:none;padding:0}.buddypress #page a{box-shadow:none;text-decoration:none!important}.buddypress .entry-title{text-align:center}@media screen and (min-width:55em){.buddypress .entry-title{text-align:right}}@media screen and (min-width:55em){.buddypress.bp-user.page .site-content,.buddypress.groups.group-create .site-content,.buddypress.single-item.groups .site-content,.directory.buddypress.page-one-column .site-content{padding-top:40px}.buddypress.bp-user.page .entry-header,.buddypress.groups.group-create .entry-header,.buddypress.single-item.groups .entry-header,.directory.buddypress.page-one-column .entry-header{margin:10px 0}}@media screen and (min-width:48em){body.buddypress.page.page-two-column #primary .entry-header{width:30%}body.buddypress.page.page-two-column #primary .entry-content{width:68%}body.buddypress:not(.has-sidebar) #primary.content-area,body.buddypress:not(.page-two-column) #primary.content-area{max-width:100%;width:100%}body.buddypress:not(.has-sidebar) #primary.content-area .content-bottom-widgets,body.buddypress:not(.has-sidebar) #primary.content-area .entry-content,body.buddypress:not(.page-two-column) #primary.content-area .content-bottom-widgets,body.buddypress:not(.page-two-column) #primary.content-area .entry-content{margin-right:0;margin-left:0}body.buddypress:not(.has-sidebar) .sidebar,body.buddypress:not(.page-two-column) .sidebar{float:right;margin-right:75%;padding:0;width:25%}}body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.current,body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.selected{border-bottom-color:#222}body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.current a,body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.selected a{color:inherit}body.colors-dark #buddypress div.item-list-tabs ul li.current a,body.colors-dark #buddypress div.item-list-tabs ul li.selected a{background:0 0;color:inherit}body.colors-dark #buddypress #object-nav li:not(.current):focus a,body.colors-dark #buddypress #object-nav li:not(.current):hover a{color:#555}body.colors-dark #buddypress #subnav.item-list-tabs ul{border-bottom:1px solid rgba(234,234,234,.9);margin-bottom:20px}body.colors-dark #buddypress #subnav.item-list-tabs ul li.last{border-top:1px solid rgba(234,234,234,.9)}body.colors-dark #buddypress #subnav.item-list-tabs select option{background-color:#333}body.colors-dark #buddypress .item-list div.meta{color:#ddd}body.colors-dark #buddypress .item-list .acomment-meta,body.colors-dark #buddypress .item-list .activity-comments ul,body.colors-dark #buddypress .item-list .activity-header p,body.colors-dark #buddypress .item-list div.item-desc{color:#eee}body.colors-dark #buddypress .item-list .action a,body.colors-dark #buddypress .item-list .activity-meta a{background:#fafafa}body.colors-dark #buddypress .item-list .action a:focus,body.colors-dark #buddypress .item-list .action a:hover,body.colors-dark #buddypress .item-list .activity-meta a:focus,body.colors-dark #buddypress .item-list .activity-meta a:hover{background:#fff}body.colors-dark #buddypress #latest-update{color:#eee}body.colors-dark #buddypress div.pagination *{color:#ddd}body.colors-dark #buddypress #item-header .user-nicename{color:#eee}body.colors-dark #buddypress #item-body table thead th,body.colors-dark #buddypress #item-body table thead tr{background:0 0;color:#eee}body.colors-dark #buddypress #item-body table tr.alt td{background:0 0;color:#eee}body.colors-dark #buddypress #item-body table .field-visibility-settings,body.colors-dark #buddypress #item-body table .field-visibility-settings-notoggle{color:#eee}body.colors-dark #buddypress #item-body fieldset{background:0 0}body.colors-dark #buddypress #item-body .checkbox label,body.colors-dark #buddypress #item-body .radio label{color:#eee}body.colors-dark #buddypress #item-body div#invite-list{background:0 0}body.colors-dark.group-members #buddypress #subnav li{background:0 0}body.colors-dark.group-members #buddypress #subnav .groups-members-search form{margin-bottom:20px;margin-top:0}.directory.colors-dark #buddypress #subnav.item-list-tabs ul{border-bottom:0;border-top:0}.directory.colors-dark #buddypress #subnav.item-list-tabs ul li.last.filter{border-top:0}.directory.colors-dark #buddypress div.activity ul.item-list{border-top:0}body.colors-light #buddypress div.item-list-tabs ul{background-color:#fafafa}body.colors-light #buddypress div#subnav.item-list-tabs ul{background-color:#f7f7f7}body.colors-light #buddypress div#subnav.item-list-tabs ul li.last{background:#fff}body.colors-light #buddypress .item-list .activity-header p{background-color:#f7f7f7;color:#878787}body.colors-light #buddypress .item-list .activity-comments .acomment-meta{color:#737373}body.colors-light #buddypress #item-body .profile h2{background:#878787;color:#fff}body.colors-light #buddypress table tr.alt td{background:#f5f5f5;color:#333}body.colors-light #buddypress div#invite-list{background:#fafafa}#buddypress div.item-list-tabs ul li.selected a{background:inherit;opacity:1}#buddypress div.item-list-tabs ul{border-bottom:1px solid rgba(234,234,234,.9);overflow:hidden;padding:0}#buddypress div.item-list-tabs ul li a span{border-radius:25%}#buddypress #object-nav ul{overflow:hidden}#buddypress #object-nav ul li{float:none}@media screen and (max-width:38.75em){#buddypress #object-nav ul li:not(:last-child){border-bottom:1px solid #eaeaea}}@media screen and (max-width:38.75em){#buddypress #object-nav ul li:not(.selected):focus,#buddypress #object-nav ul li:not(.selected):hover{background:#f4f2df}}@media screen and (min-width:38.75em){#buddypress #object-nav ul li{float:right}}#buddypress div#subnav.item-list-tabs{margin-top:0}#buddypress div#subnav.item-list-tabs ul{border-bottom:0;margin-top:5px;padding:0}#buddypress div#subnav.item-list-tabs ul li.last{margin-top:0;padding:5px 0 5px 5px;width:100%}#buddypress div#subnav.item-list-tabs ul li.last select,#buddypress div#subnav.item-list-tabs ul li.last select:focus{background:0 0;border:0;outline:0}#buddypress div#subnav.item-list-tabs ul li.last label{display:inline}#buddypress div#subnav.item-list-tabs ul li.last label,#buddypress div#subnav.item-list-tabs ul li.last option,#buddypress div#subnav.item-list-tabs ul li.last select{font-size:14px;font-size:.875rem}#buddypress div#subnav.item-list-tabs ul li.last select{font-style:italic;height:auto}@media screen and (min-width:38.75em){#buddypress div#subnav.item-list-tabs ul li.last{text-align:left}}@media screen and (min-width:55em){body:not(.page-two-column) #buddypress #object-nav{border-left:1px solid #ddd;float:right;margin-left:-1px;width:200px}body:not(.page-two-column) #buddypress #object-nav ul{background:0 0;border-bottom:0;padding:0}body:not(.page-two-column) #buddypress #object-nav ul li{float:none;overflow:hidden}body:not(.page-two-column) #buddypress #object-nav ul li span{background:#fff;border-radius:10%;float:left;margin-left:2px}body:not(.page-two-column) #buddypress #item-body{border-right:1px solid #ddd;overflow:hidden;padding:0 20px 0 0;width:auto}body:not(.page-two-column) #buddypress #item-body #subnav{margin:0 -20px 0 0}body:not(.page-two-column) #buddypress #item-body #subnav ul{margin-top:0}}@media screen and (min-width:48em){#buddypress #group-create-tabs.item-list-tabs ul:after,#buddypress #group-create-tabs.item-list-tabs ul:before{content:" ";display:table}#buddypress #group-create-tabs.item-list-tabs ul:after{clear:both}#buddypress #group-create-tabs.item-list-tabs ul{background:0 0;border:0;border-bottom:1px solid #ddd;overflow:visible;padding-bottom:0}#buddypress #group-create-tabs.item-list-tabs ul li{float:right;width:auto}#buddypress #group-create-tabs.item-list-tabs ul li.current,#buddypress #group-create-tabs.item-list-tabs ul li.selected{border:1px solid #ddd;border-bottom-color:#fff;border-top-left-radius:4px;border-top-right-radius:4px;background-clip:padding-box;margin-bottom:-1px}#buddypress #group-create-tabs.item-list-tabs ul li.current a,#buddypress #group-create-tabs.item-list-tabs ul li.selected a{background:0 0;color:#333;outline:0}#buddypress #subnav ul{border-bottom:0}}#buddypress div.pagination{box-shadow:none;font-weight:400;min-height:0}#buddypress div.pagination:after,#buddypress div.pagination:before{height:0;width:0}#buddypress div.pagination .pag-count{margin-right:0}#buddypress div.pagination .pagination-links{margin-left:0}#buddypress div.pagination .pagination-links a,#buddypress div.pagination .pagination-links span{height:auto;line-height:1;padding:5px}#buddypress div.pagination .pagination-links .next,#buddypress div.pagination .pagination-links .prev{background-color:transparent;color:inherit;overflow:visible;width:auto}#buddypress div.pagination .pagination-links .next:before,#buddypress div.pagination .pagination-links .prev:before{display:none}#buddypress div.pagination .pagination-links .prev{right:auto;position:static}#buddypress div.pagination .pagination-links .next{position:static;left:auto}#buddypress .item-list .activity-header,#buddypress .item-list .activity-meta{font-family:"Libre Franklin","Helvetica Neue",helvetica,arial,sans-serif}#buddypress .activity-meta .button:focus,#buddypress .activity-meta .button:hover{background:inherit;color:#000}#buddypress .action .generic-button a:focus,#buddypress .action .generic-button a:hover{background:inherit;color:#000}#buddypress ul.item-list li{overflow:hidden!important}#buddypress ul.item-list li .item-avatar{margin-bottom:10px;text-align:center}@media screen and (min-width:38.75em){#buddypress ul.item-list li .item-avatar{margin-bottom:0}}#buddypress ul.item-list li .item-avatar a{border-bottom:0}#buddypress ul.item-list li .item-avatar img.avatar{display:inline-block;float:none;margin-bottom:10px}@media screen and (min-width:30em){#buddypress ul.item-list li .item-avatar img.avatar{display:block;float:right}}#buddypress ul.item-list li .item{overflow:hidden}@media screen and (min-width:48em){#buddypress ul.item-list li .item{margin-right:15%}}#buddypress ul.item-list li .item span.activity{font-style:italic}#buddypress ul.item-list li .item .item-desc{margin-right:0;width:94%}#buddypress ul.item-list li .item .item-title{font-size:18px;font-size:1.125rem;line-height:1.2;text-align:center;width:100%}@media screen and (min-width:30em){#buddypress ul.item-list li .item .item-title{text-align:right}}#buddypress ul.item-list li .item .item-title .update{display:block;font-size:13px;font-size:.8125rem;padding:10px 0;text-align:right}@media screen and (min-width:55em){#buddypress ul.item-list li .item .item-title .update{font-size:14px;font-size:.875rem}}@media screen and (min-width:55em){#buddypress ul.item-list li .action,#buddypress ul.item-list li .item,#buddypress ul.item-list li .item-avatar{float:right}#buddypress ul.item-list li .item{right:5%;margin-right:0;position:relative;width:55%}#buddypress ul.item-list li .item .item-title{font-size:22px;font-size:1.375rem}}#buddypress ul.item-list li div.action{clear:right;float:none;margin-bottom:-20px;margin-right:0;padding:20px 0 5px;position:relative;text-align:right;top:0}@media screen and (min-width:55em){#buddypress ul.item-list li div.action{clear:none;float:left;margin-bottom:0;padding:0}}#buddypress ul.item-list li div.action div{display:inline-block;margin:10px 0;width:100%}#buddypress ul.item-list li div.action div a{display:block;width:100%}@media screen and (min-width:30em){#buddypress ul.item-list li div.action div{margin:0 0 10px 10px;width:auto}}@media screen and (min-width:55em){#buddypress ul.item-list li div.action div{clear:left;float:left;margin:0 0 10px 0}}#buddypress ul.item-list li div.action .meta{font-style:italic}#buddypress form#whats-new-form p.activity-greeting{line-height:1.4}@media screen and (max-width:46.25em){#buddypress form#whats-new-form #whats-new-content{clear:right;margin:10px 0 20px;padding:10px 0 0}}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box{border:1px solid rgba(190,190,190,.5);float:right;line-height:1.5;margin-top:12px;padding-right:.2em;width:100%}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box select{background:0 0;border:0;float:left;margin:0;min-height:1.5em;padding-right:.4em}@media screen and (min-width:30em){#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box{width:auto}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-submit{float:left}}#buddypress #item-body form#whats-new-form{margin:40px 0}#buddypress #activity-stream li{padding:25px 0 15px}#buddypress #activity-stream li .activity-avatar{float:none;text-align:center}#buddypress #activity-stream li .activity-avatar a{display:inline-block}#buddypress #activity-stream li .activity-avatar a img.avatar{display:inline;float:none;height:60px;margin-bottom:20px;margin-right:0;width:60px}#buddypress #activity-stream li .activity-content{margin-right:0}#buddypress #activity-stream li .activity-content .activity-header{font-size:14px;font-size:.875rem}#buddypress #activity-stream li .activity-content .activity-header a{color:#0075c4}@media screen and (min-width:48em){#buddypress #activity-stream li .activity-avatar{float:right;margin-left:10px;text-align:right}#buddypress #activity-stream li .activity-avatar a{border-bottom:0}#buddypress #activity-stream li .activity-content{margin:0;overflow:hidden}#buddypress #activity-stream li .activity-content .activity-header{font-size:16px;font-size:1rem}}#buddypress #activity-stream li.mini .activity-avatar a img.avatar{height:30px;margin-right:15px;width:30px}#buddypress #activity-stream li.mini .activity-content .activity-header{font-size:14px;font-size:.875rem}#buddypress #activity-stream .activity-content{margin-top:-12px}#buddypress #activity-stream .activity-content .activity-header{margin-left:0}#buddypress #activity-stream .activity-content .activity-header p{border:1px solid rgba(234,234,234,.6);margin-top:0;padding:0 .2em}#buddypress #activity-stream .activity-content .activity-header img.avatar{box-shadow:none;display:inline-block;margin:0 5px!important;vertical-align:middle}#buddypress #activity-stream .activity-content .activity-meta a{display:block;margin-bottom:5px}@media screen and (min-width:30em){#buddypress #activity-stream .activity-content .activity-meta a{display:inline-block;margin-bottom:0;width:auto}}#buddypress #activity-stream .load-more{background:#f7f7f7;border:1px solid transparent;padding:10px}#buddypress #activity-stream .load-more:focus,#buddypress #activity-stream .load-more:hover{background:#f4f4f4;border:1px solid rgba(159,209,226,.3)}#buddypress #activity-stream .load-more:focus a,#buddypress #activity-stream .load-more:hover a{font-style:italic}#buddypress #activity-stream .load-more a{display:block}.activity-permalink #buddypress #activity-stream li.activity-item{padding:20px}.activity-permalink #buddypress #activity-stream li.mini .activity-header{font-size:16px;font-size:1rem;margin-bottom:40px}@media screen and (min-width:48em){.activity-permalink #buddypress #activity-stream li.mini .activity-header{font-size:20px;font-size:1.25rem}}.activity-permalink #buddypress #activity-stream li.mini .activity-header p{padding:20px}#buddypress #activity-stream .activity-comments{border-right:1px solid #eaeaea;margin:20px 0 20px}@media screen and (min-width:30em){#buddypress #activity-stream .activity-comments{margin-right:20px}}#buddypress #activity-stream .activity-comments ul{margin:15px 2px 0 0}#buddypress #activity-stream .activity-comments ul li{border-top:1px solid #bebebe}#buddypress #activity-stream .activity-comments ul a{color:#0077c7}#buddypress #activity-stream .activity-comments .acomment-meta{border-bottom:1px solid #eaeaea}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel,#buddypress #activity-stream .activity-comments .ac-form input[type=submit]{color:rgba(51,51,51,.8);display:inline-block;font-family:inherit;font-size:12px;font-size:.75rem;font-weight:400;line-height:1.2;padding:4px 10px;text-transform:lowercase;width:100px}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel{border:1px solid rgba(190,190,190,.7);text-align:center}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel:focus,#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel:hover{background:#ededed}@media screen and (min-width:55em){#buddypress #members-list li .item,#buddypress #members-list li .item-avatar{float:right}#buddypress #members-list li .action{float:left}#buddypress #members-list li.is-current-user .item{float:none;right:0;padding-right:5%;width:auto}}#buddypress #signup_form.standard-form #basic-details-section,#buddypress #signup_form.standard-form #blog-details-section,#buddypress #signup_form.standard-form #profile-details-section{float:none;width:100%}@media screen and (min-width:38.75em){#buddypress #signup_form.standard-form #basic-details-section,#buddypress #signup_form.standard-form #blog-details-section,#buddypress #signup_form.standard-form #profile-details-section{width:48%}}@media screen and (min-width:30em){#buddypress #signup_form.standard-form #profile-details-section{float:left}#buddypress #signup_form.standard-form #basic-details-section{float:right}}@media screen and (min-width:48em){.bp-user.page-two-column #buddypress #cover-image-container #item-header-cover-image #item-header-content{margin-right:140px;margin-top:-100px}.single-item.groups.page-two-column #buddypress #cover-image-container #item-header-cover-image #item-header-content{margin-right:10px}}.bp-user #buddypress #item-header-cover-image .user-nicename,.single-item.groups #buddypress #item-header-cover-image .user-nicename{color:#333;text-shadow:none}@media screen and (min-width:48em){.bp-user #buddypress #item-header-cover-image .user-nicename,.single-item.groups #buddypress #item-header-cover-image .user-nicename{color:#fff;text-shadow:0 0 3px rgba(0,0,0,.8)}}.bp-user #buddypress #item-header-content #item-meta,.single-item.groups #buddypress #item-header-content #item-meta{font-size:14px;font-size:.875rem;text-align:right}.bp-user #buddypress #item-header-content #item-meta p,.single-item.groups #buddypress #item-header-content #item-meta p{margin-bottom:.5em}@media screen and (max-width:46.25em){.bp-user main header.entry-header,.single-item.groups main header.entry-header{padding-bottom:1rem}}@media screen and (max-width:38.75em){.bp-user #item-header-content,.bp-user h1,.single-item.groups #item-header-content,.single-item.groups h1{text-align:center}}@media screen and (max-width:46.25em){.bp-user #buddypress #item-header .generic-button,.single-item.groups #buddypress #item-header .generic-button{float:none;margin:1.5em 0 0}}@media screen and (max-width:38.75em){.bp-user #buddypress h1,.single-item.groups #buddypress h1{margin-bottom:0}.bp-user #buddypress #item-header-avatar img.avatar,.single-item.groups #buddypress #item-header-avatar img.avatar{margin-left:0}.bp-user #buddypress #item-header-content,.single-item.groups #buddypress #item-header-content{width:100%}}@media screen and (max-width:46.25em){.single-item.groups #buddypress #item-header #item-meta{margin-bottom:20px}}@media screen and (max-width:38.75em){.single-item.groups #buddypress div#item-header{display:flex;flex-direction:column}.single-item.groups #buddypress div#item-header #item-header-avatar{order:1;text-align:center}.single-item.groups #buddypress div#item-header #item-header-avatar a img{display:inline-block;float:none}.single-item.groups #buddypress div#item-header #item-header-content{order:2}.single-item.groups #buddypress div#item-header #item-actions{order:3}.single-item.groups #buddypress div#item-header #item-actions h2{border-bottom:1px solid #eaeaea;text-align:center}}.single-item.groups #buddypress div#item-header{padding-bottom:40px}.single-item.groups #buddypress div#item-header div#item-actions{margin:0;width:100%}@media screen and (min-width:38.75em){.single-item.groups #buddypress div#item-header div#item-actions{border-right:1px solid #eaeaea;clear:none;float:left;padding-right:.2em;width:30%}}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header div#item-actions{width:40%}}.single-item.groups #buddypress div#item-header div#item-actions ul{margin-top:0;padding-right:0}.single-item.groups #buddypress div#item-header div#item-actions h2{font-size:14px;font-size:.875rem;padding:.2em}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header div#item-actions h2{font-size:16px;font-size:1rem}}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header #item-header-avatar,.single-item.groups #buddypress div#item-header #item-header-content{float:right}.single-item.groups #buddypress div#item-header #item-header-avatar{width:21%}.single-item.groups #buddypress div#item-header #item-header-content{margin-right:4%;width:40%}.single-item.groups #buddypress div#item-header div#item-actions{float:left;width:28%}}.bp-user #buddypress #item-header{padding:20px 0}.bp-user #buddypress #item-header #item-header-avatar{text-align:center;width:100%}.bp-user #buddypress #item-header #item-header-avatar a,.bp-user #buddypress #item-header #item-header-avatar img.avatar{display:inline-block;float:none}@media screen and (min-width:48em){.bp-user #buddypress #item-header #item-header-avatar{float:right;width:20%}.bp-user #buddypress #item-header #item-header-avatar a{float:right}.bp-user #buddypress #item-header #item-header-content{float:left;margin-left:5%;width:69%}}.groups.single-item.members #buddypress #subnav.item-list-tabs ul{background:0 0;border-top:0}.groups #group-settings-form h3{background:#555;color:#fff;padding:.2em}.groups.edit-details #group-settings-form label{margin-bottom:0;padding:.2em;width:80%}.groups.edit-details #group-settings-form textarea+p label{background:0 0;color:inherit;font-size:14px;font-size:.875rem;width:auto}.groups.edit-details #group-settings-form textarea{height:auto;min-height:100px;overflow:auto}.groups.group-settings #group-settings-form div.radio label{border:1px solid #eaeaea;padding:.2em}.groups.group-settings #group-settings-form div.radio label ul{color:rgba(51,51,51,.6);font-size:14px;font-size:.875rem}.groups.group-avatar form>p{margin-top:20px}.groups.manage-members #group-settings-form .item-list li{border-bottom:1px solid #eaeaea}.groups.manage-members #group-settings-form .item-list li h5,.groups.manage-members #group-settings-form .item-list li img{float:right}.groups.manage-members #group-settings-form .item-list li h5>a,.groups.manage-members #group-settings-form .item-list li img>a{border-bottom:0}.groups.manage-members #group-settings-form .item-list li span.small{clear:right;display:block;float:none;margin-top:10px}.groups.manage-members #group-settings-form .item-list li span.small a{display:inline-block;margin:5px 0;width:100%}@media screen and (min-width:38.75em){.groups.manage-members #group-settings-form .item-list li span.small a{width:auto}}.groups.manage-members #group-settings-form .item-list li h5{margin:0}.groups.group-members #subnav li{width:100%}@media screen and (max-width:38.75em){.groups.group-members #subnav li{background:#fff;padding:20px 0}}.groups.group-members #subnav li #search-members-form{float:left;margin:5px 0 0}@media screen and (max-width:38.75em){.groups.group-members #subnav li #search-members-form{margin:0;width:100%}.groups.group-members #subnav li #search-members-form label input[type=text]{width:100%}}.bp-user .entry-title{margin-bottom:.5em}.bp-user #buddypress table th{font-size:14px;font-size:.875rem}.bp-user #buddypress table td{font-size:12px;font-size:.75rem}.bp-user #buddypress table a{color:#0074c2}@media screen and (min-width:55em){.bp-user #buddypress table th{font-size:16px;font-size:1rem}.bp-user #buddypress table td{font-size:14px;font-size:.875rem}}@media screen and (min-width:67em){.bp-user #buddypress table th{font-size:18px;font-size:1.125rem}.bp-user #buddypress table td{font-size:16px;font-size:1rem}}.bp-user #buddypress .pag-count{font-style:italic}.bp-user #buddypress .messages-options-nav,.bp-user #buddypress .notifications-options-nav{float:right;width:100%}@media screen and (min-width:38.75em){.bp-user #buddypress .messages-options-nav,.bp-user #buddypress .notifications-options-nav{width:300px}}.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav select{height:auto}.bp-user #buddypress .messages-options-nav input,.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav input,.bp-user #buddypress .notifications-options-nav select{font-size:14px;font-size:.875rem;outline:0;padding:0}.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav select{float:right;margin-left:1%;width:59%}.bp-user #buddypress .messages-options-nav input,.bp-user #buddypress .notifications-options-nav input{float:left;font-family:inherit;line-height:20px;width:40%}.bp-user #buddypress .messages-options-nav input[disabled=disabled]:focus,.bp-user #buddypress .messages-options-nav input[disabled=disabled]:hover,.bp-user #buddypress .notifications-options-nav input[disabled=disabled]:focus,.bp-user #buddypress .notifications-options-nav input[disabled=disabled]:hover{background:0 0}.bp-user #buddypress .profile h2{margin:40px 0 10px;padding:.1em .4em .1em 0}.bp-user #buddypress .profile table{margin-top:0}.bp-user #buddypress .profile .profile-fields tr.alt td{color:#333}.bp-user #buddypress .profile .profile-fields tr:last-child{border-bottom:0}.bp-user #buddypress .profile #profile-edit-form .button-nav:after,.bp-user #buddypress .profile #profile-edit-form .button-nav:before{content:" ";display:table}.bp-user #buddypress .profile #profile-edit-form .button-nav:after{clear:both}.bp-user #buddypress .profile #profile-edit-form ul.button-nav{border-bottom:1px solid #eaeaea;margin-right:0}.bp-user #buddypress .profile #profile-edit-form ul.button-nav li{float:right;margin-bottom:0}.bp-user #buddypress .profile #profile-edit-form ul.button-nav li.current{border:1px solid #eaeaea;border-bottom-color:#fff;margin-bottom:-1px}.bp-user #buddypress .profile #profile-edit-form ul.button-nav a{background:0 0;border:0;font-size:18px;font-size:1.125rem}.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings,.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-notoggle,.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-toggle{font-size:14px;font-size:.875rem;margin-top:10px}.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-close,.bp-user #buddypress .profile #profile-edit-form .visibility-toggle-link{background:#555;border-radius:3px;background-clip:padding-box;color:#fff;padding:.2em .5em}.bp-user #buddypress .profile .bp-avatar #bp-delete-avatar a{font-size:inherit}@media screen and (min-width:77.5em){.bp-user #buddypress #groups-list li .item{right:5%;width:50%}}.bp-user #buddypress #message-thread a{border-bottom:0}.bp-user #buddypress #message-thread #message-subject{background:#6f6e6e;color:#fff;padding:.3em .2em .3em 0}.bp-user #buddypress #message-thread #message-recipients{font-style:italic}.bp-user #buddypress #message-thread #message-recipients a.confirm{border:1px solid #eaeaea;font-style:normal}.bp-user #buddypress #message-thread .message-metadata:after{clear:both;content:"";display:table}.bp-user #buddypress #message-thread .message-metadata img.avatar{float:none}@media screen and (min-width:48em){.bp-user #buddypress #message-thread .message-metadata img.avatar{float:right}}.bp-user #buddypress #message-thread .message-metadata .message-star-actions{float:left;margin-left:5px;position:static}.bp-user #buddypress #message-thread .message-content{background:#f7f7f7;border:1px solid #eaeaea;margin:10px 0 0 0;padding:.3em}.bp-user #buddypress #message-thread #send-reply .message-content{background:#fff;border:0}.bp-user #buddypress #message-thread .alt{background:#fff}.bp-user #buddypress #message-threads thead tr{background:0 0;border-bottom:1px solid #bebebe}.bp-user #buddypress #message-threads thead tr th{background:#555}.bp-user #buddypress #message-threads tr{border-bottom:5px solid #878787}.bp-user #buddypress #message-threads tr td{display:inline-block;float:right}.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{border-bottom-color:#bebebe;border-bottom-width:1px;height:2.4em;padding-bottom:.2em;padding-top:.2em}@media screen and (max-width:46.25em){.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{padding-top:0}}.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from,.bp-user #buddypress #message-threads tr td.thread-info,.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{border-top:0}.bp-user #buddypress #message-threads tr td.thread-star{vertical-align:middle}.bp-user #buddypress #message-threads tr td.thread-star .message-action-star{line-height:1.2}.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from{height:3em}@media screen and (max-width:38.75em){.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from{height:5.2em}}.bp-user #buddypress #message-threads tr td.thread-from,.bp-user #buddypress #message-threads tr td.thread-options{border-right:0!important;width:calc(100% - 30px);margin-right:0}.bp-user #buddypress #message-threads tr td.thread-info{padding-right:41px;width:100%}.bp-user #buddypress #message-threads tr td.thread-options{text-align:left}.bp-user #buddypress #message-threads tr td.thread-options a{font-size:12px;font-size:.75rem;line-height:2.2}.bp-user #buddypress #message-threads tr span.from{display:none}.bp-user #buddypress #message-threads tr span.activity{display:block;float:left;line-height:2}@media screen and (max-width:38.75em){.bp-user #buddypress #message-threads tr span.activity{clear:both;font-size:11px;font-size:.6875rem;width:100%}}.bp-user #buddypress #message-threads tr.unread td{background:0 0;border-color:#bebebe}.bp-user #buddypress #message-threads th{display:none}.bp-user #buddypress #message-threads th.bulk-select-all{border-bottom:0;display:inline-block;text-align:right}.bp-user #buddypress #message-threads td.bulk-select-check,.bp-user #buddypress #message-threads td.thread-star,.bp-user #buddypress #message-threads th.bulk-select-all{border-left:0;width:30px}.bp-user #buddypress .acfb-holder{list-style:none}.bp-user #buddypress .acfb-holder li{margin-right:0}.bp-user #buddypress .acfb-holder li.friend-tab{background:#e3f6ff;border:inherit;margin-left:0;padding:.5em}.bp-user #buddypress .acfb-holder li.friend-tab span.p{padding-right:10px}.bp-user #buddypress .acfb-holder li.friend-tab span.p:focus,.bp-user #buddypress .acfb-holder li.friend-tab span.p:hover{color:#c82b2b;cursor:pointer}.bp-user #buddypress .acfb-holder li.friend-tab a{border-bottom:0;text-decoration:none}.bp-user #buddypress .acfb-holder li.friend-tab a img{display:inline;height:20px;vertical-align:middle;width:20px!important}.bp-user #buddypress #message-threads.sitewide-notices td{width:100%}.bp-user #buddypress #message-threads.sitewide-notices td strong{background:#6f6e6e;color:#fff;display:block;margin-bottom:.4em;padding-right:.2em}.bp-user #buddypress #message-threads.sitewide-notices td a{display:inline-block}.bp-user #buddypress #message-threads.sitewide-notices td:first-child{display:none}.bp-user #buddypress #message-threads.sitewide-notices td:nth-child(2) strong{margin:-8px -8px 8px}.bp-user #buddypress #message-threads.sitewide-notices td:first-child+td+td{border-bottom:0}.bp-user #buddypress #message-threads.sitewide-notices td:first-child+td+td span{line-height:1}.bp-user #buddypress #message-threads.sitewide-notices td:last-child{border-bottom-color:#b7b7b7;line-height:1;text-align:left}.bp-user #buddypress #message-threads.sitewide-notices td:last-child a:last-child:after{content:attr(title);display:block;line-height:initial;text-indent:0}.bp-user .ac_results{background:#eee;padding-right:10px}.bp-user .ac_results ul{margin:0}.bp-user .ac_results li{margin:10px 0}.bp-user .ac_results li:focus,.bp-user .ac_results li:hover{cursor:pointer}.bp-user #buddypress #settings-form>p{font-size:20px;font-size:1.25rem;margin:20px 0 10px}.bp-user #buddypress table.notification-settings td.no,.bp-user #buddypress table.notification-settings td.yes{vertical-align:middle}.bp-user #buddypress table.profile-settings{width:100%}.bp-user #buddypress table.profile-settings td.field-name,.bp-user #buddypress table.profile-settings th.field-group-name{width:50%}@media screen and (min-width:48em){.bp-user #buddypress table.profile-settings td.field-name,.bp-user #buddypress table.profile-settings th.field-group-name{width:70%}}.bp-user #buddypress table.profile-settings td.field-visibility,.bp-user #buddypress table.profile-settings th.title{width:30%}.bp-user #buddypress table.profile-settings td.field-visibility select{width:100%}#main #buddypress .standard-form li{float:none}#main #buddypress .standard-form input[type=email],#main #buddypress .standard-form input[type=password],#main #buddypress .standard-form input[type=text],#main #buddypress .standard-form textarea{width:100%}#buddypress div.activity-comments form .ac-textarea{background:#f7f7f7;border:1px solid rgba(190,190,190,.5)}#buddypress div.activity-comments form .ac-textarea textarea{background:0 0;border:0}#buddypress select{height:auto}#buddypress .standard-form button,#buddypress .standard-form input[type=email],#buddypress .standard-form input[type=password],#buddypress .standard-form input[type=text],#buddypress .standard-form select,#buddypress .standard-form textarea{border-color:rgba(190,190,190,.5);border-width:1px}#buddypress .standard-form select{color:#737373}#buddypress #signup_form.standard-form div.submit{float:none}#buddypress #signup_form.standard-form div.submit input{margin-left:0}#buddypress div.dir-search,#buddypress div.message-search,#buddypress li.groups-members-search{float:none;margin:10px 0}#buddypress div.dir-search form,#buddypress div.message-search form,#buddypress li.groups-members-search form{border:1px solid rgba(190,190,190,.6);position:relative;border-radius:2px;background-clip:padding-box;overflow:hidden}#buddypress div.dir-search form label,#buddypress div.message-search form label,#buddypress li.groups-members-search form label{float:right;margin:0;width:70%}#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{float:right;margin:0;width:100%}#buddypress div.dir-search form input[type=submit],#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=submit],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=submit],#buddypress li.groups-members-search form input[type=text]{border:0;font-size:14px;font-size:.875rem;line-height:inherit}#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{border-left:1px solid rgba(190,190,190,.6);font-weight:400;padding:.2em .2em .2em 0}#buddypress div.dir-search form input[type=submit],#buddypress div.message-search form input[type=submit],#buddypress li.groups-members-search form input[type=submit]{border-radius:none;float:left;font-weight:400;padding:.2em 1em;text-align:center;text-transform:none;width:30%}#buddypress div.dir-search{margin-top:0}#buddypress #search-groups-form input[type=text],#buddypress #search-message-form input[type=text],#buddypress .dir-search #search-members-form input[type=text]{float:right;margin:0;width:70%}@media screen and (min-width:30em){#buddypress div.dir-search,#buddypress div.message-search,#buddypress li.groups-members-search{float:left;margin-bottom:5px!important}}@media screen and (min-width:67em){#buddypress .dir-search form input[type=text],#buddypress .message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{font-size:16px;font-size:1rem}#buddypress .dir-search form input[type=submit],#buddypress .message-search form input[type=submit],#buddypress li.groups-members-search form input[type=submit]{font-size:16px;font-size:1rem}}body.colors-dark #page #buddypress .dir-search form,body.colors-dark #page #buddypress .groups-members-search form,body.colors-dark #page #buddypress .message-search form{background:#333;border-color:#555;border-radius:2px;background-clip:padding-box;padding:1px}body.colors-dark #page #buddypress .dir-search input[type=text],body.colors-dark #page #buddypress .groups-members-search input[type=text],body.colors-dark #page #buddypress .message-search input[type=text]{background:0 0}body.colors-dark #page #buddypress .dir-search input[type=submit],body.colors-dark #page #buddypress .groups-members-search input[type=submit],body.colors-dark #page #buddypress .message-search input[type=submit]{border-radius:2px;background-clip:padding-box}body.colors-dark #page .message-search{margin-top:0}#buddypress table{font-size:14px;font-size:.875rem;margin:20px 0}#buddypress table tr th{background:#f7f7f7;border-color:#eaeaea;color:#333}#buddypress table p{margin-bottom:.5em}@media screen and (min-width:55em){#buddypress table{font-size:16px;font-size:1rem}}#buddypress .messages-notices th,#buddypress .notifications th{width:30%}#buddypress .messages-notices th.bulk-select-all,#buddypress .notifications th.bulk-select-all{text-align:center;width:10%}#buddypress .messages-notices .bulk-select-check,#buddypress .messages-notices .thread-star,#buddypress .notifications .bulk-select-check,#buddypress .notifications .thread-star{text-align:center}#buddypress .messages-notices .notification-actions,#buddypress .messages-notices td.thread-options,#buddypress .notifications .notification-actions,#buddypress .notifications td.thread-options{text-align:center}#buddypress .messages-notices .notification-actions a,#buddypress .messages-notices td.thread-options a,#buddypress .notifications .notification-actions a,#buddypress .notifications td.thread-options a{display:inline-block;margin:0;padding:0}#buddypress .messages-notices td .button,#buddypress .notifications td .button{border:0;display:block;padding:0;text-align:center}#buddypress .notifications .actions{text-align:center}#buddypress div#message p{font-size:18px;font-size:1.125rem;font-weight:700}#buddypress div#message.info p{background:#b0e5ff;border:1px solid #4ac3ff;color:#00547d}#buddypress div#message.updated p{background:#dee6b2;border:1px solid #becc66;color:#454d19}#buddypress .bp-avatar-status .warning,#buddypress .bp-cover-image-status .warning{background:#7dd4ff;border:1px solid #000;color:#333;font-size:16px;font-size:1rem}.delete-group #buddypress div#message.info p{background:#db7e7e;border:1px solid #be3535;color:#1f0808}#buddypress .acfb-holder li.friend-tab{background:#7dd4ff;border:inherit}
1
+ .buddypress div.clear{display:none}.buddypress ul.item-list h1,.buddypress ul.item-list h2,.buddypress ul.item-list h3,.buddypress ul.item-list h4,.buddypress ul.item-list h5,.buddypress ul.item-list h6{clear:none;padding:0}.buddypress #page a{box-shadow:none;text-decoration:none!important}.buddypress .entry-title{text-align:center}@media screen and (min-width:55em){.buddypress .entry-title{text-align:right}}@media screen and (min-width:55em){.buddypress.bp-user.page .site-content,.buddypress.groups.group-create .site-content,.buddypress.single-item.groups .site-content,.directory.buddypress.page-one-column .site-content{padding-top:40px}.buddypress.bp-user.page .entry-header,.buddypress.groups.group-create .entry-header,.buddypress.single-item.groups .entry-header,.directory.buddypress.page-one-column .entry-header{margin:10px 0}}@media screen and (min-width:48em){body.buddypress.page.page-two-column #primary .entry-header{width:30%}body.buddypress.page.page-two-column #primary .entry-content{width:68%}body.buddypress:not(.has-sidebar) #primary.content-area,body.buddypress:not(.page-two-column) #primary.content-area{max-width:100%;width:100%}body.buddypress:not(.has-sidebar) #primary.content-area .content-bottom-widgets,body.buddypress:not(.has-sidebar) #primary.content-area .entry-content,body.buddypress:not(.page-two-column) #primary.content-area .content-bottom-widgets,body.buddypress:not(.page-two-column) #primary.content-area .entry-content{margin-right:0;margin-left:0}body.buddypress:not(.has-sidebar) .sidebar,body.buddypress:not(.page-two-column) .sidebar{float:right;margin-right:75%;padding:0;width:25%}}body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.current,body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.selected{border-bottom-color:#222}body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.current a,body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.selected a{color:inherit}body.colors-dark #buddypress div.item-list-tabs ul li.current a,body.colors-dark #buddypress div.item-list-tabs ul li.selected a{background:0 0;color:inherit}body.colors-dark #buddypress #object-nav li:not(.current):focus a,body.colors-dark #buddypress #object-nav li:not(.current):hover a{color:#555}body.colors-dark #buddypress #subnav.item-list-tabs ul{border-bottom:1px solid rgba(234,234,234,.9);margin-bottom:20px}body.colors-dark #buddypress #subnav.item-list-tabs ul li.last{border-top:1px solid rgba(234,234,234,.9)}body.colors-dark #buddypress #subnav.item-list-tabs select option{background-color:#333}body.colors-dark #buddypress .item-list div.meta{color:#ddd}body.colors-dark #buddypress .item-list .acomment-meta,body.colors-dark #buddypress .item-list .activity-comments ul,body.colors-dark #buddypress .item-list .activity-header p,body.colors-dark #buddypress .item-list div.item-desc{color:#eee}body.colors-dark #buddypress .item-list .action a,body.colors-dark #buddypress .item-list .activity-meta a{background:#fafafa}body.colors-dark #buddypress .item-list .action a:focus,body.colors-dark #buddypress .item-list .action a:hover,body.colors-dark #buddypress .item-list .activity-meta a:focus,body.colors-dark #buddypress .item-list .activity-meta a:hover{background:#fff}body.colors-dark #buddypress #latest-update{color:#eee}body.colors-dark #buddypress div.pagination *{color:#ddd}body.colors-dark #buddypress #item-header .user-nicename{color:#eee}body.colors-dark #buddypress #item-body table thead th,body.colors-dark #buddypress #item-body table thead tr{background:0 0;color:#eee}body.colors-dark #buddypress #item-body table tr.alt td{background:0 0;color:#eee}body.colors-dark #buddypress #item-body table .field-visibility-settings,body.colors-dark #buddypress #item-body table .field-visibility-settings-notoggle{color:#eee}body.colors-dark #buddypress #item-body fieldset{background:0 0}body.colors-dark #buddypress #item-body .checkbox label,body.colors-dark #buddypress #item-body .radio label{color:#eee}body.colors-dark #buddypress #item-body div#invite-list{background:0 0}body.colors-dark.group-members #buddypress #subnav li{background:0 0}body.colors-dark.group-members #buddypress #subnav .groups-members-search form{margin-bottom:20px;margin-top:0}.directory.colors-dark #buddypress #subnav.item-list-tabs ul{border-bottom:0;border-top:0}.directory.colors-dark #buddypress #subnav.item-list-tabs ul li.last.filter{border-top:0}.directory.colors-dark #buddypress div.activity ul.item-list{border-top:0}body.colors-light #buddypress div.item-list-tabs ul{background-color:#fafafa}body.colors-light #buddypress div#subnav.item-list-tabs ul{background-color:#f7f7f7}body.colors-light #buddypress div#subnav.item-list-tabs ul li.last{background:#fff}body.colors-light #buddypress .item-list .activity-header p{background-color:#f7f7f7;color:#878787}body.colors-light #buddypress .item-list .activity-comments .acomment-meta{color:#737373}body.colors-light #buddypress #item-body .profile h2{background:#878787;color:#fff}body.colors-light #buddypress table tr.alt td{background:#f5f5f5;color:#333}body.colors-light #buddypress div#invite-list{background:#fafafa}#buddypress div.item-list-tabs ul li.selected a{background:inherit;opacity:1}#buddypress div.item-list-tabs ul{border-bottom:1px solid rgba(234,234,234,.9);overflow:hidden;padding:0}#buddypress div.item-list-tabs ul li a span{border-radius:25%}#buddypress #object-nav ul{overflow:hidden}#buddypress #object-nav ul li{float:none}@media screen and (max-width:38.75em){#buddypress #object-nav ul li:not(:last-child){border-bottom:1px solid #eaeaea}}@media screen and (max-width:38.75em){#buddypress #object-nav ul li:not(.selected):focus,#buddypress #object-nav ul li:not(.selected):hover{background:#f4f2df}}@media screen and (min-width:38.75em){#buddypress #object-nav ul li{float:right}}#buddypress div#subnav.item-list-tabs{margin-top:0}#buddypress div#subnav.item-list-tabs ul{border-bottom:0;margin-top:5px;padding:0}#buddypress div#subnav.item-list-tabs ul li.last{margin-top:0;padding:5px 0 5px 5px;width:100%}#buddypress div#subnav.item-list-tabs ul li.last select,#buddypress div#subnav.item-list-tabs ul li.last select:focus{background:0 0;border:0;outline:0}#buddypress div#subnav.item-list-tabs ul li.last label{display:inline}#buddypress div#subnav.item-list-tabs ul li.last label,#buddypress div#subnav.item-list-tabs ul li.last option,#buddypress div#subnav.item-list-tabs ul li.last select{font-size:14px;font-size:.875rem}#buddypress div#subnav.item-list-tabs ul li.last select{font-style:italic;height:auto}@media screen and (min-width:38.75em){#buddypress div#subnav.item-list-tabs ul li.last{text-align:left}}@media screen and (min-width:55em){body:not(.page-two-column) #buddypress #object-nav{border-left:1px solid #ddd;float:right;margin-left:-1px;width:200px}body:not(.page-two-column) #buddypress #object-nav ul{background:0 0;border-bottom:0;padding:0}body:not(.page-two-column) #buddypress #object-nav ul li{float:none;overflow:hidden}body:not(.page-two-column) #buddypress #object-nav ul li span{background:#fff;border-radius:10%;float:left;margin-left:2px}body:not(.page-two-column) #buddypress #item-body{border-right:1px solid #ddd;overflow:hidden;padding:0 20px 0 0;width:auto}body:not(.page-two-column) #buddypress #item-body #subnav{margin:0 -20px 0 0}body:not(.page-two-column) #buddypress #item-body #subnav ul{margin-top:0}}@media screen and (min-width:48em){#buddypress #group-create-tabs.item-list-tabs ul:after,#buddypress #group-create-tabs.item-list-tabs ul:before{content:" ";display:table}#buddypress #group-create-tabs.item-list-tabs ul:after{clear:both}#buddypress #group-create-tabs.item-list-tabs ul{background:0 0;border:0;border-bottom:1px solid #ddd;overflow:visible;padding-bottom:0}#buddypress #group-create-tabs.item-list-tabs ul li{float:right;width:auto}#buddypress #group-create-tabs.item-list-tabs ul li.current,#buddypress #group-create-tabs.item-list-tabs ul li.selected{border:1px solid #ddd;border-bottom-color:#fff;border-top-left-radius:4px;border-top-right-radius:4px;background-clip:padding-box;margin-bottom:-1px}#buddypress #group-create-tabs.item-list-tabs ul li.current a,#buddypress #group-create-tabs.item-list-tabs ul li.selected a{background:0 0;color:#333;outline:0}#buddypress #subnav ul{border-bottom:0}}#buddypress div.pagination{box-shadow:none;font-weight:400;min-height:0}#buddypress div.pagination:after,#buddypress div.pagination:before{height:0;width:0}#buddypress div.pagination .pag-count{margin-right:0}#buddypress div.pagination .pagination-links{margin-left:0}#buddypress div.pagination .pagination-links a,#buddypress div.pagination .pagination-links span{height:auto;line-height:1;padding:5px}#buddypress div.pagination .pagination-links .next,#buddypress div.pagination .pagination-links .prev{background-color:transparent;color:inherit;overflow:visible;width:auto}#buddypress div.pagination .pagination-links .next:before,#buddypress div.pagination .pagination-links .prev:before{display:none}#buddypress div.pagination .pagination-links .prev{right:auto;position:static}#buddypress div.pagination .pagination-links .next{position:static;left:auto}#buddypress .item-list .activity-header,#buddypress .item-list .activity-meta{font-family:"Libre Franklin","Helvetica Neue",helvetica,arial,sans-serif}#buddypress .activity-meta .button:focus,#buddypress .activity-meta .button:hover{background:inherit;color:#000}#buddypress .action .generic-button a:focus,#buddypress .action .generic-button a:hover{background:inherit;color:#000}#buddypress ul.item-list li{overflow:hidden!important}#buddypress ul.item-list li .item-avatar{margin-bottom:10px;text-align:center}@media screen and (min-width:38.75em){#buddypress ul.item-list li .item-avatar{margin-bottom:0}}#buddypress ul.item-list li .item-avatar a{border-bottom:0}#buddypress ul.item-list li .item-avatar img.avatar{display:inline-block;float:none;margin-bottom:10px}@media screen and (min-width:30em){#buddypress ul.item-list li .item-avatar img.avatar{display:block;float:right}}#buddypress ul.item-list li .item{overflow:hidden}@media screen and (min-width:48em){#buddypress ul.item-list li .item{margin-right:15%}}#buddypress ul.item-list li .item span.activity{font-style:italic}#buddypress ul.item-list li .item .item-desc{margin-right:0;width:94%}#buddypress ul.item-list li .item .item-title{font-size:18px;font-size:1.125rem;line-height:1.2;text-align:center;width:100%}@media screen and (min-width:30em){#buddypress ul.item-list li .item .item-title{text-align:right}}#buddypress ul.item-list li .item .item-title .update{display:block;font-size:13px;font-size:.8125rem;padding:10px 0;text-align:right}@media screen and (min-width:55em){#buddypress ul.item-list li .item .item-title .update{font-size:14px;font-size:.875rem}}@media screen and (min-width:55em){#buddypress ul.item-list li .action,#buddypress ul.item-list li .item,#buddypress ul.item-list li .item-avatar{float:right}#buddypress ul.item-list li .item{right:5%;margin-right:0;position:relative;width:55%}#buddypress ul.item-list li .item .item-title{font-size:22px;font-size:1.375rem}}#buddypress ul.item-list li div.action{clear:right;float:none;margin-bottom:-20px;margin-right:0;padding:20px 0 5px;position:relative;text-align:right;top:0}@media screen and (min-width:55em){#buddypress ul.item-list li div.action{clear:none;float:left;margin-bottom:0;padding:0}}#buddypress ul.item-list li div.action div{display:inline-block;margin:10px 0;width:100%}#buddypress ul.item-list li div.action div a{display:block;width:100%}@media screen and (min-width:30em){#buddypress ul.item-list li div.action div{margin:0 0 10px 10px;width:auto}}@media screen and (min-width:55em){#buddypress ul.item-list li div.action div{clear:left;float:left;margin:0 0 10px 0}}#buddypress ul.item-list li div.action .meta{font-style:italic}#buddypress form#whats-new-form p.activity-greeting{line-height:1.4}@media screen and (max-width:46.25em){#buddypress form#whats-new-form #whats-new-content{clear:right;margin:10px 0 20px;padding:10px 0 0}}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box{border:1px solid rgba(190,190,190,.5);float:right;line-height:1.5;margin-top:12px;padding-right:.2em;width:100%}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box select{background:0 0;border:0;float:left;margin:0;min-height:1.5em;padding-right:.4em}@media screen and (min-width:30em){#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box{width:auto}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-submit{float:left}}#buddypress #item-body form#whats-new-form{margin:40px 0}#buddypress #activity-stream li{padding:25px 0 15px}#buddypress #activity-stream li .activity-avatar{float:none;text-align:center}#buddypress #activity-stream li .activity-avatar a{display:inline-block}#buddypress #activity-stream li .activity-avatar a img.avatar{display:inline;float:none;height:60px;margin-bottom:20px;margin-right:0;width:60px}#buddypress #activity-stream li .activity-content{margin-right:0}#buddypress #activity-stream li .activity-content .activity-header{font-size:14px;font-size:.875rem}#buddypress #activity-stream li .activity-content .activity-header a{color:#0075c4}@media screen and (min-width:48em){#buddypress #activity-stream li .activity-avatar{float:right;margin-left:10px;text-align:right}#buddypress #activity-stream li .activity-avatar a{border-bottom:0}#buddypress #activity-stream li .activity-content{margin:0;overflow:hidden}#buddypress #activity-stream li .activity-content .activity-header{font-size:16px;font-size:1rem}}#buddypress #activity-stream li.mini .activity-avatar a img.avatar{height:30px;margin-right:15px;width:30px}#buddypress #activity-stream li.mini .activity-content .activity-header{font-size:14px;font-size:.875rem}#buddypress #activity-stream .activity-content{margin-top:-12px}#buddypress #activity-stream .activity-content .activity-header{margin-left:0}#buddypress #activity-stream .activity-content .activity-header p{border:1px solid rgba(234,234,234,.6);margin-top:0;padding:0 .2em}#buddypress #activity-stream .activity-content .activity-header img.avatar{box-shadow:none;display:inline-block;margin:0 5px!important;vertical-align:middle}#buddypress #activity-stream .activity-content .activity-meta a{display:block;margin-bottom:5px}@media screen and (min-width:30em){#buddypress #activity-stream .activity-content .activity-meta a{display:inline-block;margin-bottom:0;width:auto}}#buddypress #activity-stream .load-more{background:#f7f7f7;border:1px solid transparent;padding:10px}#buddypress #activity-stream .load-more:focus,#buddypress #activity-stream .load-more:hover{background:#f4f4f4;border:1px solid rgba(159,209,226,.3)}#buddypress #activity-stream .load-more:focus a,#buddypress #activity-stream .load-more:hover a{font-style:italic}#buddypress #activity-stream .load-more a{display:block}.activity-permalink #buddypress #activity-stream li.activity-item{padding:20px}.activity-permalink #buddypress #activity-stream li.mini .activity-header{font-size:16px;font-size:1rem;margin-bottom:40px}@media screen and (min-width:48em){.activity-permalink #buddypress #activity-stream li.mini .activity-header{font-size:20px;font-size:1.25rem}}.activity-permalink #buddypress #activity-stream li.mini .activity-header p{padding:20px}#buddypress #activity-stream .activity-comments{border-right:1px solid #eaeaea;margin:20px 0 20px}@media screen and (min-width:30em){#buddypress #activity-stream .activity-comments{margin-right:20px}}#buddypress #activity-stream .activity-comments ul{margin:15px 2px 0 0}#buddypress #activity-stream .activity-comments ul li{border-top:1px solid #bebebe}#buddypress #activity-stream .activity-comments ul a{color:#0077c7}#buddypress #activity-stream .activity-comments .acomment-meta{border-bottom:1px solid #eaeaea}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel,#buddypress #activity-stream .activity-comments .ac-form input[type=submit]{color:rgba(51,51,51,.8);display:inline-block;font-family:inherit;font-size:12px;font-size:.75rem;font-weight:400;line-height:1.2;padding:4px 10px;text-transform:lowercase;width:100px}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel{border:1px solid rgba(190,190,190,.7);text-align:center}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel:focus,#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel:hover{background:#ededed}@media screen and (min-width:55em){#buddypress #members-list li .item,#buddypress #members-list li .item-avatar{float:right}#buddypress #members-list li .action{float:left}#buddypress #members-list li.is-current-user .item{float:none;right:0;padding-right:5%;width:auto}}#buddypress #signup_form.standard-form #basic-details-section,#buddypress #signup_form.standard-form #blog-details-section,#buddypress #signup_form.standard-form #profile-details-section{float:none;width:100%}@media screen and (min-width:38.75em){#buddypress #signup_form.standard-form #basic-details-section,#buddypress #signup_form.standard-form #blog-details-section,#buddypress #signup_form.standard-form #profile-details-section{width:48%}}@media screen and (min-width:30em){#buddypress #signup_form.standard-form #profile-details-section{float:left}#buddypress #signup_form.standard-form #basic-details-section{float:right}}@media screen and (min-width:48em){.bp-user.page-two-column #buddypress #cover-image-container #item-header-cover-image #item-header-content{margin-right:140px;margin-top:-100px}.single-item.groups.page-two-column #buddypress #cover-image-container #item-header-cover-image #item-header-content{margin-right:10px}}.bp-user #buddypress #item-header-cover-image .user-nicename,.single-item.groups #buddypress #item-header-cover-image .user-nicename{color:#333;text-shadow:none}@media screen and (min-width:48em){.bp-user #buddypress #item-header-cover-image .user-nicename,.single-item.groups #buddypress #item-header-cover-image .user-nicename{color:#fff;text-shadow:0 0 3px rgba(0,0,0,.8)}}.bp-user #buddypress #item-header-content #item-meta,.single-item.groups #buddypress #item-header-content #item-meta{font-size:14px;font-size:.875rem;text-align:right}.bp-user #buddypress #item-header-content #item-meta p,.single-item.groups #buddypress #item-header-content #item-meta p{margin-bottom:.5em}@media screen and (max-width:46.25em){.bp-user main header.entry-header,.single-item.groups main header.entry-header{padding-bottom:1rem}}@media screen and (max-width:38.75em){.bp-user #item-header-content,.bp-user h1,.single-item.groups #item-header-content,.single-item.groups h1{text-align:center}}@media screen and (max-width:46.25em){.bp-user #buddypress #item-header .generic-button,.single-item.groups #buddypress #item-header .generic-button{float:none;margin:1.5em 0 0}}@media screen and (max-width:38.75em){.bp-user #buddypress h1,.single-item.groups #buddypress h1{margin-bottom:0}.bp-user #buddypress #item-header-avatar img.avatar,.single-item.groups #buddypress #item-header-avatar img.avatar{margin-left:0}.bp-user #buddypress #item-header-content,.single-item.groups #buddypress #item-header-content{width:100%}}@media screen and (max-width:46.25em){.single-item.groups #buddypress #item-header #item-meta{margin-bottom:20px}}@media screen and (max-width:38.75em){.single-item.groups #buddypress div#item-header{display:flex;flex-direction:column}.single-item.groups #buddypress div#item-header #item-header-avatar{order:1;text-align:center}.single-item.groups #buddypress div#item-header #item-header-avatar a img{display:inline-block;float:none}.single-item.groups #buddypress div#item-header #item-header-content{order:2}.single-item.groups #buddypress div#item-header #item-actions{order:3}.single-item.groups #buddypress div#item-header #item-actions h2{border-bottom:1px solid #eaeaea;text-align:center}}.single-item.groups #buddypress div#item-header{padding-bottom:40px}.single-item.groups #buddypress div#item-header div#item-actions{margin:0;width:100%}@media screen and (min-width:38.75em){.single-item.groups #buddypress div#item-header div#item-actions{border-right:1px solid #eaeaea;clear:none;float:left;padding-right:.2em;width:30%}}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header div#item-actions{width:40%}}.single-item.groups #buddypress div#item-header div#item-actions ul{margin-top:0;padding-right:0}.single-item.groups #buddypress div#item-header div#item-actions h2{font-size:14px;font-size:.875rem;padding:.2em}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header div#item-actions h2{font-size:16px;font-size:1rem}}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header #item-header-avatar,.single-item.groups #buddypress div#item-header #item-header-content{float:right}.single-item.groups #buddypress div#item-header #item-header-avatar{width:21%}.single-item.groups #buddypress div#item-header #item-header-content{margin-right:4%;width:40%}.single-item.groups #buddypress div#item-header div#item-actions{float:left;width:28%}}.bp-user #buddypress #item-header{padding:20px 0}.bp-user #buddypress #item-header #item-header-avatar{text-align:center;width:100%}.bp-user #buddypress #item-header #item-header-avatar a,.bp-user #buddypress #item-header #item-header-avatar img.avatar{display:inline-block;float:none}@media screen and (min-width:48em){.bp-user #buddypress #item-header #item-header-avatar{float:right;width:20%}.bp-user #buddypress #item-header #item-header-avatar a{float:right}.bp-user #buddypress #item-header #item-header-content{float:left;margin-left:5%;width:69%}}.groups.single-item.members #buddypress #subnav.item-list-tabs ul{background:0 0;border-top:0}.groups #group-settings-form h3{background:#555;color:#fff;padding:.2em}.groups.edit-details #group-settings-form label{margin-bottom:0;padding:.2em;width:80%}.groups.edit-details #group-settings-form textarea+p label{background:0 0;color:inherit;font-size:14px;font-size:.875rem;width:auto}.groups.edit-details #group-settings-form textarea{height:auto;min-height:100px;overflow:auto}.groups.group-settings #group-settings-form div.radio label{border:1px solid #eaeaea;padding:.2em}.groups.group-settings #group-settings-form div.radio label ul{color:rgba(51,51,51,.6);font-size:14px;font-size:.875rem}.groups.group-avatar form>p{margin-top:20px}.groups.manage-members #group-settings-form .item-list li{border-bottom:1px solid #eaeaea}.groups.manage-members #group-settings-form .item-list li h5,.groups.manage-members #group-settings-form .item-list li img{float:right}.groups.manage-members #group-settings-form .item-list li h5>a,.groups.manage-members #group-settings-form .item-list li img>a{border-bottom:0}.groups.manage-members #group-settings-form .item-list li span.small{clear:right;display:block;float:none;margin-top:10px}.groups.manage-members #group-settings-form .item-list li span.small a{display:inline-block;margin:5px 0;width:100%}@media screen and (min-width:38.75em){.groups.manage-members #group-settings-form .item-list li span.small a{width:auto}}.groups.manage-members #group-settings-form .item-list li h5{margin:0}.groups.group-members #subnav li{width:100%}@media screen and (max-width:38.75em){.groups.group-members #subnav li{background:#fff;padding:20px 0}}.groups.group-members #subnav li #search-members-form{float:left;margin:5px 0 0}@media screen and (max-width:38.75em){.groups.group-members #subnav li #search-members-form{margin:0;width:100%}.groups.group-members #subnav li #search-members-form label input[type=text]{width:100%}}.bp-user .entry-title{margin-bottom:.5em}.bp-user #buddypress table th{font-size:14px;font-size:.875rem}.bp-user #buddypress table td{font-size:12px;font-size:.75rem}.bp-user #buddypress table a{color:#0074c2}@media screen and (min-width:55em){.bp-user #buddypress table th{font-size:16px;font-size:1rem}.bp-user #buddypress table td{font-size:14px;font-size:.875rem}}@media screen and (min-width:67em){.bp-user #buddypress table th{font-size:18px;font-size:1.125rem}.bp-user #buddypress table td{font-size:16px;font-size:1rem}}.bp-user #buddypress .pag-count{font-style:italic}.bp-user #buddypress .messages-options-nav,.bp-user #buddypress .notifications-options-nav{float:right;width:100%}@media screen and (min-width:38.75em){.bp-user #buddypress .messages-options-nav,.bp-user #buddypress .notifications-options-nav{width:300px}}.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav select{height:auto}.bp-user #buddypress .messages-options-nav input,.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav input,.bp-user #buddypress .notifications-options-nav select{font-size:14px;font-size:.875rem;outline:0;padding:0}.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav select{float:right;margin-left:1%;width:59%}.bp-user #buddypress .messages-options-nav input,.bp-user #buddypress .notifications-options-nav input{float:left;font-family:inherit;line-height:20px;width:40%}.bp-user #buddypress .messages-options-nav input[disabled=disabled]:focus,.bp-user #buddypress .messages-options-nav input[disabled=disabled]:hover,.bp-user #buddypress .notifications-options-nav input[disabled=disabled]:focus,.bp-user #buddypress .notifications-options-nav input[disabled=disabled]:hover{background:0 0}.bp-user #buddypress .profile h2{margin:40px 0 10px;padding:.1em .4em .1em 0}.bp-user #buddypress .profile table{margin-top:0}.bp-user #buddypress .profile .profile-fields tr.alt td{color:#333}.bp-user #buddypress .profile .profile-fields tr:last-child{border-bottom:0}.bp-user #buddypress .profile #profile-edit-form .button-nav:after,.bp-user #buddypress .profile #profile-edit-form .button-nav:before{content:" ";display:table}.bp-user #buddypress .profile #profile-edit-form .button-nav:after{clear:both}.bp-user #buddypress .profile #profile-edit-form ul.button-nav{border-bottom:1px solid #eaeaea;margin-right:0}.bp-user #buddypress .profile #profile-edit-form ul.button-nav li{float:right;margin-bottom:0}.bp-user #buddypress .profile #profile-edit-form ul.button-nav li.current{border:1px solid #eaeaea;border-bottom-color:#fff;margin-bottom:-1px}.bp-user #buddypress .profile #profile-edit-form ul.button-nav a{background:0 0;border:0;font-size:18px;font-size:1.125rem}.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings,.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-notoggle,.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-toggle{font-size:14px;font-size:.875rem;margin-top:10px}.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-close,.bp-user #buddypress .profile #profile-edit-form .visibility-toggle-link{background:#555;border-radius:3px;background-clip:padding-box;color:#fff;padding:.2em .5em}.bp-user #buddypress .profile .bp-avatar #bp-delete-avatar a{font-size:inherit}@media screen and (min-width:77.5em){.bp-user #buddypress #groups-list li .item{right:5%;width:50%}}.bp-user #buddypress #message-thread a{border-bottom:0}.bp-user #buddypress #message-thread #message-subject{background:#6f6e6e;color:#fff;padding:.3em .2em .3em 0}.bp-user #buddypress #message-thread #message-recipients{font-style:italic}.bp-user #buddypress #message-thread #message-recipients a.confirm{border:1px solid #eaeaea;font-style:normal}.bp-user #buddypress #message-thread .message-metadata:after{clear:both;content:"";display:table}.bp-user #buddypress #message-thread .message-metadata img.avatar{float:none}@media screen and (min-width:48em){.bp-user #buddypress #message-thread .message-metadata img.avatar{float:right}}.bp-user #buddypress #message-thread .message-metadata .message-star-actions{float:left;margin-left:5px;position:static}.bp-user #buddypress #message-thread .message-content{background:#f7f7f7;border:1px solid #eaeaea;margin:10px 0 0 0;padding:.3em}.bp-user #buddypress #message-thread #send-reply .message-content{background:#fff;border:0}.bp-user #buddypress #message-thread .alt{background:#fff}.bp-user #buddypress #message-threads thead tr{background:0 0;border-bottom:1px solid #bebebe}.bp-user #buddypress #message-threads thead tr th{background:#555}.bp-user #buddypress #message-threads tr{border-bottom:5px solid #878787}.bp-user #buddypress #message-threads tr td{display:inline-block;float:right}.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{border-bottom-color:#bebebe;border-bottom-width:1px;height:2.4em;padding-bottom:.2em;padding-top:.2em}@media screen and (max-width:46.25em){.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{padding-top:0}}.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from,.bp-user #buddypress #message-threads tr td.thread-info,.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{border-top:0}.bp-user #buddypress #message-threads tr td.thread-star{vertical-align:middle}.bp-user #buddypress #message-threads tr td.thread-star .message-action-star{line-height:1.2}.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from{height:3em}@media screen and (max-width:38.75em){.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from{height:5.2em}}.bp-user #buddypress #message-threads tr td.thread-from,.bp-user #buddypress #message-threads tr td.thread-options{border-right:0!important;width:calc(100% - 30px);margin-right:0}.bp-user #buddypress #message-threads tr td.thread-info{padding-right:41px;width:100%}.bp-user #buddypress #message-threads tr td.thread-options{text-align:left}.bp-user #buddypress #message-threads tr td.thread-options a{font-size:12px;font-size:.75rem;line-height:2.2}.bp-user #buddypress #message-threads tr span.from{display:none}.bp-user #buddypress #message-threads tr span.activity{display:block;float:left;line-height:2}@media screen and (max-width:38.75em){.bp-user #buddypress #message-threads tr span.activity{clear:both;font-size:11px;font-size:.6875rem;width:100%}}.bp-user #buddypress #message-threads tr.unread td{background:0 0;border-color:#bebebe}.bp-user #buddypress #message-threads th{display:none}.bp-user #buddypress #message-threads th.bulk-select-all{border-bottom:0;display:inline-block;text-align:right}.bp-user #buddypress #message-threads td.bulk-select-check,.bp-user #buddypress #message-threads td.thread-star,.bp-user #buddypress #message-threads th.bulk-select-all{border-left:0;width:30px}.bp-user #buddypress .acfb-holder{list-style:none}.bp-user #buddypress .acfb-holder li{margin-right:0}.bp-user #buddypress .acfb-holder li.friend-tab{background:#e3f6ff;border:inherit;margin-left:0;padding:.5em}.bp-user #buddypress .acfb-holder li.friend-tab span.p{padding-right:10px}.bp-user #buddypress .acfb-holder li.friend-tab span.p:focus,.bp-user #buddypress .acfb-holder li.friend-tab span.p:hover{color:#c82b2b;cursor:pointer}.bp-user #buddypress .acfb-holder li.friend-tab a{border-bottom:0;text-decoration:none}.bp-user #buddypress .acfb-holder li.friend-tab a img{display:inline;height:20px;vertical-align:middle;width:20px!important}.bp-user #buddypress #message-threads.sitewide-notices td{width:100%}.bp-user #buddypress #message-threads.sitewide-notices td strong{background:#6f6e6e;color:#fff;display:block;margin-bottom:.4em;padding-right:.2em}.bp-user #buddypress #message-threads.sitewide-notices td a{display:inline-block}.bp-user #buddypress #message-threads.sitewide-notices td:first-child{display:none}.bp-user #buddypress #message-threads.sitewide-notices td:nth-child(2) strong{margin:-8px -8px 8px}.bp-user #buddypress #message-threads.sitewide-notices td:first-child+td+td{border-bottom:0}.bp-user #buddypress #message-threads.sitewide-notices td:first-child+td+td span{line-height:1}.bp-user #buddypress #message-threads.sitewide-notices td:last-child{border-bottom-color:#b7b7b7;line-height:1;text-align:left}.bp-user #buddypress #message-threads.sitewide-notices td:last-child a:last-child:after{content:attr(title);display:block;line-height:initial;text-indent:0}.bp-user .ac_results{background:#eee;padding-right:10px}.bp-user .ac_results ul{margin:0}.bp-user .ac_results li{margin:10px 0}.bp-user .ac_results li:focus,.bp-user .ac_results li:hover{cursor:pointer}.bp-user #buddypress #settings-form>p{font-size:20px;font-size:1.25rem;margin:20px 0 10px}.bp-user #buddypress table.notification-settings td.no,.bp-user #buddypress table.notification-settings td.yes{vertical-align:middle}.bp-user #buddypress table.profile-settings{width:100%}.bp-user #buddypress table.profile-settings td.field-name,.bp-user #buddypress table.profile-settings th.field-group-name{width:50%}@media screen and (min-width:48em){.bp-user #buddypress table.profile-settings td.field-name,.bp-user #buddypress table.profile-settings th.field-group-name{width:70%}}.bp-user #buddypress table.profile-settings td.field-visibility,.bp-user #buddypress table.profile-settings th.title{width:30%}.bp-user #buddypress table.profile-settings td.field-visibility select{width:100%}#main #buddypress .standard-form li{float:none}#main #buddypress .standard-form input[type=email],#main #buddypress .standard-form input[type=password],#main #buddypress .standard-form input[type=text],#main #buddypress .standard-form textarea{width:100%}#buddypress div.activity-comments form .ac-textarea{background:#f7f7f7;border:1px solid rgba(190,190,190,.5)}#buddypress div.activity-comments form .ac-textarea textarea{background:0 0;border:0}#buddypress select{height:auto}#buddypress .standard-form button,#buddypress .standard-form input[type=email],#buddypress .standard-form input[type=password],#buddypress .standard-form input[type=text],#buddypress .standard-form select,#buddypress .standard-form textarea{border-color:rgba(190,190,190,.5);border-width:1px}#buddypress .standard-form select{color:#737373}#buddypress #signup_form.standard-form div.submit{float:none}#buddypress #signup_form.standard-form div.submit input{margin-left:0}#buddypress div.dir-search,#buddypress div.message-search,#buddypress li.groups-members-search{float:none;margin:10px 0}#buddypress div.dir-search form,#buddypress div.message-search form,#buddypress li.groups-members-search form{border:1px solid rgba(190,190,190,.6);position:relative;border-radius:2px;background-clip:padding-box;overflow:hidden}#buddypress div.dir-search form label,#buddypress div.message-search form label,#buddypress li.groups-members-search form label{float:right;margin:0;width:70%}#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{float:right;margin:0;width:100%}#buddypress div.dir-search form input[type=submit],#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=submit],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=submit],#buddypress li.groups-members-search form input[type=text]{border:0;font-size:14px;font-size:.875rem;line-height:inherit}#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{border-left:1px solid rgba(190,190,190,.6);font-weight:400;padding:.2em .2em .2em 0}#buddypress div.dir-search form input[type=submit],#buddypress div.message-search form input[type=submit],#buddypress li.groups-members-search form input[type=submit]{border-radius:0;float:left;font-weight:400;padding:.2em 1em;text-align:center;text-transform:none;width:30%}#buddypress div.dir-search{margin-top:0}#buddypress #search-groups-form input[type=text],#buddypress #search-message-form input[type=text],#buddypress .dir-search #search-members-form input[type=text]{float:right;margin:0;width:70%}@media screen and (min-width:30em){#buddypress div.dir-search,#buddypress div.message-search,#buddypress li.groups-members-search{float:left;margin-bottom:5px!important}}@media screen and (min-width:67em){#buddypress .dir-search form input[type=text],#buddypress .message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{font-size:16px;font-size:1rem}#buddypress .dir-search form input[type=submit],#buddypress .message-search form input[type=submit],#buddypress li.groups-members-search form input[type=submit]{font-size:16px;font-size:1rem}}body.colors-dark #page #buddypress .dir-search form,body.colors-dark #page #buddypress .groups-members-search form,body.colors-dark #page #buddypress .message-search form{background:#333;border-color:#555;border-radius:2px;background-clip:padding-box;padding:1px}body.colors-dark #page #buddypress .dir-search input[type=text],body.colors-dark #page #buddypress .groups-members-search input[type=text],body.colors-dark #page #buddypress .message-search input[type=text]{background:0 0}body.colors-dark #page #buddypress .dir-search input[type=submit],body.colors-dark #page #buddypress .groups-members-search input[type=submit],body.colors-dark #page #buddypress .message-search input[type=submit]{border-radius:2px;background-clip:padding-box}body.colors-dark #page .message-search{margin-top:0}#buddypress table{font-size:14px;font-size:.875rem;margin:20px 0}#buddypress table tr th{background:#f7f7f7;border-color:#eaeaea;color:#333}#buddypress table p{margin-bottom:.5em}@media screen and (min-width:55em){#buddypress table{font-size:16px;font-size:1rem}}#buddypress .messages-notices th,#buddypress .notifications th{width:30%}#buddypress .messages-notices th.bulk-select-all,#buddypress .notifications th.bulk-select-all{text-align:center;width:10%}#buddypress .messages-notices .bulk-select-check,#buddypress .messages-notices .thread-star,#buddypress .notifications .bulk-select-check,#buddypress .notifications .thread-star{text-align:center}#buddypress .messages-notices .notification-actions,#buddypress .messages-notices td.thread-options,#buddypress .notifications .notification-actions,#buddypress .notifications td.thread-options{text-align:center}#buddypress .messages-notices .notification-actions a,#buddypress .messages-notices td.thread-options a,#buddypress .notifications .notification-actions a,#buddypress .notifications td.thread-options a{display:inline-block;margin:0;padding:0}#buddypress .messages-notices td .button,#buddypress .notifications td .button{border:0;display:block;padding:0;text-align:center}#buddypress .notifications .actions{text-align:center}#buddypress div#message p{font-size:18px;font-size:1.125rem;font-weight:700}#buddypress div#message.info p{background:#b0e5ff;border:1px solid #4ac3ff;color:#00547d}#buddypress div#message.updated p{background:#dee6b2;border:1px solid #becc66;color:#454d19}#buddypress .bp-avatar-status .warning,#buddypress .bp-cover-image-status .warning{background:#7dd4ff;border:1px solid #000;color:#333;font-size:16px;font-size:1rem}.delete-group #buddypress div#message.info p{background:#db7e7e;border:1px solid #be3535;color:#1f0808}#buddypress .acfb-holder li.friend-tab{background:#7dd4ff;border:inherit}
bp-templates/bp-legacy/css/twentyseventeen.css CHANGED
@@ -1976,7 +1976,7 @@ body.colors-light #buddypress div#invite-list {
1976
  #buddypress div.dir-search form input[type="submit"],
1977
  #buddypress div.message-search form input[type="submit"],
1978
  #buddypress li.groups-members-search form input[type="submit"] {
1979
- border-radius: none;
1980
  float: right;
1981
  font-weight: 400;
1982
  padding: 0.2em 1em;
1976
  #buddypress div.dir-search form input[type="submit"],
1977
  #buddypress div.message-search form input[type="submit"],
1978
  #buddypress li.groups-members-search form input[type="submit"] {
1979
+ border-radius: 0;
1980
  float: right;
1981
  font-weight: 400;
1982
  padding: 0.2em 1em;
bp-templates/bp-legacy/css/twentyseventeen.min.css CHANGED
@@ -1 +1 @@
1
- .buddypress div.clear{display:none}.buddypress ul.item-list h1,.buddypress ul.item-list h2,.buddypress ul.item-list h3,.buddypress ul.item-list h4,.buddypress ul.item-list h5,.buddypress ul.item-list h6{clear:none;padding:0}.buddypress #page a{box-shadow:none;text-decoration:none!important}.buddypress .entry-title{text-align:center}@media screen and (min-width:55em){.buddypress .entry-title{text-align:left}}@media screen and (min-width:55em){.buddypress.bp-user.page .site-content,.buddypress.groups.group-create .site-content,.buddypress.single-item.groups .site-content,.directory.buddypress.page-one-column .site-content{padding-top:40px}.buddypress.bp-user.page .entry-header,.buddypress.groups.group-create .entry-header,.buddypress.single-item.groups .entry-header,.directory.buddypress.page-one-column .entry-header{margin:10px 0}}@media screen and (min-width:48em){body.buddypress.page.page-two-column #primary .entry-header{width:30%}body.buddypress.page.page-two-column #primary .entry-content{width:68%}body.buddypress:not(.has-sidebar) #primary.content-area,body.buddypress:not(.page-two-column) #primary.content-area{max-width:100%;width:100%}body.buddypress:not(.has-sidebar) #primary.content-area .content-bottom-widgets,body.buddypress:not(.has-sidebar) #primary.content-area .entry-content,body.buddypress:not(.page-two-column) #primary.content-area .content-bottom-widgets,body.buddypress:not(.page-two-column) #primary.content-area .entry-content{margin-left:0;margin-right:0}body.buddypress:not(.has-sidebar) .sidebar,body.buddypress:not(.page-two-column) .sidebar{float:left;margin-left:75%;padding:0;width:25%}}body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.current,body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.selected{border-bottom-color:#222}body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.current a,body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.selected a{color:inherit}body.colors-dark #buddypress div.item-list-tabs ul li.current a,body.colors-dark #buddypress div.item-list-tabs ul li.selected a{background:0 0;color:inherit}body.colors-dark #buddypress #object-nav li:not(.current):focus a,body.colors-dark #buddypress #object-nav li:not(.current):hover a{color:#555}body.colors-dark #buddypress #subnav.item-list-tabs ul{border-bottom:1px solid rgba(234,234,234,.9);margin-bottom:20px}body.colors-dark #buddypress #subnav.item-list-tabs ul li.last{border-top:1px solid rgba(234,234,234,.9)}body.colors-dark #buddypress #subnav.item-list-tabs select option{background-color:#333}body.colors-dark #buddypress .item-list div.meta{color:#ddd}body.colors-dark #buddypress .item-list .acomment-meta,body.colors-dark #buddypress .item-list .activity-comments ul,body.colors-dark #buddypress .item-list .activity-header p,body.colors-dark #buddypress .item-list div.item-desc{color:#eee}body.colors-dark #buddypress .item-list .action a,body.colors-dark #buddypress .item-list .activity-meta a{background:#fafafa}body.colors-dark #buddypress .item-list .action a:focus,body.colors-dark #buddypress .item-list .action a:hover,body.colors-dark #buddypress .item-list .activity-meta a:focus,body.colors-dark #buddypress .item-list .activity-meta a:hover{background:#fff}body.colors-dark #buddypress #latest-update{color:#eee}body.colors-dark #buddypress div.pagination *{color:#ddd}body.colors-dark #buddypress #item-header .user-nicename{color:#eee}body.colors-dark #buddypress #item-body table thead th,body.colors-dark #buddypress #item-body table thead tr{background:0 0;color:#eee}body.colors-dark #buddypress #item-body table tr.alt td{background:0 0;color:#eee}body.colors-dark #buddypress #item-body table .field-visibility-settings,body.colors-dark #buddypress #item-body table .field-visibility-settings-notoggle{color:#eee}body.colors-dark #buddypress #item-body fieldset{background:0 0}body.colors-dark #buddypress #item-body .checkbox label,body.colors-dark #buddypress #item-body .radio label{color:#eee}body.colors-dark #buddypress #item-body div#invite-list{background:0 0}body.colors-dark.group-members #buddypress #subnav li{background:0 0}body.colors-dark.group-members #buddypress #subnav .groups-members-search form{margin-bottom:20px;margin-top:0}.directory.colors-dark #buddypress #subnav.item-list-tabs ul{border-bottom:0;border-top:0}.directory.colors-dark #buddypress #subnav.item-list-tabs ul li.last.filter{border-top:0}.directory.colors-dark #buddypress div.activity ul.item-list{border-top:0}body.colors-light #buddypress div.item-list-tabs ul{background-color:#fafafa}body.colors-light #buddypress div#subnav.item-list-tabs ul{background-color:#f7f7f7}body.colors-light #buddypress div#subnav.item-list-tabs ul li.last{background:#fff}body.colors-light #buddypress .item-list .activity-header p{background-color:#f7f7f7;color:#878787}body.colors-light #buddypress .item-list .activity-comments .acomment-meta{color:#737373}body.colors-light #buddypress #item-body .profile h2{background:#878787;color:#fff}body.colors-light #buddypress table tr.alt td{background:#f5f5f5;color:#333}body.colors-light #buddypress div#invite-list{background:#fafafa}#buddypress div.item-list-tabs ul li.selected a{background:inherit;opacity:1}#buddypress div.item-list-tabs ul{border-bottom:1px solid rgba(234,234,234,.9);overflow:hidden;padding:0}#buddypress div.item-list-tabs ul li a span{border-radius:25%}#buddypress #object-nav ul{overflow:hidden}#buddypress #object-nav ul li{float:none}@media screen and (max-width:38.75em){#buddypress #object-nav ul li:not(:last-child){border-bottom:1px solid #eaeaea}}@media screen and (max-width:38.75em){#buddypress #object-nav ul li:not(.selected):focus,#buddypress #object-nav ul li:not(.selected):hover{background:#f4f2df}}@media screen and (min-width:38.75em){#buddypress #object-nav ul li{float:left}}#buddypress div#subnav.item-list-tabs{margin-top:0}#buddypress div#subnav.item-list-tabs ul{border-bottom:0;margin-top:5px;padding:0}#buddypress div#subnav.item-list-tabs ul li.last{margin-top:0;padding:5px 5px 5px 0;width:100%}#buddypress div#subnav.item-list-tabs ul li.last select,#buddypress div#subnav.item-list-tabs ul li.last select:focus{background:0 0;border:0;outline:0}#buddypress div#subnav.item-list-tabs ul li.last label{display:inline}#buddypress div#subnav.item-list-tabs ul li.last label,#buddypress div#subnav.item-list-tabs ul li.last option,#buddypress div#subnav.item-list-tabs ul li.last select{font-size:14px;font-size:.875rem}#buddypress div#subnav.item-list-tabs ul li.last select{font-style:italic;height:auto}@media screen and (min-width:38.75em){#buddypress div#subnav.item-list-tabs ul li.last{text-align:right}}@media screen and (min-width:55em){body:not(.page-two-column) #buddypress #object-nav{border-right:1px solid #ddd;float:left;margin-right:-1px;width:200px}body:not(.page-two-column) #buddypress #object-nav ul{background:0 0;border-bottom:0;padding:0}body:not(.page-two-column) #buddypress #object-nav ul li{float:none;overflow:hidden}body:not(.page-two-column) #buddypress #object-nav ul li span{background:#fff;border-radius:10%;float:right;margin-right:2px}body:not(.page-two-column) #buddypress #item-body{border-left:1px solid #ddd;overflow:hidden;padding:0 0 0 20px;width:auto}body:not(.page-two-column) #buddypress #item-body #subnav{margin:0 0 0 -20px}body:not(.page-two-column) #buddypress #item-body #subnav ul{margin-top:0}}@media screen and (min-width:48em){#buddypress #group-create-tabs.item-list-tabs ul:after,#buddypress #group-create-tabs.item-list-tabs ul:before{content:" ";display:table}#buddypress #group-create-tabs.item-list-tabs ul:after{clear:both}#buddypress #group-create-tabs.item-list-tabs ul{background:0 0;border:0;border-bottom:1px solid #ddd;overflow:visible;padding-bottom:0}#buddypress #group-create-tabs.item-list-tabs ul li{float:left;width:auto}#buddypress #group-create-tabs.item-list-tabs ul li.current,#buddypress #group-create-tabs.item-list-tabs ul li.selected{border:1px solid #ddd;border-bottom-color:#fff;border-top-right-radius:4px;border-top-left-radius:4px;background-clip:padding-box;margin-bottom:-1px}#buddypress #group-create-tabs.item-list-tabs ul li.current a,#buddypress #group-create-tabs.item-list-tabs ul li.selected a{background:0 0;color:#333;outline:0}#buddypress #subnav ul{border-bottom:0}}#buddypress div.pagination{box-shadow:none;font-weight:400;min-height:0}#buddypress div.pagination:after,#buddypress div.pagination:before{height:0;width:0}#buddypress div.pagination .pag-count{margin-left:0}#buddypress div.pagination .pagination-links{margin-right:0}#buddypress div.pagination .pagination-links a,#buddypress div.pagination .pagination-links span{height:auto;line-height:1;padding:5px}#buddypress div.pagination .pagination-links .next,#buddypress div.pagination .pagination-links .prev{background-color:transparent;color:inherit;overflow:visible;width:auto}#buddypress div.pagination .pagination-links .next:before,#buddypress div.pagination .pagination-links .prev:before{display:none}#buddypress div.pagination .pagination-links .prev{left:auto;position:static}#buddypress div.pagination .pagination-links .next{position:static;right:auto}#buddypress .item-list .activity-header,#buddypress .item-list .activity-meta{font-family:"Libre Franklin","Helvetica Neue",helvetica,arial,sans-serif}#buddypress .activity-meta .button:focus,#buddypress .activity-meta .button:hover{background:inherit;color:#000}#buddypress .action .generic-button a:focus,#buddypress .action .generic-button a:hover{background:inherit;color:#000}#buddypress ul.item-list li{overflow:hidden!important}#buddypress ul.item-list li .item-avatar{margin-bottom:10px;text-align:center}@media screen and (min-width:38.75em){#buddypress ul.item-list li .item-avatar{margin-bottom:0}}#buddypress ul.item-list li .item-avatar a{border-bottom:0}#buddypress ul.item-list li .item-avatar img.avatar{display:inline-block;float:none;margin-bottom:10px}@media screen and (min-width:30em){#buddypress ul.item-list li .item-avatar img.avatar{display:block;float:left}}#buddypress ul.item-list li .item{overflow:hidden}@media screen and (min-width:48em){#buddypress ul.item-list li .item{margin-left:15%}}#buddypress ul.item-list li .item span.activity{font-style:italic}#buddypress ul.item-list li .item .item-desc{margin-left:0;width:94%}#buddypress ul.item-list li .item .item-title{font-size:18px;font-size:1.125rem;line-height:1.2;text-align:center;width:100%}@media screen and (min-width:30em){#buddypress ul.item-list li .item .item-title{text-align:left}}#buddypress ul.item-list li .item .item-title .update{display:block;font-size:13px;font-size:.8125rem;padding:10px 0;text-align:left}@media screen and (min-width:55em){#buddypress ul.item-list li .item .item-title .update{font-size:14px;font-size:.875rem}}@media screen and (min-width:55em){#buddypress ul.item-list li .action,#buddypress ul.item-list li .item,#buddypress ul.item-list li .item-avatar{float:left}#buddypress ul.item-list li .item{left:5%;margin-left:0;position:relative;width:55%}#buddypress ul.item-list li .item .item-title{font-size:22px;font-size:1.375rem}}#buddypress ul.item-list li div.action{clear:left;float:none;margin-bottom:-20px;margin-left:0;padding:20px 0 5px;position:relative;text-align:left;top:0}@media screen and (min-width:55em){#buddypress ul.item-list li div.action{clear:none;float:right;margin-bottom:0;padding:0}}#buddypress ul.item-list li div.action div{display:inline-block;margin:10px 0;width:100%}#buddypress ul.item-list li div.action div a{display:block;width:100%}@media screen and (min-width:30em){#buddypress ul.item-list li div.action div{margin:0 10px 10px 0;width:auto}}@media screen and (min-width:55em){#buddypress ul.item-list li div.action div{clear:right;float:right;margin:0 0 10px 0}}#buddypress ul.item-list li div.action .meta{font-style:italic}#buddypress form#whats-new-form p.activity-greeting{line-height:1.4}@media screen and (max-width:46.25em){#buddypress form#whats-new-form #whats-new-content{clear:left;margin:10px 0 20px;padding:10px 0 0}}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box{border:1px solid rgba(190,190,190,.5);float:left;line-height:1.5;margin-top:12px;padding-left:.2em;width:100%}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box select{background:0 0;border:0;float:right;margin:0;min-height:1.5em;padding-left:.4em}@media screen and (min-width:30em){#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box{width:auto}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-submit{float:right}}#buddypress #item-body form#whats-new-form{margin:40px 0}#buddypress #activity-stream li{padding:25px 0 15px}#buddypress #activity-stream li .activity-avatar{float:none;text-align:center}#buddypress #activity-stream li .activity-avatar a{display:inline-block}#buddypress #activity-stream li .activity-avatar a img.avatar{display:inline;float:none;height:60px;margin-bottom:20px;margin-left:0;width:60px}#buddypress #activity-stream li .activity-content{margin-left:0}#buddypress #activity-stream li .activity-content .activity-header{font-size:14px;font-size:.875rem}#buddypress #activity-stream li .activity-content .activity-header a{color:#0075c4}@media screen and (min-width:48em){#buddypress #activity-stream li .activity-avatar{float:left;margin-right:10px;text-align:left}#buddypress #activity-stream li .activity-avatar a{border-bottom:0}#buddypress #activity-stream li .activity-content{margin:0;overflow:hidden}#buddypress #activity-stream li .activity-content .activity-header{font-size:16px;font-size:1rem}}#buddypress #activity-stream li.mini .activity-avatar a img.avatar{height:30px;margin-left:15px;width:30px}#buddypress #activity-stream li.mini .activity-content .activity-header{font-size:14px;font-size:.875rem}#buddypress #activity-stream .activity-content{margin-top:-12px}#buddypress #activity-stream .activity-content .activity-header{margin-right:0}#buddypress #activity-stream .activity-content .activity-header p{border:1px solid rgba(234,234,234,.6);margin-top:0;padding:0 .2em}#buddypress #activity-stream .activity-content .activity-header img.avatar{box-shadow:none;display:inline-block;margin:0 5px!important;vertical-align:middle}#buddypress #activity-stream .activity-content .activity-meta a{display:block;margin-bottom:5px}@media screen and (min-width:30em){#buddypress #activity-stream .activity-content .activity-meta a{display:inline-block;margin-bottom:0;width:auto}}#buddypress #activity-stream .load-more{background:#f7f7f7;border:1px solid transparent;padding:10px}#buddypress #activity-stream .load-more:focus,#buddypress #activity-stream .load-more:hover{background:#f4f4f4;border:1px solid rgba(159,209,226,.3)}#buddypress #activity-stream .load-more:focus a,#buddypress #activity-stream .load-more:hover a{font-style:italic}#buddypress #activity-stream .load-more a{display:block}.activity-permalink #buddypress #activity-stream li.activity-item{padding:20px}.activity-permalink #buddypress #activity-stream li.mini .activity-header{font-size:16px;font-size:1rem;margin-bottom:40px}@media screen and (min-width:48em){.activity-permalink #buddypress #activity-stream li.mini .activity-header{font-size:20px;font-size:1.25rem}}.activity-permalink #buddypress #activity-stream li.mini .activity-header p{padding:20px}#buddypress #activity-stream .activity-comments{border-left:1px solid #eaeaea;margin:20px 0 20px}@media screen and (min-width:30em){#buddypress #activity-stream .activity-comments{margin-left:20px}}#buddypress #activity-stream .activity-comments ul{margin:15px 0 0 2px}#buddypress #activity-stream .activity-comments ul li{border-top:1px solid #bebebe}#buddypress #activity-stream .activity-comments ul a{color:#0077c7}#buddypress #activity-stream .activity-comments .acomment-meta{border-bottom:1px solid #eaeaea}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel,#buddypress #activity-stream .activity-comments .ac-form input[type=submit]{color:rgba(51,51,51,.8);display:inline-block;font-family:inherit;font-size:12px;font-size:.75rem;font-weight:400;line-height:1.2;padding:4px 10px;text-transform:lowercase;width:100px}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel{border:1px solid rgba(190,190,190,.7);text-align:center}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel:focus,#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel:hover{background:#ededed}@media screen and (min-width:55em){#buddypress #members-list li .item,#buddypress #members-list li .item-avatar{float:left}#buddypress #members-list li .action{float:right}#buddypress #members-list li.is-current-user .item{float:none;left:0;padding-left:5%;width:auto}}#buddypress #signup_form.standard-form #basic-details-section,#buddypress #signup_form.standard-form #blog-details-section,#buddypress #signup_form.standard-form #profile-details-section{float:none;width:100%}@media screen and (min-width:38.75em){#buddypress #signup_form.standard-form #basic-details-section,#buddypress #signup_form.standard-form #blog-details-section,#buddypress #signup_form.standard-form #profile-details-section{width:48%}}@media screen and (min-width:30em){#buddypress #signup_form.standard-form #profile-details-section{float:right}#buddypress #signup_form.standard-form #basic-details-section{float:left}}@media screen and (min-width:48em){.bp-user.page-two-column #buddypress #cover-image-container #item-header-cover-image #item-header-content{margin-left:140px;margin-top:-100px}.single-item.groups.page-two-column #buddypress #cover-image-container #item-header-cover-image #item-header-content{margin-left:10px}}.bp-user #buddypress #item-header-cover-image .user-nicename,.single-item.groups #buddypress #item-header-cover-image .user-nicename{color:#333;text-shadow:none}@media screen and (min-width:48em){.bp-user #buddypress #item-header-cover-image .user-nicename,.single-item.groups #buddypress #item-header-cover-image .user-nicename{color:#fff;text-shadow:0 0 3px rgba(0,0,0,.8)}}.bp-user #buddypress #item-header-content #item-meta,.single-item.groups #buddypress #item-header-content #item-meta{font-size:14px;font-size:.875rem;text-align:left}.bp-user #buddypress #item-header-content #item-meta p,.single-item.groups #buddypress #item-header-content #item-meta p{margin-bottom:.5em}@media screen and (max-width:46.25em){.bp-user main header.entry-header,.single-item.groups main header.entry-header{padding-bottom:1rem}}@media screen and (max-width:38.75em){.bp-user #item-header-content,.bp-user h1,.single-item.groups #item-header-content,.single-item.groups h1{text-align:center}}@media screen and (max-width:46.25em){.bp-user #buddypress #item-header .generic-button,.single-item.groups #buddypress #item-header .generic-button{float:none;margin:1.5em 0 0}}@media screen and (max-width:38.75em){.bp-user #buddypress h1,.single-item.groups #buddypress h1{margin-bottom:0}.bp-user #buddypress #item-header-avatar img.avatar,.single-item.groups #buddypress #item-header-avatar img.avatar{margin-right:0}.bp-user #buddypress #item-header-content,.single-item.groups #buddypress #item-header-content{width:100%}}@media screen and (max-width:46.25em){.single-item.groups #buddypress #item-header #item-meta{margin-bottom:20px}}@media screen and (max-width:38.75em){.single-item.groups #buddypress div#item-header{display:flex;flex-direction:column}.single-item.groups #buddypress div#item-header #item-header-avatar{order:1;text-align:center}.single-item.groups #buddypress div#item-header #item-header-avatar a img{display:inline-block;float:none}.single-item.groups #buddypress div#item-header #item-header-content{order:2}.single-item.groups #buddypress div#item-header #item-actions{order:3}.single-item.groups #buddypress div#item-header #item-actions h2{border-bottom:1px solid #eaeaea;text-align:center}}.single-item.groups #buddypress div#item-header{padding-bottom:40px}.single-item.groups #buddypress div#item-header div#item-actions{margin:0;width:100%}@media screen and (min-width:38.75em){.single-item.groups #buddypress div#item-header div#item-actions{border-left:1px solid #eaeaea;clear:none;float:right;padding-left:.2em;width:30%}}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header div#item-actions{width:40%}}.single-item.groups #buddypress div#item-header div#item-actions ul{margin-top:0;padding-left:0}.single-item.groups #buddypress div#item-header div#item-actions h2{font-size:14px;font-size:.875rem;padding:.2em}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header div#item-actions h2{font-size:16px;font-size:1rem}}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header #item-header-avatar,.single-item.groups #buddypress div#item-header #item-header-content{float:left}.single-item.groups #buddypress div#item-header #item-header-avatar{width:21%}.single-item.groups #buddypress div#item-header #item-header-content{margin-left:4%;width:40%}.single-item.groups #buddypress div#item-header div#item-actions{float:right;width:28%}}.bp-user #buddypress #item-header{padding:20px 0}.bp-user #buddypress #item-header #item-header-avatar{text-align:center;width:100%}.bp-user #buddypress #item-header #item-header-avatar a,.bp-user #buddypress #item-header #item-header-avatar img.avatar{display:inline-block;float:none}@media screen and (min-width:48em){.bp-user #buddypress #item-header #item-header-avatar{float:left;width:20%}.bp-user #buddypress #item-header #item-header-avatar a{float:left}.bp-user #buddypress #item-header #item-header-content{float:right;margin-right:5%;width:69%}}.groups.single-item.members #buddypress #subnav.item-list-tabs ul{background:0 0;border-top:0}.groups #group-settings-form h3{background:#555;color:#fff;padding:.2em}.groups.edit-details #group-settings-form label{margin-bottom:0;padding:.2em;width:80%}.groups.edit-details #group-settings-form textarea+p label{background:0 0;color:inherit;font-size:14px;font-size:.875rem;width:auto}.groups.edit-details #group-settings-form textarea{height:auto;min-height:100px;overflow:auto}.groups.group-settings #group-settings-form div.radio label{border:1px solid #eaeaea;padding:.2em}.groups.group-settings #group-settings-form div.radio label ul{color:rgba(51,51,51,.6);font-size:14px;font-size:.875rem}.groups.group-avatar form>p{margin-top:20px}.groups.manage-members #group-settings-form .item-list li{border-bottom:1px solid #eaeaea}.groups.manage-members #group-settings-form .item-list li h5,.groups.manage-members #group-settings-form .item-list li img{float:left}.groups.manage-members #group-settings-form .item-list li h5>a,.groups.manage-members #group-settings-form .item-list li img>a{border-bottom:0}.groups.manage-members #group-settings-form .item-list li span.small{clear:left;display:block;float:none;margin-top:10px}.groups.manage-members #group-settings-form .item-list li span.small a{display:inline-block;margin:5px 0;width:100%}@media screen and (min-width:38.75em){.groups.manage-members #group-settings-form .item-list li span.small a{width:auto}}.groups.manage-members #group-settings-form .item-list li h5{margin:0}.groups.group-members #subnav li{width:100%}@media screen and (max-width:38.75em){.groups.group-members #subnav li{background:#fff;padding:20px 0}}.groups.group-members #subnav li #search-members-form{float:right;margin:5px 0 0}@media screen and (max-width:38.75em){.groups.group-members #subnav li #search-members-form{margin:0;width:100%}.groups.group-members #subnav li #search-members-form label input[type=text]{width:100%}}.bp-user .entry-title{margin-bottom:.5em}.bp-user #buddypress table th{font-size:14px;font-size:.875rem}.bp-user #buddypress table td{font-size:12px;font-size:.75rem}.bp-user #buddypress table a{color:#0074c2}@media screen and (min-width:55em){.bp-user #buddypress table th{font-size:16px;font-size:1rem}.bp-user #buddypress table td{font-size:14px;font-size:.875rem}}@media screen and (min-width:67em){.bp-user #buddypress table th{font-size:18px;font-size:1.125rem}.bp-user #buddypress table td{font-size:16px;font-size:1rem}}.bp-user #buddypress .pag-count{font-style:italic}.bp-user #buddypress .messages-options-nav,.bp-user #buddypress .notifications-options-nav{float:left;width:100%}@media screen and (min-width:38.75em){.bp-user #buddypress .messages-options-nav,.bp-user #buddypress .notifications-options-nav{width:300px}}.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav select{height:auto}.bp-user #buddypress .messages-options-nav input,.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav input,.bp-user #buddypress .notifications-options-nav select{font-size:14px;font-size:.875rem;outline:0;padding:0}.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav select{float:left;margin-right:1%;width:59%}.bp-user #buddypress .messages-options-nav input,.bp-user #buddypress .notifications-options-nav input{float:right;font-family:inherit;line-height:20px;width:40%}.bp-user #buddypress .messages-options-nav input[disabled=disabled]:focus,.bp-user #buddypress .messages-options-nav input[disabled=disabled]:hover,.bp-user #buddypress .notifications-options-nav input[disabled=disabled]:focus,.bp-user #buddypress .notifications-options-nav input[disabled=disabled]:hover{background:0 0}.bp-user #buddypress .profile h2{margin:40px 0 10px;padding:.1em 0 .1em .4em}.bp-user #buddypress .profile table{margin-top:0}.bp-user #buddypress .profile .profile-fields tr.alt td{color:#333}.bp-user #buddypress .profile .profile-fields tr:last-child{border-bottom:0}.bp-user #buddypress .profile #profile-edit-form .button-nav:after,.bp-user #buddypress .profile #profile-edit-form .button-nav:before{content:" ";display:table}.bp-user #buddypress .profile #profile-edit-form .button-nav:after{clear:both}.bp-user #buddypress .profile #profile-edit-form ul.button-nav{border-bottom:1px solid #eaeaea;margin-left:0}.bp-user #buddypress .profile #profile-edit-form ul.button-nav li{float:left;margin-bottom:0}.bp-user #buddypress .profile #profile-edit-form ul.button-nav li.current{border:1px solid #eaeaea;border-bottom-color:#fff;margin-bottom:-1px}.bp-user #buddypress .profile #profile-edit-form ul.button-nav a{background:0 0;border:0;font-size:18px;font-size:1.125rem}.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings,.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-notoggle,.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-toggle{font-size:14px;font-size:.875rem;margin-top:10px}.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-close,.bp-user #buddypress .profile #profile-edit-form .visibility-toggle-link{background:#555;border-radius:3px;background-clip:padding-box;color:#fff;padding:.2em .5em}.bp-user #buddypress .profile .bp-avatar #bp-delete-avatar a{font-size:inherit}@media screen and (min-width:77.5em){.bp-user #buddypress #groups-list li .item{left:5%;width:50%}}.bp-user #buddypress #message-thread a{border-bottom:0}.bp-user #buddypress #message-thread #message-subject{background:#6f6e6e;color:#fff;padding:.3em 0 .3em .2em}.bp-user #buddypress #message-thread #message-recipients{font-style:italic}.bp-user #buddypress #message-thread #message-recipients a.confirm{border:1px solid #eaeaea;font-style:normal}.bp-user #buddypress #message-thread .message-metadata:after{clear:both;content:"";display:table}.bp-user #buddypress #message-thread .message-metadata img.avatar{float:none}@media screen and (min-width:48em){.bp-user #buddypress #message-thread .message-metadata img.avatar{float:left}}.bp-user #buddypress #message-thread .message-metadata .message-star-actions{float:right;margin-right:5px;position:static}.bp-user #buddypress #message-thread .message-content{background:#f7f7f7;border:1px solid #eaeaea;margin:10px 0 0 0;padding:.3em}.bp-user #buddypress #message-thread #send-reply .message-content{background:#fff;border:0}.bp-user #buddypress #message-thread .alt{background:#fff}.bp-user #buddypress #message-threads thead tr{background:0 0;border-bottom:1px solid #bebebe}.bp-user #buddypress #message-threads thead tr th{background:#555}.bp-user #buddypress #message-threads tr{border-bottom:5px solid #878787}.bp-user #buddypress #message-threads tr td{display:inline-block;float:left}.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{border-bottom-color:#bebebe;border-bottom-width:1px;height:2.4em;padding-bottom:.2em;padding-top:.2em}@media screen and (max-width:46.25em){.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{padding-top:0}}.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from,.bp-user #buddypress #message-threads tr td.thread-info,.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{border-top:0}.bp-user #buddypress #message-threads tr td.thread-star{vertical-align:middle}.bp-user #buddypress #message-threads tr td.thread-star .message-action-star{line-height:1.2}.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from{height:3em}@media screen and (max-width:38.75em){.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from{height:5.2em}}.bp-user #buddypress #message-threads tr td.thread-from,.bp-user #buddypress #message-threads tr td.thread-options{border-left:0!important;width:calc(100% - 30px);margin-left:0}.bp-user #buddypress #message-threads tr td.thread-info{padding-left:41px;width:100%}.bp-user #buddypress #message-threads tr td.thread-options{text-align:right}.bp-user #buddypress #message-threads tr td.thread-options a{font-size:12px;font-size:.75rem;line-height:2.2}.bp-user #buddypress #message-threads tr span.from{display:none}.bp-user #buddypress #message-threads tr span.activity{display:block;float:right;line-height:2}@media screen and (max-width:38.75em){.bp-user #buddypress #message-threads tr span.activity{clear:both;font-size:11px;font-size:.6875rem;width:100%}}.bp-user #buddypress #message-threads tr.unread td{background:0 0;border-color:#bebebe}.bp-user #buddypress #message-threads th{display:none}.bp-user #buddypress #message-threads th.bulk-select-all{border-bottom:0;display:inline-block;text-align:left}.bp-user #buddypress #message-threads td.bulk-select-check,.bp-user #buddypress #message-threads td.thread-star,.bp-user #buddypress #message-threads th.bulk-select-all{border-right:0;width:30px}.bp-user #buddypress .acfb-holder{list-style:none}.bp-user #buddypress .acfb-holder li{margin-left:0}.bp-user #buddypress .acfb-holder li.friend-tab{background:#e3f6ff;border:inherit;margin-right:0;padding:.5em}.bp-user #buddypress .acfb-holder li.friend-tab span.p{padding-left:10px}.bp-user #buddypress .acfb-holder li.friend-tab span.p:focus,.bp-user #buddypress .acfb-holder li.friend-tab span.p:hover{color:#c82b2b;cursor:pointer}.bp-user #buddypress .acfb-holder li.friend-tab a{border-bottom:0;text-decoration:none}.bp-user #buddypress .acfb-holder li.friend-tab a img{display:inline;height:20px;vertical-align:middle;width:20px!important}.bp-user #buddypress #message-threads.sitewide-notices td{width:100%}.bp-user #buddypress #message-threads.sitewide-notices td strong{background:#6f6e6e;color:#fff;display:block;margin-bottom:.4em;padding-left:.2em}.bp-user #buddypress #message-threads.sitewide-notices td a{display:inline-block}.bp-user #buddypress #message-threads.sitewide-notices td:first-child{display:none}.bp-user #buddypress #message-threads.sitewide-notices td:nth-child(2) strong{margin:-8px -8px 8px}.bp-user #buddypress #message-threads.sitewide-notices td:first-child+td+td{border-bottom:0}.bp-user #buddypress #message-threads.sitewide-notices td:first-child+td+td span{line-height:1}.bp-user #buddypress #message-threads.sitewide-notices td:last-child{border-bottom-color:#b7b7b7;line-height:1;text-align:right}.bp-user #buddypress #message-threads.sitewide-notices td:last-child a:last-child:after{content:attr(title);display:block;line-height:initial;text-indent:0}.bp-user .ac_results{background:#eee;padding-left:10px}.bp-user .ac_results ul{margin:0}.bp-user .ac_results li{margin:10px 0}.bp-user .ac_results li:focus,.bp-user .ac_results li:hover{cursor:pointer}.bp-user #buddypress #settings-form>p{font-size:20px;font-size:1.25rem;margin:20px 0 10px}.bp-user #buddypress table.notification-settings td.no,.bp-user #buddypress table.notification-settings td.yes{vertical-align:middle}.bp-user #buddypress table.profile-settings{width:100%}.bp-user #buddypress table.profile-settings td.field-name,.bp-user #buddypress table.profile-settings th.field-group-name{width:50%}@media screen and (min-width:48em){.bp-user #buddypress table.profile-settings td.field-name,.bp-user #buddypress table.profile-settings th.field-group-name{width:70%}}.bp-user #buddypress table.profile-settings td.field-visibility,.bp-user #buddypress table.profile-settings th.title{width:30%}.bp-user #buddypress table.profile-settings td.field-visibility select{width:100%}#main #buddypress .standard-form li{float:none}#main #buddypress .standard-form input[type=email],#main #buddypress .standard-form input[type=password],#main #buddypress .standard-form input[type=text],#main #buddypress .standard-form textarea{width:100%}#buddypress div.activity-comments form .ac-textarea{background:#f7f7f7;border:1px solid rgba(190,190,190,.5)}#buddypress div.activity-comments form .ac-textarea textarea{background:0 0;border:0}#buddypress select{height:auto}#buddypress .standard-form button,#buddypress .standard-form input[type=email],#buddypress .standard-form input[type=password],#buddypress .standard-form input[type=text],#buddypress .standard-form select,#buddypress .standard-form textarea{border-color:rgba(190,190,190,.5);border-width:1px}#buddypress .standard-form select{color:#737373}#buddypress #signup_form.standard-form div.submit{float:none}#buddypress #signup_form.standard-form div.submit input{margin-right:0}#buddypress div.dir-search,#buddypress div.message-search,#buddypress li.groups-members-search{float:none;margin:10px 0}#buddypress div.dir-search form,#buddypress div.message-search form,#buddypress li.groups-members-search form{border:1px solid rgba(190,190,190,.6);position:relative;border-radius:2px;background-clip:padding-box;overflow:hidden}#buddypress div.dir-search form label,#buddypress div.message-search form label,#buddypress li.groups-members-search form label{float:left;margin:0;width:70%}#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{float:left;margin:0;width:100%}#buddypress div.dir-search form input[type=submit],#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=submit],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=submit],#buddypress li.groups-members-search form input[type=text]{border:0;font-size:14px;font-size:.875rem;line-height:inherit}#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{border-right:1px solid rgba(190,190,190,.6);font-weight:400;padding:.2em 0 .2em .2em}#buddypress div.dir-search form input[type=submit],#buddypress div.message-search form input[type=submit],#buddypress li.groups-members-search form input[type=submit]{border-radius:none;float:right;font-weight:400;padding:.2em 1em;text-align:center;text-transform:none;width:30%}#buddypress div.dir-search{margin-top:0}#buddypress #search-groups-form input[type=text],#buddypress #search-message-form input[type=text],#buddypress .dir-search #search-members-form input[type=text]{float:left;margin:0;width:70%}@media screen and (min-width:30em){#buddypress div.dir-search,#buddypress div.message-search,#buddypress li.groups-members-search{float:right;margin-bottom:5px!important}}@media screen and (min-width:67em){#buddypress .dir-search form input[type=text],#buddypress .message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{font-size:16px;font-size:1rem}#buddypress .dir-search form input[type=submit],#buddypress .message-search form input[type=submit],#buddypress li.groups-members-search form input[type=submit]{font-size:16px;font-size:1rem}}body.colors-dark #page #buddypress .dir-search form,body.colors-dark #page #buddypress .groups-members-search form,body.colors-dark #page #buddypress .message-search form{background:#333;border-color:#555;border-radius:2px;background-clip:padding-box;padding:1px}body.colors-dark #page #buddypress .dir-search input[type=text],body.colors-dark #page #buddypress .groups-members-search input[type=text],body.colors-dark #page #buddypress .message-search input[type=text]{background:0 0}body.colors-dark #page #buddypress .dir-search input[type=submit],body.colors-dark #page #buddypress .groups-members-search input[type=submit],body.colors-dark #page #buddypress .message-search input[type=submit]{border-radius:2px;background-clip:padding-box}body.colors-dark #page .message-search{margin-top:0}#buddypress table{font-size:14px;font-size:.875rem;margin:20px 0}#buddypress table tr th{background:#f7f7f7;border-color:#eaeaea;color:#333}#buddypress table p{margin-bottom:.5em}@media screen and (min-width:55em){#buddypress table{font-size:16px;font-size:1rem}}#buddypress .messages-notices th,#buddypress .notifications th{width:30%}#buddypress .messages-notices th.bulk-select-all,#buddypress .notifications th.bulk-select-all{text-align:center;width:10%}#buddypress .messages-notices .bulk-select-check,#buddypress .messages-notices .thread-star,#buddypress .notifications .bulk-select-check,#buddypress .notifications .thread-star{text-align:center}#buddypress .messages-notices .notification-actions,#buddypress .messages-notices td.thread-options,#buddypress .notifications .notification-actions,#buddypress .notifications td.thread-options{text-align:center}#buddypress .messages-notices .notification-actions a,#buddypress .messages-notices td.thread-options a,#buddypress .notifications .notification-actions a,#buddypress .notifications td.thread-options a{display:inline-block;margin:0;padding:0}#buddypress .messages-notices td .button,#buddypress .notifications td .button{border:0;display:block;padding:0;text-align:center}#buddypress .notifications .actions{text-align:center}#buddypress div#message p{font-size:18px;font-size:1.125rem;font-weight:700}#buddypress div#message.info p{background:#b0e5ff;border:1px solid #4ac3ff;color:#00547d}#buddypress div#message.updated p{background:#dee6b2;border:1px solid #becc66;color:#454d19}#buddypress .bp-avatar-status .warning,#buddypress .bp-cover-image-status .warning{background:#7dd4ff;border:1px solid #000;color:#333;font-size:16px;font-size:1rem}.delete-group #buddypress div#message.info p{background:#db7e7e;border:1px solid #be3535;color:#1f0808}#buddypress .acfb-holder li.friend-tab{background:#7dd4ff;border:inherit}
1
+ .buddypress div.clear{display:none}.buddypress ul.item-list h1,.buddypress ul.item-list h2,.buddypress ul.item-list h3,.buddypress ul.item-list h4,.buddypress ul.item-list h5,.buddypress ul.item-list h6{clear:none;padding:0}.buddypress #page a{box-shadow:none;text-decoration:none!important}.buddypress .entry-title{text-align:center}@media screen and (min-width:55em){.buddypress .entry-title{text-align:left}}@media screen and (min-width:55em){.buddypress.bp-user.page .site-content,.buddypress.groups.group-create .site-content,.buddypress.single-item.groups .site-content,.directory.buddypress.page-one-column .site-content{padding-top:40px}.buddypress.bp-user.page .entry-header,.buddypress.groups.group-create .entry-header,.buddypress.single-item.groups .entry-header,.directory.buddypress.page-one-column .entry-header{margin:10px 0}}@media screen and (min-width:48em){body.buddypress.page.page-two-column #primary .entry-header{width:30%}body.buddypress.page.page-two-column #primary .entry-content{width:68%}body.buddypress:not(.has-sidebar) #primary.content-area,body.buddypress:not(.page-two-column) #primary.content-area{max-width:100%;width:100%}body.buddypress:not(.has-sidebar) #primary.content-area .content-bottom-widgets,body.buddypress:not(.has-sidebar) #primary.content-area .entry-content,body.buddypress:not(.page-two-column) #primary.content-area .content-bottom-widgets,body.buddypress:not(.page-two-column) #primary.content-area .entry-content{margin-left:0;margin-right:0}body.buddypress:not(.has-sidebar) .sidebar,body.buddypress:not(.page-two-column) .sidebar{float:left;margin-left:75%;padding:0;width:25%}}body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.current,body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.selected{border-bottom-color:#222}body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.current a,body.colors-dark #buddypress #group-create-tabs.item-list-tabs li.selected a{color:inherit}body.colors-dark #buddypress div.item-list-tabs ul li.current a,body.colors-dark #buddypress div.item-list-tabs ul li.selected a{background:0 0;color:inherit}body.colors-dark #buddypress #object-nav li:not(.current):focus a,body.colors-dark #buddypress #object-nav li:not(.current):hover a{color:#555}body.colors-dark #buddypress #subnav.item-list-tabs ul{border-bottom:1px solid rgba(234,234,234,.9);margin-bottom:20px}body.colors-dark #buddypress #subnav.item-list-tabs ul li.last{border-top:1px solid rgba(234,234,234,.9)}body.colors-dark #buddypress #subnav.item-list-tabs select option{background-color:#333}body.colors-dark #buddypress .item-list div.meta{color:#ddd}body.colors-dark #buddypress .item-list .acomment-meta,body.colors-dark #buddypress .item-list .activity-comments ul,body.colors-dark #buddypress .item-list .activity-header p,body.colors-dark #buddypress .item-list div.item-desc{color:#eee}body.colors-dark #buddypress .item-list .action a,body.colors-dark #buddypress .item-list .activity-meta a{background:#fafafa}body.colors-dark #buddypress .item-list .action a:focus,body.colors-dark #buddypress .item-list .action a:hover,body.colors-dark #buddypress .item-list .activity-meta a:focus,body.colors-dark #buddypress .item-list .activity-meta a:hover{background:#fff}body.colors-dark #buddypress #latest-update{color:#eee}body.colors-dark #buddypress div.pagination *{color:#ddd}body.colors-dark #buddypress #item-header .user-nicename{color:#eee}body.colors-dark #buddypress #item-body table thead th,body.colors-dark #buddypress #item-body table thead tr{background:0 0;color:#eee}body.colors-dark #buddypress #item-body table tr.alt td{background:0 0;color:#eee}body.colors-dark #buddypress #item-body table .field-visibility-settings,body.colors-dark #buddypress #item-body table .field-visibility-settings-notoggle{color:#eee}body.colors-dark #buddypress #item-body fieldset{background:0 0}body.colors-dark #buddypress #item-body .checkbox label,body.colors-dark #buddypress #item-body .radio label{color:#eee}body.colors-dark #buddypress #item-body div#invite-list{background:0 0}body.colors-dark.group-members #buddypress #subnav li{background:0 0}body.colors-dark.group-members #buddypress #subnav .groups-members-search form{margin-bottom:20px;margin-top:0}.directory.colors-dark #buddypress #subnav.item-list-tabs ul{border-bottom:0;border-top:0}.directory.colors-dark #buddypress #subnav.item-list-tabs ul li.last.filter{border-top:0}.directory.colors-dark #buddypress div.activity ul.item-list{border-top:0}body.colors-light #buddypress div.item-list-tabs ul{background-color:#fafafa}body.colors-light #buddypress div#subnav.item-list-tabs ul{background-color:#f7f7f7}body.colors-light #buddypress div#subnav.item-list-tabs ul li.last{background:#fff}body.colors-light #buddypress .item-list .activity-header p{background-color:#f7f7f7;color:#878787}body.colors-light #buddypress .item-list .activity-comments .acomment-meta{color:#737373}body.colors-light #buddypress #item-body .profile h2{background:#878787;color:#fff}body.colors-light #buddypress table tr.alt td{background:#f5f5f5;color:#333}body.colors-light #buddypress div#invite-list{background:#fafafa}#buddypress div.item-list-tabs ul li.selected a{background:inherit;opacity:1}#buddypress div.item-list-tabs ul{border-bottom:1px solid rgba(234,234,234,.9);overflow:hidden;padding:0}#buddypress div.item-list-tabs ul li a span{border-radius:25%}#buddypress #object-nav ul{overflow:hidden}#buddypress #object-nav ul li{float:none}@media screen and (max-width:38.75em){#buddypress #object-nav ul li:not(:last-child){border-bottom:1px solid #eaeaea}}@media screen and (max-width:38.75em){#buddypress #object-nav ul li:not(.selected):focus,#buddypress #object-nav ul li:not(.selected):hover{background:#f4f2df}}@media screen and (min-width:38.75em){#buddypress #object-nav ul li{float:left}}#buddypress div#subnav.item-list-tabs{margin-top:0}#buddypress div#subnav.item-list-tabs ul{border-bottom:0;margin-top:5px;padding:0}#buddypress div#subnav.item-list-tabs ul li.last{margin-top:0;padding:5px 5px 5px 0;width:100%}#buddypress div#subnav.item-list-tabs ul li.last select,#buddypress div#subnav.item-list-tabs ul li.last select:focus{background:0 0;border:0;outline:0}#buddypress div#subnav.item-list-tabs ul li.last label{display:inline}#buddypress div#subnav.item-list-tabs ul li.last label,#buddypress div#subnav.item-list-tabs ul li.last option,#buddypress div#subnav.item-list-tabs ul li.last select{font-size:14px;font-size:.875rem}#buddypress div#subnav.item-list-tabs ul li.last select{font-style:italic;height:auto}@media screen and (min-width:38.75em){#buddypress div#subnav.item-list-tabs ul li.last{text-align:right}}@media screen and (min-width:55em){body:not(.page-two-column) #buddypress #object-nav{border-right:1px solid #ddd;float:left;margin-right:-1px;width:200px}body:not(.page-two-column) #buddypress #object-nav ul{background:0 0;border-bottom:0;padding:0}body:not(.page-two-column) #buddypress #object-nav ul li{float:none;overflow:hidden}body:not(.page-two-column) #buddypress #object-nav ul li span{background:#fff;border-radius:10%;float:right;margin-right:2px}body:not(.page-two-column) #buddypress #item-body{border-left:1px solid #ddd;overflow:hidden;padding:0 0 0 20px;width:auto}body:not(.page-two-column) #buddypress #item-body #subnav{margin:0 0 0 -20px}body:not(.page-two-column) #buddypress #item-body #subnav ul{margin-top:0}}@media screen and (min-width:48em){#buddypress #group-create-tabs.item-list-tabs ul:after,#buddypress #group-create-tabs.item-list-tabs ul:before{content:" ";display:table}#buddypress #group-create-tabs.item-list-tabs ul:after{clear:both}#buddypress #group-create-tabs.item-list-tabs ul{background:0 0;border:0;border-bottom:1px solid #ddd;overflow:visible;padding-bottom:0}#buddypress #group-create-tabs.item-list-tabs ul li{float:left;width:auto}#buddypress #group-create-tabs.item-list-tabs ul li.current,#buddypress #group-create-tabs.item-list-tabs ul li.selected{border:1px solid #ddd;border-bottom-color:#fff;border-top-right-radius:4px;border-top-left-radius:4px;background-clip:padding-box;margin-bottom:-1px}#buddypress #group-create-tabs.item-list-tabs ul li.current a,#buddypress #group-create-tabs.item-list-tabs ul li.selected a{background:0 0;color:#333;outline:0}#buddypress #subnav ul{border-bottom:0}}#buddypress div.pagination{box-shadow:none;font-weight:400;min-height:0}#buddypress div.pagination:after,#buddypress div.pagination:before{height:0;width:0}#buddypress div.pagination .pag-count{margin-left:0}#buddypress div.pagination .pagination-links{margin-right:0}#buddypress div.pagination .pagination-links a,#buddypress div.pagination .pagination-links span{height:auto;line-height:1;padding:5px}#buddypress div.pagination .pagination-links .next,#buddypress div.pagination .pagination-links .prev{background-color:transparent;color:inherit;overflow:visible;width:auto}#buddypress div.pagination .pagination-links .next:before,#buddypress div.pagination .pagination-links .prev:before{display:none}#buddypress div.pagination .pagination-links .prev{left:auto;position:static}#buddypress div.pagination .pagination-links .next{position:static;right:auto}#buddypress .item-list .activity-header,#buddypress .item-list .activity-meta{font-family:"Libre Franklin","Helvetica Neue",helvetica,arial,sans-serif}#buddypress .activity-meta .button:focus,#buddypress .activity-meta .button:hover{background:inherit;color:#000}#buddypress .action .generic-button a:focus,#buddypress .action .generic-button a:hover{background:inherit;color:#000}#buddypress ul.item-list li{overflow:hidden!important}#buddypress ul.item-list li .item-avatar{margin-bottom:10px;text-align:center}@media screen and (min-width:38.75em){#buddypress ul.item-list li .item-avatar{margin-bottom:0}}#buddypress ul.item-list li .item-avatar a{border-bottom:0}#buddypress ul.item-list li .item-avatar img.avatar{display:inline-block;float:none;margin-bottom:10px}@media screen and (min-width:30em){#buddypress ul.item-list li .item-avatar img.avatar{display:block;float:left}}#buddypress ul.item-list li .item{overflow:hidden}@media screen and (min-width:48em){#buddypress ul.item-list li .item{margin-left:15%}}#buddypress ul.item-list li .item span.activity{font-style:italic}#buddypress ul.item-list li .item .item-desc{margin-left:0;width:94%}#buddypress ul.item-list li .item .item-title{font-size:18px;font-size:1.125rem;line-height:1.2;text-align:center;width:100%}@media screen and (min-width:30em){#buddypress ul.item-list li .item .item-title{text-align:left}}#buddypress ul.item-list li .item .item-title .update{display:block;font-size:13px;font-size:.8125rem;padding:10px 0;text-align:left}@media screen and (min-width:55em){#buddypress ul.item-list li .item .item-title .update{font-size:14px;font-size:.875rem}}@media screen and (min-width:55em){#buddypress ul.item-list li .action,#buddypress ul.item-list li .item,#buddypress ul.item-list li .item-avatar{float:left}#buddypress ul.item-list li .item{left:5%;margin-left:0;position:relative;width:55%}#buddypress ul.item-list li .item .item-title{font-size:22px;font-size:1.375rem}}#buddypress ul.item-list li div.action{clear:left;float:none;margin-bottom:-20px;margin-left:0;padding:20px 0 5px;position:relative;text-align:left;top:0}@media screen and (min-width:55em){#buddypress ul.item-list li div.action{clear:none;float:right;margin-bottom:0;padding:0}}#buddypress ul.item-list li div.action div{display:inline-block;margin:10px 0;width:100%}#buddypress ul.item-list li div.action div a{display:block;width:100%}@media screen and (min-width:30em){#buddypress ul.item-list li div.action div{margin:0 10px 10px 0;width:auto}}@media screen and (min-width:55em){#buddypress ul.item-list li div.action div{clear:right;float:right;margin:0 0 10px 0}}#buddypress ul.item-list li div.action .meta{font-style:italic}#buddypress form#whats-new-form p.activity-greeting{line-height:1.4}@media screen and (max-width:46.25em){#buddypress form#whats-new-form #whats-new-content{clear:left;margin:10px 0 20px;padding:10px 0 0}}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box{border:1px solid rgba(190,190,190,.5);float:left;line-height:1.5;margin-top:12px;padding-left:.2em;width:100%}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box select{background:0 0;border:0;float:right;margin:0;min-height:1.5em;padding-left:.4em}@media screen and (min-width:30em){#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-post-in-box{width:auto}#buddypress form#whats-new-form #whats-new-content.active #whats-new-options[style] #whats-new-submit{float:right}}#buddypress #item-body form#whats-new-form{margin:40px 0}#buddypress #activity-stream li{padding:25px 0 15px}#buddypress #activity-stream li .activity-avatar{float:none;text-align:center}#buddypress #activity-stream li .activity-avatar a{display:inline-block}#buddypress #activity-stream li .activity-avatar a img.avatar{display:inline;float:none;height:60px;margin-bottom:20px;margin-left:0;width:60px}#buddypress #activity-stream li .activity-content{margin-left:0}#buddypress #activity-stream li .activity-content .activity-header{font-size:14px;font-size:.875rem}#buddypress #activity-stream li .activity-content .activity-header a{color:#0075c4}@media screen and (min-width:48em){#buddypress #activity-stream li .activity-avatar{float:left;margin-right:10px;text-align:left}#buddypress #activity-stream li .activity-avatar a{border-bottom:0}#buddypress #activity-stream li .activity-content{margin:0;overflow:hidden}#buddypress #activity-stream li .activity-content .activity-header{font-size:16px;font-size:1rem}}#buddypress #activity-stream li.mini .activity-avatar a img.avatar{height:30px;margin-left:15px;width:30px}#buddypress #activity-stream li.mini .activity-content .activity-header{font-size:14px;font-size:.875rem}#buddypress #activity-stream .activity-content{margin-top:-12px}#buddypress #activity-stream .activity-content .activity-header{margin-right:0}#buddypress #activity-stream .activity-content .activity-header p{border:1px solid rgba(234,234,234,.6);margin-top:0;padding:0 .2em}#buddypress #activity-stream .activity-content .activity-header img.avatar{box-shadow:none;display:inline-block;margin:0 5px!important;vertical-align:middle}#buddypress #activity-stream .activity-content .activity-meta a{display:block;margin-bottom:5px}@media screen and (min-width:30em){#buddypress #activity-stream .activity-content .activity-meta a{display:inline-block;margin-bottom:0;width:auto}}#buddypress #activity-stream .load-more{background:#f7f7f7;border:1px solid transparent;padding:10px}#buddypress #activity-stream .load-more:focus,#buddypress #activity-stream .load-more:hover{background:#f4f4f4;border:1px solid rgba(159,209,226,.3)}#buddypress #activity-stream .load-more:focus a,#buddypress #activity-stream .load-more:hover a{font-style:italic}#buddypress #activity-stream .load-more a{display:block}.activity-permalink #buddypress #activity-stream li.activity-item{padding:20px}.activity-permalink #buddypress #activity-stream li.mini .activity-header{font-size:16px;font-size:1rem;margin-bottom:40px}@media screen and (min-width:48em){.activity-permalink #buddypress #activity-stream li.mini .activity-header{font-size:20px;font-size:1.25rem}}.activity-permalink #buddypress #activity-stream li.mini .activity-header p{padding:20px}#buddypress #activity-stream .activity-comments{border-left:1px solid #eaeaea;margin:20px 0 20px}@media screen and (min-width:30em){#buddypress #activity-stream .activity-comments{margin-left:20px}}#buddypress #activity-stream .activity-comments ul{margin:15px 0 0 2px}#buddypress #activity-stream .activity-comments ul li{border-top:1px solid #bebebe}#buddypress #activity-stream .activity-comments ul a{color:#0077c7}#buddypress #activity-stream .activity-comments .acomment-meta{border-bottom:1px solid #eaeaea}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel,#buddypress #activity-stream .activity-comments .ac-form input[type=submit]{color:rgba(51,51,51,.8);display:inline-block;font-family:inherit;font-size:12px;font-size:.75rem;font-weight:400;line-height:1.2;padding:4px 10px;text-transform:lowercase;width:100px}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel{border:1px solid rgba(190,190,190,.7);text-align:center}#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel:focus,#buddypress #activity-stream .activity-comments .ac-form .ac-reply-cancel:hover{background:#ededed}@media screen and (min-width:55em){#buddypress #members-list li .item,#buddypress #members-list li .item-avatar{float:left}#buddypress #members-list li .action{float:right}#buddypress #members-list li.is-current-user .item{float:none;left:0;padding-left:5%;width:auto}}#buddypress #signup_form.standard-form #basic-details-section,#buddypress #signup_form.standard-form #blog-details-section,#buddypress #signup_form.standard-form #profile-details-section{float:none;width:100%}@media screen and (min-width:38.75em){#buddypress #signup_form.standard-form #basic-details-section,#buddypress #signup_form.standard-form #blog-details-section,#buddypress #signup_form.standard-form #profile-details-section{width:48%}}@media screen and (min-width:30em){#buddypress #signup_form.standard-form #profile-details-section{float:right}#buddypress #signup_form.standard-form #basic-details-section{float:left}}@media screen and (min-width:48em){.bp-user.page-two-column #buddypress #cover-image-container #item-header-cover-image #item-header-content{margin-left:140px;margin-top:-100px}.single-item.groups.page-two-column #buddypress #cover-image-container #item-header-cover-image #item-header-content{margin-left:10px}}.bp-user #buddypress #item-header-cover-image .user-nicename,.single-item.groups #buddypress #item-header-cover-image .user-nicename{color:#333;text-shadow:none}@media screen and (min-width:48em){.bp-user #buddypress #item-header-cover-image .user-nicename,.single-item.groups #buddypress #item-header-cover-image .user-nicename{color:#fff;text-shadow:0 0 3px rgba(0,0,0,.8)}}.bp-user #buddypress #item-header-content #item-meta,.single-item.groups #buddypress #item-header-content #item-meta{font-size:14px;font-size:.875rem;text-align:left}.bp-user #buddypress #item-header-content #item-meta p,.single-item.groups #buddypress #item-header-content #item-meta p{margin-bottom:.5em}@media screen and (max-width:46.25em){.bp-user main header.entry-header,.single-item.groups main header.entry-header{padding-bottom:1rem}}@media screen and (max-width:38.75em){.bp-user #item-header-content,.bp-user h1,.single-item.groups #item-header-content,.single-item.groups h1{text-align:center}}@media screen and (max-width:46.25em){.bp-user #buddypress #item-header .generic-button,.single-item.groups #buddypress #item-header .generic-button{float:none;margin:1.5em 0 0}}@media screen and (max-width:38.75em){.bp-user #buddypress h1,.single-item.groups #buddypress h1{margin-bottom:0}.bp-user #buddypress #item-header-avatar img.avatar,.single-item.groups #buddypress #item-header-avatar img.avatar{margin-right:0}.bp-user #buddypress #item-header-content,.single-item.groups #buddypress #item-header-content{width:100%}}@media screen and (max-width:46.25em){.single-item.groups #buddypress #item-header #item-meta{margin-bottom:20px}}@media screen and (max-width:38.75em){.single-item.groups #buddypress div#item-header{display:flex;flex-direction:column}.single-item.groups #buddypress div#item-header #item-header-avatar{order:1;text-align:center}.single-item.groups #buddypress div#item-header #item-header-avatar a img{display:inline-block;float:none}.single-item.groups #buddypress div#item-header #item-header-content{order:2}.single-item.groups #buddypress div#item-header #item-actions{order:3}.single-item.groups #buddypress div#item-header #item-actions h2{border-bottom:1px solid #eaeaea;text-align:center}}.single-item.groups #buddypress div#item-header{padding-bottom:40px}.single-item.groups #buddypress div#item-header div#item-actions{margin:0;width:100%}@media screen and (min-width:38.75em){.single-item.groups #buddypress div#item-header div#item-actions{border-left:1px solid #eaeaea;clear:none;float:right;padding-left:.2em;width:30%}}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header div#item-actions{width:40%}}.single-item.groups #buddypress div#item-header div#item-actions ul{margin-top:0;padding-left:0}.single-item.groups #buddypress div#item-header div#item-actions h2{font-size:14px;font-size:.875rem;padding:.2em}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header div#item-actions h2{font-size:16px;font-size:1rem}}@media screen and (min-width:48em){.single-item.groups #buddypress div#item-header #item-header-avatar,.single-item.groups #buddypress div#item-header #item-header-content{float:left}.single-item.groups #buddypress div#item-header #item-header-avatar{width:21%}.single-item.groups #buddypress div#item-header #item-header-content{margin-left:4%;width:40%}.single-item.groups #buddypress div#item-header div#item-actions{float:right;width:28%}}.bp-user #buddypress #item-header{padding:20px 0}.bp-user #buddypress #item-header #item-header-avatar{text-align:center;width:100%}.bp-user #buddypress #item-header #item-header-avatar a,.bp-user #buddypress #item-header #item-header-avatar img.avatar{display:inline-block;float:none}@media screen and (min-width:48em){.bp-user #buddypress #item-header #item-header-avatar{float:left;width:20%}.bp-user #buddypress #item-header #item-header-avatar a{float:left}.bp-user #buddypress #item-header #item-header-content{float:right;margin-right:5%;width:69%}}.groups.single-item.members #buddypress #subnav.item-list-tabs ul{background:0 0;border-top:0}.groups #group-settings-form h3{background:#555;color:#fff;padding:.2em}.groups.edit-details #group-settings-form label{margin-bottom:0;padding:.2em;width:80%}.groups.edit-details #group-settings-form textarea+p label{background:0 0;color:inherit;font-size:14px;font-size:.875rem;width:auto}.groups.edit-details #group-settings-form textarea{height:auto;min-height:100px;overflow:auto}.groups.group-settings #group-settings-form div.radio label{border:1px solid #eaeaea;padding:.2em}.groups.group-settings #group-settings-form div.radio label ul{color:rgba(51,51,51,.6);font-size:14px;font-size:.875rem}.groups.group-avatar form>p{margin-top:20px}.groups.manage-members #group-settings-form .item-list li{border-bottom:1px solid #eaeaea}.groups.manage-members #group-settings-form .item-list li h5,.groups.manage-members #group-settings-form .item-list li img{float:left}.groups.manage-members #group-settings-form .item-list li h5>a,.groups.manage-members #group-settings-form .item-list li img>a{border-bottom:0}.groups.manage-members #group-settings-form .item-list li span.small{clear:left;display:block;float:none;margin-top:10px}.groups.manage-members #group-settings-form .item-list li span.small a{display:inline-block;margin:5px 0;width:100%}@media screen and (min-width:38.75em){.groups.manage-members #group-settings-form .item-list li span.small a{width:auto}}.groups.manage-members #group-settings-form .item-list li h5{margin:0}.groups.group-members #subnav li{width:100%}@media screen and (max-width:38.75em){.groups.group-members #subnav li{background:#fff;padding:20px 0}}.groups.group-members #subnav li #search-members-form{float:right;margin:5px 0 0}@media screen and (max-width:38.75em){.groups.group-members #subnav li #search-members-form{margin:0;width:100%}.groups.group-members #subnav li #search-members-form label input[type=text]{width:100%}}.bp-user .entry-title{margin-bottom:.5em}.bp-user #buddypress table th{font-size:14px;font-size:.875rem}.bp-user #buddypress table td{font-size:12px;font-size:.75rem}.bp-user #buddypress table a{color:#0074c2}@media screen and (min-width:55em){.bp-user #buddypress table th{font-size:16px;font-size:1rem}.bp-user #buddypress table td{font-size:14px;font-size:.875rem}}@media screen and (min-width:67em){.bp-user #buddypress table th{font-size:18px;font-size:1.125rem}.bp-user #buddypress table td{font-size:16px;font-size:1rem}}.bp-user #buddypress .pag-count{font-style:italic}.bp-user #buddypress .messages-options-nav,.bp-user #buddypress .notifications-options-nav{float:left;width:100%}@media screen and (min-width:38.75em){.bp-user #buddypress .messages-options-nav,.bp-user #buddypress .notifications-options-nav{width:300px}}.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav select{height:auto}.bp-user #buddypress .messages-options-nav input,.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav input,.bp-user #buddypress .notifications-options-nav select{font-size:14px;font-size:.875rem;outline:0;padding:0}.bp-user #buddypress .messages-options-nav select,.bp-user #buddypress .notifications-options-nav select{float:left;margin-right:1%;width:59%}.bp-user #buddypress .messages-options-nav input,.bp-user #buddypress .notifications-options-nav input{float:right;font-family:inherit;line-height:20px;width:40%}.bp-user #buddypress .messages-options-nav input[disabled=disabled]:focus,.bp-user #buddypress .messages-options-nav input[disabled=disabled]:hover,.bp-user #buddypress .notifications-options-nav input[disabled=disabled]:focus,.bp-user #buddypress .notifications-options-nav input[disabled=disabled]:hover{background:0 0}.bp-user #buddypress .profile h2{margin:40px 0 10px;padding:.1em 0 .1em .4em}.bp-user #buddypress .profile table{margin-top:0}.bp-user #buddypress .profile .profile-fields tr.alt td{color:#333}.bp-user #buddypress .profile .profile-fields tr:last-child{border-bottom:0}.bp-user #buddypress .profile #profile-edit-form .button-nav:after,.bp-user #buddypress .profile #profile-edit-form .button-nav:before{content:" ";display:table}.bp-user #buddypress .profile #profile-edit-form .button-nav:after{clear:both}.bp-user #buddypress .profile #profile-edit-form ul.button-nav{border-bottom:1px solid #eaeaea;margin-left:0}.bp-user #buddypress .profile #profile-edit-form ul.button-nav li{float:left;margin-bottom:0}.bp-user #buddypress .profile #profile-edit-form ul.button-nav li.current{border:1px solid #eaeaea;border-bottom-color:#fff;margin-bottom:-1px}.bp-user #buddypress .profile #profile-edit-form ul.button-nav a{background:0 0;border:0;font-size:18px;font-size:1.125rem}.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings,.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-notoggle,.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-toggle{font-size:14px;font-size:.875rem;margin-top:10px}.bp-user #buddypress .profile #profile-edit-form .field-visibility-settings-close,.bp-user #buddypress .profile #profile-edit-form .visibility-toggle-link{background:#555;border-radius:3px;background-clip:padding-box;color:#fff;padding:.2em .5em}.bp-user #buddypress .profile .bp-avatar #bp-delete-avatar a{font-size:inherit}@media screen and (min-width:77.5em){.bp-user #buddypress #groups-list li .item{left:5%;width:50%}}.bp-user #buddypress #message-thread a{border-bottom:0}.bp-user #buddypress #message-thread #message-subject{background:#6f6e6e;color:#fff;padding:.3em 0 .3em .2em}.bp-user #buddypress #message-thread #message-recipients{font-style:italic}.bp-user #buddypress #message-thread #message-recipients a.confirm{border:1px solid #eaeaea;font-style:normal}.bp-user #buddypress #message-thread .message-metadata:after{clear:both;content:"";display:table}.bp-user #buddypress #message-thread .message-metadata img.avatar{float:none}@media screen and (min-width:48em){.bp-user #buddypress #message-thread .message-metadata img.avatar{float:left}}.bp-user #buddypress #message-thread .message-metadata .message-star-actions{float:right;margin-right:5px;position:static}.bp-user #buddypress #message-thread .message-content{background:#f7f7f7;border:1px solid #eaeaea;margin:10px 0 0 0;padding:.3em}.bp-user #buddypress #message-thread #send-reply .message-content{background:#fff;border:0}.bp-user #buddypress #message-thread .alt{background:#fff}.bp-user #buddypress #message-threads thead tr{background:0 0;border-bottom:1px solid #bebebe}.bp-user #buddypress #message-threads thead tr th{background:#555}.bp-user #buddypress #message-threads tr{border-bottom:5px solid #878787}.bp-user #buddypress #message-threads tr td{display:inline-block;float:left}.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{border-bottom-color:#bebebe;border-bottom-width:1px;height:2.4em;padding-bottom:.2em;padding-top:.2em}@media screen and (max-width:46.25em){.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{padding-top:0}}.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from,.bp-user #buddypress #message-threads tr td.thread-info,.bp-user #buddypress #message-threads tr td.thread-options,.bp-user #buddypress #message-threads tr td.thread-star{border-top:0}.bp-user #buddypress #message-threads tr td.thread-star{vertical-align:middle}.bp-user #buddypress #message-threads tr td.thread-star .message-action-star{line-height:1.2}.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from{height:3em}@media screen and (max-width:38.75em){.bp-user #buddypress #message-threads tr td.bulk-select-check,.bp-user #buddypress #message-threads tr td.thread-from{height:5.2em}}.bp-user #buddypress #message-threads tr td.thread-from,.bp-user #buddypress #message-threads tr td.thread-options{border-left:0!important;width:calc(100% - 30px);margin-left:0}.bp-user #buddypress #message-threads tr td.thread-info{padding-left:41px;width:100%}.bp-user #buddypress #message-threads tr td.thread-options{text-align:right}.bp-user #buddypress #message-threads tr td.thread-options a{font-size:12px;font-size:.75rem;line-height:2.2}.bp-user #buddypress #message-threads tr span.from{display:none}.bp-user #buddypress #message-threads tr span.activity{display:block;float:right;line-height:2}@media screen and (max-width:38.75em){.bp-user #buddypress #message-threads tr span.activity{clear:both;font-size:11px;font-size:.6875rem;width:100%}}.bp-user #buddypress #message-threads tr.unread td{background:0 0;border-color:#bebebe}.bp-user #buddypress #message-threads th{display:none}.bp-user #buddypress #message-threads th.bulk-select-all{border-bottom:0;display:inline-block;text-align:left}.bp-user #buddypress #message-threads td.bulk-select-check,.bp-user #buddypress #message-threads td.thread-star,.bp-user #buddypress #message-threads th.bulk-select-all{border-right:0;width:30px}.bp-user #buddypress .acfb-holder{list-style:none}.bp-user #buddypress .acfb-holder li{margin-left:0}.bp-user #buddypress .acfb-holder li.friend-tab{background:#e3f6ff;border:inherit;margin-right:0;padding:.5em}.bp-user #buddypress .acfb-holder li.friend-tab span.p{padding-left:10px}.bp-user #buddypress .acfb-holder li.friend-tab span.p:focus,.bp-user #buddypress .acfb-holder li.friend-tab span.p:hover{color:#c82b2b;cursor:pointer}.bp-user #buddypress .acfb-holder li.friend-tab a{border-bottom:0;text-decoration:none}.bp-user #buddypress .acfb-holder li.friend-tab a img{display:inline;height:20px;vertical-align:middle;width:20px!important}.bp-user #buddypress #message-threads.sitewide-notices td{width:100%}.bp-user #buddypress #message-threads.sitewide-notices td strong{background:#6f6e6e;color:#fff;display:block;margin-bottom:.4em;padding-left:.2em}.bp-user #buddypress #message-threads.sitewide-notices td a{display:inline-block}.bp-user #buddypress #message-threads.sitewide-notices td:first-child{display:none}.bp-user #buddypress #message-threads.sitewide-notices td:nth-child(2) strong{margin:-8px -8px 8px}.bp-user #buddypress #message-threads.sitewide-notices td:first-child+td+td{border-bottom:0}.bp-user #buddypress #message-threads.sitewide-notices td:first-child+td+td span{line-height:1}.bp-user #buddypress #message-threads.sitewide-notices td:last-child{border-bottom-color:#b7b7b7;line-height:1;text-align:right}.bp-user #buddypress #message-threads.sitewide-notices td:last-child a:last-child:after{content:attr(title);display:block;line-height:initial;text-indent:0}.bp-user .ac_results{background:#eee;padding-left:10px}.bp-user .ac_results ul{margin:0}.bp-user .ac_results li{margin:10px 0}.bp-user .ac_results li:focus,.bp-user .ac_results li:hover{cursor:pointer}.bp-user #buddypress #settings-form>p{font-size:20px;font-size:1.25rem;margin:20px 0 10px}.bp-user #buddypress table.notification-settings td.no,.bp-user #buddypress table.notification-settings td.yes{vertical-align:middle}.bp-user #buddypress table.profile-settings{width:100%}.bp-user #buddypress table.profile-settings td.field-name,.bp-user #buddypress table.profile-settings th.field-group-name{width:50%}@media screen and (min-width:48em){.bp-user #buddypress table.profile-settings td.field-name,.bp-user #buddypress table.profile-settings th.field-group-name{width:70%}}.bp-user #buddypress table.profile-settings td.field-visibility,.bp-user #buddypress table.profile-settings th.title{width:30%}.bp-user #buddypress table.profile-settings td.field-visibility select{width:100%}#main #buddypress .standard-form li{float:none}#main #buddypress .standard-form input[type=email],#main #buddypress .standard-form input[type=password],#main #buddypress .standard-form input[type=text],#main #buddypress .standard-form textarea{width:100%}#buddypress div.activity-comments form .ac-textarea{background:#f7f7f7;border:1px solid rgba(190,190,190,.5)}#buddypress div.activity-comments form .ac-textarea textarea{background:0 0;border:0}#buddypress select{height:auto}#buddypress .standard-form button,#buddypress .standard-form input[type=email],#buddypress .standard-form input[type=password],#buddypress .standard-form input[type=text],#buddypress .standard-form select,#buddypress .standard-form textarea{border-color:rgba(190,190,190,.5);border-width:1px}#buddypress .standard-form select{color:#737373}#buddypress #signup_form.standard-form div.submit{float:none}#buddypress #signup_form.standard-form div.submit input{margin-right:0}#buddypress div.dir-search,#buddypress div.message-search,#buddypress li.groups-members-search{float:none;margin:10px 0}#buddypress div.dir-search form,#buddypress div.message-search form,#buddypress li.groups-members-search form{border:1px solid rgba(190,190,190,.6);position:relative;border-radius:2px;background-clip:padding-box;overflow:hidden}#buddypress div.dir-search form label,#buddypress div.message-search form label,#buddypress li.groups-members-search form label{float:left;margin:0;width:70%}#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{float:left;margin:0;width:100%}#buddypress div.dir-search form input[type=submit],#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=submit],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=submit],#buddypress li.groups-members-search form input[type=text]{border:0;font-size:14px;font-size:.875rem;line-height:inherit}#buddypress div.dir-search form input[type=text],#buddypress div.message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{border-right:1px solid rgba(190,190,190,.6);font-weight:400;padding:.2em 0 .2em .2em}#buddypress div.dir-search form input[type=submit],#buddypress div.message-search form input[type=submit],#buddypress li.groups-members-search form input[type=submit]{border-radius:0;float:right;font-weight:400;padding:.2em 1em;text-align:center;text-transform:none;width:30%}#buddypress div.dir-search{margin-top:0}#buddypress #search-groups-form input[type=text],#buddypress #search-message-form input[type=text],#buddypress .dir-search #search-members-form input[type=text]{float:left;margin:0;width:70%}@media screen and (min-width:30em){#buddypress div.dir-search,#buddypress div.message-search,#buddypress li.groups-members-search{float:right;margin-bottom:5px!important}}@media screen and (min-width:67em){#buddypress .dir-search form input[type=text],#buddypress .message-search form input[type=text],#buddypress li.groups-members-search form input[type=text]{font-size:16px;font-size:1rem}#buddypress .dir-search form input[type=submit],#buddypress .message-search form input[type=submit],#buddypress li.groups-members-search form input[type=submit]{font-size:16px;font-size:1rem}}body.colors-dark #page #buddypress .dir-search form,body.colors-dark #page #buddypress .groups-members-search form,body.colors-dark #page #buddypress .message-search form{background:#333;border-color:#555;border-radius:2px;background-clip:padding-box;padding:1px}body.colors-dark #page #buddypress .dir-search input[type=text],body.colors-dark #page #buddypress .groups-members-search input[type=text],body.colors-dark #page #buddypress .message-search input[type=text]{background:0 0}body.colors-dark #page #buddypress .dir-search input[type=submit],body.colors-dark #page #buddypress .groups-members-search input[type=submit],body.colors-dark #page #buddypress .message-search input[type=submit]{border-radius:2px;background-clip:padding-box}body.colors-dark #page .message-search{margin-top:0}#buddypress table{font-size:14px;font-size:.875rem;margin:20px 0}#buddypress table tr th{background:#f7f7f7;border-color:#eaeaea;color:#333}#buddypress table p{margin-bottom:.5em}@media screen and (min-width:55em){#buddypress table{font-size:16px;font-size:1rem}}#buddypress .messages-notices th,#buddypress .notifications th{width:30%}#buddypress .messages-notices th.bulk-select-all,#buddypress .notifications th.bulk-select-all{text-align:center;width:10%}#buddypress .messages-notices .bulk-select-check,#buddypress .messages-notices .thread-star,#buddypress .notifications .bulk-select-check,#buddypress .notifications .thread-star{text-align:center}#buddypress .messages-notices .notification-actions,#buddypress .messages-notices td.thread-options,#buddypress .notifications .notification-actions,#buddypress .notifications td.thread-options{text-align:center}#buddypress .messages-notices .notification-actions a,#buddypress .messages-notices td.thread-options a,#buddypress .notifications .notification-actions a,#buddypress .notifications td.thread-options a{display:inline-block;margin:0;padding:0}#buddypress .messages-notices td .button,#buddypress .notifications td .button{border:0;display:block;padding:0;text-align:center}#buddypress .notifications .actions{text-align:center}#buddypress div#message p{font-size:18px;font-size:1.125rem;font-weight:700}#buddypress div#message.info p{background:#b0e5ff;border:1px solid #4ac3ff;color:#00547d}#buddypress div#message.updated p{background:#dee6b2;border:1px solid #becc66;color:#454d19}#buddypress .bp-avatar-status .warning,#buddypress .bp-cover-image-status .warning{background:#7dd4ff;border:1px solid #000;color:#333;font-size:16px;font-size:1rem}.delete-group #buddypress div#message.info p{background:#db7e7e;border:1px solid #be3535;color:#1f0808}#buddypress .acfb-holder li.friend-tab{background:#7dd4ff;border:inherit}
bp-templates/bp-legacy/css/twentyseventeen.scss CHANGED
@@ -166,10 +166,10 @@ $spacing-val-xs: 5px;
166
  }
167
 
168
  @mixin border-radius-none() {
169
- -webkit-border-radius: none;
170
- -moz-border-radius: none;
171
- -ms-border-radius: none;
172
- border-radius: none;
173
  }
174
 
175
  // Box sizing
166
  }
167
 
168
  @mixin border-radius-none() {
169
+ -webkit-border-radius: 0;
170
+ -moz-border-radius: 0;
171
+ -ms-border-radius: 0;
172
+ border-radius: 0;
173
  }
174
 
175
  // Box sizing
bp-templates/bp-nouveau/buddypress-functions.php CHANGED
@@ -146,7 +146,7 @@ class BP_Nouveau extends BP_Theme_Compat {
146
  bp_set_theme_compat_feature( $this->id, array(
147
  'name' => 'cover_image',
148
  'settings' => array(
149
- 'components' => array( 'xprofile', 'groups' ),
150
  'width' => $width,
151
  'height' => $top_offset + round( $avatar_height / 2 ),
152
  'callback' => 'bp_nouveau_theme_cover_image',
@@ -170,29 +170,29 @@ class BP_Nouveau extends BP_Theme_Compat {
170
  // We need to neutralize the BuddyPress core "bp_core_render_message()" once it has been added.
171
  add_action( 'bp_actions', array( $this, 'neutralize_core_template_notices' ), 6 );
172
 
173
- // Scripts
174
- add_action( 'bp_enqueue_scripts', array( $this, 'register_scripts' ), 2 ); // Register theme JS
175
  remove_action( 'bp_enqueue_scripts', 'bp_core_confirmation_js' );
176
- add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_styles' ) ); // Enqueue theme CSS
177
- add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); // Enqueue theme JS
178
- add_filter( 'bp_enqueue_scripts', array( $this, 'localize_scripts' ) ); // Enqueue theme script localization
179
 
180
- // Body no-js class
181
  add_filter( 'body_class', array( $this, 'add_nojs_body_class' ), 20, 1 );
182
 
183
- // Ajax querystring
184
  add_filter( 'bp_ajax_querystring', 'bp_nouveau_ajax_querystring', 10, 2 );
185
 
186
- // Register directory nav items
187
  add_action( 'bp_screens', array( $this, 'setup_directory_nav' ), 15 );
188
 
189
- // Register the Default front pages Dynamic Sidebars
190
  add_action( 'widgets_init', 'bp_nouveau_register_sidebars', 11 );
191
 
192
- // Register the Primary Object nav widget
193
  add_action( 'bp_widgets_init', array( 'BP_Nouveau_Object_Nav_Widget', 'register_widget' ) );
194
 
195
- // Set the BP Uri for the Ajax customizer preview
196
  add_filter( 'bp_uri', array( $this, 'customizer_set_uri' ), 10, 1 );
197
 
198
  /** Override **********************************************************/
@@ -317,7 +317,7 @@ class BP_Nouveau extends BP_Theme_Compat {
317
  ),
318
  ) );
319
 
320
- // Bail if no scripts
321
  if ( empty( $scripts ) ) {
322
  return;
323
  }
@@ -425,12 +425,14 @@ class BP_Nouveau extends BP_Theme_Compat {
425
  $params = array(
426
  'ajaxurl' => bp_core_ajax_url(),
427
  'confirm' => __( 'Are you sure?', 'buddypress' ),
 
 
428
  'show_x_comments' => __( 'Show all %d comments', 'buddypress' ),
429
  'unsaved_changes' => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
430
  'object_nav_parent' => '#buddypress',
431
  );
432
 
433
- // If the Object/Item nav are in the sidebar
434
  if ( bp_nouveau_is_object_nav_in_sidebar() ) {
435
  $params['object_nav_parent'] = '.buddypress_object_nav';
436
  }
@@ -459,11 +461,11 @@ class BP_Nouveau extends BP_Theme_Compat {
459
  $supported_objects = array_merge( $supported_objects, array( 'group_members', 'group_requests' ) );
460
  }
461
 
462
- // Add components & nonces
463
  $params['objects'] = $supported_objects;
464
  $params['nonces'] = $object_nonces;
465
 
466
- // Used to transport the settings inside the Ajax requests
467
  if ( is_customize_preview() ) {
468
  $params['customizer_settings'] = bp_nouveau_get_temporary_setting( 'any' );
469
  }
@@ -602,7 +604,7 @@ class BP_Nouveau extends BP_Theme_Compat {
602
  continue;
603
  }
604
 
605
- // Define the primary nav for the current component's directory
606
  $this->directory_nav->add_nav( $nav_item );
607
  }
608
  }
146
  bp_set_theme_compat_feature( $this->id, array(
147
  'name' => 'cover_image',
148
  'settings' => array(
149
+ 'components' => array( 'members', 'groups' ),
150
  'width' => $width,
151
  'height' => $top_offset + round( $avatar_height / 2 ),
152
  'callback' => 'bp_nouveau_theme_cover_image',
170
  // We need to neutralize the BuddyPress core "bp_core_render_message()" once it has been added.
171
  add_action( 'bp_actions', array( $this, 'neutralize_core_template_notices' ), 6 );
172
 
173
+ // Scripts.
174
+ add_action( 'bp_enqueue_scripts', array( $this, 'register_scripts' ), 2 ); // Register theme JS.
175
  remove_action( 'bp_enqueue_scripts', 'bp_core_confirmation_js' );
176
+ add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_styles' ) ); // Enqueue theme CSS.
177
+ add_action( 'bp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); // Enqueue theme JS.
178
+ add_filter( 'bp_enqueue_scripts', array( $this, 'localize_scripts' ) ); // Enqueue theme script localization.
179
 
180
+ // Body no-js class.
181
  add_filter( 'body_class', array( $this, 'add_nojs_body_class' ), 20, 1 );
182
 
183
+ // Ajax querystring.
184
  add_filter( 'bp_ajax_querystring', 'bp_nouveau_ajax_querystring', 10, 2 );
185
 
186
+ // Register directory nav items.
187
  add_action( 'bp_screens', array( $this, 'setup_directory_nav' ), 15 );
188
 
189
+ // Register the Default front pages Dynamic Sidebars.
190
  add_action( 'widgets_init', 'bp_nouveau_register_sidebars', 11 );
191
 
192
+ // Register the Primary Object nav widget.
193
  add_action( 'bp_widgets_init', array( 'BP_Nouveau_Object_Nav_Widget', 'register_widget' ) );
194
 
195
+ // Set the BP Uri for the Ajax customizer preview.
196
  add_filter( 'bp_uri', array( $this, 'customizer_set_uri' ), 10, 1 );
197
 
198
  /** Override **********************************************************/
317
  ),
318
  ) );
319
 
320
+ // Bail if no scripts.
321
  if ( empty( $scripts ) ) {
322
  return;
323
  }
425
  $params = array(
426
  'ajaxurl' => bp_core_ajax_url(),
427
  'confirm' => __( 'Are you sure?', 'buddypress' ),
428
+
429
+ /* translators: %s: number of activity comments */
430
  'show_x_comments' => __( 'Show all %d comments', 'buddypress' ),
431
  'unsaved_changes' => __( 'Your profile has unsaved changes. If you leave the page, the changes will be lost.', 'buddypress' ),
432
  'object_nav_parent' => '#buddypress',
433
  );
434
 
435
+ // If the Object/Item nav are in the sidebar.
436
  if ( bp_nouveau_is_object_nav_in_sidebar() ) {
437
  $params['object_nav_parent'] = '.buddypress_object_nav';
438
  }
461
  $supported_objects = array_merge( $supported_objects, array( 'group_members', 'group_requests' ) );
462
  }
463
 
464
+ // Add components & nonces.
465
  $params['objects'] = $supported_objects;
466
  $params['nonces'] = $object_nonces;
467
 
468
+ // Used to transport the settings inside the Ajax requests.
469
  if ( is_customize_preview() ) {
470
  $params['customizer_settings'] = bp_nouveau_get_temporary_setting( 'any' );
471
  }
604
  continue;
605
  }
606
 
607
+ // Define the primary nav for the current component's directory.
608
  $this->directory_nav->add_nav( $nav_item );
609
  }
610
  }
bp-templates/bp-nouveau/buddypress/activity/index.php CHANGED
@@ -3,7 +3,7 @@
3
  * BuddyPress Activity templates
4
  *
5
  * @since 2.3.0
6
- * @version 3.0.0
7
  */
8
  ?>
9
 
@@ -39,3 +39,4 @@
39
 
40
  </div><!-- // .screen-content -->
41
 
 
3
  * BuddyPress Activity templates
4
  *
5
  * @since 2.3.0
6
+ * @version 6.0.0
7
  */
8
  ?>
9
 
39
 
40
  </div><!-- // .screen-content -->
41
 
42
+ <?php bp_nouveau_after_directory_page(); ?>
bp-templates/bp-nouveau/buddypress/assets/emails/single-bp-email.php CHANGED
@@ -205,7 +205,7 @@ $settings = bp_email_get_appearance_settings();
205
  <br>
206
  <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="<?php echo esc_attr( $settings['direction'] ); ?>" width="100%" style="max-width: 600px; border-radius: 5px;" bgcolor="<?php echo esc_attr( $settings['footer_bg'] ); ?>" class="footer_bg">
207
  <tr>
208
- <td style="padding: 20px; width: 100%; font-size: <?php echo esc_attr( $settings['footer_text_size'] . 'px' ); ?>; font-family: sans-serif; mso-height-rule: exactly; line-height: <?php echo esc_attr( floor( $settings['footer_text_size'] * 1.618 ) . 'px' ); ?>; text-align: <?php echo esc_attr( $settings['direction'] ); ?>; color: <?php echo esc_attr( $settings['footer_text_color'] ); ?>;" class="footer_text_color footer_text_size">
209
  <?php
210
  /**
211
  * Fires before the display of the email template footer.
205
  <br>
206
  <table role="presentation" cellspacing="0" cellpadding="0" border="0" align="<?php echo esc_attr( $settings['direction'] ); ?>" width="100%" style="max-width: 600px; border-radius: 5px;" bgcolor="<?php echo esc_attr( $settings['footer_bg'] ); ?>" class="footer_bg">
207
  <tr>
208
+ <td style="padding: 20px; width: 100%; font-size: <?php echo esc_attr( $settings['footer_text_size'] . 'px' ); ?>; font-family: sans-serif; mso-height-rule: exactly; line-height: <?php echo esc_attr( floor( $settings['footer_text_size'] * 1.618 ) . 'px' ); ?>; text-align: <?php echo esc_attr( $settings['direction'] ); ?>; color: <?php echo esc_attr( $settings['footer_text_color'] ); ?>; word-break: break-all;" class="footer_text_color footer_text_size">
209
  <?php
210
  /**
211
  * Fires before the display of the email template footer.
bp-templates/bp-nouveau/buddypress/blogs/index.php CHANGED
@@ -3,7 +3,7 @@
3
  * BuddyPress - Blogs Directory
4
  *
5
  * @since 3.0.0
6
- * @version 3.0.0
7
  */
8
  ?>
9
 
@@ -26,3 +26,4 @@
26
  <?php bp_nouveau_after_blogs_directory_content(); ?>
27
  </div><!-- // .screen-content -->
28
 
 
3
  * BuddyPress - Blogs Directory
4
  *
5
  * @since 3.0.0
6
+ * @version 6.0.0
7
  */
8
  ?>
9
 
26
  <?php bp_nouveau_after_blogs_directory_content(); ?>
27
  </div><!-- // .screen-content -->
28
 
29
+ <?php bp_nouveau_after_directory_page(); ?>
bp-templates/bp-nouveau/buddypress/common/js-templates/invites/index.php CHANGED
@@ -6,7 +6,7 @@
6
  * dealing with invites.
7
  *
8
  * @since 3.0.0
9
- * @version 3.1.0
10
  */
11
  ?>
12
 
@@ -150,6 +150,6 @@
150
  <a href="#next-page" id="bp-invites-next-page" class="button invite-button bp-tooltip" data-bp-tooltip="<?php echo esc_attr_x( 'Next page', 'link', 'buddypress' ); ?>">
151
  <span class="bp-screen-reader-text"><?php echo esc_html_x( 'Next page', 'link', 'buddypress' ); ?></span>
152
  <span class="dashicons dashicons-arrow-right" aria-hidden="true"></span>
153
- </button>
154
  <# } #>
155
  </script>
6
  * dealing with invites.
7
  *
8
  * @since 3.0.0
9
+ * @version 6.0.0
10
  */
11
  ?>
12
 
150
  <a href="#next-page" id="bp-invites-next-page" class="button invite-button bp-tooltip" data-bp-tooltip="<?php echo esc_attr_x( 'Next page', 'link', 'buddypress' ); ?>">
151
  <span class="bp-screen-reader-text"><?php echo esc_html_x( 'Next page', 'link', 'buddypress' ); ?></span>
152
  <span class="dashicons dashicons-arrow-right" aria-hidden="true"></span>
153
+ </a>
154
  <# } #>
155
  </script>
bp-templates/bp-nouveau/buddypress/groups/groups-loop.php CHANGED
@@ -47,7 +47,7 @@ bp_nouveau_before_loop(); ?>
47
  <p class="last-activity item-meta">
48
  <?php
49
  printf(
50
- /* translators: %s = last activity timestamp (e.g. "active 1 hour ago") */
51
  __( 'active %s', 'buddypress' ),
52
  bp_get_group_last_active()
53
  );
47
  <p class="last-activity item-meta">
48
  <?php
49
  printf(
50
+ /* translators: %s: last activity timestamp (e.g. "active 1 hour ago") */
51
  __( 'active %s', 'buddypress' ),
52
  bp_get_group_last_active()
53
  );
bp-templates/bp-nouveau/buddypress/groups/index.php CHANGED
@@ -3,7 +3,7 @@
3
  * BP Nouveau - Groups Directory
4
  *
5
  * @since 3.0.0
6
- * @version 3.0.0
7
  */
8
  ?>
9
 
@@ -28,3 +28,4 @@
28
  <?php bp_nouveau_after_groups_directory_content(); ?>
29
  </div><!-- // .screen-content -->
30
 
 
3
  * BP Nouveau - Groups Directory
4
  *
5
  * @since 3.0.0
6
+ * @version 6.0.0
7
  */
8
  ?>
9
 
28
  <?php bp_nouveau_after_groups_directory_content(); ?>
29
  </div><!-- // .screen-content -->
30
 
31
+ <?php bp_nouveau_after_directory_page(); ?>
bp-templates/bp-nouveau/buddypress/groups/single/cover-image-header.php CHANGED
@@ -27,7 +27,7 @@
27
  <p class="highlight group-status"><strong><?php echo esc_html( bp_nouveau_group_meta()->status ); ?></strong></p>
28
  <p class="activity" data-livestamp="<?php bp_core_iso8601_date( bp_get_group_last_active( 0, array( 'relative' => false ) ) ); ?>">
29
  <?php
30
- /* translators: %s = last activity timestamp (e.g. "active 1 hour ago") */
31
  printf( __( 'active %s', 'buddypress' ), bp_get_group_last_active() );
32
  ?>
33
  </p>
27
  <p class="highlight group-status"><strong><?php echo esc_html( bp_nouveau_group_meta()->status ); ?></strong></p>
28
  <p class="activity" data-livestamp="<?php bp_core_iso8601_date( bp_get_group_last_active( 0, array( 'relative' => false ) ) ); ?>">
29
  <?php
30
+ /* translators: %s: last activity timestamp (e.g. "active 1 hour ago") */
31
  printf( __( 'active %s', 'buddypress' ), bp_get_group_last_active() );
32
  ?>
33
  </p>
bp-templates/bp-nouveau/buddypress/groups/single/default-front.php CHANGED
@@ -18,6 +18,7 @@
18
  <p>
19
  <?php
20
  printf(
 
21
  esc_html__( 'You can set your preferences for the %1$s or add %2$s to it.', 'buddypress' ),
22
  bp_nouveau_groups_get_customizer_option_link(),
23
  bp_nouveau_groups_get_customizer_widgets_link()
18
  <p>
19
  <?php
20
  printf(
21
+ /* translators: 1: link to the customizer option. 2: link to the customizer widgets section. */
22
  esc_html__( 'You can set your preferences for the %1$s or add %2$s to it.', 'buddypress' ),
23
  bp_nouveau_groups_get_customizer_option_link(),
24
  bp_nouveau_groups_get_customizer_widgets_link()
bp-templates/bp-nouveau/buddypress/groups/single/group-header.php CHANGED
@@ -27,7 +27,7 @@
27
  <?php
28
  echo esc_html(
29
  sprintf(
30
- /* translators: %s = last activity timestamp (e.g. "active 1 hour ago") */
31
  __( 'active %s', 'buddypress' ),
32
  bp_get_group_last_active()
33
  )
27
  <?php
28
  echo esc_html(
29
  sprintf(
30
+ /* translators: %s: last activity timestamp (e.g. "active 1 hour ago") */
31
  __( 'active %s', 'buddypress' ),
32
  bp_get_group_last_active()
33
  )
bp-templates/bp-nouveau/buddypress/groups/single/request-membership.php CHANGED
@@ -13,7 +13,7 @@ bp_nouveau_group_hook( 'before', 'request_membership_content' ); ?>
13
  <?php
14
  echo esc_html(
15
  sprintf(
16
- /* translators: %s = group name */
17
  __( 'You are requesting to become a member of the group "%s".', 'buddypress' ),
18
  bp_get_group_name()
19
  )
13
  <?php
14
  echo esc_html(
15
  sprintf(
16
+ /* translators: %s: group name */
17
  __( 'You are requesting to become a member of the group "%s".', 'buddypress' ),
18
  bp_get_group_name()
19
  )
bp-templates/bp-nouveau/buddypress/members/index.php CHANGED
@@ -2,7 +2,8 @@
2
  /**
3
  * BuddyPress Members Directory
4
  *
5
- * @version 3.0.0
 
6
  */
7
 
8
  ?>
@@ -25,3 +26,5 @@
25
 
26
  <?php bp_nouveau_after_members_directory_content(); ?>
27
  </div><!-- // .screen-content -->
 
 
2
  /**
3
  * BuddyPress Members Directory
4
  *
5
+ * @since 3.0.0
6
+ * @version 6.0.0
7
  */
8
 
9
  ?>
26
 
27
  <?php bp_nouveau_after_members_directory_content(); ?>
28
  </div><!-- // .screen-content -->
29
+
30
+ <?php bp_nouveau_after_directory_page(); ?>
bp-templates/bp-nouveau/buddypress/members/members-loop.php CHANGED
@@ -3,7 +3,7 @@
3
  * BuddyPress - Members Loop
4
  *
5
  * @since 3.0.0
6
- * @version 3.0.0
7
  */
8
 
9
  bp_nouveau_before_loop(); ?>
@@ -38,9 +38,15 @@ bp_nouveau_before_loop(); ?>
38
  <?php if ( bp_nouveau_member_has_meta() ) : ?>
39
  <p class="item-meta last-activity">
40
  <?php bp_nouveau_member_meta(); ?>
41
- </p><!-- #item-meta -->
42
  <?php endif; ?>
43
 
 
 
 
 
 
 
44
  <?php
45
  bp_nouveau_members_loop_buttons(
46
  array(
@@ -48,20 +54,16 @@ bp_nouveau_before_loop(); ?>
48
  'button_element' => 'button',
49
  )
50
  );
51
- ?>
52
-
53
  </div>
54
 
55
  <?php if ( bp_get_member_latest_update() && ! bp_nouveau_loop_is_grid() ) : ?>
56
- <div class="user-update">
57
- <p class="update"> <?php bp_member_latest_update(); ?></p>
58
- </div>
59
- <?php endif; ?>
60
 
61
  </div><!-- // .item -->
62
-
63
-
64
-
65
  </div>
66
  </li>
67
 
3
  * BuddyPress - Members Loop
4
  *
5
  * @since 3.0.0
6
+ * @version 6.0.0
7
  */
8
 
9
  bp_nouveau_before_loop(); ?>
38
  <?php if ( bp_nouveau_member_has_meta() ) : ?>
39
  <p class="item-meta last-activity">
40
  <?php bp_nouveau_member_meta(); ?>
41
+ </p><!-- .item-meta -->
42
  <?php endif; ?>
43
 
44
+ <?php if ( bp_nouveau_member_has_extra_content() ) : ?>
45
+ <div class="item-extra-content">
46
+ <?php bp_nouveau_member_extra_content() ; ?>
47
+ </div><!-- .item-extra-content -->
48
+ <?php endif ; ?>
49
+
50
  <?php
51
  bp_nouveau_members_loop_buttons(
52
  array(
54
  'button_element' => 'button',
55
  )
56
  );
57
+ ?>
 
58
  </div>
59
 
60
  <?php if ( bp_get_member_latest_update() && ! bp_nouveau_loop_is_grid() ) : ?>
61
+ <div class="user-update">
62
+ <p class="update"> <?php bp_member_latest_update(); ?></p>
63
+ </div>
64
+ <?php endif; ?>
65
 
66
  </div><!-- // .item -->
 
 
 
67
  </div>
68
  </li>
69
 
bp-templates/bp-nouveau/buddypress/members/single/default-front.php CHANGED
@@ -16,6 +16,7 @@
16
  <button type="button" class="bp-tooltip" data-bp-tooltip="<?php echo esc_attr_x( 'Close', 'button', 'buddypress' ); ?>" aria-label="<?php esc_attr_e( 'Close this notice', 'buddypress' ); ?>" data-bp-close="remove"><span class="dashicons dashicons-dismiss" aria-hidden="true"></span></button><br/>
17
  <?php
18
  printf(
 
19
  esc_html__( 'You can set the preferences of the %1$s or add %2$s to it.', 'buddypress' ),
20
  bp_nouveau_members_get_customizer_option_link(),
21
  bp_nouveau_members_get_customizer_widgets_link()
16
  <button type="button" class="bp-tooltip" data-bp-tooltip="<?php echo esc_attr_x( 'Close', 'button', 'buddypress' ); ?>" aria-label="<?php esc_attr_e( 'Close this notice', 'buddypress' ); ?>" data-bp-close="remove"><span class="dashicons dashicons-dismiss" aria-hidden="true"></span></button><br/>
17
  <?php
18
  printf(
19
+ /* translators: 1: link to the customizer option. 2: link to the customizer widgets section. */
20
  esc_html__( 'You can set the preferences of the %1$s or add %2$s to it.', 'buddypress' ),
21
  bp_nouveau_members_get_customizer_option_link(),
22
  bp_nouveau_members_get_customizer_widgets_link()
bp-templates/bp-nouveau/buddypress/members/single/settings/general.php CHANGED
@@ -20,7 +20,12 @@ bp_nouveau_member_hook( 'before', 'settings_template' ); ?>
20
 
21
  <?php if ( ! is_super_admin() ) : ?>
22
 
23
- <label for="pwd"><?php printf( esc_html__( 'Current Password %s', 'buddypress' ), '<span>' . esc_html__( '(required to update email or change current password)', 'buddypress' ) . '</span>' ); ?></label>
 
 
 
 
 
24
  <input type="password" name="pwd" id="pwd" value="" size="24" class="settings-input small" <?php bp_form_field_attributes( 'password' ); ?>/> &nbsp;<a href="<?php echo esc_url( wp_lostpassword_url() ); ?>"><?php esc_html_e( 'Lost your password?', 'buddypress' ); ?></a>
25
 
26
  <?php endif; ?>
20
 
21
  <?php if ( ! is_super_admin() ) : ?>
22
 
23
+ <label for="pwd">
24
+ <?php
25
+ /* translators: %s: email requirement explanations */
26
+ printf( esc_html__( 'Current Password %s', 'buddypress' ), '<span>' . esc_html__( '(required to update email or change current password)', 'buddypress' ) . '</span>' );
27
+ ?>
28
+ </label>
29
  <input type="password" name="pwd" id="pwd" value="" size="24" class="settings-input small" <?php bp_form_field_attributes( 'password' ); ?>/> &nbsp;<a href="<?php echo esc_url( wp_lostpassword_url() ); ?>"><?php esc_html_e( 'Lost your password?', 'buddypress' ); ?></a>
30
 
31
  <?php endif; ?>
bp-templates/bp-nouveau/common-styles/_bp_activity_entries.scss CHANGED
@@ -55,7 +55,7 @@
55
  position: relative;
56
 
57
  .activity-avatar {
58
- margin-left: 0 auto;
59
  text-align: center;
60
  width: auto;
61
 
55
  position: relative;
56
 
57
  .activity-avatar {
58
+ margin-left: 0;
59
  text-align: center;
60
  width: auto;
61
 
bp-templates/bp-nouveau/common-styles/_bp_filters.scss CHANGED
@@ -127,7 +127,7 @@
127
 
128
  .bulk-apply {
129
  border: 0;
130
- border-radius: none;
131
  font-weight: 400;
132
  line-height: 1.8;
133
  margin: 0 0 0 10px;
127
 
128
  .bulk-apply {
129
  border: 0;
130
+ border-radius: 0;
131
  font-weight: 400;
132
  line-height: 1.8;
133
  margin: 0 0 0 10px;
bp-templates/bp-nouveau/common-styles/_bp_generic_and_typography.scss CHANGED
@@ -64,13 +64,10 @@ body.buddypress {
64
 
65
  .entry-header {
66
  float: none;
67
- max-width: none;
68
  }
69
 
70
- .entry-content,
71
- .entry .entry-content > * {
72
  float: none;
73
- max-width: none;
74
  }
75
 
76
  // 2017 has a very large top padding we'll reduce that for bp screens
64
 
65
  .entry-header {
66
  float: none;
 
67
  }
68
 
69
+ .entry-content {
 
70
  float: none;
 
71
  }
72
 
73
  // 2017 has a very large top padding we'll reduce that for bp screens
bp-templates/bp-nouveau/common-styles/_bp_layouts.scss CHANGED
@@ -2,7 +2,8 @@
2
  // Layouts provides classes to handle specific module
3
  // layouts on a user selectable basis.
4
  // The sheet also adds layout properties such as border-box
5
- // @version 3.0.0
 
6
 
7
  #item-body,
8
  .single-screen-navs {
@@ -659,5 +660,3 @@
659
  }
660
 
661
  } // close @media
662
-
663
-
2
  // Layouts provides classes to handle specific module
3
  // layouts on a user selectable basis.
4
  // The sheet also adds layout properties such as border-box
5
+ // @since 3.0.0
6
+ // @version 6.0.0
7
 
8
  #item-body,
9
  .single-screen-navs {
660
  }
661
 
662
  } // close @media
 
 
bp-templates/bp-nouveau/common-styles/_bp_members_loop.scss CHANGED
@@ -1,5 +1,6 @@
1
  // BP Members loop.
2
- // @version 3.0.0
 
3
 
4
  .buddypress-wrap {
5
 
@@ -11,6 +12,12 @@
11
  margin-bottom: $marg-sml;
12
  }
13
 
 
 
 
 
 
 
14
  .user-update {
15
  border: 1px solid $light-grey;
16
 
1
  // BP Members loop.
2
+ // @since 3.0.0
3
+ // @version 6.0.0
4
 
5
  .buddypress-wrap {
6
 
12
  margin-bottom: $marg-sml;
13
  }
14
 
15
+ .item-extra-content {
16
+ clear: both;
17
+
18
+ @include font-size(14);
19
+ }
20
+
21
  .user-update {
22
  border: 1px solid $light-grey;
23
 
bp-templates/bp-nouveau/common-styles/_bp_navigation.scss CHANGED
@@ -484,10 +484,6 @@
484
  background: none;
485
  margin-top: 2px;
486
 
487
- &.main-navs {
488
-
489
- }
490
-
491
  // For tabbed nav we remove any default button nav styles.
492
  ul {
493
 
484
  background: none;
485
  margin-top: 2px;
486
 
 
 
 
 
487
  // For tabbed nav we remove any default button nav styles.
488
  ul {
489
 
bp-templates/bp-nouveau/css/buddypress-rtl.css CHANGED
@@ -89,12 +89,9 @@ body #buddypress .bp-list .action {
89
  }
90
  body.buddypress .entry-header {
91
  float: none;
92
- max-width: none;
93
  }
94
- body.buddypress .entry-content,
95
- body.buddypress .entry .entry-content > * {
96
  float: none;
97
- max-width: none;
98
  }
99
  body.buddypress .site-content {
100
  padding-top: 2.5em;
@@ -752,7 +749,7 @@ body.buddypress article.page > .entry-header .entry-title {
752
 
753
  .buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-apply {
754
  border: 0;
755
- border-radius: none;
756
  font-weight: 400;
757
  line-height: 1.8;
758
  margin: 0 10px 0 0;
@@ -1275,7 +1272,7 @@ body.buddypress article.page > .entry-header .entry-title {
1275
  }
1276
 
1277
  .activity-list .activity-item.mini .activity-avatar {
1278
- margin-right: 0 auto;
1279
  text-align: center;
1280
  width: auto;
1281
  }
@@ -1877,6 +1874,11 @@ form.ac-form .ac-reply-content input {
1877
  margin-bottom: 10px;
1878
  }
1879
 
 
 
 
 
 
1880
  .buddypress-wrap .members-list li .user-update {
1881
  border: 1px solid #eaeaea;
1882
  border-radius: 10px;
89
  }
90
  body.buddypress .entry-header {
91
  float: none;
 
92
  }
93
+ body.buddypress .entry-content {
 
94
  float: none;
 
95
  }
96
  body.buddypress .site-content {
97
  padding-top: 2.5em;
749
 
750
  .buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-apply {
751
  border: 0;
752
+ border-radius: 0;
753
  font-weight: 400;
754
  line-height: 1.8;
755
  margin: 0 10px 0 0;
1272
  }
1273
 
1274
  .activity-list .activity-item.mini .activity-avatar {
1275
+ margin-right: 0;
1276
  text-align: center;
1277
  width: auto;
1278
  }
1874
  margin-bottom: 10px;
1875
  }
1876
 
1877
+ .buddypress-wrap .members-list li .item-extra-content {
1878
+ clear: both;
1879
+ font-size: 14px;
1880
+ }
1881
+
1882
  .buddypress-wrap .members-list li .user-update {
1883
  border: 1px solid #eaeaea;
1884
  border-radius: 10px;
bp-templates/bp-nouveau/css/buddypress-rtl.min.css CHANGED
@@ -1 +1 @@
1
- body #buddypress * a{box-shadow:none;text-decoration:none}body #buddypress div,body #buddypress dl,body #buddypress input[type=reset],body #buddypress input[type=search],body #buddypress input[type=submit],body #buddypress li,body #buddypress select,body #buddypress textarea{border-radius:2px;background-clip:padding-box}body #buddypress #item-body blockquote,body #buddypress .bp-lists blockquote{margin-right:0}body #buddypress .bp-list .action{box-sizing:border-box}@media screen and (min-width:46.8em){body.buddypress .entry-content,body.buddypress .entry-header,body.buddypress .site-content .entry-header{max-width:none}body.buddypress .entry-header{float:none;max-width:none}body.buddypress .entry .entry-content>*,body.buddypress .entry-content{float:none;max-width:none}body.buddypress .site-content{padding-top:2.5em}body.buddypress #page #primary{max-width:none}body.buddypress #page #primary .entry-content,body.buddypress #page #primary .entry-header{float:none;width:auto}}body.buddypress .buddypress-wrap h1,body.buddypress .buddypress-wrap h2,body.buddypress .buddypress-wrap h3,body.buddypress .buddypress-wrap h4,body.buddypress .buddypress-wrap h5,body.buddypress .buddypress-wrap h6{clear:none;margin:1em 0;padding:0}body.buddypress .buddypress-wrap h2:before{display:none}.bp-wrap:after,.bp-wrap:before{content:" ";display:table}.bp-wrap:after{clear:both}.buddypress-wrap.round-avatars .avatar{border-radius:50%}body.buddypress article.page>.entry-header{margin-bottom:2em;padding:0}body.buddypress article.page>.entry-header .entry-title{font-size:28px;font-weight:inherit;color:#767676}@media screen and (min-width:46.8em){body.buddypress article.page>.entry-header .entry-title{font-size:34px}}.buddypress-wrap dt.section-title{font-size:18px}@media screen and (min-width:46.8em){.buddypress-wrap dt.section-title{font-size:22px}}.buddypress-wrap .bp-label-text,.buddypress-wrap .message-threads{font-size:13px}@media screen and (min-width:46.8em){.buddypress-wrap .bp-label-text,.buddypress-wrap .message-threads{font-size:16px}}.buddypress-wrap .activity-header{font-size:13px}@media screen and (min-width:46.8em){.buddypress-wrap .activity-header{font-size:16px}}.buddypress-wrap .activity-inner{font-size:15px}@media screen and (min-width:46.8em){.buddypress-wrap .activity-inner{font-size:18px}}.buddypress-wrap #whats-new-post-in{font-size:16px}.buddypress-wrap .acomment-meta,.buddypress-wrap .mini .activity-header{font-size:16px}.buddypress-wrap .dir-component-filters #activity-filter-by{font-size:13px}@media screen and (min-width:46.8em){.buddypress-wrap .dir-component-filters #activity-filter-by{font-size:16px}}.buddypress-wrap .bp-tables-user th{font-size:13px}@media screen and (min-width:46.8em){.buddypress-wrap .bp-tables-user th{font-size:16px}}.buddypress-wrap .bp-tables-user td{font-size:12px}@media screen and (min-width:46.8em){.buddypress-wrap .bp-tables-user td{font-size:14px}}.buddypress-wrap .profile-fields th{font-size:15px}@media screen and (min-width:46.8em){.buddypress-wrap .profile-fields th{font-size:18px}}.buddypress-wrap .profile-fields td{font-size:13px}@media screen and (min-width:46.8em){.buddypress-wrap .profile-fields td{font-size:16px}}.buddypress-wrap #notification-select{font-size:12px}@media screen and (min-width:46.8em){.buddypress-wrap #notification-select{font-size:14px}}.bp-navs{background:0 0;clear:both;overflow:hidden}.bp-navs ul{margin:0;padding:0}.bp-navs ul li{list-style:none;margin:0}.bp-navs ul li.last select{max-width:185px}.bp-navs ul li a,.bp-navs ul li span{border:0;display:block;padding:5px 10px;text-decoration:none}.bp-navs ul li .count{background:#eaeaea;border:1px solid #ccc;border-radius:50%;color:#555;display:inline;font-size:12px;margin-right:2px;padding:3px 6px;text-align:center;vertical-align:middle}.bp-navs ul li.current a,.bp-navs ul li.selected a{color:#333;opacity:1}.bp-navs.bp-invites-filters ul li a,.bp-navs.bp-messages-filters ul li a{border:1px solid #ccc;display:inline-block}.main-navs.dir-navs{margin-bottom:20px}.buddypress-wrap .bp-navs li a:hover a .count,.buddypress-wrap .bp-navs li.current a .count,.buddypress-wrap .bp-navs li.selected a .count{background-color:#ccc}.buddypress-wrap .bp-navs li:not(.current) a:focus,.buddypress-wrap .bp-navs li:not(.current) a:hover,.buddypress-wrap .bp-navs li:not(.selected) a:focus,.buddypress-wrap .bp-navs li:not(.selected) a:hover{background:#ccc;color:#333}.buddypress-wrap .bp-navs li.current a,.buddypress-wrap .bp-navs li.current a:focus,.buddypress-wrap .bp-navs li.current a:hover,.buddypress-wrap .bp-navs li.selected a,.buddypress-wrap .bp-navs li.selected a:focus,.buddypress-wrap .bp-navs li.selected a:hover{background:#555;color:#fafafa}@media screen and (min-width:46.8em){.buddypress-wrap .main-navs:not(.dir-navs) li.current a,.buddypress-wrap .main-navs:not(.dir-navs) li.selected a{background:#fff;color:#333;font-weight:600}.buddypress-wrap .main-navs.vertical li.current a,.buddypress-wrap .main-navs.vertical li.selected a{background:#555;color:#fafafa;text-decoration:none}.buddypress-wrap.bp-dir-hori-nav:not(.bp-vertical-navs) nav:not(.tabbed-links){border-bottom:1px solid #eee;border-top:1px solid #eee;box-shadow:0 2px 12px 0 #fafafa}}.buddypress-wrap .bp-subnavs li.current a,.buddypress-wrap .bp-subnavs li.selected a{background:#fff;color:#333;font-weight:600}@media screen and (max-width:46.8em){.buddypress-wrap:not(.bp-single-vert-nav) .bp-navs li{background:#eaeaea}}.buddypress-wrap:not(.bp-single-vert-nav) .main-navs>ul>li>a{padding:.5em calc(.5em + 2px)}.buddypress-wrap:not(.bp-single-vert-nav) .group-subnav#subsubnav,.buddypress-wrap:not(.bp-single-vert-nav) .user-subnav#subsubnav{background:0 0}.buddypress-wrap .bp-subnavs,.buddypress-wrap ul.subnav{width:100%}.buddypress-wrap .bp-subnavs{margin:10px 0;overflow:hidden}.buddypress-wrap .bp-subnavs ul li{margin-top:0}.buddypress-wrap .bp-subnavs ul li.current :focus,.buddypress-wrap .bp-subnavs ul li.current :hover,.buddypress-wrap .bp-subnavs ul li.selected :focus,.buddypress-wrap .bp-subnavs ul li.selected :hover{background:0 0;color:#333}.buddypress-wrap ul.subnav{width:auto}.buddypress-wrap .bp-navs.bp-invites-filters#subsubnav ul li.last,.buddypress-wrap .bp-navs.bp-invites-nav#subnav ul li.last,.buddypress-wrap .bp-navs.bp-messages-filters#subsubnav ul li.last{margin-top:0}@media screen and (max-width:46.8em){.buddypress-wrap .single-screen-navs{border:1px solid #eee}.buddypress-wrap .single-screen-navs li{border-bottom:1px solid #eee}.buddypress-wrap .single-screen-navs li:last-child{border-bottom:none}.buddypress-wrap .bp-subnavs li a{font-size:14px}.buddypress-wrap .bp-subnavs li.current a,.buddypress-wrap .bp-subnavs li.current a:focus,.buddypress-wrap .bp-subnavs li.current a:hover,.buddypress-wrap .bp-subnavs li.selected a,.buddypress-wrap .bp-subnavs li.selected a:focus,.buddypress-wrap .bp-subnavs li.selected a:hover{background:#555;color:#fff}}.buddypress-wrap .bp-navs li.current a .count,.buddypress-wrap .bp-navs li.selected a .count,.buddypress_object_nav .bp-navs li.current a .count,.buddypress_object_nav .bp-navs li.selected a .count{background-color:#fff}.buddypress-wrap .bp-navs li.dynamic a .count,.buddypress-wrap .bp-navs li.dynamic.current a .count,.buddypress-wrap .bp-navs li.dynamic.selected a .count,.buddypress_object_nav .bp-navs li.dynamic a .count,.buddypress_object_nav .bp-navs li.dynamic.current a .count,.buddypress_object_nav .bp-navs li.dynamic.selected a .count{background-color:#5087e5;border:0;color:#fafafa}.buddypress-wrap .bp-navs li.dynamic a:hover .count,.buddypress_object_nav .bp-navs li.dynamic a:hover .count{background-color:#5087e5;border:0;color:#fff}.buddypress-wrap .bp-navs li a .count:empty,.buddypress_object_nav .bp-navs li a .count:empty{display:none}.buddypress-wrap .bp-navs.group-create-links ul li:not(.current),.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current){color:#767676}.buddypress-wrap .bp-navs.group-create-links ul li:not(.current) a,.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a{color:#767676}.buddypress-wrap .bp-navs.group-create-links ul li:not(.current) a:focus,.buddypress-wrap .bp-navs.group-create-links ul li:not(.current) a:hover,.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a:focus,.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a:hover{background:0 0;color:#333}.buddypress-wrap .bp-navs.group-create-links ul li:not(.current) a[disabled]:focus,.buddypress-wrap .bp-navs.group-create-links ul li:not(.current) a[disabled]:hover,.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a[disabled]:focus,.buddypress_object_nav .bp-navs.group-create-links ul li:not(.current) a[disabled]:hover{color:#767676}.buddypress-wrap .bp-navs.group-create-links ul li.current a,.buddypress_object_nav .bp-navs.group-create-links ul li.current a{text-align:center}@media screen and (min-width:46.8em){.buddypress-wrap .bp-navs li{float:right}.buddypress-wrap .subnav{float:right}.buddypress-wrap ul.subnav{width:auto}.buddypress-wrap #subsubnav .activity-search{float:right}.buddypress-wrap #subsubnav .filter{float:left}}.buddypress_object_nav .bp-navs li a .count{display:inline-block;float:left}@media screen and (min-width:46.8em){.bp-dir-vert-nav .bp-navs.dir-navs{background:0 0}.bp-dir-vert-nav .bp-navs.dir-navs a .count{float:left}}@media screen and (min-width:46.8em){.buddypress-wrap .tabbed-links ol,.buddypress-wrap .tabbed-links ul{border-bottom:1px solid #ccc;float:none;margin:20px 0 10px}.buddypress-wrap .tabbed-links ol:after,.buddypress-wrap .tabbed-links ol:before,.buddypress-wrap .tabbed-links ul:after,.buddypress-wrap .tabbed-links ul:before{content:" ";display:block}.buddypress-wrap .tabbed-links ol:after,.buddypress-wrap .tabbed-links ul:after{clear:both}.buddypress-wrap .tabbed-links ol li,.buddypress-wrap .tabbed-links ul li{float:right;list-style:none;margin:0 0 0 10px}.buddypress-wrap .tabbed-links ol li a,.buddypress-wrap .tabbed-links ol li span:not(.count),.buddypress-wrap .tabbed-links ul li a,.buddypress-wrap .tabbed-links ul li span:not(.count){background:0 0;border:none;display:block;padding:4px 10px}.buddypress-wrap .tabbed-links ol li a:focus,.buddypress-wrap .tabbed-links ol li a:hover,.buddypress-wrap .tabbed-links ul li a:focus,.buddypress-wrap .tabbed-links ul li a:hover{background:0 0}.buddypress-wrap .tabbed-links ol li:not(.current),.buddypress-wrap .tabbed-links ul li:not(.current){margin-bottom:2px}.buddypress-wrap .tabbed-links ol li.current,.buddypress-wrap .tabbed-links ul li.current{border-color:#ccc #ccc #fff;border-style:solid;border-top-right-radius:4px;border-top-left-radius:4px;border-width:1px;margin-bottom:-1px;padding:0 .5em 1px}.buddypress-wrap .tabbed-links ol li.current a,.buddypress-wrap .tabbed-links ul li.current a{background:0 0;color:#333}.buddypress-wrap .bp-subnavs.tabbed-links>ul{margin-top:0}.buddypress-wrap .bp-navs.tabbed-links{background:0 0;margin-top:2px}.buddypress-wrap .bp-navs.tabbed-links ul li a{border-left:0;font-size:inherit}.buddypress-wrap .bp-navs.tabbed-links ul li.last{float:left;margin:0}.buddypress-wrap .bp-navs.tabbed-links ul li.last a{margin-top:-.5em}.buddypress-wrap .bp-navs.tabbed-links ul li a,.buddypress-wrap .bp-navs.tabbed-links ul li a:focus,.buddypress-wrap .bp-navs.tabbed-links ul li a:hover,.buddypress-wrap .bp-navs.tabbed-links ul li.current a,.buddypress-wrap .bp-navs.tabbed-links ul li.current a:focus,.buddypress-wrap .bp-navs.tabbed-links ul li.current a:hover{background:0 0;border:0}.buddypress-wrap .bp-navs.tabbed-links ul li a:active,.buddypress-wrap .bp-navs.tabbed-links ul li.current a:active{outline:0}}.buddypress-wrap .dir-component-filters .filter label{display:inline}.buddypress-wrap .subnav-filters:after,.buddypress-wrap .subnav-filters:before{content:" ";display:table}.buddypress-wrap .subnav-filters:after{clear:both}.buddypress-wrap .subnav-filters{background:0 0;list-style:none;margin:15px 0 0;padding:0}.buddypress-wrap .subnav-filters div{margin:0}.buddypress-wrap .subnav-filters>ul{float:right;list-style:none}.buddypress-wrap .subnav-filters.bp-messages-filters ul{width:100%}.buddypress-wrap .subnav-filters.bp-messages-filters .messages-search{margin-bottom:1em}@media screen and (min-width:46.8em){.buddypress-wrap .subnav-filters.bp-messages-filters .messages-search{margin-bottom:0}}.buddypress-wrap .subnav-filters div{float:none}.buddypress-wrap .subnav-filters div input[type=search],.buddypress-wrap .subnav-filters div select{font-size:16px}.buddypress-wrap .subnav-filters div button.nouveau-search-submit{padding:5px .8em 6px}.buddypress-wrap .subnav-filters div button#user_messages_search_submit{padding:7px .8em}.buddypress-wrap .subnav-filters .component-filters{margin-top:10px}.buddypress-wrap .subnav-filters .feed{margin-left:15px}.buddypress-wrap .subnav-filters .last.filter label{display:inline}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-actions-wrap:after,.buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-actions-wrap:before{content:" ";display:table}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-actions-wrap:after{clear:both}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-actions-wrap.bp-show{display:inline-block}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-actions-wrap.bp-hide{display:none}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .select-wrap{border:0}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .select-wrap:focus,.buddypress-wrap .subnav-filters .user-messages-bulk-actions .select-wrap:hover{outline:1px solid #d6d6d6}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-actions{float:right}.buddypress-wrap .subnav-filters .user-messages-bulk-actions label{display:inline-block;font-weight:300;margin-left:25px;padding:5px 0}.buddypress-wrap .subnav-filters .user-messages-bulk-actions div select{-webkit-appearance:textfield}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-apply{border:0;border-radius:none;font-weight:400;line-height:1.8;margin:0 10px 0 0;padding:3px 5px;text-align:center;text-transform:none;width:auto}.buddypress-wrap .subnav-filters .user-messages-bulk-actions .bulk-apply span{vertical-align:middle}@media screen and (min-width:32em){.buddypress-wrap .subnav-filters li{margin-bottom:0}.buddypress-wrap .subnav-filters .bp-search,.buddypress-wrap .subnav-filters .dir-search,.buddypress-wrap .subnav-filters .feed,.buddypress-wrap .subnav-filters .group-act-search,.buddypress-wrap .subnav-filters .group-invites-search,.buddypress-wrap .subnav-filters .subnav-search,.buddypress-wrap .subnav-filters .subnav-search form,.buddypress-wrap .subnav-filters .user-messages-bulk-actions,.buddypress-wrap .subnav-filters .user-messages-search{float:right}.buddypress-wrap .subnav-filters .component-filters,.buddypress-wrap .subnav-filters .last{float:left;margin-top:0;width:auto}.buddypress-wrap .subnav-filters .component-filters select,.buddypress-wrap .subnav-filters .last select{max-width:250px}.buddypress-wrap .subnav-filters .user-messages-search{float:left}}.buddypress-wrap .notifications-options-nav input#notification-bulk-manage{border:0;border-radius:0;line-height:1.6}.buddypress-wrap .group-subnav-filters .group-invites-search{margin-bottom:1em}.buddypress-wrap .group-subnav-filters .last{text-align:center}.buddypress-wrap .bp-pagination{background:0 0;border:0;color:#767676;float:right;font-size:small;margin:0;padding:.5em 0;position:relative;width:100%}.buddypress-wrap .bp-pagination .pag-count{float:right}.buddypress-wrap .bp-pagination .bp-pagination-links{float:left;margin-left:10px}.buddypress-wrap .bp-pagination .bp-pagination-links a,.buddypress-wrap .bp-pagination .bp-pagination-links span{font-size:small;padding:0 5px}.buddypress-wrap .bp-pagination .bp-pagination-links a:focus,.buddypress-wrap .bp-pagination .bp-pagination-links a:hover{opacity:1}.buddypress-wrap .bp-pagination p{margin:0}.bp-list:after,.bp-list:before{content:" ";display:table}.bp-list:after{clear:both}.bp-list{box-sizing:border-box;border-top:1px solid #eaeaea;clear:both;list-style:none;margin:20px 0;padding:.5em 0;width:100%}.bp-list li:after,.bp-list li:before{content:" ";display:table}.bp-list li:after{clear:both}.bp-list>li{border-bottom:1px solid #eaeaea}.bp-list li{list-style:none;margin:10px 0;padding:.5em 0;position:relative}.bp-list li .item-avatar{text-align:center}.bp-list li .item-avatar img.avatar{display:inline-block;width:auto;height:auto}.bp-list li .item .group-details,.bp-list li .item .item-avatar,.bp-list li .item .item-meta,.bp-list li .item .list-title{text-align:center}.bp-list li .item .list-title{clear:none;font-size:22px;font-weight:400;line-height:1.1;margin:0 auto}@media screen and (min-width:46.8em){.bp-list li .item .list-title{font-size:26px}}.bp-list li .item-meta,.bp-list li .meta{color:#737373;font-size:12px;margin-bottom:10px;margin-top:10px}.bp-list li .last-post{text-align:center}.bp-list li .action{margin:0;text-align:center}.bp-list li .action .generic-button{display:inline-block;font-size:12px;margin:0 0 0 10px}.bp-list li .action div.generic-button{margin:10px 0}@media screen and (min-width:46.8em){.bp-list li .item-avatar{float:right;margin-left:5%}.bp-list li .item{margin:0;overflow:hidden}.bp-list li .item .item-block{float:right;margin-left:2%;width:50%}.bp-list li .item .item-meta,.bp-list li .item .list-title{float:right;text-align:right}.bp-list li .item .group-details,.bp-list li .item .last-post{text-align:right}.bp-list li .group-desc,.bp-list li .last-post,.bp-list li .user-update{clear:none;overflow:hidden;width:auto}.bp-list li .action{clear:right;padding:0;text-align:right}.bp-list li .action li.generic-button{margin-left:0}.bp-list li .action div.generic-button{margin:0 0 10px}.bp-list li .generic-button{display:block;margin:0 0 5px 0}}@media screen and (min-width:32em){#activity-stream{clear:both;padding-top:1em}}.activity-list.bp-list{background:#fafafa;border:1px solid #eee}.activity-list.bp-list .activity-item{background:#fff;border:1px solid #b7b7b7;box-shadow:0 0 6px #d2d2d2;margin:20px 0}.activity-list.bp-list li:first-child{margin-top:0}.friends-list{list-style-type:none}.friends-request-list .item-title,.membership-requests-list .item-title{text-align:center}@media screen and (min-width:46.8em){.friends-request-list li,.membership-requests-list li{display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-o-flex-flow:row nowrap;flex-flow:row nowrap}.friends-request-list li .item,.membership-requests-list li .item{-moz-flex:1 1 auto;-o-flex:1 1 auto;flex:1 1 auto}.friends-request-list li .action,.membership-requests-list li .action{text-align:left}.friends-request-list li .item-title,.membership-requests-list li .item-title{font-size:22px;text-align:right}.friends-request-list li .item-title h3,.membership-requests-list li .item-title h3{margin:0}}#notifications-user-list{clear:both;padding-top:1em}@media screen and (min-width:46.8em){body:not(.logged-in) .bp-list .item{margin-left:0}}.activity-permalink .item-list,.activity-permalink .item-list li.activity-item{border:0}.activity-update-form{padding:10px 10px 0}.item-body .activity-update-form .activity-form{margin:0;padding:0}.activity-update-form{border:1px solid #ccc;box-shadow:inset 0 0 6px #eee;margin:15px 0}.activity-update-form #whats-new-avatar{margin:10px 0;text-align:center}.activity-update-form #whats-new-avatar img{box-shadow:none;display:inline-block;height:auto;width:auto}.activity-update-form #whats-new-content{padding:0 0 20px 0}.activity-update-form #whats-new-textarea textarea{background:#fff;box-sizing:border-box;color:#333;font-family:inherit;font-size:medium;height:2.2em;line-height:1.4;padding:6px;width:100%}.activity-update-form #whats-new-textarea textarea:focus{box-shadow:0 0 6px 0 #d6d6d6}.activity-update-form #whats-new-post-in-box{margin:10px 0}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items{list-style:none;margin:10px 0;padding-right:0}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items li{margin-bottom:10px}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items button.bp-remove-item{margin-right:10px;height:auto}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items #activity-autocomplete{padding:.3em;width:100%}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items .bp-activity-object{display:flex;align-items:center;padding:.2em}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items .bp-activity-object .avatar{width:30px;height:30px}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items .bp-activity-object span{padding-right:10px;vertical-align:middle}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items .bp-activity-object:focus,.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items .bp-activity-object:hover{background:#eaeaea;cursor:pointer}.activity-update-form #whats-new-post-in-box #whats-new-post-in-box-items .bp-activity-object.selected{border:1px solid #d6d6d6}.activity-update-form #whats-new-submit{margin:15px 0 10px}.activity-update-form #whats-new-submit input{font-size:14px;line-height:inherit;margin-bottom:10px;margin-left:10px;padding:.2em 0;text-align:center;width:100%}@media screen and (min-width:46.8em){.activity-update-form #whats-new-avatar{display:block;float:right;margin:0}.activity-update-form #whats-new-content,.activity-update-form #whats-new-post-in-box,.activity-update-form #whats-new-submit{margin-right:55px}.activity-update-form #whats-new-submit input{margin-bottom:0;margin-left:10px;width:8em}}.activity-list{padding:.5em}.activity-list .activity-item:after,.activity-list .activity-item:before{content:" ";display:table}.activity-list .activity-item:after{clear:both}.activity-list .activity-item{list-style:none;padding:1em}.activity-list .activity-item.has-comments{padding-bottom:1em}.activity-list .activity-item div.item-avatar{margin:0 auto;text-align:center;width:auto}.activity-list .activity-item div.item-avatar img{height:auto;max-width:40%}@media screen and (min-width:46.8em){.activity-list .activity-item div.item-avatar{margin:0 0 0 2%;text-align:right;width:15%}.activity-list .activity-item div.item-avatar img{max-width:80%}}.activity-list .activity-item.mini{font-size:13px;position:relative}.activity-list .activity-item.mini .activity-avatar{margin-right:0 auto;text-align:center;width:auto}.activity-list .activity-item.mini .activity-avatar img.FB_profile_pic,.activity-list .activity-item.mini .activity-avatar img.avatar{max-width:15%}@media screen and (min-width:46.8em){.activity-list .activity-item.mini .activity-avatar{margin-right:15px;text-align:right;width:15%}.activity-list .activity-item.mini .activity-avatar img.FB_profile_pic,.activity-list .activity-item.mini .activity-avatar img.avatar{max-width:60%}}.activity-list .activity-item.new_forum_post .activity-inner,.activity-list .activity-item.new_forum_topic .activity-inner{border-right:2px solid #eaeaea;margin-right:10px;padding-right:1em}.activity-list .activity-item.newest_blogs_activity,.activity-list .activity-item.newest_friends_activity,.activity-list .activity-item.newest_groups_activity,.activity-list .activity-item.newest_mentions_activity{background:rgba(31,179,221,.1)}.activity-list .activity-item .activity-inreplyto{color:#767676;font-size:13px}.activity-list .activity-item .activity-inreplyto>p{display:inline;margin:0}.activity-list .activity-item .activity-inreplyto .activity-inner,.activity-list .activity-item .activity-inreplyto blockquote{background:0 0;border:0;display:inline;margin:0;overflow:hidden;padding:0}.activity-list .activity-item .activity-header{margin:0 auto;width:80%}.activity-list .activity-item .activity-header a,.activity-list .activity-item .activity-header img{display:inline}.activity-list .activity-item .activity-header .avatar{display:inline-block;margin:0 5px;vertical-align:text-top;width:20px;height:20px}.activity-list .activity-item .activity-header .time-since{font-size:14px;color:#767676;text-decoration:none}.activity-list .activity-item .activity-header .time-since:hover{color:#767676;cursor:pointer;text-decoration:underline}.activity-list .activity-item .activity-content .activity-header,.activity-list .activity-item .activity-content .comment-header{color:#767676;margin-bottom:10px}.activity-list .activity-item .activity-content .activity-inner,.activity-list .activity-item .activity-content blockquote{background:#fafafa;margin:15px 0 10px;overflow:hidden;padding:1em}.activity-list .activity-item .activity-content p{margin:0}.activity-list .activity-item .activity-inner p{word-wrap:break-word}.activity-list .activity-item .activity-read-more{margin-right:1em;white-space:nowrap}.activity-list .activity-item ul.activity-meta{margin:0;padding-right:0}.activity-list .activity-item ul.activity-meta li{border:0;display:inline-block}.activity-list .activity-item .activity-meta.action{border:1px solid transparent;background:#fafafa;padding:2px;position:relative;text-align:right}.activity-list .activity-item .activity-meta.action div.generic-button{margin:0}.activity-list .activity-item .activity-meta.action .button{background:0 0;color:#555}.activity-list .activity-item .activity-meta.action a{padding:4px 8px}.activity-list .activity-item .activity-meta.action .button:focus,.activity-list .activity-item .activity-meta.action .button:hover{background:0 0}.activity-list .activity-item .activity-meta.action .button:before,.activity-list .activity-item .activity-meta.action .icons:before{font-family:dashicons;font-size:18px;vertical-align:middle}.activity-list .activity-item .activity-meta.action .acomment-reply.button:before{content:"\f101"}.activity-list .activity-item .activity-meta.action .view:before{content:"\f125"}.activity-list .activity-item .activity-meta.action .fav:before{content:"\f154"}.activity-list .activity-item .activity-meta.action .unfav:before{content:"\f155"}.activity-list .activity-item .activity-meta.action .delete-activity:before{content:"\f153"}.activity-list .activity-item .activity-meta.action .delete-activity:hover{color:#800}.activity-list .activity-item .activity-meta.action .button{border:0;box-shadow:none}.activity-list .activity-item .activity-meta.action .button span{background:0 0;color:#555;font-weight:700}@media screen and (min-width:46.8em){.activity-list.bp-list{padding:30px}.activity-list .activity-item .activity-content{margin:0;position:relative}.activity-list .activity-item .activity-content:after{clear:both;content:"";display:table}.activity-list .activity-item .activity-header{margin:0 0 0 15px;width:auto}}.buddypress-wrap .activity-list .load-more,.buddypress-wrap .activity-list .load-newest{background:#fafafa;border:1px solid #eee;font-size:110%;margin:15px 0;padding:0;text-align:center}.buddypress-wrap .activity-list .load-more a,.buddypress-wrap .activity-list .load-newest a{color:#555;display:block;padding:.5em 0}.buddypress-wrap .activity-list .load-more a:focus,.buddypress-wrap .activity-list .load-more a:hover,.buddypress-wrap .activity-list .load-newest a:focus,.buddypress-wrap .activity-list .load-newest a:hover{background:#fff;color:#333}.buddypress-wrap .activity-list .load-more:focus,.buddypress-wrap .activity-list .load-more:hover,.buddypress-wrap .activity-list .load-newest:focus,.buddypress-wrap .activity-list .load-newest:hover{border-color:#e1e1e1;box-shadow:0 0 6px 0 #eaeaea}body.activity-permalink .activity-list li{border-width:1px;padding:1em 0 0 0}body.activity-permalink .activity-list li:first-child{padding-top:0}body.activity-permalink .activity-list li.has-comments{padding-bottom:0}body.activity-permalink .activity-list .activity-avatar{width:auto}body.activity-permalink .activity-list .activity-avatar a{display:block}body.activity-permalink .activity-list .activity-avatar img{max-width:100%;background-color:#eaeaea}body.activity-permalink .activity-list .activity-content{border:0;font-size:100%;line-height:1.5;padding:0}body.activity-permalink .activity-list .activity-content .activity-header{margin:0;padding:.5em 0 0 0;text-align:center;width:100%}body.activity-permalink .activity-list .activity-content .activity-inner,body.activity-permalink .activity-list .activity-content blockquote{margin-right:0;margin-top:10px}body.activity-permalink .activity-list .activity-meta{margin:10px 0 10px}body.activity-permalink .activity-list .activity-comments{margin-bottom:10px}@media screen and (min-width:46.8em){body.activity-permalink .activity-list .activity-avatar{right:-20px;margin-left:0;position:relative;top:-20px}body.activity-permalink .activity-list .activity-avatar img{box-shadow:0 0 0 8px #fff}body.activity-permalink .activity-list .activity-content{margin-left:10px}body.activity-permalink .activity-list .activity-content .activity-header p{text-align:right}}.buddypress-wrap .activity-comments{clear:both;margin:0 5%;overflow:hidden;position:relative;width:auto}.buddypress-wrap .activity-comments ul{clear:both;list-style:none;margin:15px 0 0;padding:0}.buddypress-wrap .activity-comments ul li{border-top:1px solid #eee;border-bottom:0;padding:1em 0 0}.buddypress-wrap .activity-comments ul li ul{margin-right:5%}.buddypress-wrap .activity-comments ul li:first-child{border-top:0}.buddypress-wrap .activity-comments ul li:last-child{margin-bottom:0}.buddypress-wrap .activity-comments div.acomment-avatar{width:auto}.buddypress-wrap .activity-comments div.acomment-avatar img{border-width:1px;float:right;height:25px;max-width:none;width:25px}.buddypress-wrap .activity-comments .acomment-content p,.buddypress-wrap .activity-comments .acomment-meta{font-size:14px}.buddypress-wrap .activity-comments .acomment-meta{color:#555;overflow:hidden;padding-right:2%}.buddypress-wrap .activity-comments .acomment-content{border-right:1px solid #ccc;margin:15px 10% 0 0;padding:.5em 1em}.buddypress-wrap .activity-comments .acomment-content p{margin-bottom:.5em}.buddypress-wrap .activity-comments .acomment-options{float:right;margin:10px 20px 10px 0}.buddypress-wrap .activity-comments .acomment-options a{color:#767676;font-size:14px}.buddypress-wrap .activity-comments .acomment-options a:focus,.buddypress-wrap .activity-comments .acomment-options a:hover{color:inherit}.buddypress-wrap .activity-comments .activity-meta.action{background:0 0;margin-top:10px}.buddypress-wrap .activity-comments .activity-meta.action button{font-size:14px;font-weight:400;text-transform:none}.buddypress-wrap .activity-comments .show-all button{font-size:14px;text-decoration:underline;padding-right:.5em}.buddypress-wrap .activity-comments .show-all button span{text-decoration:none}.buddypress-wrap .activity-comments .show-all button:focus span,.buddypress-wrap .activity-comments .show-all button:hover span{color:#5087e5}.buddypress-wrap .mini .activity-comments{clear:both;margin-top:0}body.activity-permalink .activity-comments{background:0 0;width:auto}body.activity-permalink .activity-comments>ul{padding:0 1em 0 .5em}body.activity-permalink .activity-comments ul li>ul{margin-top:10px}form.ac-form{display:none;padding:1em}form.ac-form .ac-reply-avatar{float:right}form.ac-form .ac-reply-avatar img{border:1px solid #eee}form.ac-form .ac-reply-content{color:#767676;padding-right:1em}form.ac-form .ac-reply-content a{text-decoration:none}form.ac-form .ac-reply-content .ac-textarea{margin-bottom:15px;padding:0 .5em;overflow:hidden}form.ac-form .ac-reply-content .ac-textarea textarea{background:0 0;box-shadow:none;color:#555;font-family:inherit;font-size:100%;height:60px;margin:0;outline:0;padding:.5em;width:100%}form.ac-form .ac-reply-content .ac-textarea textarea:focus{box-shadow:0 0 6px #d6d6d6}form.ac-form .ac-reply-content input{margin-top:10px}.activity-comments li form.ac-form{clear:both;margin-left:15px}.activity-comments form.root{margin-right:0}@media screen and (min-width:46.8em){.buddypress-wrap .blogs-list li .item-block{float:none;width:auto}.buddypress-wrap .blogs-list li .item-meta{clear:right;float:none}}@media screen and (min-width:46.8em){.buddypress-wrap .bp-dir-vert-nav .blogs-list .list-title{width:auto}}.buddypress-wrap .groups-list li .list-title{text-align:center}.buddypress-wrap .groups-list li .group-details{clear:right}.buddypress-wrap .groups-list li .group-desc{border:1px solid #eaeaea;border-radius:10px;background-clip:padding-box;font-size:13px;color:#737373;font-style:italic;margin:10px auto 0;padding:1em}@media screen and (min-width:46.8em){.buddypress-wrap .groups-list li .group-desc{font-size:16px}}.buddypress-wrap .groups-list li p{margin:0 0 .5em}@media screen and (min-width:46.8em){.buddypress-wrap .groups-list li .item{margin-left:0}.buddypress-wrap .groups-list li .item-meta,.buddypress-wrap .groups-list li .list-title{text-align:right;width:auto}.buddypress-wrap .groups-list li .item-meta{margin-bottom:20px}.buddypress-wrap .groups-list li .last-activity{clear:right;margin-top:-20px}}.buddypress-wrap .groups-list li.group-no-avatar div.group-desc{margin-right:0}.buddypress-wrap .mygroups .groups-list.grid .wrap{min-height:450px;padding-bottom:0}@media screen and (min-width:46.8em){.buddypress-wrap .groups-list.grid.four .group-desc,.buddypress-wrap .groups-list.grid.three .group-desc{font-size:14px}}@media screen and (min-width:46.8em){.buddypress .bp-vertical-navs .groups-list .item-avatar{margin-left:3%;width:15%}}.buddypress-wrap .members-list li .member-name{margin-bottom:10px}.buddypress-wrap .members-list li .user-update{border:1px solid #eaeaea;border-radius:10px;background-clip:padding-box;color:#737373;font-style:italic;font-size:13px;margin:15px auto;padding:1em}@media screen and (min-width:46.8em){.buddypress-wrap .members-list li .user-update{font-size:16px}}.buddypress-wrap .members-list li .user-update .activity-read-more{display:block;font-size:12px;font-style:normal;margin-top:10px;padding-right:2px}@media screen and (min-width:46.8em){.buddypress-wrap .members-list li .last-activity{clear:right;margin-top:-10px}}@media screen and (min-width:46.8em){.buddypress-wrap .members-group-list li .joined{clear:right;float:none}}@media screen and (min-width:32em){body:not(.logged-in) .members-list .user-update{width:96%}}.register-page .register-section{box-sizing:border-box}.register-page .signup-form{margin-top:20px}.register-page .signup-form .default-profile input{margin-bottom:20px}.register-page .signup-form label,.register-page .signup-form legend{margin:10px 0 0}.register-page .signup-form .editfield{margin:15px 0}.register-page .signup-form .editfield fieldset{border:0;padding:0}.register-page .signup-form .editfield fieldset legend{margin:0 0 5px;text-indent:0}.register-page .signup-form .editfield .field-visibility-settings{padding:.5em}.register-page .signup-form .editfield .field-visibility-settings fieldset{margin:0 0 10px}.register-page .signup-form #signup-avatar img{margin:0 0 10px 15px}.register-page .signup-form .wp-pwd button{vertical-align:middle}.register-page .signup-form #pass-strength-result,.register-page .signup-form #pass1,.register-page .signup-form #pass1-text{width:10em}.register-page .signup-form #pass1{display:inline-block;margin-bottom:inherit}.register-page .signup-form #pass1-text,.register-page .signup-form .pw-weak{display:none}.register-page .signup-form .show-password #pass1-text{display:inline-block;margin-bottom:inherit}.register-page .signup-form .show-password #pass1{display:none}.register-page .signup-form .description.indicator-hint{font-size:14px}.register-page .signup-form #submit:disabled{color:#767676;opacity:.4}.register-page .signup-form .password-entry,.register-page .signup-form .password-entry-confirm{border:1px solid #eee}body.buddypress.register.js .user-pass2-wrap{display:none}body.buddypress.register.no-js .wp-hide-pw{display:none}@media screen and (min-width:46.8em){.buddypress-wrap .register-page .layout-wrap{display:flex;flex-flow:row wrap;justify-content:space-around}.buddypress-wrap .register-page .layout-wrap .default-profile{flex:1;padding-left:2em}.buddypress-wrap .register-page .layout-wrap .blog-details{flex:1;padding-right:2em}.buddypress-wrap .register-page .submit{clear:both}}@media screen and (min-width:46.8em){.buddypress-wrap.extended-default-reg .register-page .default-profile{min-width:14em;flex:1;padding-left:1em}.buddypress-wrap.extended-default-reg .register-page .extended-profile{flex:2;padding-right:1em}.buddypress-wrap.extended-default-reg .register-page .blog-details{flex:1 100%}}#group-create-body{padding:.5em}#group-create-body .creation-step-name{text-align:center}#group-create-body img.avatar{width:auto;height:auto}#group-create-body .avatar-nav-items{margin-top:15px}.single-headers:after,.single-headers:before{content:" ";display:table}.single-headers:after{clear:both}.single-headers{margin-bottom:15px}.single-headers #item-header-avatar a{display:block;text-align:center}.single-headers #item-header-avatar a img{float:none;width:auto;height:auto}.single-headers div#item-header-content{float:none}@media screen and (min-width:46.8em){.single-headers #item-header-avatar a{text-align:right}.single-headers #item-header-avatar a img{float:right}.single-headers #item-header-content{padding-right:2em}}.single-headers .activity,.single-headers .group-status{display:inline}.single-headers .group-status{font-size:18px;color:#333;padding-left:1em}.single-headers .activity{display:inline-block;font-size:12px;padding:0}.single-headers #sitewide-notice p,.single-headers div#message p{background-color:#ffd;border:1px solid #cb2;color:#440;font-weight:400;margin-top:3px;text-decoration:none}.single-headers h2{line-height:1.2;margin:0 0 5px}.single-headers h2 a{color:#767676;text-decoration:none}.single-headers h2 span.highlight{display:inline-block;font-size:60%;font-weight:400;line-height:1.7;vertical-align:middle}.single-headers h2 span.highlight span{background:#a1dcfa;color:#fff;cursor:pointer;font-size:80%;font-weight:700;margin-bottom:2px;padding:1px 4px;position:relative;left:-2px;top:-2px;vertical-align:middle}.single-headers img.avatar{float:right;margin:0 0 19px 15px}.single-headers .item-meta{color:#767676;font-size:14px;margin:15px 0 5px;padding-bottom:.5em}.single-headers ul{margin-bottom:15px}.single-headers ul li{float:left;list-style:none}.single-headers div.generic-button{text-align:center}.single-headers li.generic-button{display:inline-block;text-align:center}@media screen and (min-width:46.8em){.single-headers a.button,.single-headers div.generic-button,.single-headers li.generic-button{float:right}}.single-headers a.button,.single-headers div.generic-button{margin:10px 0 0 10px}.single-headers li.generic-button{margin:2px 10px}.single-headers li.generic-button:first-child{margin-right:0}.single-headers div#message.info{line-height:.8}body.no-js .single-item-header .js-self-profile-button{display:none}#cover-image-container{position:relative}#header-cover-image{background-color:#c5c5c5;background-position:center top;background-repeat:no-repeat;background-size:cover;border:0;display:block;right:0;margin:0;padding:0;position:absolute;top:0;width:100%;z-index:1}#item-header-cover-image{position:relative;z-index:2}#item-header-cover-image #item-header-avatar{padding:0 1em}.groups-header .bp-group-type-list{margin:0}.groups-header .bp-feedback{clear:both}.groups-header .group-item-actions{float:right;margin:0 15px 15px 0;padding-top:0;width:100%}.groups-header .moderators-lists{margin-top:0}.groups-header .moderators-lists .moderators-title{font-size:14px}.groups-header .moderators-lists .user-list{margin:0 0 5px}.groups-header .moderators-lists .user-list ul:after{clear:both;content:"";display:table}.groups-header .moderators-lists .user-list li{display:inline-block;float:none;margin-right:4px;padding:4px}.groups-header .moderators-lists img.avatar{box-shadow:none;float:none;height:30px;margin:0;max-width:100%;width:30px}@media screen and (min-width:46.8em){.groups-header div#item-header-content{float:right;margin-right:10%;text-align:right;padding-top:15px;width:42%}.groups-header .group-item-actions{float:left;margin:0 15px 15px 0;text-align:left;width:20%}.groups-header .groups-meta{clear:both}}.groups-header .desc-wrap{background:#eaeaea;border:1px solid #d6d6d6;margin:0 0 15px;padding:1em;text-align:center}.groups-header .desc-wrap .group-description{background:#fafafa;box-shadow:inset 0 0 9px #ccc;padding:1em;text-align:right}.groups-header .desc-wrap .group-description p{margin:0;padding:0}.bp-user .users-header .user-nicename{margin-bottom:5px}.bp-user .member-header-actions{overflow:hidden}.bp-user .member-header-actions *>*{display:block}.buddypress-wrap .item-body{margin:20px 0}.buddypress-wrap .item-body .screen-heading{font-size:20px;font-weight:400}.buddypress-wrap .item-body .button-tabs{margin:30px 0 15px;list-style:none}.buddypress-wrap.bp-single-vert-nav .bp-list:not(.grid) .item-entry{padding-right:.5em}.single-item.group-members .item-body .filters:not(.no-subnav){border-top:5px solid #eaeaea;padding-top:1em}.single-item.group-members .item-body .filters{margin-top:0}.buddypress-wrap .group-status-type ul{margin:0 20px 20px 0}.groups-manage-members-list{padding:.5em 0}.groups-manage-members-list dd{margin:0;padding:1em 0}.groups-manage-members-list .section-title{background:#eaeaea;padding-right:.3em}.groups-manage-members-list ul{list-style:none;margin-bottom:0}.groups-manage-members-list ul li{border-bottom:1px solid #eee;margin-bottom:10px;padding:.5em .3em .3em}.groups-manage-members-list ul li:last-child,.groups-manage-members-list ul li:only-child{border-bottom:0}.groups-manage-members-list ul li:nth-child(even){background:#fafafa}.groups-manage-members-list ul li.banned-user{background:#fad3d3}.groups-manage-members-list ul .member-name{margin-bottom:0;text-align:center}.groups-manage-members-list ul img{display:block;margin:0 auto;width:20%}@media screen and (min-width:32em){.groups-manage-members-list ul .member-name{text-align:right}.groups-manage-members-list ul img{display:inline;width:50px}}.groups-manage-members-list ul .members-manage-buttons:after,.groups-manage-members-list ul .members-manage-buttons:before{content:" ";display:table}.groups-manage-members-list ul .members-manage-buttons:after{clear:both}.groups-manage-members-list ul .members-manage-buttons{margin:15px 0 5px}.groups-manage-members-list ul .members-manage-buttons a.button{color:#767676;display:block;font-size:13px}@media screen and (min-width:32em){.groups-manage-members-list ul .members-manage-buttons a.button{display:inline-block}}.groups-manage-members-list ul .members-manage-buttons.text-links-list{margin-bottom:0}@media screen and (max-width:32em){.groups-manage-members-list ul .members-manage-buttons.text-links-list a.button{background:#fafafa;border:1px solid #eee;display:block;margin-bottom:10px}}.groups-manage-members-list ul .action:not(.text-links-list) a.button{font-size:12px}@media screen and (min-width:46.8em){.groups-manage-members-list ul li .avatar,.groups-manage-members-list ul li .member-name{float:right}.groups-manage-members-list ul li .avatar{margin-left:15px}.groups-manage-members-list ul li .action{clear:both;float:right}}#group-manage-members-ui #group-members-search-form button[type=submit]{float:left;font-size:inherit;font-weight:400;line-height:1.5;text-align:center;text-transform:none}#group-manage-members-ui #group-members-search-form button[type=submit] span{font-family:dashicons;font-size:18px;line-height:1.6}#group-manage-members-ui #group-members-pagination button:last-child{margin-left:2em}#group-manage-members-ui #bp-no-group-members td{border:none}.buddypress .bp-invites-content ul.item-list{border-top:0}.buddypress .bp-invites-content ul.item-list li{border:1px solid #eaeaea;margin:0 0 1%;padding-right:5px;padding-left:5px;position:relative;width:auto}.buddypress .bp-invites-content ul.item-list li .list-title{margin:0 auto;width:80%}.buddypress .bp-invites-content ul.item-list li .action{position:absolute;top:10px;left:10px}.buddypress .bp-invites-content ul.item-list li .action a.button.invite-button{border:0}.buddypress .bp-invites-content ul.item-list li .action a.button.invite-button:focus,.buddypress .bp-invites-content ul.item-list li .action a.button.invite-button:hover{color:#1fb3dd}.buddypress .bp-invites-content ul.item-list li.selected{box-shadow:inset 0 0 12px 0 rgba(237,187,52,.2)}.buddypress .bp-invites-content .group-inviters li,.buddypress .bp-invites-content .item-list .item-meta span{color:#767676}.buddypress .bp-invites-content li ul.group-inviters{clear:both;margin:0}.buddypress .bp-invites-content li ul.group-inviters li{border:0;float:right;font-size:20px;width:inherit}.buddypress .bp-invites-content li .status{font-size:20px;font-style:italic;clear:both;color:#555;margin:10px 0}.buddypress .bp-invites-content #send-invites-editor ul:after,.buddypress .bp-invites-content #send-invites-editor ul:before{content:" ";display:table}.buddypress .bp-invites-content #send-invites-editor ul:after{clear:both}.buddypress .bp-invites-content #send-invites-editor textarea{width:100%}.buddypress .bp-invites-content #send-invites-editor ul{clear:both;list-style:none;margin:10px 0}.buddypress .bp-invites-content #send-invites-editor ul li{float:right;margin:.5%;max-height:50px;max-width:50px}.buddypress .bp-invites-content #send-invites-editor #bp-send-invites-form{clear:both;margin-top:10px}.buddypress .bp-invites-content #send-invites-editor .action{margin-top:10px;padding-top:10px}.buddypress .bp-invites-content #send-invites-editor.bp-hide{display:none}@media screen and (min-width:46.8em){.buddypress .bp-invites-content ul.item-list>li{box-sizing:border-box;border:1px solid #eaeaea;float:right;padding-right:.5em;padding-left:.5em;width:49.5%}.buddypress .bp-invites-content ul.item-list>li:nth-child(odd){margin-left:.5%}.buddypress .bp-invites-content ul.item-list>li:nth-child(even){margin-right:.5%}.buddypress .bp-invites-content ul.item-list ul.group-inviters{float:right;width:auto}}@media screen and (min-width:46.8em){:not(.vertical)+.item-body #group-invites-container{display:-ms-grid;display:grid;-ms-grid-columns:25% auto;grid-template-columns:25% auto;grid-template-areas:"group-invites-nav group-invites-column"}:not(.vertical)+.item-body #group-invites-container .bp-invites-nav{-ms-grid-row:1;-ms-grid-column:1;grid-area:group-invites-nav}:not(.vertical)+.item-body #group-invites-container .bp-invites-nav li{display:block;float:none}:not(.vertical)+.item-body #group-invites-container .group-invites-column{-ms-grid-row:1;-ms-grid-column:2;grid-area:group-invites-column}}.buddypress.groups .activity-update-form{margin-top:0}.buddypress-wrap .profile{margin-top:30px}.buddypress-wrap .public .profile-fields td.label{width:30%}.buddypress-wrap .profile.edit ul.button-nav{list-style:none;margin:30px 0 10px;padding-right:0}.buddypress-wrap .profile.edit ul.button-nav li{display:inline-block;margin-left:10px}.buddypress-wrap .profile.edit ul.button-nav li a{padding:.5em}.buddypress-wrap .profile.edit .editfield{background:#fafafa;border:1px solid #eee;margin:15px 0;padding:1em}.buddypress-wrap .profile.edit .editfield fieldset{border:0}.buddypress-wrap .profile.edit .editfield fieldset label{font-weight:400}.buddypress-wrap .profile.edit .editfield fieldset label.xprofile-field-label{display:inline}.buddypress-wrap .profile.edit .editfield{display:flex;flex-direction:column}.buddypress-wrap .profile.edit .editfield .description{margin-top:10px;order:2}.buddypress-wrap .profile.edit .editfield>fieldset{order:1}.buddypress-wrap .profile.edit .editfield .field-visibility-settings,.buddypress-wrap .profile.edit .editfield .field-visibility-settings-toggle{order:3}body.no-js .buddypress-wrap .field-visibility-settings-close,body.no-js .buddypress-wrap .field-visibility-settings-toggle{display:none}body.no-js .buddypress-wrap .field-visibility-settings{display:block}.buddypress-wrap .field-visibility-settings{margin:10px 0}.buddypress-wrap .current-visibility-level{font-style:normal;font-weight:700}.buddypress-wrap .field-visibility-settings,.buddypress-wrap .field-visibility-settings-header{color:#737373}.buddypress-wrap .field-visibility-settings fieldset{margin:5px 0}.buddypress-wrap .standard-form .editfield fieldset{margin:0}.buddypress-wrap .standard-form .field-visibility-settings label{font-weight:400;margin:0}.buddypress-wrap .standard-form .field-visibility-settings .radio{list-style:none;margin-bottom:0}.buddypress-wrap .standard-form .field-visibility-settings .field-visibility-settings-close{font-size:12px}.buddypress-wrap .standard-form .wp-editor-container{border:1px solid #dedede}.buddypress-wrap .standard-form .wp-editor-container textarea{background:#fff;width:100%}.buddypress-wrap .standard-form .description{background:#fafafa;font-size:inherit}.buddypress-wrap .standard-form .field-visibility-settings legend,.buddypress-wrap .standard-form .field-visibility-settings-header{font-style:italic}.buddypress-wrap .standard-form .field-visibility-settings-header{font-size:14px}.buddypress-wrap .standard-form .field-visibility-settings label,.buddypress-wrap .standard-form .field-visibility-settings legend{font-size:14px}.buddypress-wrap .standard-form .field-visibility select{margin:0}.buddypress-wrap .html-active button.switch-html{background:#f5f5f5;border-bottom-color:transparent;border-bottom-right-radius:0;border-bottom-left-radius:0}.buddypress-wrap .tmce-active button.switch-tmce{background:#f5f5f5;border-bottom-color:transparent;border-bottom-right-radius:0;border-bottom-left-radius:0}.buddypress-wrap .profile.public .profile-group-title{border-bottom:1px solid #ccc}body.register .buddypress-wrap .page ul{list-style:none}.buddypress-wrap .profile .bp-avatar-nav{margin-top:20px}.message-action-delete:before,.message-action-star:before,.message-action-unstar:before,.message-action-view:before{font-family:dashicons;font-size:18px}.message-action-star:before{color:#aaa;content:"\f154"}.message-action-unstar:before{color:#fcdd77;content:"\f155"}.message-action-view:before{content:"\f473"}.message-action-delete:before{content:"\f153"}.message-action-delete:hover:before{color:#a00}.preview-content .actions a{text-decoration:none}.bp-messages-content{margin:15px 0}.bp-messages-content .avatar{box-shadow:none}.bp-messages-content .thread-participants{list-style:none}.bp-messages-content .thread-participants dd{margin-right:0}.bp-messages-content time{color:#737373;font-size:12px}#message-threads{border-top:1px solid #eaeaea;clear:both;list-style:none;margin:0;max-height:220px;overflow-x:hidden;overflow-y:auto;padding:0;width:100%}#message-threads li{border-bottom:1px solid #eaeaea;display:-moz-flex;display:-ms-flex;display:-o-flex;display:flex;-o-flex-flow:row nowrap;flex-flow:row nowrap;margin:0;overflow:hidden;padding:.5em 0}#message-threads li .thread-cb{display:flex;align-items:center;-moz-flex:1 2 5%;-o-flex:1 2 5%;flex:1 2 5%}#message-threads li .thread-from,#message-threads li .thread-to{-moz-flex:1 2 20%;-o-flex:1 2 20%;flex:1 2 20%}#message-threads li .thread-from img.avatar,#message-threads li .thread-to img.avatar{float:right;margin:0 0 0 10px}#message-threads li .thread-from .user-name,#message-threads li .thread-to .user-name{display:inline-block;line-height:1.1}#message-threads li .thread-from .num-recipients,#message-threads li .thread-to .num-recipients{color:#737373;font-weight:400;font-size:12px;margin:0}#message-threads li .thread-content{-moz-flex:1 2 60%;-o-flex:1 2 60%;flex:1 2 60%}#message-threads li .thread-date{-moz-flex:1 2 15%;-o-flex:1 2 15%;flex:1 2 15%}#message-threads li.selected{background-color:#fafafa}#message-threads li.selected .thread-subject .subject{color:#5087e5}#message-threads li.unread{font-weight:700}#message-threads li .thread-content .excerpt{color:#737373;font-size:12px;margin:0}#message-threads li .thread-content .thread-from,#message-threads li .thread-content .thread-subject,#message-threads li .thread-content .thread-to{font-size:13px}@media screen and (min-width:46.8em){#message-threads li .thread-content .thread-from,#message-threads li .thread-content .thread-subject,#message-threads li .thread-content .thread-to{font-size:16px}}#message-threads li .thread-content .thread-subject{vertical-align:top}#message-threads li .thread-content .thread-subject .excerpt{font-weight:400}#message-threads li .thread-date{padding-left:5px;text-align:left}.bp-messages-content .actions{float:left;max-width:30%;line-height:1}.bp-messages-content .actions .bp-icons:not(.bp-hide){display:inline-block;margin:0;padding:.3em .5em}.bp-messages-content .actions .bp-icons:not(.bp-hide):before{font-size:26px}.bp-messages-content #thread-preview{border:1px solid #eaeaea;margin-top:20px}.bp-messages-content #thread-preview .preview-message{overflow:hidden}.bp-messages-content #thread-preview .preview-content{margin:.5em}.bp-messages-content #thread-preview .preview-content .preview-message{background:#fafafa;margin:10px 0;padding:1em .3em .3em}.bp-messages-content #bp-message-thread-list{border-top:1px solid #eaeaea;clear:both;list-style:none;padding:1em 0 .3em}.bp-messages-content #bp-message-thread-list li{padding:.5em}.bp-messages-content #bp-message-thread-list li:nth-child(2n) .message-content{background:#fafafa}.bp-messages-content #bp-message-thread-list .message-metadata{border-bottom:1px solid #ccc;box-shadow:2px 1px 9px 0 #eee;display:table;padding:.2em;width:100%}.bp-messages-content #bp-message-thread-list .message-metadata .avatar{width:30px}.bp-messages-content #bp-message-thread-list .message-metadata .user-link{display:block;font-size:13px;float:right}@media screen and (min-width:46.8em){.bp-messages-content #bp-message-thread-list .message-metadata .user-link{font-size:16px}}.bp-messages-content #bp-message-thread-list .message-metadata time{color:#737373;font-size:12px;padding:0 .5em}.bp-messages-content #bp-message-thread-list .message-metadata button{padding:0 .3em}.bp-messages-content #bp-message-thread-list .message-metadata button:before{font-size:20px}.bp-messages-content #bp-message-thread-list .message-content{overflow:hidden;margin:1em auto 0;width:90%}.bp-messages-content #bp-message-thread-list img.avatar{float:right;margin:0 0 0 10px}.bp-messages-content #bp-message-thread-list .actions a:before{font-size:18px}.bp-messages-content form.send-reply .avatar-box{padding:.5em 0}.bp-messages-content .preview-pane-header,.bp-messages-content .single-message-thread-header{border-bottom:1px solid #eaeaea}.bp-messages-content .preview-pane-header:after,.bp-messages-content .single-message-thread-header:after{clear:both;content:"";display:table}.bp-messages-content .preview-thread-title,.bp-messages-content .single-thread-title{font-size:16px}.bp-messages-content .preview-thread-title .messages-title,.bp-messages-content .single-thread-title .messages-title{padding-right:2em}.bp-messages-content .thread-participants{float:right;margin:5px 0;width:70%}.bp-messages-content .thread-participants dd,.bp-messages-content .thread-participants ul{margin-bottom:10px}.bp-messages-content .thread-participants ul{list-style:none}.bp-messages-content .thread-participants ul:after{clear:both;content:"";display:table}.bp-messages-content .thread-participants li{float:right;margin-right:5px}.bp-messages-content .thread-participants img{width:30px;height:30px}.bp-messages-content #bp-message-thread-list li .message-content blockquote,.bp-messages-content #bp-message-thread-list li .message-content ol,.bp-messages-content #bp-message-thread-list li .message-content ul,.bp-messages-content #thread-preview .preview-message blockquote,.bp-messages-content #thread-preview .preview-message ol,.bp-messages-content #thread-preview .preview-message ul{list-style-position:inside;margin-right:0}.bp-messages-content #thread-preview:empty,.bp-messages-content ul#message-threads:empty{display:none}.bp-messages-content #bp-message-thread-header h2:first-child,.bp-messages-content #thread-preview h2:first-child{background-color:#eaeaea;color:#555;font-weight:700;margin:0;padding:.5em}.bp-messages-content #bp-message-thread-list li a.user-link,.bp-messages-content #message-threads .thread-content a{border:0;text-decoration:none}.bp-messages-content .standard-form #subject{margin-bottom:20px}div.bp-navs#subsubnav.bp-messages-filters .user-messages-bulk-actions{margin-left:15px;max-width:42.5%}.buddypress.settings .profile-settings.bp-tables-user select{width:100%}body.buddypress.settings .wp-pwd button{vertical-align:middle}body.buddypress.settings #pass-strength-result,body.buddypress.settings #pass1,body.buddypress.settings #pass1-text{width:16em}body.buddypress.settings #pass1{display:inline-block;margin-bottom:inherit}body.buddypress.settings #pass-strength-result,body.buddypress.settings #pass1-text,body.buddypress.settings .pw-weak{display:none}body.buddypress.settings .show-password #pass1-text{display:inline-block;margin-bottom:inherit}body.buddypress.settings .show-password #pass1{display:none}body.buddypress.settings #your-profile #submit:disabled{color:#767676;opacity:.4}body.buddypress.settings.js .user-pass2-wrap,body.buddypress.settings.js .wp-pwd{display:none}body.buddypress.settings.no-js .wp-cancel-pw,body.buddypress.settings.no-js .wp-generate-pw,body.buddypress.settings.no-js .wp-hide-pw{display:none}body.buddypress.settings.data #buddypress.buddypress-wrap .item-body p a{text-decoration:underline}.buddypress-wrap #whats-new-post-in-box select,.buddypress-wrap .filter select{border:1px solid #d6d6d6}.buddypress-wrap input.action[disabled]{cursor:pointer;opacity:.4}.buddypress-wrap #notification-bulk-manage[disabled]{display:none}.buddypress-wrap fieldset legend{font-size:inherit;font-weight:600}.buddypress-wrap input[type=email]:focus,.buddypress-wrap input[type=password]:focus,.buddypress-wrap input[type=tel]:focus,.buddypress-wrap input[type=text]:focus,.buddypress-wrap input[type=url]:focus,.buddypress-wrap textarea:focus{box-shadow:0 0 8px #eaeaea}.buddypress-wrap select{height:auto}.buddypress-wrap textarea{resize:vertical}.buddypress-wrap .standard-form .bp-controls-wrap{margin:1em 0}.buddypress-wrap .standard-form .groups-members-search input[type=search],.buddypress-wrap .standard-form .groups-members-search input[type=text],.buddypress-wrap .standard-form [data-bp-search] input[type=search],.buddypress-wrap .standard-form [data-bp-search] input[type=text],.buddypress-wrap .standard-form input[type=color],.buddypress-wrap .standard-form input[type=date],.buddypress-wrap .standard-form input[type=datetime-local],.buddypress-wrap .standard-form input[type=datetime],.buddypress-wrap .standard-form input[type=email],.buddypress-wrap .standard-form input[type=month],.buddypress-wrap .standard-form input[type=number],.buddypress-wrap .standard-form input[type=password],.buddypress-wrap .standard-form input[type=range],.buddypress-wrap .standard-form input[type=search],.buddypress-wrap .standard-form input[type=tel],.buddypress-wrap .standard-form input[type=text],.buddypress-wrap .standard-form input[type=time],.buddypress-wrap .standard-form input[type=url],.buddypress-wrap .standard-form input[type=week],.buddypress-wrap .standard-form select,.buddypress-wrap .standard-form textarea{background:#fafafa;border:1px solid #d6d6d6;border-radius:0;font:inherit;font-size:100%;padding:.5em}.buddypress-wrap .standard-form input[required],.buddypress-wrap .standard-form select[required],.buddypress-wrap .standard-form textarea[required]{box-shadow:none;border-width:2px;outline:0}.buddypress-wrap .standard-form input[required]:invalid,.buddypress-wrap .standard-form select[required]:invalid,.buddypress-wrap .standard-form textarea[required]:invalid{border-color:#b71717}.buddypress-wrap .standard-form input[required]:valid,.buddypress-wrap .standard-form select[required]:valid,.buddypress-wrap .standard-form textarea[required]:valid{border-color:#91cc2c}.buddypress-wrap .standard-form input[required]:focus,.buddypress-wrap .standard-form select[required]:focus,.buddypress-wrap .standard-form textarea[required]:focus{border-color:#d6d6d6;border-width:1px}.buddypress-wrap .standard-form input.invalid[required],.buddypress-wrap .standard-form select.invalid[required],.buddypress-wrap .standard-form textarea.invalid[required]{border-color:#b71717}.buddypress-wrap .standard-form input:not(.small),.buddypress-wrap .standard-form textarea{width:100%}.buddypress-wrap .standard-form input[type=checkbox],.buddypress-wrap .standard-form input[type=radio]{margin-left:5px;width:auto}.buddypress-wrap .standard-form select{padding:3px}.buddypress-wrap .standard-form textarea{height:120px}.buddypress-wrap .standard-form textarea#message_content{height:200px}.buddypress-wrap .standard-form input[type=password]{margin-bottom:5px}.buddypress-wrap .standard-form input:focus,.buddypress-wrap .standard-form select:focus,.buddypress-wrap .standard-form textarea:focus{background:#fafafa;color:#555;outline:0}.buddypress-wrap .standard-form label,.buddypress-wrap .standard-form span.label{display:block;font-weight:600;margin:15px 0 5px;width:auto}.buddypress-wrap .standard-form a.clear-value{display:block;margin-top:5px;outline:0}.buddypress-wrap .standard-form .submit{clear:both;padding:15px 0 0}.buddypress-wrap .standard-form p.submit{margin-bottom:0}.buddypress-wrap .standard-form div.submit input{margin-left:15px}.buddypress-wrap .standard-form #invite-list label,.buddypress-wrap .standard-form p label{font-weight:400;margin:auto}.buddypress-wrap .standard-form p.description{color:#737373;margin:5px 0}.buddypress-wrap .standard-form div.checkbox label:nth-child(n+2),.buddypress-wrap .standard-form div.radio div label{color:#737373;font-size:100%;font-weight:400;margin:5px 0 0}.buddypress-wrap .standard-form#send-reply textarea{width:97.5%}.buddypress-wrap .standard-form#sidebar-login-form label{margin-top:5px}.buddypress-wrap .standard-form#sidebar-login-form input[type=password],.buddypress-wrap .standard-form#sidebar-login-form input[type=text]{padding:4px;width:95%}.buddypress-wrap .standard-form.profile-edit input:focus{background:#fff}@media screen and (min-width:46.8em){.buddypress-wrap .standard-form .left-menu{float:right}.buddypress-wrap .standard-form #invite-list ul{list-style:none;margin:1%}.buddypress-wrap .standard-form #invite-list ul li{margin:0 1% 0 0}.buddypress-wrap .standard-form .main-column{margin-right:190px}.buddypress-wrap .standard-form .main-column ul#friend-list{clear:none;float:right}.buddypress-wrap .standard-form .main-column ul#friend-list h4{clear:none}}.buddypress-wrap .standard-form .bp-tables-user label{margin:0}.buddypress-wrap .signup-form label,.buddypress-wrap .signup-form legend{font-weight:400}body.no-js .buddypress #delete_inbox_messages,body.no-js .buddypress #delete_sentbox_messages,body.no-js .buddypress #message-type-select,body.no-js .buddypress #messages-bulk-management #select-all-messages,body.no-js .buddypress #notifications-bulk-management #select-all-notifications,body.no-js .buddypress label[for=message-type-select]{display:none}.buddypress-wrap .wp-editor-wrap .wp-editor-wrap button,.buddypress-wrap .wp-editor-wrap .wp-editor-wrap input[type=button],.buddypress-wrap .wp-editor-wrap .wp-editor-wrap input[type=submit],.buddypress-wrap .wp-editor-wrap a.button,.buddypress-wrap .wp-editor-wrap input[type=reset]{padding:0 8px 1px}.buddypress-wrap .select-wrap{border:1px solid #eee}.buddypress-wrap .select-wrap label{display:inline}.buddypress-wrap .select-wrap select::-ms-expand{display:none}.buddypress-wrap .select-wrap select{-moz-appearance:none;-webkit-appearance:none;-o-appearance:none;appearance:none;border:0;cursor:pointer;margin-left:-25px;padding:6px 10px 6px 25px;position:relative;text-indent:-2px;z-index:1;width:auto}.buddypress-wrap .select-wrap select,.buddypress-wrap .select-wrap select:active,.buddypress-wrap .select-wrap select:focus{background:0 0}.buddypress-wrap .select-wrap span.select-arrow{display:inline-block;position:relative;z-index:0}.buddypress-wrap .select-wrap span.select-arrow:before{color:#ccc;content:"\25BC"}.buddypress-wrap .select-wrap:focus .select-arrow:before,.buddypress-wrap .select-wrap:hover .select-arrow:before{color:#a6a6a6}.buddypress-wrap .bp-search form:focus,.buddypress-wrap .bp-search form:hover,.buddypress-wrap .select-wrap:focus,.buddypress-wrap .select-wrap:hover{border:1px solid #d5d4d4;box-shadow:inset 0 0 3px #eee}@media screen and (min-width:32em){.buddypress-wrap .notifications-options-nav .select-wrap{float:right}}.buddypress-wrap .bp-dir-search-form,.buddypress-wrap .bp-messages-search-form:after,.buddypress-wrap .bp-messages-search-form:before{content:" ";display:table}.buddypress-wrap .bp-dir-search-form,.buddypress-wrap .bp-messages-search-form:after{clear:both}.buddypress-wrap form#group-members-search,.buddypress-wrap form.bp-dir-search-form,.buddypress-wrap form.bp-messages-search-form,.buddypress-wrap form[data-bp-search].bp-invites-search-form{border:1px solid #eee;width:100%}.buddypress-wrap form#group-members-search label,.buddypress-wrap form.bp-dir-search-form label,.buddypress-wrap form.bp-messages-search-form label,.buddypress-wrap form[data-bp-search].bp-invites-search-form label{margin:0}.buddypress-wrap form#group-members-search button[type=submit],.buddypress-wrap form#group-members-search input[type=search],.buddypress-wrap form#group-members-search input[type=text],.buddypress-wrap form.bp-dir-search-form button[type=submit],.buddypress-wrap form.bp-dir-search-form input[type=search],.buddypress-wrap form.bp-dir-search-form input[type=text],.buddypress-wrap form.bp-messages-search-form button[type=submit],.buddypress-wrap form.bp-messages-search-form input[type=search],.buddypress-wrap form.bp-messages-search-form input[type=text],.buddypress-wrap form[data-bp-search].bp-invites-search-form button[type=submit],.buddypress-wrap form[data-bp-search].bp-invites-search-form input[type=search],.buddypress-wrap form[data-bp-search].bp-invites-search-form input[type=text]{background:0 0;border:0;border-radius:0;background-clip:padding-box}.buddypress-wrap form#group-members-search input[type=search],.buddypress-wrap form#group-members-search input[type=text],.buddypress-wrap form.bp-dir-search-form input[type=search],.buddypress-wrap form.bp-dir-search-form input[type=text],.buddypress-wrap form.bp-messages-search-form input[type=search],.buddypress-wrap form.bp-messages-search-form input[type=text],.buddypress-wrap form[data-bp-search].bp-invites-search-form input[type=search],.buddypress-wrap form[data-bp-search].bp-invites-search-form input[type=text]{float:right;line-height:1.5;padding:3px 10px;width:80%}.buddypress-wrap form#group-members-search button[type=submit],.buddypress-wrap form.bp-dir-search-form button[type=submit],.buddypress-wrap form.bp-messages-search-form button[type=submit],.buddypress-wrap form[data-bp-search].bp-invites-search-form button[type=submit]{float:left;font-size:inherit;font-weight:400;line-height:1.5;padding:3px .7em;text-align:center;text-transform:none;width:20%}.buddypress-wrap form#group-members-search button[type=submit] span,.buddypress-wrap form.bp-dir-search-form button[type=submit] span,.buddypress-wrap form.bp-messages-search-form button[type=submit] span,.buddypress-wrap form[data-bp-search].bp-invites-search-form button[type=submit] span{font-family:dashicons;font-size:18px;line-height:1.6}.buddypress-wrap form#group-members-search button[type=submit].bp-show,.buddypress-wrap form.bp-dir-search-form button[type=submit].bp-show,.buddypress-wrap form.bp-messages-search-form button[type=submit].bp-show,.buddypress-wrap form[data-bp-search].bp-invites-search-form button[type=submit].bp-show{height:auto;right:0;overflow:visible;position:static;top:0}.buddypress-wrap form#group-members-search input[type=search]::-webkit-search-cancel-button,.buddypress-wrap form.bp-dir-search-form input[type=search]::-webkit-search-cancel-button,.buddypress-wrap form.bp-messages-search-form input[type=search]::-webkit-search-cancel-button,.buddypress-wrap form[data-bp-search].bp-invites-search-form input[type=search]::-webkit-search-cancel-button{-webkit-appearance:searchfield-cancel-button}.buddypress-wrap form#group-members-search input[type=search]::-webkit-search-results-button,.buddypress-wrap form#group-members-search input[type=search]::-webkit-search-results-decoration,.buddypress-wrap form.bp-dir-search-form input[type=search]::-webkit-search-results-button,.buddypress-wrap form.bp-dir-search-form input[type=search]::-webkit-search-results-decoration,.buddypress-wrap form.bp-messages-search-form input[type=search]::-webkit-search-results-button,.buddypress-wrap form.bp-messages-search-form input[type=search]::-webkit-search-results-decoration,.buddypress-wrap form[data-bp-search].bp-invites-search-form input[type=search]::-webkit-search-results-button,.buddypress-wrap form[data-bp-search].bp-invites-search-form input[type=search]::-webkit-search-results-decoration{display:none}.buddypress-wrap form#group-members-search:hover{border:1px solid #d5d4d4;box-shadow:inset 0 0 3px #eee}.buddypress-wrap ul.filters li form label input{line-height:1.4;padding:.1em .7em}.buddypress-wrap .current-member-type{font-style:italic}.buddypress-wrap .dir-form{clear:both}.budypress.no-js form.bp-dir-search-form button[type=submit]{height:auto;right:0;overflow:visible;position:static;top:0}.bp-user [data-bp-search] form input[type=search],.bp-user [data-bp-search] form input[type=text]{padding:6px 10px 7px}.buddypress-wrap .bp-tables-user,.buddypress-wrap table.forum,.buddypress-wrap table.wp-profile-fields{width:100%}.buddypress-wrap .bp-tables-user thead tr,.buddypress-wrap table.forum thead tr,.buddypress-wrap table.wp-profile-fields thead tr{background:0 0;border-bottom:2px solid #ccc}.buddypress-wrap .bp-tables-user tbody tr,.buddypress-wrap table.forum tbody tr,.buddypress-wrap table.wp-profile-fields tbody tr{background:#fafafa}.buddypress-wrap .bp-tables-user tr td,.buddypress-wrap .bp-tables-user tr th,.buddypress-wrap table.forum tr td,.buddypress-wrap table.forum tr th,.buddypress-wrap table.wp-profile-fields tr td,.buddypress-wrap table.wp-profile-fields tr th{padding:.5em;vertical-align:middle}.buddypress-wrap .bp-tables-user tr td.label,.buddypress-wrap table.forum tr td.label,.buddypress-wrap table.wp-profile-fields tr td.label{border-left:1px solid #eaeaea;font-weight:600;width:25%}.buddypress-wrap .bp-tables-user tr.alt td,.buddypress-wrap table.wp-profile-fields tr.alt td{background:#fafafa}.buddypress-wrap table.profile-fields .data{padding:.5em 1em}.buddypress-wrap table.profile-fields tr:last-child{border-bottom:none}.buddypress-wrap table.notifications td{padding:1em .5em}.buddypress-wrap table.notifications .bulk-select-all,.buddypress-wrap table.notifications .bulk-select-check{width:7%}.buddypress-wrap table.notifications .bulk-select-check{vertical-align:middle}.buddypress-wrap table.notifications .date,.buddypress-wrap table.notifications .notification-description,.buddypress-wrap table.notifications .notification-since,.buddypress-wrap table.notifications .title{width:39%}.buddypress-wrap table.notifications .actions,.buddypress-wrap table.notifications .notification-actions{width:15%}.buddypress-wrap table.notification-settings th.title,.buddypress-wrap table.profile-settings th.title{width:80%}.buddypress-wrap table.notifications .notification-actions a.delete,.buddypress-wrap table.notifications .notification-actions a.mark-read{display:inline-block}.buddypress-wrap table.notification-settings{margin-bottom:15px;text-align:right}.buddypress-wrap #groups-notification-settings{margin-bottom:0}.buddypress-wrap table.notification-settings td:first-child,.buddypress-wrap table.notification-settings th.icon,.buddypress-wrap table.notifications td:first-child,.buddypress-wrap table.notifications th.icon{display:none}.buddypress-wrap table.notification-settings .no,.buddypress-wrap table.notification-settings .yes{text-align:center;width:40px;vertical-align:middle}.buddypress-wrap table#message-threads{clear:both}.buddypress-wrap table#message-threads .thread-info{min-width:40%}.buddypress-wrap table#message-threads .thread-info p{margin:0}.buddypress-wrap table#message-threads .thread-info p.thread-excerpt{color:#737373;font-size:12px;margin-top:3px}.buddypress-wrap table.profile-fields{margin-bottom:20px}.buddypress-wrap table.profile-fields:last-child{margin-bottom:0}.buddypress-wrap table.profile-fields p{margin:0}.buddypress-wrap table.profile-fields p:last-child{margin-top:0}.bp-screen-reader-text{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}.clearfix:after,.clearfix:before{content:" ";display:table}.clearfix:after{clear:both}.center-vert{display:flex;align-items:center}.bp-hide{display:none}.bp-show{height:auto;right:0;overflow:visible;position:static;top:0}.buddypress .buddypress-wrap .activity-read-more a,.buddypress .buddypress-wrap .comment-reply-link,.buddypress .buddypress-wrap .generic-button a,.buddypress .buddypress-wrap a.bp-title-button,.buddypress .buddypress-wrap a.button,.buddypress .buddypress-wrap button,.buddypress .buddypress-wrap input[type=button],.buddypress .buddypress-wrap input[type=reset],.buddypress .buddypress-wrap input[type=submit],.buddypress .buddypress-wrap ul.button-nav:not(.button-tabs) li a{background:#fff;border-color:#ccc;border-style:solid;border-width:1px;border-radius:0;color:#555;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:400;outline:0;padding:.3em .5em;text-align:center;text-decoration:none;width:auto;line-height:1}.buddypress .buddypress-wrap a.button.dashicons,.buddypress .buddypress-wrap button.dashicons{font-family:dashicons}.buddypress .buddypress-wrap .button-small[type=button]{padding:0 8px 1px}.buddypress .buddypress-wrap .activity-read-more a:focus,.buddypress .buddypress-wrap .activity-read-more a:hover,.buddypress .buddypress-wrap .button-nav li a:focus,.buddypress .buddypress-wrap .button-nav li a:hover,.buddypress .buddypress-wrap .button-nav li.current a,.buddypress .buddypress-wrap .comment-reply-link:focus,.buddypress .buddypress-wrap .comment-reply-link:hover,.buddypress .buddypress-wrap .generic-button a:focus,.buddypress .buddypress-wrap .generic-button a:hover,.buddypress .buddypress-wrap a.button:focus,.buddypress .buddypress-wrap a.button:hover,.buddypress .buddypress-wrap button:focus,.buddypress .buddypress-wrap button:hover,.buddypress .buddypress-wrap input[type=button]:focus,.buddypress .buddypress-wrap input[type=button]:hover,.buddypress .buddypress-wrap input[type=reset]:focus,.buddypress .buddypress-wrap input[type=reset]:hover,.buddypress .buddypress-wrap input[type=submit]:focus,.buddypress .buddypress-wrap input[type=submit]:hover{background:#ededed;border-color:#999;color:#333;outline:0;text-decoration:none}.buddypress .buddypress-wrap a.disabled,.buddypress .buddypress-wrap button.disabled,.buddypress .buddypress-wrap button.pending,.buddypress .buddypress-wrap div.pending a,.buddypress .buddypress-wrap input[type=button].disabled,.buddypress .buddypress-wrap input[type=button].pending,.buddypress .buddypress-wrap input[type=reset].disabled,.buddypress .buddypress-wrap input[type=reset].pending,.buddypress .buddypress-wrap input[type=submit].pending,.buddypress .buddypress-wrap input[type=submit][disabled=disabled]{border-color:#eee;color:#767676;cursor:default}.buddypress .buddypress-wrap a.disabled:hover,.buddypress .buddypress-wrap button.disabled:hover,.buddypress .buddypress-wrap button.pending:hover,.buddypress .buddypress-wrap div.pending a:hover,.buddypress .buddypress-wrap input[type=button]:hover.disabled,.buddypress .buddypress-wrap input[type=button]:hover.pending,.buddypress .buddypress-wrap input[type=reset]:hover.disabled,.buddypress .buddypress-wrap input[type=reset]:hover.pending,.buddypress .buddypress-wrap input[type=submit]:hover.disabled,.buddypress .buddypress-wrap input[type=submit]:hover.pending{border-color:#eee;color:#767676}.buddypress .buddypress-wrap button.text-button,.buddypress .buddypress-wrap input.text-button{background:0 0;border:0;box-shadow:none;color:#767676}.buddypress .buddypress-wrap button.text-button.small,.buddypress .buddypress-wrap input.text-button.small{font-size:13px}.buddypress .buddypress-wrap button.text-button:focus,.buddypress .buddypress-wrap button.text-button:hover,.buddypress .buddypress-wrap input.text-button:focus,.buddypress .buddypress-wrap input.text-button:hover{background:0 0;text-decoration:underline}.buddypress .buddypress-wrap .activity-list a.button{border:none}.buddypress .buddypress-wrap .bp-invites-content ul.bp-list li a.invite-button:hover{color:#1fb3dd}.buddypress .buddypress-wrap .bp-invites-content ul.bp-list li a.group-remove-invite-button:hover,.buddypress .buddypress-wrap .bp-invites-content ul.bp-list li a.invite-button:hover,.buddypress .buddypress-wrap .bp-invites-content ul.bp-list li.selected a.group-remove-invite-button:hover,.buddypress .buddypress-wrap .bp-invites-content ul.bp-list li.selected a.invite-button:hover{color:#a00}.buddypress .buddypress-wrap #item-buttons:empty{display:none}.buddypress .buddypress-wrap input:disabled:focus,.buddypress .buddyp