BuddyPress - Version 5.0.0-beta1

Version Description

= 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 5.0.0-beta1
Comparing to
See all releases

Code changes from version 4.4.0 to 5.0.0-beta1

Files changed (166) hide show
  1. bp-activity/actions/post.php +7 -4
  2. bp-activity/bp-activity-admin.php +21 -8
  3. bp-activity/bp-activity-cssjs.php +1 -1
  4. bp-activity/bp-activity-filters.php +4 -2
  5. bp-activity/bp-activity-template.php +5 -0
  6. bp-activity/classes/class-bp-activity-activity.php +8 -3
  7. bp-activity/classes/class-bp-activity-component.php +36 -3
  8. bp-activity/classes/class-bp-activity-list-table.php +23 -17
  9. bp-activity/classes/class-bp-activity-template.php +4 -2
  10. bp-activity/classes/class-bp-rest-activity-endpoint.php +1550 -0
  11. bp-blogs/classes/class-bp-blogs-recent-posts-widget.php +12 -6
  12. bp-core/admin/bp-core-admin-functions.php +39 -0
  13. bp-core/admin/bp-core-admin-schema.php +51 -0
  14. bp-core/admin/bp-core-admin-tools.php +79 -0
  15. bp-core/bp-core-avatars.php +3 -2
  16. bp-core/bp-core-cache.php +11 -0
  17. bp-core/bp-core-catchuri.php +1 -1
  18. bp-core/bp-core-cssjs.php +18 -2
  19. bp-core/bp-core-filters.php +24 -2
  20. bp-core/bp-core-functions.php +23 -3
  21. bp-core/bp-core-rest-api.php +392 -0
  22. bp-core/bp-core-template.php +1 -1
  23. bp-core/bp-core-update.php +48 -0
  24. bp-core/classes/class-bp-admin.php +1 -1
  25. bp-core/classes/class-bp-component.php +22 -0
  26. bp-core/classes/class-bp-email-address.php +40 -0
  27. bp-core/classes/class-bp-email-participant.php +84 -0
  28. bp-core/classes/class-bp-email-recipient.php +13 -29
  29. bp-core/classes/class-bp-email-sender.php +8 -0
  30. bp-core/classes/class-bp-email.php +11 -5
  31. bp-core/classes/class-bp-embed.php +7 -1
  32. bp-core/classes/class-bp-invitation-manager.php +717 -0
  33. bp-core/classes/class-bp-invitation.php +1056 -0
  34. bp-core/classes/class-bp-rest-attachments-group-avatar-endpoint.php +499 -0
  35. bp-core/classes/class-bp-rest-attachments-member-avatar-endpoint.php +515 -0
  36. bp-core/classes/class-bp-rest-components-endpoint.php +537 -0
  37. bp-core/classes/class-bp-user-query.php +1 -1
  38. bp-core/classes/trait-attachments.php +300 -0
  39. bp-core/deprecated/2.1.php +1 -1
  40. bp-core/js/bp-api-request.js +45 -0
  41. bp-core/js/bp-api-request.min.js +1 -0
  42. bp-friends/bp-friends-filters.php +10 -6
  43. bp-friends/classes/class-bp-core-friends-widget.php +1 -1
  44. bp-groups/actions/create.php +2 -2
  45. bp-groups/actions/leave-group.php +32 -1
  46. bp-groups/admin/css/admin-rtl.css +33 -0
  47. bp-groups/admin/css/admin-rtl.min.css +1 -1
  48. bp-groups/admin/css/admin.css +33 -0
  49. bp-groups/admin/css/admin.min.css +1 -1
  50. bp-groups/bp-groups-activity.php +145 -9
  51. bp-groups/bp-groups-admin.php +19 -1
  52. bp-groups/bp-groups-cache.php +36 -2
  53. bp-groups/bp-groups-cssjs.php +62 -0
  54. bp-groups/bp-groups-filters.php +14 -12
  55. bp-groups/bp-groups-functions.php +595 -362
  56. bp-groups/bp-groups-notifications.php +56 -18
  57. bp-groups/bp-groups-template.php +82 -2
  58. bp-groups/classes/class-bp-group-member-query.php +94 -1
  59. bp-groups/classes/class-bp-groups-component.php +27 -2
  60. bp-groups/classes/class-bp-groups-group-members-template.php +3 -2
  61. bp-groups/classes/class-bp-groups-group.php +34 -23
  62. bp-groups/classes/class-bp-groups-invitation-manager.php +191 -0
  63. bp-groups/classes/class-bp-groups-invite-template.php +3 -2
  64. bp-groups/classes/class-bp-groups-list-table.php +10 -2
  65. bp-groups/classes/class-bp-groups-member.php +32 -88
  66. bp-groups/classes/class-bp-groups-membership-requests-template.php +3 -2
  67. bp-groups/classes/class-bp-groups-template.php +3 -2
  68. bp-groups/classes/class-bp-groups-widget.php +13 -4
  69. bp-groups/classes/class-bp-rest-group-invites-endpoint.php +1037 -0
  70. bp-groups/classes/class-bp-rest-group-membership-endpoint.php +950 -0
  71. bp-groups/classes/class-bp-rest-group-membership-request-endpoint.php +906 -0
  72. bp-groups/classes/class-bp-rest-groups-endpoint.php +1216 -0
  73. bp-groups/js/manage-members.js +549 -0
  74. bp-groups/js/manage-members.min.js +1 -0
  75. bp-groups/screens/single/admin/membership-requests.php +24 -14
  76. bp-groups/screens/single/send-invites.php +2 -2
  77. bp-loader.php +1 -1
  78. bp-members/bp-members-functions.php +94 -17
  79. bp-members/classes/class-bp-core-members-widget.php +12 -6
  80. bp-members/classes/class-bp-core-recently-active-widget.php +14 -6
  81. bp-members/classes/class-bp-core-whos-online-widget.php +14 -6
  82. bp-members/classes/class-bp-members-admin.php +1 -1
  83. bp-members/classes/class-bp-members-component.php +22 -0
  84. bp-members/classes/class-bp-rest-members-endpoint.php +811 -0
  85. bp-members/classes/class-bp-signup.php +6 -1
  86. bp-messages/bp-messages-cssjs.php +1 -1
  87. bp-messages/bp-messages-filters.php +4 -2
  88. bp-messages/bp-messages-functions.php +7 -0
  89. bp-messages/bp-messages-template.php +34 -14
  90. bp-messages/classes/class-bp-messages-box-template.php +3 -2
  91. bp-messages/classes/class-bp-messages-component.php +12 -0
  92. bp-messages/classes/class-bp-messages-thread.php +4 -2
  93. bp-messages/classes/class-bp-rest-messages-endpoint.php +1282 -0
  94. bp-notifications/bp-notifications-filters.php +4 -2
  95. bp-notifications/classes/class-bp-notifications-component.php +12 -0
  96. bp-notifications/classes/class-bp-rest-notifications-endpoint.php +897 -0
  97. bp-settings/bp-settings-filters.php +4 -2
  98. bp-settings/bp-settings-functions.php +27 -7
  99. bp-templates/bp-legacy/buddypress-functions.php +1 -1
  100. bp-templates/bp-legacy/css/buddypress-rtl.css +8 -3
  101. bp-templates/bp-legacy/css/buddypress-rtl.min.css +1 -1
  102. bp-templates/bp-legacy/css/buddypress.css +8 -3
  103. bp-templates/bp-legacy/css/buddypress.min.css +1 -1
  104. bp-templates/bp-legacy/js/buddypress.js +1 -1
  105. bp-templates/bp-legacy/js/buddypress.min.js +1 -1
  106. bp-templates/bp-nouveau/buddypress-functions.php +8 -1
  107. bp-templates/bp-nouveau/buddypress/common/js-templates/activity/form.php +6 -1
  108. bp-templates/bp-nouveau/buddypress/common/js-templates/group-members/index.php +147 -0
  109. bp-templates/bp-nouveau/buddypress/groups/single/admin/manage-members.php +14 -3
  110. bp-templates/bp-nouveau/buddypress/members/single/friends/requests-loop.php +46 -0
  111. bp-templates/bp-nouveau/buddypress/members/single/friends/requests.php +5 -40
  112. bp-templates/bp-nouveau/buddypress/members/single/settings/general.php +38 -13
  113. bp-templates/bp-nouveau/common-styles/_bp-mixins.scss +21 -0
  114. bp-templates/bp-nouveau/common-styles/_bp-variables.scss +4 -2
  115. bp-templates/bp-nouveau/common-styles/_bp_activity_entries.scss +13 -3
  116. bp-templates/bp-nouveau/common-styles/_bp_buttons.scss +10 -1
  117. bp-templates/bp-nouveau/common-styles/_bp_forms.scss +4 -3
  118. bp-templates/bp-nouveau/common-styles/_bp_generic_and_typography.scss +9 -3
  119. bp-templates/bp-nouveau/common-styles/_bp_groups_create.scss +5 -0
  120. bp-templates/bp-nouveau/common-styles/_bp_groups_management.scss +33 -0
  121. bp-templates/bp-nouveau/common-styles/_bp_info_messages.scss +8 -3
  122. bp-templates/bp-nouveau/common-styles/_bp_item_body_general.scss +3 -1
  123. bp-templates/bp-nouveau/common-styles/_bp_item_header_general.scss +4 -1
  124. bp-templates/bp-nouveau/common-styles/_bp_lists.scss +5 -2
  125. bp-templates/bp-nouveau/common-styles/_bp_registration.scss +57 -0
  126. bp-templates/bp-nouveau/common-styles/_bp_search.scss +12 -6
  127. bp-templates/bp-nouveau/common-styles/_bp_update_form.scss +13 -3
  128. bp-templates/bp-nouveau/common-styles/_bp_user_profile.scss +3 -3
  129. bp-templates/bp-nouveau/common-styles/_bp_user_settings.scss +80 -1
  130. bp-templates/bp-nouveau/css/buddypress-rtl.css +214 -35
  131. bp-templates/bp-nouveau/css/buddypress-rtl.min.css +1 -1
  132. bp-templates/bp-nouveau/css/buddypress.css +214 -35
  133. bp-templates/bp-nouveau/css/buddypress.min.css +1 -1
  134. bp-templates/bp-nouveau/includes/activity/ajax.php +2 -2
  135. bp-templates/bp-nouveau/includes/activity/functions.php +5 -2
  136. bp-templates/bp-nouveau/includes/activity/template-tags.php +3 -9
  137. bp-templates/bp-nouveau/includes/ajax.php +4 -0
  138. bp-templates/bp-nouveau/includes/functions.php +3 -17
  139. bp-templates/bp-nouveau/includes/groups/ajax.php +2 -1
  140. bp-templates/bp-nouveau/includes/groups/classes.php +28 -11
  141. bp-templates/bp-nouveau/includes/groups/functions.php +12 -6
  142. bp-templates/bp-nouveau/includes/template-tags.php +143 -113
  143. bp-templates/bp-nouveau/js/buddypress-activity-post-form.js +34 -12
  144. bp-templates/bp-nouveau/js/buddypress-activity-post-form.min.js +1 -1
  145. bp-templates/bp-nouveau/js/buddypress-activity.js +1 -1
  146. bp-templates/bp-nouveau/js/buddypress-activity.min.js +1 -1
  147. bp-templates/bp-nouveau/js/buddypress-messages.js +1 -1
  148. bp-templates/bp-nouveau/js/buddypress-messages.min.js +1 -1
  149. bp-templates/bp-nouveau/js/buddypress-nouveau.js +9 -13
  150. bp-templates/bp-nouveau/js/buddypress-nouveau.min.js +1 -1
  151. bp-templates/bp-nouveau/js/password-verify.js +10 -1
  152. bp-templates/bp-nouveau/js/password-verify.min.js +1 -1
  153. bp-templates/bp-nouveau/sass/_nouveau_invites.scss +0 -1
  154. bp-templates/bp-nouveau/sass/_nouveau_messages.scss +4 -1
  155. bp-xprofile/bp-xprofile-cache.php +13 -0
  156. bp-xprofile/bp-xprofile-cssjs.php +1 -1
  157. bp-xprofile/bp-xprofile-filters.php +57 -20
  158. bp-xprofile/classes/class-bp-rest-xprofile-data-endpoint.php +598 -0
  159. bp-xprofile/classes/class-bp-rest-xprofile-field-groups-endpoint.php +892 -0
  160. bp-xprofile/classes/class-bp-rest-xprofile-fields-endpoint.php +1179 -0
  161. bp-xprofile/classes/class-bp-xprofile-component.php +18 -0
  162. bp-xprofile/classes/class-bp-xprofile-data-template.php +3 -2
  163. bp-xprofile/classes/class-bp-xprofile-field.php +7 -3
  164. bp-xprofile/classes/class-bp-xprofile-group.php +150 -63
  165. buddypress.pot +4629 -2834
  166. class-buddypress.php +57 -29
bp-activity/actions/post.php CHANGED
@@ -77,12 +77,15 @@ function bp_activity_action_post_update() {
77
* Filters activity object for BuddyPress core and plugin authors before posting activity update.
78
*
79
* @since 1.2.0
80
*
81
- * @param string $object Activity item being associated to.
82
- * @param string $item_id Component ID being posted to.
83
- * @param string $content Activity content being posted.
84
*/
85
- $activity_id = apply_filters( 'bp_activity_custom_update', $object, $item_id, $content );
86
}
87
88
// Provide user feedback.
77
* Filters activity object for BuddyPress core and plugin authors before posting activity update.
78
*
79
* @since 1.2.0
80
+ * @since 5.0.0 Fixed filter signature to match other instances of filter,
81
+ * with $activity_id as the first param.
82
*
83
+ * @param int $activity_id ID of the activity item.
84
+ * @param string $object Activity item being associated to.
85
+ * @param string $item_id Component ID being posted to.
86
+ * @param string $content Activity content being posted.
87
*/
88
+ $activity_id = apply_filters( 'bp_activity_custom_update', 0, $object, $item_id, $content );
89
}
90
91
// Provide user feedback.
bp-activity/bp-activity-admin.php CHANGED
@@ -310,7 +310,7 @@ function bp_activity_admin_load() {
310
) );
311
wp_enqueue_style( 'bp_activity_admin_css', $bp->plugin_url . "bp-activity/admin/css/admin{$min}.css", array(), bp_get_version() );
312
313
- wp_style_add_data( 'bp_activity_admin_css', 'rtl', true );
314
if ( $min ) {
315
wp_style_add_data( 'bp_activity_admin_css', 'suffix', $min );
316
}
@@ -840,13 +840,19 @@ function bp_activity_admin_get_activity_actions() {
840
$action = array_values( (array) $action );
841
842
for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
843
$actions[ $action[$i]['key'] ] = $action[$i]['value'];
844
}
845
}
846
847
- // This was a mis-named activity type from before BP 1.6.
848
- unset( $actions['friends_register_activity_action'] );
849
-
850
// Sort array by the human-readable value.
851
natsort( $actions );
852
@@ -870,13 +876,20 @@ function bp_activity_admin_edit_metabox_type( $item ) {
870
foreach ( bp_activity_get_actions() as $action ) {
871
$action = array_values( (array) $action );
872
873
- for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ )
874
$actions[ $action[$i]['key'] ] = $action[$i]['value'];
875
}
876
877
- // This was a mis-named activity type from before BP 1.6.
878
- unset( $actions['friends_register_activity_action'] );
879
-
880
// Sort array by the human-readable value.
881
natsort( $actions );
882
310
) );
311
wp_enqueue_style( 'bp_activity_admin_css', $bp->plugin_url . "bp-activity/admin/css/admin{$min}.css", array(), bp_get_version() );
312
313
+ wp_style_add_data( 'bp_activity_admin_css', 'rtl', 'replace' );
314
if ( $min ) {
315
wp_style_add_data( 'bp_activity_admin_css', 'suffix', $min );
316
}
840
$action = array_values( (array) $action );
841
842
for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
843
+ /**
844
+ * Don't take in account:
845
+ * - a mis-named Friends activity type from before BP 1.6,
846
+ * - The Group's component 'activity_update' one as the Activity component is using it.
847
+ */
848
+ if ( 'friends_register_activity_action' === $action[$i]['key'] || 'bp_groups_format_activity_action_group_activity_update' === $action[$i]['format_callback'] ) {
849
+ continue;
850
+ }
851
+
852
$actions[ $action[$i]['key'] ] = $action[$i]['value'];
853
}
854
}
855
856
// Sort array by the human-readable value.
857
natsort( $actions );
858
876
foreach ( bp_activity_get_actions() as $action ) {
877
$action = array_values( (array) $action );
878
879
+ for ( $i = 0, $i_count = count( $action ); $i < $i_count; $i++ ) {
880
+ /**
881
+ * Don't take in account:
882
+ * - a mis-named Friends activity type from before BP 1.6,
883
+ * - The Group's component 'activity_update' one as the Activity component is using it.
884
+ */
885
+ if ( 'friends_register_activity_action' === $action[$i]['key'] || 'bp_groups_format_activity_action_group_activity_update' === $action[$i]['format_callback'] ) {
886
+ continue;
887
+ }
888
+
889
$actions[ $action[$i]['key'] ] = $action[$i]['value'];
890
+ }
891
}
892
893
// Sort array by the human-readable value.
894
natsort( $actions );
895
bp-activity/bp-activity-cssjs.php CHANGED
@@ -36,7 +36,7 @@ function bp_activity_mentions_script() {
36
wp_enqueue_script( 'bp-mentions', buddypress()->plugin_url . "bp-activity/js/mentions{$min}.js", array( 'jquery', 'jquery-atwho' ), bp_get_version(), true );
37
wp_enqueue_style( 'bp-mentions-css', buddypress()->plugin_url . "bp-activity/css/mentions{$min}.css", array(), bp_get_version() );
38
39
- wp_style_add_data( 'bp-mentions-css', 'rtl', true );
40
if ( $min ) {
41
wp_style_add_data( 'bp-mentions-css', 'suffix', $min );
42
}
36
wp_enqueue_script( 'bp-mentions', buddypress()->plugin_url . "bp-activity/js/mentions{$min}.js", array( 'jquery', 'jquery-atwho' ), bp_get_version(), true );
37
wp_enqueue_style( 'bp-mentions-css', buddypress()->plugin_url . "bp-activity/css/mentions{$min}.css", array(), bp_get_version() );
38
39
+ wp_style_add_data( 'bp-mentions-css', 'rtl', 'replace' );
40
if ( $min ) {
41
wp_style_add_data( 'bp-mentions-css', 'suffix', $min );
42
}
bp-activity/bp-activity-filters.php CHANGED
@@ -818,14 +818,16 @@ add_filter( 'bp_activity_set_mentions_scope_args', 'bp_activity_filter_mentions_
818
* Registers Activity personal data exporter.
819
*
820
* @since 4.0.0
821
*
822
* @param array $exporters An array of personal data exporters.
823
* @return array An array of personal data exporters.
824
*/
825
function bp_activity_register_personal_data_exporter( $exporters ) {
826
$exporters['buddypress-activity'] = array(
827
- 'exporter_friendly_name' => __( 'BuddyPress Activity Data', 'buddypress' ),
828
- 'callback' => 'bp_activity_personal_data_exporter',
829
);
830
831
return $exporters;
818
* Registers Activity personal data exporter.
819
*
820
* @since 4.0.0
821
+ * @since 5.0.0 adds an `exporter_bp_friendly_name` param to exporters.
822
*
823
* @param array $exporters An array of personal data exporters.
824
* @return array An array of personal data exporters.
825
*/
826
function bp_activity_register_personal_data_exporter( $exporters ) {
827
$exporters['buddypress-activity'] = array(
828
+ 'exporter_friendly_name' => __( 'BuddyPress Activity Data', 'buddypress' ),
829
+ 'callback' => 'bp_activity_personal_data_exporter',
830
+ 'exporter_bp_friendly_name' => _x( 'Activity Data', 'BuddyPress Activity data exporter friendly name', 'buddypress' ),
831
);
832
833
return $exporters;
bp-activity/bp-activity-template.php CHANGED
@@ -3848,6 +3848,11 @@ function bp_activity_show_filters( $context = '' ) {
3848
$action['key'] = 'friendship_accepted,friendship_created';
3849
}
3850
3851
$filters[ $action['key'] ] = $action['label'];
3852
}
3853
3848
$action['key'] = 'friendship_accepted,friendship_created';
3849
}
3850
3851
+ // The 'activity_update' filter is already used by the Activity component.
3852
+ if ( 'bp_groups_format_activity_action_group_activity_update' === $action['format_callback'] ) {
3853
+ continue;
3854
+ }
3855
+
3856
$filters[ $action['key'] ] = $action['label'];
3857
}
3858
bp-activity/classes/class-bp-activity-activity.php CHANGED
@@ -360,8 +360,10 @@ class BP_Activity_Activity {
360
public static function get( $args = array() ) {
361
global $wpdb;
362
363
// Backward compatibility with old method of passing arguments.
364
- if ( !is_array( $args ) || func_num_args() > 1 ) {
365
_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__ ) );
366
367
$old_args_keys = array(
@@ -378,7 +380,7 @@ class BP_Activity_Activity {
378
10 => 'spam'
379
);
380
381
- $args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
382
}
383
384
$bp = buddypress();
@@ -1467,6 +1469,8 @@ class BP_Activity_Activity {
1467
public static function get_activity_comments( $activity_id, $left, $right, $spam = 'ham_only', $top_level_parent_id = 0 ) {
1468
global $wpdb;
1469
1470
if ( empty( $top_level_parent_id ) ) {
1471
$top_level_parent_id = $activity_id;
1472
}
@@ -1514,7 +1518,7 @@ class BP_Activity_Activity {
1514
* @param BP_Activity_Activity $value Magic method referring to currently called method.
1515
* @param array $func_args Array of the method's argument list.
1516
*/
1517
- if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, func_get_args() ) ) {
1518
1519
/**
1520
* Filters the MySQL prepared statement for the legacy activity query.
@@ -1539,6 +1543,7 @@ class BP_Activity_Activity {
1539
$descendant_ids = $wpdb->get_col( $sql );
1540
$descendants = self::get_activity_data( $descendant_ids );
1541
$descendants = self::append_user_fullnames( $descendants );
1542
}
1543
1544
$ref = array();
360
public static function get( $args = array() ) {
361
global $wpdb;
362
363
+ $function_args = func_get_args();
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(
380
10 => 'spam'
381
);
382
383
+ $args = bp_core_parse_args_array( $old_args_keys, $function_args );
384
}
385
386
$bp = buddypress();
1469
public static function get_activity_comments( $activity_id, $left, $right, $spam = 'ham_only', $top_level_parent_id = 0 ) {
1470
global $wpdb;
1471
1472
+ $function_args = func_get_args();
1473
+
1474
if ( empty( $top_level_parent_id ) ) {
1475
$top_level_parent_id = $activity_id;
1476
}
1518
* @param BP_Activity_Activity $value Magic method referring to currently called method.
1519
* @param array $func_args Array of the method's argument list.
1520
*/
1521
+ if ( apply_filters( 'bp_use_legacy_activity_query', false, __METHOD__, $function_args ) ) {
1522
1523
/**
1524
* Filters the MySQL prepared statement for the legacy activity query.
1543
$descendant_ids = $wpdb->get_col( $sql );
1544
$descendants = self::get_activity_data( $descendant_ids );
1545
$descendants = self::append_user_fullnames( $descendants );
1546
+ $descendants = self::generate_action_strings( $descendants );
1547
}
1548
1549
$ref = array();
bp-activity/classes/class-bp-activity-component.php CHANGED
@@ -124,9 +124,30 @@ class BP_Activity_Component extends BP_Component {
124
require $this->path . 'bp-activity/screens/just-me.php';
125
}
126
127
- // Screens - User secondary nav.
128
- if ( bp_is_user() && in_array( bp_current_action(), array( 'friends', 'groups', 'favorites', 'mentions' ), true ) ) {
129
- require $this->path . 'bp-activity/screens/' . bp_current_action() . '.php';
130
}
131
132
// Screens - Single permalink.
@@ -435,4 +456,16 @@ class BP_Activity_Component extends BP_Component {
435
436
parent::setup_cache_groups();
437
}
438
}
124
require $this->path . 'bp-activity/screens/just-me.php';
125
}
126
127
+ /**
128
+ * Screens - User secondary nav.
129
+ *
130
+ * For these specific actions, slugs can be customized using `BP_{COMPONENT}_SLUGS`.
131
+ * As a result, we need to map filenames with slugs.
132
+ */
133
+ $filenames = array(
134
+ 'favorites' => 'favorites',
135
+ 'mentions' => 'mentions',
136
+ );
137
+
138
+ if ( bp_is_active( 'friends' ) ) {
139
+ $filenames[bp_get_friends_slug()] = 'friends';
140
+ }
141
+
142
+ if ( bp_is_active( 'groups' ) ) {
143
+ $filenames[bp_get_groups_slug()] = 'groups';
144
+ }
145
+
146
+ // The slug is the current action requested.
147
+ $slug = bp_current_action();
148
+
149
+ if ( bp_is_user() && isset( $filenames[ $slug ] ) ) {
150
+ require $this->path . 'bp-activity/screens/' . $filenames[ $slug ] . '.php';
151
}
152
153
// Screens - Single permalink.
456
457
parent::setup_cache_groups();
458
}
459
+
460
+ /**
461
+ * Init the BP REST API.
462
+ *
463
+ * @since 5.0.0
464
+ */
465
+ public function rest_api_init() {
466
+ $controller = new BP_REST_Activity_Endpoint();
467
+ $controller->register_routes();
468
+
469
+ parent::rest_api_init();
470
+ }
471
}
bp-activity/classes/class-bp-activity-list-table.php CHANGED
@@ -338,11 +338,7 @@ class BP_Activity_List_Table extends WP_List_Table {
338
*
339
* @return array Key/value pairs for the bulk actions dropdown.
340
*/
341
- function get_bulk_actions() {
342
- $actions = array();
343
- $actions['bulk_spam'] = __( 'Mark as Spam', 'buddypress' );
344
- $actions['bulk_ham'] = __( 'Not Spam', 'buddypress' );
345
- $actions['bulk_delete'] = __( 'Delete Permanently', 'buddypress' );
346
347
/**
348
* Filters the default bulk actions so plugins can add custom actions.
@@ -351,7 +347,11 @@ class BP_Activity_List_Table extends WP_List_Table {
351
*
352
* @param array $actions Default available actions for bulk operations.
353
*/
354
- return apply_filters( 'bp_activity_list_table_get_bulk_actions', $actions );
355
}
356
357
/**
@@ -364,6 +364,7 @@ class BP_Activity_List_Table extends WP_List_Table {
364
* @return array The columns to appear in the Activity list table.
365
*/
366
function get_columns() {
367
/**
368
* Filters the titles for the columns for the activity list table.
369
*
@@ -373,7 +374,7 @@ class BP_Activity_List_Table extends WP_List_Table {
373
*/
374
return apply_filters( 'bp_activity_list_table_get_columns', array(
375
'cb' => '<input name type="checkbox" />',
376
- 'author' => _x('Author', 'Admin SWA column header', 'buddypress' ),
377
'comment' => _x( 'Activity', 'Admin SWA column header', 'buddypress' ),
378
'action' => _x( 'Action', 'Admin SWA column header', 'buddypress' ),
379
'response' => _x( 'In Response To', 'Admin SWA column header', 'buddypress' ),
@@ -383,20 +384,20 @@ class BP_Activity_List_Table extends WP_List_Table {
383
/**
384
* Get the column names for sortable columns.
385
*
386
- * Currently, returns an empty array (no columns are sortable).
387
- *
388
* @since 1.6.0
389
- * @todo For this to work, BP_Activity_Activity::get() needs updating
390
- * to support ordering by specific fields.
391
*
392
* @return array The columns that can be sorted on the Activity screen.
393
*/
394
- function get_sortable_columns() {
395
- return array();
396
397
- /*return array(
398
- 'author' => array( 'activity_author', false ), // Intentionally not using "=>"
399
- );*/
400
}
401
402
/**
@@ -434,6 +435,11 @@ class BP_Activity_List_Table extends WP_List_Table {
434
$component = 'xprofile';
435
}
436
437
if ( bp_is_active( $component ) ) {
438
if ( $component === 'xprofile' ) {
439
$component_name = buddypress()->profile->name;
@@ -454,7 +460,7 @@ class BP_Activity_List_Table extends WP_List_Table {
454
<?php
455
456
// Skip the incorrectly named pre-1.6 action.
457
- if ( 'friends_register_activity_action' !== $action_key ) : ?>
458
459
<option value="<?php echo esc_attr( $action_key ); ?>" <?php selected( $action_key, $selected ); ?>><?php echo esc_html( $action_values[ 'value' ] ); ?></option>
460
338
*
339
* @return array Key/value pairs for the bulk actions dropdown.
340
*/
341
+ public function get_bulk_actions() {
342
343
/**
344
* Filters the default bulk actions so plugins can add custom actions.
347
*
348
* @param array $actions Default available actions for bulk operations.
349
*/
350
+ return apply_filters( 'bp_activity_list_table_get_bulk_actions', array(
351
+ 'bulk_spam' => __( 'Mark as Spam', 'buddypress' ),
352
+ 'bulk_ham' => __( 'Not Spam', 'buddypress' ),
353
+ 'bulk_delete' => __( 'Delete Permanently', 'buddypress' ),
354
+ ) );
355
}
356
357
/**
364
* @return array The columns to appear in the Activity list table.
365
*/
366
function get_columns() {
367
+
368
/**
369
* Filters the titles for the columns for the activity list table.
370
*
374
*/
375
return apply_filters( 'bp_activity_list_table_get_columns', array(
376
'cb' => '<input name type="checkbox" />',
377
+ 'author' => _x( 'Author', 'Admin SWA column header', 'buddypress' ),
378
'comment' => _x( 'Activity', 'Admin SWA column header', 'buddypress' ),
379
'action' => _x( 'Action', 'Admin SWA column header', 'buddypress' ),
380
'response' => _x( 'In Response To', 'Admin SWA column header', 'buddypress' ),
384
/**
385
* Get the column names for sortable columns.
386
*
387
* @since 1.6.0
388
*
389
* @return array The columns that can be sorted on the Activity screen.
390
*/
391
+ public function get_sortable_columns() {
392
393
+ /**
394
+ * Filters the column names for the sortable columns.
395
+ *
396
+ * @since 5.0.0
397
+ *
398
+ * @param array $value Array of column names.
399
+ */
400
+ return apply_filters( 'bp_activity_list_table_get_sortable_columns', array() );
401
}
402
403
/**
435
$component = 'xprofile';
436
}
437
438
+ // The 'activity_update' filter is already used by the Activity component.
439
+ if ( isset( $actions->activity_update ) && 'bp_groups_format_activity_action_group_activity_update' === $actions->activity_update['format_callback'] ) {
440
+ unset( $actions->activity_update );
441
+ }
442
+
443
if ( bp_is_active( $component ) ) {
444
if ( $component === 'xprofile' ) {
445
$component_name = buddypress()->profile->name;
460
<?php
461
462
// Skip the incorrectly named pre-1.6 action.
463
+ if ( 'friends_register_activity_action' !== $action_key ) : ?>
464
465
<option value="<?php echo esc_attr( $action_key ); ?>" <?php selected( $action_key, $selected ); ?>><?php echo esc_html( $action_values[ 'value' ] ); ?></option>
466
bp-activity/classes/class-bp-activity-template.php CHANGED
@@ -139,8 +139,10 @@ class BP_Activity_Template {
139
public function __construct( $args ) {
140
$bp = buddypress();
141
142
// Backward compatibility with old method of passing arguments.
143
- if ( !is_array( $args ) || func_num_args() > 1 ) {
144
_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__ ) );
145
146
$old_args_keys = array(
@@ -159,7 +161,7 @@ class BP_Activity_Template {
159
12 => 'page_arg'
160
);
161
162
- $args = bp_core_parse_args_array( $old_args_keys, func_get_args() );
163
}
164
165
$defaults = array(
139
public function __construct( $args ) {
140
$bp = buddypress();
141
142
+ $function_args = func_get_args();
143
+
144
// Backward compatibility with old method of passing arguments.
145
+ if ( !is_array( $args ) || count( $function_args ) > 1 ) {
146
_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__ ) );
147
148
$old_args_keys = array(
161
12 => 'page_arg'
162
);
163
164
+ $args = bp_core_parse_args_array( $old_args_keys, $function_args );
165
}
166
167
$defaults = array(
bp-activity/classes/class-bp-rest-activity-endpoint.php ADDED
@@ -0,0 +1,1550 @@
1
+ <?php
2
+ /**
3
+ * BP REST: BP_REST_Activity_Endpoint class
4
+ *
5
+ * @package BuddyPress
6
+ * @since 5.0.0
7
+ */
8
+
9
+ defined( 'ABSPATH' ) || exit;
10
+
11
+ /**
12
+ * Activity endpoints.
13
+ *
14
+ * @since 5.0.0
15
+ */
16
+ class BP_REST_Activity_Endpoint extends WP_REST_Controller {
17
+
18
+ /**
19
+ * User favorites.
20
+ *
21
+ * @since 5.0.0
22
+ *
23
+ * @var array|null
24
+ */
25
+ protected $user_favorites = null;
26
+
27
+ /**
28
+ * Constructor.
29
+ *
30
+ * @since 5.0.0
31
+ */
32
+ public function __construct() {
33
+ $this->namespace = bp_rest_namespace() . '/' . bp_rest_version();
34
+ $this->rest_base = buddypress()->activity->id;
35
+ }
36
+
37
+ /**
38
+ * Register the component routes.
39
+ *
40
+ * @since 5.0.0
41
+ */
42
+ public function register_routes() {
43
+ register_rest_route(
44
+ $this->namespace,
45
+ '/' . $this->rest_base,
46
+ array(
47
+ array(
48
+ 'methods' => WP_REST_Server::READABLE,
49
+ 'callback' => array( $this, 'get_items' ),
50
+ 'permission_callback' => array( $this, 'get_items_permissions_check' ),
51
+ 'args' => $this->get_collection_params(),
52
+ ),
53
+ array(
54
+ 'methods' => WP_REST_Server::CREATABLE,
55
+ 'callback' => array( $this, 'create_item' ),
56
+ 'permission_callback' => array( $this, 'create_item_permissions_check' ),
57
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
58
+ ),
59
+ 'schema' => array( $this, 'get_item_schema' ),
60
+ )
61
+ );
62
+
63
+ $activity_endpoint = '/' . $this->rest_base . '/(?P<id>[\d]+)';
64
+
65
+ register_rest_route(
66
+ $this->namespace,
67
+ $activity_endpoint,
68
+ array(
69
+ 'args' => array(
70
+ 'id' => array(
71
+ 'description' => __( 'A unique numeric ID for the activity.', 'buddypress' ),
72
+ 'type' => 'integer',
73
+ ),
74
+ ),
75
+ array(
76
+ 'methods' => WP_REST_Server::READABLE,
77
+ 'callback' => array( $this, 'get_item' ),
78
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
79
+ 'args' => array(
80
+ 'context' => $this->get_context_param(
81
+ array(
82
+ 'default' => 'view',
83
+ )
84
+ ),
85
+ ),
86
+ ),
87
+ array(
88
+ 'methods' => WP_REST_Server::EDITABLE,
89
+ 'callback' => array( $this, 'update_item' ),
90
+ 'permission_callback' => array( $this, 'update_item_permissions_check' ),
91
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
92
+ ),
93
+ array(
94
+ 'methods' => WP_REST_Server::DELETABLE,
95
+ 'callback' => array( $this, 'delete_item' ),
96
+ 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
97
+ ),
98
+ 'schema' => array( $this, 'get_item_schema' ),
99
+ )
100
+ );
101
+
102
+ // Register the favorite route.
103
+ register_rest_route(
104
+ $this->namespace,
105
+ $activity_endpoint . '/favorite',
106
+ array(
107
+ 'args' => array(
108
+ 'id' => array(
109
+ 'description' => __( 'A unique numeric ID for the activity.', 'buddypress' ),
110
+ 'type' => 'integer',
111
+ ),
112
+ ),
113
+ array(
114
+ 'methods' => WP_REST_Server::EDITABLE,
115
+ 'callback' => array( $this, 'update_favorite' ),
116
+ 'permission_callback' => array( $this, 'update_favorite_permissions_check' ),
117
+ ),
118
+ 'schema' => array( $this, 'get_item_schema' ),
119
+ )
120
+ );
121
+ }
122
+
123
+ /**
124
+ * Retrieve activities.
125
+ *
126
+ * @since 5.0.0
127
+ *
128
+ * @param WP_REST_Request $request Full details about the request.
129
+ * @return WP_REST_Response List of activities response data.
130
+ */
131
+ public function get_items( $request ) {
132
+ $args = array(
133
+ 'exclude' => $request['exclude'],
134
+ 'in' => $request['include'],
135
+ 'page' => $request['page'],
136
+ 'per_page' => $request['per_page'],
137
+ 'search_terms' => $request['search'],
138
+ 'sort' => $request['order'],
139
+ 'spam' => $request['status'],
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,
146
+ 'update_meta_cache' => true,
147
+ 'filter' => false,
148
+ );
149
+
150
+ if ( empty( $args['display_comments'] ) || 'false' === $args['display_comments'] ) {
151
+ $args['display_comments'] = false;
152
+ }
153
+
154
+ if ( empty( $request['exclude'] ) ) {
155
+ $args['exclude'] = false;
156
+ }
157
+
158
+ if ( empty( $request['include'] ) ) {
159
+ $args['in'] = false;
160
+ }
161
+
162
+ if ( isset( $request['after'] ) ) {
163
+ $args['since'] = $request['after'];
164
+ }
165
+
166
+ if ( isset( $request['user_id'] ) ) {
167
+ $args['filter']['user_id'] = $request['user_id'];
168
+ }
169
+
170
+ $item_id = 0;
171
+ if ( ! empty( $args['group_id'] ) ) {
172
+ $args['filter']['object'] = 'groups';
173
+ $args['filter']['primary_id'] = $args['group_id'];
174
+
175
+ $item_id = $args['group_id'];
176
+ }
177
+
178
+ if ( ! empty( $args['site_id'] ) ) {
179
+ $args['filter']['object'] = 'blogs';
180
+ $args['filter']['primary_id'] = $args['site_id'];
181
+
182
+ $item_id = $args['site_id'];
183
+ }
184
+
185
+ if ( empty( $args['group_id'] ) && empty( $args['site_id'] ) ) {
186
+ if ( isset( $request['component'] ) ) {
187
+ $args['filter']['object'] = $request['component'];
188
+ }
189
+
190
+ if ( ! empty( $request['primary_id'] ) ) {
191
+ $item_id = $request['primary_id'];
192
+ $args['filter']['primary_id'] = $item_id;
193
+ }
194
+ }
195
+
196
+ if ( isset( $request['type'] ) ) {
197
+ $args['filter']['action'] = $request['type'];
198
+ }
199
+
200
+ if ( ! empty( $request['secondary_id'] ) ) {
201
+ $args['filter']['secondary_id'] = $request['secondary_id'];
202
+ }
203
+
204
+ if ( $args['in'] ) {
205
+ $args['count_total'] = false;
206
+ }
207
+
208
+ if ( $this->show_hidden( $request['component'], $item_id ) ) {
209
+ $args['show_hidden'] = true;
210
+ }
211
+
212
+ /**
213
+ * Filter the query arguments for the request.
214
+ *
215
+ * @since 5.0.0
216
+ *
217
+ * @param array $args Key value array of query var to query value.
218
+ * @param WP_REST_Request $request The request sent to the API.
219
+ */
220
+ $args = apply_filters( 'bp_rest_activity_get_items_query_args', $args, $request );
221
+
222
+ // Actually, query it.
223
+ $activities = bp_activity_get( $args );
224
+
225
+ $retval = array();
226
+ foreach ( $activities['activities'] as $activity ) {
227
+ $retval[] = $this->prepare_response_for_collection(
228
+ $this->prepare_item_for_response( $activity, $request )
229
+ );
230
+ }
231
+
232
+ $response = rest_ensure_response( $retval );
233
+ $response = bp_rest_response_add_total_headers( $response, $activities['total'], $args['per_page'] );
234
+
235
+ /**
236
+ * Fires after a list of activities is fetched via the REST API.
237
+ *
238
+ * @since 5.0.0
239
+ *
240
+ * @param array $activities Fetched activities.
241
+ * @param WP_REST_Response $response The response data.
242
+ * @param WP_REST_Request $request The request sent to the API.
243
+ */
244
+ do_action( 'bp_rest_activity_get_items', $activities, $response, $request );
245
+
246
+ return $response;
247
+ }
248
+
249
+ /**
250
+ * Check if a given request has access to activity items.
251
+ *
252
+ * @since 5.0.0
253
+ *
254
+ * @param WP_REST_Request $request Full data about the request.
255
+ * @return bool|WP_Error
256
+ */
257
+ public function get_items_permissions_check( $request ) {
258
+
259
+ /**
260
+ * Filter the activity `get_items` permissions check.
261
+ *
262
+ * @since 5.0.0
263
+ *
264
+ * @param bool|WP_Error $retval Returned value.
265
+ * @param WP_REST_Request $request The request sent to the API.
266
+ */
267
+ return apply_filters( 'bp_rest_activity_get_items_permissions_check', true, $request );
268
+ }
269
+
270
+ /**
271
+ * Retrieve an activity.
272
+ *
273
+ * @since 5.0.0
274
+ *
275
+ * @param WP_REST_Request $request Full details about the request.
276
+ * @return WP_REST_Response|WP_Error
277
+ */
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 )
284
+ ),
285
+ );
286
+
287
+ $response = rest_ensure_response( $retval );
288
+
289
+ /**
290
+ * Fires after an activity is fetched via the REST API.
291
+ *
292
+ * @since 5.0.0
293
+ *
294
+ * @param BP_Activity_Activity $activity Fetched activity.
295
+ * @param WP_REST_Response $response The response data.
296
+ * @param WP_REST_Request $request The request sent to the API.
297
+ */
298
+ do_action( 'bp_rest_activity_get_item', $activity, $response, $request );
299
+
300
+ return $response;
301
+ }
302
+
303
+ /**
304
+ * Check if a given request has access to get information about a specific activity.
305
+ *
306
+ * @since 5.0.0
307
+ *
308
+ * @param WP_REST_Request $request Full data about the request.
309
+ * @return bool|WP_Error
310
+ */
311
+ public function get_item_permissions_check( $request ) {
312
+ $retval = true;
313
+
314
+ if ( ! $this->can_see( $request ) ) {
315
+ $retval = new WP_Error(
316
+ 'bp_rest_authorization_required',
317
+ __( 'Sorry, you cannot view the activities.', 'buddypress' ),
318
+ array(
319
+ 'status' => rest_authorization_required_code(),
320
+ )
321
+ );
322
+ }
323
+
324
+ /**
325
+ * Filter the activity `get_item` permissions check.
326
+ *
327
+ * @since 5.0.0
328
+ *
329
+ * @param bool|WP_Error $retval Returned value.
330
+ * @param WP_REST_Request $request The request sent to the API.
331
+ */
332
+ return apply_filters( 'bp_rest_activity_get_item_permissions_check', $retval, $request );
333
+ }
334
+
335
+ /**
336
+ * Create an activity.
337
+ *
338
+ * @since 5.0.0
339
+ *
340
+ * @param WP_REST_Request $request Full data about the request.
341
+ * @return WP_REST_Response|WP_Error
342
+ */
343
+ public function create_item( $request ) {
344
+ $request->set_param( 'context', 'edit' );
345
+
346
+ if ( empty( $request['content'] ) ) {
347
+ return new WP_Error(
348
+ 'bp_rest_create_activity_empty_content',
349
+ __( 'Please, enter some content.', 'buddypress' ),
350
+ array(
351
+ 'status' => 500,
352
+ )
353
+ );
354
+ }
355
+
356
+ $prepared_activity = $this->prepare_item_for_database( $request );
357
+
358
+ // Fallback for the activity_update type.
359
+ $type = 'activity_update';
360
+ if ( ! empty( $request['type'] ) ) {
361
+ $type = $request['type'];
362
+ }
363
+
364
+ $prime = $request['primary_item_id'];
365
+ $activity_id = 0;
366
+
367
+ // Post a regular activity update.
368
+ if ( 'activity_update' === $type ) {
369
+ if ( bp_is_active( 'groups' ) && ! is_null( $prime ) ) {
370
+ $activity_id = groups_post_update( $prepared_activity );
371
+ } else {
372
+ $activity_id = bp_activity_post_update( $prepared_activity );
373
+ }
374
+
375
+ // Post an activity comment.
376
+ } elseif ( 'activity_comment' === $type ) {
377
+
378
+ // ID of the root activity item.
379
+ if ( isset( $prime ) ) {
380
+ $prepared_activity->activity_id = (int) $prime;
381
+ }
382
+
383
+ // ID of a parent comment.
384
+ if ( isset( $request['secondary_item_id'] ) ) {
385
+ $prepared_activity->parent_id = (int) $request['secondary_item_id'];
386
+ }
387
+
388
+ $activity_id = bp_activity_new_comment( $prepared_activity );
389
+
390
+ // Otherwise add an activity.
391
+ } else {
392
+ $activity_id = bp_activity_add( $prepared_activity );
393
+ }
394
+
395
+ if ( ! is_numeric( $activity_id ) ) {
396
+ return new WP_Error(
397
+ 'bp_rest_user_cannot_create_activity',
398
+ __( 'Cannot create new activity.', 'buddypress' ),
399
+ array(
400
+ 'status' => 500,
401
+ )
402
+ );
403
+ }
404
+
405
+ $activity = bp_activity_get(
406
+ array(
407
+ 'in' => $activity_id,
408
+ 'display_comments' => 'stream',
409
+ 'show_hidden' => $request['hidden'],
410
+ )
411
+ );
412
+
413
+ $activity = current( $activity['activities'] );
414
+ $fields_update = $this->update_additional_fields_for_object( $activity, $request );
415
+
416
+ if ( is_wp_error( $fields_update ) ) {
417
+ return $fields_update;
418
+ }
419
+
420
+ $retval = array(
421
+ $this->prepare_response_for_collection(
422
+ $this->prepare_item_for_response( $activity, $request )
423
+ ),
424
+ );
425
+
426
+ $response = rest_ensure_response( $retval );
427
+
428
+ /**
429
+ * Fires after an activity item is created via the REST API.
430
+ *
431
+ * @since 5.0.0
432
+ *
433
+ * @param BP_Activity_Activity $activity The created activity.
434
+ * @param WP_REST_Response $response The response data.
435
+ * @param WP_REST_Request $request The request sent to the API.
436
+ */
437
+ do_action( 'bp_rest_activity_create_item', $activity, $response, $request );
438
+
439
+ return $response;
440
+ }
441
+
442
+ /**
443
+ * Checks if a given request has access to create an activity.
444
+ *
445
+ * @since 5.0.0
446
+ *
447
+ * @param WP_REST_Request $request Full details about the request.
448
+ * @return bool|WP_Error
449
+ */
450
+ public function create_item_permissions_check( $request ) {
451
+ $retval = true;
452
+
453
+ if ( ! is_user_logged_in() ) {
454
+ $retval = new WP_Error(
455
+ 'bp_rest_authorization_required',
456
+ __( 'Sorry, you are not allowed to create activities.', 'buddypress' ),
457
+ array(
458
+ 'status' => rest_authorization_required_code(),
459
+ )
460
+ );
461
+ }
462
+
463
+ $item_id = $request['primary_item_id'];
464
+ $component = $request['component'];
465
+
466
+ if ( true === $retval && bp_is_active( 'groups' ) && buddypress()->groups->id === $component && ! is_null( $item_id ) ) {
467
+ if ( ! $this->show_hidden( $component, $item_id ) ) {
468
+ $retval = new WP_Error(
469
+ 'bp_rest_authorization_required',
470
+ __( 'Sorry, you are not allowed to create activities.', 'buddypress' ),
471
+ array(
472
+ 'status' => rest_authorization_required_code(),
473
+ )
474
+ );
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Filter the activity `create_item` permissions check.
480
+ *
481
+ * @since 5.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_activity_create_item_permissions_check', $retval, $request );
487
+ }
488
+
489
+ /**
490
+ * Update an activity.
491
+ *
492
+ * @since 5.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 update_item( $request ) {
498
+ $request->set_param( 'context', 'edit' );
499
+
500
+ if ( empty( $request['content'] ) ) {
501
+ return new WP_Error(
502
+ 'bp_rest_update_activity_empty_content',
503
+ __( 'Please, enter some content.', 'buddypress' ),
504
+ array(
505
+ 'status' => 500,
506
+ )
507
+ );
508
+ }
509
+
510
+ $activity_id = bp_activity_add( $this->prepare_item_for_database( $request ) );
511
+
512
+ if ( ! is_numeric( $activity_id ) ) {
513
+ return new WP_Error(
514
+ 'bp_rest_user_cannot_update_activity',
515
+ __( 'Cannot update existing activity.', 'buddypress' ),
516
+ array(
517
+ 'status' => 500,
518
+ )
519
+ );
520
+ }
521
+
522
+ $activity = $this->get_activity_object( $activity_id );
523
+ $fields_update = $this->update_additional_fields_for_object( $activity, $request );
524
+
525
+ if ( is_wp_error( $fields_update ) ) {
526
+ return $fields_update;
527
+ }
528
+
529
+ $retval = array(
530
+ $this->prepare_response_for_collection(
531
+ $this->prepare_item_for_response( $activity, $request )
532
+ ),
533
+ );
534
+
535
+ $response = rest_ensure_response( $retval );
536
+
537
+ /**
538
+ * Fires after an activity is updated via the REST API.
539
+ *
540
+ * @since 5.0.0
541
+ *
542
+ * @param BP_Activity_Activity $activity The updated activity.
543
+ * @param WP_REST_Response $response The response data.
544
+ * @param WP_REST_Request $request The request sent to the API.
545
+ */
546
+ do_action( 'bp_rest_activity_update_item', $activity, $response, $request );
547
+
548
+ return $response;
549
+ }
550
+
551
+ /**
552
+ * Check if a given request has access to update an activity.
553
+ *
554
+ * @since 5.0.0
555
+ *
556
+ * @param WP_REST_Request $request Full details about the request.
557
+ * @return bool|WP_Error
558
+ */
559
+ public function update_item_permissions_check( $request ) {
560
+ $retval = true;
561
+
562
+ if ( ! is_user_logged_in() ) {
563
+ $retval = new WP_Error(
564
+ 'bp_rest_authorization_required',
565
+ __( 'Sorry, you are not allowed to update this activity.', 'buddypress' ),
566
+ array(
567
+ 'status' => rest_authorization_required_code(),
568
+ )
569
+ );
570
+ }
571
+
572
+ $activity = $this->get_activity_object( $request );
573
+
574
+ if ( true === $retval && empty( $activity->id ) ) {
575
+ $retval = new WP_Error(
576
+ 'bp_rest_invalid_id',
577
+ __( 'Invalid activity id.', 'buddypress' ),
578
+ array(
579
+ 'status' => 404,
580
+ )
581
+ );
582
+ }
583
+
584
+ if ( true === $retval && ! bp_activity_user_can_delete( $activity ) ) {
585
+ $retval = new WP_Error(
586
+ 'bp_rest_authorization_required',
587
+ __( 'Sorry, you are not allowed to update this activity.', 'buddypress' ),
588
+ array(
589
+ 'status' => 500,
590
+ )
591
+ );
592
+ }
593
+
594
+ /**
595
+ * Filter the activity `update_item` permissions check.
596
+ *
597
+ * @since 5.0.0
598
+ *
599
+ * @param bool|WP_Error $retval Returned value.
600
+ * @param WP_REST_Request $request The request sent to the API.
601
+ */
602
+ return apply_filters( 'bp_rest_activity_update_item_permissions_check', $retval, $request );
603
+ }
604
+
605
+ /**
606
+ * Delete activity.
607
+ *
608
+ * @since 5.0.0
609
+ *
610
+ * @param WP_REST_Request $request Full details about the request.
611
+ * @return WP_REST_Response|WP_Error
612
+ */
613
+ public function delete_item( $request ) {
614
+ // Setting context.
615
+ $request->set_param( 'context', 'edit' );
616
+
617
+ // Get the activity before it's deleted.
618
+ $activity = $this->get_activity_object( $request );
619
+ $previous = $this->prepare_item_for_response( $activity, $request );
620
+
621
+ if ( 'activity_comment' === $activity->type ) {
622
+ $retval = bp_activity_delete_comment( $activity->item_id, $activity->id );
623
+ } else {
624
+ $retval = bp_activity_delete(
625
+ array(
626
+ 'id' => $activity->id,
627
+ )
628
+ );
629
+ }
630
+
631
+ if ( ! $retval ) {
632
+ return new WP_Error(
633
+ 'bp_rest_activity_cannot_delete',
634
+ __( 'Could not delete the activity.', 'buddypress' ),
635
+ array(
636
+ 'status' => 500,
637
+ )
638
+ );
639
+ }
640
+
641
+ // Build the response.
642
+ $response = new WP_REST_Response();
643
+ $response->set_data(
644
+ array(
645
+ 'deleted' => true,
646
+ 'previous' => $previous->get_data(),
647
+ )
648
+ );
649
+
650
+ /**
651
+ * Fires after an activity is deleted via the REST API.
652
+ *
653
+ * @since 5.0.0
654
+ *
655
+ * @param BP_Activity_Activity $activity The deleted activity.
656
+ * @param WP_REST_Response $response The response data.
657
+ * @param WP_REST_Request $request The request sent to the API.
658
+ */
659
+ do_action( 'bp_rest_activity_delete_item', $activity, $response, $request );
660
+
661
+ return $response;
662
+ }
663
+
664
+ /**
665
+ * Check if a given request has access to delete an activity.
666
+ *
667
+ * @since 5.0.0
668
+ *
669
+ * @param WP_REST_Request $request Full details about the request.
670
+ * @return bool|WP_Error
671
+ */
672
+ public function delete_item_permissions_check( $request ) {
673
+ $retval = true;
674
+
675
+ if ( ! is_user_logged_in() ) {
676
+ $retval = new WP_Error(
677
+ 'bp_rest_authorization_required',
678
+ __( 'Sorry, you are not allowed to delete this activity.', 'buddypress' ),
679
+ array(
680
+ 'status' => rest_authorization_required_code(),
681
+ )
682
+ );
683
+ }
684
+
685
+ $activity = $this->get_activity_object( $request );
686
+
687
+ if ( true === $retval && empty( $activity->id ) ) {
688
+ $retval = new WP_Error(
689
+ 'bp_rest_invalid_id',
690
+ __( 'Invalid activity id.', 'buddypress' ),
691
+ array(
692
+ 'status' => 404,
693
+ )
694
+ );
695
+ }
696
+
697
+ if ( true === $retval && ! bp_activity_user_can_delete( $activity ) ) {
698
+ $retval = new WP_Error(
699
+ 'bp_rest_authorization_required',
700
+ __( 'Sorry, you are not allowed to delete this activity.', 'buddypress' ),
701
+ array(
702
+ 'status' => rest_authorization_required_code(),
703
+ )
704
+ );
705
+ }
706
+
707
+ /**
708
+ * Filter the activity `delete_item` permissions check.
709
+ *
710
+ * @since 5.0.0
711
+ *
712
+ * @param bool|WP_Error $retval Returned value.
713
+ * @param WP_REST_Request $request The request sent to the API.
714
+ */
715
+ return apply_filters( 'bp_rest_activity_delete_item_permissions_check', $retval, $request );
716
+ }
717
+
718
+ /**
719
+ * Gets the current user's favorites.
720
+ *
721
+ * @since 5.0.0
722
+ *
723
+ * @return array Array of activity IDs.
724
+ */
725
+ public function get_user_favorites() {
726
+ if ( null === $this->user_favorites ) {
727
+ if ( is_user_logged_in() ) {
728
+ $user_favorites = bp_activity_get_user_favorites( get_current_user_id() );
729
+ $this->user_favorites = array_filter( wp_parse_id_list( $user_favorites ) );
730
+ } else {
731
+ $this->user_favorites = array();
732
+ }
733
+ }
734
+
735
+ return $this->user_favorites;
736
+ }
737
+
738
+ /**
739
+ * Adds or removes the activity from the current user's favorites.
740
+ *
741
+ * @since 5.0.0
742
+ *
743
+ * @param WP_REST_Request $request Full details about the request.
744
+ * @return WP_REST_Response|WP_Error
745
+ */
746
+ public function update_favorite( $request ) {
747
+ $activity = $this->get_activity_object( $request );
748
+
749
+ if ( empty( $activity->id ) ) {
750
+ return new WP_Error(
751
+ 'bp_rest_invalid_id',
752
+ __( 'Invalid activity id.', 'buddypress' ),
753
+ array(
754
+ 'status' => 404,
755
+ )
756
+ );
757
+ }
758
+
759
+ $user_id = get_current_user_id();
760
+
761
+ $result = false;
762
+ if ( in_array( $activity->id, $this->get_user_favorites(), true ) ) {
763
+ $result = bp_activity_remove_user_favorite( $activity->id, $user_id );
764
+ $message = __( 'Sorry, you cannot remove the activity from your favorites.', 'buddypress' );
765
+
766
+ // Update the user favorites, removing the activity ID.
767
+ $this->user_favorites = array_diff( $this->get_user_favorites(), array( $activity->id ) );
768
+ } else {
769
+ $result = bp_activity_add_user_favorite( $activity->id, $user_id );
770
+ $message = __( 'Sorry, you cannot add the activity to your favorites.', 'buddypress' );
771
+
772
+ // Update the user favorites, adding the activity ID.
773
+ $this->user_favorites[] = (int) $activity->id;
774
+ }
775
+
776
+ if ( ! $result ) {
777
+ return new WP_Error(
778
+ 'bp_rest_user_cannot_update_activity_favorite',
779
+ $message,
780
+ array(
781
+ 'status' => 500,
782
+ )
783
+ );
784
+ }
785
+
786
+ // Setting context.
787
+ $request->set_param( 'context', 'edit' );
788
+
789
+ // Prepare the response now the user favorites has been updated.
790
+ $retval = array(
791
+ $this->prepare_response_for_collection(
792
+ $this->prepare_item_for_response( $activity, $request )
793
+ ),
794
+ );
795
+
796
+ $response = rest_ensure_response( $retval );
797
+
798
+ /**
799
+ * Fires after user favorited activities has been updated via the REST API.
800
+ *
801
+ * @since 5.0.0
802
+ *
803
+ * @param BP_Activity_Activity $activity The updated activity.
804
+ * @param array $user_favorites The updated user favorites.
805
+ * @param WP_REST_Response $response The response data.
806
+ * @param WP_REST_Request $request The request sent to the API.
807
+ */
808
+ do_action( 'bp_rest_activity_update_favorite', $activity, $this->get_user_favorites(), $response, $request );
809
+
810
+ return $response;
811
+ }
812
+
813
+ /**
814
+ * Check if a given request has access to update user favorites.
815
+ *
816
+ * @since 5.0.0
817
+ *
818
+ * @param WP_REST_Request $request Full details about the request.
819
+ * @return bool|WP_Error
820
+ */
821
+ public function update_favorite_permissions_check( $request ) {
822
+ $retval = true;
823
+
824
+ if ( ! ( is_user_logged_in() && bp_activity_can_favorite() ) ) {
825
+ $retval = new WP_Error(
826
+ 'bp_rest_authorization_required',
827
+ __( 'Sorry, you are not allowed to update favorites.', 'buddypress' ),
828
+ array(
829
+ 'status' => rest_authorization_required_code(),
830
+ )
831
+ );
832
+ }
833
+
834
+ /**
835
+ * Filter the activity `update_favorite` permissions check.
836
+ *
837
+ * @since 5.0.0
838
+ *
839
+ * @param bool|WP_Error $retval Returned value.
840
+ * @param WP_REST_Request $request The request sent to the API.
841
+ */
842
+ return apply_filters( 'bp_rest_activity_update_favorite_permissions_check', $retval, $request );
843
+ }
844
+
845
+ /**
846
+ * Renders the content of an activity.
847
+ *
848
+ * @since 5.0.0
849
+ *
850
+ * @param BP_Activity_Activity $activity Activity data.
851
+ * @return string The rendered activity content.
852
+ */
853
+ public function render_item( $activity ) {
854
+ $rendered = '';
855
+
856
+ if ( empty( $activity->content ) ) {
857
+ return $rendered;
858
+ }
859
+
860
+ // Do not truncate activities.
861
+ add_filter( 'bp_activity_maybe_truncate_entry', '__return_false' );
862
+
863
+ if ( 'activity_comment' === $activity->type ) {
864
+ $rendered = apply_filters( 'bp_get_activity_content', $activity->content );
865
+ } else {
866
+ $activities_template = null;
867
+
868
+ if ( isset( $GLOBALS['activities_template'] ) ) {
869
+ $activities_template = $GLOBALS['activities_template'];
870
+ }
871
+
872
+ // Set the `activities_template` global for the current activity.
873
+ $GLOBALS['activities_template'] = new stdClass();
874
+ $GLOBALS['activities_template']->activity = $activity;
875
+
876
+ // Set up activity oEmbed cache.
877
+ bp_activity_embed();
878
+
879
+ $rendered = apply_filters( 'bp_get_activity_content_body', $activity->content );
880
+
881
+ // Restore the `activities_template` global.
882
+ $GLOBALS['activities_template'] = $activities_template;
883
+ }
884
+
885
+ // Restore the filter to truncate activities.
886
+ remove_filter( 'bp_activity_maybe_truncate_entry', '__return_false' );
887
+
888
+ return $rendered;
889
+ }
890
+
891
+ /**
892
+ * Prepares activity data for return as an object.
893
+ *
894
+ * @since 5.0.0
895
+ *
896
+ * @param BP_Activity_Activity $activity Activity data.
897
+ * @param WP_REST_Request $request Full details about the request.
898
+ * @return WP_REST_Response
899
+ */
900
+ public function prepare_item_for_response( $activity, $request ) {
901
+ $data = array(
902
+ 'user_id' => $activity->user_id,
903
+ 'component' => $activity->component,
904
+ 'content' => array(
905
+ 'raw' => $activity->content,
906
+ 'rendered' => $this->render_item( $activity ),
907
+ ),
908
+ 'date' => bp_rest_prepare_date_response( $activity->date_recorded ),
909
+ 'id' => $activity->id,
910
+ 'link' => bp_activity_get_permalink( $activity->id ),
911
+ 'primary_item_id' => $activity->item_id,
912
+ 'secondary_item_id' => $activity->secondary_item_id,
913
+ 'status' => $activity->is_spam ? 'spam' : 'published',
914
+ 'title' => $activity->action,
915
+ 'type' => $activity->type,
916
+ 'favorited' => in_array( $activity->id, $this->get_user_favorites(), true ),
917
+ );
918
+
919
+ // Get item schema.
920
+ $schema = $this->get_item_schema();
921
+
922
+ // Get comments (count).
923
+ if ( ! empty( $activity->children ) ) {
924
+ $comment_count = wp_filter_object_list( $activity->children, array( 'type' => 'activity_comment' ), 'AND', 'id' );
925
+ $data['comment_count'] = ! empty( $comment_count ) ? count( $comment_count ) : 0;
926
+
927
+ if ( ! empty( $schema['properties']['comments'] ) && 'threaded' === $request['display_comments'] ) {
928
+ $data['comments'] = $this->prepare_activity_comments( $activity->children, $request );
929
+ }
930
+ }
931
+
932
+ if ( ! empty( $schema['properties']['user_avatar'] ) ) {
933
+ $data['user_avatar'] = array(
934
+ 'full' => bp_core_fetch_avatar(
935
+ array(
936
+ 'item_id' => $activity->user_id,
937
+ 'html' => false,
938
+ 'type' => 'full',
939
+ )
940
+ ),
941
+
942
+ 'thumb' => bp_core_fetch_avatar(
943
+ array(
944
+ 'item_id' => $activity->user_id,
945
+ 'html' => false,
946
+ )
947
+ ),
948
+ );
949
+ }
950
+
951
+ $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
952
+ $data = $this->add_additional_fields_to_object( $data, $request );
953
+ $data = $this->filter_response_by_context( $data, $context );
954
+
955
+ $response = rest_ensure_response( $data );
956
+ $response->add_links( $this->prepare_links( $activity ) );
957
+
958
+ /**
959
+ * Filter an activity value returned from the API.
960
+ *
961
+ * @since 5.0.0
962
+ *
963
+ * @param WP_REST_Response $response The response data.
964
+ * @param WP_REST_Request $request Request used to generate the response.
965
+ * @param BP_Activity_Activity $activity The activity object.
966
+ */
967
+ return apply_filters( 'bp_rest_activity_prepare_value', $response, $request, $activity );
968
+ }
969
+
970
+ /**
971
+ * Prepare activity comments.
972
+ *
973
+ * @since 5.0.0
974
+ *
975
+ * @param array $comments Comments.
976
+ * @param WP_REST_Request $request Full details about the request.
977
+ * @return array An array of activity comments.
978
+ */
979
+ protected function prepare_activity_comments( $comments, $request ) {
980
+ $data = array();
981
+
982
+ if ( empty( $comments ) ) {
983
+ return $data;
984
+ }
985
+
986
+ foreach ( $comments as $comment ) {
987
+ $data[] = $this->prepare_response_for_collection(
988
+ $this->prepare_item_for_response( $comment, $request )
989
+ );
990
+ }
991
+
992
+ /**
993
+ * Filter activity comments returned from the API.
994
+ *
995
+ * @since 5.0.0
996
+ *
997
+ * @param array $data An array of activity comments.
998
+ * @param array $comments Comments.
999
+ * @param WP_REST_Request $request Request used to generate the response.
1000
+ */
1001
+ return apply_filters( 'bp_rest_activity_prepare_comments', $data, $comments, $request );
1002
+ }
1003
+
1004
+ /**
1005
+ * Prepare an activity for create or update.
1006
+ *
1007
+ * @since 5.0.0
1008
+ *
1009
+ * @param WP_REST_Request $request Request object.
1010
+ * @return stdClass|WP_Error Object or WP_Error.
1011
+ */
1012
+ protected function prepare_item_for_database( $request ) {
1013
+ $prepared_activity = new stdClass();
1014
+ $schema = $this->get_item_schema();
1015
+ $activity = $this->get_activity_object( $request );
1016
+
1017
+ if ( ! empty( $schema['properties']['id'] ) && ! empty( $activity->id ) ) {
1018
+ $prepared_activity->id = $activity->id;
1019
+
1020
+ if ( 'activity_comment' !== $request['type'] ) {
1021
+ $prepared_activity->error_type = 'wp_error';
1022
+ }
1023
+ }
1024
+
1025
+ // Activity author ID.
1026
+ if ( ! empty( $schema['properties']['user_id'] ) && isset( $request['user_id'] ) ) {
1027
+ $prepared_activity->user_id = (int) $request['user_id'];
1028
+ } else {
1029
+ $prepared_activity->user_id = get_current_user_id();
1030
+ }
1031
+
1032
+ // Activity component.
1033
+ if ( ! empty( $schema['properties']['component'] ) && isset( $request['component'] ) ) {
1034
+ $prepared_activity->component = $request['component'];
1035
+ } else {
1036
+ $prepared_activity->component = buddypress()->activity->id;
1037
+ }
1038
+
1039
+ // Activity Item ID.
1040
+ if ( ! empty( $schema['properties']['primary_item_id'] ) && isset( $request['primary_item_id'] ) ) {
1041
+ $item_id = (int) $request['primary_item_id'];
1042
+
1043
+ // Set the group ID of the activity.
1044
+ if ( bp_is_active( 'groups' ) && isset( $prepared_activity->component ) && buddypress()->groups->id === $prepared_activity->component ) {
1045
+ $prepared_activity->group_id = $item_id;
1046
+
1047
+ // Use a generic item ID for other components.
1048
+ } else {
1049
+ $prepared_activity->item_id = $item_id;
1050
+ }
1051
+ }
1052
+
1053
+ // Secondary Item ID.
1054
+ if ( ! empty( $schema['properties']['secondary_item_id'] ) && isset( $request['secondary_item_id'] ) ) {
1055
+ $prepared_activity->secondary_item_id = (int) $request['secondary_item_id'];
1056
+ }
1057
+
1058
+ // Activity type.
1059
+ if ( ! empty( $schema['properties']['type'] ) && isset( $request['type'] ) ) {
1060
+ $prepared_activity->type = $request['type'];
1061
+ }
1062
+
1063
+ // Activity content.
1064
+ if ( ! empty( $schema['properties']['content'] ) && isset( $request['content'] ) ) {
1065
+ if ( is_string( $request['content'] ) ) {
1066
+ $prepared_activity->content = $request['content'];
1067
+ } elseif ( isset( $request['content']['raw'] ) ) {
1068
+ $prepared_activity->content = $request['content']['raw'];
1069
+ }
1070
+ }
1071
+
1072
+ // Activity Sitewide visibility.
1073
+ if ( ! empty( $schema['properties']['hidden'] ) && isset( $request['hidden'] ) ) {
1074
+ $prepared_activity->hide_sitewide = (bool) $request['hidden'];
1075
+ }
1076
+
1077
+ /**
1078
+ * Filters an activity before it is inserted or updated via the REST API.
1079
+ *
1080
+ * @since 5.0.0
1081
+ *
1082
+ * @param stdClass $prepared_activity An object prepared for inserting or updating the database.
1083
+ * @param WP_REST_Request $request Request object.
1084
+ */
1085
+ return apply_filters( 'bp_rest_activity_pre_insert_value', $prepared_activity, $request );
1086
+ }
1087
+
1088
+ /**
1089
+ * Prepare links for the request.
1090
+ *
1091
+ * @since 5.0.0
1092
+ *
1093
+ * @param BP_Activity_Activity $activity Activity object.
1094
+ * @return array
1095
+ */
1096
+ protected function prepare_links( $activity ) {
1097
+ $base = sprintf( '/%s/%s/', $this->namespace, $this->rest_base );
1098
+ $url = $base . $activity->id;
1099
+
1100
+ // Entity meta.
1101
+ $links = array(
1102
+ 'self' => array(
1103
+ 'href' => rest_url( $url ),
1104
+ ),
1105
+ 'collection' => array(
1106
+ 'href' => rest_url( $base ),
1107
+ ),
1108
+ 'user' => array(
1109
+ 'href' => rest_url( bp_rest_get_user_url( $activity->user_id ) ),
1110
+ 'embeddable' => true,
1111
+ ),
1112
+ );
1113
+
1114
+ if ( 'activity_comment' === $activity->type ) {
1115
+ $links['up'] = array(
1116
+ 'href' => rest_url( $url ),
1117
+ );
1118
+ }
1119
+
1120
+ if ( bp_activity_can_favorite() ) {
1121
+ $links['favorite'] = array(
1122
+ 'href' => rest_url( $url . '/favorite' ),
1123
+ );
1124
+ }
1125
+
1126
+ if ( bp_is_active( 'groups' ) && 'groups' === $activity->component && ! empty( $activity->item_id ) ) {
1127
+ $group = groups_get_group( $activity->item_id );
1128
+
1129
+ $links['group'] = array(
1130
+ 'href' => bp_get_group_permalink( $group ),
1131
+ 'embeddable' => true,
1132
+ );
1133
+ }
1134
+
1135
+ /**
1136
+ * Filter links prepared for the REST response.
1137
+ *
1138
+ * @since 5.0.0
1139
+ *
1140
+ * @param array $links The prepared links of the REST response.
1141
+ * @param BP_Activity_Activity $activity Activity object.
1142
+ */
1143
+ return apply_filters( 'bp_rest_activity_prepare_links', $links, $activity );
1144
+ }
1145
+
1146
+ /**
1147
+ * Can this user see the activity?
1148
+ *
1149
+ * @since 5.0.0
1150
+ *
1151
+ * @param WP_REST_Request $request Full details about the request.
1152
+ * @return boolean
1153
+ */
1154
+ protected function can_see( $request ) {
1155
+ return bp_activity_user_can_read(
1156
+ $this->get_activity_object( $request ),
1157
+ bp_loggedin_user_id()
1158
+ );
1159
+ }
1160
+
1161
+ /**
1162
+ * Show hidden activity?
1163
+ *
1164
+ * @since 5.0.0
1165
+ *
1166
+ * @param string $component The activity component.
1167
+ * @param int $item_id The activity item ID.
1168
+ * @return boolean
1169
+ */
1170
+ protected function show_hidden( $component, $item_id ) {
1171
+ $user_id = get_current_user_id();
1172
+ $retval = false;
1173
+
1174
+ if ( ! is_null( $component ) ) {
1175
+ // If activity is from a group, do an extra cap check.
1176
+ if ( ! $retval && ! empty( $item_id ) && bp_is_active( $component ) && buddypress()->groups->id === $component ) {
1177
+ // Group admins and mods have access as well.
1178
+ if ( groups_is_user_admin( $user_id, $item_id ) || groups_is_user_mod( $user_id, $item_id ) ) {
1179
+ $retval = true;
1180
+
1181
+ // User is a member of the group.
1182
+ } elseif ( (bool) groups_is_user_member( $user_id, $item_id ) ) {
1183
+ $retval = true;
1184
+ }
1185
+ }
1186
+ }
1187
+
1188
+ // Moderators as well.
1189
+ if ( bp_current_user_can( 'bp_moderate' ) ) {
1190
+ $retval = true;
1191
+ }
1192
+
1193
+ return (bool) $retval;
1194
+ }
1195
+
1196
+ /**
1197
+ * Get activity object.
1198
+ *
1199
+ * @since 5.0.0
1200
+ *
1201
+ * @param WP_REST_Request $request Full details about the request.
1202
+ * @return BP_Activity_Activity|string An activity object.
1203
+ */
1204
+ public function get_activity_object( $request ) {
1205
+ $activity_id = is_numeric( $request ) ? $request : (int) $request['id'];
1206
+
1207
+ $activity = bp_activity_get_specific(
1208
+ array(
1209
+ 'activity_ids' => array( $activity_id ),
1210
+ 'display_comments' => true,
1211
+ )
1212
+ );
1213
+
1214
+ if ( is_array( $activity ) && ! empty( $activity['activities'][0] ) ) {
1215
+ return $activity['activities'][0];
1216
+ }
1217
+
1218
+ return '';
1219
+ }
1220
+
1221
+ /**
1222
+ * Edit the type of the some properties for the CREATABLE & EDITABLE methods.
1223
+ *
1224
+ * @since 5.0.0
1225
+ *
1226
+ * @param string $method Optional. HTTP method of the request.
1227
+ * @return array Endpoint arguments.
1228
+ */
1229
+ public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {
1230
+ $args = WP_REST_Controller::get_endpoint_args_for_item_schema( $method );
1231
+ $key = 'get_item';
1232
+
1233
+ if ( WP_REST_Server::CREATABLE === $method || WP_REST_Server::EDITABLE === $method ) {
1234
+ $key = 'create_item';
1235
+ $args['content']['type'] = 'string';
1236
+ unset( $args['content']['properties'] );
1237
+
1238
+ if ( WP_REST_Server::EDITABLE === $method ) {
1239
+ $key = 'update_item';
1240
+ $args['type']['required'] = true;
1241
+ }
1242
+ } elseif ( WP_REST_Server::DELETABLE === $method ) {
1243
+ $key = 'delete_item';
1244
+ }
1245
+
1246
+ /**
1247
+ * Filters the method query arguments.
1248
+ *
1249
+ * @since 5.0.0
1250
+ *
1251
+ * @param array $args Query arguments.
1252
+ * @param string $method HTTP method of the request.
1253
+ */
1254
+ return apply_filters( "bp_rest_activity_{$key}_query_arguments", $args, $method );
1255
+ }
1256
+
1257
+ /**
1258
+ * Get the plugin schema, conforming to JSON Schema.
1259
+ *
1260
+ * @since 5.0.0
1261
+ *
1262
+ * @return array
1263
+ */
1264
+ public function get_item_schema() {
1265
+ $schema = array(
1266
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
1267
+ 'title' => 'bp_activity',
1268
+ 'type' => 'object',
1269
+ 'properties' => array(
1270
+ 'id' => array(
1271
+ 'context' => array( 'view', 'edit' ),
1272
+ 'description' => __( 'A unique numeric ID for the activity.', 'buddypress' ),
1273
+ 'readonly' => true,
1274
+ 'type' => 'integer',
1275
+ ),
1276
+ 'primary_item_id' => array(
1277
+ 'context' => array( 'view', 'edit' ),
1278
+ 'description' => __( 'The ID of some other object primarily associated with this one.', 'buddypress' ),
1279
+ 'type' => 'integer',
1280
+ ),
1281
+ 'secondary_item_id' => array(
1282
+ 'context' => array( 'view', 'edit' ),
1283
+ 'description' => __( 'The ID of some other object also associated with this one.', 'buddypress' ),
1284
+ 'type' => 'integer',
1285
+ ),
1286
+ 'user_id' => array(
1287
+ 'context' => array( 'view', 'edit' ),
1288
+ 'description' => __( 'The ID for the author of the activity.', 'buddypress' ),
1289
+ 'type' => 'integer',
1290
+ ),
1291
+ 'link' => array(
1292
+ 'context' => array( 'view', 'edit' ),
1293
+ 'description' => __( 'The permalink to this activity on the site.', 'buddypress' ),
1294
+ 'format' => 'uri',
1295
+ 'type' => 'string',
1296
+ ),
1297
+ 'component' => array(
1298
+ 'context' => array( 'view', 'edit' ),
1299
+ 'description' => __( 'The active BuddyPress component the activity relates to.', 'buddypress' ),
1300
+ 'type' => 'string',
1301
+ 'enum' => array_keys( buddypress()->active_components ),
1302
+ 'arg_options' => array(
1303
+ 'sanitize_callback' => 'sanitize_key',
1304
+ ),
1305
+ ),
1306
+ 'type'